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 <getopt.h>
00031 #include <stdio.h>
00032 #include <stdint.h>
00033 #include <sys/types.h>
00034 #include <sys/stat.h>
00035 #include <fcntl.h>
00036 #include <string.h>
00037 #include <unistd.h>
00038
00039 #include "replex.h"
00040 #include "pes.h"
00041
00042 #include "avcodec.h"
00043 #include "avformat.h"
00044
00045 #ifdef USING_MINGW
00046 # define S_IRGRP 0
00047 # define S_IWGRP 0
00048 # define S_IROTH 0
00049 # define S_IWOTH 0
00050 #endif
00051
00052 #ifndef O_LARGEFILE
00053 #define O_LARGEFILE 0
00054 #endif
00055
00056 static int replex_all_set(struct replex *rx);
00057
00058 int replex_check_id(struct replex *rx, uint16_t id)
00059 {
00060 int i;
00061
00062 if (id==rx->vpid)
00063 return 0;
00064
00065 for (i=0; i<rx->apidn; i++)
00066 if (id==rx->apid[i])
00067 return i+1;
00068
00069 for (i=0; i<rx->ac3n; i++)
00070 if (id==rx->ac3_id[i])
00071 return i+0x80;
00072
00073 return -1;
00074 }
00075
00076 int encode_mp2_audio(audio_frame_t *aframe, uint8_t *buffer, int bufsize)
00077 {
00078 AVCodec *codec;
00079 AVCodecContext *c= NULL;
00080 int frame_size, j, out_size;
00081 short *samples;
00082
00083 fprintf(stderr, "encoding an MP2 audio frame\n");
00084
00085
00086 codec = avcodec_find_encoder(CODEC_ID_MP2);
00087 if (!codec) {
00088 fprintf(stderr, "codec not found\n");
00089 return 1;
00090 }
00091
00092 c = avcodec_alloc_context();
00093
00094
00095 c->bit_rate = aframe->bit_rate;
00096 c->sample_rate = aframe->frequency;
00097 c->channels = 2;
00098
00099
00100 if (avcodec_open(c, codec) < 0) {
00101 fprintf(stderr, "could not open codec\n");
00102 av_free(c);
00103 return 1;
00104 }
00105
00106
00107 frame_size = c->frame_size;
00108 samples = malloc(frame_size * 2 * c->channels);
00109
00110
00111 for (j=0;j<frame_size;j++) {
00112 samples[2*j] = 0;
00113 samples[2*j+1] = 0;
00114 }
00115
00116
00117 out_size = avcodec_encode_audio(c, buffer, bufsize, samples);
00118
00119 if (out_size != bufsize) {
00120 fprintf(stderr, "frame size (%d) does not equal required size (%d)?\n",
00121 out_size, bufsize);
00122 free(samples);
00123 avcodec_close(c);
00124 av_free(c);
00125 return 1;
00126 }
00127
00128 free(samples);
00129 avcodec_close(c);
00130 av_free(c);
00131
00132 return 0;
00133 }
00134
00135 void analyze_audio( pes_in_t *p, struct replex *rx, int len, int num, int type)
00136 {
00137 int c=0;
00138 int pos=0;
00139 audio_frame_t *aframe = NULL;
00140 index_unit *iu = NULL;
00141 ringbuffer *rbuf = NULL, *index_buf = NULL;
00142 uint64_t *acount=NULL;
00143 uint64_t *fpts=NULL;
00144 uint64_t *lpts=NULL;
00145 int bsize = 0;
00146 int first = 1;
00147 uint8_t buf[7];
00148 int off=0;
00149 int *apes_abort=NULL;
00150 int re=0;
00151
00152 switch ( type ){
00153 case AC3:
00154 #ifdef IN_DEBUG
00155 fprintf(stderr, "AC3\n");
00156 #endif
00157 aframe = &rx->ac3frame[num];
00158 iu = &rx->current_ac3index[num];
00159 rbuf = &rx->ac3rbuffer[num];
00160 index_buf = &rx->index_ac3rbuffer[num];
00161 acount = &rx->ac3frame_count[num];
00162 fpts = &rx->first_ac3pts[num];
00163 lpts = &rx->last_ac3pts[num];
00164 bsize = rx->ac3buf;
00165 apes_abort = &rx->ac3pes_abort[num];
00166 break;
00167
00168 case MPEG_AUDIO:
00169 #ifdef IN_DEBUG
00170 fprintf(stderr, "MPEG AUDIO\n");
00171 #endif
00172 aframe = &rx->aframe[num];
00173 iu = &rx->current_aindex[num];
00174 rbuf = &rx->arbuffer[num];
00175 index_buf = &rx->index_arbuffer[num];
00176 acount = &rx->aframe_count[num];
00177 fpts = &rx->first_apts[num];
00178 lpts = &rx->last_apts[num];
00179 bsize = rx->audiobuf;
00180 apes_abort = &rx->apes_abort[num];
00181 break;
00182 }
00183
00184 *apes_abort = 0;
00185 off = ring_rdiff(rbuf, p->ini_pos);
00186 while (c < len){
00187 if ( (pos = find_audio_sync(rbuf, buf, c+off, type, len-c) )
00188 >= 0 ){
00189 if (!aframe->set){
00190 switch( type ){
00191 case AC3:
00192 re = get_ac3_info(rbuf, aframe,
00193 pos+c+off,
00194 len-c-pos);
00195 break;
00196 case MPEG_AUDIO:
00197 re = get_audio_info(rbuf, aframe,
00198 pos+c+off,
00199 len-c-pos);
00200 break;
00201 }
00202 if ( re == -2){
00203 *apes_abort = len -c;
00204 return;
00205 }
00206 if (re < 0) return;
00207
00208
00209 if (!rx->ignore_pts){
00210 if ((p->flag2 & PTS_ONLY)){
00211 *fpts = trans_pts_dts(p->pts);
00212 fprintf(stderr,
00213 "starting audio PTS: ");
00214 printpts(*fpts);
00215 fprintf(stderr,"\n");
00216 } else aframe->set = 0;
00217 }
00218
00219 if (aframe->set && first)
00220 ring_skip(rbuf,pos+c);
00221
00222 } else {
00223 int diff = ring_posdiff(rbuf, iu->start,
00224 p->ini_pos + pos+c);
00225
00226 if ( (re = check_audio_header(rbuf, aframe,
00227 pos+c+off,len-c-pos,
00228 type)) < 0){
00229
00230 if ( re == -2){
00231 *apes_abort = len -c;
00232 return;
00233 }
00234
00235 if ((int) aframe->framesize > diff){
00236 if ( re == -3){
00237 c += pos+1;
00238 continue;
00239 }
00240
00241 c += pos+2;
00242 #ifdef IN_DEBUG
00243 fprintf(stderr,"WRONG HEADER1 %d\n", diff);
00244 #endif
00245 continue;
00246 }
00247 }
00248 if ((int) aframe->framesize > diff){
00249 c += pos+2;
00250
00251 continue;
00252 }
00253 }
00254
00255
00256 if (aframe->set && rx->fix_sync && first && type == MPEG_AUDIO){
00257 int frame_time = aframe->frametime;
00258 int64_t diff;
00259 diff = ptsdiff(trans_pts_dts(p->pts), add_pts_audio(0, aframe,*acount + 1) + *fpts);
00260 if (abs ((int)diff) >= frame_time){
00261 fprintf(stderr,"fixing audio PTS inconsistency - diff: ");
00262 printpts(abs(diff));
00263
00264 if (diff < 0){
00265 diff = abs(diff);
00266 int framesdiff = diff / frame_time;
00267 fprintf(stderr, " - need to remove %d frame(s)\n", framesdiff);
00268
00269
00270 if (framesdiff > 1)
00271 framesdiff = 1;
00272 iu->pts = add_pts_audio(0, aframe, -framesdiff);
00273 c += aframe->framesize;
00274 continue;
00275 } else {
00276 int framesdiff = diff / frame_time;
00277 fprintf(stderr, " - need to add %d frame(s)\n", framesdiff);
00278
00279
00280 if (framesdiff > 5)
00281 framesdiff = 5;
00282
00283
00284 uint8_t *framebuf;
00285 if ( !(framebuf = (uint8_t *) malloc(sizeof(uint8_t) * aframe->framesize))) {
00286 fprintf(stderr,"Not enough memory for audio frame\n");
00287 exit(1);
00288 }
00289
00290
00291 if (encode_mp2_audio(aframe, framebuf, sizeof(uint8_t) * aframe->framesize) != 0) {
00292
00293 int res;
00294 res = ring_peek(rbuf, framebuf, aframe->framesize, 0);
00295 if (res != (int) aframe->framesize) {
00296 fprintf(stderr,"ring buffer failed to peek frame res: %d\n", res);
00297 exit(1);
00298 }
00299 }
00300
00301
00302 int x;
00303 for (x = 0; x < framesdiff; x++){
00304 if (type == AC3){
00305 if (rx->dmx_out[num+1+rx->apidn])
00306 write(rx->dmx_out[num+1+rx->apidn], framebuf, aframe->framesize);
00307 }else{
00308 if (rx->dmx_out[num+1])
00309 write(rx->dmx_out[num+1], framebuf, aframe->framesize);
00310 }
00311 *acount += 1;
00312 }
00313
00314 free(framebuf);
00315 }
00316 }
00317 }
00318
00319 if (aframe->set){
00320 if(iu->active){
00321 iu->length = ring_posdiff(rbuf,
00322 iu->start,
00323 p->ini_pos +
00324 pos+c);
00325
00326 if (iu->length < aframe->framesize ||
00327 iu->length > aframe->framesize+1){
00328 fprintf(stderr,"Wrong audio frame size: %d\n", iu->length);
00329 iu->err= FRAME_ERR;
00330 }
00331 if (ring_write(index_buf,
00332 (uint8_t *)iu,
00333 sizeof(index_unit)) < 0){
00334 fprintf(stderr,"audio ring buffer overrun error\n");
00335 exit(1);
00336 }
00337 *acount += 1;
00338 }
00339
00340 init_index(iu);
00341 iu->active = 1;
00342 iu->pts = add_pts_audio(0, aframe,*acount);
00343 iu->framesize = aframe->framesize;
00344
00345 if (!rx->ignore_pts &&
00346 first && (p->flag2 & PTS_ONLY)){
00347 int64_t diff;
00348
00349 diff = ptsdiff(trans_pts_dts(p->pts),
00350 iu->pts + *fpts);
00351 if( !rx->keep_pts && abs ((int)diff) > 40*CLOCK_MS){
00352 fprintf(stderr,"audio PTS inconsistent: ");
00353 printpts(trans_pts_dts(p->pts)-*fpts);
00354 printpts(iu->pts);
00355 fprintf(stderr,"diff: ");
00356 printpts(abs(diff));
00357 fprintf(stderr,"\n");
00358 }
00359 if (rx->keep_pts){
00360 fix_audio_count(acount, aframe,
00361 uptsdiff(trans_pts_dts(
00362 p->pts),
00363 *fpts),
00364 iu->pts);
00365 iu->pts = uptsdiff(trans_pts_dts(p->pts),
00366 *fpts);
00367 if (*lpts && ptsdiff(iu->pts,*lpts)<0)
00368 fprintf(stderr,
00369 "Warning negative audio PTS increase!\n");
00370 *lpts = iu->pts;
00371 }
00372 first = 0;
00373 }
00374 if (rx->analyze >1){
00375 if ((p->flag2 & PTS_ONLY)){
00376 iu->pts = trans_pts_dts(p->pts);
00377 } else {
00378 iu->pts = 0;
00379 }
00380 }
00381 iu->start = (p->ini_pos+pos+c)%bsize;
00382 }
00383 c += pos;
00384 if (c + (int) aframe->framesize > len){
00385
00386 c = len;
00387 } else {
00388 c += aframe->framesize;
00389 }
00390 } else {
00391 *apes_abort = len-c;
00392 c=len;
00393 }
00394 }
00395 }
00396
00397 void analyze_video( pes_in_t *p, struct replex *rx, int len)
00398 {
00399 uint8_t buf[8];
00400 int c=0;
00401 int pos=0;
00402 uint8_t head;
00403 int seq_end = 0;
00404 uint8_t frame = 0;
00405 uint64_t newpts = 0;
00406 uint64_t newdts = 0;
00407 index_unit *iu;
00408 int off=0;
00409 ringbuffer *rbuf;
00410 ringbuffer *index_buf;
00411 sequence_t *s;
00412 int i;
00413
00414 uint16_t tempref = 0;
00415 int seq_h = 0;
00416 int gop = 0;
00417 int frame_off = 0;
00418 int gop_off = 0;
00419 int seq_p = 0;
00420 int flush=0;
00421
00422 rbuf = &rx->vrbuffer;
00423 index_buf = &rx->index_vrbuffer;
00424 iu = &rx->current_vindex;
00425 s = &rx->seq_head;
00426
00427 rx->vpes_abort = 0;
00428 off = ring_rdiff(rbuf, p->ini_pos);
00429 #ifdef IN_DEBUG
00430 fprintf(stderr, " ini pos %d\n",
00431 (p->ini_pos)%rx->videobuf);
00432 #endif
00433
00434
00435
00436 while (c < len){
00437 if ((pos = ring_find_any_header( rbuf, &head, c+off, len-c))
00438 >=0 ){
00439 switch(head){
00440 case SEQUENCE_HDR_CODE:
00441 #ifdef IN_DEBUG
00442 fprintf(stderr, " seq headr %d\n",
00443 (p->ini_pos+c+pos)%rx->videobuf);
00444 #endif
00445
00446 seq_h = 1;
00447 seq_p = c+pos;
00448
00449
00450 if (!s->set){
00451 int re=0;
00452 re = get_video_info(rbuf, &rx->seq_head,
00453 pos+c+off, len -c -pos);
00454
00455 #ifdef IN_DEBUG
00456 fprintf(stderr, " seq headr result %d\n",re);
00457 #endif
00458 if (re == -2){
00459 rx->vpes_abort = len -(c+pos-1);
00460 return;
00461 }
00462 if (s->set){
00463 ring_skip(rbuf, pos+c);
00464 off -= pos+c;
00465 }
00466 if (!rx->ignore_pts &&
00467 !(p->flag2 & PTS_ONLY)) s->set = 0;
00468 }
00469 if (s->set){
00470 flush = 1;
00471 }
00472 break;
00473
00474 case EXTENSION_START_CODE:{
00475 int ext_id = 0;
00476
00477 #ifdef IN_DEBUG
00478 fprintf(stderr," seq ext headr %d\n",
00479 (p->ini_pos+c+pos)+rx->videobuf);
00480 #endif
00481 ext_id = get_video_ext_info(rbuf,
00482 &rx->seq_head,
00483 pos+c+off,
00484 len -c -pos);
00485 if (ext_id == -2){
00486 rx->vpes_abort = len - (pos-1+c);
00487 return;
00488 }
00489
00490
00491 if(ext_id == PICTURE_CODING_EXTENSION
00492 && s->ext_set && iu->active){
00493 if (!rx->ignore_pts &&
00494 !rx->vframe_count &&
00495 !rx->first_vpts){
00496 rx->first_vpts = trans_pts_dts(
00497 p->pts);
00498
00499 for (i = 0; i< s->current_tmpref;
00500 i++) ptsdec(&rx->first_vpts,
00501 SEC_PER);
00502 fprintf(stderr,"starting with video PTS: ");
00503 printpts(rx->first_vpts);
00504 fprintf(stderr,"\n");
00505 }
00506
00507 newpts = 0;
00508 #ifdef IN_DEBUG
00509
00510 fprintf(stderr,"fcount %d gcount %d tempref %d %d\n",
00511 (int)rx->vframe_count, (int)rx->vgroup_count,
00512 (int)s->current_tmpref,
00513 (int)(s->current_tmpref - rx->vgroup_count
00514 + rx->vframe_count));
00515 #endif
00516 newdts = next_ptsdts_video(
00517 &newpts,s, rx->vframe_count,
00518 rx->vgroup_count);
00519
00520 if (!rx->ignore_pts &&
00521 (p->flag2 & PTS_ONLY)){
00522 int64_t diff;
00523
00524 diff = ptsdiff(iu->pts,
00525 rx->first_vpts
00526 + newpts);
00527
00528 if (!rx->keep_pts &&
00529 abs((int)(diff)) > 3*SEC_PER/2){
00530 fprintf(stderr,"video PTS inconsistent: ");
00531 printpts(trans_pts_dts(p->pts));
00532 printpts(iu->pts);
00533 printpts(newpts+rx->first_vpts);
00534 printpts(newpts);
00535 fprintf(stderr," diff: ");
00536 printpts(abs((int)diff));
00537 fprintf(stderr,"\n");
00538 }
00539 }
00540
00541 if (!rx->ignore_pts &&
00542 (p->flag2 & PTS_DTS) == PTS_DTS){
00543 uint64_t diff;
00544 diff = ptsdiff(iu->dts,
00545 newdts +
00546 rx->first_vpts);
00547 if (!rx->keep_pts &&
00548 abs((int)diff) > 3*SEC_PER/2){
00549 fprintf(stderr,"video DTS inconsistent: ");
00550 printpts(trans_pts_dts(p->dts));
00551 printpts(iu->dts);
00552 printpts(newdts+rx->first_vpts);
00553 printpts(newdts);
00554 fprintf(stderr,"diff: ");
00555 printpts(abs((int)diff));
00556 fprintf(stderr,"\n");
00557 }
00558 }
00559 if (!rx->keep_pts){
00560 iu->pts = newpts;
00561 iu->dts = newdts;
00562 } else {
00563 if (p->flag2 & PTS_DTS){
00564 ptsdec(&iu->pts,
00565 rx->first_vpts);
00566
00567 if ((p->flag2 & PTS_DTS) == PTS_DTS){
00568 ptsdec(&iu->dts,
00569 rx->first_vpts);
00570 } else iu->dts = newdts;
00571
00572 fix_video_count(s,&rx->vframe_count,
00573 iu->pts,newpts,
00574 iu->dts,newdts);
00575
00576 } else {
00577 iu->pts = newpts;
00578 iu->dts = newdts;
00579 }
00580 }
00581 if (rx->last_vpts &&
00582 ptsdiff(iu->dts, rx->last_vpts) <0)
00583 fprintf(stderr,
00584 "Warning negative video PTS increase!\n");
00585 rx->last_vpts = iu->dts;
00586 }
00587
00588 if (rx->analyze){
00589 if ((p->flag2 & PTS_DTS) == PTS_DTS){
00590 iu->pts = trans_pts_dts(p->pts);
00591 iu->dts = trans_pts_dts(p->dts);
00592 } else if (p->flag2 & PTS_ONLY){
00593 iu->pts = trans_pts_dts(p->pts);
00594 iu->dts = 0;
00595 } else {
00596 iu->pts = 0;
00597 iu->dts = 0;
00598 }
00599 }
00600
00601
00602 break;
00603 }
00604
00605 case SEQUENCE_END_CODE:
00606 #ifdef IN_DEBUG
00607 fprintf(stderr, " seq end %d\n",
00608 (p->ini_pos+c+pos)%rx->videobuf);
00609 #endif
00610 if (s->set)
00611 seq_end = 1;
00612
00613 break;
00614
00615 case GROUP_START_CODE:{
00616 int hour, min, sec;
00617
00618 #ifdef ANA
00619 fprintf(stderr," %d", (int)rx->vgroup_count);
00620 fprintf(stderr,"\n");
00621
00622 #endif
00623 if (s->set){
00624 if (!seq_h) flush = 1;
00625 }
00626 gop = 1;
00627 gop_off = c+pos - seq_p;
00628
00629 if (ring_peek(rbuf, (uint8_t *) buf, 7,
00630 off+c+pos) < 0){
00631 rx->vpes_abort = len -(c+pos-1);
00632 return;
00633 }
00634 hour = (int)((buf[4]>>2)& 0x1F);
00635 min = (int)(((buf[4]<<4)& 0x30)|
00636 ((buf[5]>>4)& 0x0F));
00637 sec = (int)(((buf[5]<<3)& 0x38)|
00638 ((buf[6]>>5)& 0x07));
00639 #ifdef IN_DEBUG
00640 fprintf(stderr, " gop %02d:%02d.%02d %d\n",
00641 hour,min,sec,
00642 (p->ini_pos+c+pos)%rx->videobuf);
00643 #endif
00644 rx->vgroup_count = 0;
00645
00646 break;
00647 }
00648
00649 case PICTURE_START_CODE:{
00650 if (len-(c+pos) < 14){
00651 rx->vpes_abort = len - (pos-1+c);
00652 return;
00653 }
00654
00655 if (ring_peek(rbuf, (uint8_t *) buf, 6,
00656 off+c+pos) < 0) return;
00657
00658
00659 frame = ((buf[5]&0x38) >>3);
00660
00661 if (frame == I_FRAME){
00662 if( !rx->first_iframe){
00663 if (s->set){
00664 rx->first_iframe = 1;
00665 } else {
00666 s->set=0;
00667 flush = 0;
00668 break;
00669 }
00670 }
00671 }
00672
00673 frame_off = c+pos - seq_p;
00674 if (s->set){
00675 if (!seq_h && !gop) flush = 1;
00676 }
00677 tempref = (buf[5]>>6) & 0x03;
00678 tempref |= buf[4] << 2;
00679
00680 switch (frame){
00681 case I_FRAME:
00682 #ifdef ANA
00683 fprintf(stderr,"I");
00684 #endif
00685 #ifdef IN_DEBUG
00686 fprintf(stderr, " I-frame %d\n",
00687 (p->ini_pos+c+pos)%rx->videobuf);
00688 #endif
00689 break;
00690 case B_FRAME:
00691 #ifdef ANA
00692 fprintf(stderr,"B");
00693 #endif
00694 #ifdef IN_DEBUG
00695 fprintf(stderr, " B-frame %d\n",
00696 (p->ini_pos+c+pos)%rx->videobuf);
00697 #endif
00698 break;
00699 case P_FRAME:
00700 #ifdef ANA
00701 fprintf(stderr,"P");
00702 #endif
00703 #ifdef IN_DEBUG
00704 fprintf(stderr, " P-frame %d\n",
00705 (p->ini_pos+c+pos)%rx->videobuf);
00706 #endif
00707 break;
00708 }
00709 s->current_frame = frame;
00710 s->current_tmpref = tempref;
00711
00712 break;
00713 }
00714 default:
00715 #ifdef IN_DEBUG
00716
00717 #endif
00718 break;
00719 }
00720
00721 if (flush && s->set && rx->first_iframe){
00722 if(iu->active){
00723 rx->vframe_count++;
00724 rx->vgroup_count++;
00725
00726 iu->length = ring_posdiff(rbuf,
00727 iu->start,
00728 p->ini_pos+
00729 pos+c-frame_off);
00730
00731 if ( ring_write(index_buf, (uint8_t *)
00732 &rx->current_vindex,
00733 sizeof(index_unit))<0){
00734 fprintf(stderr,"video ring buffer overrun error\n");
00735 exit(1);
00736
00737 }
00738 }
00739 init_index(&rx->current_vindex);
00740 flush = 0;
00741 iu->active = 1;
00742 if (!rx->ignore_pts){
00743 if ((p->flag2 & PTS_DTS) == PTS_DTS){
00744 iu->pts = trans_pts_dts(p->pts);
00745 iu->dts = trans_pts_dts(p->dts);
00746 } else if (p->flag2 & PTS_ONLY){
00747 iu->pts = trans_pts_dts(p->pts);
00748 }
00749 }
00750 iu->start = (p->ini_pos+pos+c-frame_off)
00751 %rx->videobuf;
00752 #ifdef IN_DEBUG
00753 fprintf(stderr,"START %d\n", iu->start);
00754 #endif
00755 }
00756
00757 if (s->set){
00758 if (frame)
00759 iu->frame = (frame&0xFF);
00760 if (seq_h)
00761 iu->seq_header = 1;
00762 if (seq_end)
00763 iu->seq_end = 1;
00764 if (gop)
00765 iu->gop = 1;
00766 if (gop_off)
00767 iu->gop_off = gop_off;
00768 if (frame_off)
00769 iu->frame_off = frame_off;
00770 }
00771 c+=pos+4;
00772 } else {
00773 if (pos == -2){
00774 rx->vpes_abort = 4;
00775
00776 }
00777 c = len;
00778 }
00779 }
00780 }
00781
00782 void es_out(pes_in_t *p)
00783 {
00784
00785 struct replex *rx;
00786 char t[80];
00787 int len;
00788
00789 len = p->plength-3-p->hlength;
00790
00791 rx = (struct replex *) p->priv;
00792
00793 switch(p->type)
00794 {
00795 case 0xE0: {
00796 sprintf(t, "Video ");
00797 if (rx->vpes_abort){
00798 p->ini_pos = (p->ini_pos - rx->vpes_abort)%rx->vrbuffer.size;
00799 len += rx->vpes_abort;
00800 }
00801 analyze_video(p, rx, len);
00802 if (!rx->seq_head.set){
00803 ring_skip(&rx->vrbuffer, len);
00804 }
00805 break;
00806 }
00807
00808 case 1 ... 32:{
00809 int l;
00810 l = p->type - 1;
00811 sprintf(t, "Audio%d ", l);
00812 if (rx->apes_abort[l]){
00813 p->ini_pos = (p->ini_pos - rx->apes_abort[l])
00814 %rx->arbuffer[l].size;
00815 len += rx->apes_abort[l];
00816 }
00817 analyze_audio(p, rx, len, l, MPEG_AUDIO);
00818 if (!rx->aframe[l].set)
00819 ring_skip(&rx->arbuffer[l], len);
00820
00821 break;
00822 }
00823
00824 case 0x80 ... 0x87:{
00825 int l;
00826 l = p->type - 0x80;
00827 sprintf(t, "AC3 %d ", p->type);
00828 if (rx->ac3pes_abort[l]){
00829 p->ini_pos = (p->ini_pos - rx->ac3pes_abort[l])
00830 %rx->ac3rbuffer[l].size;
00831 len += rx->ac3pes_abort[l];
00832 }
00833 analyze_audio(p, rx, len, l, AC3);
00834 if (!rx->ac3frame[l].set)
00835 ring_skip(&rx->ac3rbuffer[l], len);
00836 break;
00837 }
00838
00839 default:
00840 return;
00841
00842
00843 }
00844
00845 #ifdef IN_DEBUG
00846 fprintf(stderr,"%s PES\n", t);
00847 #endif
00848 }
00849
00850 void pes_es_out(pes_in_t *p)
00851 {
00852
00853 struct replex *rx;
00854 char t[80];
00855 int len, i;
00856 int l=0;
00857
00858 len = p->plength-3-p->hlength;
00859 rx = (struct replex *) p->priv;
00860
00861 switch(p->cid){
00862 case VIDEO_STREAM_S ... VIDEO_STREAM_E:
00863 if (rx->vpid != p->cid) break;
00864 p->type = 0xE0;
00865 p->ini_pos = ring_wpos(&rx->vrbuffer);
00866
00867 if (ring_write(&rx->vrbuffer, p->buf+9+p->hlength, len)<0){
00868 fprintf(stderr,"video ring buffer overrun error\n");
00869 exit(1);
00870 }
00871 if (rx->vpes_abort){
00872 p->ini_pos = (p->ini_pos - rx->vpes_abort)%rx->vrbuffer.size;
00873 len += rx->vpes_abort;
00874 }
00875 sprintf(t, "Video ");
00876 analyze_video(p, rx, len);
00877 if (!rx->seq_head.set){
00878 ring_skip(&rx->vrbuffer, len);
00879 }
00880 break;
00881
00882 case AUDIO_STREAM_S ... AUDIO_STREAM_E:
00883 p->type = p->cid - 0xc0 + 1;
00884 l = -1;
00885 for (i=0; i<rx->apidn; i++)
00886 if (p->cid == rx->apid[i])
00887 l = i;
00888 if (l < 0) break;
00889 p->ini_pos = ring_wpos(&rx->arbuffer[l]);
00890 if (ring_write(&rx->arbuffer[l], p->buf+9+p->hlength, len)<0){
00891 fprintf(stderr,"video ring buffer overrun error\n");
00892 exit(1);
00893 }
00894 if (rx->apes_abort[l]){
00895 p->ini_pos = (p->ini_pos - rx->apes_abort[l])
00896 %rx->arbuffer[l].size;
00897 len += rx->apes_abort[l];
00898 }
00899
00900 sprintf(t, "Audio%d ", l);
00901 analyze_audio(p, rx, len, l, MPEG_AUDIO);
00902 if (!rx->aframe[l].set)
00903 ring_skip(&rx->arbuffer[l], len);
00904
00905 break;
00906
00907 case PRIVATE_STREAM1:{
00908 int hl=4;
00909 if (rx->vdr){
00910 hl=0;
00911 p->type=0x80;
00912 l = 0;
00913 } else {
00914 uint16_t fframe;
00915
00916 fframe=0;
00917 fframe = p->buf[9+p->hlength+3];
00918 fframe |= (p->buf[9+p->hlength+2]<<8);
00919
00920 if (fframe > p->plength) break;
00921
00922 p->type = p->buf[9+p->hlength];
00923 l = -1;
00924 for (i=0; i<rx->ac3n; i++)
00925 if (p->type == rx->ac3_id[i])
00926 l = i;
00927 if (l < 0) break;
00928 }
00929 len -= hl;
00930 p->ini_pos = ring_wpos(&rx->ac3rbuffer[l]);
00931
00932 if (ring_write(&rx->ac3rbuffer[l], p->buf+9+hl+p->hlength, len)<0){
00933 fprintf(stderr,"video ring buffer overrun error\n");
00934 exit(1);
00935 }
00936 if (rx->ac3pes_abort[l]){
00937 p->ini_pos = (p->ini_pos - rx->ac3pes_abort[l])
00938 %rx->ac3rbuffer[l].size;
00939 len += rx->ac3pes_abort[l];
00940 }
00941
00942 sprintf(t, "AC3 %d ", p->type);
00943 analyze_audio(p, rx, len, l, AC3);
00944 sprintf(t,"%d",rx->ac3frame[l].set);
00945 if (!rx->ac3frame[l].set)
00946 ring_skip(&rx->ac3rbuffer[l], len);
00947 }
00948 break;
00949
00950 default:
00951 return;
00952 }
00953
00954 #ifdef IN_DEBUG
00955 fprintf(stderr,"%s PES %d\n", t,len);
00956 #endif
00957 }
00958
00959 void avi_es_out(pes_in_t *p)
00960 {
00961
00962 struct replex *rx;
00963 char t[80];
00964 int len;
00965
00966 len = p->plength;
00967
00968 rx = (struct replex *) p->priv;
00969
00970
00971 switch(p->type)
00972 {
00973 case 0xE0: {
00974 sprintf(t, "Video ");
00975 if (!len){
00976 rx->vframe_count++;
00977 break;
00978 }
00979 analyze_video(p, rx, len);
00980 if (!rx->seq_head.set){
00981 ring_skip(&rx->vrbuffer, len);
00982 }
00983 break;
00984 }
00985
00986 case 1 ... 32:{
00987 int l;
00988 l = p->type - 1;
00989 sprintf(t, "Audio%d ", l);
00990 if (!len){
00991 rx->aframe_count[l]++;
00992 break;
00993 }
00994 analyze_audio(p, rx, len, l, MPEG_AUDIO);
00995 if (!rx->aframe[l].set)
00996 ring_skip(&rx->arbuffer[l], len);
00997
00998 break;
00999 }
01000
01001 case 0x80 ... 0x87:{
01002 int l;
01003
01004 l = p->type - 0x80;
01005 sprintf(t, "AC3 %d ", p->type);
01006 if (!len){
01007 rx->ac3frame_count[l]++;
01008 break;
01009 }
01010 analyze_audio(p, rx, len, l, AC3);
01011 if (!rx->ac3frame[l].set)
01012 ring_skip(&rx->ac3rbuffer[l], len);
01013 break;
01014 }
01015
01016 default:
01017 return;
01018
01019
01020 }
01021 #ifdef IN_DEBUG
01022 fprintf(stderr,"%s PES\n", t);
01023 #endif
01024
01025 }
01026
01027
01028 int replex_tsp(struct replex *rx, uint8_t *tsp)
01029 {
01030 uint16_t pid;
01031 int type;
01032 int off=0;
01033 pes_in_t *p=NULL;
01034
01035 pid = get_pid(tsp+1);
01036
01037 if ((type=replex_check_id(rx, pid))<0)
01038 return 0;
01039
01040 switch(type){
01041 case 0:
01042 p = &rx->pvideo;
01043 break;
01044
01045 case 1 ... 32:
01046 p = &rx->paudio[type-1];
01047 break;
01048
01049 case 0x80 ... 0x87:
01050 p = &rx->pac3[type-0x80];
01051 break;
01052 default:
01053 return 0;
01054
01055 }
01056
01057
01058 if ( tsp[1] & PAY_START) {
01059 if (p->plength == MMAX_PLENGTH-6){
01060 p->plength = p->found-6;
01061 es_out(p);
01062 init_pes_in(p, p->type, NULL, 0);
01063 }
01064 }
01065
01066 if ( tsp[3] & ADAPT_FIELD) {
01067 off = tsp[4] + 1;
01068 if (off+4 >= TS_SIZE) return 0;
01069 }
01070
01071 get_pes(p, tsp+4+off, TS_SIZE-4-off, es_out);
01072
01073 return 0;
01074 }
01075
01076
01077 ssize_t save_read(struct replex *rx, void *buf, size_t count)
01078 {
01079 ssize_t neof = 1;
01080 size_t re = 0;
01081 int fd = rx->fd_in;
01082
01083 if (rx->itype== REPLEX_AVI){
01084 int l = rx->inflength - rx->finread;
01085 if ( l <= 0) return 0;
01086 if ( (int) count > l) count = l;
01087 }
01088 while(neof >= 0 && re < count){
01089 neof = read(fd, buf+re, count - re);
01090 if (neof > 0) re += neof;
01091 else break;
01092 }
01093 rx->finread += re;
01094 #ifndef OUT_DEBUG
01095 if (rx->inflength){
01096 uint8_t per=0;
01097
01098 per = (uint8_t)(rx->finread*100/rx->inflength);
01099 if (rx->lastper < per){
01100 fprintf(stderr,"read %3d%%\r", (int)per);
01101 rx->lastper = per;
01102 }
01103 } else fprintf(stderr,"read %.2f MB\r", rx->finread/1024./1024.);
01104 #endif
01105 if (neof < 0 && re == 0) return neof;
01106 else return re;
01107 }
01108
01109 int guess_fill( struct replex *rx)
01110 {
01111 int vavail, aavail, ac3avail, i, fill;
01112
01113 vavail = 0;
01114 ac3avail =0;
01115 aavail = 0;
01116 fill =0;
01117
01118 #define LIMIT 3
01119 if ((vavail = ring_avail(&rx->index_vrbuffer)/sizeof(index_unit))
01120 < LIMIT)
01121 fill = ring_free(&rx->vrbuffer);
01122
01123 for (i=0; i<rx->apidn;i++){
01124 if ((aavail = ring_avail(&rx->index_arbuffer[i])
01125 /sizeof(index_unit)) < LIMIT)
01126 if (fill < (int) ring_free(&rx->arbuffer[i]))
01127 fill = ring_free(&rx->arbuffer[i]);
01128 }
01129
01130 for (i=0; i<rx->ac3n;i++){
01131 if ((ac3avail = ring_avail(&rx->index_ac3rbuffer[i])
01132 /sizeof(index_unit)) < LIMIT)
01133 if (fill < (int) ring_free(&rx->ac3rbuffer[i]))
01134 fill = ring_free(&rx->ac3rbuffer[i]);
01135 }
01136
01137
01138
01139 if (!fill){
01140 if(vavail && (aavail || ac3avail)) return 0;
01141 else return -1;
01142 }
01143
01144 return fill/2;
01145 }
01146
01147
01148
01149 #define IN_SIZE (1000*TS_SIZE)
01150 void find_pids_file(struct replex *rx)
01151 {
01152 uint8_t buf[IN_SIZE];
01153 int afound=0;
01154 int vfound=0;
01155 int count=0;
01156 int re=0;
01157 uint16_t vpid=0, apid=0, ac3pid=0;
01158
01159 fprintf(stderr,"Trying to find PIDs\n");
01160 while (!afound && !vfound && count < (int) rx->inflength){
01161 if (rx->vpid) vfound = 1;
01162 if (rx->apidn) afound = 1;
01163 if ((re = save_read(rx,buf,IN_SIZE))<0)
01164 perror("reading");
01165 else
01166 count += re;
01167 if ( (re = find_pids(&vpid, &apid, &ac3pid, buf, re))){
01168 if (!rx->vpid && vpid){
01169 rx->vpid = vpid;
01170 fprintf(stderr,"vpid 0x%04x \n",
01171 (int)rx->vpid);
01172 vfound++;
01173 }
01174 if (!rx->apidn && apid){
01175 rx->apid[0] = apid;
01176 fprintf(stderr,"apid 0x%04x \n",
01177 (int)rx->apid[0]);
01178 rx->apidn++;
01179 afound++;
01180 }
01181 if (!rx->ac3n && ac3pid){
01182 rx->ac3_id[0] = ac3pid;
01183 fprintf(stderr,"ac3pid 0x%04x \n",
01184 (int)rx->ac3_id[0]);
01185 rx->ac3n++;
01186 afound++;
01187 }
01188
01189 }
01190
01191 }
01192
01193 lseek(rx->fd_in,0,SEEK_SET);
01194 if (!afound || !vfound){
01195 fprintf(stderr,"Couldn't find all pids\n");
01196 exit(1);
01197 }
01198
01199 }
01200
01201 #define MAXVPID 16
01202 #define MAXAPID 32
01203 #define MAXAC3PID 16
01204 void find_all_pids_file(struct replex *rx)
01205 {
01206 uint8_t buf[IN_SIZE];
01207 int count=0;
01208 int j;
01209 int re=0;
01210 uint16_t vpid[MAXVPID], apid[MAXAPID], ac3pid[MAXAC3PID];
01211 int vn=0, an=0,ac3n=0;
01212 uint16_t vp,ap,cp;
01213 int vpos, apos, cpos;
01214
01215 memset (vpid , 0 , MAXVPID*sizeof(uint16_t));
01216 memset (apid , 0 , MAXAPID*sizeof(uint16_t));
01217 memset (ac3pid , 0 , MAXAC3PID*sizeof(uint16_t));
01218
01219 fprintf(stderr,"Trying to find PIDs\n");
01220 while (count < (int) rx->inflength-IN_SIZE){
01221 if ((re = save_read(rx,buf,IN_SIZE))<0)
01222 perror("reading");
01223 else
01224 count += re;
01225 if ( (re = find_pids_pos(&vp, &ap, &cp, buf, re,
01226 &vpos, &apos, &cpos))){
01227 if (vp){
01228 int old=0;
01229 for (j=0; j < vn; j++){
01230
01231 if (vpid[j] == vp){
01232 old = 1;
01233 break;
01234 }
01235 }
01236 if (!old){
01237 vpid[vn]=vp;
01238
01239 printf("vpid %d: 0x%04x (%d) PES ID: 0x%02x\n",
01240 vn+1,
01241 (int)vpid[vn], (int)vpid[vn],
01242 buf[vpos]);
01243 if (vn+1 < MAXVPID) vn++;
01244 }
01245 }
01246
01247 if (ap){
01248 int old=0;
01249 for (j=0; j < an; j++)
01250 if (apid[j] == ap){
01251 old = 1;
01252 break;
01253 }
01254 if (!old){
01255 apid[an]=ap;
01256 printf("apid %d: 0x%04x (%d) PES ID: 0x%02x\n",
01257 an +1,
01258 (int)apid[an],(int)apid[an],
01259 buf[apos]);
01260 if (an+1 < MAXAPID) an++;
01261 }
01262 }
01263
01264 if (cp){
01265 int old=0;
01266 for (j=0; j < ac3n; j++)
01267 if (ac3pid[j] == cp){
01268 old = 1;
01269 break;
01270 }
01271 if (!old){
01272 ac3pid[ac3n]=cp;
01273 printf("ac3pid %d: 0x%04x (%d) \n",
01274 ac3n+1,
01275 (int)ac3pid[ac3n],
01276 (int)ac3pid[ac3n]);
01277 if (ac3n+1< MAXAC3PID) ac3n++;
01278 }
01279 }
01280 }
01281
01282 }
01283
01284 lseek(rx->fd_in,0,SEEK_SET);
01285 }
01286
01287 void find_pids_stdin(struct replex *rx, uint8_t *buf, int len)
01288 {
01289 int afound=0;
01290 int vfound=0;
01291 uint16_t vpid=0, apid=0, ac3pid=0;
01292
01293 if (rx->vpid) vfound = 1;
01294 if (rx->apidn) afound = 1;
01295 fprintf(stderr,"Trying to find PIDs\n");
01296 if ( find_pids(&vpid, &apid, &ac3pid, buf, len) ){
01297 if (!rx->vpid && vpid){
01298 rx->vpid = vpid;
01299 vfound++;
01300 }
01301 if (!rx->apidn && apid){
01302 rx->apid[0] = apid;
01303 rx->apidn++;
01304 afound++;
01305 ring_init(&rx->arbuffer[0], rx->audiobuf);
01306 init_pes_in(&rx->paudio[0], 1, &rx->arbuffer[0], 0);
01307 rx->paudio[0].priv = (void *) rx;
01308 ring_init(&rx->index_arbuffer[0], INDEX_BUF);
01309 memset(&rx->aframe[0], 0, sizeof(audio_frame_t));
01310 init_index(&rx->current_aindex[0]);
01311 rx->aframe_count[0] = 0;
01312 rx->first_apts[0] = 0;
01313 }
01314
01315 if (!rx->ac3n && ac3pid){
01316 rx->ac3_id[0] = ac3pid;
01317 rx->ac3n++;
01318 afound++;
01319 ring_init(&rx->ac3rbuffer[0], AC3_BUF);
01320 init_pes_in(&rx->pac3[0], 0x80, &rx->ac3rbuffer[0],0);
01321 rx->pac3[0].priv = (void *) rx;
01322 ring_init(&rx->index_ac3rbuffer[0], INDEX_BUF);
01323 memset(&rx->ac3frame[0], 0, sizeof(audio_frame_t));
01324 init_index(&rx->current_ac3index[0]);
01325 rx->ac3frame_count[0] = 0;
01326 rx->first_ac3pts[0] = 0;
01327 }
01328
01329 }
01330
01331 if (afound && vfound){
01332 fprintf(stderr,"found ");
01333 if (rx->vpid) fprintf(stderr,"vpid %d (0x%04x) ",
01334 rx->vpid, rx->vpid);
01335 if (rx->apidn) fprintf(stderr,"apid %d (0x%04x) ",
01336 rx->apid[0], rx->apid[0]);
01337 if (rx->ac3n) fprintf(stderr,"ac3pid %d (0x%04x) ",
01338 rx->ac3_id[0], rx->ac3_id[0]);
01339 fprintf(stderr,"\n");
01340 } else {
01341 fprintf(stderr,"Couldn't find pids\n");
01342 exit(1);
01343 }
01344
01345 }
01346
01347
01348 void pes_id_out(pes_in_t *p)
01349 {
01350
01351 struct replex *rx;
01352 int len;
01353
01354 len = p->plength-3-p->hlength;
01355 rx = (struct replex *) p->priv;
01356
01357 rx->scan_found=0;
01358 switch(p->cid){
01359 case VIDEO_STREAM_S ... VIDEO_STREAM_E:
01360 rx->scan_found=p->cid;
01361 break;
01362
01363 case AUDIO_STREAM_S ... AUDIO_STREAM_E:
01364 rx->scan_found=p->cid;
01365 break;
01366
01367 case PRIVATE_STREAM1:
01368 if (rx->vdr){
01369 rx->scan_found = 0x80;
01370 break;
01371 } else {
01372
01373 uint8_t id = p->buf[9+p->hlength];
01374 switch(id){
01375 case 0x80 ... 0x8f:
01376 {
01377 int c=0;
01378 uint16_t fframe;
01379
01380 fframe=0;
01381 fframe = p->buf[9+p->hlength+3];
01382 fframe |= (p->buf[9+p->hlength+2]<<8);
01383
01384 if (fframe < p->plength){
01385 if ((c=find_audio_s(p->buf,
01386 9+p->hlength+4+fframe,
01387 AC3, p->plength+6)) >= 0){
01388 rx->scan_found = id;
01389
01390
01391
01392
01393 }
01394 }
01395 break;
01396 }
01397 }
01398 break;
01399 }
01400 default:
01401 p->cid = 0;
01402 p->type = 0;
01403 rx->scan_found=0;
01404 memset(p->buf,0,MAX_PLENGTH*sizeof(uint8_t));
01405 return;
01406 }
01407 }
01408
01409 void find_pes_ids(struct replex *rx)
01410 {
01411 uint8_t buf[IN_SIZE];
01412 int count=0;
01413 int j;
01414 int re=0;
01415 uint16_t vpid[MAXVPID], apid[MAXAPID], ac3pid[MAXAC3PID];
01416 int vn=0, an=0,ac3n=0;
01417
01418 memset (vpid , 0 , MAXVPID*sizeof(uint16_t));
01419 memset (apid , 0 , MAXAPID*sizeof(uint16_t));
01420 memset (ac3pid , 0 , MAXAC3PID*sizeof(uint16_t));
01421
01422 fprintf(stderr,"Trying to find PES IDs\n");
01423 rx->scan_found=0;
01424 rx->pvideo.priv = rx ;
01425 while (count < (int) rx->inflength-IN_SIZE){
01426 if ((re = save_read(rx,buf,IN_SIZE))<0)
01427 perror("reading");
01428 else
01429 count += re;
01430
01431 get_pes(&rx->pvideo, buf, re, pes_id_out);
01432
01433 if ( rx->scan_found ){
01434
01435 switch (rx->scan_found){
01436
01437 case VIDEO_STREAM_S ... VIDEO_STREAM_E:
01438 {
01439 int old=0;
01440 for (j=0; j < vn; j++){
01441
01442 if (vpid[j] == rx->scan_found){
01443 old = 1;
01444 break;
01445 }
01446 }
01447 if (!old){
01448 vpid[vn]=rx->scan_found;
01449
01450 printf("MPEG VIDEO %d: 0x%02x (%d)\n",
01451 vn+1,
01452 (int)vpid[vn], (int)vpid[vn]);
01453 if (vn+1 < MAXVPID) vn++;
01454 }
01455 }
01456 break;
01457
01458
01459 case AUDIO_STREAM_S ... AUDIO_STREAM_E:
01460 {
01461 int old=0;
01462 for (j=0; j < an; j++)
01463 if (apid[j] == rx->scan_found){
01464 old = 1;
01465 break;
01466 }
01467 if (!old){
01468 apid[an]=rx->scan_found;
01469 printf("MPEG AUDIO %d: 0x%02x (%d)\n",
01470 an +1,
01471 (int)apid[an],(int)apid[an]);
01472 if (an+1 < MAXAPID) an++;
01473 }
01474 }
01475 break;
01476
01477 case 0x80 ... 0x8f:
01478 {
01479 int old=0;
01480 for (j=0; j < ac3n; j++)
01481 if (ac3pid[j] == rx->scan_found){
01482 old = 1;
01483 break;
01484 }
01485 if (!old){
01486 ac3pid[ac3n]=rx->scan_found;
01487 if (rx->vdr){
01488 printf("possible AC3 AUDIO with private stream 1 pid (0xbd) \n");
01489 }else{
01490 printf("AC3 AUDIO %d: 0x%02x (%d) \n",
01491 ac3n+1,
01492 (int)ac3pid[ac3n],
01493 (int)ac3pid[ac3n]);
01494 }
01495 if (ac3n+1< MAXAC3PID) ac3n++;
01496 }
01497 rx->scan_found = 0;
01498 }
01499 break;
01500 }
01501 rx->scan_found = 0;
01502 }
01503 }
01504 }
01505
01506
01507
01508 void replex_finish(struct replex *rx)
01509 {
01510
01511 fprintf(stderr,"\n");
01512 if (!replex_all_set(rx)){
01513 fprintf(stderr,"Can't find all required streams\n");
01514 if (rx->itype == REPLEX_PS){
01515 fprintf(stderr,"Please check if audio and video have standard IDs (0xc0 or 0xe0)\n");
01516 }
01517 exit(1);
01518 }
01519
01520 if (!rx->demux)
01521 finish_mpg((multiplex_t *)rx->priv);
01522 exit(0);
01523 }
01524
01525 int replex_fill_buffers(struct replex *rx, uint8_t *mbuf)
01526 {
01527 uint8_t buf[IN_SIZE];
01528 int i,j;
01529 int count=0;
01530 int fill;
01531 int re;
01532 int rsize;
01533 int tries = 0;
01534
01535 if (rx->finish) return 0;
01536 fill = guess_fill(rx);
01537
01538 if (fill < 0) return -1;
01539
01540 memset(buf, 0, IN_SIZE);
01541
01542 switch(rx->itype){
01543 case REPLEX_TS:
01544 if (fill < IN_SIZE){
01545 rsize = fill - (fill%188);
01546 } else rsize = IN_SIZE;
01547
01548
01549
01550 if (!rsize) return 0;
01551
01552 memset(buf, 0, IN_SIZE);
01553
01554 if ( mbuf ){
01555 for ( i = 0; i < 188 ; i++){
01556 if ( mbuf[i] == 0x47 ) break;
01557 }
01558
01559 if ( i == 188){
01560 fprintf(stderr,"Not a TS\n");
01561 return -1;
01562 } else {
01563 memcpy(buf,mbuf+i,2*TS_SIZE-i);
01564 if ((count = save_read(rx,mbuf,i))<0)
01565 perror("reading");
01566 memcpy(buf+2*TS_SIZE-i,mbuf,i);
01567 i = 188;
01568 }
01569 } else i=0;
01570
01571
01572 #define MAX_TRIES 5
01573 while (count < rsize && tries < MAX_TRIES){
01574 if ((re = save_read(rx,buf+i,rsize-i)+i)<0)
01575 perror("reading");
01576 else
01577 count += re;
01578 tries++;
01579
01580 if (!rx->vpid || !(rx->apidn || rx->ac3n)){
01581 find_pids_stdin(rx, buf, re);
01582 }
01583
01584 for( j = 0; j < re; j+= TS_SIZE){
01585
01586 if ( re - j < TS_SIZE) break;
01587
01588 if ( replex_tsp( rx, buf+j) < 0){
01589 fprintf(stderr, "Error reading TS\n");
01590 exit(1);
01591 }
01592 }
01593 i=0;
01594 }
01595
01596 if (tries == MAX_TRIES)
01597 replex_finish(rx);
01598 return 0;
01599 break;
01600
01601 case REPLEX_PS:
01602 rsize = fill;
01603 if (fill > IN_SIZE) rsize = IN_SIZE;
01604 if (mbuf)
01605 get_pes(&rx->pvideo, mbuf, 2*TS_SIZE, pes_es_out);
01606
01607 while (count < rsize && tries < MAX_TRIES){
01608 if ((re = save_read(rx, buf, rsize))<0)
01609 perror("reading PS");
01610 else
01611 count += re;
01612
01613 get_pes(&rx->pvideo, buf, re, pes_es_out);
01614
01615 tries++;
01616
01617 }
01618
01619 if (tries == MAX_TRIES)
01620 replex_finish(rx);
01621 return 0;
01622 break;
01623
01624
01625 case REPLEX_AVI:
01626 rsize = fill;
01627 if (fill > IN_SIZE) rsize = IN_SIZE;
01628
01629 if (!(rx->ac.avih_flags & AVI_HASINDEX)){
01630
01631 if (mbuf){
01632 get_avi(&rx->pvideo, mbuf, rx->avi_rest, avi_es_out);
01633 }
01634
01635 while (count < rsize && tries < MAX_TRIES){
01636 if ((re = save_read(rx, buf, rsize))<0)
01637 perror("reading AVI");
01638 else
01639 count += re;
01640
01641 get_avi(&rx->pvideo, buf, re, avi_es_out);
01642
01643 tries++;
01644 }
01645 } else {
01646 if (get_avi_from_index(&rx->pvideo, rx->fd_in,
01647 &rx->ac, avi_es_out, rsize) < 0)
01648 tries = MAX_TRIES;
01649 }
01650
01651 if (tries == MAX_TRIES)
01652 replex_finish(rx);
01653 return 0;
01654 break;
01655 }
01656
01657 return -1;
01658 }
01659
01660 int fill_buffers(void *r, int finish)
01661 {
01662 struct replex *rx = (struct replex *)r;
01663
01664 rx->finish = finish;
01665
01666 return replex_fill_buffers(rx, NULL);
01667 }
01668
01669
01670 void init_index(index_unit *iu)
01671 {
01672 memset(iu,0, sizeof(index_unit));
01673 iu->frame_start = 1;
01674 }
01675
01676 static int replex_all_set(struct replex *rx)
01677 {
01678 int i;
01679 int set=0;
01680
01681 for (i=0; i < rx->ac3n ;i++){
01682 set += rx->ac3frame[i].set;
01683 }
01684 for (i=0; i<rx->apidn;i++){
01685 set += rx->aframe[i].set;
01686 }
01687 set += rx->seq_head.set;
01688
01689 if (set == (rx->ac3n+ rx->apidn + 1)) return 1;
01690 return 0;
01691 }
01692
01693
01694 int check_stream_type(struct replex *rx, uint8_t * buf, int len)
01695 {
01696 int c=0;
01697 avi_context ac;
01698 uint8_t head;
01699
01700 if (rx->itype != REPLEX_TS) return rx->itype;
01701
01702 if (len< 2*TS_SIZE){
01703 fprintf(stderr,"cannot determine streamtype");
01704 exit(1);
01705 }
01706
01707 fprintf(stderr, "Checking for TS: ");
01708 while (c < len && buf[c]!=0x47) c++;
01709 if (c<len && len-c>=TS_SIZE){
01710 if (buf[c+TS_SIZE] == 0x47){
01711 fprintf(stderr,"confirmed\n");
01712 return REPLEX_TS;
01713 } else fprintf(stderr,"failed\n");
01714 } else fprintf(stderr,"failed\n");
01715
01716 fprintf(stderr, "Checking for AVI: ");
01717 if (check_riff(&ac, buf, len)>=0){
01718 fprintf(stderr,"confirmed\n");
01719 rx->itype = REPLEX_AVI;
01720 rx->vpid = 0xE0;
01721 rx->apidn = 1;
01722 rx->apid[0] = 0xC0;
01723 rx->ignore_pts =1;
01724 return REPLEX_AVI;
01725 } else fprintf(stderr,"failed\n");
01726
01727 fprintf(stderr, "Checking for PS: ");
01728 if (find_any_header(&head, buf, len) >= 0){
01729 fprintf(stderr,"confirmed(maybe)\n");
01730 } else {
01731 fprintf(stderr,"failed, trying it anyway\n");
01732 }
01733 rx->itype=REPLEX_PS;
01734 if (!rx->vpid) rx->vpid = 0xE0;
01735 if (!(rx->apidn || rx->ac3n)){
01736 rx->apidn = 1;
01737 rx->apid[0] = 0xC0;
01738 }
01739 return REPLEX_PS;
01740 }
01741
01742
01743 void init_replex(struct replex *rx)
01744 {
01745 int i;
01746 uint8_t mbuf[2*TS_SIZE];
01747
01748 rx->analyze=0;
01749
01750 if (save_read(rx, mbuf, 2*TS_SIZE)<0)
01751 perror("reading");
01752
01753 check_stream_type(rx, mbuf, 2*TS_SIZE);
01754 if (rx->itype == REPLEX_TS){
01755 if (!rx->vpid || !(rx->apidn || rx->ac3n)){
01756 if (rx->inflength){
01757 find_pids_file(rx);
01758 }
01759 }
01760 }
01761
01762
01763 if (rx->otype==REPLEX_HDTV){
01764 rx->videobuf = 4*VIDEO_BUF;
01765 } else {
01766 rx->videobuf = VIDEO_BUF;
01767 }
01768 rx->audiobuf = AUDIO_BUF;
01769 rx->ac3buf = AC3_BUF;
01770
01771 if (rx->itype == REPLEX_AVI){
01772 rx->videobuf = 4*VIDEO_BUF;
01773 rx->audiobuf = 2*rx->videobuf;
01774 }
01775
01776 rx->vpes_abort = 0;
01777 rx->first_iframe = 0;
01778 ring_init(&rx->vrbuffer, rx->videobuf);
01779 if (rx->itype == REPLEX_TS || rx->itype == REPLEX_AVI)
01780 init_pes_in(&rx->pvideo, 0xE0, &rx->vrbuffer, 0);
01781 else {
01782 init_pes_in(&rx->pvideo, 0, NULL, 1);
01783 }
01784 rx->pvideo.priv = (void *) rx;
01785 ring_init(&rx->index_vrbuffer, INDEX_BUF);
01786 memset(&rx->seq_head, 0, sizeof(sequence_t));
01787 init_index(&rx->current_vindex);
01788 rx->vgroup_count = 0;
01789 rx->vframe_count = 0;
01790 rx->first_vpts = 0;
01791 rx->video_state = S_SEARCH;
01792 rx->last_vpts = 0;
01793
01794 for (i=0; i<rx->apidn;i++){
01795
01796 rx->apes_abort[i] = 0;
01797 rx->audio_state[i] = S_SEARCH;
01798 ring_init(&rx->arbuffer[i], rx->audiobuf);
01799
01800 if (rx->itype == REPLEX_TS){
01801 init_pes_in(&rx->paudio[i], i+1,
01802 &rx->arbuffer[i], 0);
01803 rx->paudio[i].priv = (void *) rx;
01804 }
01805 ring_init(&rx->index_arbuffer[i], INDEX_BUF);
01806 memset(&rx->aframe[i], 0, sizeof(audio_frame_t));
01807 init_index(&rx->current_aindex[i]);
01808 rx->aframe_count[i] = 0;
01809 rx->first_apts[i] = 0;
01810 rx->last_apts[i] = 0;
01811 }
01812
01813 for (i=0; i<rx->ac3n;i++){
01814 rx->ac3pes_abort[i] = 0;
01815 rx->ac3_state[i] = S_SEARCH;
01816 ring_init(&rx->ac3rbuffer[i], AC3_BUF);
01817 if (rx->itype == REPLEX_TS){
01818 init_pes_in(&rx->pac3[i], 0x80+i,
01819 &rx->ac3rbuffer[i],0);
01820 rx->pac3[i].priv = (void *) rx;
01821 }
01822 ring_init(&rx->index_ac3rbuffer[i], INDEX_BUF);
01823 memset(&rx->ac3frame[i], 0, sizeof(audio_frame_t));
01824 init_index(&rx->current_ac3index[i]);
01825 rx->ac3frame_count[i] = 0;
01826 rx->first_ac3pts[i] = 0;
01827 rx->last_ac3pts[i] = 0;
01828 }
01829
01830 if (rx->itype == REPLEX_TS){
01831 if (replex_fill_buffers(rx, mbuf)< 0) {
01832 fprintf(stderr,"error filling buffer\n");
01833 exit(1);
01834 }
01835 } else if ( rx->itype == REPLEX_AVI){
01836 #define AVI_S 1024
01837 avi_context *ac;
01838 uint8_t buf[AVI_S];
01839 int re=0;
01840
01841 lseek(rx->fd_in, 0, SEEK_SET);
01842 ac = &rx->ac;
01843 memset(ac, 0, sizeof(avi_context));
01844 save_read(rx, buf, 12);
01845
01846 if (check_riff(ac, buf, 12) < 0){
01847 fprintf(stderr, "Wrong RIFF header\n");
01848 exit(1);
01849 } else {
01850 fprintf(stderr,"Found RIFF header\n");
01851 }
01852
01853 memset(ac, 0, sizeof(avi_context));
01854 re = read_avi_header(ac, rx->fd_in);
01855 if (avi_read_index(ac,rx->fd_in) < 0){
01856 fprintf(stderr, "Error reading index\n");
01857 exit(1);
01858 }
01859
01860 rx->vframe_count = ac->ai[0].initial_frames*ac->vi.fps/
01861 ac->ai[0].fps;
01862
01863 rx->inflength = lseek(rx->fd_in, 0, SEEK_CUR)+ac->movi_length;
01864
01865 fprintf(stderr,"AVI initial frames %d\n",
01866 (int)rx->vframe_count);
01867 if (!ac->done){
01868 fprintf(stderr,"Error reading AVI header\n");
01869 exit(1);
01870 }
01871
01872 if (replex_fill_buffers(rx, buf+re)< 0) {
01873 fprintf(stderr,"error filling buffer\n");
01874 exit(1);
01875 }
01876 } else {
01877 if (replex_fill_buffers(rx, mbuf)< 0) {
01878 fprintf(stderr,"error filling buffer\n");
01879 exit(1);
01880 }
01881 }
01882
01883 }
01884
01885
01886 void fix_audio(struct replex *rx, multiplex_t *mx)
01887 {
01888 int i;
01889 index_unit aiu;
01890 int size;
01891
01892 size = sizeof(index_unit);
01893
01894 for ( i = 0; i < rx->apidn; i++){
01895 do {
01896 while (ring_avail(&rx->index_arbuffer[i]) <
01897 sizeof(index_unit)){
01898 if (replex_fill_buffers(rx, 0)< 0) {
01899 fprintf(stderr,
01900 "error in fix audio\n");
01901 exit(1);
01902 }
01903 }
01904 ring_peek(&rx->index_arbuffer[i], (uint8_t *)&aiu, size, 0);
01905 if ( ptscmp(aiu.pts + rx->first_apts[i], rx->first_vpts) < 0){
01906 ring_skip(&rx->index_arbuffer[i], size);
01907 ring_skip(&rx->arbuffer[i], aiu.length);
01908 } else break;
01909
01910 } while (1);
01911 mx->ext[i].pts_off = aiu.pts;
01912
01913 fprintf(stderr,"Audio%d offset: ",i);
01914 printpts(mx->ext[i].pts_off);
01915 printpts(rx->first_apts[i]+mx->ext[i].pts_off);
01916 fprintf(stderr,"\n");
01917 }
01918
01919 for ( i = 0; i < rx->ac3n; i++){
01920 do {
01921 while (ring_avail(&rx->index_ac3rbuffer[i]) <
01922 sizeof(index_unit)){
01923 if (replex_fill_buffers(rx, 0)< 0) {
01924 fprintf(stderr,
01925 "error in fix audio\n");
01926 exit(1);
01927 }
01928 }
01929 ring_peek(&rx->index_ac3rbuffer[i], (uint8_t *)&aiu,
01930 size, 0);
01931 if ( ptscmp (aiu.pts+rx->first_ac3pts[i], rx->first_vpts) < 0){
01932 ring_skip(&rx->index_ac3rbuffer[i], size);
01933 ring_skip(&rx->ac3rbuffer[i], aiu.length);
01934 } else break;
01935 } while (1);
01936 mx->ext[i].pts_off = aiu.pts;
01937
01938 fprintf(stderr,"AC3%d offset: ",i);
01939 printpts(mx->ext[i].pts_off);
01940 printpts(rx->first_ac3pts[i]+mx->ext[i].pts_off);
01941 fprintf(stderr,"\n");
01942
01943 }
01944 }
01945
01946
01947
01948 static int get_next_video_unit(struct replex *rx, index_unit *viu)
01949 {
01950 if (ring_avail(&rx->index_vrbuffer)){
01951 ring_read(&rx->index_vrbuffer, (uint8_t *)viu,
01952 sizeof(index_unit));
01953 return 1;
01954 }
01955 return 0;
01956 }
01957
01958 static int get_next_audio_unit(struct replex *rx, index_unit *aiu, int i)
01959 {
01960 if(ring_avail(&rx->index_arbuffer[i])){
01961 ring_read(&rx->index_arbuffer[i], (uint8_t *)aiu,
01962 sizeof(index_unit));
01963 return 1;
01964 }
01965 return 0;
01966 }
01967
01968 static int get_next_ac3_unit(struct replex *rx, index_unit *aiu, int i)
01969 {
01970 if (ring_avail(&rx->index_ac3rbuffer[i])) {
01971 ring_read(&rx->index_ac3rbuffer[i], (uint8_t *)aiu,
01972 sizeof(index_unit));
01973
01974 return 1;
01975 }
01976 return 0;
01977 }
01978
01979
01980 void do_analyze(struct replex *rx)
01981 {
01982 index_unit dummy;
01983 index_unit dummy2;
01984 int i;
01985 uint64_t lastvpts;
01986 uint64_t lastvdts;
01987 uint64_t lastapts[N_AUDIO];
01988 uint64_t lastac3pts[N_AC3];
01989 int av;
01990
01991 av = rx->analyze-1;
01992
01993 lastvpts = 0;
01994 lastvdts = 0;
01995 memset(lastapts, 0, N_AUDIO*sizeof(uint64_t));
01996 memset(lastac3pts, 0, N_AC3*sizeof(uint64_t));
01997
01998 fprintf(stderr,"STARTING ANALYSIS\n");
01999
02000
02001 while(!rx->finish){
02002 if (replex_fill_buffers(rx, 0)< 0) {
02003 fprintf(stderr,"error in get next video unit\n");
02004 return;
02005 }
02006 for (i=0; i< rx->apidn; i++){
02007 while(get_next_audio_unit(rx, &dummy2, i)){
02008 ring_skip(&rx->arbuffer[i],
02009 dummy2.length);
02010 if (av>=1){
02011 fprintf(stdout,
02012 "MPG2 Audio%d unit: ",
02013 i);
02014 fprintf(stdout,
02015 " length %d PTS ",
02016 dummy2.length);
02017 printptss(dummy2.pts);
02018
02019 if (lastapts[i]){
02020 fprintf(stdout," diff:");
02021 printptss(ptsdiff(dummy2.pts,lastapts[i]));
02022 }
02023 lastapts[i] = dummy2.pts;
02024
02025 fprintf(stdout,"\n");
02026 }
02027 }
02028 }
02029
02030 for (i=0; i< rx->ac3n; i++){
02031 while(get_next_ac3_unit(rx, &dummy2, i)){
02032 ring_skip(&rx->ac3rbuffer[i],
02033 dummy2.length);
02034 if (av>=1){
02035 fprintf(stdout,
02036 "AC3 Audio%d unit: ",
02037 i);
02038 fprintf(stdout,
02039 " length %d PTS ",
02040 dummy2.length);
02041 printptss(dummy2.pts);
02042 if (lastac3pts[i]){
02043 fprintf(stdout," diff:");
02044 printptss(ptsdiff(dummy2.pts, lastac3pts[i]));
02045 }
02046 lastac3pts[i] = dummy2.pts;
02047
02048 fprintf(stdout,"\n");
02049 }
02050 }
02051 }
02052
02053 while (get_next_video_unit(rx, &dummy)){
02054 ring_skip(&rx->vrbuffer,
02055 dummy.length);
02056 if (av==0 || av==2){
02057 fprintf(stdout,
02058 "Video unit: ");
02059 if (dummy.seq_header){
02060 fprintf(stdout,"Sequence header ");
02061 }
02062 if (dummy.gop){
02063 fprintf(stdout,"GOP header ");
02064 }
02065 switch (dummy.frame){
02066 case I_FRAME:
02067 fprintf(stdout, "I-frame");
02068 break;
02069 case B_FRAME:
02070 fprintf(stdout, "B-frame");
02071 break;
02072 case P_FRAME:
02073 fprintf(stdout, "P-frame");
02074 break;
02075 }
02076 fprintf(stdout,
02077 " length %d PTS ",
02078 dummy.length);
02079 printptss(dummy.pts);
02080 if (lastvpts){
02081 fprintf(stdout," diff:");
02082 printptss(ptsdiff(dummy.pts, lastvpts));
02083 }
02084 lastvpts = dummy.pts;
02085
02086 fprintf(stdout,
02087 " DTS ");
02088 printptss(dummy.dts);
02089 if (lastvdts){
02090 fprintf(stdout," diff:");
02091 printptss(ptsdiff(dummy.dts,lastvdts));
02092 }
02093 lastvdts = dummy.dts;
02094
02095 fprintf(stdout,"\n");
02096 }
02097 }
02098 }
02099
02100
02101 }
02102
02103 void do_scan(struct replex *rx)
02104 {
02105 uint8_t mbuf[2*TS_SIZE];
02106
02107 rx->analyze=0;
02108
02109 if (save_read(rx, mbuf, 2*TS_SIZE)<0)
02110 perror("reading");
02111
02112 fprintf(stderr,"STARTING SCAN\n");
02113
02114 check_stream_type(rx, mbuf, 2*TS_SIZE);
02115
02116 switch(rx->itype){
02117 case REPLEX_TS:
02118 find_all_pids_file(rx);
02119 break;
02120
02121 case REPLEX_PS:
02122 init_pes_in(&rx->pvideo, 0, NULL, 1);
02123 find_pes_ids(rx);
02124 break;
02125
02126 case REPLEX_AVI:
02127 break;
02128 }
02129
02130 }
02131
02132 void do_demux(struct replex *rx)
02133 {
02134 index_unit dummy;
02135 index_unit dummy2;
02136 int i;
02137 fprintf(stderr,"STARTING DEMUX\n");
02138
02139 while(!rx->finish){
02140 if (replex_fill_buffers(rx, 0)< 0) {
02141 fprintf(stderr,"error in get next video unit\n");
02142 return;
02143 }
02144 for (i=0; i< rx->apidn; i++){
02145 while(get_next_audio_unit(rx, &dummy2, i)){
02146 ring_read_file(&rx->arbuffer[i],
02147 rx->dmx_out[i+1],
02148 dummy2.length);
02149 }
02150 }
02151
02152 for (i=0; i< rx->ac3n; i++){
02153 while(get_next_ac3_unit(rx, &dummy2, i)){
02154 ring_read_file(&rx->ac3rbuffer[i],
02155 rx->dmx_out[i+1+rx->apidn],
02156 dummy2.length);
02157 }
02158 }
02159
02160 while (get_next_video_unit(rx, &dummy)){
02161 ring_read_file(&rx->vrbuffer, rx->dmx_out[0],
02162 dummy.length);
02163 }
02164 }
02165 }
02166
02167
02168 void do_replex(struct replex *rx)
02169 {
02170 int video_ok = 0;
02171 int ext_ok[N_AUDIO];
02172 int start=1;
02173 multiplex_t mx;
02174
02175
02176 fprintf(stderr,"STARTING REPLEX\n");
02177 memset(&mx, 0, sizeof(mx));
02178 memset(ext_ok, 0, N_AUDIO*sizeof(int));
02179
02180 while (!replex_all_set(rx)){
02181 if (replex_fill_buffers(rx, 0)< 0) {
02182 fprintf(stderr,"error filling buffer\n");
02183 exit(1);
02184 }
02185 }
02186
02187 int i;
02188 for (i = 0; i < rx->apidn; i++){
02189 rx->exttype[i] = 2;
02190 rx->extframe[i] = rx->aframe[i];
02191 rx->extrbuffer[i] = rx->arbuffer[i];
02192 rx->index_extrbuffer[i] = rx->index_arbuffer[i];
02193 rx->exttypcnt[i+1] = i;
02194 }
02195
02196 int ac3Count = 1;
02197 for (i = rx->apidn; i < rx->apidn + rx->ac3n; i++){
02198 rx->exttype[i] = 1;
02199 rx->extframe[i] = rx->ac3frame[i];
02200 rx->extrbuffer[i] = rx->ac3rbuffer[i];
02201 rx->index_extrbuffer[i] = rx->index_ac3rbuffer[i];
02202 rx->exttypcnt[i] = ac3Count++;
02203 }
02204
02205 mx.priv = (void *) rx;
02206 rx->priv = (void *) &mx;
02207 init_multiplex(&mx, &rx->seq_head, rx->extframe,
02208 rx->exttype, rx->exttypcnt, rx->video_delay,
02209 rx->audio_delay, rx->fd_out, fill_buffers,
02210 &rx->vrbuffer, &rx->index_vrbuffer,
02211 rx->extrbuffer, rx->index_extrbuffer,
02212 rx->otype);
02213
02214 if (!rx->ignore_pts){
02215 fix_audio(rx, &mx);
02216 }
02217 setup_multiplex(&mx);
02218
02219 while(1){
02220 check_times( &mx, &video_ok, ext_ok, &start);
02221
02222 write_out_packs( &mx, video_ok, ext_ok);
02223 }
02224 }
02225
02226
02227 void usage(char *progname)
02228 {
02229 printf ("usage: %s [options] <input files>\n\n",progname);
02230 printf ("options:\n");
02231 printf (" --help, -h: print help message\n");
02232 printf (" --type, -t: set output type (MPEG2, DVD, HDTV)\n");
02233 printf (" --of, -o: set output file\n");
02234 printf (" --input_stream, -i: set input stream type (TS(default), PS, AVI)\n");
02235 printf (" --audio_pid, -a: audio PID for TS stream (also used for PS id)\n");
02236 printf (" --ac3_id, -c: ID of AC3 audio for demux (also used for PS id)\n");
02237 printf (" --video_pid, -v: video PID for TS stream (also used for PS id)\n");
02238 printf (" --video_delay, -d: video delay in ms\n");
02239 printf (" --audio_delay, -e: audio delay in ms\n");
02240 printf (" --ignore_PTS, -f: ignore all PTS information of original\n");
02241 printf (" --keep_PTS, -k: keep and don't correct PTS information of original\n");
02242 printf (" --fix_sync, -n: try to fix audio sync while demuxing\n");
02243 printf (" --demux, -z: demux only (-o is basename)\n");
02244 printf (" --analyze, -y: analyze (0=video,1=audio, 2=both)\n");
02245 printf (" --scan, -s: scan for streams\n");
02246 printf (" --vdr, -x: handle AC3 for vdr input file\n");
02247 exit(1);
02248 }
02249
02250 int main(int argc, char **argv)
02251 {
02252 int c;
02253 int analyze=0;
02254 int scan =0;
02255 char *filename = NULL;
02256 char *type = "SVCD";
02257 char *inpt = "TS";
02258
02259 struct replex rx;
02260
02261 memset(&rx, 0, sizeof(struct replex));
02262
02263 while (1) {
02264 int option_index = 0;
02265 static struct option long_options[] = {
02266 {"type", required_argument, NULL, 't'},
02267 {"input_stream", required_argument, NULL, 'i'},
02268 {"video_pid", required_argument, NULL, 'v'},
02269 {"audio_pid", required_argument, NULL, 'a'},
02270 {"audio_delay", required_argument, NULL, 'e'},
02271 {"video_delay", required_argument, NULL, 'd'},
02272 {"ac3_id", required_argument, NULL, 'c'},
02273 {"of",required_argument, NULL, 'o'},
02274 {"ignore_PTS",required_argument, NULL, 'f'},
02275 {"keep_PTS",required_argument, NULL, 'k'},
02276 {"fix_sync",no_argument, NULL, 'n'},
02277 {"demux",no_argument, NULL, 'z'},
02278 {"analyze",required_argument, NULL, 'y'},
02279 {"scan",required_argument, NULL, 's'},
02280 {"vdr",required_argument, NULL, 'x'},
02281 {"help", no_argument , NULL, 'h'},
02282 {0, 0, 0, 0}
02283 };
02284 c = getopt_long (argc, argv,
02285 "t:o:a:v:i:hp:q:d:c:n:fkd:e:zy:sx",
02286 long_options, &option_index);
02287 if (c == -1)
02288 break;
02289
02290 switch (c) {
02291 case 't':
02292 type = optarg;
02293 break;
02294 case 'i':
02295 inpt = optarg;
02296 break;
02297 case 'd':
02298 rx.video_delay = strtol(optarg,(char **)NULL, 0)
02299 *CLOCK_MS;
02300 break;
02301 case 'e':
02302 rx.audio_delay = strtol(optarg,(char **)NULL, 0)
02303 *CLOCK_MS;
02304 break;
02305 case 'a':
02306 if (rx.apidn==N_AUDIO){
02307 fprintf(stderr,"Too many audio PIDs\n");
02308 exit(1);
02309 }
02310 rx.apid[rx.apidn] = strtol(optarg,(char **)NULL, 0);
02311 rx.apidn++;
02312 break;
02313 case 'v':
02314 rx.vpid = strtol(optarg,(char **)NULL, 0);
02315 break;
02316 case 'c':
02317 if (rx.ac3n==N_AC3){
02318 fprintf(stderr,"Too many audio PIDs\n");
02319 exit(1);
02320 }
02321 rx.ac3_id[rx.ac3n] = strtol(optarg,(char **)NULL, 0);
02322 rx.ac3n++;
02323 break;
02324 case 'o':
02325 filename = optarg;
02326 break;
02327 case 'f':
02328 rx.ignore_pts =1;
02329 break;
02330 case 'k':
02331 rx.keep_pts =1;
02332 break;
02333 case 'z':
02334 rx.demux =1;
02335 break;
02336 case 'n':
02337 rx.fix_sync =1;
02338 break;
02339 case 'y':
02340 analyze = strtol(optarg,(char **)NULL, 0);
02341 if (analyze>2) usage(argv[0]);
02342 analyze++;
02343 break;
02344 case 's':
02345 scan = 1;
02346 break;
02347 case 'x':
02348 rx.vdr=1;
02349 break;
02350 case 'h':
02351 case '?':
02352 default:
02353 usage(argv[0]);
02354 }
02355 }
02356
02357 if (rx.fix_sync)
02358 av_register_all();
02359
02360 if (optind == argc-1) {
02361 if ((rx.fd_in = open(argv[optind] ,O_RDONLY| O_LARGEFILE)) < 0) {
02362 perror("Error opening input file ");
02363 exit(1);
02364 }
02365 fprintf(stderr,"Reading from %s\n", argv[optind]);
02366 rx.inflength = lseek(rx.fd_in, 0, SEEK_END);
02367 fprintf(stderr,"Input file length: %.2f MB\n",rx.inflength/1024./1024.);
02368 lseek(rx.fd_in,0,SEEK_SET);
02369 rx.lastper = 0;
02370 rx.finread = 0;
02371 } else {
02372 fprintf(stderr,"using stdin as input\n");
02373 rx.fd_in = STDIN_FILENO;
02374 rx.inflength = 0;
02375 }
02376
02377 if (!rx.demux){
02378 if (filename){
02379 if ((rx.fd_out = open(filename,O_WRONLY|O_CREAT
02380 |O_TRUNC|O_LARGEFILE,
02381 S_IRUSR|S_IWUSR|S_IRGRP|
02382 S_IWGRP|
02383 S_IROTH|S_IWOTH)) < 0){
02384 perror("Error opening output file");
02385 exit(1);
02386 }
02387 fprintf(stderr,"Output File is: %s\n",
02388 filename);
02389 } else {
02390 rx.fd_out = STDOUT_FILENO;
02391 fprintf(stderr,"using stdout as output\n");
02392 }
02393 }
02394 if (scan){
02395 if (rx.fd_in == STDIN_FILENO){
02396 fprintf(stderr,"Can`t scan from pipe\n");
02397 exit(1);
02398 }
02399 do_scan(&rx);
02400 exit(0);
02401 }
02402
02403 if (!strncmp(type,"MPEG2",6))
02404 rx.otype=REPLEX_MPEG2;
02405 else if (!strncmp(type,"DVD",4))
02406 rx.otype=REPLEX_DVD;
02407 else if (!strncmp(type,"HDTV",4))
02408 rx.otype=REPLEX_HDTV;
02409 else if (!rx.demux)
02410 usage(argv[0]);
02411
02412 if (!strncmp(inpt,"TS",3)){
02413 rx.itype=REPLEX_TS;
02414 } else if (!strncmp(inpt,"PS",3)){
02415 rx.itype=REPLEX_PS;
02416 if (!rx.vpid) rx.vpid = 0xE0;
02417 if (!(rx.apidn || rx.ac3n)){
02418 rx.apidn = 1;
02419 rx.apid[0] = 0xC0;
02420 }
02421 } else if (!strncmp(inpt,"AVI",4)){
02422 rx.itype=REPLEX_AVI;
02423 rx.vpid = 0xE0;
02424 rx.apidn = 1;
02425 rx.apid[0] = 0xC0;
02426 rx.ignore_pts =1;
02427 } else {
02428 usage(argv[0]);
02429 }
02430
02431 init_replex(&rx);
02432 rx.analyze= analyze;
02433
02434 if (rx.demux) {
02435 int i;
02436 char fname[256];
02437 if (!filename){
02438 filename = malloc(4);
02439 strcpy(filename,"out");
02440 }
02441 if (strlen(filename) > 250){
02442 fprintf(stderr,"Basename too long\n");
02443 exit(0);
02444 }
02445
02446 snprintf(fname,256,"%s.mv2",filename);
02447 if ((rx.dmx_out[0] = open(fname,O_WRONLY|
02448 O_CREAT|O_TRUNC|
02449 O_LARGEFILE,
02450 S_IRUSR|S_IWUSR|
02451 S_IRGRP|S_IWGRP|
02452 S_IROTH|S_IWOTH))
02453 < 0){
02454 perror("Error opening output file");
02455 exit(1);
02456 }
02457 fprintf(stderr,"Video output File is: %s\n",
02458 fname);
02459
02460 for (i=0; i < rx.apidn; i++){
02461 snprintf(fname,256,"%s%d.mp2",filename
02462 ,i);
02463 if ((rx.dmx_out[i+1] =
02464 open(fname,O_WRONLY|
02465 O_CREAT|O_TRUNC|
02466 O_LARGEFILE,
02467 S_IRUSR|S_IWUSR|
02468 S_IRGRP|S_IWGRP|
02469 S_IROTH|S_IWOTH))
02470 < 0){
02471 perror("Error opening output file");
02472 exit(1);
02473 }
02474 fprintf(stderr,"Audio%d output File is: %s\n",i,fname);
02475 }
02476
02477
02478 for (i=0; i < rx.ac3n; i++){
02479 snprintf(fname,256,"%s%d.ac3",filename
02480 ,i);
02481 if ((rx.dmx_out[i+1+rx.apidn] =
02482 open(fname,O_WRONLY|
02483 O_CREAT|O_TRUNC|
02484 O_LARGEFILE,
02485 S_IRUSR|S_IWUSR|
02486 S_IRGRP|S_IWGRP|
02487 S_IROTH|S_IWOTH))
02488 < 0){
02489 perror("Error opening output file");
02490 exit(1);
02491 }
02492 fprintf(stderr,"AC3%d output File is: %s\n",i,fname);
02493 }
02494 do_demux(&rx);
02495 } else if (analyze){
02496 rx.demux=1;
02497 do_analyze(&rx);
02498 } else {
02499 do_replex(&rx);
02500 }
02501
02502 return 0;
02503 }