Ticket #2077: mt-replexsync-clean.diff
File mt-replexsync-clean.diff, 163.9 KB (added by , 17 years ago) |
---|
-
programs/mythtranscode/replex/element.h
2 2 * element.h 3 3 * 4 4 * 5 * Copyright (C) 2003 Marcus Metzler <mocm@metzlerbros.de> 5 * Copyright (C) 2003 - 2006 6 * Marcus Metzler <mocm@metzlerbros.de> 6 7 * Metzler Brothers Systementwicklung GbR 7 8 * 8 9 * This program is free software; you can redistribute it and/or … … 51 52 #define PICTURE_DISPLAY_EXTENSION 0x07 52 53 53 54 #define I_FRAME 0x01 54 #define P_FRAME 0x0255 #define B_FRAME 0x0356 #define D_FRAME 0x0 455 #define B_FRAME 0x02 56 #define P_FRAME 0x03 57 #define D_FRAME 0x03 57 58 58 59 #define OFF_SIZE 4 59 60 #define FIRST_FIELD 0 … … 74 75 #define PULLDOWN32 1 75 76 #define PULLDOWN23 2 76 77 78 #define PROGRESSIVE 1 79 #define ONE_FIELD 2 80 #define TWO_FIELD 3 81 77 82 #define CLOCK_MS 27000ULL 78 83 #define CLOCK_PER 27000000000ULL 79 84 #define SEC_PER (CLOCK_PER/s->frame_rate) 80 85 81 86 82 87 enum { 83 NONE=0,AC3, MPEG_AUDIO, LPCM , MAX_TYPES88 NONE=0,AC3, MPEG_AUDIO, LPCM 84 89 }; 85 90 86 91 typedef struct sequence_s{ … … 109 114 struct audio_frame_s{ 110 115 int set; 111 116 int layer; 117 int padding; 118 int sample_rate; 119 int mpg25; 120 int lsf; 112 121 uint32_t bit_rate; 113 122 uint32_t frequency; 114 123 uint32_t mode; 115 124 uint32_t mode_extension; 116 125 uint32_t emphasis; 117 126 uint32_t framesize; 118 uint32_t frametime;119 127 uint32_t off; 120 char language[4];128 121 129 } audio_frame_t; 122 130 123 131 void pts2time(uint64_t pts, uint8_t *buf, int len); 124 int find_audio_sync(ringbuffer *rbuf, uint8_t *buf, intoff, int type, int le);125 int find_audio_s(uint8_t *rbuf, intoff, int type, int le);126 int get_video_info(ringbuffer *rbuf, sequence_t *s, intoff, int le);127 int get_audio_info(ringbuffer *rbuf, audio_frame_t *af, int off, int le);128 int get_ac3_info(ringbuffer *rbuf, audio_frame_t *af, int off, int le);132 int find_audio_sync(ringbuffer *rbuf, uint8_t *buf, long off, int type, int le); 133 int find_audio_s(uint8_t *rbuf, long off, int type, int le); 134 int get_video_info(ringbuffer *rbuf, sequence_t *s, long off, int le); 135 int get_audio_info(ringbuffer *rbuf, audio_frame_t *af, long off, int le, int verb); 136 int get_ac3_info(ringbuffer *rbuf, audio_frame_t *af, long off, int le, int verb); 129 137 uint64_t add_pts_audio(uint64_t pts, audio_frame_t *aframe, uint64_t frames); 130 138 uint64_t next_ptsdts_video(uint64_t *pts, sequence_t *s, uint64_t fcount, uint64_t gcount); 139 int cfix_audio_count(audio_frame_t *aframe, uint64_t origpts, uint64_t pts); 131 140 void fix_audio_count(uint64_t *acount, audio_frame_t *aframe, 132 141 uint64_t origpts, uint64_t pts); 133 142 void fix_video_count(sequence_t *s, uint64_t *frame, uint64_t origpts, 134 143 uint64_t pts, uint64_t origdts, uint64_t dts); 135 144 136 145 int check_audio_header(ringbuffer *rbuf, audio_frame_t * af, 137 intoff, int le, int type);138 int get_video_ext_info(ringbuffer *rbuf, sequence_t *s, intoff, int le);146 long off, int le, int type); 147 int get_video_ext_info(ringbuffer *rbuf, sequence_t *s, long off, int le); 139 148 140 149 #endif /*_ELEMENT_H_*/ -
programs/mythtranscode/replex/ringbuffer.h
2 2 * ringbuffer.h 3 3 * 4 4 * 5 * Copyright (C) 2003 Marcus Metzler <mocm@metzlerbros.de> 5 * Copyright (C) 2003 - 2006 6 * Marcus Metzler <mocm@metzlerbros.de> 6 7 * Metzler Brothers Systementwicklung GbR 7 8 * 8 9 * This program is free software; you can redistribute it and/or … … 40 41 typedef struct ringbuffer { 41 42 int read_pos; 42 43 int write_pos; 43 uint32_t size;44 int size; 44 45 uint8_t *buffer; 45 46 } ringbuffer; 46 47 47 48 48 #define DBUF_INDEX 1000 049 #define DBUF_INDEX 1000 49 50 50 51 typedef struct dummy_buffer_s { 51 52 uint32_t size; … … 56 57 57 58 58 59 int ring_init (ringbuffer *rbuf, int size); 59 int ring_reinit (ringbuffer *rbuf, int size);60 60 void ring_clear(ringbuffer *rbuf); 61 61 void ring_destroy(ringbuffer *rbuf); 62 62 int ring_write(ringbuffer *rbuf, uint8_t *data, int count); 63 63 int ring_read(ringbuffer *rbuf, uint8_t *data, int count); 64 64 int ring_write_file(ringbuffer *rbuf, int fd, int count); 65 65 int ring_read_file(ringbuffer *rbuf, int fd, int count); 66 int ring_peek(ringbuffer *rbuf, uint8_t *data, unsigned int count, 67 uint32_t off); 68 int ring_poke(ringbuffer *rbuf, uint8_t *data, unsigned int count, 69 uint32_t off); 66 int ring_peek(ringbuffer *rbuf, uint8_t *data, int count, long off); 70 67 int ring_skip(ringbuffer *rbuf, int count); 71 68 72 69 static inline int ring_wpos(ringbuffer *rbuf) … … 95 92 return ring_posdiff(rbuf, rbuf->read_pos,pos); 96 93 } 97 94 98 static inline unsignedint ring_free(ringbuffer *rbuf){95 static inline int ring_free(ringbuffer *rbuf){ 99 96 int free; 100 free = rbuf->read_pos - rbuf->write_pos ;97 free = rbuf->read_pos - rbuf->write_pos-1; 101 98 if (free <= 0) free += rbuf->size; 102 //Note: free is gauranteed to be >=1 from the above103 return free - 1;99 100 return free; 104 101 } 105 102 106 static inline unsignedint ring_avail(ringbuffer *rbuf){103 static inline int ring_avail(ringbuffer *rbuf){ 107 104 int avail; 108 105 avail = rbuf->write_pos - rbuf->read_pos; 109 106 if (avail < 0) avail += rbuf->size; … … 121 118 int dummy_add(dummy_buffer *dbuf, uint64_t time, uint32_t size); 122 119 void dummy_clear(dummy_buffer *dbuf); 123 120 int dummy_init(dummy_buffer *dbuf, int s); 124 void dummy_destroy(dummy_buffer *dbuf); 125 void ring_show(ringbuffer *rbuf, unsigned int count, uint32_t off); 121 void ring_show(ringbuffer *rbuf, int count, long off); 126 122 127 123 #ifdef __cplusplus 128 124 } -
programs/mythtranscode/replex/replex.c
2 2 * replex.c 3 3 * 4 4 * 5 * Copyright (C) 2003 Marcus Metzler <mocm@metzlerbros.de> 5 * Copyright (C) 2003 - 2006 6 * Marcus Metzler <mocm@metzlerbros.de> 6 7 * Metzler Brothers Systementwicklung GbR 8 * (C) 2006 Reel Multimedia 7 9 * 8 10 * This program is free software; you can redistribute it and/or 9 11 * modify it under the terms of the GNU General Public License … … 39 41 #include "replex.h" 40 42 #include "pes.h" 41 43 42 #include "avcodec.h" 43 #include "avformat.h" 44 static int replex_all_set(struct replex *rx); 44 45 45 #ifdef USING_MINGW 46 # define S_IRGRP 0 47 # define S_IWGRP 0 48 # define S_IROTH 0 49 # define S_IWOTH 0 50 #endif 46 void overflow_exit(struct replex *rx) 47 { 48 rx->overflows++; 51 49 52 #ifndef O_LARGEFILE 53 #define O_LARGEFILE 0 54 #endif 50 if (rx->max_overflows && 51 rx->overflows > rx->max_overflows){ 52 fprintf(stderr,"exiting after %d overflows last video PTS: ", rx->overflows); 53 printpts(rx->last_vpts); 54 fprintf(stderr,"\n"); 55 exit(1); 56 } 57 } 55 58 56 static int replex_all_set(struct replex *rx);57 58 59 int replex_check_id(struct replex *rx, uint16_t id) 59 60 { 60 61 int i; … … 73 74 return -1; 74 75 } 75 76 76 int encode_mp2_audio(audio_frame_t *aframe, uint8_t *buffer, int bufsize) 77 78 static int audio_jump(struct replex *rx) 77 79 { 78 AVCodec *codec; 79 AVCodecContext *c= NULL; 80 int frame_size, j, out_size; 81 short *samples; 80 int i; 81 82 for (i=0; i<rx->apidn; i++) 83 if (rx->audio_jump[i]) 84 return 1; 85 86 for (i=0; i<rx->ac3n; i++) 87 if (rx->ac3_jump[i]) 88 return 1; 89 90 return 0; 91 } 92 93 94 static int jump_finished(struct replex *rx) 95 { 96 int i; 97 98 if (!rx->video_jump) return 0; 99 for (i=0; i<rx->apidn; i++) 100 if (!rx->audio_jump[i]) 101 return 0; 102 103 for (i=0; i<rx->ac3n; i++) 104 if (!rx->ac3_jump[i]) 105 return 0; 106 107 return 1; 108 } 109 110 111 static void clear_jump(struct replex *rx) 112 { 113 int i; 114 115 rx->video_jump = 0; 116 for (i=0; i<rx->apidn; i++) 117 rx->audio_jump[i] = 0; 118 119 for (i=0; i<rx->ac3n; i++) 120 rx->ac3_jump[i] = 0; 121 } 122 123 124 static void create_fillframe1(ringbuffer *rbuf, int off, int *fsize, 125 int type, uint8_t *fillframe, struct replex *rx) 126 { 127 int fs = *fsize; 82 128 83 fprintf(stderr, "encoding an MP2 audio frame\n");129 if (fs > MAXFRAME) return; 84 130 85 /* find the MP2 encoder */86 codec = avcodec_find_encoder(CODEC_ID_MP2);87 if (!codec) {88 f printf(stderr, "codec not found\n");89 return 1;131 if ( type == MPEG_AUDIO){ 132 audio_frame_t afr; 133 get_audio_info(rbuf, &afr, off, fs,0); 134 fs = afr.framesize; 135 off += (*fsize-fs); 90 136 } 91 92 c = avcodec_alloc_context(); 137 if (rx->fillzero && type == MPEG_AUDIO) 138 memset(fillframe+4, 0, MAXFRAME-4); 139 else 140 ring_peek (rbuf, fillframe, fs, off); 141 *fsize = fs; 142 } 93 143 94 /* put sample parameters */ 95 c->bit_rate = aframe->bit_rate; 96 c->sample_rate = aframe->frequency; 97 c->channels = 2; 98 99 /* open it */ 100 if (avcodec_open(c, codec) < 0) { 101 fprintf(stderr, "could not open codec\n"); 102 av_free(c); 103 return 1; 144 static void create_fillframe2(ringbuffer *rbuf, int off, int *fsize, 145 int type, uint8_t *fillframe, struct replex *rx) 146 { 147 int fs = *fsize; 148 149 if (fs > MAXFRAME) return; 150 151 if ( type == MPEG_AUDIO){ 152 audio_frame_t afr; 153 get_audio_info(rbuf, &afr, off, fs,0); 154 fs = afr.framesize; 104 155 } 156 if (rx->fillzero && type == MPEG_AUDIO) 157 memset(fillframe+4, 0, MAXFRAME-4); 158 else 159 ring_peek (rbuf, fillframe, fs, off); 105 160 106 /* the codec gives us the frame size, in samples */ 107 frame_size = c->frame_size; 108 samples = malloc(frame_size * 2 * c->channels); 161 *fsize = fs; 162 } 163 164 165 static void fill_in_frames(ringbuffer *index_buf, int fc, audio_frame_t *aframe, 166 uint64_t *acount, uint8_t *fillframe, int fsize, struct replex *rx) 167 { 168 index_unit iu; 169 int f; 170 171 for (f=0; f < fc; f++){ 172 init_index(&iu); 173 iu.active = 1; 174 iu.pts = add_pts_audio(0, aframe,*acount); 175 iu.framesize = fsize; 176 iu.length = fsize; 177 iu.fillframe = fillframe; 178 iu.err = DUMMY_ERR; 179 if (ring_write(index_buf, (uint8_t *)&iu, sizeof(index_unit)) < 0){ 180 fprintf(stderr,"audio ring buffer overrun error\n"); 181 overflow_exit(rx); 182 } 183 *acount += 1; 184 } 185 } 186 187 static int analyze_audio_loop( pes_in_t *p, struct replex *rx, int type, 188 audio_frame_t *aframe, index_unit *iu, 189 ringbuffer *rbuf, ringbuffer *index_buf, 190 uint64_t *acount, uint64_t *fpts, 191 uint64_t *lpts, int bsize, int *apes_abort, 192 uint64_t *ajump, uint64_t *aoff, 193 uint64_t adelay, int n, int off, 194 int c, int len, int pos, int *first, int *filled) 195 { 196 int re=0; 197 uint8_t *fillframe=NULL; 109 198 110 /* create samples for a single blank frame */ 111 for (j=0;j<frame_size;j++) { 112 samples[2*j] = 0; 113 samples[2*j+1] = 0; 199 switch( type ){ 200 case AC3: 201 fillframe = rx->ac3fillframe[n]; 202 break; 203 case MPEG_AUDIO: 204 fillframe = rx->afillframe[n]; 205 break; 114 206 } 207 if (!aframe->set){ 208 switch( type ){ 209 case AC3: 210 re = get_ac3_info(rbuf, aframe, 211 pos+c+off, 212 len-c-pos,1); 213 break; 214 case MPEG_AUDIO: 215 re = get_audio_info(rbuf, aframe, 216 pos+c+off, 217 len-c-pos, 1); 218 break; 219 } 220 if ( re == -2){ 221 *apes_abort = len -c; 222 return c; 223 } 224 if (re < 0) return c; 115 225 116 /* encode the samples */ 117 out_size = avcodec_encode_audio(c, buffer, bufsize, samples); 226 if (!rx->ignore_pts){ 227 if ((p->flag2 & PTS_ONLY)){ 228 *fpts = trans_pts_dts(p->pts); 229 fprintf(stderr, 230 "starting audio PTS: "); 231 printpts(*fpts); 232 fprintf(stderr,"\n"); 233 } else { 234 aframe->set = 0; 235 ring_skip(rbuf,pos+c+off+re); 236 } 237 } 238 239 if (aframe->set && *first) 240 ring_skip(rbuf,pos+c); 241 } else { 242 int diff = ring_posdiff(rbuf, iu->start, 243 p->ini_pos + pos+c); 244 245 if ( (re =check_audio_header(rbuf, aframe, 246 pos+c+off,len-c-pos, 247 type)) < 0){ 248 249 if ( re == -2){ 250 *apes_abort = len -c; 251 return c; 252 } 253 254 if (aframe->framesize > diff){ 255 if ( re == -3){ 256 c+= pos+1; 257 return c; 258 } 259 260 c += pos+2; 261 #ifdef IN_DEBUG 262 fprintf(stderr,"WRONG HEADER1 %d\n", diff); 263 #endif 264 return c; 265 } 266 } 267 if (aframe->framesize > diff){ 268 c += pos+2; 269 //fprintf(stderr,"WRONG HEADER2 %d\n", diff); 270 return c; 271 } 272 } 118 273 119 if (out_size != bufsize) { 120 fprintf(stderr, "frame size (%d) does not equal required size (%d)?\n", 121 out_size, bufsize); 122 free(samples); 123 avcodec_close(c); 124 av_free(c); 125 return 1; 126 } 274 275 if (aframe->set){ 276 if(iu->active){ 277 iu->length = ring_posdiff(rbuf, 278 iu->start, 279 p->ini_pos + 280 pos+c); 127 281 128 free(samples); 129 avcodec_close(c); 130 av_free(c); 282 if (fillframe && !*filled){ 283 int fsize = aframe->framesize; 284 int pdiff = ring_posdiff(rbuf, ring_rpos(rbuf),iu->start); 285 286 create_fillframe2(rbuf, pdiff, &fsize, type, fillframe, rx); 287 *filled = 1; 288 } 289 290 if (iu->length != aframe->framesize){ 291 iu->err= FRAME_ERR; 292 fprintf(stderr,"Wrong audio frame size: %d (%d)\n", 293 iu->length, aframe->framesize); 294 *acount -= 1; 295 } 296 297 if (ring_write(index_buf, (uint8_t *)iu, sizeof(index_unit)) < 0){ 298 fprintf(stderr,"audio ring buffer overrun error\n"); 299 overflow_exit(rx); 300 } 301 if (iu->err == JUMP_ERR) *acount -= 1; 302 *acount += 1; 303 } 304 305 init_index(iu); 306 iu->active = 1; 307 iu->pts = add_pts_audio(0, aframe,*acount); 308 iu->framesize = aframe->framesize; 309 310 if (!rx->ignore_pts && *first && (p->flag2 & PTS_ONLY)){ 311 int64_t dpts; 312 int64_t diff; 313 314 dpts = ptsdiff(trans_pts_dts(p->pts), *fpts); 315 diff = ptsdiff(dpts, iu->pts); 316 317 if (rx->allow_jump && 318 (int)diff > rx->allow_jump){ 319 320 if (!(*ajump) && rx->video_jump){ 321 int fc=0; 322 int fsize = 0; 323 uint64_t oldfpts = 0; 324 uint64_t ndpts = 0; 325 326 int pdiff = ring_posdiff(rbuf, ring_rpos(rbuf),p->ini_pos + 327 pos+c ); 328 329 *ajump = diff; 330 oldfpts = *fpts; 331 *fpts += rx->video_jump; 332 333 fprintf(stderr,"found jump in audio PTS\n"); 334 printpts(iu->pts); 335 printpts(diff); 336 fprintf(stderr,"\n"); 337 338 339 ndpts = uptsdiff(trans_pts_dts(p->pts),*fpts); 340 fsize = aframe->framesize; 341 if (fillframe){ 342 create_fillframe1(rbuf, pdiff-fsize, &fsize, 343 type, fillframe, rx); 344 *filled = 1; 345 } 346 347 if (iu->pts < ndpts){ 348 fc = cfix_audio_count(aframe, ndpts, iu->pts); 349 350 if ( fc > 100) { 351 *acount+= fc; 352 fprintf(stderr,"need to fill in %d audio frames\n",fc); 353 fprintf(stderr,"this is too much, try re-cutting\n"); 354 *fpts = oldfpts; 355 fc = 0; // just too broken 356 rx->video_jump=0; 357 } else fill_in_frames(index_buf, fc, aframe, 358 acount, fillframe, aframe->framesize, rx); 359 init_index(iu); 360 iu->active = 1; 361 iu->pts = add_pts_audio(0, aframe,*acount); 362 iu->framesize = aframe->framesize; 363 364 //iu->pts = uptsdiff(trans_pts_dts(p->pts), 365 // *fpts); 366 printpts(iu->pts); 367 fprintf(stderr," fixed %d frames\n", fc); 368 369 diff = 0; 370 371 } else { 372 fc = cfix_audio_count(aframe, iu->pts, ndpts); 373 fprintf(stderr,"need to drop %d audio frames: ",fc); 374 diff = ptsdiff(ndpts, iu->pts); 375 printpts(diff); 376 fprintf(stderr,"\n"); 377 iu->pts = add_pts_audio(0, aframe,*acount); 378 } 379 380 } 381 382 if (!rx->video_jump && diff > 0){ 383 uint64_t vadiff = ptsdiff(dpts, rx->last_vpts); 384 iu->err = JUMP_ERR; 385 *ajump = diff; 386 387 fprintf(stderr,"found jump in audio PTS without video jump\n"); 388 printpts(iu->pts); 389 printpts(diff); 390 fprintf(stderr,"\n"); 391 392 if (abs(vadiff) < 600 * CLOCK_MS){ 393 int fc=0; 394 int fsize = 0; 395 396 int pdiff = ring_posdiff(rbuf, ring_rpos(rbuf),p->ini_pos + 397 pos+c ); 398 399 *ajump = diff; 400 *fpts += rx->video_jump; 401 402 fprintf(stderr,"filling in audio frames\n"); 403 printpts(iu->pts); 404 printpts(diff); 405 fprintf(stderr,"\n"); 406 407 408 fc = cfix_audio_count(aframe, 409 uptsdiff(trans_pts_dts(p->pts), 410 *fpts), iu->pts); 411 fsize = aframe->framesize; 412 if (fillframe){ 413 create_fillframe1(rbuf, pdiff-fsize, &fsize, 414 type, fillframe, rx); 415 *filled = 1; 416 } 417 418 fill_in_frames(index_buf, fc, aframe, 419 acount, fillframe, fsize, rx); 420 421 init_index(iu); 422 iu->active = 1; 423 iu->pts = add_pts_audio(0, aframe,*acount); 424 iu->framesize = aframe->framesize; 425 fprintf(stderr," fixed %d frames\n", fc); 131 426 132 return 0; 133 } 427 diff = 0; 428 } 429 } 134 430 431 if (jump_finished(rx)) clear_jump(rx); 432 } 433 434 435 if ( diff < 0){ 436 fprintf(stderr,"drop audio frame\n"); 437 init_index(iu); 438 iu->err = JUMP_ERR; 439 iu->active = 1; 440 iu->pts = add_pts_audio(0, aframe,*acount); 441 iu->framesize = aframe->framesize; 442 } 443 444 if( iu->err!= JUMP_ERR && !rx->keep_pts && diff > 40*CLOCK_MS){ 445 if (!rx->allow_jump || abs((int)diff) > rx->allow_jump){ 446 fprintf(stderr,"audio PTS inconsistent: "); 447 printpts(dpts); 448 printpts(iu->pts); 449 fprintf(stderr,"diff: "); 450 printpts(diff); 451 fprintf(stderr,"\n"); 452 } 453 } 454 if (rx->keep_pts){ 455 fix_audio_count(acount, aframe, 456 uptsdiff(trans_pts_dts( 457 p->pts), 458 *fpts), 459 iu->pts); 460 iu->pts = uptsdiff(trans_pts_dts(p->pts), 461 *fpts); 462 if (*lpts && ptsdiff(iu->pts,*lpts)<0) 463 fprintf(stderr, 464 "Warning negative audio PTS increase!\n"); 465 *lpts = iu->pts; 466 } 467 *first = 0; 468 } 469 if (rx->analyze >1){ 470 if ((p->flag2 & PTS_ONLY)){ 471 iu->pts = trans_pts_dts(p->pts); 472 } else { 473 iu->pts = 0; 474 } 475 } 476 iu->start = (p->ini_pos+pos+c)%bsize; 477 } 478 c += pos; 479 if (c + aframe->framesize > len){ 480 // fprintf(stderr,"SHORT %d\n", len -c); 481 c = len; 482 } else { 483 c += aframe->framesize; 484 } 485 return c; 486 } 487 488 489 135 490 void analyze_audio( pes_in_t *p, struct replex *rx, int len, int num, int type) 136 491 { 137 492 int c=0; … … 143 498 uint64_t *fpts=NULL; 144 499 uint64_t *lpts=NULL; 145 500 int bsize = 0; 146 int first = 1; 501 uint64_t *ajump=NULL; 502 uint64_t *aoff=NULL; 147 503 uint8_t buf[7]; 148 504 int off=0; 149 505 int *apes_abort=NULL; 150 int re=0; 506 uint64_t adelay=0; 507 int first = 1; 508 int *filled=NULL; 151 509 152 510 switch ( type ){ 153 511 case AC3: … … 163 521 lpts = &rx->last_ac3pts[num]; 164 522 bsize = rx->ac3buf; 165 523 apes_abort = &rx->ac3pes_abort[num]; 524 ajump = &rx->ac3_jump[num]; 525 aoff = &rx->ac3pts_off[num]; 526 adelay = rx->ac3pts_off[num]; 527 filled = &rx->ac3filled[num]; 166 528 break; 167 529 168 530 case MPEG_AUDIO: … … 178 540 lpts = &rx->last_apts[num]; 179 541 bsize = rx->audiobuf; 180 542 apes_abort = &rx->apes_abort[num]; 543 ajump = &rx->audio_jump[num]; 544 aoff = &rx->apts_off[num]; 545 adelay = rx->apts_off[num]; 546 filled = &rx->afilled[num]; 181 547 break; 182 548 } 183 549 … … 186 552 while (c < len){ 187 553 if ( (pos = find_audio_sync(rbuf, buf, c+off, type, len-c) ) 188 554 >= 0 ){ 189 if (!aframe->set){ 190 switch( type ){ 191 case AC3: 192 re = get_ac3_info(rbuf, aframe, 193 pos+c+off, 194 len-c-pos); 195 break; 196 case MPEG_AUDIO: 197 re = get_audio_info(rbuf, aframe, 198 pos+c+off, 199 len-c-pos); 200 break; 201 } 202 if ( re == -2){ 203 *apes_abort = len -c; 204 return; 205 } 206 if (re < 0) return; 207 208 209 if (!rx->ignore_pts){ 210 if ((p->flag2 & PTS_ONLY)){ 211 *fpts = trans_pts_dts(p->pts); 212 fprintf(stderr, 213 "starting audio PTS: "); 214 printpts(*fpts); 215 fprintf(stderr,"\n"); 216 } else aframe->set = 0; 217 } 218 219 if (aframe->set && first) 220 ring_skip(rbuf,pos+c); 221 222 } else { 223 int diff = ring_posdiff(rbuf, iu->start, 224 p->ini_pos + pos+c); 225 226 if ( (re = check_audio_header(rbuf, aframe, 227 pos+c+off,len-c-pos, 228 type)) < 0){ 229 230 if ( re == -2){ 231 *apes_abort = len -c; 232 return; 233 } 234 235 if ((int) aframe->framesize > diff){ 236 if ( re == -3){ 237 c += pos+1; 238 continue; 239 } 240 241 c += pos+2; 242 #ifdef IN_DEBUG 243 fprintf(stderr,"WRONG HEADER1 %d\n", diff); 244 #endif 245 continue; 246 } 247 } 248 if ((int) aframe->framesize > diff){ 249 c += pos+2; 250 //fprintf(stderr,"WRONG HEADER2 %d\n", diff); 251 continue; 252 } 253 } 254 255 // try to fix audio sync - only works for mpeg audio for now 256 if (aframe->set && rx->fix_sync && first && type == MPEG_AUDIO){ 257 int frame_time = aframe->frametime; 258 int64_t diff; 259 diff = ptsdiff(trans_pts_dts(p->pts), add_pts_audio(0, aframe,*acount + 1) + *fpts); 260 if (abs ((int)diff) >= frame_time){ 261 fprintf(stderr,"fixing audio PTS inconsistency - diff: "); 262 printpts(abs(diff)); 263 264 if (diff < 0){ 265 diff = abs(diff); 266 int framesdiff = diff / frame_time; 267 fprintf(stderr, " - need to remove %d frame(s)\n", framesdiff); 268 269 // FIXME can only remove one frame at a time for now 270 if (framesdiff > 1) 271 framesdiff = 1; 272 iu->pts = add_pts_audio(0, aframe, -framesdiff); 273 c += aframe->framesize; 274 continue; 275 } else { 276 int framesdiff = diff / frame_time; 277 fprintf(stderr, " - need to add %d frame(s)\n", framesdiff); 278 279 // limit inserts to a maximum of 5 frames 280 if (framesdiff > 5) 281 framesdiff = 5; 282 283 // alloc memmory for audio frame 284 uint8_t *framebuf; 285 if ( !(framebuf = (uint8_t *) malloc(sizeof(uint8_t) * aframe->framesize))) { 286 fprintf(stderr,"Not enough memory for audio frame\n"); 287 exit(1); 288 } 289 290 // try to encode a blank frame 291 if (encode_mp2_audio(aframe, framebuf, sizeof(uint8_t) * aframe->framesize) != 0) { 292 // encode failed so just use a copy of the current frame 293 int res; 294 res = ring_peek(rbuf, framebuf, aframe->framesize, 0); 295 if (res != (int) aframe->framesize) { 296 fprintf(stderr,"ring buffer failed to peek frame res: %d\n", res); 297 exit(1); 298 } 299 } 300 301 // add each extra frame required direct to the output file 302 int x; 303 for (x = 0; x < framesdiff; x++){ 304 if (type == AC3){ 305 if (rx->dmx_out[num+1+rx->apidn]) 306 write(rx->dmx_out[num+1+rx->apidn], framebuf, aframe->framesize); 307 }else{ 308 if (rx->dmx_out[num+1]) 309 write(rx->dmx_out[num+1], framebuf, aframe->framesize); 310 } 311 *acount += 1; 312 } 313 314 free(framebuf); 315 } 316 } 317 } 318 319 if (aframe->set){ 320 if(iu->active){ 321 iu->length = ring_posdiff(rbuf, 322 iu->start, 323 p->ini_pos + 324 pos+c); 325 326 if (iu->length < aframe->framesize || 327 iu->length > aframe->framesize+1){ 328 fprintf(stderr,"Wrong audio frame size: %d\n", iu->length); 329 iu->err= FRAME_ERR; 330 } 331 if (ring_write(index_buf, 332 (uint8_t *)iu, 333 sizeof(index_unit)) < 0){ 334 fprintf(stderr,"audio ring buffer overrun error\n"); 335 exit(1); 336 } 337 *acount += 1; 338 } 339 340 init_index(iu); 341 iu->active = 1; 342 iu->pts = add_pts_audio(0, aframe,*acount); 343 iu->framesize = aframe->framesize; 344 345 if (!rx->ignore_pts && 346 first && (p->flag2 & PTS_ONLY)){ 347 int64_t diff; 348 349 diff = ptsdiff(trans_pts_dts(p->pts), 350 iu->pts + *fpts); 351 if( !rx->keep_pts && abs ((int)diff) > 40*CLOCK_MS){ 352 fprintf(stderr,"audio PTS inconsistent: "); 353 printpts(trans_pts_dts(p->pts)-*fpts); 354 printpts(iu->pts); 355 fprintf(stderr,"diff: "); 356 printpts(abs(diff)); 357 fprintf(stderr,"\n"); 358 } 359 if (rx->keep_pts){ 360 fix_audio_count(acount, aframe, 361 uptsdiff(trans_pts_dts( 362 p->pts), 363 *fpts), 364 iu->pts); 365 iu->pts = uptsdiff(trans_pts_dts(p->pts), 366 *fpts); 367 if (*lpts && ptsdiff(iu->pts,*lpts)<0) 368 fprintf(stderr, 369 "Warning negative audio PTS increase!\n"); 370 *lpts = iu->pts; 371 } 372 first = 0; 373 } 374 if (rx->analyze >1){ 375 if ((p->flag2 & PTS_ONLY)){ 376 iu->pts = trans_pts_dts(p->pts); 377 } else { 378 iu->pts = 0; 379 } 380 } 381 iu->start = (p->ini_pos+pos+c)%bsize; 382 } 383 c += pos; 384 if (c + (int) aframe->framesize > len){ 385 // fprintf(stderr,"SHORT %d\n", len -c); 386 c = len; 387 } else { 388 c += aframe->framesize; 389 } 555 c = analyze_audio_loop( p, rx, type, aframe, iu, 556 rbuf, index_buf, acount, fpts, 557 lpts, bsize, apes_abort, 558 ajump, aoff, adelay, num, off, 559 c, len, pos, &first, filled); 390 560 } else { 391 561 *apes_abort = len-c; 392 562 c=len; … … 394 564 } 395 565 } 396 566 567 397 568 void analyze_video( pes_in_t *p, struct replex *rx, int len) 398 569 { 399 570 uint8_t buf[8]; … … 418 589 int gop_off = 0; 419 590 int seq_p = 0; 420 591 int flush=0; 592 int keep_now = 0; 421 593 422 594 rbuf = &rx->vrbuffer; 423 595 index_buf = &rx->index_vrbuffer; … … 524 696 diff = ptsdiff(iu->pts, 525 697 rx->first_vpts 526 698 + newpts); 699 700 if (rx->allow_jump && 701 abs(diff) > rx->allow_jump) 702 { 703 if (audio_jump(rx)){ 704 fprintf(stderr,"AUDIO JUMPED\n"); 705 clear_jump(rx); 706 } 707 fprintf(stderr,"found jump in video PTS\n"); 708 printpts(iu->pts); 709 printpts(diff); 710 fprintf(stderr,"\n"); 711 rx->video_jump = diff; 712 rx->first_vpts += diff; 713 diff = 0; 714 } else { 715 keep_now = 1; 716 } 527 717 528 718 if (!rx->keep_pts && 529 719 abs((int)(diff)) > 3*SEC_PER/2){ … … 533 723 printpts(newpts+rx->first_vpts); 534 724 printpts(newpts); 535 725 fprintf(stderr," diff: "); 536 printpts( abs((int)diff));726 printpts(diff); 537 727 fprintf(stderr,"\n"); 538 728 } 539 729 } … … 544 734 diff = ptsdiff(iu->dts, 545 735 newdts + 546 736 rx->first_vpts); 547 if (!rx->keep_pts && 737 if (!rx->keep_pts && !keep_now && 548 738 abs((int)diff) > 3*SEC_PER/2){ 549 739 fprintf(stderr,"video DTS inconsistent: "); 550 740 printpts(trans_pts_dts(p->dts)); … … 552 742 printpts(newdts+rx->first_vpts); 553 743 printpts(newdts); 554 744 fprintf(stderr,"diff: "); 555 printpts( abs((int)diff));745 printpts(diff); 556 746 fprintf(stderr,"\n"); 557 747 } 558 748 } 559 if (!rx->keep_pts ){749 if (!rx->keep_pts && !keep_now){ 560 750 iu->pts = newpts; 561 751 iu->dts = newdts; 562 752 } else { … … 626 816 gop = 1; 627 817 gop_off = c+pos - seq_p; 628 818 629 if (ring_peek(rbuf, (uint8_t *) buf, 7, 630 off+c+pos) < 0){ 819 if (ring_peek(rbuf, buf, 7, off+c+pos) < 0){ 631 820 rx->vpes_abort = len -(c+pos-1); 632 821 return; 633 822 } … … 652 841 return; 653 842 } 654 843 655 if (ring_peek(rbuf, (uint8_t *) buf, 6,656 off+c+pos) < 0)return;844 if (ring_peek(rbuf, buf, 6, off+c+pos) < 0) 845 return; 657 846 658 847 659 848 frame = ((buf[5]&0x38) >>3); … … 731 920 if ( ring_write(index_buf, (uint8_t *) 732 921 &rx->current_vindex, 733 922 sizeof(index_unit))<0){ 734 fprintf(stderr,"video ring buffer overrun error \n");735 exit(1);923 fprintf(stderr,"video ring buffer overrun error 1\n"); 924 overflow_exit(rx); 736 925 737 926 } 738 927 } … … 850 1039 void pes_es_out(pes_in_t *p) 851 1040 { 852 1041 853 struct replex *rx ;1042 struct replex *rx = NULL; 854 1043 char t[80]; 855 int len , i;1044 int len = 0, i =0; 856 1045 int l=0; 857 1046 858 1047 len = p->plength-3-p->hlength; … … 865 1054 p->ini_pos = ring_wpos(&rx->vrbuffer); 866 1055 867 1056 if (ring_write(&rx->vrbuffer, p->buf+9+p->hlength, len)<0){ 868 fprintf(stderr,"video ring buffer overrun error \n");869 exit(1);1057 fprintf(stderr,"video ring buffer overrun error 2\n"); 1058 overflow_exit(rx); 870 1059 } 871 1060 if (rx->vpes_abort){ 872 1061 p->ini_pos = (p->ini_pos - rx->vpes_abort)%rx->vrbuffer.size; … … 888 1077 if (l < 0) break; 889 1078 p->ini_pos = ring_wpos(&rx->arbuffer[l]); 890 1079 if (ring_write(&rx->arbuffer[l], p->buf+9+p->hlength, len)<0){ 891 fprintf(stderr," video ring buffer overrun error\n");892 exit(1);1080 fprintf(stderr,"audio ring buffer overrun error\n"); 1081 overflow_exit(rx); 893 1082 } 894 1083 if (rx->apes_abort[l]){ 895 1084 p->ini_pos = (p->ini_pos - rx->apes_abort[l]) … … 930 1119 p->ini_pos = ring_wpos(&rx->ac3rbuffer[l]); 931 1120 932 1121 if (ring_write(&rx->ac3rbuffer[l], p->buf+9+hl+p->hlength, len)<0){ 933 fprintf(stderr," videoring buffer overrun error\n");934 exit(1);1122 fprintf(stderr,"ac3 ring buffer overrun error\n"); 1123 overflow_exit(rx); 935 1124 } 936 1125 if (rx->ac3pes_abort[l]){ 937 1126 p->ini_pos = (p->ini_pos - rx->ac3pes_abort[l]) … … 1055 1244 } 1056 1245 1057 1246 1058 if ( tsp[1] & PAY_START) 1247 if ( tsp[1] & PAY_START){ 1059 1248 if (p->plength == MMAX_PLENGTH-6){ 1060 1249 p->plength = p->found-6; 1061 1250 es_out(p); … … 1063 1252 } 1064 1253 } 1065 1254 1066 if ( tsp[3] & ADAPT_FIELD) 1255 if ( tsp[3] & ADAPT_FIELD){ // adaptation field? 1067 1256 off = tsp[4] + 1; 1068 1257 if (off+4 >= TS_SIZE) return 0; 1069 1258 } … … 1083 1272 if (rx->itype== REPLEX_AVI){ 1084 1273 int l = rx->inflength - rx->finread; 1085 1274 if ( l <= 0) return 0; 1086 if ( (int)count > l) count = l;1275 if ( count > l) count = l; 1087 1276 } 1088 1277 while(neof >= 0 && re < count){ 1089 neof = read(fd, ((char*)buf)+re, count - re);1278 neof = read(fd, buf+re, count - re); 1090 1279 if (neof > 0) re += neof; 1091 1280 else break; 1092 1281 } … … 1100 1289 fprintf(stderr,"read %3d%%\r", (int)per); 1101 1290 rx->lastper = per; 1102 1291 } 1292 if (rx->finread >= rx->inflength && rx->inputFiles && rx->inputFiles[rx->inputIdx + 1]) { 1293 close(rx->fd_in); 1294 rx->inputIdx ++; 1295 if ((rx->fd_in = open(rx->inputFiles[rx->inputIdx] ,O_RDONLY| O_LARGEFILE)) < 0) { 1296 fprintf(stderr,"Error opening input file %s",rx->inputFiles[rx->inputIdx] ); 1297 exit(1); 1298 } 1299 fprintf(stderr,"Reading from %s\n", rx->inputFiles[rx->inputIdx]); 1300 rx->inflength = lseek(rx->fd_in, 0, SEEK_END); 1301 fprintf(stderr,"Input file length: %.2f MB\n",rx->inflength/1024./1024.); 1302 lseek(rx->fd_in,0,SEEK_SET); 1303 rx->lastper = 0; 1304 rx->finread = 0; 1305 } 1103 1306 } else fprintf(stderr,"read %.2f MB\r", rx->finread/1024./1024.); 1104 1307 #endif 1105 1308 if (neof < 0 && re == 0) return neof; … … 1123 1326 for (i=0; i<rx->apidn;i++){ 1124 1327 if ((aavail = ring_avail(&rx->index_arbuffer[i]) 1125 1328 /sizeof(index_unit)) < LIMIT) 1126 if (fill < (int)ring_free(&rx->arbuffer[i]))1329 if (fill < ring_free(&rx->arbuffer[i])) 1127 1330 fill = ring_free(&rx->arbuffer[i]); 1128 1331 } 1129 1332 1130 1333 for (i=0; i<rx->ac3n;i++){ 1131 1334 if ((ac3avail = ring_avail(&rx->index_ac3rbuffer[i]) 1132 1335 /sizeof(index_unit)) < LIMIT) 1133 if (fill < (int)ring_free(&rx->ac3rbuffer[i]))1336 if (fill < ring_free(&rx->ac3rbuffer[i])) 1134 1337 fill = ring_free(&rx->ac3rbuffer[i]); 1135 1338 } 1136 1339 … … 1155 1358 int count=0; 1156 1359 int re=0; 1157 1360 uint16_t vpid=0, apid=0, ac3pid=0; 1158 1361 1159 1362 fprintf(stderr,"Trying to find PIDs\n"); 1160 while (!afound && !vfound && count < (int)rx->inflength){1363 while (!afound && !vfound && count < rx->inflength){ 1161 1364 if (rx->vpid) vfound = 1; 1162 1365 if (rx->apidn) afound = 1; 1163 1366 if ((re = save_read(rx,buf,IN_SIZE))<0) 1164 1367 perror("reading"); 1165 else 1368 else 1166 1369 count += re; 1167 1370 if ( (re = find_pids(&vpid, &apid, &ac3pid, buf, re))){ 1168 1371 if (!rx->vpid && vpid){ … … 1186 1389 afound++; 1187 1390 } 1188 1391 1189 } 1392 } 1190 1393 1191 1394 } 1192 1395 … … 1211 1414 int vn=0, an=0,ac3n=0; 1212 1415 uint16_t vp,ap,cp; 1213 1416 int vpos, apos, cpos; 1214 1417 1215 1418 memset (vpid , 0 , MAXVPID*sizeof(uint16_t)); 1216 1419 memset (apid , 0 , MAXAPID*sizeof(uint16_t)); 1217 1218 1420 memset (ac3pid , 0 , MAXAC3PID*sizeof(uint16_t)); 1421 1219 1422 fprintf(stderr,"Trying to find PIDs\n"); 1220 while (count < (int)rx->inflength-IN_SIZE){1423 while (count < rx->inflength-IN_SIZE){ 1221 1424 if ((re = save_read(rx,buf,IN_SIZE))<0) 1222 1425 perror("reading"); 1223 else 1426 else 1224 1427 count += re; 1225 if ( (re = find_pids_pos(&vp, &ap, &cp, buf, re, 1428 if ( (re = find_pids_pos(&vp, &ap, &cp, buf, re, 1226 1429 &vpos, &apos, &cpos))){ 1227 1430 if (vp){ 1228 1431 int old=0; … … 1241 1444 (int)vpid[vn], (int)vpid[vn], 1242 1445 buf[vpos]); 1243 1446 if (vn+1 < MAXVPID) vn++; 1244 } 1447 } 1245 1448 } 1246 1449 1247 1450 if (ap){ 1248 1451 int old=0; 1249 1452 for (j=0; j < an; j++) … … 1258 1461 (int)apid[an],(int)apid[an], 1259 1462 buf[apos]); 1260 1463 if (an+1 < MAXAPID) an++; 1261 } 1464 } 1262 1465 } 1263 1466 1264 1467 if (cp){ 1265 1468 int old=0; 1266 1469 for (j=0; j < ac3n; j++) … … 1270 1473 } 1271 1474 if (!old){ 1272 1475 ac3pid[ac3n]=cp; 1273 printf("ac3pid %d: 0x%04x (%d) \n", 1476 printf("ac3pid %d: 0x%04x (%d) \n", 1274 1477 ac3n+1, 1275 1478 (int)ac3pid[ac3n], 1276 1479 (int)ac3pid[ac3n]); 1277 1480 if (ac3n+1< MAXAC3PID) ac3n++; 1278 } 1481 } 1279 1482 } 1280 } 1483 } 1281 1484 1282 1485 } 1283 1486 … … 1289 1492 int afound=0; 1290 1493 int vfound=0; 1291 1494 uint16_t vpid=0, apid=0, ac3pid=0; 1292 1495 1293 1496 if (rx->vpid) vfound = 1; 1294 1497 if (rx->apidn) afound = 1; 1295 1498 fprintf(stderr,"Trying to find PIDs\n"); … … 1305 1508 ring_init(&rx->arbuffer[0], rx->audiobuf); 1306 1509 init_pes_in(&rx->paudio[0], 1, &rx->arbuffer[0], 0); 1307 1510 rx->paudio[0].priv = (void *) rx; 1308 ring_init(&rx->index_arbuffer[0], INDEX_BUF); 1511 ring_init(&rx->index_arbuffer[0], INDEX_BUF); 1309 1512 memset(&rx->aframe[0], 0, sizeof(audio_frame_t)); 1310 1513 init_index(&rx->current_aindex[0]); 1311 1514 rx->aframe_count[0] = 0; 1312 1515 rx->first_apts[0] = 0; 1313 1516 } 1314 1517 1315 1518 if (!rx->ac3n && ac3pid){ 1316 1519 rx->ac3_id[0] = ac3pid; 1317 1520 rx->ac3n++; 1318 1521 afound++; 1319 ring_init(&rx->ac3rbuffer[0], AC3_BUF);1522 ring_init(&rx->ac3rbuffer[0], rx->ac3buf); 1320 1523 init_pes_in(&rx->pac3[0], 0x80, &rx->ac3rbuffer[0],0); 1321 1524 rx->pac3[0].priv = (void *) rx; 1322 1525 ring_init(&rx->index_ac3rbuffer[0], INDEX_BUF); … … 1326 1529 rx->first_ac3pts[0] = 0; 1327 1530 } 1328 1531 1329 } 1330 1532 } 1533 1331 1534 if (afound && vfound){ 1332 1535 fprintf(stderr,"found "); 1333 1536 if (rx->vpid) fprintf(stderr,"vpid %d (0x%04x) ", … … 1337 1540 if (rx->ac3n) fprintf(stderr,"ac3pid %d (0x%04x) ", 1338 1541 rx->ac3_id[0], rx->ac3_id[0]); 1339 1542 fprintf(stderr,"\n"); 1340 } else { 1543 } 1544 else { 1341 1545 fprintf(stderr,"Couldn't find pids\n"); 1342 1546 exit(1); 1343 1547 } 1344 1548 1345 1549 } 1346 1550 1347 1551 1348 1552 void pes_id_out(pes_in_t *p) 1349 1553 { 1350 1554 1351 1555 struct replex *rx; 1352 1556 int len; 1353 1557 1354 1558 len = p->plength-3-p->hlength; 1355 1559 rx = (struct replex *) p->priv; 1356 1560 1357 1561 rx->scan_found=0; 1358 switch (p->cid){1562 switch (p->cid){ 1359 1563 case VIDEO_STREAM_S ... VIDEO_STREAM_E: 1360 1564 rx->scan_found=p->cid; 1361 1565 break; … … 1368 1572 if (rx->vdr){ 1369 1573 rx->scan_found = 0x80; 1370 1574 break; 1371 } else { 1575 } 1576 else { 1372 1577 1373 1578 uint8_t id = p->buf[9+p->hlength]; 1374 switch (id){1579 switch (id){ 1375 1580 case 0x80 ... 0x8f: 1376 { 1377 int c=0; 1581 { 1582 int c=0; 1378 1583 uint16_t fframe; 1379 1584 1380 1585 fframe=0; … … 1383 1588 1384 1589 if (fframe < p->plength){ 1385 1590 if ((c=find_audio_s(p->buf, 1386 9+p->hlength+4+fframe, 1591 9+p->hlength+4+fframe, 1387 1592 AC3, p->plength+6)) >= 0){ 1388 1593 rx->scan_found = id; 1389 1594 //fprintf(stderr,"0x%04x 0x%04x \n", … … 1414 1619 int re=0; 1415 1620 uint16_t vpid[MAXVPID], apid[MAXAPID], ac3pid[MAXAC3PID]; 1416 1621 int vn=0, an=0,ac3n=0; 1417 1622 1418 1623 memset (vpid , 0 , MAXVPID*sizeof(uint16_t)); 1419 1624 memset (apid , 0 , MAXAPID*sizeof(uint16_t)); 1420 1625 memset (ac3pid , 0 , MAXAC3PID*sizeof(uint16_t)); 1421 1626 1422 1627 fprintf(stderr,"Trying to find PES IDs\n"); 1423 1628 rx->scan_found=0; 1424 1629 rx->pvideo.priv = rx ; 1425 while (count < (int)rx->inflength-IN_SIZE){1630 while (count < 50000000 && count < rx->inflength-IN_SIZE){ 1426 1631 if ((re = save_read(rx,buf,IN_SIZE))<0) 1427 1632 perror("reading"); 1428 else 1633 else 1429 1634 count += re; 1430 1635 1431 1636 get_pes(&rx->pvideo, buf, re, pes_id_out); 1432 1637 1433 1638 if ( rx->scan_found ){ 1434 1639 1435 1640 switch (rx->scan_found){ 1436 1641 1437 1642 case VIDEO_STREAM_S ... VIDEO_STREAM_E: … … 1452 1657 (int)vpid[vn], (int)vpid[vn]); 1453 1658 if (vn+1 < MAXVPID) vn++; 1454 1659 } 1455 } 1660 } 1456 1661 break; 1457 1458 1662 1663 1459 1664 case AUDIO_STREAM_S ... AUDIO_STREAM_E: 1460 1665 { 1461 1666 int old=0; … … 1465 1670 break; 1466 1671 } 1467 1672 if (!old){ 1468 apid[an] =rx->scan_found;1673 apid[an] = rx->apid[an] = rx->scan_found; 1469 1674 printf("MPEG AUDIO %d: 0x%02x (%d)\n", 1470 1675 an +1, 1471 1676 (int)apid[an],(int)apid[an]); 1472 1677 if (an+1 < MAXAPID) an++; 1473 } 1678 } 1474 1679 } 1475 1680 break; 1476 1681 1477 1682 case 0x80 ... 0x8f: 1478 1683 { 1479 1684 int old=0; … … 1483 1688 break; 1484 1689 } 1485 1690 if (!old){ 1486 ac3pid[ac3n]=rx-> scan_found;1691 ac3pid[ac3n]=rx->ac3_id[ac3n]=rx->scan_found; 1487 1692 if (rx->vdr){ 1488 1693 printf("possible AC3 AUDIO with private stream 1 pid (0xbd) \n"); 1489 }else{ 1490 printf("AC3 AUDIO %d: 0x%02x (%d) \n", 1694 } 1695 else { 1696 printf("AC3 AUDIO %d: 0x%02x (%d) \n", 1491 1697 ac3n+1, 1492 1698 (int)ac3pid[ac3n], 1493 1699 (int)ac3pid[ac3n]); 1494 1700 } 1495 1701 if (ac3n+1< MAXAC3PID) ac3n++; 1496 } 1702 } 1497 1703 rx->scan_found = 0; 1498 1704 } 1499 1705 break; … … 1501 1707 rx->scan_found = 0; 1502 1708 } 1503 1709 } 1710 rx->ac3n = ac3n; 1711 rx->apidn = an; 1504 1712 } 1505 1713 1506 1714 1507 1715 1508 1716 void replex_finish(struct replex *rx) 1509 1717 { 1510 1718 1511 1719 fprintf(stderr,"\n"); 1512 1720 if (!replex_all_set(rx)){ 1513 1721 fprintf(stderr,"Can't find all required streams\n"); … … 1516 1724 } 1517 1725 exit(1); 1518 1726 } 1519 1727 1520 1728 if (!rx->demux) 1521 1729 finish_mpg((multiplex_t *)rx->priv); 1522 1730 exit(0); … … 1740 1948 } 1741 1949 1742 1950 1743 void init_replex(struct replex *rx )1951 void init_replex(struct replex *rx,int bufsize) 1744 1952 { 1745 1953 int i; 1746 1954 uint8_t mbuf[2*TS_SIZE]; 1747 1955 1956 int VIDEO_BUF, AUDIO_BUF, AC3_BUF; 1957 1958 VIDEO_BUF = bufsize; 1959 AUDIO_BUF = (VIDEO_BUF/10); 1960 AC3_BUF = (VIDEO_BUF/10); 1961 1748 1962 rx->analyze=0; 1749 1963 1750 1964 if (save_read(rx, mbuf, 2*TS_SIZE)<0) … … 1757 1971 find_pids_file(rx); 1758 1972 } 1759 1973 } 1760 } 1974 } 1761 1975 1762 1763 1976 if (rx->otype==REPLEX_HDTV){ 1764 1977 rx->videobuf = 4*VIDEO_BUF; 1765 1978 } else { … … 1778 1991 ring_init(&rx->vrbuffer, rx->videobuf); 1779 1992 if (rx->itype == REPLEX_TS || rx->itype == REPLEX_AVI) 1780 1993 init_pes_in(&rx->pvideo, 0xE0, &rx->vrbuffer, 0); 1781 else {1994 else if (rx->itype == REPLEX_PS){ 1782 1995 init_pes_in(&rx->pvideo, 0, NULL, 1); 1783 } 1996 // find_pes_in(rx); 1997 } else init_pes_in(&rx->pvideo, 0, NULL, 1); 1998 1784 1999 rx->pvideo.priv = (void *) rx; 1785 2000 ring_init(&rx->index_vrbuffer, INDEX_BUF); 1786 2001 memset(&rx->seq_head, 0, sizeof(sequence_t)); … … 1828 2043 } 1829 2044 1830 2045 if (rx->itype == REPLEX_TS){ 1831 if (replex_fill_buffers(rx, mbuf)< 0) 2046 if (replex_fill_buffers(rx, mbuf)< 0){ 1832 2047 fprintf(stderr,"error filling buffer\n"); 1833 2048 exit(1); 1834 2049 } … … 1837 2052 avi_context *ac; 1838 2053 uint8_t buf[AVI_S]; 1839 2054 int re=0; 1840 ssize_t read_count = 0;1841 2055 1842 2056 lseek(rx->fd_in, 0, SEEK_SET); 1843 2057 ac = &rx->ac; 1844 2058 memset(ac, 0, sizeof(avi_context)); 1845 if ((read_count = save_read(rx, buf, 12)) != 12) { 1846 fprintf(stderr, 1847 "Error reading in 12 bytes from replex. Read %d bytes\n", 1848 (int)read_count); 1849 exit(1); 1850 } 2059 save_read(rx, buf, 12); 1851 2060 1852 2061 if (check_riff(ac, buf, 12) < 0){ 1853 2062 fprintf(stderr, "Wrong RIFF header\n"); … … 1875 2084 exit(1); 1876 2085 } 1877 2086 1878 if (replex_fill_buffers(rx, buf+re)< 0) 2087 if (replex_fill_buffers(rx, buf+re)< 0){ 1879 2088 fprintf(stderr,"error filling buffer\n"); 1880 2089 exit(1); 1881 2090 } 1882 2091 } else { 1883 if (replex_fill_buffers(rx, mbuf)< 0) 2092 if (replex_fill_buffers(rx, mbuf)< 0){ 1884 2093 fprintf(stderr,"error filling buffer\n"); 1885 2094 exit(1); 1886 2095 } … … 1901 2110 do { 1902 2111 while (ring_avail(&rx->index_arbuffer[i]) < 1903 2112 sizeof(index_unit)){ 1904 if (replex_fill_buffers(rx, 0)< 0) 2113 if (replex_fill_buffers(rx, 0)< 0){ 1905 2114 fprintf(stderr, 1906 2115 "error in fix audio\n"); 1907 2116 exit(1); 1908 2117 } 1909 2118 } 1910 ring_peek(&rx->index_arbuffer[i], (uint8_t *)&aiu, size, 0); 2119 ring_peek(&rx->index_arbuffer[i], (uint8_t *)&aiu, 2120 size, 0); 1911 2121 if ( ptscmp(aiu.pts + rx->first_apts[i], rx->first_vpts) < 0){ 1912 2122 ring_skip(&rx->index_arbuffer[i], size); 1913 2123 ring_skip(&rx->arbuffer[i], aiu.length); 1914 2124 } else break; 1915 2125 1916 2126 } while (1); 1917 mx->ext[i].pts_off = aiu.pts; 2127 mx->apts_off[i] = aiu.pts; 2128 rx->apts_off[i] = aiu.pts; 2129 mx->aframes[i] = aiu.framesize; 1918 2130 1919 2131 fprintf(stderr,"Audio%d offset: ",i); 1920 printpts(mx-> ext[i].pts_off);1921 printpts(rx->first_apts[i]+mx-> ext[i].pts_off);2132 printpts(mx->apts_off[i]); 2133 printpts(rx->first_apts[i]+mx->apts_off[i]); 1922 2134 fprintf(stderr,"\n"); 1923 2135 } 1924 2136 … … 1926 2138 do { 1927 2139 while (ring_avail(&rx->index_ac3rbuffer[i]) < 1928 2140 sizeof(index_unit)){ 1929 if (replex_fill_buffers(rx, 0)< 0) 2141 if (replex_fill_buffers(rx, 0)< 0){ 1930 2142 fprintf(stderr, 1931 2143 "error in fix audio\n"); 1932 2144 exit(1); 1933 2145 } 1934 2146 } 1935 ring_peek(&rx->index_ac3rbuffer[i], (uint8_t *)&aiu,2147 ring_peek(&rx->index_ac3rbuffer[i],(uint8_t *) &aiu, 1936 2148 size, 0); 1937 2149 if ( ptscmp (aiu.pts+rx->first_ac3pts[i], rx->first_vpts) < 0){ 1938 2150 ring_skip(&rx->index_ac3rbuffer[i], size); 1939 2151 ring_skip(&rx->ac3rbuffer[i], aiu.length); 1940 2152 } else break; 1941 2153 } while (1); 1942 mx->ext[i].pts_off = aiu.pts; 2154 mx->ac3pts_off[i] = aiu.pts; 2155 rx->ac3pts_off[i] = aiu.pts; 1943 2156 1944 2157 fprintf(stderr,"AC3%d offset: ",i); 1945 printpts(mx-> ext[i].pts_off);1946 printpts(rx->first_ac3pts[i]+mx-> ext[i].pts_off);2158 printpts(mx->ac3pts_off[i]); 2159 printpts(rx->first_ac3pts[i]+mx->ac3pts_off[i]); 1947 2160 fprintf(stderr,"\n"); 1948 2161 1949 2162 } … … 1973 2186 1974 2187 static int get_next_ac3_unit(struct replex *rx, index_unit *aiu, int i) 1975 2188 { 1976 if (ring_avail(&rx->index_ac3rbuffer[i])) 2189 if (ring_avail(&rx->index_ac3rbuffer[i])){ 1977 2190 ring_read(&rx->index_ac3rbuffer[i], (uint8_t *)aiu, 1978 2191 sizeof(index_unit)); 1979 2192 … … 2005 2218 2006 2219 2007 2220 while(!rx->finish){ 2008 if (replex_fill_buffers(rx, 0)< 0) 2221 if (replex_fill_buffers(rx, 0)< 0){ 2009 2222 fprintf(stderr,"error in get next video unit\n"); 2010 2223 return; 2011 2224 } … … 2140 2353 index_unit dummy; 2141 2354 index_unit dummy2; 2142 2355 int i; 2356 multiplex_t mx; 2143 2357 fprintf(stderr,"STARTING DEMUX\n"); 2358 2359 2360 while (!replex_all_set(rx)){ 2361 if (replex_fill_buffers(rx, 0)< 0){ 2362 fprintf(stderr,"error filling buffer\n"); 2363 exit(1); 2364 } 2365 } 2366 2367 fix_audio(rx, &mx); 2144 2368 2145 2369 while(!rx->finish){ 2146 if (replex_fill_buffers(rx, 0)< 0) 2370 if (replex_fill_buffers(rx, 0)< 0){ 2147 2371 fprintf(stderr,"error in get next video unit\n"); 2148 2372 return; 2149 2373 } 2150 2374 for (i=0; i< rx->apidn; i++){ 2151 2375 while(get_next_audio_unit(rx, &dummy2, i)){ 2152 ring_read_file(&rx->arbuffer[i], 2153 rx->dmx_out[i+1], 2154 dummy2.length); 2376 switch(dummy2.err){ 2377 case JUMP_ERR: 2378 ring_skip(&rx->arbuffer[i],dummy2.length); 2379 break; 2380 case DUMMY_ERR: 2381 write(rx->dmx_out[i+1],dummy.fillframe,dummy2.length); 2382 break; 2383 default: 2384 ring_read_file(&rx->arbuffer[i], 2385 rx->dmx_out[i+1], 2386 dummy2.length); 2387 } 2155 2388 } 2156 2389 } 2157 2390 2158 2391 for (i=0; i< rx->ac3n; i++){ 2159 2392 while(get_next_ac3_unit(rx, &dummy2, i)){ 2160 ring_read_file(&rx->ac3rbuffer[i], 2161 rx->dmx_out[i+1+rx->apidn], 2162 dummy2.length); 2393 switch(dummy2.err){ 2394 case JUMP_ERR: 2395 ring_skip(&rx->ac3rbuffer[i],dummy2.length); 2396 break; 2397 case DUMMY_ERR: 2398 write(rx->dmx_out[i+1+rx->apidn],dummy.fillframe,dummy2.length); 2399 break; 2400 default: 2401 ring_read_file(&rx->ac3rbuffer[i], 2402 rx->dmx_out[i+1+rx->apidn], 2403 dummy2.length); 2404 } 2163 2405 } 2164 2406 } 2165 2407 … … 2174 2416 void do_replex(struct replex *rx) 2175 2417 { 2176 2418 int video_ok = 0; 2177 int ext_ok[N_AUDIO]; 2419 int audio_ok[N_AUDIO]; 2420 int ac3_ok[N_AC3]; 2178 2421 int start=1; 2179 2422 multiplex_t mx; 2423 int done = 0; 2180 2424 2181 2425 2182 2426 fprintf(stderr,"STARTING REPLEX\n"); 2183 2427 memset(&mx, 0, sizeof(mx)); 2184 memset(ext_ok, 0, N_AUDIO*sizeof(int)); 2428 memset(audio_ok, 0, N_AUDIO*sizeof(int)); 2429 memset(ac3_ok, 0, N_AC3*sizeof(int)); 2185 2430 2186 2431 while (!replex_all_set(rx)){ 2187 if (replex_fill_buffers(rx, 0)< 0) 2432 if (replex_fill_buffers(rx, 0)< 0){ 2188 2433 fprintf(stderr,"error filling buffer\n"); 2189 2434 exit(1); 2190 2435 } 2191 2436 } 2192 2437 2193 int i; 2194 for (i = 0; i < rx->apidn; i++){ 2195 rx->exttype[i] = 2; 2196 rx->extframe[i] = rx->aframe[i]; 2197 rx->extrbuffer[i] = rx->arbuffer[i]; 2198 rx->index_extrbuffer[i] = rx->index_arbuffer[i]; 2199 rx->exttypcnt[i+1] = i; 2200 } 2201 2202 int ac3Count = 1; 2203 for (i = rx->apidn; i < rx->apidn + rx->ac3n; i++){ 2204 rx->exttype[i] = 1; 2205 rx->extframe[i] = rx->ac3frame[i]; 2206 rx->extrbuffer[i] = rx->ac3rbuffer[i]; 2207 rx->index_extrbuffer[i] = rx->index_ac3rbuffer[i]; 2208 rx->exttypcnt[i] = ac3Count++; 2209 } 2210 2211 mx.priv = (void *) rx; 2438 mx.priv = (void *) rx; 2212 2439 rx->priv = (void *) &mx; 2213 init_multiplex(&mx, &rx->seq_head, rx->extframe, 2214 rx->exttype, rx->exttypcnt, rx->video_delay,2215 2216 &rx->vrbuffer, &rx->index_vrbuffer, 2217 rx->extrbuffer, rx->index_extrbuffer,2218 2440 init_multiplex(&mx, &rx->seq_head, rx->aframe, rx->ac3frame, 2441 rx->apidn, rx->ac3n, rx->video_delay, 2442 rx->audio_delay, rx->fd_out, fill_buffers, 2443 &rx->vrbuffer, &rx->index_vrbuffer, 2444 rx->arbuffer, rx->index_arbuffer, 2445 rx->ac3rbuffer, rx->index_ac3rbuffer, rx->otype); 2219 2446 2220 2447 if (!rx->ignore_pts){ 2221 2448 fix_audio(rx, &mx); 2222 2449 } 2223 2450 setup_multiplex(&mx); 2224 2451 2225 while(1){2226 check_times( &mx, &video_ok, ext_ok, &start);2452 do { 2453 check_times( &mx, &video_ok, audio_ok, ac3_ok, &start); 2227 2454 2228 write_out_packs( &mx, video_ok, ext_ok); 2229 } 2455 write_out_packs( &mx, video_ok, audio_ok, ac3_ok); 2456 2457 if (mx.max_reached) done = 1; 2458 if (mx.zero_write_count >100){ 2459 fprintf(stderr,"Can`t continue, check input file\n"); 2460 done=1; 2461 } 2462 } while (!done); 2463 2230 2464 } 2231 2465 2232 2466 … … 2234 2468 { 2235 2469 printf ("usage: %s [options] <input files>\n\n",progname); 2236 2470 printf ("options:\n"); 2237 printf (" --help, -h: print help message\n"); 2238 printf (" --type, -t: set output type (MPEG2, DVD, HDTV)\n"); 2239 printf (" --of, -o: set output file\n"); 2240 printf (" --input_stream, -i: set input stream type (TS(default), PS, AVI)\n"); 2241 printf (" --audio_pid, -a: audio PID for TS stream (also used for PS id)\n"); 2242 printf (" --ac3_id, -c: ID of AC3 audio for demux (also used for PS id)\n"); 2243 printf (" --video_pid, -v: video PID for TS stream (also used for PS id)\n"); 2244 printf (" --video_delay, -d: video delay in ms\n"); 2245 printf (" --audio_delay, -e: audio delay in ms\n"); 2246 printf (" --ignore_PTS, -f: ignore all PTS information of original\n"); 2247 printf (" --keep_PTS, -k: keep and don't correct PTS information of original\n"); 2248 printf (" --fix_sync, -n: try to fix audio sync while demuxing\n"); 2249 printf (" --demux, -z: demux only (-o is basename)\n"); 2250 printf (" --analyze, -y: analyze (0=video,1=audio, 2=both)\n"); 2251 printf (" --scan, -s: scan for streams\n"); 2252 printf (" --vdr, -x: handle AC3 for vdr input file\n"); 2471 printf (" --help, -h : print help message\n"); 2472 printf ("\n"); 2473 printf (" --audio_pid, -a <integer> : audio PID for TS stream (also used for PS id, default 0xc0)\n"); 2474 printf (" --ac3_id, -c <integer> : ID of AC3 audio for demux (also used for PS id, i.e. 0x80)\n"); 2475 printf (" --video_delay, -d <integer> : video delay in ms\n"); 2476 printf (" --audio_delay, -e <integer> : audio delay in ms\n"); 2477 printf (" --ignore_PTS, -f : ignore all PTS information of original\n"); 2478 printf (" --larger_buffer -g <integer> : video buffer in MB\n"); 2479 printf (" --input_stream, -i <string> : set input stream type (string = TS(default), PS, AVI)\n"); 2480 printf (" --allow_jump, -j : allow jump in the PTS and try repair\n"); 2481 printf (" --keep_PTS, -k : keep and don't correct PTS information of original\n"); 2482 printf (" --min_jump, -l <integer> : don't try to fix jumps in PTS larger than <int> but treat them as a cut (default 100ms)\n"); 2483 printf (" --of, -o <filename> : set output file\n"); 2484 printf (" --fillzero -p : fill audio frames with zeros (only MPEG AUDIO)\n"); 2485 printf (" --max_overflow -q <integer> : max_number of overflows allowed (default: 100, 0=no restriction)\n"); 2486 printf (" --scan, -s : scan for streams\n"); 2487 printf (" --type, -t <string> : set output type (string = MPEG2, DVD, HDTV)\n"); 2488 printf (" --video_pid, -v <integer> : video PID for TS stream (also used for PS id, default 0xe0)\n"); 2489 printf (" --vdr, -x : handle AC3 for vdr input file\n"); 2490 printf (" --analyze, -y <integer> : analyze (0=video,1=audio, 2=both)\n"); 2491 printf (" --demux, -z : demux only (-o is basename)\n"); 2253 2492 exit(1); 2254 2493 } 2255 2494 2256 2495 int main(int argc, char **argv) 2257 2496 { 2258 2497 int c; 2259 2498 int analyze=0; 2260 2499 int scan =0; 2261 char *filename = NULL; 2262 char *type = "SVCD"; 2263 char *inpt = "TS"; 2500 char *filename = NULL; 2501 char *type = "SVCD"; 2502 char *inpt = "TS"; 2503 int bufsize = 6*1024*1024; 2504 uint64_t min_jump=0; 2505 int fillzero = 0; 2264 2506 2265 2507 struct replex rx; 2266 2508 2509 fprintf(stderr,"replex version Myth-Internal"); 2510 2267 2511 memset(&rx, 0, sizeof(struct replex)); 2512 rx.max_overflows = 100; 2268 2513 2269 while (1) { 2270 int option_index = 0; 2271 static struct option long_options[] = { 2272 {"type", required_argument, NULL, 't'}, 2273 {"input_stream", required_argument, NULL, 'i'}, 2274 {"video_pid", required_argument, NULL, 'v'}, 2514 while (1){ 2515 int option_index = 0; 2516 static struct option long_options[] = { 2275 2517 {"audio_pid", required_argument, NULL, 'a'}, 2518 {"ac3_id", required_argument, NULL, 'c'}, 2519 {"video_delay", required_argument, NULL, 'd'}, 2276 2520 {"audio_delay", required_argument, NULL, 'e'}, 2277 {"video_delay", required_argument, NULL, 'd'},2278 {"ac3_id", required_argument, NULL, 'c'},2279 {"of",required_argument, NULL, 'o'},2280 2521 {"ignore_PTS",required_argument, NULL, 'f'}, 2522 {"larger_buffer",required_argument, NULL, 'g'}, 2523 {"help", no_argument , NULL, 'h'}, 2524 {"input_stream", required_argument, NULL, 'i'}, 2525 {"allow_jump",required_argument, NULL, 'j'}, 2281 2526 {"keep_PTS",required_argument, NULL, 'k'}, 2282 {"fix_sync",no_argument, NULL, 'n'}, 2283 {"demux",no_argument, NULL, 'z'}, 2284 {"analyze",required_argument, NULL, 'y'}, 2527 {"min_jump",required_argument, NULL, 'l'}, 2528 {"of",required_argument, NULL, 'o'}, 2529 {"fillzero",required_argument, NULL, 'p'}, 2530 {"max_overflow",required_argument, NULL, 'q'}, 2285 2531 {"scan",required_argument, NULL, 's'}, 2532 {"type", required_argument, NULL, 't'}, 2533 {"video_pid", required_argument, NULL, 'v'}, 2286 2534 {"vdr",required_argument, NULL, 'x'}, 2287 {"help", no_argument , NULL, 'h'}, 2535 {"analyze",required_argument, NULL, 'y'}, 2536 {"demux",no_argument, NULL, 'z'}, 2288 2537 {0, 0, 0, 0} 2289 2538 }; 2290 2291 "t:o:a:v:i:hp:q:d:c:n:fkd:e:zy:sx",2539 c = getopt_long (argc, argv, 2540 "a:c:d:e:fg:hi:jkl:o:pq:st:v:xy:z", 2292 2541 long_options, &option_index); 2293 2294 2542 if (c == -1) 2543 break; 2295 2544 2296 switch (c) { 2297 case 't': 2298 type = optarg; 2299 break; 2300 case 'i': 2301 inpt = optarg; 2302 break; 2303 case 'd': 2304 rx.video_delay = strtol(optarg,(char **)NULL, 0) 2305 *CLOCK_MS; 2306 break; 2307 case 'e': 2308 rx.audio_delay = strtol(optarg,(char **)NULL, 0) 2309 *CLOCK_MS; 2310 break; 2311 case 'a': 2545 switch (c){ 2546 case 'a': 2312 2547 if (rx.apidn==N_AUDIO){ 2313 2548 fprintf(stderr,"Too many audio PIDs\n"); 2314 2549 exit(1); 2315 2550 } 2316 2551 rx.apid[rx.apidn] = strtol(optarg,(char **)NULL, 0); 2317 2552 rx.apidn++; 2318 break; 2319 case 'v': 2320 rx.vpid = strtol(optarg,(char **)NULL, 0); 2321 break; 2322 case 'c': 2553 break; 2554 case 'c': 2323 2555 if (rx.ac3n==N_AC3){ 2324 2556 fprintf(stderr,"Too many audio PIDs\n"); 2325 2557 exit(1); 2326 2558 } 2327 2559 rx.ac3_id[rx.ac3n] = strtol(optarg,(char **)NULL, 0); 2328 2560 rx.ac3n++; 2561 break; 2562 case 'd': 2563 rx.video_delay = strtol(optarg,(char **)NULL, 0) 2564 *CLOCK_MS; 2329 2565 break; 2330 case 'o': 2331 filename = optarg; 2566 case 'e': 2567 rx.audio_delay = strtol(optarg,(char **)NULL, 0) 2568 *CLOCK_MS; 2332 2569 break; 2333 2570 case 'f': 2334 2571 rx.ignore_pts =1; 2335 2572 break; 2573 case 'g': 2574 bufsize = strtol(optarg,(char **)NULL, 0) *1024*1024; 2575 break; 2576 case 'i': 2577 inpt = optarg; 2578 break; 2579 case 'j': 2580 rx.allow_jump = MIN_JUMP; 2581 break; 2336 2582 case 'k': 2337 2583 rx.keep_pts =1; 2338 2584 break; 2339 case ' z':2340 rx.demux =1;2585 case 'l': 2586 min_jump = strtol(optarg,(char **)NULL, 0) *CLOCK_MS; 2341 2587 break; 2342 case 'n': 2343 rx.fix_sync =1; 2588 case 'o': 2589 filename = optarg; 2590 break; 2591 case 'p': 2592 fillzero = 1; 2344 2593 break; 2345 case 'y': 2346 analyze = strtol(optarg,(char **)NULL, 0); 2347 if (analyze>2) usage(argv[0]); 2348 analyze++; 2594 case 'q': 2595 rx.max_overflows = strtol(optarg,(char **)NULL, 0); 2349 2596 break; 2350 2597 case 's': 2351 2598 scan = 1; 2352 2599 break; 2600 case 't': 2601 type = optarg; 2602 break; 2603 case 'v': 2604 rx.vpid = strtol(optarg,(char **)NULL, 0); 2605 break; 2353 2606 case 'x': 2354 2607 rx.vdr=1; 2355 2608 break; 2356 case 'h': 2357 case '?': 2358 default: 2359 usage(argv[0]); 2609 case 'y': 2610 analyze = strtol(optarg,(char **)NULL, 0); 2611 if (analyze>2) usage(argv[0]); 2612 analyze++; 2613 break; 2614 case 'z': 2615 rx.demux = 1; 2616 break; 2617 case 'h': 2618 case '?': 2619 default: 2620 usage(argv[0]); 2621 } 2622 } 2623 2624 if (rx.allow_jump && min_jump) rx.allow_jump = min_jump; 2625 2626 if (fillzero) rx.fillzero = 1; 2627 rx.inputFiles = NULL; 2628 if (optind < argc){ 2629 int i = 0; 2630 rx.inputFiles = calloc( sizeof(char * ), argc - optind + 1); 2631 while (optind < argc) { 2632 if ((rx.fd_in = open(argv[optind] ,O_RDONLY| O_LARGEFILE)) < 0){ 2633 fprintf(stderr,"Error opening input file %s",argv[optind] ); 2634 exit(1); 2635 } 2636 close(rx.fd_in); 2637 rx.inputFiles[i] = argv[optind]; 2638 i++; 2639 optind++; 2360 2640 } 2361 } 2362 2363 if (rx.fix_sync) 2364 av_register_all(); 2365 2366 if (optind == argc-1) { 2367 if ((rx.fd_in = open(argv[optind] ,O_RDONLY| O_LARGEFILE)) < 0) { 2368 perror("Error opening input file "); 2641 rx.inputFiles[i] = NULL; 2642 rx.inputIdx = 0; 2643 if ((rx.fd_in = open(rx.inputFiles[0] ,O_RDONLY| O_LARGEFILE)) < 0) { 2644 fprintf(stderr,"Error opening input file %s",argv[optind] ); 2369 2645 exit(1); 2370 2646 } 2371 fprintf(stderr,"Reading from %s\n", argv[optind]); 2647 2648 fprintf(stderr,"Reading from %s\n", argv[optind]); 2372 2649 rx.inflength = lseek(rx.fd_in, 0, SEEK_END); 2373 2650 fprintf(stderr,"Input file length: %.2f MB\n",rx.inflength/1024./1024.); 2374 2651 lseek(rx.fd_in,0,SEEK_SET); 2375 2652 rx.lastper = 0; 2376 2653 rx.finread = 0; 2377 2654 } else { 2378 2655 fprintf(stderr,"using stdin as input\n"); 2379 2656 rx.fd_in = STDIN_FILENO; 2380 2657 rx.inflength = 0; 2381 2658 } 2382 2659 2383 2660 if (!rx.demux){ 2384 2661 if (filename){ 2385 2662 if ((rx.fd_out = open(filename,O_WRONLY|O_CREAT 2386 |O_TRUNC|O_LARGEFILE,2387 S_IRUSR|S_IWUSR|S_IRGRP|2388 S_IWGRP|2389 S_IROTH|S_IWOTH)) < 0){2663 |O_TRUNC|O_LARGEFILE, 2664 S_IRUSR|S_IWUSR|S_IRGRP| 2665 S_IWGRP| 2666 S_IROTH|S_IWOTH)) < 0){ 2390 2667 perror("Error opening output file"); 2391 2668 exit(1); 2392 2669 } … … 2406 2683 exit(0); 2407 2684 } 2408 2685 2409 2686 if (!strncmp(type,"MPEG2",6)) 2410 2687 rx.otype=REPLEX_MPEG2; 2411 2688 else if (!strncmp(type,"DVD",4)) 2412 2689 rx.otype=REPLEX_DVD; 2413 2690 else if (!strncmp(type,"HDTV",4)) 2414 2691 rx.otype=REPLEX_HDTV; 2415 else if (!rx.demux)2416 2692 else if (!rx.demux && !analyze) 2693 usage(argv[0]); 2417 2694 2418 2695 if (!strncmp(inpt,"TS",3)){ 2419 2696 rx.itype=REPLEX_TS; 2420 2697 } else if (!strncmp(inpt,"PS",3)){ 2421 2698 rx.itype=REPLEX_PS; … … 2431 2708 rx.apid[0] = 0xC0; 2432 2709 rx.ignore_pts =1; 2433 2710 } else { 2434 2711 usage(argv[0]); 2435 2712 } 2436 2713 2437 init_replex(&rx );2714 init_replex(&rx, bufsize); 2438 2715 rx.analyze= analyze; 2439 2716 2440 if (rx.demux) 2717 if (rx.demux){ 2441 2718 int i; 2442 2719 char fname[256]; 2443 2720 if (!filename){ … … 2504 2781 } else { 2505 2782 do_replex(&rx); 2506 2783 } 2507 2784 2508 2785 return 0; 2509 2786 } -
programs/mythtranscode/replex/mpg_common.h
2 2 * mpg_common.h 3 3 * 4 4 * 5 * Copyright (C) 2003 Marcus Metzler <mocm@metzlerbros.de> 5 * Copyright (C) 2003 - 2006 6 * Marcus Metzler <mocm@metzlerbros.de> 6 7 * Metzler Brothers Systementwicklung GbR 8 * (C) 2006 Reel Multimedia 7 9 * 8 10 * This program is free software; you can redistribute it and/or 9 11 * modify it under the terms of the GNU General Public License … … 47 49 uint8_t frame_off; 48 50 uint8_t frame_start; 49 51 uint8_t err; 50 uint32_tframesize;51 uint 64_t ptsrate;52 int framesize; 53 uint8_t *fillframe; 52 54 } index_unit; 53 55 54 typedef struct extdata_s{55 index_unit iu;56 uint64_t pts;57 uint64_t pts_off;58 int type;59 int strmnum;60 int frmperpkt;61 char language[4];62 dummy_buffer dbuf;63 } extdata_t;64 65 66 56 #define NO_ERR 0 67 57 #define FRAME_ERR 1 58 #define PTS_ERR 2 59 #define JUMP_ERR 3 60 #define DUMMY_ERR 4 61 #define DROP_ERR 5 68 62 69 70 63 void show_buf(uint8_t *buf, int length); 71 64 int find_mpg_header(uint8_t head, uint8_t *buf, int length); 72 65 int find_any_header(uint8_t *head, uint8_t *buf, int length); 73 66 uint64_t trans_pts_dts(uint8_t *pts); 74 int mring_peek( ringbuffer *rbuf, uint8_t *buf, unsigned int l, uint32_toff);67 int mring_peek( ringbuffer *rbuf, uint8_t *buf, int l, long off); 75 68 int ring_find_mpg_header(ringbuffer *rbuf, uint8_t head, int off, int le); 76 69 int ring_find_any_header(ringbuffer *rbuf, uint8_t *head, int off, int le); 77 70 -
programs/mythtranscode/replex/replex.h
2 2 * replex.h 3 3 * 4 4 * 5 * Copyright (C) 2003 Marcus Metzler <mocm@metzlerbros.de> 5 * Copyright (C) 2003 - 2006 6 * Marcus Metzler <mocm@metzlerbros.de> 6 7 * Metzler Brothers Systementwicklung GbR 8 * (C) 2006 Reel Multimedia 7 9 * 8 10 * This program is free software; you can redistribute it and/or 9 11 * modify it under the terms of the GNU General Public License … … 36 38 #include "multiplex.h" 37 39 38 40 enum { S_SEARCH, S_FOUND, S_ERROR }; 41 #define MIN_JUMP 100*CLOCK_MS; 42 #define MAXFRAME 2000 39 43 40 44 struct replex { 41 45 #define REPLEX_TS 0 … … 45 49 int otype; 46 50 int ignore_pts; 47 51 int keep_pts; 48 int fix_sync;52 uint64_t allow_jump; 49 53 uint64_t inflength; 50 54 uint64_t finread; 51 55 int lastper; … … 59 63 int analyze; 60 64 avi_context ac; 61 65 int vdr; 66 int fillzero; 67 int overflows; 68 int max_overflows; 62 69 63 70 uint64_t video_delay; 64 71 uint64_t audio_delay; 65 72 66 #define VIDEO_BUF (6*1024*1024)67 #define AUDIO_BUF (VIDEO_BUF/10)68 #define AC3_BUF (VIDEO_BUF/10)69 73 #define INDEX_BUF (32000*32) 74 70 75 int audiobuf; 71 76 int ac3buf; 72 77 int videobuf; 73 78 74 int ext_count;75 int exttype[N_AUDIO];76 int exttypcnt[N_AUDIO];77 audio_frame_t extframe[N_AUDIO];78 ringbuffer extrbuffer[N_AUDIO];79 ringbuffer index_extrbuffer[N_AUDIO];80 81 79 //ac3 82 80 int ac3n; 83 81 uint16_t ac3_id[N_AC3]; … … 91 89 uint64_t first_ac3pts[N_AC3]; 92 90 int ac3_state[N_AUDIO]; 93 91 uint64_t last_ac3pts[N_AC3]; 92 uint64_t ac3_jump[N_AUDIO]; 93 uint64_t ac3pts_off[N_AC3]; 94 uint8_t ac3fillframe[N_AC3][MAXFRAME]; 95 int ac3filled[N_AC3]; 94 96 97 95 98 // mpeg audio 96 99 int apidn; 97 100 uint16_t apid[N_AUDIO]; … … 105 108 uint64_t first_apts[N_AUDIO]; 106 109 int audio_state[N_AUDIO]; 107 110 uint64_t last_apts[N_AUDIO]; 111 uint64_t audio_jump[N_AUDIO]; 112 uint64_t apts_off[N_AUDIO]; 113 uint8_t afillframe[N_AC3][MAXFRAME]; 114 int afilled[N_AC3]; 108 115 109 116 //mpeg video 110 117 uint16_t vpid; … … 120 127 uint64_t first_vpts; 121 128 int video_state; 122 129 uint64_t last_vpts; 130 uint64_t video_jump; 131 uint64_t vjump_pts; 123 132 124 133 void *priv; 125 134 int scan_found; 135 char **inputFiles; 136 int inputIdx; 126 137 }; 127 138 128 139 void init_index(index_unit *iu); -
programs/mythtranscode/replex/README
6 6 usage: ./replex [options] <input files> 7 7 8 8 options: 9 --help, -h: print help message 10 --type, -t: set output type (MPEG2, DVD, HDTV) 11 --of, -o: set output file 12 --input_stream, -i: set input stream type (TS(default), PS, AVI) 13 --audio_pid, -a: audio PID for TS stream (also used for PS id) 14 --ac3_id, -c: ID of AC3 audio for demux (also used for PS id) 15 --video_pid, -v: video PID for TS stream (also used for PS id) 16 --video_delay, -d: video delay in ms 17 --audio_delay, -e: audio delay in ms 18 --ignore_PTS, -f: ignore all PTS information of original 19 --keep_PTS, -k: keep and don't correct PTS information of original 20 --demux, -z: demux only (-o is basename) 21 --analyze, -y: analyze (0=video,1=audio, 2=both) 22 --scan, -s: scan for streams 23 --vdr, -x: handle AC3 for vdr input file 9 --help, -h : print help message 24 10 11 --audio_pid, -a <integer> : audio PID for TS stream (also used for PS id, default 0xc0) 12 --ac3_id, -c <integer> : ID of AC3 audio for demux (also used for PS id, i.e. 0x80) 13 --video_delay, -d <integer> : video delay in ms 14 --audio_delay, -e <integer> : audio delay in ms 15 --ignore_PTS, -f : ignore all PTS information of original 16 --larger_buffer -g <integer> : video buffer in MB 17 --input_stream, -i <string> : set input stream type (string = TS(default), PS, AVI) 18 --allow_jump, -j : allow jump in the PTS and try repair 19 --keep_PTS, -k : keep and don't correct PTS information of original 20 --min_jump, -l <integer> : don't try to fix jumps in PTS larger than <int> but treat them as a cut (default 100ms) 21 --of, -o <filename> : set output file 22 --fillzero -p : fill audio frames with zeros (only MPEG AUDIO) 23 --max_overflow -q <integer> : max_number of overflows allowed (default: 100, 0=no restriction) 24 --scan, -s : scan for streams 25 --type, -t <string> : set output type (string = MPEG2, DVD, HDTV) 26 --video_pid, -v <integer> : video PID for TS stream (also used for PS id, default 0xe0) 27 --vdr, -x : handle AC3 for vdr input file 28 --analyze, -y <integer> : analyze (0=video,1=audio, 2=both) 29 --demux, -z : demux only (-o is basename) 30 25 31 A typical call would be 26 32 replex -t DVD -o mynewps.mpg myoldts.ts 27 33 28 34 Replex can guess the PIDs of your audio and video streams, but 29 35 especially if you have more than one audio stream you should use the 30 36 -v and -a or -c options. The -a and -c options can be used more than 31 once to create multiple audio tracks. 37 once to create multiple audio tracks. Use the -s option to find out 38 about the PIDs in your file 32 39 33 40 The -k option means that replex tries to keep the original PTS spacing, 34 41 which can be helpful in case of corrupt streams. Replex will ignore … … 39 46 from t]he original and creates the PTS according to the frames that are 40 47 found. 41 48 49 The -j option lets replex jump over PTS discontiniuties like the ones 50 you get from cutting an MPEG file. With -l you can set the minimum time 51 a jump has to have to get treated as cut. The default for that is 100ms. 52 If you have video jumps without any audio jumps and they are larger than 53 100ms (usually > 2 frames) you can try increasing the min_jump setting. 54 If you set it too high and you have real jumps, e.g. audio and video 55 jumps from a cut, they may not get fixed correctly. 56 57 58 The -g option can be helpful if you get ringbuffer overflows, it increases 59 the video buffer size. Default is 6MB. 60 42 61 For questions and/or suggestions contact me at mocm@metzlerbros.de. -
programs/mythtranscode/replex/avi.c
2 2 * avi.c: AVI container functions for replex 3 3 * 4 4 * 5 * Copyright (C) 2003 Marcus Metzler <mocm@metzlerbros.de> 5 * Copyright (C) 2003 - 2006 6 * Marcus Metzler <mocm@metzlerbros.de> 6 7 * Metzler Brothers Systementwicklung GbR 7 8 * 8 9 * This program is free software; you can redistribute it and/or -
programs/mythtranscode/replex/multiplex.c
1 /* 2 * multiplex.c: multiplex functions for replex 3 * 4 * 5 * Copyright (C) 2003 - 2006 6 * Marcus Metzler <mocm@metzlerbros.de> 7 * Metzler Brothers Systementwicklung GbR 8 * (C) 2006 Reel Multimedia 9 * 10 * This program is free software; you can redistribute it and/or 11 * modify it under the terms of the GNU General Public License 12 * as published by the Free Software Foundation; either version 2 13 * of the License, or (at your option) any later version. 14 * 15 * 16 * This program is distributed in the hope that it will be useful, 17 * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 * General Public License for more details. 20 * 21 * 22 * You should have received a copy of the GNU General Public License 23 * along with this program; if not, write to the Free Software 24 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 25 * Or, point your browser to http://www.gnu.org/copyleft/gpl.html 26 * 27 */ 28 1 29 #include <unistd.h> 2 30 #include <string.h> 3 31 #include <stdlib.h> … … 3 31 4 32 #include "multiplex.h" 5 #include "ts.h"6 33 34 35 static int mplx_write(multiplex_t *mx, uint8_t *buffer,int length) 36 { 37 int k=0; 38 39 if ( mx->max_write && mx->total_written+ length > 40 mx-> max_write && !mx->max_reached){ 41 mx->max_reached = 1; 42 fprintf(stderr,"Maximum file size %dKB reached\n", mx->max_write/1024); 43 return 0; 44 } 45 if ((k=write(mx->fd_out, buffer, length)) <= 0){ 46 mx->zero_write_count++; 47 } else { 48 mx->total_written += k; 49 } 50 return k; 51 } 52 7 53 static int buffers_filled(multiplex_t *mx) 8 54 { … … 11 57 12 58 vavail = ring_avail(mx->index_vrbuffer)/sizeof(index_unit); 13 59 14 for (i=0; i<mx->extcnt;i++){ 15 aavail += ring_avail(&mx->index_extrbuffer[i])/ 16 sizeof(index_unit); 60 for (i=0; i<mx->apidn;i++){ 61 aavail += ring_avail(&mx->index_arbuffer[i])/sizeof(index_unit); 17 62 } 18 63 64 for (i=0; i<mx->ac3n;i++){ 65 aavail += ring_avail(&mx->index_ac3rbuffer[i]) 66 /sizeof(index_unit); 67 } 19 68 if (aavail+vavail) return ((aavail+vavail)); 20 69 return 0; 21 70 } 22 71 23 static int use_video(uint64_t vpts, extdata_t *ext,int *aok, int n)72 static int all_audio_ok(int *aok, int n) 24 73 { 25 int i; 26 for(i=0; i < n; i++) 27 if(aok[i] && ptscmp(vpts,ext[i].pts) > 0) 28 return 0; 29 return 1; 74 int ok=0,i; 75 76 if (!n) return 0; 77 for (i=0; i < n ;i++){ 78 if (aok[i]) ok ++; 79 } 80 if (ok == n) return 1; 81 return 0; 30 82 } 31 static int which_ext(extdata_t *ext, int *aok, int n) 83 84 static int rest_audio_ok(int j, int *aok, int n) 32 85 { 33 int i; 34 int started = 0; 35 int pos = -1; 36 uint64_t tmppts = 0; 37 for(i=0; i < n; i++) 38 if(aok[i]){ 39 if(! started){ 40 started=1; 41 tmppts=ext[i].pts; 42 pos = i; 43 } else if(ptscmp(tmppts, ext[i].pts) > 0) { 44 tmppts = ext[i].pts; 45 pos = i; 46 } 47 } 48 return pos; 86 int ok=0,i; 87 88 if (!(n-1)) return 0; 89 for (i=0; i < n ;i++){ 90 if (i!=j && aok[i]) ok ++; 91 } 92 if (ok == n) return 1; 93 return 0; 49 94 } 50 95 51 static int peek_next_video_unit(multiplex_t *mx, index_unit *viu)96 static int get_next_video_unit(multiplex_t *mx, index_unit *viu) 52 97 { 53 98 if (!ring_avail(mx->index_vrbuffer) && mx->finish) return 0; 54 99 55 100 while (ring_avail(mx->index_vrbuffer) < sizeof(index_unit)) 56 101 if (mx->fill_buffers(mx->priv, mx->finish)< 0) { 57 fprintf(stderr,"error in peeknext video unit\n");102 fprintf(stderr,"error in get next video unit\n"); 58 103 return 0; 59 104 } 60 105 61 ring_ peek(mx->index_vrbuffer, (uint8_t *)viu, sizeof(index_unit),0);106 ring_read(mx->index_vrbuffer, (uint8_t *)viu, sizeof(index_unit)); 62 107 #ifdef OUT_DEBUG 63 108 fprintf(stderr,"video index start: %d stop: %d (%d) rpos: %d\n", 64 109 viu->start, (viu->start+viu->length), … … 67 112 68 113 return 1; 69 114 } 70 71 static int get_next_video_unit(multiplex_t *mx, index_unit *viu)115 116 static int peek_next_video_unit(multiplex_t *mx, index_unit *viu) 72 117 { 73 index_unit nviu;74 118 if (!ring_avail(mx->index_vrbuffer) && mx->finish) return 0; 75 119 76 120 while (ring_avail(mx->index_vrbuffer) < sizeof(index_unit)) 77 121 if (mx->fill_buffers(mx->priv, mx->finish)< 0) { 78 fprintf(stderr,"error in getnext video unit\n");122 fprintf(stderr,"error in peek next video unit\n"); 79 123 return 0; 80 124 } 81 125 82 ring_ read(mx->index_vrbuffer, (uint8_t *)viu, sizeof(index_unit));126 ring_peek(mx->index_vrbuffer, (uint8_t *)viu, sizeof(index_unit),0); 83 127 #ifdef OUT_DEBUG 84 128 fprintf(stderr,"video index start: %d stop: %d (%d) rpos: %d\n", 85 129 viu->start, (viu->start+viu->length), 86 130 viu->length, ring_rpos(mx->vrbuffer)); 87 131 #endif 88 if(! peek_next_video_unit(mx, &nviu)) 89 return 1; 90 //left-shift by 8 to increase precision 91 viu->ptsrate = (uptsdiff(nviu.dts, viu->dts) << 8) / viu->length; 132 92 133 return 1; 93 134 } 94 95 static int peek_next_ext_unit(multiplex_t *mx, index_unit *extiu, int i)135 136 static int get_next_audio_unit(multiplex_t *mx, index_unit *aiu, int i) 96 137 { 97 if (!ring_avail(&mx->index_ extrbuffer[i]) && mx->finish) return 0;138 if (!ring_avail(&mx->index_arbuffer[i]) && mx->finish) return 0; 98 139 99 while (ring_avail(&mx->index_extrbuffer[i]) < sizeof(index_unit))140 while(ring_avail(&mx->index_arbuffer[i]) < sizeof(index_unit)) 100 141 if (mx->fill_buffers(mx->priv, mx->finish)< 0) { 101 fprintf(stderr,"error in peek next video unit\n");142 fprintf(stderr,"error in get next audio unit\n"); 102 143 return 0; 103 144 } 145 146 ring_read(&mx->index_arbuffer[i], (uint8_t *)aiu, sizeof(index_unit)); 104 147 105 ring_peek(&mx->index_extrbuffer[i], (uint8_t *)extiu,106 sizeof(index_unit),0);107 148 #ifdef OUT_DEBUG 108 fprintf(stderr," extindex start: %d stop: %d (%d) rpos: %d\n",109 extiu->start, (extiu->start+extiu->length),110 extiu->length, ring_rpos(mx->extrbuffer));149 fprintf(stderr,"audio index start: %d stop: %d (%d) rpos: %d\n", 150 aiu->start, (aiu->start+aiu->length), 151 aiu->length, ring_rpos(&mx->arbuffer[i])); 111 152 #endif 112 113 153 return 1; 114 154 } 115 116 static int get_next_ ext_unit(multiplex_t *mx, index_unit *extiu, int i)155 156 static int get_next_ac3_unit(multiplex_t *mx, index_unit *aiu, int i) 117 157 { 118 index_unit niu, *piu = extiu; 119 int j, length = 0; 120 for(j = 0; j < mx->ext[i].frmperpkt; j++) { 121 if (!ring_avail(&mx->index_extrbuffer[i]) && mx->finish) 122 break; 123 124 while(ring_avail(&mx->index_extrbuffer[i]) < sizeof(index_unit)) 125 if (mx->fill_buffers(mx->priv, mx->finish)< 0) { 126 fprintf(stderr,"error in get next ext unit\n"); 127 break; 128 } 158 if (!ring_avail(&mx->index_ac3rbuffer[i]) && mx->finish) return 0; 159 while(ring_avail(&mx->index_ac3rbuffer[i]) < sizeof(index_unit)) 160 if (mx->fill_buffers(mx->priv, mx->finish)< 0) { 161 fprintf(stderr,"error in get next ac3 unit\n"); 162 return 0; 163 } 129 164 130 ring_read(&mx->index_extrbuffer[i], (uint8_t *)piu, 131 sizeof(index_unit)); 132 length += piu->length; 133 piu = &niu; 134 } 135 if (j == 0) 136 return 0; 137 extiu->length = length; 138 extiu->framesize = length; 139 if(! peek_next_ext_unit(mx, &niu, i)) 140 return 1; 141 //left-shift by 8 to increase precision 142 extiu->ptsrate = (uptsdiff(niu.pts, extiu->pts) << 8) / extiu->length; 143 144 #ifdef OUT_DEBUG 145 fprintf(stderr,"ext index start: %d stop: %d (%d) rpos: %d\n", 146 extiu->start, (extiu->start+extiu->length), 147 extiu->length, ring_rpos(&mx->extrbuffer[i])); 148 #endif 165 ring_read(&mx->index_ac3rbuffer[i], (uint8_t *)aiu, sizeof(index_unit)); 149 166 return 1; 150 167 } 151 168 152 static uint8_t get_ptsdts(multiplex_t *mx, index_unit *viu)153 {154 uint8_t ptsdts = 0;155 switch (mx->frame_timestamps){156 case TIME_ALWAYS:157 if (viu->frame == I_FRAME || viu->frame == P_FRAME)158 ptsdts = PTS_DTS;159 else160 ptsdts = PTS_ONLY;161 break;162 163 case TIME_IFRAME:164 if (viu->frame == I_FRAME)165 ptsdts = PTS_DTS;166 break;167 }168 return ptsdts;169 }170 171 169 static void writeout_video(multiplex_t *mx) 172 170 { 173 171 uint8_t outbuf[3000]; 174 172 int written=0; 175 173 uint8_t ptsdts=0; 176 unsignedint length;174 int length; 177 175 int nlength=0; 178 int frame_len=0;179 176 index_unit *viu = &mx->viu; 180 177 181 178 #ifdef OUT_DEBUG 182 fprintf(stderr,"writing VIDEO pack \n");179 fprintf(stderr,"writing VIDEO pack"); 183 180 #endif 184 185 if(viu->frame_start) { 186 ptsdts = get_ptsdts(mx, viu); 187 frame_len = viu->length; 188 } 189 181 190 182 if (viu->frame_start && viu->seq_header && viu->gop && 191 183 viu->frame == I_FRAME){ 192 if (!mx->startup && mx->is_ts){ 193 write_ts_patpmt(mx->ext, mx->extcnt, 1, outbuf); 194 write(mx->fd_out, outbuf, mx->pack_size*2); 195 ptsinc(&mx->SCR, mx->SCRinc*2); 196 } else if (!mx->startup && mx->navpack){ 197 write_nav_pack(mx->pack_size, mx->extcnt, 184 if (!mx->startup && mx->navpack){ 185 write_nav_pack(mx->pack_size, mx->apidn, mx->ac3n, 198 186 mx->SCR, mx->muxr, outbuf); 199 write(mx->fd_out, outbuf, mx->pack_size);187 mplx_write(mx, outbuf, mx->pack_size); 200 188 ptsinc(&mx->SCR, mx->SCRinc); 201 189 } else mx->startup = 0; 202 190 #ifdef OUT_DEBUG … … 207 195 if (mx->finish != 2 && dummy_space(&mx->vdbuf) < mx->data_size){ 208 196 return; 209 197 } 198 210 199 length = viu->length; 211 while (!mx->is_ts && length < mx->data_size){ 200 if (length < mx->data_size ) 201 dummy_add(&mx->vdbuf, uptsdiff(viu->dts+mx->video_delay,0) 202 , length); 203 204 while (length < mx->data_size ){ 212 205 index_unit nviu; 213 int old_start = viu->frame_start;214 int old_frame = viu->frame;215 uint64_t old_pts = viu->pts;216 uint64_t old_dts = viu->dts;217 dummy_add(&mx->vdbuf, uptsdiff(viu->dts+mx->video_delay,0)218 , viu->length);219 206 if ( peek_next_video_unit(mx, &nviu)){ 220 207 if (!(nviu.seq_header && nviu.gop && 221 208 nviu.frame == I_FRAME)){ 222 209 get_next_video_unit(mx, viu); 223 frame_len = viu->length;224 210 length += viu->length; 225 if(old_start) { 226 viu->pts = old_pts; 227 viu->dts = old_dts; 228 viu->frame = old_frame; 229 } else { 230 ptsdts = get_ptsdts(mx, viu); 231 } 211 if (length < mx->data_size ) 212 dummy_add(&mx->vdbuf, 213 uptsdiff(viu->dts+ 214 mx->video_delay,0) 215 , viu->length); 232 216 } else break; 233 217 } else break; 234 218 } 235 219 236 220 if (viu->frame_start){ 221 switch (mx->frame_timestamps){ 222 case TIME_ALWAYS: 223 if (viu->frame == I_FRAME || viu->frame == P_FRAME) 224 ptsdts = PTS_DTS; 225 else 226 ptsdts = PTS_ONLY; 227 break; 228 229 case TIME_IFRAME: 230 if (viu->frame == I_FRAME) 231 ptsdts = PTS_DTS; 232 break; 233 } 237 234 viu->frame_start=0; 238 if (viu->gop){239 uint8_t gop[8];240 frame_len=length-frame_len;241 ring_peek(mx->vrbuffer, gop, 8, frame_len);242 pts2time( viu->pts + mx->video_delay, gop, 8);243 ring_poke(mx->vrbuffer, gop, 8, frame_len);244 viu->gop=0;245 }246 235 if (mx->VBR) { 247 236 mx->extra_clock = ptsdiff(viu->dts + mx->video_delay, 248 237 mx->SCR + 500*CLOCK_MS); 249 #ifdef OUT_DEBUG 1238 #ifdef OUT_DEBUG 250 239 fprintf(stderr,"EXTRACLOCK2: %lli %lli %lli\n", viu->dts, mx->video_delay, mx->SCR); 251 240 fprintf(stderr,"EXTRACLOCK2: %lli ", mx->extra_clock); 252 241 printpts(mx->extra_clock); … … 260 249 261 250 262 251 nlength = length; 263 if (mx->is_ts) 264 written = write_video_ts( viu->pts+mx->video_delay, 265 viu->dts+mx->video_delay, 266 mx->SCR, outbuf, &nlength, 267 ptsdts, mx->vrbuffer); 268 else 269 written = write_video_pes( mx->pack_size, mx->extcnt, 270 viu->pts+mx->video_delay, 271 viu->dts+mx->video_delay, 272 mx->SCR, mx->muxr, outbuf, &nlength, 273 ptsdts, mx->vrbuffer); 252 written = write_video_pes( mx->pack_size, mx->apidn, mx->ac3n, 253 viu->pts+mx->video_delay, 254 viu->dts+mx->video_delay, 255 mx->SCR, mx->muxr, outbuf, &nlength, ptsdts, 256 mx->vrbuffer); 274 257 275 // something bad happened with the PES or TS write, bail276 if (written == -1)277 return;278 279 258 length -= nlength; 280 259 dummy_add(&mx->vdbuf, uptsdiff( viu->dts+mx->video_delay,0) 281 260 , viu->length-length); 282 261 viu->length = length; 262 if (viu->gop){ 263 pts2time( viu->pts + mx->video_delay, outbuf, written); 264 } 283 265 284 //estimate next pts based on bitrate of this stream and data written 285 viu->dts = uptsdiff(viu->dts + ((nlength*viu->ptsrate)>>8), 0); 266 mplx_write(mx, outbuf, written); 267 268 if (viu->length == 0){ 269 get_next_video_unit(mx, viu); 270 } 286 271 287 write(mx->fd_out, outbuf, written); 272 } 288 273 274 275 #define INSIZE 6000 276 int add_to_inbuf(uint8_t *inbuf,ringbuffer *arbuffer, int inbc, int off, int length) 277 { 278 int add; 279 280 if (inbc + length > INSIZE) { 281 fprintf(stderr,"buffer too small in write_out_audio %d %d\n",inbc,length); 282 return 0; 283 } 284 add= ring_peek( arbuffer, inbuf+inbc, length, off); 285 if (add < length) { 286 fprintf(stderr,"error while peeking audio ring %d (%d)\n", add,length); 287 return 0; 288 } 289 return add; 290 } 291 292 293 static void clear_audio(multiplex_t *mx, int type, int n) 294 { 295 index_unit *aiu; 296 int g=0; 297 ringbuffer *arbuffer; 298 299 switch (type){ 300 301 case MPEG_AUDIO: 289 302 #ifdef OUT_DEBUG 290 fprintf(stderr,"VPTS"); 291 printpts(viu->pts); 292 fprintf(stderr," DTS"); 293 printpts(viu->dts); 294 printpts(mx->video_delay); 295 fprintf(stderr,"\n"); 303 fprintf(stderr,"clear AUDIO%d pack\n",n); 296 304 #endif 297 298 if (viu->length == 0){ 299 get_next_video_unit(mx, viu); 305 arbuffer = &mx->arbuffer[n]; 306 aiu = &mx->aiu[n]; 307 break; 308 309 case AC3: 310 #ifdef OUT_DEBUG 311 fprintf(stderr,"clear AC3%d pack\n",n); 312 #endif 313 arbuffer = &mx->ac3rbuffer[n]; 314 aiu = &mx->ac3iu[n]; 315 break; 316 317 default: 318 return; 300 319 } 320 while (aiu->err == JUMP_ERR){ 321 // fprintf(stderr,"FOUND ONE\n"); 322 ring_skip(arbuffer, aiu->length); 323 if (type == MPEG_AUDIO) 324 g = get_next_audio_unit(mx, aiu, n); 325 else 326 g = get_next_ac3_unit(mx, aiu, n); 327 } 301 328 302 329 } 303 330 304 static void writeout_ext(multiplex_t *mx, int n) 331 332 333 static void my_memcpy(uint8_t *target, int offset, uint8_t *source, int length, int maxlength) 334 { 335 uint8_t *targ = NULL; 336 337 targ = target + offset; 338 339 if ( offset+length > maxlength){ 340 fprintf(stderr,"WARNING: buffer overflow in my_memcopy \n"); 341 // fprintf(stderr, "source 0x%x offset %d target 0x%x length %d maxlength %d\n" 342 // , source, offset, target, length, maxlength); 343 } 344 memcpy(targ, source, length); 345 } 346 347 348 static void writeout_audio(multiplex_t *mx, int type, int n) 305 349 { 306 350 uint8_t outbuf[3000]; 351 uint8_t inbuf[INSIZE]; 352 int inbc=0; 307 353 int written=0; 308 unsigned int length=0; 354 int length=0; 355 dummy_buffer *dbuf; 356 ringbuffer *airbuffer; 357 ringbuffer *arbuffer; 309 358 int nlength=0; 310 359 uint64_t pts, dpts=0; 360 uint64_t adelay; 361 int aframesize; 311 362 int newpts=0; 312 363 int nframes=1; 313 364 int ac3_off=0; 314 365 int rest_data = 5; 366 uint64_t *apts; 367 index_unit *aiu; 368 int g=0; 369 int add, off=0; 370 int fakelength = 0; 371 int droplength = 0; 315 372 316 int type = mx->ext[n].type;317 ringbuffer *airbuffer = &mx->index_extrbuffer[n];318 dummy_buffer *dbuf = &mx->ext[n].dbuf;319 uint64_t adelay = mx->ext[n].pts_off;320 uint64_t *apts = &mx->ext[n].pts;321 index_unit *aiu = &mx->ext[n].iu;322 323 373 switch (type){ 324 374 325 375 case MPEG_AUDIO: 326 376 #ifdef OUT_DEBUG 327 377 fprintf(stderr,"writing AUDIO%d pack\n",n); 328 378 #endif 379 airbuffer = &mx->index_arbuffer[n]; 380 arbuffer = &mx->arbuffer[n]; 381 dbuf = &mx->adbuf[n]; 382 adelay = mx->apts_off[n]; 383 aframesize = mx->aframes[n]; 384 apts = &mx->apts[n]; 385 aiu = &mx->aiu[n]; 329 386 break; 330 387 331 388 case AC3: 332 389 #ifdef OUT_DEBUG 333 390 fprintf(stderr,"writing AC3%d pack\n",n); 334 391 #endif 392 airbuffer = &mx->index_ac3rbuffer[n]; 393 arbuffer = &mx->ac3rbuffer[n]; 394 dbuf = &mx->ac3dbuf[n]; 395 adelay = mx->ac3pts_off[n]; 396 aframesize = mx->ac3frames[n]; 335 397 rest_data = 1; // 4 bytes AC3 header 398 apts = &mx->ac3pts[n]; 399 aiu = &mx->ac3iu[n]; 336 400 break; 337 401 338 402 default: … … 346 410 pts = uptsdiff( aiu->pts + mx->audio_delay, adelay ); 347 411 *apts = pts; 348 412 length = aiu->length; 349 if (length < aiu->framesize){ 413 414 if (length < aiu->framesize){ 350 415 newpts = 1; 351 416 ac3_off = length; 417 nframes = 0; 418 } 419 420 switch (aiu->err){ 421 422 case NO_ERR: 423 add = add_to_inbuf(inbuf, arbuffer, inbc, off, aiu->length); 424 off += add; 425 inbc += add; 426 break; 427 case PTS_ERR: 428 break; 429 case FRAME_ERR: 430 case JUMP_ERR: 431 break; 432 case DUMMY_ERR: 433 if (aiu->fillframe){ 434 // fprintf(stderr,"1. memcopy 0x%x\n",aiu->fillframe); 435 my_memcpy(inbuf, inbc 436 , aiu->fillframe + aframesize - length 437 , length, INSIZE); 438 inbc += length; 439 fakelength += length; 440 } else fprintf(stderr,"no fillframe \n"); 441 442 break; 352 443 } 444 353 445 dummy_add(dbuf, pts, aiu->length); 354 446 355 447 #ifdef OUT_DEBUG … … 363 455 printpts(pts); 364 456 fprintf(stderr,"\n"); 365 457 #endif 366 while ( !mx->is_ts &&length < mx->data_size + rest_data){458 while (length < mx->data_size + rest_data){ 367 459 if (ring_read(airbuffer, (uint8_t *)aiu, sizeof(index_unit)) > 0){ 460 368 461 dpts = uptsdiff(aiu->pts +mx->audio_delay, adelay ); 369 462 370 463 if (newpts){ 371 464 pts = dpts; 372 465 newpts=0; 373 466 } 467 468 469 switch(aiu->err) 470 { 471 case NO_ERR: 472 length += aiu->length; 473 add = add_to_inbuf(inbuf, arbuffer, inbc, off, aiu->length); 474 inbc += add; 475 off += add; 476 nframes++; 477 break; 374 478 375 length+= aiu->length; 479 case PTS_ERR: 480 break; 481 case FRAME_ERR: 482 case JUMP_ERR: 483 droplength += aiu->length; 484 off += aiu->length; 485 break; 486 case DUMMY_ERR: 487 length += aframesize; 488 if (aiu->fillframe){ 489 // fprintf(stderr,"2. memcopy 0x%x\n",aiu->fillframe); 490 my_memcpy(inbuf, inbc, aiu->fillframe, aframesize, INSIZE); 491 inbc += aframesize; 492 fakelength += aframesize; 493 nframes++; 494 } else fprintf(stderr,"no fillframe \n"); 495 496 break; 497 } 498 376 499 if (length < mx->data_size + rest_data) 377 500 dummy_add(dbuf, dpts, aiu->length); 378 501 379 502 *apts = dpts; 380 nframes++; 503 504 381 505 #ifdef OUT_DEBUG 382 506 fprintf(stderr,"start: %d stop: %d (%d) length %d ", 383 507 aiu->start, (aiu->start+aiu->length), … … 391 515 } else if (mx->finish){ 392 516 break; 393 517 } else if (mx->fill_buffers(mx->priv, mx->finish)< 0) { 394 fprintf(stderr,"error in writeout ext\n");518 fprintf(stderr,"error in writeout audio\n"); 395 519 exit(1); 396 520 } 397 521 } 398 399 522 nlength = length; 400 523 401 switch (type) { 402 case MPEG_AUDIO: 403 if(mx->is_ts) 404 written = write_audio_ts( mx->ext[n].strmnum, pts, 405 outbuf, &nlength, newpts ? 0 : PTS_ONLY, 406 &mx->extrbuffer[n]); 407 else 408 written = write_audio_pes( mx->pack_size, mx->extcnt, 409 mx->ext[n].strmnum, pts, mx->SCR, 410 mx->muxr, outbuf, &nlength, PTS_ONLY, 411 &mx->extrbuffer[n]); 412 break; 413 case AC3: 414 if(mx->is_ts) 415 written = write_ac3_ts(mx->ext[n].strmnum, pts, 416 outbuf, &nlength, newpts ? 0 : PTS_ONLY, 417 mx->ext[n].frmperpkt, &mx->extrbuffer[n]); 418 else 419 written = write_ac3_pes( mx->pack_size, mx->extcnt, 420 mx->ext[n].strmnum, pts, mx->SCR, 421 mx->muxr, outbuf, &nlength, PTS_ONLY, 422 nframes, ac3_off, 423 &mx->extrbuffer[n]); 424 break; 524 /* 525 if (type == MPEG_AUDIO) 526 written = write_audio_pes( mx->pack_size, mx->apidn, mx->ac3n 527 , n, pts, mx->SCR, mx->muxr, 528 outbuf, &nlength, PTS_ONLY, 529 arbuffer); 530 else 531 written = write_ac3_pes( mx->pack_size, mx->apidn, mx->ac3n 532 , n, pts, mx->SCR, mx->muxr, 533 outbuf, &nlength, PTS_ONLY, 534 nframes, ac3_off, 535 arbuffer, aiu->length); 536 */ 537 538 if (type == MPEG_AUDIO) 539 written = bwrite_audio_pes( mx->pack_size, mx->apidn, mx->ac3n 540 , n, pts, mx->SCR, mx->muxr, 541 outbuf, &nlength, PTS_ONLY, 542 inbuf, inbc); 543 else 544 written = bwrite_ac3_pes( mx->pack_size, mx->apidn, mx->ac3n 545 , n, pts, mx->SCR, mx->muxr, 546 outbuf, &nlength, PTS_ONLY, 547 nframes, ac3_off, 548 inbuf, inbc , aiu->length); 549 550 if (aiu->err == DUMMY_ERR){ 551 fakelength -= length-nlength; 425 552 } 426 427 // something bad happened when writing TS or PES to the MPEG or AC3428 // audio stream429 if (written == -1)430 return;431 432 553 length -= nlength; 433 write(mx->fd_out, outbuf, written); 434 554 mplx_write(mx, outbuf, written); 555 if (nlength-fakelength+droplength){ 556 ring_skip(arbuffer, nlength-fakelength+droplength); 557 } 435 558 dummy_add(dbuf, dpts, aiu->length-length); 436 559 aiu->length = length; 437 aiu->start = ring_rpos( &mx->extrbuffer[n]);560 aiu->start = ring_rpos(arbuffer); 438 561 439 562 if (aiu->length == 0){ 440 get_next_ext_unit(mx, aiu, n);441 } else {442 //estimate next pts based on bitrate of stream and data written443 aiu->pts = uptsdiff(aiu->pts + ((nlength*aiu->ptsrate)>>8), 0);563 if (type == MPEG_AUDIO) 564 g = get_next_audio_unit(mx, aiu, n); 565 else 566 g = get_next_ac3_unit(mx, aiu, n); 444 567 } 568 569 445 570 *apts = uptsdiff(aiu->pts + mx->audio_delay, adelay); 446 571 #ifdef OUT_DEBUG 447 if ((int64_t)*apts < 0) fprintf(stderr," SCHEISS");572 if ((int64_t)*apts < 0) fprintf(stderr,"MIST "); 448 573 fprintf(stderr,"APTS"); 449 574 printpts(*apts); 450 575 printpts(aiu->pts); … … 452 577 printpts(adelay); 453 578 fprintf(stderr,"\n"); 454 579 #endif 580 int lc=0; 581 while (aiu->err == JUMP_ERR && lc < 100){ 582 lc++; 583 584 ring_skip(arbuffer, aiu->length); 585 if (type == MPEG_AUDIO) 586 g = get_next_audio_unit(mx, aiu, n); 587 else 588 g = get_next_ac3_unit(mx, aiu, n); 589 } 455 590 456 591 if (mx->fill_buffers(mx->priv, mx->finish)< 0) { 457 fprintf(stderr,"error in writeout ext\n");592 fprintf(stderr,"error in writeout audio\n"); 458 593 exit(1); 459 594 } 460 595 } … … 464 599 uint8_t outbuf[3000]; 465 600 //fprintf(stderr,"writing PADDING pack\n"); 466 601 467 write_padding_pes( mx->pack_size, mx-> extcnt, mx->SCR,602 write_padding_pes( mx->pack_size, mx->apidn, mx->ac3n, mx->SCR, 468 603 mx->muxr, outbuf); 469 write(mx->fd_out, outbuf, mx->pack_size);604 mplx_write(mx, outbuf, mx->pack_size); 470 605 } 471 606 472 void check_times( multiplex_t *mx, int *video_ok, int *ext_ok, int *start) 607 void check_times( multiplex_t *mx, int *video_ok, int *audio_ok, int *ac3_ok, 608 int *start) 473 609 { 474 610 int i; 475 int set_ok = 0;476 477 memset( ext_ok, 0, N_AUDIO*sizeof(int));611 612 memset(audio_ok, 0, N_AUDIO*sizeof(int)); 613 memset(ac3_ok, 0, N_AC3*sizeof(int)); 478 614 *video_ok = 0; 479 615 480 616 if (mx->fill_buffers(mx->priv, mx->finish)< 0) { … … 489 625 } else *start = 0; 490 626 491 627 if (mx->VBR) { 492 #ifdef OUT_DEBUG 1628 #ifdef OUT_DEBUG 493 629 fprintf(stderr,"EXTRACLOCK: %lli ", mx->extra_clock); 494 630 printpts(mx->extra_clock); 495 631 fprintf(stderr,"\n"); … … 506 642 if (mx->extra_clock > 0.0) { 507 643 int64_t temp_scr = mx->extra_clock; 508 644 509 for (i=0; i<mx-> extcnt; i++){645 for (i=0; i<mx->apidn; i++){ 510 646 if (ptscmp(mx->SCR + temp_scr + 100*CLOCK_MS, 511 mx-> ext[i].iu.pts) > 0) {647 mx->aiu[i].pts) > 0) { 512 648 while (ptscmp(mx->SCR + temp_scr 513 649 + 100*CLOCK_MS, 514 mx-> ext[i].iu.pts) > 0)650 mx->aiu[i].pts) > 0) 515 651 temp_scr -= mx->SCRinc; 516 652 temp_scr += mx->SCRinc; 517 653 } 518 654 } 519 655 656 for (i=0; i<mx->ac3n; i++){ 657 if (ptscmp(mx->SCR + temp_scr + 100*CLOCK_MS, 658 mx->ac3iu[i].pts) > 0) { 659 while (ptscmp(mx->SCR + temp_scr 660 + 100*CLOCK_MS, 661 mx->ac3iu[i].pts) > 0) 662 temp_scr -= mx->SCRinc; 663 temp_scr += mx->SCRinc; 664 } 665 } 666 520 667 if (temp_scr > 0.0) { 521 668 mx->SCR += temp_scr; 522 669 mx->extra_clock -= temp_scr; … … 524 671 mx->extra_clock = 0.0; 525 672 } 526 673 } 527 674 675 528 676 /* clear decoder buffers up to SCR */ 529 677 dummy_delete(&mx->vdbuf, mx->SCR); 530 678 531 for (i=0;i <mx->extcnt; i++) 532 dummy_delete(&mx->ext[i].dbuf, mx->SCR); 679 for (i=0;i <mx->apidn; i++){ 680 dummy_delete(&mx->adbuf[i], mx->SCR); 681 clear_audio(mx, MPEG_AUDIO, i); 682 } 683 for (i=0;i <mx->ac3n; i++) { 684 dummy_delete(&mx->ac3dbuf[i], mx->SCR); 685 clear_audio(mx, AC3, i); 686 } 533 687 688 534 689 if (dummy_space(&mx->vdbuf) > mx->vsize && mx->viu.length > 0 && 535 (ptscmp(mx->viu.dts + mx->video_delay, 500*CLOCK_MS +mx->oldSCR)<0)690 (ptscmp(mx->viu.dts + mx->video_delay, 1000*CLOCK_MS +mx->oldSCR)<0) 536 691 && ring_avail(mx->index_vrbuffer)){ 537 692 *video_ok = 1; 538 set_ok = 1;539 693 } 540 694 541 for (i = 0; i < mx->extcnt; i++){ 542 if (dummy_space(&mx->ext[i].dbuf) > mx->extsize && 543 mx->ext[i].iu.length > 0 && 544 ptscmp(mx->ext[i].pts, 500*CLOCK_MS + mx->oldSCR) < 0 545 && ring_avail(&mx->index_extrbuffer[i])){ 546 ext_ok[i] = 1; 547 set_ok = 1; 695 for (i = 0; i < mx->apidn; i++){ 696 if (dummy_space(&mx->adbuf[i]) > mx->asize && 697 mx->aiu[i].length > 0 && 698 ptscmp(mx->apts[i], 200*CLOCK_MS + mx->oldSCR) < 0 699 && ring_avail(&mx->index_arbuffer[i])){ 700 audio_ok[i] = 1; 548 701 } 549 702 } 550 #ifdef OUT_DEBUG 551 if (set_ok) { 552 fprintf(stderr, "SCR"); 553 printpts(mx->oldSCR); 554 fprintf(stderr, "VDTS"); 555 printpts(mx->viu.dts); 556 fprintf(stderr, " (%d)", *video_ok); 557 fprintf(stderr, " EXT"); 558 for (i = 0; i < mx->extcnt; i++){ 559 fprintf(stderr, "%d:", mx->ext[i].type); 560 printpts(mx->ext[i].pts); 561 fprintf(stderr, " (%d)", ext_ok[i]); 703 for (i = 0; i < mx->ac3n; i++){ 704 if (dummy_space(&mx->ac3dbuf[i]) > mx->asize && 705 mx->ac3iu[i].length > 0 && 706 ptscmp(mx->ac3pts[i], 200*CLOCK_MS + mx->oldSCR) < 0 707 && ring_avail(&mx->index_ac3rbuffer[i])){ 708 ac3_ok[i] = 1; 562 709 } 563 fprintf(stderr, "\n");564 710 } 565 #endif566 711 } 567 void write_out_packs( multiplex_t *mx, int video_ok, int *ext_ok) 712 713 void write_out_packs( multiplex_t *mx, int video_ok, 714 int *audio_ok, int *ac3_ok) 568 715 { 569 716 int i; 570 717 571 if (video_ok && use_video(mx->viu.dts + mx->video_delay,572 mx->ext, ext_ok, mx->extcnt)) {718 if (video_ok && !all_audio_ok(audio_ok, mx->apidn) && 719 !all_audio_ok(ac3_ok, mx->ac3n)) { 573 720 writeout_video(mx); 574 721 } else { // second case(s): audio ok, video in time 575 i = which_ext(mx->ext, ext_ok, mx->extcnt);576 722 int done=0; 577 if(i>=0) { 578 writeout_ext(mx, i); 579 done = 1; 723 for ( i = 0; i < mx->ac3n; i++){ 724 if ( ac3_ok[i] && !rest_audio_ok(i,ac3_ok, mx->ac3n) 725 && !all_audio_ok(audio_ok, mx->apidn)){ 726 727 writeout_audio(mx, AC3, i); 728 done = 1; 729 break; 730 } 580 731 } 732 733 for ( i = 0; i < mx->apidn && !done; i++){ 734 if ( audio_ok[i] && !rest_audio_ok(i, audio_ok, 735 mx->apidn)){ 736 writeout_audio(mx, MPEG_AUDIO, i); 737 done = 1; 738 break; 739 } 740 } 741 742 581 743 if (!done && !mx->VBR){ 582 744 writeout_padding(mx); 583 745 } … … 589 751 { 590 752 int start=0; 591 753 int video_ok = 0; 592 int ext_ok[N_AUDIO]; 754 int audio_ok[N_AUDIO]; 755 int ac3_ok[N_AC3]; 593 756 int n,nn,old,i; 594 757 uint8_t mpeg_end[4] = { 0x00, 0x00, 0x01, 0xB9 }; 595 758 596 memset(ext_ok, 0, N_AUDIO*sizeof(int)); 759 memset(audio_ok, 0, N_AUDIO*sizeof(int)); 760 memset(ac3_ok, 0, N_AC3*sizeof(int)); 597 761 mx->finish = 1; 598 762 599 763 old = 0;nn=0; 600 while ((n=buffers_filled(mx)) && nn< 1000 ){764 while ((n=buffers_filled(mx)) && nn<20 ){ 601 765 if (n== old) nn++; 602 else nn=0;766 else if (nn) nn--; 603 767 old = n; 604 check_times( mx, &video_ok, ext_ok, &start);605 write_out_packs( mx, video_ok, ext_ok);768 check_times( mx, &video_ok, audio_ok, ac3_ok, &start); 769 write_out_packs( mx, video_ok, audio_ok, ac3_ok); 606 770 } 607 771 608 772 old = 0;nn=0; 609 773 while ((n=ring_avail(mx->index_vrbuffer)/sizeof(index_unit)) 610 && nn<10 00){774 && nn<10){ 611 775 if (n== old) nn++; 612 else nn= 0;776 else if (nn) nn--; 613 777 old = n; 614 778 writeout_video(mx); 615 779 } … … 617 781 // flush the rest 618 782 mx->finish = 2; 619 783 old = 0;nn=0; 620 for (i = 0; i < mx-> extcnt; i++){621 while ((n=ring_avail(&mx->index_ extrbuffer[i])/622 sizeof(index_unit)) && nn <100){784 for (i = 0; i < mx->apidn; i++){ 785 while ((n=ring_avail(&mx->index_arbuffer[i])/sizeof(index_unit)) 786 && nn <10){ 623 787 if (n== old) nn++; 624 else nn = 0;788 else if (nn) nn--; 625 789 old = n; 626 writeout_ ext(mx, i);790 writeout_audio(mx, MPEG_AUDIO, i); 627 791 } 628 792 } 629 793 794 old = 0;nn=0; 795 for (i = 0; i < mx->ac3n; i++){ 796 while ((n=ring_avail(&mx->index_ac3rbuffer[i]) 797 /sizeof(index_unit)) 798 && nn<10){ 799 if (n== old) nn++; 800 else if (nn) nn--; 801 old = n; 802 writeout_audio(mx, AC3, i); 803 } 804 } 805 806 630 807 if (mx->otype == REPLEX_MPEG2) 631 write(mx->fd_out, mpeg_end,4); 632 633 dummy_destroy(&mx->vdbuf); 634 for (i=0; i<mx->extcnt;i++) 635 dummy_destroy(&mx->ext[i].dbuf); 808 mplx_write(mx, mpeg_end,4); 636 809 } 637 810 638 static int get_ts_video_overhead(int pktsize, sequence_t *seq)639 {640 uint32_t framesize;641 uint32_t numpkt;642 int pktdata = pktsize - TS_HEADER_MIN;643 framesize = seq->bit_rate * 50 / seq->frame_rate; //avg bytes/frame644 numpkt = (framesize + PES_H_MIN + 10 + pktdata -1) / pktdata;645 return pktsize- ((pktsize * numpkt) - framesize + numpkt - 1) / numpkt;646 }647 811 648 static int get_ts_ext_overhead(int pktsize, audio_frame_t *extframe, 649 extdata_t *ext, int cnt) 650 { 651 int i, max = 0; 652 int pktdata = pktsize - TS_HEADER_MIN; 653 for (i = 0; i < cnt; i++) { 654 int size, numpkt, overhead; 655 // 1/53 is approx 0.15 * 1/8 which allows us to calculate the 656 // # of packets in .15 seconds (which is the number of packets 657 // per PES. 658 ext[i].frmperpkt = extframe[i].bit_rate / 53 / 659 extframe[i].framesize; 660 size = extframe[i].framesize * ext[i].frmperpkt; 661 numpkt = (size + pktdata - 1) / pktdata; 662 overhead = (pktsize * numpkt - size + numpkt - 1) / numpkt; 663 if(overhead > max) 664 max = overhead; 665 } 666 return pktsize - max; 667 } 668 669 void init_multiplex( multiplex_t *mx, sequence_t *seq_head, 670 audio_frame_t *extframe, int *exttype, int *exttypcnt, 812 void init_multiplex( multiplex_t *mx, sequence_t *seq_head, audio_frame_t *aframe, 813 audio_frame_t *ac3frame, int apidn, int ac3n, 671 814 uint64_t video_delay, uint64_t audio_delay, int fd, 672 815 int (*fill_buffers)(void *p, int f), 673 816 ringbuffer *vrbuffer, ringbuffer *index_vrbuffer, 674 ringbuffer *extrbuffer, ringbuffer *index_extrbuffer, 817 ringbuffer *arbuffer, ringbuffer *index_arbuffer, 818 ringbuffer *ac3rbuffer, ringbuffer *index_ac3rbuffer, 675 819 int otype) 676 820 { 677 821 int i; … … 682 826 mx->audio_delay = audio_delay; 683 827 mx->fd_out = fd; 684 828 mx->otype = otype; 829 mx->total_written = 0; 830 mx->zero_write_count = 0; 831 mx->max_write = 0; 832 mx->max_reached = 0; 685 833 686 834 switch(mx->otype){ 687 835 … … 698 846 mx->reset_clocks = 0; 699 847 mx->write_end_codes = 0; 700 848 mx->set_broken_link = 0; 701 mx->is_ts = 0;849 // mx->max_write = 1024*1024*1024; // 1GB max VOB length 702 850 break; 703 851 704 852 … … 715 863 mx->reset_clocks = 1; 716 864 mx->write_end_codes = 1; 717 865 mx->set_broken_link = 1; 718 mx->is_ts = 0;719 866 break; 720 867 721 868 case REPLEX_HDTV: … … 731 878 mx->reset_clocks = 1; 732 879 mx->write_end_codes = 1; 733 880 mx->set_broken_link = 1; 734 mx->is_ts = 0;735 881 break; 882 } 736 883 737 case REPLEX_TS_SD: 738 mx->video_delay += 180*CLOCK_MS; 739 mx->audio_delay += 180*CLOCK_MS; 740 mx->pack_size = 188; 741 mx->audio_buffer_size = 4*1024; 742 mx->video_buffer_size = 232*1024; 743 mx->mux_rate = 1260000; 744 mx->navpack = 0; 745 mx->frame_timestamps = TIME_ALWAYS; 746 mx->VBR = 1; 747 mx->reset_clocks = 0; 748 mx->write_end_codes = 0; 749 mx->set_broken_link = 0; 750 mx->is_ts = 1; 751 break; 884 mx->apidn = apidn; 885 mx->ac3n = ac3n; 752 886 753 case REPLEX_TS_HD:754 mx->video_delay += 180*CLOCK_MS;755 mx->audio_delay += 180*CLOCK_MS;756 mx->pack_size = 188;757 mx->audio_buffer_size = 4*1024;758 mx->video_buffer_size = 4*224*1024;759 mx->mux_rate = 0;760 mx->navpack = 0;761 mx->frame_timestamps = TIME_ALWAYS;762 mx->VBR = 1;763 mx->reset_clocks = 0;764 mx->write_end_codes = 0;765 mx->set_broken_link = 0;766 mx->is_ts = 1;767 break;768 }769 887 770 for (mx->extcnt = 0, data_rate = 0, i = 0;771 i < N_AUDIO && exttype[i]; i++){772 if (exttype[i] >= MAX_TYPES) {773 fprintf(stderr, "Found illegal stream type %d\n",774 exttype[i]);775 exit(1);776 }777 mx->ext[i].type = exttype[i];778 mx->ext[i].pts_off = 0;779 mx->ext[i].frmperpkt = 1;780 mx->ext[i].strmnum = exttypcnt[i];781 strncpy(mx->ext[i].language, extframe[i].language, 4);782 dummy_init(&mx->ext[i].dbuf, mx->audio_buffer_size);783 data_rate += extframe[i].bit_rate;784 mx->extcnt++;785 }786 787 888 mx->vrbuffer = vrbuffer; 788 889 mx->index_vrbuffer = index_vrbuffer; 789 mx->extrbuffer = extrbuffer; 790 mx->index_extrbuffer = index_extrbuffer; 890 mx->arbuffer = arbuffer; 891 mx->index_arbuffer = index_arbuffer; 892 mx->ac3rbuffer = ac3rbuffer; 893 mx->index_ac3rbuffer = index_ac3rbuffer; 791 894 792 895 dummy_init(&mx->vdbuf, mx->video_buffer_size); 896 for (i=0; i<mx->apidn;i++){ 897 mx->apts_off[i] = 0; 898 dummy_init(&mx->adbuf[i],mx->audio_buffer_size); 899 } 900 for (i=0; i<mx->ac3n;i++){ 901 mx->ac3pts_off[i] = 0; 902 dummy_init(&mx->ac3dbuf[i], mx->audio_buffer_size); 903 } 793 904 794 //NOTE: vpkt_hdr/extpkt_hdr are worst-case for PS streams, but 795 //best-guess for TS streams 796 if(mx->is_ts) { 797 //Use best guess for TS streams 798 mx->data_size = get_ts_video_overhead(mx->pack_size, seq_head); 799 mx->extsize = get_ts_ext_overhead(mx->pack_size, extframe, 800 mx->ext, mx->extcnt); 801 802 } else { 803 //Use worst case for PS streams 804 mx->data_size = mx->pack_size - PES_H_MIN - PS_HEADER_L1 - 10; 805 mx->extsize = mx->data_size + 5; //one less DTS 806 } 905 mx->data_size = mx->pack_size - PES_H_MIN -10; 807 906 mx->vsize = mx->data_size; 907 mx->asize = mx->data_size+5; // one less DTS 808 908 809 data_rate += seq_head->bit_rate *400; 909 data_rate = seq_head->bit_rate *400; 910 for ( i = 0; i < mx->apidn; i++) 911 data_rate += aframe[i].bit_rate; 912 for ( i = 0; i < mx->ac3n; i++) 913 data_rate += ac3frame[i].bit_rate; 810 914 811 mx->muxr = ((uint64_t)data_rate / 8 * mx->pack_size) / mx->data_size; 915 916 mx->muxr = (data_rate / 8 * mx->pack_size) / mx->data_size; 812 917 // muxrate of payload in Byte/s 813 918 814 919 if (mx->mux_rate) { … … 825 930 826 931 void setup_multiplex(multiplex_t *mx) 827 932 { 933 int packlen; 828 934 int i; 829 935 830 936 get_next_video_unit(mx, &mx->viu); 831 for (i=0; i < mx->extcnt; i++) 832 { 833 get_next_ext_unit(mx, &mx->ext[i].iu, i); 834 if (mx->ext[i].type == MPEG_AUDIO || mx->ext[i].type == AC3) 835 mx->ext[i].pts = uptsdiff( 836 mx->ext[i].iu.pts + mx->audio_delay, 837 mx->ext[i].pts_off); 838 else 839 mx->ext[i].pts = uptsdiff( 840 mx->ext[i].iu.pts, mx->ext[i].pts_off); 937 for (i=0; i < mx->apidn; i++){ 938 get_next_audio_unit(mx, &mx->aiu[i], i); 939 mx->apts[i] = uptsdiff(mx->aiu[i].pts +mx->audio_delay, 940 mx->apts_off[i]); 841 941 } 942 for (i=0; i < mx->ac3n; i++){ 943 get_next_ac3_unit(mx, &mx->ac3iu[i], i); 944 mx->ac3pts[i] = uptsdiff(mx->ac3iu[i].pts +mx->audio_delay, 945 mx->ac3pts_off[i]); 946 } 842 947 948 packlen = mx->pack_size; 949 843 950 mx->SCR = 0; 844 951 845 952 // write first VOBU header 846 if (mx-> is_ts){953 if (mx->navpack){ 847 954 uint8_t outbuf[2048]; 848 write_ts_patpmt(mx->ext, mx->extcnt, 1, outbuf); 849 write(mx->fd_out, outbuf, mx->pack_size*2); 850 ptsinc(&mx->SCR, mx->SCRinc*2); 851 mx->startup = 1; 852 } else if (mx->navpack){ 853 uint8_t outbuf[2048]; 854 write_nav_pack(mx->pack_size, mx->extcnt, 955 write_nav_pack(mx->pack_size, mx->apidn, mx->ac3n, 855 956 mx->SCR, mx->muxr, outbuf); 856 write(mx->fd_out, outbuf, mx->pack_size);957 mplx_write(mx, outbuf, mx->pack_size); 857 958 ptsinc(&mx->SCR, mx->SCRinc); 858 959 mx->startup = 1; 859 960 } else mx->startup = 0; -
programs/mythtranscode/replex/avi.h
2 2 * avi.h 3 3 * 4 4 * 5 * Copyright (C) 2003 Marcus Metzler <mocm@metzlerbros.de> 5 * Copyright (C) 2003 - 2006 6 * Marcus Metzler <mocm@metzlerbros.de> 6 7 * Metzler Brothers Systementwicklung GbR 7 8 * 8 9 * This program is free software; you can redistribute it and/or -
programs/mythtranscode/replex/TODO
1 - check for dvdauthor audio PTS errors1 - fix/replace broken frames 2 2 3 - check/fix/replace broken frames4 5 3 - split DVD output Files 6 4 7 5 - use more than one input File 8 6 9 7 - add cutting option 10 8 11 - better handling of broken streams12 -
programs/mythtranscode/replex/ts.c
2 2 * ts.c: MPEG TS functions for replex 3 3 * 4 4 * 5 * Copyright (C) 2003 Marcus Metzler <mocm@metzlerbros.de> 5 * Copyright (C) 2003 - 2006 6 * Marcus Metzler <mocm@metzlerbros.de> 6 7 * Metzler Brothers Systementwicklung GbR 7 8 * 8 9 * This program is free software; you can redistribute it and/or … … 24 25 * 25 26 */ 26 27 27 #include <stdlib.h>28 28 #include <stdint.h> 29 29 #include <string.h> 30 30 #include <stdio.h> 31 31 32 #ifdef USING_MINGW33 #include <winsock2.h>34 #else35 #include <netinet/in.h>36 #endif37 38 32 #include "ts.h" 39 #include "element.h"40 #include "pes.h"41 33 42 34 uint16_t get_pid(uint8_t *pid) 43 35 { … … 49 41 return pp; 50 42 } 51 43 44 int write_ts_header(uint16_t pid, uint8_t *counter, int pes_start, 45 uint8_t *buf, uint8_t length) 46 { 47 int i; 48 int c = 0; 49 int fill; 50 uint8_t tshead[4] = { 0x47, 0x00, 0x00, 0x10}; 51 52 53 fill = TS_SIZE-4-length; 54 if (pes_start) tshead[1] = 0x40; 55 if (fill) tshead[3] = 0x30; 56 tshead[1] |= (uint8_t)((pid & 0x1F00) >> 8); 57 tshead[2] |= (uint8_t)(pid & 0x00FF); 58 tshead[3] |= ((*counter)++ & 0x0F) ; 59 memcpy(buf,tshead,4); 60 c+=4; 61 62 63 if (fill){ 64 buf[4] = fill-1; 65 c++; 66 if (fill >1){ 67 buf[5] = 0x00; 68 c++; 69 } 70 for ( i = 6; i < fill+4; i++){ 71 buf[i] = 0xFF; 72 c++; 73 } 74 } 75 76 return c; 77 } 78 79 52 80 int find_pids_pos(uint16_t *vpid, uint16_t *apid, uint16_t *ac3pid,uint8_t *buf, int len, int *vpos, int *apos, int *ac3pos) 53 81 { 54 82 int c=0; … … 123 151 { 124 152 return find_pids_pos(vpid, apid, ac3pid, buf, len, NULL, NULL, NULL); 125 153 } 126 127 //taken and adapted from libdtv, (c) Rolf Hakenes128 // CRC32 lookup table for polynomial 0x04c11db7129 static unsigned int crc_table[256] = {130 0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9, 0x130476dc, 0x17c56b6b,131 0x1a864db2, 0x1e475005, 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61,132 0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd, 0x4c11db70, 0x48d0c6c7,133 0x4593e01e, 0x4152fda9, 0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75,134 0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011, 0x791d4014, 0x7ddc5da3,135 0x709f7b7a, 0x745e66cd, 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039,136 0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5, 0xbe2b5b58, 0xbaea46ef,137 0xb7a96036, 0xb3687d81, 0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d,138 0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49, 0xc7361b4c, 0xc3f706fb,139 0xceb42022, 0xca753d95, 0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1,140 0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d, 0x34867077, 0x30476dc0,141 0x3d044b19, 0x39c556ae, 0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072,142 0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16, 0x018aeb13, 0x054bf6a4,143 0x0808d07d, 0x0cc9cdca, 0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde,144 0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02, 0x5e9f46bf, 0x5a5e5b08,145 0x571d7dd1, 0x53dc6066, 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba,146 0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e, 0xbfa1b04b, 0xbb60adfc,147 0xb6238b25, 0xb2e29692, 0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6,148 0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a, 0xe0b41de7, 0xe4750050,149 0xe9362689, 0xedf73b3e, 0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2,150 0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686, 0xd5b88683, 0xd1799b34,151 0xdc3abded, 0xd8fba05a, 0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637,152 0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb, 0x4f040d56, 0x4bc510e1,153 0x46863638, 0x42472b8f, 0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53,154 0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47, 0x36194d42, 0x32d850f5,155 0x3f9b762c, 0x3b5a6b9b, 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff,156 0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623, 0xf12f560e, 0xf5ee4bb9,157 0xf8ad6d60, 0xfc6c70d7, 0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b,158 0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f, 0xc423cd6a, 0xc0e2d0dd,159 0xcda1f604, 0xc960ebb3, 0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7,160 0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b, 0x9b3660c6, 0x9ff77d71,161 0x92b45ba8, 0x9675461f, 0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3,162 0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640, 0x4e8ee645, 0x4a4ffbf2,163 0x470cdd2b, 0x43cdc09c, 0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8,164 0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24, 0x119b4be9, 0x155a565e,165 0x18197087, 0x1cd86d30, 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec,166 0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088, 0x2497d08d, 0x2056cd3a,167 0x2d15ebe3, 0x29d4f654, 0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0,168 0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c, 0xe3a1cbc1, 0xe760d676,169 0xea23f0af, 0xeee2ed18, 0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4,170 0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0, 0x9abc8bd5, 0x9e7d9662,171 0x933eb0bb, 0x97ffad0c, 0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668,172 0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4};173 174 unsigned int crc32_04c11db7 (const unsigned char *d, int len, unsigned int crc)175 {176 register int i;177 const unsigned char *u=(unsigned char*)d; // Saves '& 0xff'178 179 for (i=0; i<len; i++)180 crc = (crc << 8) ^ crc_table[((crc >> 24) ^ *u++)];181 182 return crc;183 }184 185 static int write_ts_header(int pid, int payload_start, int count,186 int64_t SCR, uint8_t *obuf, int stuff)187 {188 int c = 0;189 uint8_t *scr;190 uint32_t lscr;191 uint16_t scr_ext = 0;192 193 obuf[c++] = 0x47;194 obuf[c++] = (payload_start ? 0x40 : 0x00) | ((pid >> 8) & 0x1f);195 obuf[c++] = pid & 0xff;196 obuf[c++] = ((SCR >= 0 || stuff) ? 0x30 : 0x10) | count;197 if (SCR >= 0|| stuff) {198 if (stuff)199 stuff--;200 int size = stuff;201 unsigned char flags = 0;202 if(SCR >= 0) {203 if(size < 7)204 size = 7;205 flags |= 0x10;206 }207 obuf[c++] = size;208 if(size) {209 obuf[c++] = flags;210 size--;211 }212 if(SCR >= 0) {213 uint8_t bit;214 lscr = (uint32_t) ((SCR/300ULL) & 0xFFFFFFFFULL);215 bit = (lscr & 0x01) << 7;216 lscr = htonl(lscr >> 1);217 scr = (uint8_t *) 𝓁218 scr_ext = (uint16_t) ((SCR%300ULL) & 0x1FFULL);219 obuf[c++] = scr[0];220 obuf[c++] = scr[1];221 obuf[c++] = scr[2];222 obuf[c++] = scr[3];223 obuf[c++] = bit | 0x7e | (scr_ext >> 8);224 obuf[c++] = scr_ext & 0xff;225 size -= 6;226 }227 while(size-- > 0)228 obuf[c++] = 0xff;229 }230 return c;231 }232 233 int write_video_ts(uint64_t vpts, uint64_t vdts, uint64_t SCR, uint8_t *buf,234 int *vlength, uint8_t ptsdts, ringbuffer *vrbuffer)235 {236 //Unlike program streams, we only do one PES per frame237 static int count = 0;238 int add;239 int pos = 0;240 int p = 0;241 int stuff = 0;242 int length = *vlength;243 244 if (! length) return 0;245 p = 4;246 if ( ptsdts ) {247 p += PES_H_MIN + 8;248 249 if ( ptsdts == PTS_ONLY) {250 p += 5;251 } else if (ptsdts == PTS_DTS){252 p += 10;253 }254 }255 if ( length+p >= TS_SIZE){256 length = TS_SIZE;257 } else {258 stuff = TS_SIZE - length - p;259 length = TS_SIZE;260 }261 if(ptsdts) {262 //printf("SCR: %f PTS: %f DTS: %f\n", SCR/27000000.0, vpts / 27000000.0, vdts / 27000000.0);263 pos = write_ts_header(TS_VIDPID, 1, count, SCR, buf, stuff);264 // always use length == 0 for video streams265 pos += write_pes_header( 0xE0, 6, vpts, vdts, buf+pos,266 0, ptsdts);267 } else {268 pos = write_ts_header(TS_VIDPID, 0, count, -1, buf, stuff);269 }270 count = (count+1) & 0x0f;271 272 if (length-pos > *vlength){273 fprintf(stderr,"WHAT THE HELL %d > %d\n", length-pos,274 *vlength);275 }276 277 add = ring_read( vrbuffer, buf+pos, length-pos);278 *vlength = add;279 if (add < 0) return -1;280 pos += add;281 282 return pos;283 }284 285 int write_audio_ts(int n, uint64_t pts, uint8_t *buf, int *alength,286 uint8_t ptsdts, ringbuffer *arbuffer)287 {288 static int count[32] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,289 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};290 int add;291 int pos = 0;292 int p = 0;293 int stuff = 0;294 int length = *alength;295 296 if (!length) return 0;297 p = 4;298 299 if (ptsdts == PTS_ONLY){300 p += PES_H_MIN + 5;301 }302 303 if ( length+p >= TS_SIZE){304 length = TS_SIZE;305 } else {306 stuff = TS_SIZE - length - p;307 length = TS_SIZE;308 }309 if(ptsdts) {310 pos = write_ts_header(TS_MP2PID+n, 1, count[n], -1, buf, stuff);311 pos += write_pes_header( 0xC0+n, *alength + PES_H_MIN + 5, pts,312 0, buf+pos, 0, ptsdts);313 } else {314 pos = write_ts_header(TS_MP2PID+n, 0, count[n], -1, buf, stuff);315 }316 count[n] = (count[n]+1) & 0x0f;317 add = ring_read( arbuffer, buf+pos, length-pos);318 *alength = add;319 if (add < 0) return -1;320 pos += add;321 322 if (pos != TS_SIZE) {323 fprintf(stderr,"apos: %d\n",pos);324 exit(1);325 }326 327 return pos;328 }329 330 int write_ac3_ts(int n, uint64_t pts, uint8_t *buf, int *alength,331 uint8_t ptsdts, int nframes, ringbuffer *ac3rbuffer)332 {333 static int count[32] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,334 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};335 int add;336 int pos = 0;337 int p = 0;338 int stuff = 0;339 int length = *alength;340 341 if (!length) return 0;342 p = 4;343 344 if (ptsdts == PTS_ONLY){345 p += PES_H_MIN + 5 + 4; //PES header + PTS + PS1346 }347 348 if ( length+p >= TS_SIZE){349 length = TS_SIZE;350 } else {351 stuff = TS_SIZE - length - p;352 length = TS_SIZE;353 }354 if(ptsdts) {355 pos = write_ts_header(TS_AC3PID+n, 1, count[n], -1, buf, stuff);356 pos += write_pes_header( PRIVATE_STREAM1,357 *alength + 4 + PES_H_MIN + 5,358 pts, 0, buf+pos, 0, ptsdts);359 buf[pos] = 0x80 + n;360 buf[pos+1] = nframes;361 buf[pos+2] = 0x00;362 buf[pos+3] = 0x00;363 pos += 4;364 } else {365 pos = write_ts_header(TS_AC3PID+n, 0, count[n], -1, buf, stuff);366 }367 count[n] = (count[n]+1) & 0x0f;368 369 add = ring_read( ac3rbuffer, buf+pos, length-pos);370 *alength = add;371 if (add < 0) return -1;372 pos += add;373 374 if (pos != TS_SIZE) {375 fprintf(stderr,"apos: %d\n",pos);376 exit(1);377 }378 379 return pos;380 }381 382 void write_ts_patpmt(extdata_t *ext, int extcnt, uint8_t prog_num, uint8_t *buf)383 {384 #define PMTPID 0x20385 static int count = 0;386 int pos, i, pmtpos = 13;387 //PMT Program number = 1388 //PMT PID = 0x20389 uint8_t pat[17] = {0x00, 0x00, 0xb0, 0x0d, 0xfe, 0xef, 0xc1, 0x00, 0x00,390 0x00, 0x00, 0xe0, PMTPID, 0x00, 0x00, 0x00, 0x00};391 uint8_t pmt[184] ={0x00, 0x02, 0xb0, 0x00, 0x00, 0x00, 0xc1, 0x00, 0x00,392 0x00, 0x00, 0xf0, 0x00};393 394 //PAT395 pat[10] = prog_num;396 pos = write_ts_header(0x00, 1, count, -1, buf, 0);397 *(uint32_t *)(pat+13)= htonl(crc32_04c11db7(pat+1, 12, 0xffffffff));398 memcpy(buf+pos, pat, 17);399 pos += 17;400 memset(buf+pos, 0xff, TS_SIZE - pos);401 pos = TS_SIZE;402 //PMT403 pos += write_ts_header(PMTPID, 1, count, -1, buf+pos, 0);404 for(i = 0; i <= extcnt; i++) {405 uint8_t type;406 uint32_t pid;407 int n = ext[i-1].strmnum;408 if(i == 0) {409 type = 0x02;410 pid = TS_VIDPID;411 } else if(ext[i-1].type == MPEG_AUDIO) {412 type = 0x04;413 pid = TS_MP2PID + n;414 } else if(ext[i-1].type == AC3) {415 type = 0x81;416 pid = TS_AC3PID + n;417 } else {418 type = 0xff;419 pid = 0x1fff;420 }421 pmt[pmtpos++] = type;422 pmt[pmtpos++] = 0xe0 | (0xff & (pid >> 8));423 pmt[pmtpos++] = 0xff & pid;424 pmt[pmtpos++] = 0xf0;425 if(strlen(ext[i-1].language) == 3) {426 pmt[pmtpos++] = 0x06;427 pmt[pmtpos++] = 0x0a;428 pmt[pmtpos++] = 0x04;429 pmt[pmtpos++] = ext[i-1].language[0];430 pmt[pmtpos++] = ext[i-1].language[1];431 pmt[pmtpos++] = ext[i-1].language[2];432 pmt[pmtpos++] = 0x00;433 } else {434 pmt[pmtpos++] = 0x00;435 }436 }437 pmt[3] = pmtpos + 4/*crc*/ - 3 - 1/*pointer_field*/;438 pmt[5] = prog_num;439 pmt[9] = 0xf0 | (0xff & (TS_VIDPID >> 8));440 pmt[10] = 0xff & TS_VIDPID;441 *(uint32_t *)&pmt[pmtpos] = htonl(crc32_04c11db7(&pmt[1], pmtpos -1,442 0xffffffff));443 pmtpos+=4;444 memcpy(buf+pos, pmt, pmtpos);445 pos += pmtpos;446 memset(buf+pos, 0xff, 2*TS_SIZE - pos);447 pos = 2*TS_SIZE;448 count = (count+1) & 0x0f;449 } -
programs/mythtranscode/replex/pes.c
2 2 * pes.c: MPEG PES functions for replex 3 3 * 4 4 * 5 * Copyright (C) 2003 Marcus Metzler <mocm@metzlerbros.de> 5 * Copyright (C) 2003 - 2006 6 * Marcus Metzler <mocm@metzlerbros.de> 6 7 * Metzler Brothers Systementwicklung GbR 8 * (C) 2006 Reel Multimedia 7 9 * 8 10 * This program is free software; you can redistribute it and/or 9 11 * modify it under the terms of the GNU General Public License … … 26 28 27 29 #include <stdlib.h> 28 30 #include <stdio.h> 31 #include <netinet/in.h> 29 32 #include <string.h> 30 33 31 #ifdef USING_MINGW 32 #include <winsock2.h> 33 #else 34 #include <netinet/in.h> 35 #endif 34 #include "pes.h" 36 35 37 #include "pes.h" 36 //#define PES_DEBUG 37 38 38 void printpts(int64_t pts) 39 39 { 40 40 if (pts < 0){ … … 43 43 } 44 44 pts = pts/300; 45 45 pts &= (MAX_PTS-1); 46 fprintf(stderr,"%2d:%02d:%02d.%0 4d ",46 fprintf(stderr,"%2d:%02d:%02d.%03d ", 47 47 (unsigned int)(pts/90000.)/3600, 48 48 ((unsigned int)(pts/90000.)%3600)/60, 49 49 ((unsigned int)(pts/90000.)%3600)%60, 50 (((unsigned int)(pts/9 .)%36000000)%600000)%1000050 (((unsigned int)(pts/90.)%3600000)%60000)%1000 51 51 ); 52 52 } 53 53 … … 159 159 void get_pes (pes_in_t *p, uint8_t *buf, int count, void (*func)(pes_in_t *p)) 160 160 { 161 161 162 int l ;163 unsigned short *pl ;164 int done;162 int l=0; 163 unsigned short *pl=NULL; 164 int c=0; 165 165 166 166 uint8_t headr[3] = { 0x00, 0x00, 0x01} ; 167 do { 168 int c=0; 169 done = 1; 170 while (c < count && (!p->mpeg || 171 (p->mpeg == 2 && p->found < 9)) 172 && (p->found < 5 || !p->done)){ 173 switch ( p->found ){ 174 case 0: 175 case 1: 176 if (buf[c] == 0x00) p->found++; 177 else p->found = 0; 167 while (c < count && (!p->mpeg || 168 (p->mpeg == 2 && p->found < 9)) 169 && (p->found < 5 || !p->done)){ 170 switch ( p->found ){ 171 case 0: 172 case 1: 173 if (buf[c] == 0x00) p->found++; 174 else p->found = 0; 175 c++; 176 break; 177 case 2: 178 if (buf[c] == 0x01) p->found++; 179 else if (buf[c] == 0){ 180 p->found = 2; 181 } else p->found = 0; 182 c++; 183 break; 184 case 3: 185 p->cid = 0; 186 switch (buf[c]){ 187 case PROG_STREAM_MAP: 188 case PRIVATE_STREAM2: 189 case PROG_STREAM_DIR: 190 case ECM_STREAM : 191 case EMM_STREAM : 192 case PADDING_STREAM : 193 case DSM_CC_STREAM : 194 case ISO13522_STREAM: 195 p->done = 1; 196 case PRIVATE_STREAM1: 197 case VIDEO_STREAM_S ... VIDEO_STREAM_E: 198 case AUDIO_STREAM_S ... AUDIO_STREAM_E: 199 p->found++; 200 p->cid = buf[c]; 178 201 c++; 179 202 break; 180 case 2: 181 if (buf[c] == 0x01) p->found++; 182 else if (buf[c] == 0){ 183 p->found = 2; 184 } else p->found = 0; 203 default: 204 case PACK_START: 205 case SYS_START: 206 p->found = 0; 185 207 c++; 186 208 break; 187 case 3: 188 p->cid = 0; 189 switch (buf[c]){ 190 case PROG_STREAM_MAP: 191 case PRIVATE_STREAM2: 192 case PROG_STREAM_DIR: 193 case ECM_STREAM : 194 case EMM_STREAM : 195 case PADDING_STREAM : 196 case DSM_CC_STREAM : 197 case ISO13522_STREAM: 198 p->done = 1; 199 case PRIVATE_STREAM1: 200 case VIDEO_STREAM_S ... VIDEO_STREAM_E: 201 case AUDIO_STREAM_S ... AUDIO_STREAM_E: 202 p->found++; 203 p->cid = buf[c]; 204 c++; 205 break; 206 default: 207 case PACK_START: 208 case SYS_START: 209 p->found = 0; 210 c++; 211 break; 212 } 213 break; 209 } 210 break; 214 211 215 212 216 case 4: 217 if (count-c > 1){ 218 pl = (unsigned short *) (buf+c); 219 p->plength = ntohs(*pl); 220 p->plen[0] = buf[c]; 221 c++; 222 p->plen[1] = buf[c]; 223 c++; 224 p->found+=2; 225 } else { 226 p->plen[0] = buf[c]; 227 p->found++; 228 return; 229 } 230 break; 231 case 5: 213 case 4: 214 if (count-c > 1){ 215 pl = (unsigned short *) (buf+c); 216 p->plength = ntohs(*pl); 217 p->plen[0] = buf[c]; 218 c++; 232 219 p->plen[1] = buf[c]; 233 220 c++; 234 pl = (unsigned short *) p->plen; 235 p->plength = ntohs(*pl); 221 p->found+=2; 222 } else { 223 p->plen[0] = buf[c]; 236 224 p->found++; 237 break; 225 return; 226 } 227 break; 228 case 5: 229 p->plen[1] = buf[c]; 230 c++; 231 pl = (unsigned short *) p->plen; 232 p->plength = ntohs(*pl); 233 p->found++; 234 break; 238 235 239 236 240 case 6: 241 if (!p->done){ 242 p->flag1 = buf[c]; 243 c++; 244 p->found++; 245 if ( (p->flag1 & 0xC0) == 0x80 ) p->mpeg = 2; 246 else { 247 fprintf(stderr, 248 "Error: THIS IS AN MPEG1 FILE\n"); 249 exit(1); 250 } 237 case 6: 238 if (!p->done){ 239 p->flag1 = buf[c]; 240 c++; 241 p->found++; 242 if ( (p->flag1 & 0xC0) == 0x80 ) p->mpeg = 2; 243 else { 244 fprintf(stderr, "Error in PES Header 0x%2x\n",p->cid); 245 p->found = 0; 251 246 } 252 break; 247 } 248 break; 253 249 254 255 256 257 258 259 260 250 case 7: 251 if ( !p->done && p->mpeg == 2){ 252 p->flag2 = buf[c]; 253 c++; 254 p->found++; 255 } 256 break; 261 257 262 263 264 265 266 267 268 258 case 8: 259 if ( !p->done && p->mpeg == 2){ 260 p->hlength = buf[c]; 261 c++; 262 p->found++; 263 } 264 break; 269 265 270 266 default: 271 267 272 break; 273 } 268 break; 274 269 } 270 if(p->plength && p->found == 9 && p->found > p->plength+6){ 271 fprintf(stderr, "Error in PES Header 0x%2x\n",p->cid); 272 p->found = 0; 273 } 274 } 275 275 276 276 if (!p->plength) p->plength = MMAX_PLENGTH-6; 277 277 278 278 279 280 279 if ( p->done || (p->mpeg == 2 && p->found >= 9) ){ 280 switch (p->cid){ 281 281 282 283 284 282 case AUDIO_STREAM_S ... AUDIO_STREAM_E: 283 case VIDEO_STREAM_S ... VIDEO_STREAM_E: 284 case PRIVATE_STREAM1: 285 285 286 if (p->withbuf){ 287 memcpy(p->buf, headr, 3); 288 p->buf[3] = p->cid; 289 memcpy(p->buf+4,p->plen,2); 290 } else { 291 memcpy(p->hbuf, headr, 3); 292 p->hbuf[3] = p->cid; 293 memcpy(p->hbuf+4,p->plen,2); 294 } 295 296 if (p->found == 9){ 286 297 if (p->withbuf){ 287 memcpy(p->buf, headr, 3);288 p->buf[ 3] = p->cid;289 memcpy(p->buf+4,p->plen,2);298 p->buf[6] = p->flag1; 299 p->buf[7] = p->flag2; 300 p->buf[8] = p->hlength; 290 301 } else { 291 memcpy(p->hbuf, headr, 3);292 p->hbuf[ 3] = p->cid;293 memcpy(p->hbuf+4,p->plen,2);302 p->hbuf[6] = p->flag1; 303 p->hbuf[7] = p->flag2; 304 p->hbuf[8] = p->hlength; 294 305 } 306 } 295 307 296 if (p->found == 9){ 297 if (p->withbuf){ 298 p->buf[6] = p->flag1; 299 p->buf[7] = p->flag2; 300 p->buf[8] = p->hlength; 301 } else { 302 p->hbuf[6] = p->flag1; 303 p->hbuf[7] = p->flag2; 304 p->hbuf[8] = p->hlength; 305 } 308 if ( (p->flag2 & PTS_ONLY) && p->found < 14){ 309 while (c < count && p->found < 14){ 310 p->pts[p->found-9] = buf[c]; 311 if (p->withbuf) 312 p->buf[p->found] = buf[c]; 313 else 314 p->hbuf[p->found] = buf[c]; 315 c++; 316 p->found++; 306 317 } 318 if (c == count) return; 319 } 307 320 308 if ( (p->flag2 & PTS_ONLY) && p->found < 14){ 309 while (c < count && p->found < 14){ 310 p->pts[p->found-9] = buf[c]; 311 if (p->withbuf) 312 p->buf[p->found] = buf[c]; 313 else 314 p->hbuf[p->found] = buf[c]; 315 c++; 316 p->found++; 317 } 318 if (c == count) return; 321 if (((p->flag2 & PTS_DTS) == 0xC0) && p->found < 19){ 322 while (c < count && p->found < 19){ 323 p->dts[p->found-14] = buf[c]; 324 if (p->withbuf) 325 p->buf[p->found] = buf[c]; 326 else 327 p->hbuf[p->found] = buf[c]; 328 c++; 329 p->found++; 319 330 } 331 if (c == count) return; 332 } 320 333 321 if (((p->flag2 & PTS_DTS) == 0xC0) && p->found < 19){322 while (c < count && p->found < 19){323 p->dts[p->found-14] = buf[c];324 if (p->withbuf)325 p->buf[p->found] = buf[c];326 else327 p->hbuf[p->found] = buf[c];328 c++;329 p->found++;330 }331 if (c == count) return;332 }333 334 334 335 while (c < count && p->found < p->plength+6){ 336 l = count -c; 337 if (l+p->found > p->plength+6) 338 l = p->plength+6-p->found; 339 if (p->withbuf) 340 memcpy(p->buf+p->found, buf+c, l); 341 else { 342 if ( p->found < 343 (unsigned int)p->hlength+9 ){ 344 int rest = p->hlength+9-p->found; 345 memcpy(p->hbuf+p->found, buf+c, rest); 346 if (ring_write(p->rbuf, buf+c+rest, 347 l-rest) <0){ 348 exit(1); 349 } 350 } else { 351 if (ring_write(p->rbuf, buf+c, l)<0){ 352 fprintf(stderr, 353 "ring buffer overflow %d\n" 354 ,p->rbuf->size); 355 exit(1); 356 } 335 while (c < count && p->found < p->plength+6){ 336 l = count -c; 337 if (l+p->found > p->plength+6) 338 l = p->plength+6-p->found; 339 if (p->withbuf) 340 memcpy(p->buf+p->found, buf+c, l); 341 else { 342 if ( p->found < p->hlength+9 ){ 343 int rest = p->hlength+9-p->found; 344 memcpy(p->hbuf+p->found, buf+c, rest); 345 if (ring_write(p->rbuf, buf+c+rest, 346 l-rest) <0){ 347 fprintf(stderr, 348 "ring buffer overflow in get_pes %d\n" 349 ,p->rbuf->size); 350 exit(1); 357 351 } 352 } else { 353 if (ring_write(p->rbuf, buf+c, l)<0){ 354 fprintf(stderr, 355 "ring buffer overflow in get_pes %d\n" 356 ,p->rbuf->size); 357 exit(1); 358 } 358 359 } 360 } 359 361 360 p->found += l; 361 c += l; 362 } 363 if(p->found == p->plength+6){ 364 func(p); 365 } 366 break; 362 p->found += l; 363 c += l; 364 } 365 if(p->found == p->plength+6){ 366 func(p); 367 367 } 368 break; 369 } 368 370 369 if ( p->done ){ 370 if( p->found + count - c < p->plength+6){ 371 p->found += count-c; 372 c = count; 373 } else { 374 c += p->plength+6 - p->found; 375 p->found = p->plength+6; 376 } 371 if ( p->done ){ 372 if( p->found + count - c < p->plength+6){ 373 p->found += count-c; 374 c = count; 375 } else { 376 c += p->plength+6 - p->found; 377 p->found = p->plength+6; 377 378 } 379 } 378 380 379 if (p->plength && p->found == p->plength+6) { 380 init_pes_in(p, p->type, NULL, p->withbuf); 381 if (c < count) { 382 done = 0; 383 count -= c; 384 buf += c; 385 } 386 } 387 } 388 } while(!done); 381 if (p->plength && p->found == p->plength+6) { 382 init_pes_in(p, p->type, NULL, p->withbuf); 383 if (c < count) 384 get_pes(p, buf+c, count-c, func); 385 } 386 } 389 387 return; 390 388 } 391 389 … … 459 457 int cwrite_ps(uint8_t *buf, ps_packet *p, uint32_t length) 460 458 { 461 459 long count,i; 462 (void)length;463 460 uint8_t headr1[4] = {0x00, 0x00, 0x01, PACK_START }; 464 461 uint8_t headr2[4] = {0x00, 0x00, 0x01, SYS_START }; 465 462 uint8_t buffy = 0xFF; … … 556 553 p.rate_bound[1] = (uint8_t)(0xff & (muxr >> 7)); 557 554 p.rate_bound[2] = (uint8_t)(0x01 | ((muxr & 0x7f)<<1)); 558 555 559 560 556 p.audio_bound = (uint8_t)((audio_bound << 2)|(fixed << 1)|CSPS); 561 557 p.video_bound = (uint8_t)((audio_lock << 7)| 562 558 (video_lock << 6)|0x20|video_bound); … … 586 582 } 587 583 588 584 589 staticvoid get_pespts(uint8_t *spts,uint8_t *pts)585 void get_pespts(uint8_t *spts,uint8_t *pts) 590 586 { 591 //Make sure to set the 1st 4 bits properly 592 pts[0] = 0x 01 |587 588 pts[0] = 0x21 | 593 589 ((spts[0] & 0xC0) >>5); 594 590 pts[1] = ((spts[0] & 0x3F) << 2) | 595 591 ((spts[1] & 0xC0) >> 6); … … 647 643 648 644 dummy[0] = 0x80; 649 645 dummy[1] = 0; 650 dummy[2] = stuffing;646 dummy[2] = 0; 651 647 652 648 if (ptsdts == PTS_ONLY){ 653 dummy[2] += 5;649 dummy[2] = 5 + stuffing; 654 650 dummy[1] |= PTS_ONLY; 655 ppts[0] |= 0x20;656 651 } else if (ptsdts == PTS_DTS){ 657 dummy[2] += 10;652 dummy[2] = 10 + stuffing; 658 653 dummy[1] |= PTS_DTS; 659 ppts[0] |= 0x30;660 pdts[0] |= 0x10;661 654 } 662 663 655 664 656 memcpy(obuf+c,dummy,3); 665 657 c += 3; 666 658 659 memset(obuf+c,0xFF,stuffing); 660 c += stuffing; 661 667 662 if (ptsdts == PTS_ONLY){ 668 663 memcpy(obuf+c,ppts,5); 669 664 c += 5; … … 673 668 memcpy(obuf+c,pdts,5); 674 669 c += 5; 675 670 } 676 677 memset(obuf+c,0xFF,stuffing);678 c += stuffing;679 680 671 return c; 681 672 } 682 673 683 void write_padding_pes( int pack_size, int extcnt,674 void write_padding_pes( int pack_size, int apidn, int ac3n, 684 675 uint64_t SCR, uint64_t muxr, uint8_t *buf) 685 676 { 686 677 int pos = 0; 687 678 688 pos = write_ps_header(buf,SCR,muxr, extcnt, 0, 0, 1, 1, 1,679 pos = write_ps_header(buf,SCR,muxr, apidn+ ac3n, 0, 0, 1, 1, 1, 689 680 0); 690 681 691 682 pos += write_pes_header( PADDING_STREAM, pack_size-pos, 0, 0, buf+pos, … … 693 684 694 685 } 695 686 696 int write_video_pes( int pack_size, int extcnt, uint64_t vpts,687 int write_video_pes( int pack_size, int apidn, int ac3n, uint64_t vpts, 697 688 uint64_t vdts, uint64_t SCR, uint64_t muxr, 698 689 uint8_t *buf, int *vlength, 699 690 uint8_t ptsdts, ringbuffer *vrbuffer) … … 704 695 int stuff = 0; 705 696 int length = *vlength; 706 697 698 #ifdef PES_DEBUG 699 fprintf(stderr,"write video PES "); 700 printpts(vdts); 701 fprintf(stderr,"\n"); 702 #endif 707 703 if (! length) return 0; 708 704 p = PS_HEADER_L1+PES_H_MIN; 709 705 … … 723 719 length = length+p; 724 720 } 725 721 726 pos = write_ps_header(buf,SCR,muxr, extcnt, 0, 0, 1, 1,722 pos = write_ps_header(buf,SCR,muxr, apidn+ac3n, 0, 0, 1, 1, 727 723 1, 0); 728 724 729 725 pos += write_pes_header( 0xE0, length-pos, vpts, vdts, buf+pos, … … 746 742 return pos; 747 743 } 748 744 749 int write_audio_pes( int pack_size, int extcnt, int n, uint64_t pts,745 int write_audio_pes( int pack_size, int apidn, int ac3n, int n, uint64_t pts, 750 746 uint64_t SCR, uint32_t muxr, uint8_t *buf, int *alength, 751 747 uint8_t ptsdts, ringbuffer *arbuffer) 752 748 { … … 756 752 int stuff = 0; 757 753 int length = *alength; 758 754 755 #ifdef PES_DEBUG 756 fprintf(stderr,"write audio PES "); 757 printpts(pts); 758 fprintf(stderr,"\n"); 759 #endif 760 759 761 if (!length) return 0; 760 762 p = PS_HEADER_L1+PES_H_MIN; 761 763 … … 772 774 } else 773 775 length = length+p; 774 776 } 775 pos = write_ps_header(buf,SCR,muxr, extcnt, 0, 0, 1, 1,777 pos = write_ps_header(buf,SCR,muxr, apidn + ac3n, 0, 0, 1, 1, 776 778 1, 0); 777 779 pos += write_pes_header( 0xC0+n, length-pos, pts, 0, buf+pos, stuff, 778 780 ptsdts); … … 794 796 return pos; 795 797 } 796 798 797 int write_ac3_pes( int pack_size, int extcnt, int n, 799 800 801 int write_ac3_pes( int pack_size, int apidn, int ac3n, int n, 798 802 uint64_t pts, uint64_t SCR, 799 803 uint32_t muxr, uint8_t *buf, int *alength, uint8_t ptsdts, 800 int nframes,int ac3_off, ringbuffer *ac3rbuffer )804 int nframes,int ac3_off, ringbuffer *ac3rbuffer, int framelength) 801 805 { 802 806 int add; 803 807 int pos = 0; … … 805 809 int stuff = 0; 806 810 int length = *alength; 807 811 812 #ifdef PES_DEBUG 813 fprintf(stderr,"write ac3 PES "); 814 printpts(pts); 815 fprintf(stderr,"\n"); 816 #endif 817 808 818 if (!length) return 0; 809 p = PS_HEADER_L1+PES_H_MIN +4;819 p = PS_HEADER_L1+PES_H_MIN; 810 820 811 821 if (ptsdts == PTS_ONLY){ 812 822 p += 5; 813 823 } 814 824 815 825 if ( length+p >= pack_size){ 826 if (length+p -pack_size == framelength-4) nframes--; 816 827 length = pack_size; 817 828 } else { 818 829 if (pack_size-length-p <= PES_MIN){ … … 821 832 } else 822 833 length = length+p; 823 834 } 824 pos = write_ps_header(buf,SCR,muxr, extcnt, 0, 0, 1, 1,835 pos = write_ps_header(buf,SCR,muxr, apidn+ac3n, 0, 0, 1, 1, 825 836 1, 0); 826 837 827 838 pos += write_pes_header( PRIVATE_STREAM1, length-pos, pts, 0, 828 839 buf+pos, stuff, ptsdts); 829 buf[pos] = 0x80 + n ;840 buf[pos] = 0x80 + n +apidn; 830 841 buf[pos+1] = nframes; 831 842 buf[pos+2] = (ac3_off >> 8)& 0xFF; 832 843 buf[pos+3] = (ac3_off)& 0xFF; … … 850 861 return pos; 851 862 } 852 863 853 int write_nav_pack(int pack_size, int extcnt, uint64_t SCR, uint32_t muxr, 864 865 int bwrite_audio_pes( int pack_size, int apidn, int ac3n, int n, uint64_t pts, 866 uint64_t SCR, uint32_t muxr, uint8_t *buf, int *alength, 867 uint8_t ptsdts, uint8_t *arbuffer, int bsize ) 868 { 869 int add; 870 int pos = 0; 871 int p = 0; 872 int stuff = 0; 873 int length = *alength; 874 875 #ifdef PES_DEBUG 876 fprintf(stderr,"write audio PES "); 877 printpts(pts); 878 fprintf(stderr,"\n"); 879 #endif 880 881 if (!length) return 0; 882 p = PS_HEADER_L1+PES_H_MIN; 883 884 if (ptsdts == PTS_ONLY){ 885 p += 5; 886 } 887 888 if ( length+p >= pack_size){ 889 length = pack_size; 890 } else { 891 if (pack_size-length-p <= PES_MIN){ 892 stuff = pack_size - length-p; 893 length = pack_size; 894 } else 895 length = length+p; 896 } 897 pos = write_ps_header(buf,SCR,muxr, apidn + ac3n, 0, 0, 1, 1, 898 1, 0); 899 pos += write_pes_header( 0xC0+n, length-pos, pts, 0, buf+pos, stuff, 900 ptsdts); 901 902 if (length -pos < bsize){ 903 memcpy(buf+pos, arbuffer, length-pos); 904 add = length - pos; 905 *alength = add; 906 } else return -1; 907 908 pos += add; 909 910 if (pos+PES_MIN < pack_size){ 911 pos += write_pes_header( PADDING_STREAM, pack_size-pos, 0,0, 912 buf+pos, 0, 0); 913 pos = pack_size; 914 } 915 if (pos != pack_size) { 916 fprintf(stderr,"apos: %d\n",pos); 917 exit(1); 918 } 919 920 return pos; 921 } 922 923 924 925 int bwrite_ac3_pes( int pack_size, int apidn, int ac3n, int n, 926 uint64_t pts, uint64_t SCR, 927 uint32_t muxr, uint8_t *buf, int *alength, uint8_t ptsdts, 928 int nframes,int ac3_off, uint8_t *ac3rbuffer, int bsize, int framelength) 929 { 930 int add; 931 int pos = 0; 932 int p = 0; 933 int stuff = 0; 934 int length = *alength; 935 936 #ifdef PES_DEBUG 937 fprintf(stderr,"write ac3 PES "); 938 printpts(pts); 939 fprintf(stderr,"\n"); 940 #endif 941 if (!length) return 0; 942 p = PS_HEADER_L1+PES_H_MIN; 943 944 if (ptsdts == PTS_ONLY){ 945 p += 5; 946 } 947 948 if ( length+p >= pack_size){ 949 if (length+p -pack_size == framelength-4) nframes--; 950 length = pack_size; 951 } else { 952 if (pack_size-length-p <= PES_MIN){ 953 stuff = pack_size - length-p; 954 length = pack_size; 955 } else 956 length = length+p; 957 } 958 pos = write_ps_header(buf,SCR,muxr, apidn+ac3n, 0, 0, 1, 1, 959 1, 0); 960 961 pos += write_pes_header( PRIVATE_STREAM1, length-pos, pts, 0, 962 buf+pos, stuff, ptsdts); 963 buf[pos] = 0x80 + n +apidn; 964 buf[pos+1] = nframes; 965 buf[pos+2] = (ac3_off >> 8)& 0xFF; 966 buf[pos+3] = (ac3_off)& 0xFF; 967 pos += 4; 968 969 if (length-pos <= bsize){ 970 memcpy(buf+pos, ac3rbuffer, length-pos); 971 add = length-pos; 972 *alength = add; 973 } else return -1; 974 pos += add; 975 976 if (pos+PES_MIN < pack_size){ 977 pos += write_pes_header( PADDING_STREAM, pack_size-pos, 0,0, 978 buf+pos, 0, 0); 979 pos = pack_size; 980 } 981 if (pos != pack_size) { 982 fprintf(stderr,"apos: %d\n",pos); 983 exit(1); 984 } 985 986 return pos; 987 } 988 989 990 int write_nav_pack(int pack_size, int apidn, int ac3n, uint64_t SCR, uint32_t muxr, 854 991 uint8_t *buf) 855 992 { 856 993 int pos = 0; 857 994 uint8_t headr[5] = {0x00, 0x00, 0x01, PRIVATE_STREAM2, 0x03 }; 858 (void)pack_size;859 995 860 pos = write_ps_header( buf, SCR, muxr, extcnt, 0, 0, 1, 1, 1, 1);996 pos = write_ps_header( buf, SCR, muxr, apidn+ac3n, 0, 0, 1, 1, 1, 1); 861 997 memcpy(buf+pos, headr, 5); 862 998 buf[pos+5] = 0xD4; 863 999 pos += 6; -
programs/mythtranscode/replex/CHANGES
1 0.1.6 2 DVB wants continuous numbering of audio streams, even for MP2 AC3 mix 3 added handling of too few audio PTS in some streams 4 added audio frame dropping, when video cut is larger than audio cut 5 add the -j option to jump over PTS discontinuities and cuts 6 add -l option to set the minimum time in ms a jump has to have 7 add -g option to set video buffer size in GB 8 fixed MPEG2 and AC3 multiplexing 9 add version information 10 add -p option for filling MPEG audio frames with zero 11 add -q options to set limit for overflow errors 12 13 0.1.5 14 various minor fixes 15 added better audio frame recognition 16 fixed AC3 PTS problem for dvdauthor 17 1 18 0.1.4 2 19 fixed problem with audio PTS which ruined dvdauthor 3 20 -
programs/mythtranscode/replex/multiplex.h
2 2 * multiplex.h 3 3 * 4 4 * 5 * Copyright (C) 2003 Marcus Metzler <mocm@metzlerbros.de> 5 * Copyright (C) 2003 - 2006 6 * Marcus Metzler <mocm@metzlerbros.de> 6 7 * Metzler Brothers Systementwicklung GbR 8 * (C) 2006 Reel Multimedia 7 9 * 8 10 * This program is free software; you can redistribute it and/or 9 11 * modify it under the terms of the GNU General Public License … … 33 35 #define N_AUDIO 32 34 36 #define N_AC3 8 35 37 38 36 39 typedef struct multiplex_s{ 37 40 int fd_out; 38 41 #define REPLEX_MPEG2 0 39 42 #define REPLEX_DVD 1 40 43 #define REPLEX_HDTV 2 41 #define REPLEX_TS_SD 342 #define REPLEX_TS_HD 443 44 int otype; 44 45 int startup; 45 46 int finish; … … 48 49 uint64_t video_delay; 49 50 uint64_t audio_delay; 50 51 int pack_size; 51 unsignedint data_size;52 int data_size; 52 53 uint32_t audio_buffer_size; 53 54 uint32_t video_buffer_size; 54 55 uint32_t mux_rate; … … 58 59 #define TIME_IFRAME 2 59 60 int frame_timestamps; 60 61 int VBR; 61 int is_ts;62 62 int reset_clocks; 63 63 int write_end_codes; 64 64 int set_broken_link; 65 unsigned int vsize, extsize;65 int vsize, asize; 66 66 int64_t extra_clock; 67 uint64_t first_vpts; 68 uint64_t first_apts[N_AUDIO]; 69 uint64_t first_ac3pts[N_AC3]; 70 67 71 uint64_t SCR; 68 72 uint64_t oldSCR; 69 73 uint64_t SCRinc; 70 74 index_unit viu; 75 index_unit aiu[N_AUDIO]; 76 index_unit ac3iu[N_AC3]; 77 uint64_t apts[N_AUDIO]; 78 uint64_t ac3pts[N_AC3]; 79 uint64_t ac3pts_off[N_AC3]; 80 uint64_t apts_off[N_AUDIO]; 81 int aframes[N_AUDIO]; 82 int ac3frames[N_AUDIO]; 83 int total_written; 84 int zero_write_count; 85 int max_write; 86 int max_reached; 71 87 88 /* needed from replex */ 89 int apidn; 90 int ac3n; 91 72 92 dummy_buffer vdbuf; 93 dummy_buffer adbuf[N_AUDIO]; 94 dummy_buffer ac3dbuf[N_AC3]; 73 95 74 extdata_t ext[N_AUDIO]; 75 int extcnt; 76 77 ringbuffer *extrbuffer; 78 ringbuffer *index_extrbuffer; 96 ringbuffer *ac3rbuffer; 97 ringbuffer *index_ac3rbuffer; 98 ringbuffer *arbuffer; 99 ringbuffer *index_arbuffer; 79 100 ringbuffer *vrbuffer; 80 101 ringbuffer *index_vrbuffer; 81 102 … … 83 104 void *priv; 84 105 } multiplex_t; 85 106 86 void check_times( multiplex_t *mx, int *video_ok, int *ext_ok, int *start); 87 void write_out_packs( multiplex_t *mx, int video_ok, int *ext_ok); 107 void check_times( multiplex_t *mx, int *video_ok, int *audio_ok, int *ac3_ok, 108 int *start); 109 void write_out_packs( multiplex_t *mx, int video_ok, 110 int *audio_ok, int *ac3_ok); 88 111 void finish_mpg(multiplex_t *mx); 89 void init_multiplex( multiplex_t *mx, sequence_t *seq_head, 90 audio_frame_t * extframe, int *exttype, int *exttypcnt,112 void init_multiplex( multiplex_t *mx, sequence_t *seq_head, audio_frame_t *aframe, 113 audio_frame_t *ac3frame, int apidn, int ac3n, 91 114 uint64_t video_delay, uint64_t audio_delay, int fd, 92 115 int (*fill_buffers)(void *p, int f), 93 116 ringbuffer *vrbuffer, ringbuffer *index_vrbuffer, 94 ringbuffer *extrbuffer, ringbuffer *index_extrbuffer, 117 ringbuffer *arbuffer, ringbuffer *index_arbuffer, 118 ringbuffer *ac3rbuffer, ringbuffer *index_ac3rbuffer, 95 119 int otype); 96 120 97 121 void setup_multiplex(multiplex_t *mx); -
programs/mythtranscode/replex/element.c
2 2 * element.c: MPEG ELEMENTARY STREAM functions for replex 3 3 * 4 4 * 5 * Copyright (C) 2003 Marcus Metzler <mocm@metzlerbros.de> 5 * Copyright (C) 2003 - 2006 6 * Marcus Metzler <mocm@metzlerbros.de> 6 7 * Metzler Brothers Systementwicklung GbR 8 * (C) 2006 Reel Multimedia 7 9 * 8 10 * This program is free software; you can redistribute it and/or 9 11 * modify it under the terms of the GNU General Public License … … 26 28 27 29 #include <stdio.h> 28 30 #include <string.h> 31 #include <stdlib.h> 29 32 30 33 #include "element.h" 31 34 #include "mpg_common.h" 32 35 #include "pes.h" 33 36 34 37 unsigned int slots [4] = {12, 144, 0, 0}; 35 unsigned int bitrates[3][16] = 36 {{0,32,64,96,128,160,192,224,256,288,320,352,384,416,448,0}, 37 {0,32,48,56,64,80,96,112,128,160,192,224,256,320,384,0}, 38 {0,32,40,48,56,64,80,96,112,128,160,192,224,256,320,0}}; 38 const uint16_t bitrates[2][3][15] = { 39 { {0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448 }, 40 {0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384 }, 41 {0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320 } }, 42 { {0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256}, 43 {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160}, 44 {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160} 45 } 46 }; 39 47 40 uint32_t freq[4] = {441, 480, 320, 0}; 41 static uint64_t samples[4] = { 384, 1152, 1152, 1536}; 48 const uint16_t freqs[3] = { 44100, 48000, 32000 }; 49 50 static uint32_t samples[4] = { 384, 1152, 1152, 1536}; 51 42 52 char *frames[3] = {"I-Frame","P-Frame","B-Frame"}; 43 53 44 54 unsigned int ac3_bitrates[32] = … … 58 68 return newpts>0 ? newpts%MAX_PTS2: MAX_PTS2+newpts; 59 69 } 60 70 61 void fix_audio_count(uint64_t *acount,audio_frame_t *aframe, uint64_t origpts, uint64_t pts)71 int cfix_audio_count(audio_frame_t *aframe, uint64_t origpts, uint64_t pts) 62 72 { 63 73 int64_t diff; 64 74 uint64_t di; 65 75 int c=0; 66 67 76 di = (samples [3-aframe->layer] * 27000000ULL); 68 77 diff = ptsdiff(origpts,pts); 69 78 c=(aframe->frequency * diff+di/2)/di; 70 if (c) fprintf(stderr,"fix audio frames %d\n",c); 79 return c; 80 } 81 82 83 void fix_audio_count(uint64_t *acount, audio_frame_t *aframe, uint64_t origpts, uint64_t pts) 84 { 85 int c=0; 86 87 c = cfix_audio_count(aframe, origpts, pts); 71 88 *acount += c; 72 89 } 73 90 … … 79 96 80 97 81 98 if ( s->pulldown == NOPULLDOWN ) { 82 newdts = ( (fcount-1) * SEC_PER + *pts); 83 newpts = ((fnum ) * SEC_PER + *pts); 99 if (s->progressive == TWO_FIELD){ 100 newdts = ( (fcount-2) * SEC_PER*2 + *pts); 101 newpts = ((fnum-1 ) * SEC_PER*2 + *pts); 102 } else { 103 newdts = ( (fcount-1) * SEC_PER + *pts); 104 newpts = ((fnum ) * SEC_PER + *pts); 105 } 84 106 } else { 85 107 uint64_t extra_time = 0; 86 108 // fprintf(stderr,"pulldown %d %d\n",(int) fcount-1, fnum-1); … … 144 166 (int)fr/2); 145 167 } 146 168 147 169 int FindPacketHeader(const uint8_t *Data, int s, int l); 170 171 void inserttime(uint8_t *buf, uint8_t h, uint8_t m, uint8_t s) 172 { 173 buf[4] &= ~(0x7F); 174 buf[4] |= (h & 0x1F) << 2; 175 buf[4] |= (m & 0x30) >> 4; 176 177 buf[5] &= ~(0xF7); 178 buf[5] |= (m & 0x0F) << 4; 179 buf[5] |= (s & 0x38) >> 3; 180 181 buf[6] &= ~(0xE0); 182 buf[6] |= (s & 0x07) << 5; 183 } 184 148 185 void pts2time(uint64_t pts, uint8_t *buf, int len) 149 186 { 150 187 uint8_t h,m,s; 188 int c=0,x; 189 // uint8_t *data=buf; 190 191 pts = (pts/300)%MAX_PTS; 192 h = (uint8_t)(pts/90000)/3600; 193 m = (uint8_t)((pts/90000)%3600)/60; 194 s = (uint8_t)((pts/90000)%3600)%60; 195 196 while(c+7 < len) { 197 x=FindPacketHeader(buf, c, len); 198 if (x==-1) 199 return; 200 if (buf[x+3]==GROUP_START_CODE && (buf[x+5] & 0x08)) { 201 inserttime(buf+x, h, m, s); 202 } 203 c=x+4; 204 } 205 206 } 207 void pts2timex(uint64_t pts, uint8_t *buf, int len) 208 { 209 uint8_t h,m,s; 151 210 int c = 0; 152 211 153 212 pts = (pts/300)%MAX_PTS; … … 158 217 while (c+7 < len){ 159 218 if (buf[c] == 0x00 && buf[c+1] == 0x00 && buf[c+2] == 0x01 && 160 219 buf[c+3] == GROUP_START_CODE && (buf[c+5] & 0x08)){ 161 buf[c+4] &= ~(0x7F); 162 buf[c+4] |= (h & 0x1F) << 2; 163 buf[c+4] |= (m & 0x30) >> 4; 164 165 buf[c+5] &= ~(0xF7); 166 buf[c+5] |= (m & 0x0F) << 4; 167 buf[c+5] |= (s & 0x38) >> 3; 168 169 buf[c+6] &= ~(0xE0); 170 buf[c+6] |= (s & 0x07) << 5; 171 220 inserttime(buf+c,h,m,s); 172 221 /* 1hhhhhmm|mmmm1sss|sss */ 173 222 /* 174 223 c+=4; … … 186 235 } 187 236 188 237 189 int get_video_info(ringbuffer *rbuf, sequence_t *s, intoff, int le)238 int get_video_info(ringbuffer *rbuf, sequence_t *s, long off, int le) 190 239 { 191 240 uint8_t buf[150]; 192 241 uint8_t *headr; … … 311 360 return c; 312 361 } 313 362 314 int find_audio_sync(ringbuffer *rbuf, uint8_t *buf, intoff, int type, int le)363 int find_audio_sync(ringbuffer *rbuf, uint8_t *buf, long off, int type, int le) 315 364 { 316 365 int found = 0; 317 366 int c=0; … … 364 413 return -1; 365 414 } 366 415 367 int find_audio_s(uint8_t *rbuf, intoff, int type, int le)416 int find_audio_s(uint8_t *rbuf, long off, int type, int le) 368 417 { 369 418 int found = 0; 370 419 int c=0; … … 411 460 return -1; 412 461 } 413 462 414 int check_audio_header(ringbuffer *rbuf, audio_frame_t * af, int off, int le, 463 static int calculate_mpg_framesize(audio_frame_t *af) 464 { 465 int frame_size; 466 467 frame_size = af->bit_rate/1000; 468 if (!frame_size) return -1; 469 switch(af->layer) { 470 case 1: 471 frame_size = (frame_size * 12000) / af->sample_rate; 472 frame_size = (frame_size + af->padding) * 4; 473 break; 474 case 2: 475 frame_size = (frame_size * 144000) / af->sample_rate; 476 frame_size += af->padding; 477 break; 478 default: 479 case 3: 480 frame_size = (frame_size * 144000) / (af->sample_rate << af->lsf); 481 frame_size += af->padding; 482 break; 483 } 484 return frame_size; 485 } 486 487 int check_audio_header(ringbuffer *rbuf, audio_frame_t * af, long off, int le, 415 488 int type) 416 489 { 417 490 uint8_t headr[7]; … … 432 505 switch (type){ 433 506 434 507 case MPEG_AUDIO: 435 if ( af->layer != ((headr[1] & 0x06) >> 1) ){508 if ( af->layer != 4 -((headr[1] & 0x06) >> 1) ){ 436 509 if ( headr[1] == 0xff){ 437 510 return -3; 438 511 } else { … … 442 515 return -1; 443 516 } 444 517 } 445 if ( af->bit_rate != 446 (bitrates[(3-af->layer)][(headr[2] >> 4 )]*1000)){518 if ( af->bit_rate != 519 ( af->bit_rate = bitrates[af->lsf][af->layer-1][(headr[2] >> 4 )]*1000)){ 447 520 #ifdef IN_DEBUG 448 521 fprintf(stderr,"Wrong audio bit rate\n"); 449 522 #endif 450 return -1; 451 } 523 return -1; 524 } 525 526 if (af->padding != ((headr[2] >> 1) & 1)){ 527 int fsize; 528 af->padding = (headr[2] >> 1) & 1; 529 if ((fsize = calculate_mpg_framesize(af)) < 0 || 530 abs(fsize - af->framesize) >2) return -1; 531 af->framesize = fsize; 532 #ifdef IN_DEBUG 533 fprintf(stderr,"padding changed : %d\n",af->padding); 534 #endif 535 536 } 537 452 538 break; 453 539 454 540 case AC3: … … 476 562 } 477 563 478 564 479 int get_audio_info(ringbuffer *rbuf, audio_frame_t *af, int off, int le)565 int get_audio_info(ringbuffer *rbuf, audio_frame_t *af, long off, int le, int verb) 480 566 { 481 567 int c = 0; 482 568 int fr =0; 483 uint8_t headr[7]; 569 uint8_t headr[4]; 570 int sample_rate_index; 484 571 485 572 af->set=0; 486 573 487 574 if ( (c = find_audio_sync(rbuf, headr, off, MPEG_AUDIO,le)) < 0 ) 488 575 return c; 489 576 490 af->layer = (headr[1] & 0x06) >> 1; 577 af->layer = 4 - ((headr[1] & 0x06) >> 1); 578 // if (af->layer >3) return -1; 491 579 492 if (DEBUG) 493 fprintf(stderr,"Audiostream: layer: %d", 4-af->layer); 580 if (DEBUG && verb) 581 fprintf(stderr,"Audiostream: layer: %d", af->layer); 582 if (headr[1] & (1<<4)) { 583 af->lsf = (headr[1] & (1<<3)) ? 0 : 1; 584 af->mpg25 = 0; 585 if (DEBUG && verb) 586 fprintf(stderr," version: 1"); 587 } else { 588 af->lsf = 1; 589 af->mpg25 = 1; 590 if (DEBUG && verb) 591 fprintf(stderr," version: 2"); 592 } 593 /* extract frequency */ 594 sample_rate_index = (headr[2] >> 2) & 3; 595 if (sample_rate_index > 2) return -1; 596 af->sample_rate = freqs[sample_rate_index] >> (af->lsf + af->mpg25); 494 597 598 af->padding = (headr[2] >> 1) & 1; 495 599 496 af->bit_rate = bitrates[(3-af->layer)][(headr[2] >> 4 )]*1000;497 600 498 if (DEBUG){ 601 af->bit_rate = bitrates[af->lsf][af->layer-1][(headr[2] >> 4 )]*1000; 602 603 604 if (DEBUG && verb){ 499 605 if (af->bit_rate == 0) 500 606 fprintf (stderr," Bit rate: free"); 501 607 else if (af->bit_rate == 0xf) … … 505 611 } 506 612 507 613 fr = (headr[2] & 0x0c ) >> 2; 508 af->frequency = freq[fr]*100; 509 510 if (DEBUG){ 614 af->frequency = freqs[fr]; 615 616 617 if (DEBUG && verb){ 511 618 if (af->frequency == 3) 512 619 fprintf (stderr, " Freq: reserved"); 513 620 else … … 516 623 } 517 624 af->off = c; 518 625 af->set = 1; 519 520 af->frametime = ((samples [3-af->layer] * 27000000ULL) / af->frequency); 521 af->framesize = af->bit_rate *slots [3-af->layer]/ af->frequency; 522 fprintf(stderr," frame size: %d (", af->framesize); 523 printpts(af->frametime); 524 fprintf(stderr,") "); 525 626 af->framesize = calculate_mpg_framesize(af); 627 //af->framesize = af->bit_rate *slots [3-af->layer]/ af->frequency; 628 if (DEBUG && verb) fprintf(stderr," frame size: %d \n", af->framesize); 526 629 return c; 527 630 } 528 631 529 int get_ac3_info(ringbuffer *rbuf, audio_frame_t *af, int off, int le)632 int get_ac3_info(ringbuffer *rbuf, audio_frame_t *af, long off, int le, int verb) 530 633 { 531 634 int c=0; 532 uint8_t headr[ 7];635 uint8_t headr[6]; 533 636 uint8_t frame; 534 637 int half = 0; 535 638 int fr; … … 544 647 545 648 af->layer = 0; // 0 for AC3 546 649 547 if (DEBUG ) fprintf (stderr,"AC3 stream:");650 if (DEBUG && verb) fprintf (stderr,"AC3 stream:"); 548 651 frame = (headr[4]&0x3F); 549 652 af->bit_rate = ac3_bitrates[frame>>1]*1000; 550 653 half = ac3half[headr[5] >> 3]; 551 if (DEBUG ) fprintf (stderr," bit rate: %d kb/s", af->bit_rate/1000);654 if (DEBUG && verb) fprintf (stderr," bit rate: %d kb/s", af->bit_rate/1000); 552 655 fr = (headr[4] & 0xc0) >> 6; 553 656 af->frequency = (ac3_freq[fr] *100) >> half; 554 657 555 if (DEBUG ) fprintf (stderr," freq: %d Hz\n", af->frequency);658 if (DEBUG && verb) fprintf (stderr," freq: %d Hz\n", af->frequency); 556 659 557 660 switch (headr[4] & 0xc0) { 558 661 case 0: … … 568 671 break; 569 672 } 570 673 571 if (DEBUG ) fprintf (stderr," frame size %d\n", af->framesize);674 if (DEBUG && verb) fprintf (stderr," frame size %d\n", af->framesize); 572 675 573 676 af->off = c; 574 677 af->set = 1; 575 576 //FIXME calculate frametime 577 af->frametime = 0; 578 579 return c; 678 return c; 580 679 } 581 680 582 681 583 int get_video_ext_info(ringbuffer *rbuf, sequence_t *s, intoff, int le)682 int get_video_ext_info(ringbuffer *rbuf, sequence_t *s, long off, int le) 584 683 { 585 684 uint8_t *headr; 586 685 uint8_t buf[12]; … … 612 711 613 712 if (DEBUG) fprintf(stderr,"Sequence Extension:"); 614 713 s->profile = ((headr[0]&0x0F) << 4) | ((headr[1]&0xF0) >> 4); 615 if (headr[1]&0x08) s->progressive = 1; 616 else s->progressive = 0; 714 if (headr[1]&0x08){ 715 s->progressive = 1; 716 if (DEBUG) fprintf(stderr," progressive sequence "); 717 } else s->progressive = 0; 617 718 s->chroma = (headr[1]&0x06)>>1; 618 719 if (DEBUG){ 619 720 switch(s->chroma){ … … 660 761 break; 661 762 662 763 case PICTURE_CODING_EXTENSION:{ 663 int pulldown = 0; 764 int repeat_first = 0; 765 int top_field = 0; 766 int prog_frame = 0; 664 767 665 768 if (!s->set || s->pulldown_set) break; 666 769 if (ring_peek(rbuf, buf, 10, off) < 0) return -2; 667 770 headr=buf+4; 668 771 669 772 if ( (headr[2]&0x03) != 0x03 ) break; // not frame picture 670 if ( (headr[3]&0x02) ) pulldown = 1; // repeat flag set => pulldown 773 if ( (headr[3]&0x02) ) repeat_first = 1; // repeat flag set => pulldown 774 if ( (headr[3]&0x80) ) top_field=1; 775 if ( (headr[4]&0x80) ) prog_frame=1; 776 777 if (repeat_first) { 778 if (!s->progressive){ 779 if (s->current_tmpref) 780 s->pulldown = PULLDOWN23; 781 else 782 s->pulldown = PULLDOWN32; 783 s->pulldown_set = 1; 784 } else { 785 if(prog_frame && top_field) 786 s->progressive = TWO_FIELD; 787 // if (DEBUG) fprintf(stderr,"Picture Coding Extension: progressive tmp %d top %d prog %d rep %d\n", s->current_tmpref, top_field, prog_frame, repeat_first); 788 } 789 } 671 790 672 if (pulldown){673 if (s->current_tmpref)674 s->pulldown = PULLDOWN23;675 else676 s->pulldown = PULLDOWN32;677 s->pulldown_set = 1;678 }679 791 if (DEBUG){ 680 792 switch (s->pulldown) { 681 793 case PULLDOWN32: 682 if (DEBUG)fprintf(stderr,"Picture Coding Extension:");794 fprintf(stderr,"Picture Coding Extension:"); 683 795 fprintf(stderr," 3:2 pulldown detected \n"); 684 796 break; 685 797 case PULLDOWN23: 686 if (DEBUG)fprintf(stderr,"Picture Coding Extension:");798 fprintf(stderr,"Picture Coding Extension:"); 687 799 fprintf(stderr," 2:3 pulldown detected \n"); 688 800 break; 689 801 // default: -
programs/mythtranscode/replex/ringbuffer.c
2 2 * ringbuffer.c 3 3 * 4 4 * 5 * Copyright (C) 2003 Marcus Metzler <mocm@metzlerbros.de> 5 * Copyright (C) 2003 - 2006 6 * Marcus Metzler <mocm@metzlerbros.de> 6 7 * Metzler Brothers Systementwicklung GbR 8 * (C) 2006 Reel Multimedia 7 9 * 8 10 * This program is free software; you can redistribute it and/or 9 11 * modify it under the terms of the GNU General Public License … … 30 32 #include "pes.h" 31 33 32 34 #define DEBUG 1 35 // Initialize buffer 33 36 int ring_init (ringbuffer *rbuf, int size) 34 37 { 35 38 if (size > 0){ … … 47 50 return 0; 48 51 } 49 52 50 int ring_reinit (ringbuffer *rbuf, int size) 51 { 52 if (size > (int)(rbuf->size)) { 53 uint8_t *tmpalloc = (uint8_t *) realloc(rbuf->buffer, 54 sizeof(uint8_t)*size); 55 if (! tmpalloc) 56 return -1; 57 rbuf->buffer = tmpalloc; 58 if (rbuf->write_pos < rbuf->read_pos) 59 { 60 unsigned int delta = size - rbuf->size; 61 memmove(rbuf->buffer + rbuf->read_pos + delta, 62 rbuf->buffer + rbuf->read_pos, 63 rbuf->size - rbuf->read_pos); 64 rbuf->read_pos += delta; 65 } 66 rbuf->size = size; 67 } 68 return 0; 69 } 53 // reset buffer 70 54 void ring_clear(ringbuffer *rbuf) 71 55 { 72 56 rbuf->read_pos = 0; … … 74 58 } 75 59 76 60 77 61 // delete buffer 78 62 void ring_destroy(ringbuffer *rbuf) 79 63 { 80 64 free(rbuf->buffer); 81 65 } 82 66 83 67 68 //write into buffer 84 69 int ring_write(ringbuffer *rbuf, uint8_t *data, int count) 85 70 { 86 71 … … 92 77 free = ring_free(rbuf); 93 78 94 79 if ( free < count ){ 95 if (DEBUG) fprintf(stderr,"ringbuffer overflow %d<%d %d\n", 96 free, count, rbuf->size); 97 return FULL_BUFFER; 80 if ( free > 0 ){ 81 count = free; 82 } else { 83 if (DEBUG) fprintf(stderr,"ringbuffer overflow %d<%d %d\n", 84 free, count, rbuf->size); 85 return FULL_BUFFER; 86 } 98 87 } 99 88 100 89 if (count >= rest){ … … 112 101 return count; 113 102 } 114 103 115 int ring_peek(ringbuffer *rbuf, uint8_t *data, unsigned int count, uint32_t off) 104 // peek into buffer 105 int ring_peek(ringbuffer *rbuf, uint8_t *data, int count, long off) 116 106 { 117 107 118 unsignedint avail, pos, rest;108 int avail, pos, rest; 119 109 120 110 if (count <=0 || off+count > rbuf->size || off+count >ring_avail(rbuf)) return -1; 121 111 pos = (rbuf->read_pos+off)%rbuf->size; … … 140 130 return count; 141 131 } 142 132 143 int ring_poke(ringbuffer *rbuf, uint8_t *data, unsigned int count, uint32_t off)144 {145 133 146 unsigned int avail, pos, rest; 147 148 if (count <=0 || off+count > rbuf->size || off+count >ring_avail(rbuf)) return -1; 149 pos = (rbuf->read_pos+off)%rbuf->size; 150 rest = rbuf->size - pos ; 151 avail = ring_avail(rbuf); 152 153 154 if ( avail < count ){ 155 // if (DEBUG) fprintf(stderr,"ringbuffer peek underflow %d<%d %d %d\n", 156 // avail, count, pos, rbuf->write_pos); 157 return EMPTY_BUFFER; 158 } 159 160 if ( count < rest ){ 161 memcpy(rbuf->buffer+pos, data, count); 162 } else { 163 memcpy(rbuf->buffer+pos, data, rest); 164 if ( count - rest) 165 memcpy(rbuf->buffer, data+rest, count - rest); 166 } 167 168 return count; 169 } 170 134 //read from buffer 171 135 int ring_read(ringbuffer *rbuf, uint8_t *data, int count) 172 136 { 173 137 … … 199 163 return count; 200 164 } 201 165 166 //skip buffer 202 167 int ring_skip(ringbuffer *rbuf, int count) 203 168 { 204 169 … … 226 191 } 227 192 228 193 229 194 // write from file into buffer 230 195 int ring_write_file(ringbuffer *rbuf, int fd, int count) 231 196 { 232 197 … … 237 202 rest = rbuf->size - pos; 238 203 free = ring_free(rbuf); 239 204 240 if ( free < count){205 if ( !free ){ 241 206 if (DEBUG) fprintf(stderr,"ringbuffer overflow %d<%d %d %d\n", 242 207 free, count, pos, rbuf->read_pos); 243 208 return FULL_BUFFER; 244 209 } 210 211 if ( count > free ) count = free; 245 212 246 213 if (count >= rest){ 247 214 rr = read (fd, rbuf->buffer+pos, rest); … … 262 229 263 230 264 231 232 // write from buffer into file 265 233 int ring_read_file(ringbuffer *rbuf, int fd, int count) 266 234 { 267 235 … … 296 264 return rr; 297 265 } 298 266 299 267 // print memory 300 268 static void show(uint8_t *buf, int length) 301 269 { 302 270 int i,j,r; … … 329 297 } 330 298 } 331 299 332 void ring_show(ringbuffer *rbuf, unsigned int count, uint32_toff)300 void ring_show(ringbuffer *rbuf, int count, long off) 333 301 { 334 302 335 unsignedint avail, pos, rest;303 int avail, pos, rest; 336 304 337 305 if (count <=0 || off+count > rbuf->size || off+count >ring_avail(rbuf)) return; 338 306 pos = (rbuf->read_pos+off)%rbuf->size; … … 368 336 return 0; 369 337 } 370 338 371 void dummy_destroy(dummy_buffer *dbuf)372 {373 ring_destroy(&dbuf->time_index);374 ring_destroy(&dbuf->data_index);375 }376 377 339 void dummy_clear(dummy_buffer *dbuf) 378 340 { 379 341 dbuf->fill = 0; … … 423 385 424 386 return dsize; 425 387 } 426 void dummy_print(dummy_buffer *dbuf)427 {428 int i;429 uint64_t rtime;430 uint32_t size;431 int avail = ring_avail(&dbuf->time_index) / sizeof(uint64_t);432 for(i = 0; i < avail; i++) {433 ring_peek(&dbuf->time_index,(uint8_t *) &rtime,434 sizeof(uint64_t), i * sizeof(uint64_t));435 ring_peek(&dbuf->data_index,(uint8_t *) &size,436 sizeof(uint32_t), i * sizeof(uint32_t));437 438 printf("%d : %llu %u\n", i, (long long unsigned int)rtime, size);439 }440 printf("Used: %d Free: %d data-free: %d\n", avail, 1000-avail, dbuf->size - dbuf->fill);441 } -
programs/mythtranscode/replex/mpg_common.c
2 2 * mpg_common.c: COMMON MPEG functions for replex 3 3 * 4 4 * 5 * Copyright (C) 2003 Marcus Metzler <mocm@metzlerbros.de> 5 * Copyright (C) 2003 - 2006 6 * Marcus Metzler <mocm@metzlerbros.de> 6 7 * Metzler Brothers Systementwicklung GbR 8 * (C) 2006 Reel Multimedia 7 9 * 8 10 * This program is free software; you can redistribute it and/or 9 11 * modify it under the terms of the GNU General Public License … … 61 63 } 62 64 } 63 65 66 //---------------------------------------------------------------------------- 67 #define CMP_CORE(offset) \ 68 x=Data[i+1+offset]; \ 69 if (x<2) { \ 70 if (x==0) { \ 71 if ( Data[i+offset]==0 && Data[i+2+offset]==1) \ 72 return i+offset; \ 73 else if (Data[i+2+offset]==0 && Data[i+3+offset]==1) \ 74 return i+1+offset; \ 75 } \ 76 else if (x==1 && Data[i-1+offset]==0 && Data[i+offset]==0 && (i+offset)>0) \ 77 return i-1+offset; \ 78 } 64 79 80 int FindPacketHeader(const uint8_t *Data, int s, int l) 81 { 82 int i; 83 uint8_t x; 65 84 66 int find_mpg_header(uint8_t head, uint8_t *buf, int length) 85 if (l>12) { 86 for(i=s;i<l-12;i+=12) { 87 CMP_CORE(0); 88 CMP_CORE(3); 89 CMP_CORE(6); 90 CMP_CORE(9); 91 } 92 93 for(; i<l-3; i+=3) { 94 CMP_CORE(0); 95 } 96 } 97 else { 98 for(i=s; i<l-3; i+=3) { 99 CMP_CORE(0); 100 } 101 } 102 return -1; 103 } 104 //---------------------------------------------------------------------------- 105 106 int find_mpg_header(uint8_t head, uint8_t *buf, int Count) 67 107 { 108 int n=0; 109 uint8_t *Data=buf; 110 while(n<Count) { 111 int x; 112 x=FindPacketHeader(Data, 0, Count - n); // returns position of first 00 113 if (x!=-1) { 114 Data+=x; 115 n+=x; 116 if (Data[3]==head) { 117 return n; 118 } 119 n+=3; 120 Data+=3; 121 Count-=3; 122 } 123 else 124 break; 125 } 126 return -1; 68 127 128 } 129 130 int find_any_header(uint8_t *head, uint8_t *buf, int Count) 131 { 132 int n=0; 133 uint8_t *Data=buf; 134 while(n<Count) { 135 int x; 136 x=FindPacketHeader(Data, 0, Count - n); // returns position of first 00 137 if (x!=-1) { 138 Data+=x; 139 n+=x; 140 *head=Data[3]; 141 return n; 142 } 143 else 144 break; 145 } 146 return -1; 147 148 } 149 150 int find_mpg_headerx(uint8_t head, uint8_t *buf, int length) 151 { 152 69 153 int c = 0; 70 154 int found=0; 71 155 … … 99 183 } 100 184 101 185 102 int find_any_header (uint8_t *head, uint8_t *buf, int length)186 int find_any_headerx(uint8_t *head, uint8_t *buf, int length) 103 187 { 104 188 105 189 int c = 0; … … 153 237 } 154 238 155 239 156 int mring_peek( ringbuffer *rbuf, uint8_t *buf, unsigned int l, uint32_toff)240 int mring_peek( ringbuffer *rbuf, uint8_t *buf, int l, long off) 157 241 { 158 242 int c = 0; 159 243 … … 205 289 } 206 290 207 291 208 int ring_find_any_header(ringbuffer *rbuf, uint8_t *head, int off, int le) 292 #define PEEK_SIZE (512+1024) 293 int ring_find_any_headery(ringbuffer *rbuf, uint8_t *head, int off, int le) 209 294 { 295 uint8_t buf[PEEK_SIZE]; 296 // int xoff; 297 int res,x; 298 // int found; 299 int n=off; 300 int peek_snip; 301 // printf("# %i %i\n",off,le); 302 while(le>0) { 303 if (le>PEEK_SIZE) 304 peek_snip=PEEK_SIZE; 305 else 306 peek_snip=le; 210 307 308 res=mring_peek(rbuf, buf, peek_snip, n); 309 if (res<0) { 310 peek_snip=ring_avail(rbuf); 311 // printf("PP %i\n",peek_snip); 312 if (peek_snip>PEEK_SIZE) 313 peek_snip=PEEK_SIZE; 314 if (peek_snip>le) 315 peek_snip=le; 316 res=mring_peek(rbuf,buf,peek_snip,n); 317 if (res<0) 318 return -1; 319 } 320 // printf("ZZ %i %i\n",peek_snip,n); 321 x=FindPacketHeader(buf, 0, peek_snip); // returns position of first 00 322 if (x!=-1 && x<=peek_snip-4) { 323 n+=x-off; 324 325 *head=buf[x+3]; 326 return n; 327 } 328 if (peek_snip<=4) { 329 int i; 330 for(i=0;i<peek_snip;i++) 331 if (buf[i]==0) 332 return -2; 333 return -1; 334 } 335 336 n+=peek_snip-4; 337 le-=peek_snip-4; 338 } 339 return -1; // Not found 340 } 341 342 int ring_find_any_headerx(ringbuffer *rbuf, uint8_t *head, int off, int le) 343 { 344 211 345 int c = 0; 212 346 int found =0; 213 347 … … 244 378 else return -1; 245 379 } 246 380 381 int ring_find_any_header(ringbuffer *rbuf, uint8_t *head, int off, int le) 382 { 383 uint8_t a=0; 384 // uint8_t b=0; 385 int x; 386 // int y; 387 388 x=ring_find_any_headery(rbuf, &a, off, le); 389 #if 0 390 y=ring_find_any_headery(rbuf, &b, off, le); 391 if (x!=y || a!=b) 392 printf("MY %i %i, ORG %i %i\n",y, b, x, a); 393 #endif 394 *head=a; 395 return x; 396 } -
programs/mythtranscode/replex/ts.h
2 2 * ts.h 3 3 * 4 4 * 5 * Copyright (C) 2003 Marcus Metzler <mocm@metzlerbros.de> 5 * Copyright (C) 2003 - 2006 6 * Marcus Metzler <mocm@metzlerbros.de> 6 7 * Metzler Brothers Systementwicklung GbR 7 8 * 8 9 * This program is free software; you can redistribute it and/or … … 27 28 #ifndef _TS_H_ 28 29 #define _TS_H_ 29 30 30 #include "ringbuffer.h"31 #include "mpg_common.h"32 33 31 #define TS_SIZE 188 34 32 #define TRANS_ERROR 0x80 35 33 #define PAY_START 0x40 … … 58 56 #define PIECE_RATE 0x40 59 57 #define SEAM_SPLICE 0x20 60 58 61 #define TS_VIDPID 410162 #define TS_MP2PID 420163 #define TS_AC3PID 430164 59 uint16_t get_pid(uint8_t *pid); 65 60 int find_pids(uint16_t *vpid, uint16_t *apid, uint16_t *ac3pid,uint8_t *buf, int len); 66 61 int find_pids_pos(uint16_t *vpid, uint16_t *apid, uint16_t *ac3pid,uint8_t *buf, int len, int *vpos, int *apos, int *ac3pos); 67 68 int write_video_ts(uint64_t vpts, uint64_t vdts, uint64_t SCR,69 uint8_t *buf, int *vlength, uint8_t ptsdts, ringbuffer *vrbuffer);70 int write_audio_ts(int n, uint64_t pts,71 uint8_t *buf, int *alength, uint8_t ptsdts, ringbuffer *arbuffer);72 int write_ac3_ts(int n, uint64_t pts, uint8_t *buf, int *alength,73 uint8_t ptsdts, int nframes, ringbuffer *ac3rbuffer);74 void write_ts_patpmt(extdata_t *ext, int extcnt, uint8_t prog_num,75 uint8_t *buf);76 62 #endif /*_TS_H_*/ -
programs/mythtranscode/replex/pes.h
1 /* 2 Copyright (C) 2003 Marcus Metzler (mocm@metzlerbros.de) 1 /* 2 * pes.h: MPEG PES functions for replex 3 * 4 * 5 * Copyright (C) 2003 - 2006 6 * Marcus Metzler <mocm@metzlerbros.de> 7 * Metzler Brothers Systementwicklung GbR 8 * (C) 2006 Reel Multimedia 9 * 10 * This program is free software; you can redistribute it and/or 11 * modify it under the terms of the GNU General Public License 12 * as published by the Free Software Foundation; either version 2 13 * of the License, or (at your option) any later version. 14 * 15 * 16 * This program is distributed in the hope that it will be useful, 17 * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 * General Public License for more details. 20 * 21 * 22 * You should have received a copy of the GNU General Public License 23 * along with this program; if not, write to the Free Software 24 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 25 * Or, point your browser to http://www.gnu.org/copyleft/gpl.html 26 * 27 */ 3 28 4 */5 29 6 30 #ifndef _PES_H_ 7 31 #define _PES_H_ … … 9 33 #include <stdint.h> 10 34 #include "ringbuffer.h" 11 35 12 #define TS_HEADER_MIN 413 36 #define PS_HEADER_L1 14 14 37 #define PS_HEADER_L2 (PS_HEADER_L1+24) 15 38 #define PES_MIN 7 … … 71 94 typedef 72 95 struct pes_in_s{ 73 96 int type; 74 unsignedint found;97 int found; 75 98 int withbuf; 76 99 uint8_t *buf; 77 100 ringbuffer *rbuf; … … 102 125 uint64_t ptsadd(uint64_t pts1, uint64_t pts2); 103 126 104 127 105 int write_pes_header(uint8_t id, int length , uint64_t PTS, uint64_t DTS, 106 uint8_t *obuf, int stuffing, uint8_t ptsdts); 107 void write_padding_pes( int pack_size, int extcnt, 128 void write_padding_pes( int pack_size, int apidn, int ac3n, 108 129 uint64_t SCR, uint64_t muxr, uint8_t *buf); 109 int write_ac3_pes( int pack_size, int extcnt, int n, uint64_t pts,130 int write_ac3_pes( int pack_size, int apidn, int ac3n, int n, uint64_t pts, 110 131 uint64_t SCR, 111 132 uint32_t muxr, uint8_t *buf, int *alength, uint8_t ptsdts, 112 int nframes,int ac3_off, ringbuffer *ac3rbuffer); 113 int write_audio_pes( int pack_size, int extcnt, int n, uint64_t pts, 133 int nframes,int ac3_off, ringbuffer *ac3rbuffer, int framelength); 134 int bwrite_ac3_pes( int pack_size, int apidn, int ac3n, int n, uint64_t pts, 135 uint64_t SCR, 136 uint32_t muxr, uint8_t *buf, int *alength, uint8_t ptsdts, 137 int nframes,int ac3_off, uint8_t *ac3rbuffer, int bsize, int framelength); 138 int write_audio_pes( int pack_size, int apidn, int ac3n, int n, uint64_t pts, 114 139 uint64_t SCR, uint32_t muxr, uint8_t *buf, int *alength, 115 140 uint8_t ptsdts, ringbuffer *arbuffer); 116 int write_video_pes( int pack_size, int extcnt, uint64_t vpts, 141 int bwrite_audio_pes( int pack_size, int apidn, int ac3n, int n, uint64_t pts, 142 uint64_t SCR, uint32_t muxr, uint8_t *buf, int *alength, 143 uint8_t ptsdts, uint8_t *arbuffer, int bsize ); 144 int write_video_pes( int pack_size, int apidn, int ac3n, uint64_t vpts, 117 145 uint64_t vdts, uint64_t SCR, uint64_t muxr, 118 146 uint8_t *buf, int *vlength, 119 147 uint8_t ptsdts, ringbuffer *vrbuffer); 120 int write_nav_pack(int pack_size, int extcnt, uint64_t SCR, uint32_t muxr,148 int write_nav_pack(int pack_size, int apidn, int ac3n, uint64_t SCR, uint32_t muxr, 121 149 uint8_t *buf); 122 150 123 124 151 static inline void ptsdec(uint64_t *pts1, uint64_t pts2) 125 152 { 126 153 *pts1= uptsdiff(*pts1, pts2); -
programs/mythtranscode/mythtranscode.pro
19 19 20 20 INCLUDEPATH += replex 21 21 INCLUDEPATH += ../../libs/libavcodec ../../libs/libavformat \ 22 ../../libs/libavutil ../../libs/ libmythmpeg222 ../../libs/libavutil ../../libs/ ../../libs/libmythmpeg2 23 23 24 24 #The following line was inserted by qt3to4 25 25 QT += network xml sql opengl qt3support -
programs/mythtranscode/main.cpp
363 363 if(!strcmp(a.argv()[argpos + 1], "dvd")) 364 364 otype = REPLEX_DVD; 365 365 if(!strcmp(a.argv()[argpos + 1], "ts")) 366 otype = REPLEX_ TS_SD;366 otype = REPLEX_HDTV; 367 367 368 368 ++argpos; 369 369 }