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