37#include <netinet/in.h>
52 LOG(VB_GENERAL, LOG_INFO, QString(
"%1%2:%3:%4.%5")
53 .arg(negative ?
"-" :
"")
54 .arg((
unsigned int)(
pts/90000.0)/3600, 2,10,QChar(
'0'))
55 .arg(((
unsigned int)(
pts/90000.0)%3600)/60, 2,10,QChar(
'0'))
56 .arg(((
unsigned int)(
pts/90000.0)%3600)%60, 2,10,QChar(
'0'))
57 .arg((((
unsigned int)(
pts/9.0)%36000000)%600000)%10000, 4,10,QChar(
'0')));
69 LOG(VB_GENERAL, LOG_INFO, QString(
"%1%2:%3:%4.%5")
70 .arg(negative ?
"-" :
"")
71 .arg((
unsigned int)(
pts/90000.0)/3600, 2,10,QChar(
'0'))
72 .arg(((
unsigned int)(
pts/90000.0)%3600)/60, 2,10,QChar(
'0'))
73 .arg(((
unsigned int)(
pts/90000.0)%3600)%60, 2,10,QChar(
'0'))
74 .arg((((
unsigned int)(
pts/90.0)%3600000)%60000)%1000, 3,10,QChar(
'0')));
78int64_t
ptsdiff(uint64_t pts1, uint64_t pts2)
80 switch (
ptscmp(pts1, pts2)){
106 int64_t diff = pts1 - pts2;
123 }
else if (pts1 == pts2) {
132 LOG(VB_GENERAL, LOG_INFO,
133 QString(
"PTSCMP: %1 %2 %3\n").arg(pts1).arg(pts2).arg(ret));
140uint64_t
ptsadd(uint64_t pts1, uint64_t pts2)
154 if (
p->withbuf &&
p->buf.empty()){
161 memset(
p->pts, 0 , 5);
162 memset(
p->dts, 0 , 5);
168 unsigned short *pl =
nullptr;
171 std::array<uint8_t,3> headr { 0x00, 0x00, 0x01} ;
176 while (c < count && (!
p->mpeg ||
177 (
p->mpeg == 2 &&
p->found < 9))
178 && (
p->found < 5 || !
p->done)){
182 if (buf[c] == 0x00)
p->found++;
187 if (buf[c] == 0x01)
p->found++;
188 else if (buf[c] == 0){
227 pl = (
unsigned short *) (buf+c);
228 p->plength = ntohs(*pl);
243 pl = (
unsigned short *)
p->plen;
244 p->plength = ntohs(*pl);
254 if ( (
p->flag1 & 0xC0) == 0x80 )
p->mpeg = 2;
256 LOG(VB_GENERAL, LOG_ERR,
257 "Error: THIS IS AN MPEG1 FILE");
264 if ( !
p->done &&
p->mpeg == 2){
272 if ( !
p->done &&
p->mpeg == 2){
288 if (
p->done || (
p->mpeg == 2 &&
p->found >= 9) ){
296 memcpy(
p->buf.data(), headr.data(), 3);
298 memcpy(
p->buf.data()+4,
p->plen,2);
300 memcpy(
p->hbuf, headr.data(), 3);
302 memcpy(
p->hbuf+4,
p->plen,2);
307 p->buf[6] =
p->flag1;
308 p->buf[7] =
p->flag2;
309 p->buf[8] =
p->hlength;
311 p->hbuf[6] =
p->flag1;
312 p->hbuf[7] =
p->flag2;
313 p->hbuf[8] =
p->hlength;
317 if ( (
p->flag2 &
PTS_ONLY) &&
p->found >= 9 &&
p->found < 14){
318 while (c < count && p->found < 14){
319 p->pts[
p->found-9] = buf[c];
321 p->buf[
p->found] = buf[c];
323 p->hbuf[
p->found] = buf[c];
327 if (c == count)
return;
330 if (((
p->flag2 &
PTS_DTS) == 0xC0) &&
p->found >= 14 &&
p->found < 19){
331 while (c < count && p->found < 19){
332 p->dts[
p->found-14] = buf[c];
334 p->buf[
p->found] = buf[c];
336 p->hbuf[
p->found] = buf[c];
340 if (c == count)
return;
344 while (c < count && p->found < p->plength+6){
346 if (l+
p->found >
p->plength+6)
347 l =
p->plength+6-
p->found;
349 memcpy(
p->buf.data()+
p->found, buf+c, l);
352 (
unsigned int)
p->hlength+9 ){
353 int rest =
p->hlength+9-
p->found;
354 memcpy(
p->hbuf+
p->found, buf+c, rest);
361 LOG(VB_GENERAL, LOG_ERR,
362 QString(
"ring buffer overflow %1")
363 .arg(
p->rbuf->size));
372 if(
p->found ==
p->plength+6){
379 if(
p->found + count - c < p->plength+6){
383 c +=
p->plength+6 -
p->found;
384 p->found =
p->plength+6;
388 if (
p->plength &&
p->found ==
p->plength+6) {
402static uint32_t scr_base_ps(
const uint8_t *scr)
405 uint8_t *buf = (uint8_t *)&base;
407 buf[0] |= (uint8_t)((scr[0] & 0x18) << 3);
408 buf[0] |= (uint8_t)((scr[0] & 0x03) << 4);
409 buf[0] |= (uint8_t)((scr[1] & 0xF0) >> 4);
411 buf[1] |= (uint8_t)((scr[1] & 0x0F) << 4);
412 buf[1] |= (uint8_t)((scr[2] & 0xF0) >> 4);
414 buf[2] |= (uint8_t)((scr[2] & 0x08) << 4);
415 buf[2] |= (uint8_t)((scr[2] & 0x03) << 5);
416 buf[2] |= (uint8_t)((scr[3] & 0xF8) >> 3);
418 buf[3] |= (uint8_t)((scr[3] & 0x07) << 5);
419 buf[3] |= (uint8_t)((scr[4] & 0xF8) >> 3);
425static uint16_t scr_ext_ps(
const uint8_t *scr)
429 ext = (short)(scr[5] >> 1);
430 ext += (short) (scr[4] & 0x03) * 128;
439 p->stuff_length=0xF8;
453 auto *ll = (
short *)
p->sheader_llength;
454 p->sheader.resize(ntohs(*ll) - 6);
466 std::array<uint8_t,4> headr1 {0x00, 0x00, 0x01,
PACK_START };
467 std::array<uint8_t,4> headr2 {0x00, 0x00, 0x01,
SYS_START };
468 uint8_t buffy = 0xFF;
471 memcpy(buf,headr1.data(),4);
473 memcpy(buf+count,
p->scr,6);
475 memcpy(buf+count,
p->mux_rate,3);
477 memcpy(buf+count,&
p->stuff_length,1);
479 for (
long i=0; i< (
p->stuff_length & 3); i++){
480 memcpy(buf+count,&buffy,1);
484 if (!
p->sheader.empty()){
485 memcpy(buf+count,headr2.data(),4);
487 memcpy(buf+count,
p->sheader_llength,2);
489 memcpy(buf+count,
p->rate_bound,3);
491 memcpy(buf+count,&
p->audio_bound,1);
493 memcpy(buf+count,&
p->video_bound,1);
495 memcpy(buf+count,&
p->reserved,1);
497 memcpy(buf+count,
p->sheader.data(),
p->sheader.size());
498 count +=
p->sheader.size();
521 uint32_t lscr = htonl((uint32_t) ((SCR/300ULL) & 0x00000000FFFFFFFF));
522 auto *scr = (uint8_t *) 𝓁
523 auto scr_ext = (
uint16_t) ((SCR%300ULL) & 0x00000000000001FF);
533 p.scr[0] = 0x44 | ((scr[0] >> 3)&0x18) | ((scr[0] >> 4)&0x03);
534 p.scr[1] = 0x00 | ((scr[0] << 4)&0xF0) | ((scr[1] >> 4)&0x0F);
535 p.scr[2] = 0x04 | ((scr[1] << 4)&0xF0) | ((scr[2] >> 4)&0x08)
536 | ((scr[2] >> 5)&0x03);
537 p.scr[3] = 0x00 | ((scr[2] << 3)&0xF8) | ((scr[3] >> 5)&0x07);
538 p.scr[4] = 0x04 | ((scr[3] << 3)&0xF8) | ((scr_ext >> 7)&0x03);
539 p.scr[5] = 0x01 | ((scr_ext << 1)&0xFF);
543 p.mux_rate[0] = (uint8_t)(muxr >> 14);
544 p.mux_rate[1] = (uint8_t)(0xff & (muxr >> 6));
545 p.mux_rate[2] = (uint8_t)(0x03 | ((muxr & 0x3f) << 2));
547 p.stuff_length = 0xF8;
550 p.sheader_llength[0] = 0x00;
551 p.sheader_llength[1] = 0x12;
555 p.rate_bound[0] = (uint8_t)(0x80 | (muxr >>15));
556 p.rate_bound[1] = (uint8_t)(0xff & (muxr >> 7));
557 p.rate_bound[2] = (uint8_t)(0x01 | ((muxr & 0x7f)<<1));
560 p.audio_bound = (uint8_t)((audio_bound << 2)|(fixed << 1)|CSPS);
561 p.video_bound = (uint8_t)((audio_lock << 7)|
562 (video_lock << 6)|0x20|video_bound);
563 p.reserved = (uint8_t)(0xFF >> 1);
575 p.sheader[10] = 0xE0;
576 p.sheader[11] = 0x02;
593 ((spts[0] & 0xC0) >>5);
594 pts[1] = ((spts[0] & 0x3F) << 2) |
595 ((spts[1] & 0xC0) >> 6);
596 pts[2] = 0x01 | ((spts[1] & 0x3F) << 2) |
597 ((spts[2] & 0x80) >> 6);
598 pts[3] = ((spts[2] & 0x7F) << 1) |
599 ((spts[3] & 0x80) >> 7);
600 pts[4] = 0x01 | ((spts[3] & 0x7F) << 1);
604 uint8_t *obuf,
int stuffing, uint8_t ptsdts)
606 std::array<uint8_t,2> le {};
607 std::array<uint8_t,3> dummy {};
610 std::array<uint8_t,3> headr {0x00, 0x00, 0x01};
612 uint32_t lpts = htonl((PTS/300ULL) & 0x00000000FFFFFFFFULL);
613 auto *
pts = (uint8_t *) &lpts;
615 if ((PTS/300ULL) & 0x0000000100000000ULL) ppts[0] |= 0x80;
617 uint32_t ldts = htonl((DTS/300ULL) & 0x00000000FFFFFFFFULL);
618 auto *dts = (uint8_t *) &ldts;
620 if ((DTS/300ULL) & 0x0000000100000000ULL) pdts[0] |= 0x80;
623 memcpy(obuf+c,headr.data(),3);
625 memcpy(obuf+c,&
id,1);
632 le[0] |= ((uint8_t)(length >> 8) & 0xFF);
633 le[1] |= ((uint8_t)(length) & 0xFF);
634 memcpy(obuf+c,le.data(),2);
638 memset(obuf+c,0xff,length);
659 memcpy(obuf+c,dummy.data(),3);
663 memcpy(obuf+c,ppts.data(),5);
665 }
else if ( ptsdts ==
PTS_DTS ){
666 memcpy(obuf+c,ppts.data(),5);
668 memcpy(obuf+c,pdts.data(),5);
672 memset(obuf+c,0xFF,stuffing);
679 uint64_t SCR, uint64_t muxr, uint8_t *buf)
691 uint64_t vdts, uint64_t SCR, uint64_t muxr,
692 uint8_t *buf,
int *vlength,
696 int length = *vlength;
698 if (! length)
return 0;
707 if ( length+
p >= pack_size){
710 if (pack_size - length -
p <=
PES_MIN){
711 stuff = pack_size - length-
p;
723 if (length-pos > *vlength){
724 LOG(VB_GENERAL, LOG_ERR,
725 QString(
"WHAT THE HELL %1 > %2").arg(length-pos).arg(*vlength));
728 int add =
ring_read( vrbuffer, buf+pos, length-pos);
730 if (add < 0)
return -1;
742 uint64_t SCR, uint32_t muxr, uint8_t *buf,
int *alength,
746 int length = *alength;
748 if (!length)
return 0;
755 if ( length+
p >= pack_size){
759 stuff = pack_size - length-
p;
769 int add =
ring_read( arbuffer, buf+pos, length-pos);
771 if (add < 0)
return -1;
779 if (pos != pack_size) {
780 LOG(VB_GENERAL, LOG_ERR, QString(
"apos: %1").arg(pos));
788 uint64_t
pts, uint64_t SCR,
789 uint32_t muxr, uint8_t *buf,
int *alength, uint8_t ptsdts,
790 int nframes,
int ac3_off,
ringbuffer *ac3rbuffer)
793 int length = *alength;
795 if (!length)
return 0;
802 if ( length+
p >= pack_size){
806 stuff = pack_size - length-
p;
816 buf+pos, stuff, ptsdts);
818 buf[pos+1] = nframes;
819 buf[pos+2] = (ac3_off >> 8)& 0xFF;
820 buf[pos+3] = (ac3_off)& 0xFF;
823 int add =
ring_read( ac3rbuffer, buf+pos, length-pos);
825 if (add < 0)
return -1;
833 if (pos != pack_size) {
834 LOG(VB_GENERAL, LOG_ERR, QString(
"apos: %1").arg(pos));
845 std::array<uint8_t,5> headr {0x00, 0x00, 0x01,
PRIVATE_STREAM2, 0x03 };
849 memcpy(buf+pos, headr.data(), 5);
852 memset(buf+pos, 0, 0x03d4);
855 memcpy(buf+pos, headr.data(), 5);
858 memset(buf+pos, 0, 0x03fA);
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
std::chrono::duration< CHRONO_TYPE, std::ratio< 1, 90000 > > pts
int write_pes_header(uint8_t id, int length, uint64_t PTS, uint64_t DTS, uint8_t *obuf, int stuffing, uint8_t ptsdts)
void get_pes(pes_in_t *p, uint8_t *buf, int count, void(*func)(pes_in_t *p))
static void setl_ps(ps_packet *p)
static void init_ps(ps_packet *p)
static void setlength_ps(ps_packet *p)
static int write_ps_header(uint8_t *buf, uint64_t SCR, uint32_t muxr, uint8_t audio_bound, uint8_t fixed, uint8_t CSPS, uint8_t audio_lock, uint8_t video_lock, uint8_t video_bound, uint8_t navpack)
void write_padding_pes(int pack_size, int extcnt, uint64_t SCR, uint64_t muxr, uint8_t *buf)
static void get_pespts(const uint8_t *spts, pts_arr &pts)
void printptss(int64_t pts)
void printpts(int64_t pts)
int write_audio_pes(int pack_size, int extcnt, int n, uint64_t pts, uint64_t SCR, uint32_t muxr, uint8_t *buf, int *alength, uint8_t ptsdts, ringbuffer *arbuffer)
int ptscmp(uint64_t pts1, uint64_t pts2)
static void kill_ps(ps_packet *p)
std::array< uint8_t, 5 > pts_arr
int write_video_pes(int pack_size, int extcnt, uint64_t vpts, uint64_t vdts, uint64_t SCR, uint64_t muxr, uint8_t *buf, int *vlength, uint8_t ptsdts, ringbuffer *vrbuffer)
uint64_t ptsadd(uint64_t pts1, uint64_t pts2)
int64_t ptsdiff(uint64_t pts1, uint64_t pts2)
int write_nav_pack(int pack_size, int extcnt, uint64_t SCR, uint32_t muxr, uint8_t *buf)
static int cwrite_ps(uint8_t *buf, ps_packet *p, uint32_t length)
int write_ac3_pes(int pack_size, int extcnt, int n, uint64_t pts, uint64_t SCR, uint32_t muxr, uint8_t *buf, int *alength, uint8_t ptsdts, int nframes, int ac3_off, ringbuffer *ac3rbuffer)
uint64_t uptsdiff(uint64_t pts1, uint64_t pts2)
void init_pes_in(pes_in_t *p, int t, ringbuffer *rb, int wi)
static void ptsinc(uint64_t *pts1, uint64_t pts2)
int ring_read(ringbuffer *rbuf, uint8_t *data, int count)
int ring_write(ringbuffer *rbuf, uint8_t *data, int count)
static int ring_wpos(ringbuffer *rbuf)