00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #include <stdlib.h>
00030 #include <stdio.h>
00031 #include <string.h>
00032
00033 #ifdef USING_MINGW
00034 #include <winsock2.h>
00035 #else
00036 #include <netinet/in.h>
00037 #endif
00038
00039 #include "pes.h"
00040 #include "mythlogging.h"
00041
00042 void printpts(int64_t pts)
00043 {
00044 int negative = 0;
00045 if (pts < 0){
00046 negative = 1;
00047 pts = -pts;
00048 }
00049 pts = pts/300;
00050 pts &= (MAX_PTS-1);
00051 LOG(VB_GENERAL, LOG_INFO, "%s%2d:%02d:%02d.%04d",
00052 (negative ? "-" : ""),
00053 (unsigned int)(pts/90000.0)/3600,
00054 ((unsigned int)(pts/90000.0)%3600)/60,
00055 ((unsigned int)(pts/90000.0)%3600)%60,
00056 (((unsigned int)(pts/9.0)%36000000)%600000)%10000);
00057 }
00058
00059 void printptss(int64_t pts)
00060 {
00061 int negative = 0;
00062 if (pts < 0){
00063 negative = 0;
00064 pts = -pts;
00065 }
00066 pts = pts/300;
00067 pts &= (MAX_PTS-1);
00068 LOG(VB_GENERAL, LOG_INFO, "%s%2d:%02d:%02d.%03d",
00069 (negative ? "-" : ""),
00070 (unsigned int)(pts/90000.0)/3600,
00071 ((unsigned int)(pts/90000.0)%3600)/60,
00072 ((unsigned int)(pts/90000.0)%3600)%60,
00073 (((unsigned int)(pts/90.0)%3600000)%60000)%1000
00074 );
00075 }
00076
00077
00078 int64_t ptsdiff(uint64_t pts1, uint64_t pts2)
00079 {
00080 switch (ptscmp(pts1, pts2)){
00081 case 0:
00082 return 0;
00083 break;
00084
00085 case 1:
00086 case -2:
00087 return (pts1 -pts2);
00088 break;
00089
00090 case 2:
00091 return (pts1 + MAX_PTS2 -pts2);
00092 break;
00093
00094 case -1:
00095 return (pts1 - (pts2+ MAX_PTS2));
00096 break;
00097
00098 }
00099
00100 return 0;
00101 }
00102
00103
00104 uint64_t uptsdiff(uint64_t pts1, uint64_t pts2)
00105 {
00106 int64_t diff;
00107
00108 diff = pts1 - pts2;
00109
00110 if (diff < 0){
00111 diff = MAX_PTS2 +diff;
00112 }
00113 return diff;
00114 }
00115
00116 int ptscmp(uint64_t pts1, uint64_t pts2)
00117 {
00118 int ret;
00119
00120 if (pts1 > pts2){
00121 if ((pts1 - pts2) > MAX_PTS2/2)
00122 ret = -1;
00123 else
00124 ret = 1;
00125 } else if (pts1 == pts2) ret = 0;
00126 else {
00127 if ((pts2 - pts1) > MAX_PTS2/2)
00128 ret = 2;
00129 else
00130 ret = -2;
00131 }
00132 #if 0
00133 LOG(VB_GENERAL, LOG_INFO, "PTSCMP: %lli %lli %d\n", pts1, pts2, ret);
00134 printpts(pts1);
00135 printpts(pts2);
00136 #endif
00137 return ret;
00138 }
00139
00140 uint64_t ptsadd(uint64_t pts1, uint64_t pts2)
00141 {
00142 ptsinc(&pts1,pts2);
00143 return pts1;
00144
00145 }
00146
00147 void init_pes_in(pes_in_t *p, int t, ringbuffer *rb, int wi){
00148 p->type = t;
00149 p->found = 0;
00150 p->cid = 0;
00151 p->mpeg = 0;
00152 p->withbuf = wi;
00153
00154 if (p->withbuf && !p->buf){
00155 p->buf = malloc(MAX_PLENGTH*sizeof(uint8_t));
00156 memset(p->buf,0,MAX_PLENGTH*sizeof(uint8_t));
00157 } else if (rb) p->rbuf = rb;
00158 if (p->rbuf) p->ini_pos = ring_wpos(p->rbuf);
00159 p->done = 0;
00160 memset(p->pts, 0 , 5);
00161 memset(p->dts, 0 , 5);
00162 }
00163
00164
00165 void get_pes (pes_in_t *p, uint8_t *buf, int count, void (*func)(pes_in_t *p))
00166 {
00167
00168 int l;
00169 unsigned short *pl;
00170 int done;
00171
00172 uint8_t headr[3] = { 0x00, 0x00, 0x01} ;
00173 do {
00174 int c=0;
00175 done = 1;
00176 while (c < count && (!p->mpeg ||
00177 (p->mpeg == 2 && p->found < 9))
00178 && (p->found < 5 || !p->done)){
00179 switch ( p->found ){
00180 case 0:
00181 case 1:
00182 if (buf[c] == 0x00) p->found++;
00183 else p->found = 0;
00184 c++;
00185 break;
00186 case 2:
00187 if (buf[c] == 0x01) p->found++;
00188 else if (buf[c] == 0){
00189 p->found = 2;
00190 } else p->found = 0;
00191 c++;
00192 break;
00193 case 3:
00194 p->cid = 0;
00195 switch (buf[c]){
00196 case PROG_STREAM_MAP:
00197 case PRIVATE_STREAM2:
00198 case PROG_STREAM_DIR:
00199 case ECM_STREAM :
00200 case EMM_STREAM :
00201 case PADDING_STREAM :
00202 case DSM_CC_STREAM :
00203 case ISO13522_STREAM:
00204 p->done = 1;
00205 case PRIVATE_STREAM1:
00206 case VIDEO_STREAM_S ... VIDEO_STREAM_E:
00207 case AUDIO_STREAM_S ... AUDIO_STREAM_E:
00208 p->found++;
00209 p->cid = buf[c];
00210 c++;
00211 break;
00212 default:
00213 case PACK_START:
00214 case SYS_START:
00215 p->found = 0;
00216 c++;
00217 break;
00218 }
00219 break;
00220
00221
00222 case 4:
00223 if (count-c > 1){
00224 pl = (unsigned short *) (buf+c);
00225 p->plength = ntohs(*pl);
00226 p->plen[0] = buf[c];
00227 c++;
00228 p->plen[1] = buf[c];
00229 c++;
00230 p->found+=2;
00231 } else {
00232 p->plen[0] = buf[c];
00233 p->found++;
00234 return;
00235 }
00236 break;
00237 case 5:
00238 p->plen[1] = buf[c];
00239 c++;
00240 pl = (unsigned short *) p->plen;
00241 p->plength = ntohs(*pl);
00242 p->found++;
00243 break;
00244
00245
00246 case 6:
00247 if (!p->done){
00248 p->flag1 = buf[c];
00249 c++;
00250 p->found++;
00251 if ( (p->flag1 & 0xC0) == 0x80 ) p->mpeg = 2;
00252 else {
00253 LOG(VB_GENERAL, LOG_ERR,
00254 "Error: THIS IS AN MPEG1 FILE");
00255 exit(1);
00256 }
00257 }
00258 break;
00259
00260 case 7:
00261 if ( !p->done && p->mpeg == 2){
00262 p->flag2 = buf[c];
00263 c++;
00264 p->found++;
00265 }
00266 break;
00267
00268 case 8:
00269 if ( !p->done && p->mpeg == 2){
00270 p->hlength = buf[c];
00271 c++;
00272 p->found++;
00273 }
00274 break;
00275
00276 default:
00277
00278 break;
00279 }
00280 }
00281
00282 if (!p->plength) p->plength = MMAX_PLENGTH-6;
00283
00284
00285 if ( p->done || (p->mpeg == 2 && p->found >= 9) ){
00286 switch (p->cid){
00287
00288 case AUDIO_STREAM_S ... AUDIO_STREAM_E:
00289 case VIDEO_STREAM_S ... VIDEO_STREAM_E:
00290 case PRIVATE_STREAM1:
00291
00292 if (p->withbuf){
00293 memcpy(p->buf, headr, 3);
00294 p->buf[3] = p->cid;
00295 memcpy(p->buf+4,p->plen,2);
00296 } else {
00297 memcpy(p->hbuf, headr, 3);
00298 p->hbuf[3] = p->cid;
00299 memcpy(p->hbuf+4,p->plen,2);
00300 }
00301
00302 if (p->found == 9){
00303 if (p->withbuf){
00304 p->buf[6] = p->flag1;
00305 p->buf[7] = p->flag2;
00306 p->buf[8] = p->hlength;
00307 } else {
00308 p->hbuf[6] = p->flag1;
00309 p->hbuf[7] = p->flag2;
00310 p->hbuf[8] = p->hlength;
00311 }
00312 }
00313
00314 if ( (p->flag2 & PTS_ONLY) && p->found < 14){
00315 while (c < count && p->found < 14){
00316 p->pts[p->found-9] = buf[c];
00317 if (p->withbuf)
00318 p->buf[p->found] = buf[c];
00319 else
00320 p->hbuf[p->found] = buf[c];
00321 c++;
00322 p->found++;
00323 }
00324 if (c == count) return;
00325 }
00326
00327 if (((p->flag2 & PTS_DTS) == 0xC0) && p->found < 19){
00328 while (c < count && p->found < 19){
00329 p->dts[p->found-14] = buf[c];
00330 if (p->withbuf)
00331 p->buf[p->found] = buf[c];
00332 else
00333 p->hbuf[p->found] = buf[c];
00334 c++;
00335 p->found++;
00336 }
00337 if (c == count) return;
00338 }
00339
00340
00341 while (c < count && p->found < p->plength+6){
00342 l = count -c;
00343 if (l+p->found > p->plength+6)
00344 l = p->plength+6-p->found;
00345 if (p->withbuf)
00346 memcpy(p->buf+p->found, buf+c, l);
00347 else {
00348 if ( p->found <
00349 (unsigned int)p->hlength+9 ){
00350 int rest = p->hlength+9-p->found;
00351 memcpy(p->hbuf+p->found, buf+c, rest);
00352 if (ring_write(p->rbuf, buf+c+rest,
00353 l-rest) <0){
00354 exit(1);
00355 }
00356 } else {
00357 if (ring_write(p->rbuf, buf+c, l)<0){
00358 LOG(VB_GENERAL, LOG_ERR,
00359 "ring buffer overflow %d",
00360 p->rbuf->size);
00361 exit(1);
00362 }
00363 }
00364 }
00365
00366 p->found += l;
00367 c += l;
00368 }
00369 if(p->found == p->plength+6){
00370 func(p);
00371 }
00372 break;
00373 }
00374
00375 if ( p->done ){
00376 if( p->found + count - c < p->plength+6){
00377 p->found += count-c;
00378 c = count;
00379 } else {
00380 c += p->plength+6 - p->found;
00381 p->found = p->plength+6;
00382 }
00383 }
00384
00385 if (p->plength && p->found == p->plength+6) {
00386 init_pes_in(p, p->type, NULL, p->withbuf);
00387 if (c < count) {
00388 done = 0;
00389 count -= c;
00390 buf += c;
00391 }
00392 }
00393 }
00394 } while(!done);
00395 return;
00396 }
00397
00398
00399 static uint32_t scr_base_ps(uint8_t *scr)
00400 {
00401 uint32_t base = 0;
00402 uint8_t *buf = (uint8_t *)&base;
00403
00404 buf[0] |= (uint8_t)((scr[0] & 0x18) << 3);
00405 buf[0] |= (uint8_t)((scr[0] & 0x03) << 4);
00406 buf[0] |= (uint8_t)((scr[1] & 0xF0) >> 4);
00407
00408 buf[1] |= (uint8_t)((scr[1] & 0x0F) << 4);
00409 buf[1] |= (uint8_t)((scr[2] & 0xF0) >> 4);
00410
00411 buf[2] |= (uint8_t)((scr[2] & 0x08) << 4);
00412 buf[2] |= (uint8_t)((scr[2] & 0x03) << 5);
00413 buf[2] |= (uint8_t)((scr[3] & 0xF8) >> 3);
00414
00415 buf[3] |= (uint8_t)((scr[3] & 0x07) << 5);
00416 buf[3] |= (uint8_t)((scr[4] & 0xF8) >> 3);
00417
00418 base = ntohl(base);
00419 return base;
00420 }
00421
00422 static uint16_t scr_ext_ps(uint8_t *scr)
00423 {
00424 short ext = 0;
00425
00426 ext = (short)(scr[5] >> 1);
00427 ext += (short) (scr[4] & 0x03) * 128;
00428
00429 return ext;
00430 }
00431
00432
00433
00434 static void init_ps(ps_packet *p)
00435 {
00436 p->stuff_length=0xF8;
00437 p->data = NULL;
00438 p->sheader_length = 0;
00439 p->audio_bound = 0;
00440 p->video_bound = 0;
00441 p->npes = 0;
00442 }
00443
00444 static void kill_ps(ps_packet *p)
00445 {
00446 if (p->data)
00447 free(p->data);
00448 init_ps(p);
00449 }
00450
00451 static void setlength_ps(ps_packet *p)
00452 {
00453 short *ll;
00454 ll = (short *) p->sheader_llength;
00455 p->sheader_length = ntohs(*ll) - 6;
00456 }
00457
00458 static void setl_ps(ps_packet *p)
00459 {
00460 setlength_ps(p);
00461 p->data = (uint8_t *) malloc(p->sheader_length);
00462 }
00463
00464
00465 static int cwrite_ps(uint8_t *buf, ps_packet *p, uint32_t length)
00466 {
00467 long count,i;
00468 (void)length;
00469 uint8_t headr1[4] = {0x00, 0x00, 0x01, PACK_START };
00470 uint8_t headr2[4] = {0x00, 0x00, 0x01, SYS_START };
00471 uint8_t buffy = 0xFF;
00472
00473
00474 memcpy(buf,headr1,4);
00475 count = 4;
00476 memcpy(buf+count,p->scr,6);
00477 count += 6;
00478 memcpy(buf+count,p->mux_rate,3);
00479 count += 3;
00480 memcpy(buf+count,&p->stuff_length,1);
00481 count++;
00482 for(i=0; i< (p->stuff_length & 3); i++){
00483 memcpy(buf+count,&buffy,1);
00484 count++;
00485 }
00486
00487 if (p->sheader_length){
00488 memcpy(buf+count,headr2,4);
00489 count += 4;
00490 memcpy(buf+count,p->sheader_llength,2);
00491 count += 2;
00492 memcpy(buf+count,p->rate_bound,3);
00493 count += 3;
00494 memcpy(buf+count,&p->audio_bound,1);
00495 count++;
00496 memcpy(buf+count,&p->video_bound,1);
00497 count++;
00498 memcpy(buf+count,&p->reserved,1);
00499 count++;
00500 memcpy(buf+count,p->data,p->sheader_length);
00501 count += p->sheader_length;
00502 }
00503
00504 return count;
00505 }
00506
00507
00508
00509 static int write_ps_header(uint8_t *buf,
00510 uint64_t SCR,
00511 uint32_t muxr,
00512 uint8_t audio_bound,
00513 uint8_t fixed,
00514 uint8_t CSPS,
00515 uint8_t audio_lock,
00516 uint8_t video_lock,
00517 uint8_t video_bound,
00518 uint8_t navpack)
00519 {
00520 ps_packet p;
00521 uint8_t *scr;
00522 uint32_t lscr;
00523 uint16_t scr_ext = 0;
00524
00525 init_ps(&p);
00526
00527 lscr = htonl((uint32_t) ((SCR/300ULL) & 0x00000000FFFFFFFF));
00528 scr = (uint8_t *) 𝓁
00529 scr_ext = (uint16_t) ((SCR%300ULL) & 0x00000000000001FF);
00530
00531
00532 p.scr[0] = 0x44;
00533 p.scr[1] = 0x00;
00534 p.scr[2] = 0x04;
00535 p.scr[3] = 0x00;
00536 p.scr[4] = 0x04;
00537 p.scr[5] = 0x01;
00538
00539 p.scr[0] = 0x44 | ((scr[0] >> 3)&0x18) | ((scr[0] >> 4)&0x03);
00540 p.scr[1] = 0x00 | ((scr[0] << 4)&0xF0) | ((scr[1] >> 4)&0x0F);
00541 p.scr[2] = 0x04 | ((scr[1] << 4)&0xF0) | ((scr[2] >> 4)&0x08)
00542 | ((scr[2] >> 5)&0x03);
00543 p.scr[3] = 0x00 | ((scr[2] << 3)&0xF8) | ((scr[3] >> 5)&0x07);
00544 p.scr[4] = 0x04 | ((scr[3] << 3)&0xF8) | ((scr_ext >> 7)&0x03);
00545 p.scr[5] = 0x01 | ((scr_ext << 1)&0xFF);
00546
00547
00548 muxr = muxr/50;
00549 p.mux_rate[0] = (uint8_t)(muxr >> 14);
00550 p.mux_rate[1] = (uint8_t)(0xff & (muxr >> 6));
00551 p.mux_rate[2] = (uint8_t)(0x03 | ((muxr & 0x3f) << 2));
00552
00553 p.stuff_length = 0xF8;
00554
00555 if (navpack){
00556 p.sheader_llength[0] = 0x00;
00557 p.sheader_llength[1] = 0x12;
00558
00559 setl_ps(&p);
00560
00561 p.rate_bound[0] = (uint8_t)(0x80 | (muxr >>15));
00562 p.rate_bound[1] = (uint8_t)(0xff & (muxr >> 7));
00563 p.rate_bound[2] = (uint8_t)(0x01 | ((muxr & 0x7f)<<1));
00564
00565
00566 p.audio_bound = (uint8_t)((audio_bound << 2)|(fixed << 1)|CSPS);
00567 p.video_bound = (uint8_t)((audio_lock << 7)|
00568 (video_lock << 6)|0x20|video_bound);
00569 p.reserved = (uint8_t)(0xFF >> 1);
00570
00571 p.data[0] = 0xB9;
00572 p.data[1] = 0xE0;
00573 p.data[2] = 0xE8;
00574 p.data[3] = 0xB8;
00575 p.data[4] = 0xC0;
00576 p.data[5] = 0x20;
00577 p.data[6] = 0xbd;
00578 p.data[7] = 0xe0;
00579 p.data[8] = 0x3a;
00580 p.data[9] = 0xBF;
00581 p.data[10] = 0xE0;
00582 p.data[11] = 0x02;
00583
00584 cwrite_ps(buf, &p, PS_HEADER_L2);
00585 kill_ps(&p);
00586 return PS_HEADER_L2;
00587 } else {
00588 cwrite_ps(buf, &p, PS_HEADER_L1);
00589 kill_ps(&p);
00590 return PS_HEADER_L1;
00591 }
00592 }
00593
00594
00595 static void get_pespts(uint8_t *spts,uint8_t *pts)
00596 {
00597
00598 pts[0] = 0x01 |
00599 ((spts[0] & 0xC0) >>5);
00600 pts[1] = ((spts[0] & 0x3F) << 2) |
00601 ((spts[1] & 0xC0) >> 6);
00602 pts[2] = 0x01 | ((spts[1] & 0x3F) << 2) |
00603 ((spts[2] & 0x80) >> 6);
00604 pts[3] = ((spts[2] & 0x7F) << 1) |
00605 ((spts[3] & 0x80) >> 7);
00606 pts[4] = 0x01 | ((spts[3] & 0x7F) << 1);
00607 }
00608
00609 int write_pes_header(uint8_t id, int length , uint64_t PTS, uint64_t DTS,
00610 uint8_t *obuf, int stuffing, uint8_t ptsdts)
00611 {
00612 uint8_t le[2];
00613 uint8_t dummy[3];
00614 uint8_t *pts;
00615 uint8_t ppts[5];
00616 uint32_t lpts;
00617 uint8_t *dts;
00618 uint8_t pdts[5];
00619 uint32_t ldts;
00620 int c;
00621 uint8_t headr[3] = {0x00, 0x00, 0x01};
00622
00623 lpts = htonl((PTS/300ULL) & 0x00000000FFFFFFFFULL);
00624 pts = (uint8_t *) &lpts;
00625 get_pespts(pts,ppts);
00626 if ((PTS/300ULL) & 0x0000000100000000ULL) ppts[0] |= 0x80;
00627
00628 ldts = htonl((DTS/300ULL) & 0x00000000FFFFFFFFULL);
00629 dts = (uint8_t *) &ldts;
00630 get_pespts(dts,pdts);
00631 if ((DTS/300ULL) & 0x0000000100000000ULL) pdts[0] |= 0x80;
00632
00633 c = 0;
00634 memcpy(obuf+c,headr,3);
00635 c += 3;
00636 memcpy(obuf+c,&id,1);
00637 c++;
00638
00639 le[0] = 0;
00640 le[1] = 0;
00641 length -= 6;
00642
00643 le[0] |= ((uint8_t)(length >> 8) & 0xFF);
00644 le[1] |= ((uint8_t)(length) & 0xFF);
00645 memcpy(obuf+c,le,2);
00646 c += 2;
00647
00648 if (id == PADDING_STREAM){
00649 memset(obuf+c,0xff,length);
00650 c+= length;
00651 return c;
00652 }
00653
00654 dummy[0] = 0x80;
00655 dummy[1] = 0;
00656 dummy[2] = stuffing;
00657
00658 if (ptsdts == PTS_ONLY){
00659 dummy[2] += 5;
00660 dummy[1] |= PTS_ONLY;
00661 ppts[0] |= 0x20;
00662 } else if (ptsdts == PTS_DTS){
00663 dummy[2] += 10;
00664 dummy[1] |= PTS_DTS;
00665 ppts[0] |= 0x30;
00666 pdts[0] |= 0x10;
00667 }
00668
00669
00670 memcpy(obuf+c,dummy,3);
00671 c += 3;
00672
00673 if (ptsdts == PTS_ONLY){
00674 memcpy(obuf+c,ppts,5);
00675 c += 5;
00676 } else if ( ptsdts == PTS_DTS ){
00677 memcpy(obuf+c,ppts,5);
00678 c += 5;
00679 memcpy(obuf+c,pdts,5);
00680 c += 5;
00681 }
00682
00683 memset(obuf+c,0xFF,stuffing);
00684 c += stuffing;
00685
00686 return c;
00687 }
00688
00689 void write_padding_pes( int pack_size, int extcnt,
00690 uint64_t SCR, uint64_t muxr, uint8_t *buf)
00691 {
00692 int pos = 0;
00693
00694 pos = write_ps_header(buf,SCR,muxr, extcnt, 0, 0, 1, 1, 1,
00695 0);
00696
00697 pos += write_pes_header( PADDING_STREAM, pack_size-pos, 0, 0, buf+pos,
00698 0, 0);
00699
00700 }
00701
00702 int write_video_pes( int pack_size, int extcnt, uint64_t vpts,
00703 uint64_t vdts, uint64_t SCR, uint64_t muxr,
00704 uint8_t *buf, int *vlength,
00705 uint8_t ptsdts, ringbuffer *vrbuffer)
00706 {
00707 int add;
00708 int pos = 0;
00709 int p = 0;
00710 int stuff = 0;
00711 int length = *vlength;
00712
00713 if (! length) return 0;
00714 p = PS_HEADER_L1+PES_H_MIN;
00715
00716 if ( ptsdts == PTS_ONLY){
00717 p += 5;
00718 } else if (ptsdts == PTS_DTS){
00719 p += 10;
00720 }
00721
00722 if ( length+p >= pack_size){
00723 length = pack_size;
00724 } else {
00725 if (pack_size - length - p <= PES_MIN){
00726 stuff = pack_size - length-p;
00727 length = pack_size;
00728 } else
00729 length = length+p;
00730 }
00731
00732 pos = write_ps_header(buf,SCR,muxr, extcnt, 0, 0, 1, 1,
00733 1, 0);
00734
00735 pos += write_pes_header( 0xE0, length-pos, vpts, vdts, buf+pos,
00736 stuff, ptsdts);
00737 if (length-pos > *vlength){
00738 LOG(VB_GENERAL, LOG_ERR, "WHAT THE HELL %d > %d", length-pos,
00739 *vlength);
00740 }
00741
00742 add = ring_read( vrbuffer, buf+pos, length-pos);
00743 *vlength = add;
00744 if (add < 0) return -1;
00745 pos += add;
00746
00747 if (pos+PES_MIN < pack_size){
00748 pos += write_pes_header( PADDING_STREAM, pack_size-pos, 0, 0,
00749 buf+pos, 0, 0);
00750 pos = pack_size;
00751 }
00752 return pos;
00753 }
00754
00755 int write_audio_pes( int pack_size, int extcnt, int n, uint64_t pts,
00756 uint64_t SCR, uint32_t muxr, uint8_t *buf, int *alength,
00757 uint8_t ptsdts, ringbuffer *arbuffer)
00758 {
00759 int add;
00760 int pos = 0;
00761 int p = 0;
00762 int stuff = 0;
00763 int length = *alength;
00764
00765 if (!length) return 0;
00766 p = PS_HEADER_L1+PES_H_MIN;
00767
00768 if (ptsdts == PTS_ONLY){
00769 p += 5;
00770 }
00771
00772 if ( length+p >= pack_size){
00773 length = pack_size;
00774 } else {
00775 if (pack_size-length-p <= PES_MIN){
00776 stuff = pack_size - length-p;
00777 length = pack_size;
00778 } else
00779 length = length+p;
00780 }
00781 pos = write_ps_header(buf,SCR,muxr, extcnt, 0, 0, 1, 1,
00782 1, 0);
00783 pos += write_pes_header( 0xC0+n, length-pos, pts, 0, buf+pos, stuff,
00784 ptsdts);
00785 add = ring_read( arbuffer, buf+pos, length-pos);
00786 *alength = add;
00787 if (add < 0) return -1;
00788 pos += add;
00789
00790 if (pos+PES_MIN < pack_size){
00791 pos += write_pes_header( PADDING_STREAM, pack_size-pos, 0,0,
00792 buf+pos, 0, 0);
00793 pos = pack_size;
00794 }
00795 if (pos != pack_size) {
00796 LOG(VB_GENERAL, LOG_ERR, "apos: %d", pos);
00797 exit(1);
00798 }
00799
00800 return pos;
00801 }
00802
00803 int write_ac3_pes( int pack_size, int extcnt, int n,
00804 uint64_t pts, uint64_t SCR,
00805 uint32_t muxr, uint8_t *buf, int *alength, uint8_t ptsdts,
00806 int nframes,int ac3_off, ringbuffer *ac3rbuffer)
00807 {
00808 int add;
00809 int pos = 0;
00810 int p = 0;
00811 int stuff = 0;
00812 int length = *alength;
00813
00814 if (!length) return 0;
00815 p = PS_HEADER_L1+PES_H_MIN+4;
00816
00817 if (ptsdts == PTS_ONLY){
00818 p += 5;
00819 }
00820
00821 if ( length+p >= pack_size){
00822 length = pack_size;
00823 } else {
00824 if (pack_size-length-p <= PES_MIN){
00825 stuff = pack_size - length-p;
00826 length = pack_size;
00827 } else
00828 length = length+p;
00829 }
00830 pos = write_ps_header(buf,SCR,muxr, extcnt, 0, 0, 1, 1,
00831 1, 0);
00832
00833 pos += write_pes_header( PRIVATE_STREAM1, length-pos, pts, 0,
00834 buf+pos, stuff, ptsdts);
00835 buf[pos] = 0x80 + n;
00836 buf[pos+1] = nframes;
00837 buf[pos+2] = (ac3_off >> 8)& 0xFF;
00838 buf[pos+3] = (ac3_off)& 0xFF;
00839 pos += 4;
00840
00841 add = ring_read( ac3rbuffer, buf+pos, length-pos);
00842 *alength = add;
00843 if (add < 0) return -1;
00844 pos += add;
00845
00846 if (pos+PES_MIN < pack_size){
00847 pos += write_pes_header( PADDING_STREAM, pack_size-pos, 0,0,
00848 buf+pos, 0, 0);
00849 pos = pack_size;
00850 }
00851 if (pos != pack_size) {
00852 LOG(VB_GENERAL, LOG_ERR, "apos: %d", pos);
00853 exit(1);
00854 }
00855
00856 return pos;
00857 }
00858
00859 int write_nav_pack(int pack_size, int extcnt, uint64_t SCR, uint32_t muxr,
00860 uint8_t *buf)
00861 {
00862 int pos = 0;
00863 uint8_t headr[5] = {0x00, 0x00, 0x01, PRIVATE_STREAM2, 0x03 };
00864 (void)pack_size;
00865
00866 pos = write_ps_header( buf, SCR, muxr, extcnt, 0, 0, 1, 1, 1, 1);
00867 memcpy(buf+pos, headr, 5);
00868 buf[pos+5] = 0xD4;
00869 pos += 6;
00870 memset(buf+pos, 0, 0x03d4);
00871 pos += 0x03d4;
00872
00873 memcpy(buf+pos, headr, 5);
00874 buf[pos+5] = 0xFA;
00875 pos += 6;
00876 memset(buf+pos, 0, 0x03fA);
00877 pos += 0x03fA;
00878
00879 return pos;
00880 }