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) {
189 }
else if (buf[c] == 0) {
228 pl = (
unsigned short *) (buf+c);
229 p->plength = ntohs(*pl);
244 pl = (
unsigned short *)
p->plen;
245 p->plength = ntohs(*pl);
255 if ( (
p->flag1 & 0xC0) == 0x80 ) {
258 LOG(VB_GENERAL, LOG_ERR,
259 "Error: THIS IS AN MPEG1 FILE");
266 if ( !
p->done &&
p->mpeg == 2){
274 if ( !
p->done &&
p->mpeg == 2){
290 if (
p->done || (
p->mpeg == 2 &&
p->found >= 9) ){
298 memcpy(
p->buf.data(), headr.data(), 3);
300 memcpy(
p->buf.data()+4,
p->plen,2);
302 memcpy(
p->hbuf, headr.data(), 3);
304 memcpy(
p->hbuf+4,
p->plen,2);
309 p->buf[6] =
p->flag1;
310 p->buf[7] =
p->flag2;
311 p->buf[8] =
p->hlength;
313 p->hbuf[6] =
p->flag1;
314 p->hbuf[7] =
p->flag2;
315 p->hbuf[8] =
p->hlength;
319 if ( (
p->flag2 &
PTS_ONLY) &&
p->found >= 9 &&
p->found < 14){
320 while (c < count && p->found < 14){
321 p->pts[
p->found-9] = buf[c];
323 p->buf[
p->found] = buf[c];
325 p->hbuf[
p->found] = buf[c];
329 if (c == count)
return;
332 if (((
p->flag2 &
PTS_DTS) == 0xC0) &&
p->found >= 14 &&
p->found < 19){
333 while (c < count && p->found < 19){
334 p->dts[
p->found-14] = buf[c];
336 p->buf[
p->found] = buf[c];
338 p->hbuf[
p->found] = buf[c];
342 if (c == count)
return;
346 while (c < count && p->found < p->plength+6){
348 if (l+
p->found >
p->plength+6)
349 l =
p->plength+6-
p->found;
351 memcpy(
p->buf.data()+
p->found, buf+c, l);
354 (
unsigned int)
p->hlength+9 ){
355 int rest =
p->hlength+9-
p->found;
356 memcpy(
p->hbuf+
p->found, buf+c, rest);
363 LOG(VB_GENERAL, LOG_ERR,
364 QString(
"ring buffer overflow %1")
365 .arg(
p->rbuf->size));
374 if(
p->found ==
p->plength+6){
381 if(
p->found + count - c < p->plength+6){
385 c +=
p->plength+6 -
p->found;
386 p->found =
p->plength+6;
390 if (
p->plength &&
p->found ==
p->plength+6) {
404static uint32_t scr_base_ps(
const uint8_t *scr)
407 uint8_t *buf = (uint8_t *)&base;
409 buf[0] |= (uint8_t)((scr[0] & 0x18) << 3);
410 buf[0] |= (uint8_t)((scr[0] & 0x03) << 4);
411 buf[0] |= (uint8_t)((scr[1] & 0xF0) >> 4);
413 buf[1] |= (uint8_t)((scr[1] & 0x0F) << 4);
414 buf[1] |= (uint8_t)((scr[2] & 0xF0) >> 4);
416 buf[2] |= (uint8_t)((scr[2] & 0x08) << 4);
417 buf[2] |= (uint8_t)((scr[2] & 0x03) << 5);
418 buf[2] |= (uint8_t)((scr[3] & 0xF8) >> 3);
420 buf[3] |= (uint8_t)((scr[3] & 0x07) << 5);
421 buf[3] |= (uint8_t)((scr[4] & 0xF8) >> 3);
427static uint16_t scr_ext_ps(
const uint8_t *scr)
431 ext = (short)(scr[5] >> 1);
432 ext += (short) (scr[4] & 0x03) * 128;
441 p->stuff_length=0xF8;
455 auto *ll = (
short *)
p->sheader_llength;
456 p->sheader.resize(ntohs(*ll) - 6);
468 std::array<uint8_t,4> headr1 {0x00, 0x00, 0x01,
PACK_START };
469 std::array<uint8_t,4> headr2 {0x00, 0x00, 0x01,
SYS_START };
470 uint8_t buffy = 0xFF;
473 memcpy(buf,headr1.data(),4);
475 memcpy(buf+count,
p->scr,6);
477 memcpy(buf+count,
p->mux_rate,3);
479 memcpy(buf+count,&
p->stuff_length,1);
481 for (
long i=0; i< (
p->stuff_length & 3); i++){
482 memcpy(buf+count,&buffy,1);
486 if (!
p->sheader.empty()){
487 memcpy(buf+count,headr2.data(),4);
489 memcpy(buf+count,
p->sheader_llength,2);
491 memcpy(buf+count,
p->rate_bound,3);
493 memcpy(buf+count,&
p->audio_bound,1);
495 memcpy(buf+count,&
p->video_bound,1);
497 memcpy(buf+count,&
p->reserved,1);
499 memcpy(buf+count,
p->sheader.data(),
p->sheader.size());
500 count +=
p->sheader.size();
523 uint32_t lscr = htonl((uint32_t) ((SCR/300ULL) & 0x00000000FFFFFFFF));
524 auto *scr = (uint8_t *) 𝓁
525 auto scr_ext = (
uint16_t) ((SCR%300ULL) & 0x00000000000001FF);
535 p.scr[0] = 0x44 | ((scr[0] >> 3)&0x18) | ((scr[0] >> 4)&0x03);
536 p.scr[1] = 0x00 | ((scr[0] << 4)&0xF0) | ((scr[1] >> 4)&0x0F);
537 p.scr[2] = 0x04 | ((scr[1] << 4)&0xF0) | ((scr[2] >> 4)&0x08)
538 | ((scr[2] >> 5)&0x03);
539 p.scr[3] = 0x00 | ((scr[2] << 3)&0xF8) | ((scr[3] >> 5)&0x07);
540 p.scr[4] = 0x04 | ((scr[3] << 3)&0xF8) | ((scr_ext >> 7)&0x03);
541 p.scr[5] = 0x01 | ((scr_ext << 1)&0xFF);
545 p.mux_rate[0] = (uint8_t)(muxr >> 14);
546 p.mux_rate[1] = (uint8_t)(0xff & (muxr >> 6));
547 p.mux_rate[2] = (uint8_t)(0x03 | ((muxr & 0x3f) << 2));
549 p.stuff_length = 0xF8;
552 p.sheader_llength[0] = 0x00;
553 p.sheader_llength[1] = 0x12;
557 p.rate_bound[0] = (uint8_t)(0x80 | (muxr >>15));
558 p.rate_bound[1] = (uint8_t)(0xff & (muxr >> 7));
559 p.rate_bound[2] = (uint8_t)(0x01 | ((muxr & 0x7f)<<1));
562 p.audio_bound = (uint8_t)((audio_bound << 2)|(fixed << 1)|CSPS);
563 p.video_bound = (uint8_t)((audio_lock << 7)|
564 (video_lock << 6)|0x20|video_bound);
565 p.reserved = (uint8_t)(0xFF >> 1);
577 p.sheader[10] = 0xE0;
578 p.sheader[11] = 0x02;
595 ((spts[0] & 0xC0) >>5);
596 pts[1] = ((spts[0] & 0x3F) << 2) |
597 ((spts[1] & 0xC0) >> 6);
598 pts[2] = 0x01 | ((spts[1] & 0x3F) << 2) |
599 ((spts[2] & 0x80) >> 6);
600 pts[3] = ((spts[2] & 0x7F) << 1) |
601 ((spts[3] & 0x80) >> 7);
602 pts[4] = 0x01 | ((spts[3] & 0x7F) << 1);
606 uint8_t *obuf,
int stuffing, uint8_t ptsdts)
608 std::array<uint8_t,2> le {};
609 std::array<uint8_t,3> dummy {};
612 std::array<uint8_t,3> headr {0x00, 0x00, 0x01};
614 uint32_t lpts = htonl((PTS/300ULL) & 0x00000000FFFFFFFFULL);
615 auto *
pts = (uint8_t *) &lpts;
617 if ((PTS/300ULL) & 0x0000000100000000ULL) ppts[0] |= 0x80;
619 uint32_t ldts = htonl((DTS/300ULL) & 0x00000000FFFFFFFFULL);
620 auto *dts = (uint8_t *) &ldts;
622 if ((DTS/300ULL) & 0x0000000100000000ULL) pdts[0] |= 0x80;
625 memcpy(obuf+c,headr.data(),3);
627 memcpy(obuf+c,&
id,1);
634 le[0] |= ((uint8_t)(length >> 8) & 0xFF);
635 le[1] |= ((uint8_t)length & 0xFF);
636 memcpy(obuf+c,le.data(),2);
640 memset(obuf+c,0xff,length);
661 memcpy(obuf+c,dummy.data(),3);
665 memcpy(obuf+c,ppts.data(),5);
667 }
else if ( ptsdts ==
PTS_DTS ){
668 memcpy(obuf+c,ppts.data(),5);
670 memcpy(obuf+c,pdts.data(),5);
674 memset(obuf+c,0xFF,stuffing);
681 uint64_t SCR, uint64_t muxr, uint8_t *buf)
693 uint64_t vdts, uint64_t SCR, uint64_t muxr,
694 uint8_t *buf,
int *vlength,
698 int length = *vlength;
700 if (! length)
return 0;
709 if ( length+
p >= pack_size){
712 if (pack_size - length -
p <=
PES_MIN){
713 stuff = pack_size - length-
p;
725 if (length-pos > *vlength){
726 LOG(VB_GENERAL, LOG_ERR,
727 QString(
"WHAT THE HELL %1 > %2").arg(length-pos).arg(*vlength));
730 int add =
ring_read( vrbuffer, buf+pos, length-pos);
732 if (add < 0)
return -1;
744 uint64_t SCR, uint32_t muxr, uint8_t *buf,
int *alength,
748 int length = *alength;
750 if (!length)
return 0;
757 if ( length+
p >= pack_size){
761 stuff = pack_size - length-
p;
771 int add =
ring_read( arbuffer, buf+pos, length-pos);
773 if (add < 0)
return -1;
781 if (pos != pack_size) {
782 LOG(VB_GENERAL, LOG_ERR, QString(
"apos: %1").arg(pos));
790 uint64_t
pts, uint64_t SCR,
791 uint32_t muxr, uint8_t *buf,
int *alength, uint8_t ptsdts,
792 int nframes,
int ac3_off,
ringbuffer *ac3rbuffer)
795 int length = *alength;
797 if (!length)
return 0;
804 if ( length+
p >= pack_size){
808 stuff = pack_size - length-
p;
818 buf+pos, stuff, ptsdts);
820 buf[pos+1] = nframes;
821 buf[pos+2] = (ac3_off >> 8)& 0xFF;
822 buf[pos+3] = ac3_off& 0xFF;
825 int add =
ring_read( ac3rbuffer, buf+pos, length-pos);
827 if (add < 0)
return -1;
835 if (pos != pack_size) {
836 LOG(VB_GENERAL, LOG_ERR, QString(
"apos: %1").arg(pos));
847 std::array<uint8_t,5> headr {0x00, 0x00, 0x01,
PRIVATE_STREAM2, 0x03 };
851 memcpy(buf+pos, headr.data(), 5);
854 memset(buf+pos, 0, 0x03d4);
857 memcpy(buf+pos, headr.data(), 5);
860 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)