|
MythTV
0.25-pre
|
00001 /* 00002 * pes.c: MPEG PES functions for replex 00003 * 00004 * 00005 * Copyright (C) 2003 Marcus Metzler <mocm@metzlerbros.de> 00006 * Metzler Brothers Systementwicklung GbR 00007 * Changes to use MythTV logging 00008 * Copyright (C) 2011 Gavin Hurlbut <ghurlbut@mythtv.org> 00009 * 00010 * This program is free software; you can redistribute it and/or 00011 * modify it under the terms of the GNU General Public License 00012 * as published by the Free Software Foundation; either version 2 00013 * of the License, or (at your option) any later version. 00014 * 00015 * 00016 * This program is distributed in the hope that it will be useful, 00017 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00019 * General Public License for more details. 00020 * 00021 * 00022 * You should have received a copy of the GNU General Public License 00023 * along with this program; if not, write to the Free Software 00024 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 00025 * Or, point your browser to http://www.gnu.org/copyleft/gpl.html 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 /* use if you know that ptss are close and may overflow */ 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 /* use, if you need an unsigned result in pts range */ 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 // SCR = 0 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 //Make sure to set the 1st 4 bits properly 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 }
1.7.6.1