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){
155 p->buf =
static_cast<uchar*
>(malloc(
MAX_PLENGTH*
sizeof(uint8_t)));
162 memset(
p->pts, 0 , 5);
163 memset(
p->dts, 0 , 5);
169 unsigned short *pl =
nullptr;
172 std::array<uint8_t,3> headr { 0x00, 0x00, 0x01} ;
177 while (c < count && (!
p->mpeg ||
178 (
p->mpeg == 2 &&
p->found < 9))
179 && (
p->found < 5 || !
p->done)){
183 if (buf[c] == 0x00)
p->found++;
188 if (buf[c] == 0x01)
p->found++;
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 )
p->mpeg = 2;
257 LOG(VB_GENERAL, LOG_ERR,
258 "Error: THIS IS AN MPEG1 FILE");
265 if ( !
p->done &&
p->mpeg == 2){
273 if ( !
p->done &&
p->mpeg == 2){
289 if (
p->done || (
p->mpeg == 2 &&
p->found >= 9) ){
297 memcpy(
p->buf, headr.data(), 3);
299 memcpy(
p->buf+4,
p->plen,2);
301 memcpy(
p->hbuf, headr.data(), 3);
303 memcpy(
p->hbuf+4,
p->plen,2);
308 p->buf[6] =
p->flag1;
309 p->buf[7] =
p->flag2;
310 p->buf[8] =
p->hlength;
312 p->hbuf[6] =
p->flag1;
313 p->hbuf[7] =
p->flag2;
314 p->hbuf[8] =
p->hlength;
318 if ( (
p->flag2 &
PTS_ONLY) &&
p->found >= 9 &&
p->found < 14){
319 while (c < count && p->found < 14){
320 p->pts[
p->found-9] = buf[c];
322 p->buf[
p->found] = buf[c];
324 p->hbuf[
p->found] = buf[c];
328 if (c == count)
return;
331 if (((
p->flag2 &
PTS_DTS) == 0xC0) &&
p->found >= 14 &&
p->found < 19){
332 while (c < count && p->found < 19){
333 p->dts[
p->found-14] = buf[c];
335 p->buf[
p->found] = buf[c];
337 p->hbuf[
p->found] = buf[c];
341 if (c == count)
return;
345 while (c < count && p->found < p->plength+6){
347 if (l+
p->found >
p->plength+6)
348 l =
p->plength+6-
p->found;
350 memcpy(
p->buf+
p->found, buf+c, l);
353 (
unsigned int)
p->hlength+9 ){
354 int rest =
p->hlength+9-
p->found;
355 memcpy(
p->hbuf+
p->found, buf+c, rest);
362 LOG(VB_GENERAL, LOG_ERR,
363 QString(
"ring buffer overflow %1")
364 .arg(
p->rbuf->size));
373 if(
p->found ==
p->plength+6){
380 if(
p->found + count - c < p->plength+6){
384 c +=
p->plength+6 -
p->found;
385 p->found =
p->plength+6;
389 if (
p->plength &&
p->found ==
p->plength+6) {
403static uint32_t scr_base_ps(
const uint8_t *scr)
406 uint8_t *buf = (uint8_t *)&base;
408 buf[0] |= (uint8_t)((scr[0] & 0x18) << 3);
409 buf[0] |= (uint8_t)((scr[0] & 0x03) << 4);
410 buf[0] |= (uint8_t)((scr[1] & 0xF0) >> 4);
412 buf[1] |= (uint8_t)((scr[1] & 0x0F) << 4);
413 buf[1] |= (uint8_t)((scr[2] & 0xF0) >> 4);
415 buf[2] |= (uint8_t)((scr[2] & 0x08) << 4);
416 buf[2] |= (uint8_t)((scr[2] & 0x03) << 5);
417 buf[2] |= (uint8_t)((scr[3] & 0xF8) >> 3);
419 buf[3] |= (uint8_t)((scr[3] & 0x07) << 5);
420 buf[3] |= (uint8_t)((scr[4] & 0xF8) >> 3);
426static uint16_t scr_ext_ps(
const uint8_t *scr)
430 ext = (short)(scr[5] >> 1);
431 ext += (short) (scr[4] & 0x03) * 128;
440 p->stuff_length=0xF8;
442 p->sheader_length = 0;
457 auto *ll = (
short *)
p->sheader_llength;
458 p->sheader_length = ntohs(*ll) - 6;
464 p->data = (uint8_t *) malloc(
p->sheader_length);
471 std::array<uint8_t,4> headr1 {0x00, 0x00, 0x01,
PACK_START };
472 std::array<uint8_t,4> headr2 {0x00, 0x00, 0x01,
SYS_START };
473 uint8_t buffy = 0xFF;
476 memcpy(buf,headr1.data(),4);
478 memcpy(buf+count,
p->scr,6);
480 memcpy(buf+count,
p->mux_rate,3);
482 memcpy(buf+count,&
p->stuff_length,1);
484 for (
long i=0; i< (
p->stuff_length & 3); i++){
485 memcpy(buf+count,&buffy,1);
489 if (
p->sheader_length){
490 memcpy(buf+count,headr2.data(),4);
492 memcpy(buf+count,
p->sheader_llength,2);
494 memcpy(buf+count,
p->rate_bound,3);
496 memcpy(buf+count,&
p->audio_bound,1);
498 memcpy(buf+count,&
p->video_bound,1);
500 memcpy(buf+count,&
p->reserved,1);
502 memcpy(buf+count,
p->data,
p->sheader_length);
503 count +=
p->sheader_length;
526 uint32_t lscr = htonl((uint32_t) ((SCR/300ULL) & 0x00000000FFFFFFFF));
527 auto *scr = (uint8_t *) 𝓁
528 auto scr_ext = (
uint16_t) ((SCR%300ULL) & 0x00000000000001FF);
538 p.scr[0] = 0x44 | ((scr[0] >> 3)&0x18) | ((scr[0] >> 4)&0x03);
539 p.scr[1] = 0x00 | ((scr[0] << 4)&0xF0) | ((scr[1] >> 4)&0x0F);
540 p.scr[2] = 0x04 | ((scr[1] << 4)&0xF0) | ((scr[2] >> 4)&0x08)
541 | ((scr[2] >> 5)&0x03);
542 p.scr[3] = 0x00 | ((scr[2] << 3)&0xF8) | ((scr[3] >> 5)&0x07);
543 p.scr[4] = 0x04 | ((scr[3] << 3)&0xF8) | ((scr_ext >> 7)&0x03);
544 p.scr[5] = 0x01 | ((scr_ext << 1)&0xFF);
548 p.mux_rate[0] = (uint8_t)(muxr >> 14);
549 p.mux_rate[1] = (uint8_t)(0xff & (muxr >> 6));
550 p.mux_rate[2] = (uint8_t)(0x03 | ((muxr & 0x3f) << 2));
552 p.stuff_length = 0xF8;
555 p.sheader_llength[0] = 0x00;
556 p.sheader_llength[1] = 0x12;
560 p.rate_bound[0] = (uint8_t)(0x80 | (muxr >>15));
561 p.rate_bound[1] = (uint8_t)(0xff & (muxr >> 7));
562 p.rate_bound[2] = (uint8_t)(0x01 | ((muxr & 0x7f)<<1));
565 p.audio_bound = (uint8_t)((audio_bound << 2)|(fixed << 1)|CSPS);
566 p.video_bound = (uint8_t)((audio_lock << 7)|
567 (video_lock << 6)|0x20|video_bound);
568 p.reserved = (uint8_t)(0xFF >> 1);
602 ((spts[0] & 0xC0) >>5);
603 pts[1] = ((spts[0] & 0x3F) << 2) |
604 ((spts[1] & 0xC0) >> 6);
605 pts[2] = 0x01 | ((spts[1] & 0x3F) << 2) |
606 ((spts[2] & 0x80) >> 6);
607 pts[3] = ((spts[2] & 0x7F) << 1) |
608 ((spts[3] & 0x80) >> 7);
609 pts[4] = 0x01 | ((spts[3] & 0x7F) << 1);
613 uint8_t *obuf,
int stuffing, uint8_t ptsdts)
615 std::array<uint8_t,2> le {};
616 std::array<uint8_t,3> dummy {};
619 std::array<uint8_t,3> headr {0x00, 0x00, 0x01};
621 uint32_t lpts = htonl((PTS/300ULL) & 0x00000000FFFFFFFFULL);
622 auto *
pts = (uint8_t *) &lpts;
624 if ((PTS/300ULL) & 0x0000000100000000ULL) ppts[0] |= 0x80;
626 uint32_t ldts = htonl((DTS/300ULL) & 0x00000000FFFFFFFFULL);
627 auto *dts = (uint8_t *) &ldts;
629 if ((DTS/300ULL) & 0x0000000100000000ULL) pdts[0] |= 0x80;
632 memcpy(obuf+c,headr.data(),3);
634 memcpy(obuf+c,&
id,1);
641 le[0] |= ((uint8_t)(length >> 8) & 0xFF);
642 le[1] |= ((uint8_t)(length) & 0xFF);
643 memcpy(obuf+c,le.data(),2);
647 memset(obuf+c,0xff,length);
668 memcpy(obuf+c,dummy.data(),3);
672 memcpy(obuf+c,ppts.data(),5);
674 }
else if ( ptsdts ==
PTS_DTS ){
675 memcpy(obuf+c,ppts.data(),5);
677 memcpy(obuf+c,pdts.data(),5);
681 memset(obuf+c,0xFF,stuffing);
688 uint64_t SCR, uint64_t muxr, uint8_t *buf)
700 uint64_t vdts, uint64_t SCR, uint64_t muxr,
701 uint8_t *buf,
int *vlength,
705 int length = *vlength;
707 if (! length)
return 0;
716 if ( length+
p >= pack_size){
719 if (pack_size - length -
p <=
PES_MIN){
720 stuff = pack_size - length-
p;
732 if (length-pos > *vlength){
733 LOG(VB_GENERAL, LOG_ERR,
734 QString(
"WHAT THE HELL %1 > %2").arg(length-pos).arg(*vlength));
737 int add =
ring_read( vrbuffer, buf+pos, length-pos);
739 if (add < 0)
return -1;
751 uint64_t SCR, uint32_t muxr, uint8_t *buf,
int *alength,
755 int length = *alength;
757 if (!length)
return 0;
764 if ( length+
p >= pack_size){
768 stuff = pack_size - length-
p;
778 int add =
ring_read( arbuffer, buf+pos, length-pos);
780 if (add < 0)
return -1;
788 if (pos != pack_size) {
789 LOG(VB_GENERAL, LOG_ERR, QString(
"apos: %1").arg(pos));
797 uint64_t
pts, uint64_t SCR,
798 uint32_t muxr, uint8_t *buf,
int *alength, uint8_t ptsdts,
799 int nframes,
int ac3_off,
ringbuffer *ac3rbuffer)
802 int length = *alength;
804 if (!length)
return 0;
811 if ( length+
p >= pack_size){
815 stuff = pack_size - length-
p;
825 buf+pos, stuff, ptsdts);
827 buf[pos+1] = nframes;
828 buf[pos+2] = (ac3_off >> 8)& 0xFF;
829 buf[pos+3] = (ac3_off)& 0xFF;
832 int add =
ring_read( ac3rbuffer, buf+pos, length-pos);
834 if (add < 0)
return -1;
842 if (pos != pack_size) {
843 LOG(VB_GENERAL, LOG_ERR, QString(
"apos: %1").arg(pos));
854 std::array<uint8_t,5> headr {0x00, 0x00, 0x01,
PRIVATE_STREAM2, 0x03 };
858 memcpy(buf+pos, headr.data(), 5);
861 memset(buf+pos, 0, 0x03d4);
864 memcpy(buf+pos, headr.data(), 5);
867 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)