Ticket #2077: mythtranscode-replexsync-trunk-r18755.diff

File mythtranscode-replexsync-trunk-r18755.diff, 173.2 KB (added by robert.mcnamara@…, 12 years ago)

Updated version of replex resync with some bug fixes.

  • replex/ringbuffer.h

     
    22 * ringbuffer.h
    33 *       
    44 *
    5  * Copyright (C) 2003 Marcus Metzler <mocm@metzlerbros.de>
     5 * Copyright (C) 2003 - 2006
     6 *                    Marcus Metzler <mocm@metzlerbros.de>
    67 *                    Metzler Brothers Systementwicklung GbR
    78 *
    89 * This program is free software; you can redistribute it and/or
     
    4041        typedef struct ringbuffer {
    4142                int read_pos;
    4243                int write_pos;
    43                 uint32_t size;
     44                int size;
    4445                uint8_t *buffer;
    4546        } ringbuffer;
    4647
    4748
    48 #define DBUF_INDEX 10000
     49#define DBUF_INDEX 1000
    4950
    5051        typedef struct dummy_buffer_s {
    5152                uint32_t size;
     
    5657
    5758
    5859        int  ring_init (ringbuffer *rbuf, int size);
    59         int  ring_reinit (ringbuffer *rbuf, int size);
    6060        void ring_clear(ringbuffer *rbuf);
    6161        void ring_destroy(ringbuffer *rbuf);
    6262        int ring_write(ringbuffer *rbuf, uint8_t *data, int count);
    6363        int ring_read(ringbuffer *rbuf, uint8_t *data, int count);
    6464        int ring_write_file(ringbuffer *rbuf, int fd, int count);
    6565        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);
    7067        int ring_skip(ringbuffer *rbuf, int count);
    7168
    7269        static inline int ring_wpos(ringbuffer *rbuf)
     
    9592                return ring_posdiff(rbuf, rbuf->read_pos,pos);
    9693        }
    9794
    98         static inline unsigned int ring_free(ringbuffer *rbuf){
     95        static inline int ring_free(ringbuffer *rbuf){
    9996                int free;
    100                 free = rbuf->read_pos - rbuf->write_pos;
     97                free = rbuf->read_pos - rbuf->write_pos-1;
    10198                if (free <= 0) free += rbuf->size;
    102                 //Note: free is gauranteed to be >=1 from the above
    103                 return free - 1;
     99               
     100                return free;
    104101        }
    105102
    106         static inline unsigned int ring_avail(ringbuffer *rbuf){
     103        static inline int ring_avail(ringbuffer *rbuf){
    107104                int avail;
    108105                avail = rbuf->write_pos - rbuf->read_pos;
    109106                if (avail < 0) avail += rbuf->size;
     
    121118        int dummy_add(dummy_buffer *dbuf, uint64_t time, uint32_t size);
    122119        void dummy_clear(dummy_buffer *dbuf);
    123120        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);
    126122
    127123#ifdef __cplusplus
    128124}
  • replex/element.h

     
    22 * element.h
    33 *       
    44 *
    5  * Copyright (C) 2003 Marcus Metzler <mocm@metzlerbros.de>
     5 * Copyright (C) 2003 - 2006
     6 *                    Marcus Metzler <mocm@metzlerbros.de>
    67 *                    Metzler Brothers Systementwicklung GbR
    78 *
    89 * This program is free software; you can redistribute it and/or
     
    5152#define PICTURE_DISPLAY_EXTENSION    0x07
    5253
    5354#define I_FRAME 0x01
    54 #define P_FRAME 0x02
    55 #define B_FRAME 0x03
    56 #define D_FRAME 0x04
     55#define B_FRAME 0x02
     56#define P_FRAME 0x03
     57#define D_FRAME 0x03
    5758
    5859#define OFF_SIZE 4
    5960#define FIRST_FIELD 0
     
    7475#define PULLDOWN32 1
    7576#define PULLDOWN23 2
    7677
     78#define PROGRESSIVE 1
     79#define ONE_FIELD 2
     80#define TWO_FIELD 3
     81
    7782#define CLOCK_MS        27000ULL
    7883#define CLOCK_PER    27000000000ULL
    7984#define SEC_PER      (CLOCK_PER/s->frame_rate)
    8085
    8186
    8287enum {
    83         NONE=0,AC3, MPEG_AUDIO, LPCM, MAX_TYPES
     88        NONE=0,AC3, MPEG_AUDIO, LPCM
    8489};
    8590
    8691typedef struct sequence_s{
     
    109114struct audio_frame_s{
    110115        int set;
    111116        int layer;
     117        int padding;
     118        int sample_rate;
     119        int mpg25;
     120        int lsf;
    112121        uint32_t bit_rate;
    113122        uint32_t frequency;
    114123        uint32_t mode;
    115124        uint32_t mode_extension;
    116125        uint32_t emphasis;
    117126        uint32_t framesize;
    118         uint32_t frametime;
    119127        uint32_t off;
    120         char     language[4];
     128       
    121129} audio_frame_t;
    122130
    123131void pts2time(uint64_t pts, uint8_t *buf, int len);
    124 int find_audio_sync(ringbuffer *rbuf, uint8_t *buf, int off, int type, int le);
    125 int find_audio_s(uint8_t *rbuf, int off, int type, int le);
    126 int get_video_info(ringbuffer *rbuf, sequence_t *s, int off, 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);
     132int find_audio_sync(ringbuffer *rbuf, uint8_t *buf, long off, int type, int le);
     133int find_audio_s(uint8_t *rbuf, long off, int type, int le);
     134int get_video_info(ringbuffer *rbuf, sequence_t *s, long off, int le);
     135int get_audio_info(ringbuffer *rbuf, audio_frame_t *af, long off, int le, int verb);
     136int get_ac3_info(ringbuffer *rbuf, audio_frame_t *af, long off, int le, int verb);
    129137uint64_t add_pts_audio(uint64_t pts, audio_frame_t *aframe, uint64_t frames);
    130138uint64_t next_ptsdts_video(uint64_t *pts, sequence_t *s, uint64_t fcount, uint64_t gcount);
     139int  cfix_audio_count(audio_frame_t *aframe, uint64_t origpts, uint64_t pts);
    131140void fix_audio_count(uint64_t *acount, audio_frame_t *aframe,
    132141                     uint64_t origpts, uint64_t pts);
    133142void fix_video_count(sequence_t *s, uint64_t *frame, uint64_t origpts,
    134143                     uint64_t pts, uint64_t origdts, uint64_t dts);
    135144
    136145int check_audio_header(ringbuffer *rbuf, audio_frame_t * af,
    137                        int  off, int le, int type);
    138 int get_video_ext_info(ringbuffer *rbuf, sequence_t *s, int off, int le);
     146                       long  off, int le, int type);
     147int get_video_ext_info(ringbuffer *rbuf, sequence_t *s, long off, int le);
    139148
    140149#endif /*_ELEMENT_H_*/
  • replex/replex.c

     
    22 * replex.c
    33 *       
    44 *
    5  * Copyright (C) 2003 Marcus Metzler <mocm@metzlerbros.de>
     5 * Copyright (C) 2003 - 2006
     6 *                    Marcus Metzler <mocm@metzlerbros.de>
    67 *                    Metzler Brothers Systementwicklung GbR
     8 *           (C) 2006 Reel Multimedia
    79 *
    810 * This program is free software; you can redistribute it and/or
    911 * modify it under the terms of the GNU General Public License
     
    3941#include "replex.h"
    4042#include "pes.h"
    4143
    42 #include "avcodec.h"
    43 #include "avformat.h"
     44static int replex_all_set(struct replex *rx);
    4445
    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
     46void overflow_exit(struct replex *rx)
     47{
     48        rx->overflows++;
    5149
    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}
    5558
    56 static int replex_all_set(struct replex *rx);
    57 
    5859int replex_check_id(struct replex *rx, uint16_t id)
    5960{
    6061        int i;
     
    7374        return -1;
    7475}
    7576
    76 int encode_mp2_audio(audio_frame_t *aframe, uint8_t *buffer, int bufsize)
     77
     78static int audio_jump(struct replex *rx)
    7779{
    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
     94static 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
     111static 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
     124static void create_fillframe1(ringbuffer *rbuf, int off, int *fsize,
     125                              int type, uint8_t *fillframe, struct replex *rx)
     126{
     127        int fs = *fsize;
    82128       
    83         fprintf(stderr, "encoding an MP2 audio frame\n");
     129        if (fs > MAXFRAME) return;
    84130
    85         /* find the MP2 encoder */
    86         codec = avcodec_find_encoder(CODEC_ID_MP2);
    87         if (!codec) {
    88                 fprintf(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);
    90136        }
    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}
    93143
    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;
     144static 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;
    104155        }
     156        if (rx->fillzero && type == MPEG_AUDIO)
     157                memset(fillframe+4, 0, MAXFRAME-4);
     158        else
     159                ring_peek (rbuf, fillframe, fs, off);
    105160
    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
     165static 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
     187static 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;
    109198       
    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;
    114206        }
     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;
    115225               
    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        }
    118273       
    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);
    127281
    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);
    131426       
    132         return 0;
    133 }
     427                                                diff = 0;
     428                                        }
     429                                }
    134430
     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
    135490void analyze_audio( pes_in_t *p, struct replex *rx, int len, int num, int type)
    136491{
    137492        int c=0;
     
    143498        uint64_t *fpts=NULL;
    144499        uint64_t *lpts=NULL;
    145500        int bsize = 0;
    146         int first = 1;
     501        uint64_t *ajump=NULL;
     502        uint64_t *aoff=NULL;
    147503        uint8_t buf[7];
    148504        int off=0;
    149505        int *apes_abort=NULL;
    150         int re=0;
     506        uint64_t adelay=0;
     507        int first = 1;
     508        int *filled=NULL;
    151509       
    152510        switch ( type ){
    153511        case AC3:
     
    163521                lpts = &rx->last_ac3pts[num];
    164522                bsize = rx->ac3buf;
    165523                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];
    166528                break;
    167529
    168530        case MPEG_AUDIO:
     
    178540                lpts = &rx->last_apts[num];
    179541                bsize = rx->audiobuf;
    180542                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];
    181547                break;
    182548        }
    183549       
     
    186552        while (c < len){
    187553                if ( (pos = find_audio_sync(rbuf, buf, c+off, type, len-c) )
    188554                     >= 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);
    390560                } else {
    391561                        *apes_abort = len-c;
    392562                        c=len;
     
    394564        }       
    395565}
    396566
     567
    397568void analyze_video( pes_in_t *p, struct replex *rx, int len)
    398569{
    399570        uint8_t buf[8];
     
    418589        int gop_off = 0;
    419590        int seq_p = 0;
    420591        int flush=0;
     592        int keep_now = 0;
    421593
    422594        rbuf = &rx->vrbuffer;
    423595        index_buf = &rx->index_vrbuffer;
     
    524696                                                diff = ptsdiff(iu->pts,
    525697                                                               rx->first_vpts
    526698                                                               + 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                                                }
    527717
    528718                                                if (!rx->keep_pts &&
    529719                                                    abs((int)(diff)) > 3*SEC_PER/2){
     
    533723                                                        printpts(newpts+rx->first_vpts);
    534724                                                        printpts(newpts);
    535725                                                        fprintf(stderr," diff: ");
    536                                                         printpts(abs((int)diff));
     726                                                        printpts(diff);
    537727                                                        fprintf(stderr,"\n");
    538728                                                }
    539729                                        }
     
    544734                                                diff = ptsdiff(iu->dts,
    545735                                                               newdts +
    546736                                                               rx->first_vpts);
    547                                                 if (!rx->keep_pts &&
     737                                                if (!rx->keep_pts && !keep_now &&
    548738                                                    abs((int)diff) > 3*SEC_PER/2){
    549739                                                        fprintf(stderr,"video DTS inconsistent: ");
    550740                                                        printpts(trans_pts_dts(p->dts));
     
    552742                                                        printpts(newdts+rx->first_vpts);
    553743                                                        printpts(newdts);
    554744                                                        fprintf(stderr,"diff: ");
    555                                                         printpts(abs((int)diff));
     745                                                        printpts(diff);
    556746                                                        fprintf(stderr,"\n");
    557747                                                }
    558748                                        }
    559                                         if (!rx->keep_pts){
     749                                        if (!rx->keep_pts && !keep_now){
    560750                                                iu->pts = newpts;
    561751                                                iu->dts = newdts;
    562752                                        } else {
     
    626816                                gop = 1;
    627817                                gop_off = c+pos - seq_p;
    628818                               
    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){
    631820                                        rx->vpes_abort = len -(c+pos-1);
    632821                                        return;
    633822                                }                               
     
    652841                                        return;
    653842                                }
    654843                               
    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;
    657846
    658847
    659848                                frame = ((buf[5]&0x38) >>3);
     
    731920                                        if ( ring_write(index_buf, (uint8_t *)
    732921                                                         &rx->current_vindex,
    733922                                                         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);
    736925
    737926                                        }
    738927                                }
     
    8501039void pes_es_out(pes_in_t *p)
    8511040{
    8521041
    853         struct replex *rx;
     1042        struct replex *rx = NULL;
    8541043        char t[80];
    855         int len, i;
     1044        int len = 0, i =0;
    8561045        int l=0;
    8571046
    8581047        len = p->plength-3-p->hlength;
     
    8651054                p->ini_pos = ring_wpos(&rx->vrbuffer);
    8661055
    8671056                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);
    8701059                }
    8711060                if (rx->vpes_abort){
    8721061                        p->ini_pos = (p->ini_pos - rx->vpes_abort)%rx->vrbuffer.size;
     
    8881077                if (l < 0) break;
    8891078                p->ini_pos = ring_wpos(&rx->arbuffer[l]);
    8901079                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);
    8931082                }
    8941083                if (rx->apes_abort[l]){
    8951084                        p->ini_pos = (p->ini_pos - rx->apes_abort[l])
     
    9301119                p->ini_pos = ring_wpos(&rx->ac3rbuffer[l]);
    9311120       
    9321121                if (ring_write(&rx->ac3rbuffer[l], p->buf+9+hl+p->hlength, len)<0){
    933                         fprintf(stderr,"video ring buffer overrun error\n");
    934                         exit(1);
     1122                        fprintf(stderr,"ac3 ring buffer overrun error\n");
     1123                        overflow_exit(rx);
    9351124                }
    9361125                if (rx->ac3pes_abort[l]){
    9371126                        p->ini_pos = (p->ini_pos - rx->ac3pes_abort[l])
     
    10551244        }
    10561245
    10571246       
    1058         if ( tsp[1] & PAY_START) {
     1247        if ( tsp[1] & PAY_START){
    10591248                if (p->plength == MMAX_PLENGTH-6){
    10601249                        p->plength = p->found-6;
    10611250                        es_out(p);
     
    10631252                }
    10641253        }
    10651254
    1066         if ( tsp[3] & ADAPT_FIELD) {  // adaptation field?
     1255        if ( tsp[3] & ADAPT_FIELD){  // adaptation field?
    10671256                off = tsp[4] + 1;
    10681257                if (off+4 >= TS_SIZE) return 0;
    10691258        }
     
    11001289                        fprintf(stderr,"read %3d%%\r", (int)per);
    11011290                        rx->lastper = per;
    11021291                }
     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                }
    11031306        } else fprintf(stderr,"read %.2f MB\r", rx->finread/1024./1024.);
    11041307#endif
    11051308        if (neof < 0 && re == 0) return neof;
     
    11231326        for (i=0; i<rx->apidn;i++){
    11241327                if ((aavail = ring_avail(&rx->index_arbuffer[i])
    11251328                     /sizeof(index_unit)) < LIMIT)
    1126                         if (fill < (int) ring_free(&rx->arbuffer[i]))
     1329                        if (fill < ring_free(&rx->arbuffer[i]))
    11271330                                fill = ring_free(&rx->arbuffer[i]);
    11281331        }
    11291332
    11301333        for (i=0; i<rx->ac3n;i++){
    11311334                if ((ac3avail = ring_avail(&rx->index_ac3rbuffer[i])
    11321335                     /sizeof(index_unit)) < LIMIT)
    1133                         if (fill < (int) ring_free(&rx->ac3rbuffer[i]))
     1336                        if (fill < ring_free(&rx->ac3rbuffer[i]))
    11341337                                fill = ring_free(&rx->ac3rbuffer[i]);
    11351338        }
    11361339
     
    11551358        int count=0;
    11561359        int re=0;
    11571360        uint16_t vpid=0, apid=0, ac3pid=0;
    1158                
     1361       
    11591362        fprintf(stderr,"Trying to find PIDs\n");
    1160         while (!afound && !vfound && count < (int) rx->inflength){
     1363        while (!afound && !vfound && count < rx->inflength){
    11611364                if (rx->vpid) vfound = 1;
    11621365                if (rx->apidn) afound = 1;
    11631366                if ((re = save_read(rx,buf,IN_SIZE))<0)
    11641367                        perror("reading");
    1165                 else 
     1368                else
    11661369                        count += re;
    11671370                if ( (re = find_pids(&vpid, &apid, &ac3pid, buf, re))){
    11681371                        if (!rx->vpid && vpid){
     
    11861389                                afound++;
    11871390                        }
    11881391                       
    1189                 } 
     1392                }
    11901393               
    11911394        }
    11921395       
     
    12111414        int vn=0, an=0,ac3n=0;
    12121415        uint16_t vp,ap,cp;
    12131416        int vpos, apos, cpos;
    1214                
     1417       
    12151418        memset (vpid , 0 , MAXVPID*sizeof(uint16_t));
    12161419        memset (apid , 0 , MAXAPID*sizeof(uint16_t));
    1217     memset (ac3pid , 0 , MAXAC3PID*sizeof(uint16_t));
    1218 
     1420        memset (ac3pid , 0 , MAXAC3PID*sizeof(uint16_t));
     1421       
    12191422        fprintf(stderr,"Trying to find PIDs\n");
    1220         while (count < (int) rx->inflength-IN_SIZE){
     1423        while (count < rx->inflength-IN_SIZE){
    12211424                if ((re = save_read(rx,buf,IN_SIZE))<0)
    12221425                        perror("reading");
    1223                 else 
     1426                else
    12241427                        count += re;
    1225                 if ( (re = find_pids_pos(&vp, &ap, &cp, buf, re, 
     1428                if ( (re = find_pids_pos(&vp, &ap, &cp, buf, re,
    12261429                                         &vpos, &apos, &cpos))){
    12271430                        if (vp){
    12281431                                int old=0;
     
    12411444                                               (int)vpid[vn], (int)vpid[vn],
    12421445                                               buf[vpos]);
    12431446                                        if (vn+1 < MAXVPID) vn++;
    1244                                 }                               
     1447                                }
    12451448                        }
    1246 
     1449                       
    12471450                        if (ap){
    12481451                                int old=0;
    12491452                                for (j=0; j < an; j++)
     
    12581461                                               (int)apid[an],(int)apid[an],
    12591462                                               buf[apos]);
    12601463                                        if (an+1 < MAXAPID) an++;
    1261                                 }                               
     1464                                }
    12621465                        }
    1263 
     1466                       
    12641467                        if (cp){
    12651468                                int old=0;
    12661469                                for (j=0; j < ac3n; j++)
     
    12701473                                        }
    12711474                                if (!old){
    12721475                                        ac3pid[ac3n]=cp;
    1273                                         printf("ac3pid %d: 0x%04x (%d) \n", 
     1476                                        printf("ac3pid %d: 0x%04x (%d) \n",
    12741477                                               ac3n+1,
    12751478                                               (int)ac3pid[ac3n],
    12761479                                               (int)ac3pid[ac3n]);
    12771480                                        if (ac3n+1< MAXAC3PID) ac3n++;
    1278                                 }                               
     1481                                }
    12791482                        }
    1280                 } 
     1483                }
    12811484               
    12821485        }
    12831486       
     
    12891492        int afound=0;
    12901493        int vfound=0;
    12911494        uint16_t vpid=0, apid=0, ac3pid=0;
    1292                
     1495       
    12931496        if (rx->vpid) vfound = 1;
    12941497        if (rx->apidn) afound = 1;
    12951498        fprintf(stderr,"Trying to find PIDs\n");
     
    13051508                        ring_init(&rx->arbuffer[0], rx->audiobuf);
    13061509                        init_pes_in(&rx->paudio[0], 1, &rx->arbuffer[0], 0);
    13071510                        rx->paudio[0].priv = (void *) rx;
    1308                         ring_init(&rx->index_arbuffer[0], INDEX_BUF);   
     1511                        ring_init(&rx->index_arbuffer[0], INDEX_BUF);
    13091512                        memset(&rx->aframe[0], 0, sizeof(audio_frame_t));
    13101513                        init_index(&rx->current_aindex[0]);
    13111514                        rx->aframe_count[0] = 0;
    13121515                        rx->first_apts[0] = 0;
    13131516                }
    1314 
     1517               
    13151518                if (!rx->ac3n && ac3pid){
    13161519                        rx->ac3_id[0] = ac3pid;
    13171520                        rx->ac3n++;
    13181521                        afound++;
    1319                         ring_init(&rx->ac3rbuffer[0], AC3_BUF);
     1522                        ring_init(&rx->ac3rbuffer[0], rx->ac3buf);
    13201523                        init_pes_in(&rx->pac3[0], 0x80, &rx->ac3rbuffer[0],0);
    13211524                        rx->pac3[0].priv = (void *) rx;
    13221525                        ring_init(&rx->index_ac3rbuffer[0], INDEX_BUF);
     
    13261529                        rx->first_ac3pts[0] = 0;
    13271530                }
    13281531               
    1329         } 
    1330 
     1532        }
     1533       
    13311534        if (afound && vfound){
    13321535                fprintf(stderr,"found ");
    13331536                if (rx->vpid) fprintf(stderr,"vpid %d (0x%04x)  ",
     
    13371540                if (rx->ac3n) fprintf(stderr,"ac3pid %d (0x%04x)  ",
    13381541                                      rx->ac3_id[0], rx->ac3_id[0]);
    13391542                fprintf(stderr,"\n");
    1340         } else {
     1543        }
     1544        else {
    13411545                fprintf(stderr,"Couldn't find pids\n");
    13421546                exit(1);
    13431547        }
    1344 
     1548       
    13451549}
    13461550
    13471551
    13481552void pes_id_out(pes_in_t *p)
    13491553{
    1350 
     1554       
    13511555        struct replex *rx;
    13521556        int len;
    1353 
     1557       
    13541558        len = p->plength-3-p->hlength;
    13551559        rx = (struct replex *) p->priv;
    1356 
     1560       
    13571561        rx->scan_found=0;
    1358         switch(p->cid){
     1562        switch (p->cid){
    13591563        case VIDEO_STREAM_S ... VIDEO_STREAM_E:
    13601564                rx->scan_found=p->cid;
    13611565                break;
     
    13681572                if (rx->vdr){
    13691573                        rx->scan_found = 0x80;
    13701574                        break;
    1371                 } else {
     1575                }
     1576                else {
    13721577                       
    13731578                        uint8_t id = p->buf[9+p->hlength];
    1374                         switch(id){
     1579                        switch (id){
    13751580                        case 0x80 ... 0x8f:
    1376                         { 
    1377                                 int c=0; 
     1581                        {
     1582                                int c=0;
    13781583                                uint16_t fframe;
    13791584                               
    13801585                                fframe=0;
     
    13831588                               
    13841589                                if (fframe < p->plength){
    13851590                                        if ((c=find_audio_s(p->buf,
    1386                                                             9+p->hlength+4+fframe, 
     1591                                                            9+p->hlength+4+fframe,
    13871592                                                            AC3, p->plength+6)) >= 0){
    13881593                                                rx->scan_found = id;
    13891594                                                //fprintf(stderr,"0x%04x  0x%04x \n",
     
    14141619        int re=0;
    14151620        uint16_t vpid[MAXVPID], apid[MAXAPID], ac3pid[MAXAC3PID];
    14161621        int vn=0, an=0,ac3n=0;
    1417                
     1622       
    14181623        memset (vpid , 0 , MAXVPID*sizeof(uint16_t));
    14191624        memset (apid , 0 , MAXAPID*sizeof(uint16_t));
    14201625        memset (ac3pid , 0 , MAXAC3PID*sizeof(uint16_t));
    1421 
     1626       
    14221627        fprintf(stderr,"Trying to find PES IDs\n");
    14231628        rx->scan_found=0;
    14241629        rx->pvideo.priv = rx ;
    1425         while (count < (int) rx->inflength-IN_SIZE){
     1630        while (count < 50000000 && count < rx->inflength-IN_SIZE){
    14261631                if ((re = save_read(rx,buf,IN_SIZE))<0)
    14271632                        perror("reading");
    1428                 else 
     1633                else
    14291634                        count += re;
    14301635               
    14311636                get_pes(&rx->pvideo, buf, re, pes_id_out);
    14321637               
    14331638                if ( rx->scan_found ){
    1434 
     1639                       
    14351640                        switch (rx->scan_found){
    14361641                               
    14371642                        case VIDEO_STREAM_S ... VIDEO_STREAM_E:
     
    14521657                                               (int)vpid[vn], (int)vpid[vn]);
    14531658                                        if (vn+1 < MAXVPID) vn++;
    14541659                                }
    1455                         }                               
     1660                        }
    14561661                        break;
    1457 
    14581662                       
     1663                       
    14591664                        case AUDIO_STREAM_S ... AUDIO_STREAM_E:
    14601665                        {
    14611666                                int old=0;
     
    14651670                                                break;
    14661671                                        }
    14671672                                if (!old){
    1468                                         apid[an]=rx->scan_found;
     1673                                        apid[an] = rx->apid[an] = rx->scan_found;
    14691674                                        printf("MPEG AUDIO %d: 0x%02x (%d)\n",
    14701675                                               an +1,
    14711676                                               (int)apid[an],(int)apid[an]);
    14721677                                        if (an+1 < MAXAPID) an++;
    1473                                 }                               
     1678                                }
    14741679                        }
    14751680                        break;
    1476 
     1681                       
    14771682                        case 0x80 ... 0x8f:
    14781683                        {
    14791684                                int old=0;
     
    14831688                                                break;
    14841689                                        }
    14851690                                if (!old){
    1486                                         ac3pid[ac3n]=rx->scan_found;
     1691                                        ac3pid[ac3n]=rx->ac3_id[ac3n]=rx->scan_found;
    14871692                                        if (rx->vdr){
    14881693                                                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",
    14911697                                                       ac3n+1,
    14921698                                                       (int)ac3pid[ac3n],
    14931699                                                       (int)ac3pid[ac3n]);
    14941700                                        }
    14951701                                        if (ac3n+1< MAXAC3PID) ac3n++;
    1496                                 }                               
     1702                                }
    14971703                                rx->scan_found = 0;
    14981704                        }
    14991705                        break;
     
    15011707                        rx->scan_found = 0;
    15021708                }
    15031709        }
     1710        rx->ac3n = ac3n;
     1711        rx->apidn = an;
    15041712}
    15051713
    15061714
    15071715
    15081716void replex_finish(struct replex *rx)
    15091717{
    1510 
     1718       
    15111719        fprintf(stderr,"\n");
    15121720        if (!replex_all_set(rx)){
    15131721                fprintf(stderr,"Can't find all required streams\n");
     
    15161724                }
    15171725                exit(1);
    15181726        }
    1519 
     1727       
    15201728        if (!rx->demux)
    15211729                finish_mpg((multiplex_t *)rx->priv);
    15221730        exit(0);
     
    17401948}
    17411949
    17421950
    1743 void init_replex(struct replex *rx)
     1951void init_replex(struct replex *rx,int bufsize)
    17441952{
    17451953        int i;
    17461954        uint8_t mbuf[2*TS_SIZE];
    17471955       
     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
    17481962        rx->analyze=0;
    17491963
    17501964        if (save_read(rx, mbuf, 2*TS_SIZE)<0)
     
    17571971                                find_pids_file(rx);
    17581972                        }
    17591973                }
    1760         }
     1974        }       
    17611975
    1762        
    17631976        if (rx->otype==REPLEX_HDTV){
    17641977                rx->videobuf = 4*VIDEO_BUF;
    17651978        } else {
     
    17781991        ring_init(&rx->vrbuffer, rx->videobuf);
    17791992        if (rx->itype == REPLEX_TS || rx->itype == REPLEX_AVI)
    17801993                init_pes_in(&rx->pvideo, 0xE0, &rx->vrbuffer, 0);
    1781         else {
     1994        else if (rx->itype == REPLEX_PS){
    17821995                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       
    17841999        rx->pvideo.priv = (void *) rx;
    17852000        ring_init(&rx->index_vrbuffer, INDEX_BUF);
    17862001        memset(&rx->seq_head, 0, sizeof(sequence_t));
     
    18282043        }       
    18292044       
    18302045        if (rx->itype == REPLEX_TS){
    1831                 if (replex_fill_buffers(rx, mbuf)< 0) {
     2046                if (replex_fill_buffers(rx, mbuf)< 0){
    18322047                        fprintf(stderr,"error filling buffer\n");
    18332048                        exit(1);
    18342049                }
     
    18752090                        exit(1);
    18762091                }
    18772092
    1878                 if (replex_fill_buffers(rx, buf+re)< 0) {
     2093                if (replex_fill_buffers(rx, buf+re)< 0){
    18792094                        fprintf(stderr,"error filling buffer\n");
    18802095                        exit(1);
    18812096                }
    18822097        } else {
    1883                 if (replex_fill_buffers(rx, mbuf)< 0) {
     2098                if (replex_fill_buffers(rx, mbuf)< 0){
    18842099                        fprintf(stderr,"error filling buffer\n");
    18852100                        exit(1);
    18862101                }
     
    19012116                do {
    19022117                        while (ring_avail(&rx->index_arbuffer[i]) <
    19032118                               sizeof(index_unit)){
    1904                                 if (replex_fill_buffers(rx, 0)< 0) {
     2119                                if (replex_fill_buffers(rx, 0)< 0){
    19052120                                        fprintf(stderr,
    19062121                                                "error in fix audio\n");
    19072122                                        exit(1);
    19082123                                }       
    19092124                        }
    1910                         ring_peek(&rx->index_arbuffer[i], (uint8_t *)&aiu, size, 0);
     2125                        ring_peek(&rx->index_arbuffer[i], (uint8_t *)&aiu,
     2126                                  size, 0);
    19112127                        if ( ptscmp(aiu.pts + rx->first_apts[i], rx->first_vpts) < 0){
    19122128                                ring_skip(&rx->index_arbuffer[i], size);
    19132129                                ring_skip(&rx->arbuffer[i], aiu.length);
    19142130                        } else break;
    19152131
    19162132                } while (1);
    1917                 mx->ext[i].pts_off = aiu.pts;
     2133                mx->apts_off[i] = aiu.pts;
     2134                rx->apts_off[i] = aiu.pts;
     2135                mx->aframes[i] = aiu.framesize;
    19182136               
    19192137                fprintf(stderr,"Audio%d  offset: ",i);
    1920                 printpts(mx->ext[i].pts_off);
    1921                 printpts(rx->first_apts[i]+mx->ext[i].pts_off);
     2138                printpts(mx->apts_off[i]);
     2139                printpts(rx->first_apts[i]+mx->apts_off[i]);
    19222140                fprintf(stderr,"\n");
    19232141        }
    19242142                         
     
    19262144                do {
    19272145                        while (ring_avail(&rx->index_ac3rbuffer[i]) <
    19282146                               sizeof(index_unit)){
    1929                                 if (replex_fill_buffers(rx, 0)< 0) {
     2147                                if (replex_fill_buffers(rx, 0)< 0){
    19302148                                        fprintf(stderr,
    19312149                                                "error in fix audio\n");
    19322150                                        exit(1);
    19332151                                }       
    19342152                        }
    1935                         ring_peek(&rx->index_ac3rbuffer[i], (uint8_t *)&aiu,
     2153                        ring_peek(&rx->index_ac3rbuffer[i],(uint8_t *) &aiu,
    19362154                                  size, 0);
    19372155                        if ( ptscmp (aiu.pts+rx->first_ac3pts[i], rx->first_vpts) < 0){
    19382156                                ring_skip(&rx->index_ac3rbuffer[i], size);
    19392157                                ring_skip(&rx->ac3rbuffer[i], aiu.length);
    19402158                        } else break;
    19412159                } while (1);
    1942                 mx->ext[i].pts_off = aiu.pts;
     2160                mx->ac3pts_off[i] = aiu.pts;
     2161                rx->ac3pts_off[i] = aiu.pts;
    19432162               
    19442163                fprintf(stderr,"AC3%d  offset: ",i);
    1945                 printpts(mx->ext[i].pts_off);
    1946                 printpts(rx->first_ac3pts[i]+mx->ext[i].pts_off);
     2164                printpts(mx->ac3pts_off[i]);
     2165                printpts(rx->first_ac3pts[i]+mx->ac3pts_off[i]);
    19472166                fprintf(stderr,"\n");
    19482167
    19492168        }
     
    19732192
    19742193static int get_next_ac3_unit(struct replex *rx, index_unit *aiu, int i)
    19752194{
    1976         if (ring_avail(&rx->index_ac3rbuffer[i])) {
     2195        if (ring_avail(&rx->index_ac3rbuffer[i])){
    19772196                ring_read(&rx->index_ac3rbuffer[i], (uint8_t *)aiu,
    19782197                          sizeof(index_unit));
    19792198               
     
    20052224       
    20062225       
    20072226        while(!rx->finish){
    2008                 if (replex_fill_buffers(rx, 0)< 0) {
     2227                if (replex_fill_buffers(rx, 0)< 0){
    20092228                        fprintf(stderr,"error in get next video unit\n");
    20102229                        return;
    20112230                }
     
    21402359        index_unit dummy;
    21412360        index_unit dummy2;
    21422361        int i;
     2362        multiplex_t mx;
    21432363        fprintf(stderr,"STARTING DEMUX\n");
     2364
     2365
     2366        while (!replex_all_set(rx)){
     2367                if (replex_fill_buffers(rx, 0)< 0){
     2368                        fprintf(stderr,"error filling buffer\n");
     2369                        exit(1);
     2370                }
     2371        }
     2372
     2373        fix_audio(rx, &mx);
    21442374       
    21452375        while(!rx->finish){
    2146                 if (replex_fill_buffers(rx, 0)< 0) {
     2376                if (replex_fill_buffers(rx, 0)< 0){
    21472377                        fprintf(stderr,"error in get next video unit\n");
    21482378                        return;
    21492379                }
    21502380                for (i=0; i< rx->apidn; i++){
    21512381                        while(get_next_audio_unit(rx, &dummy2, i)){
    2152                                 ring_read_file(&rx->arbuffer[i],
    2153                                                rx->dmx_out[i+1],
    2154                                                dummy2.length);
     2382                                switch(dummy2.err){
     2383                                case JUMP_ERR:
     2384                                        ring_skip(&rx->arbuffer[i],dummy2.length);
     2385                                        break;
     2386                                case DUMMY_ERR:
     2387                                        write(rx->dmx_out[i+1],dummy.fillframe,dummy2.length);
     2388                                        break;
     2389                                default:
     2390                                        ring_read_file(&rx->arbuffer[i],
     2391                                                       rx->dmx_out[i+1],
     2392                                                       dummy2.length);
     2393                                }
    21552394                        }
    21562395                }
    21572396               
    21582397                for (i=0; i< rx->ac3n; i++){
    21592398                        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);
     2399                                switch(dummy2.err){
     2400                                case JUMP_ERR:
     2401                                        ring_skip(&rx->ac3rbuffer[i],dummy2.length);
     2402                                        break;
     2403                                case DUMMY_ERR:
     2404                                        write(rx->dmx_out[i+1+rx->apidn],dummy.fillframe,dummy2.length);
     2405                                        break;
     2406                                default:
     2407                                        ring_read_file(&rx->ac3rbuffer[i],
     2408                                                       rx->dmx_out[i+1+rx->apidn],
     2409                                                       dummy2.length);
     2410                                }
    21632411                        }
    21642412                }
    21652413               
     
    21742422void do_replex(struct replex *rx)
    21752423{
    21762424        int video_ok = 0;
    2177         int ext_ok[N_AUDIO];
     2425        int audio_ok[N_AUDIO];
     2426        int ac3_ok[N_AC3];
    21782427        int start=1;
    21792428        multiplex_t mx;
     2429        int done = 0;
    21802430
    21812431
    21822432        fprintf(stderr,"STARTING REPLEX\n");
    21832433        memset(&mx, 0, sizeof(mx));
    2184         memset(ext_ok, 0, N_AUDIO*sizeof(int));
     2434        memset(audio_ok, 0, N_AUDIO*sizeof(int));
     2435        memset(ac3_ok, 0, N_AC3*sizeof(int));
    21852436
    21862437        while (!replex_all_set(rx)){
    2187                 if (replex_fill_buffers(rx, 0)< 0) {
     2438                if (replex_fill_buffers(rx, 0)< 0){
    21882439                        fprintf(stderr,"error filling buffer\n");
    21892440                        exit(1);
    21902441                }
    21912442        }
    21922443
    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;
     2444        mx.priv = (void *) rx;
    22122445        rx->priv = (void *) &mx;
    2213     init_multiplex(&mx, &rx->seq_head, rx->extframe,
    2214                  rx->exttype, rx->exttypcnt, rx->video_delay,
    2215                  rx->audio_delay, rx->fd_out, fill_buffers,
    2216                  &rx->vrbuffer, &rx->index_vrbuffer, 
    2217                  rx->extrbuffer, rx->index_extrbuffer,
    2218                 rx->otype);
     2446        init_multiplex(&mx, &rx->seq_head, rx->aframe, rx->ac3frame,
     2447                       rx->apidn, rx->ac3n, rx->video_delay,
     2448                       rx->audio_delay, rx->fd_out, fill_buffers,
     2449                       &rx->vrbuffer, &rx->index_vrbuffer,     
     2450                       rx->arbuffer, rx->index_arbuffer,
     2451                       rx->ac3rbuffer, rx->index_ac3rbuffer, rx->otype);
    22192452
    22202453        if (!rx->ignore_pts){
    22212454                fix_audio(rx, &mx);
    22222455        }
    22232456        setup_multiplex(&mx);
    22242457
    2225         while(1){
    2226                 check_times( &mx, &video_ok, ext_ok, &start);
     2458        do {
     2459                check_times( &mx, &video_ok, audio_ok, ac3_ok, &start);
    22272460
    2228                 write_out_packs( &mx, video_ok, ext_ok);
    2229         }
     2461                write_out_packs( &mx, video_ok, audio_ok, ac3_ok);
     2462       
     2463                if (mx.max_reached) done = 1;
     2464                if (mx.zero_write_count >100){
     2465                        fprintf(stderr,"Can`t continue, check input file\n");
     2466                        done=1;
     2467                }
     2468        } while (!done);
     2469       
    22302470}
    22312471
    22322472
     
    22342474{
    22352475        printf ("usage: %s [options] <input files>\n\n",progname);
    22362476        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");
     2477        printf ("  --help,             -h            :  print help message\n");
     2478        printf ("\n");
     2479        printf ("  --audio_pid,        -a <integer>  :  audio PID for TS stream (also used for PS id, default 0xc0)\n");
     2480        printf ("  --ac3_id,           -c <integer>  :  ID of AC3 audio for demux (also used for PS id, i.e. 0x80)\n");
     2481        printf ("  --video_delay,      -d <integer>  :  video delay in ms\n");
     2482        printf ("  --audio_delay,      -e <integer>  :  audio delay in ms\n");
     2483        printf ("  --ignore_PTS,       -f            :  ignore all PTS information of original\n");
     2484        printf ("  --larger_buffer     -g <integer>  :  video buffer in MB\n");
     2485        printf ("  --input_stream,     -i <string>   :  set input stream type (string = TS(default), PS, AVI)\n");
     2486        printf ("  --allow_jump,       -j            :  allow jump in the PTS and try repair\n");
     2487        printf ("  --keep_PTS,         -k            :  keep and don't correct PTS information of original\n");
     2488        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");
     2489        printf ("  --of,               -o <filename> :  set output file\n");
     2490        printf ("  --fillzero          -p            :  fill audio frames with zeros (only MPEG AUDIO)\n");
     2491        printf ("  --max_overflow      -q <integer>  :  max_number of overflows allowed (default: 100, 0=no restriction)\n");
     2492        printf ("  --scan,             -s            :  scan for streams\n");
     2493        printf ("  --type,             -t <string>   :  set output type (string = MPEG2, DVD, HDTV)\n");
     2494        printf ("  --video_pid,        -v <integer>  :  video PID for TS stream (also used for PS id, default 0xe0)\n");
     2495        printf ("  --vdr,              -x            :  handle AC3 for vdr input file\n");
     2496        printf ("  --analyze,          -y <integer>  :  analyze (0=video,1=audio, 2=both)\n");
     2497        printf ("  --demux,            -z            :  demux only (-o is basename)\n");
    22532498        exit(1);
    22542499}
    22552500
    22562501int main(int argc, char **argv)
    22572502{
    2258         int c;
     2503        int c;
    22592504        int analyze=0;
    22602505        int scan =0;
    2261         char *filename = NULL;
    2262         char *type = "SVCD";
    2263         char *inpt = "TS";
     2506        char *filename = NULL;
     2507        char *type = "SVCD";
     2508        char *inpt = "TS";
     2509        int bufsize = 6*1024*1024;
     2510        uint64_t min_jump=0;
     2511        int fillzero = 0;
    22642512
    22652513        struct replex rx;
    22662514
     2515        fprintf(stderr,"replex version Myth-Internal");
     2516
    22672517        memset(&rx, 0, sizeof(struct replex));
     2518        rx.max_overflows = 100;
    22682519
    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'},
     2520        while (1){
     2521                int option_index = 0;
     2522                static struct option long_options[] = {
    22752523                        {"audio_pid", required_argument, NULL, 'a'},
     2524                        {"ac3_id", required_argument, NULL, 'c'},
     2525                        {"video_delay", required_argument, NULL, 'd'},
    22762526                        {"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'},
    22802527                        {"ignore_PTS",required_argument, NULL, 'f'},
     2528                        {"larger_buffer",required_argument, NULL, 'g'},
     2529                        {"help", no_argument , NULL, 'h'},
     2530                        {"input_stream", required_argument, NULL, 'i'},
     2531                        {"allow_jump",required_argument, NULL, 'j'},
    22812532                        {"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'},
     2533                        {"min_jump",required_argument, NULL, 'l'},
     2534                        {"of",required_argument, NULL, 'o'},
     2535                        {"fillzero",required_argument, NULL, 'p'},
     2536                        {"max_overflow",required_argument, NULL, 'q'},
    22852537                        {"scan",required_argument, NULL, 's'},
     2538                        {"type", required_argument, NULL, 't'},
     2539                        {"video_pid", required_argument, NULL, 'v'},
    22862540                        {"vdr",required_argument, NULL, 'x'},
    2287                         {"help", no_argument , NULL, 'h'},
     2541                        {"analyze",required_argument, NULL, 'y'},
     2542                        {"demux",no_argument, NULL, 'z'},
    22882543                        {0, 0, 0, 0}
    22892544                };
    2290                 c = getopt_long (argc, argv,
    2291                                         "t:o:a:v:i:hp:q:d:c:n:fkd:e:zy:sx",
     2545                c = getopt_long (argc, argv,
     2546                                 "a:c:d:e:fg:hi:jkl:o:pq:st:v:xy:z",
    22922547                                 long_options, &option_index);
    2293                 if (c == -1)
    2294                 break;
     2548                if (c == -1)
     2549                        break;
    22952550
    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':
     2551                switch (c){
     2552                case 'a':
    23122553                        if (rx.apidn==N_AUDIO){
    23132554                                fprintf(stderr,"Too many audio PIDs\n");
    23142555                                exit(1);
    23152556                        }
    23162557                        rx.apid[rx.apidn] = strtol(optarg,(char **)NULL, 0);
    23172558                        rx.apidn++;
    2318                         break;
    2319                 case 'v':
    2320                         rx.vpid = strtol(optarg,(char **)NULL, 0);
    2321                         break;
    2322                 case 'c':
     2559                        break;
     2560                case 'c':
    23232561                        if (rx.ac3n==N_AC3){
    23242562                                fprintf(stderr,"Too many audio PIDs\n");
    23252563                                exit(1);
    23262564                        }
    2327                         rx.ac3_id[rx.ac3n] = strtol(optarg,(char **)NULL, 0);
     2565                        rx.ac3_id[rx.ac3n] = strtol(optarg,(char **)NULL, 0);
    23282566                        rx.ac3n++;
     2567                        break;
     2568                case 'd':
     2569                        rx.video_delay = strtol(optarg,(char **)NULL, 0)
     2570                                *CLOCK_MS;
    23292571                        break;
    2330                 case 'o':
    2331                         filename = optarg;
     2572                case 'e':
     2573                        rx.audio_delay = strtol(optarg,(char **)NULL, 0)
     2574                                *CLOCK_MS;
    23322575                        break;
    23332576                case 'f':
    23342577                        rx.ignore_pts =1;
    23352578                        break;
     2579                case 'g':
     2580                        bufsize = strtol(optarg,(char **)NULL, 0) *1024*1024;
     2581                        break;
     2582                case 'i':
     2583                        inpt = optarg;
     2584                        break;
     2585                case 'j':
     2586                        rx.allow_jump = MIN_JUMP;
     2587                        break;
    23362588                case 'k':
    23372589                        rx.keep_pts =1;
    23382590                        break;
    2339                 case 'z':
    2340                         rx.demux =1;
     2591                case 'l':
     2592                        min_jump = strtol(optarg,(char **)NULL, 0) *CLOCK_MS;
    23412593                        break;
    2342                 case 'n':
    2343                         rx.fix_sync =1;
     2594                case 'o':
     2595                        filename = optarg;
     2596                        break;
     2597                case 'p':
     2598                        fillzero = 1;
    23442599                        break;
    2345                 case 'y':
    2346                         analyze = strtol(optarg,(char **)NULL, 0);
    2347                         if (analyze>2) usage(argv[0]);
    2348                         analyze++;
     2600                case 'q':
     2601                        rx.max_overflows = strtol(optarg,(char **)NULL, 0);
    23492602                        break;
    23502603                case 's':
    23512604                        scan = 1;
    23522605                        break;
     2606                case 't':
     2607                        type = optarg;
     2608                        break;
     2609                case 'v':
     2610                        rx.vpid = strtol(optarg,(char **)NULL, 0);
     2611                        break;
    23532612                case 'x':
    23542613                        rx.vdr=1;
    23552614                        break;
    2356                 case 'h':
    2357                 case '?':
    2358                 default:
    2359                         usage(argv[0]);
     2615                case 'y':
     2616                        analyze = strtol(optarg,(char **)NULL, 0);
     2617                        if (analyze>2) usage(argv[0]);
     2618                        analyze++;
     2619                        break;
     2620                case 'z':
     2621                        rx.demux = 1;
     2622                        break;
     2623                case 'h':
     2624                case '?':
     2625                default:
     2626                        usage(argv[0]);
     2627                }
     2628        }
     2629
     2630        if (rx.allow_jump && min_jump) rx.allow_jump = min_jump;
     2631
     2632        if (fillzero) rx.fillzero = 1;
     2633        rx.inputFiles = NULL;
     2634        if (optind < argc){
     2635                int i = 0;
     2636                rx.inputFiles = calloc( sizeof(char * ), argc - optind + 1);
     2637                while (optind < argc) {
     2638                        if ((rx.fd_in = open(argv[optind] ,O_RDONLY| O_LARGEFILE)) < 0){
     2639                                fprintf(stderr,"Error opening input file %s",argv[optind] );
     2640                                exit(1);
     2641                        }
     2642                        close(rx.fd_in);
     2643                        rx.inputFiles[i] = argv[optind];
     2644                        i++;
     2645                        optind++;
    23602646                }
    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 ");
     2647                rx.inputFiles[i] = NULL;
     2648                rx.inputIdx = 0;
     2649                if ((rx.fd_in = open(rx.inputFiles[0] ,O_RDONLY| O_LARGEFILE)) < 0) {
     2650                        fprintf(stderr,"Error opening input file %s",argv[optind] );
    23692651                        exit(1);
    23702652                }
    2371                 fprintf(stderr,"Reading from %s\n", argv[optind]);
     2653
     2654                fprintf(stderr,"Reading from %s\n", argv[optind]);
    23722655                rx.inflength = lseek(rx.fd_in, 0, SEEK_END);
    23732656                fprintf(stderr,"Input file length: %.2f MB\n",rx.inflength/1024./1024.);
    23742657                lseek(rx.fd_in,0,SEEK_SET);
    23752658                rx.lastper = 0;
    23762659                rx.finread = 0;
    2377         } else {
     2660        } else {
    23782661                fprintf(stderr,"using stdin as input\n");
    23792662                rx.fd_in = STDIN_FILENO;
    23802663                rx.inflength = 0;
    2381         }
     2664        }
    23822665
    23832666        if (!rx.demux){
    23842667                if (filename){
    23852668                        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){
     2669                                              |O_TRUNC|O_LARGEFILE,
     2670                                              S_IRUSR|S_IWUSR|S_IRGRP|
     2671                                              S_IWGRP|
     2672                                              S_IROTH|S_IWOTH)) < 0){
    23902673                                perror("Error opening output file");
    23912674                                exit(1);
    23922675                        }
     
    24062689                exit(0);
    24072690        }
    24082691
    2409         if (!strncmp(type,"MPEG2",6))
     2692        if (!strncmp(type,"MPEG2",6))
    24102693                rx.otype=REPLEX_MPEG2;
    24112694        else if (!strncmp(type,"DVD",4))
    24122695                rx.otype=REPLEX_DVD;
    24132696        else if (!strncmp(type,"HDTV",4))
    24142697                rx.otype=REPLEX_HDTV;
    2415         else if (!rx.demux)
    2416                 usage(argv[0]);
     2698        else if (!rx.demux && !analyze)
     2699                usage(argv[0]);
    24172700       
    2418         if (!strncmp(inpt,"TS",3)){
     2701        if (!strncmp(inpt,"TS",3)){
    24192702                rx.itype=REPLEX_TS;
    24202703        } else if (!strncmp(inpt,"PS",3)){
    24212704                rx.itype=REPLEX_PS;
     
    24312714                rx.apid[0] = 0xC0;
    24322715                rx.ignore_pts =1;
    24332716        } else {
    2434                 usage(argv[0]);
     2717                usage(argv[0]);
    24352718        }
    24362719
    2437         init_replex(&rx);
     2720        init_replex(&rx, bufsize);
    24382721        rx.analyze= analyze;
    24392722
    2440         if (rx.demux) {
     2723        if (rx.demux){
    24412724                int i;
    24422725                char fname[256];
    24432726                if (!filename){
     
    25042787        } else {
    25052788                do_replex(&rx);
    25062789        }
    2507 
     2790       
    25082791        return 0;
    25092792}
  • replex/mpg_common.h

     
    22 * mpg_common.h
    33 *       
    44 *
    5  * Copyright (C) 2003 Marcus Metzler <mocm@metzlerbros.de>
     5 * Copyright (C) 2003 - 2006
     6 *                    Marcus Metzler <mocm@metzlerbros.de>
    67 *                    Metzler Brothers Systementwicklung GbR
     8 *           (C) 2006 Reel Multimedia
    79 *
    810 * This program is free software; you can redistribute it and/or
    911 * modify it under the terms of the GNU General Public License
     
    4749        uint8_t  frame_off;
    4850        uint8_t  frame_start;
    4951        uint8_t  err;
    50         uint32_t framesize;
    51         uint64_t ptsrate;
     52        int      framesize;
     53        uint8_t  *fillframe;
    5254} index_unit;
    5355
    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 
    6656#define NO_ERR    0
    6757#define FRAME_ERR 1
     58#define PTS_ERR 2
     59#define JUMP_ERR 3
     60#define DUMMY_ERR 4
     61#define DROP_ERR 5
    6862
    69 
    7063void show_buf(uint8_t *buf, int length);
    7164int find_mpg_header(uint8_t head, uint8_t *buf, int length);
    7265int find_any_header(uint8_t *head, uint8_t *buf, int length);
    7366uint64_t trans_pts_dts(uint8_t *pts);
    74 int mring_peek( ringbuffer *rbuf, uint8_t *buf, unsigned int l, uint32_t off);
     67int mring_peek( ringbuffer *rbuf, uint8_t *buf, int l, long off);
    7568int ring_find_mpg_header(ringbuffer *rbuf, uint8_t head, int off, int le);
    7669int ring_find_any_header(ringbuffer *rbuf, uint8_t *head, int off, int le);
    7770
  • replex/replex.h

     
    22 * replex.h
    33 *       
    44 *
    5  * Copyright (C) 2003 Marcus Metzler <mocm@metzlerbros.de>
     5 * Copyright (C) 2003 - 2006
     6 *                    Marcus Metzler <mocm@metzlerbros.de>
    67 *                    Metzler Brothers Systementwicklung GbR
     8 *           (C) 2006 Reel Multimedia
    79 *
    810 * This program is free software; you can redistribute it and/or
    911 * modify it under the terms of the GNU General Public License
     
    3638#include "multiplex.h"
    3739
    3840enum { S_SEARCH, S_FOUND, S_ERROR };
     41#define MIN_JUMP 100*CLOCK_MS;
     42#define MAXFRAME 2000
    3943
    4044struct replex {
    4145#define REPLEX_TS  0
     
    4549        int otype;
    4650        int ignore_pts;
    4751        int keep_pts;
    48         int fix_sync;
     52        uint64_t allow_jump;
    4953        uint64_t inflength;
    5054        uint64_t finread;
    5155        int lastper;
     
    5963        int analyze;
    6064        avi_context ac;
    6165        int vdr;
     66        int fillzero;
     67        int overflows;
     68        int max_overflows;
    6269
    6370        uint64_t video_delay;
    6471        uint64_t audio_delay;
    6572
    66 #define VIDEO_BUF (6*1024*1024)
    67 #define AUDIO_BUF (VIDEO_BUF/10)
    68 #define AC3_BUF   (VIDEO_BUF/10)
    6973#define INDEX_BUF (32000*32)
     74
    7075        int audiobuf;
    7176        int ac3buf;
    7277        int videobuf;
    7378
    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 
    8179  //ac3
    8280        int ac3n;
    8381        uint16_t ac3_id[N_AC3];
     
    9189        uint64_t first_ac3pts[N_AC3];
    9290        int ac3_state[N_AUDIO];
    9391        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];
    9496
     97
    9598// mpeg audio
    9699        int apidn;
    97100        uint16_t apid[N_AUDIO];
     
    105108        uint64_t first_apts[N_AUDIO];
    106109        int audio_state[N_AUDIO];
    107110        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];
    108115
    109116//mpeg video
    110117        uint16_t vpid;
     
    120127        uint64_t first_vpts;
    121128        int video_state;
    122129        uint64_t last_vpts;
     130        uint64_t video_jump;
     131        uint64_t vjump_pts;
    123132
    124133        void *priv;
    125134        int scan_found;
     135        char **inputFiles;
     136        int inputIdx;
    126137};
    127138
    128139void init_index(index_unit *iu);
  • replex/README

     
    66usage: ./replex [options] <input files>
    77 
    88options:
    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
    2410
     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
    2531A typical call would be
    2632replex -t DVD -o mynewps.mpg myoldts.ts
    2733
    2834Replex can guess the PIDs of your audio and video streams, but
    2935especially if you have more than one audio stream you should use the
    3036-v and -a or -c options. The -a and -c options can be used more than
    31 once to create multiple audio tracks.
     37once to create multiple audio tracks. Use the -s option to find out
     38about the PIDs in your file
    3239
    3340The -k option means that replex tries to keep the original PTS spacing,
    3441which can be helpful in case of corrupt streams. Replex will ignore
     
    3946from t]he original and creates the PTS according to the frames that are
    4047found.
    4148
     49The -j option lets replex jump over PTS discontiniuties like the ones
     50you get from cutting an MPEG file. With -l you can set the minimum time
     51a jump has to have to get treated as cut. The default for that is 100ms.
     52If you have video jumps without any audio jumps and they are larger than
     53100ms (usually > 2 frames) you can try increasing the min_jump setting.
     54If you set it too high and you have real jumps, e.g. audio and video
     55jumps from a cut, they may not get fixed correctly.
     56
     57
     58The -g option can be helpful if you get ringbuffer overflows, it increases
     59the video buffer size. Default is 6MB.
     60
    4261For questions and/or suggestions contact me at mocm@metzlerbros.de.
  • replex/avi.c

     
    22 * avi.c: AVI container functions for replex
    33 *       
    44 *
    5  * Copyright (C) 2003 Marcus Metzler <mocm@metzlerbros.de>
     5 * Copyright (C) 2003 - 2006
     6 *                    Marcus Metzler <mocm@metzlerbros.de>
    67 *                    Metzler Brothers Systementwicklung GbR
    78 *
    89 * This program is free software; you can redistribute it and/or
  • 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
    129#include <unistd.h>
    230#include <string.h>
    331#include <stdlib.h>
     
    331
    432#include "multiplex.h"
    5 #include "ts.h"
    633
     34
     35static 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
    753static int buffers_filled(multiplex_t *mx)
    854{
     
    1157
    1258        vavail = ring_avail(mx->index_vrbuffer)/sizeof(index_unit);
    1359       
    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->extcnt;i++){
     61//              aavail += ring_avail(&mx->index_extrbuffer[i])/
     62//                                   sizeof(index_unit);
     63//      }
     64        for (i=0; i<mx->apidn;i++){
     65                aavail += ring_avail(&mx->index_arbuffer[i])/sizeof(index_unit);
     66        }
     67 
     68        for (i=0; i<mx->ac3n;i++){
     69                aavail += ring_avail(&mx->index_ac3rbuffer[i])
     70                        /sizeof(index_unit);
    1771        }
    1872
    1973        if (aavail+vavail) return ((aavail+vavail));
    2074        return 0;
    2175}
    2276
     77static int all_audio_ok(int *aok, int n)
     78{
     79       int ok=0,i;
     80 
     81       if (!n) return 0;
     82       for (i=0;  i < n ;i++){
     83               if (aok[i]) ok++;
     84       }
     85       if (ok == n) return 1;
     86       return 0;
     87}
     88static int rest_audio_ok(int j, int *aok, int n)
     89{
     90       int ok=0,i;
     91 
     92       if (!(n-1)) return 0;
     93       for (i=0;  i < n ;i++){
     94               if (i!=j && aok[i]) ok++;
     95       }
     96       if (ok == n) return 1;
     97       return 0;
     98}
     99
     100/*
    23101static int use_video(uint64_t vpts, extdata_t *ext, int *aok, int n)
    24102{
    25103        int i;
     
    28106                        return 0;
    29107        return 1;
    30108}
     109*/
     110/*
    31111static int which_ext(extdata_t *ext, int *aok, int n)
    32112{
    33113        int i;
     
    47127                }
    48128        return pos;
    49129}
    50 
     130*/
     131/*
    51132static int peek_next_video_unit(multiplex_t *mx, index_unit *viu)
    52133{
    53134        if (!ring_avail(mx->index_vrbuffer) && mx->finish) return 0;
     
    59140                }
    60141
    61142        ring_peek(mx->index_vrbuffer, (uint8_t *)viu, sizeof(index_unit),0);
     143*/
     144static int get_next_video_unit(multiplex_t *mx, index_unit *viu)
     145{
     146       if (!ring_avail(mx->index_vrbuffer) && mx->finish) return 0;
     147 
     148       while (ring_avail(mx->index_vrbuffer) < sizeof(index_unit))
     149               if (mx->fill_buffers(mx->priv, mx->finish)< 0) {
     150                       fprintf(stderr,"error in get next video unit\n");
     151                       return 0;
     152               }
     153 
     154       ring_read(mx->index_vrbuffer, (uint8_t *)viu, sizeof(index_unit));
     155
    62156#ifdef OUT_DEBUG
    63157        fprintf(stderr,"video index start: %d  stop: %d  (%d)  rpos: %d\n",
    64158                viu->start, (viu->start+viu->length),
     
    67161
    68162        return 1;
    69163}
    70        
    71 static int get_next_video_unit(multiplex_t *mx, index_unit *viu)
     164
     165static int peek_next_video_unit(multiplex_t *mx, index_unit *viu)
    72166{
    73         index_unit nviu;
    74167        if (!ring_avail(mx->index_vrbuffer) && mx->finish) return 0;
    75168
    76169        while (ring_avail(mx->index_vrbuffer) < sizeof(index_unit))
    77170                if (mx->fill_buffers(mx->priv, mx->finish)< 0) {
    78                         fprintf(stderr,"error in get next video unit\n");
     171                        fprintf(stderr,"error in peek next video unit\n");
    79172                        return 0;
    80173                }
    81174
    82         ring_read(mx->index_vrbuffer, (uint8_t *)viu, sizeof(index_unit));
     175        ring_peek(mx->index_vrbuffer, (uint8_t *)viu, sizeof(index_unit),0);
    83176#ifdef OUT_DEBUG
    84177        fprintf(stderr,"video index start: %d  stop: %d  (%d)  rpos: %d\n",
    85178                viu->start, (viu->start+viu->length),
    86179                viu->length, ring_rpos(mx->vrbuffer));
    87180#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;
     181
    92182        return 1;
    93183}
    94 
    95 static int peek_next_ext_unit(multiplex_t *mx, index_unit *extiu, int i)
     184       
     185static int get_next_audio_unit(multiplex_t *mx, index_unit *aiu, int i)
    96186{
    97         if (!ring_avail(&mx->index_extrbuffer[i]) && mx->finish) return 0;
     187        if (!ring_avail(&mx->index_arbuffer[i]) && mx->finish) return 0;
    98188
    99         while (ring_avail(&mx->index_extrbuffer[i]) < sizeof(index_unit))
     189        while(ring_avail(&mx->index_arbuffer[i]) < sizeof(index_unit))
    100190                if (mx->fill_buffers(mx->priv, mx->finish)< 0) {
    101                         fprintf(stderr,"error in peek next video unit\n");
     191                        fprintf(stderr,"error in get next audio unit\n");
    102192                        return 0;
    103193                }
     194       
     195        ring_read(&mx->index_arbuffer[i], (uint8_t *)aiu, sizeof(index_unit));
    104196
    105         ring_peek(&mx->index_extrbuffer[i], (uint8_t *)extiu,
    106                   sizeof(index_unit),0);
    107197#ifdef OUT_DEBUG
    108         fprintf(stderr,"ext index start: %d  stop: %d  (%d)  rpos: %d\n",
    109                 extiu->start, (extiu->start+extiu->length),
    110                 extiu->length, ring_rpos(mx->extrbuffer));
     198        fprintf(stderr,"audio index start: %d  stop: %d  (%d)  rpos: %d\n",
     199                aiu->start, (aiu->start+aiu->length),
     200                aiu->length, ring_rpos(&mx->arbuffer[i]));
    111201#endif
    112 
    113202        return 1;
    114203}
    115        
    116 static int get_next_ext_unit(multiplex_t *mx, index_unit *extiu, int i)
     204
     205static int get_next_ac3_unit(multiplex_t *mx, index_unit *aiu, int i)
    117206{
    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                         }
     207        if (!ring_avail(&mx->index_ac3rbuffer[i]) && mx->finish) return 0;
     208        while(ring_avail(&mx->index_ac3rbuffer[i]) < sizeof(index_unit))
     209                if (mx->fill_buffers(mx->priv, mx->finish)< 0) {
     210                        fprintf(stderr,"error in get next ac3 unit\n");
     211                        return 0;
     212                }
    129213       
    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
     214        ring_read(&mx->index_ac3rbuffer[i], (uint8_t *)aiu, sizeof(index_unit));
    149215        return 1;
    150216}
    151217
    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                 else
    160                         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 
    171218static void writeout_video(multiplex_t *mx)
    172219
    173220        uint8_t outbuf[3000];
    174221        int written=0;
    175222        uint8_t ptsdts=0;
    176         unsigned int length;
     223        int length;
    177224        int nlength=0;
    178         int frame_len=0;
    179225        index_unit *viu = &mx->viu;
    180226
    181227#ifdef OUT_DEBUG
    182         fprintf(stderr,"writing VIDEO pack\n");
     228        fprintf(stderr,"writing VIDEO pack");
    183229#endif
    184 
    185         if(viu->frame_start) {
    186                 ptsdts = get_ptsdts(mx, viu);
    187                 frame_len = viu->length;
    188         }
    189 
     230       
    190231        if (viu->frame_start && viu->seq_header && viu->gop &&
    191232            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,
     233                if (!mx->startup && mx->navpack){
     234                        write_nav_pack(mx->pack_size, mx->apidn, mx->ac3n,
    198235                                       mx->SCR, mx->muxr, outbuf);
    199                         write(mx->fd_out, outbuf, mx->pack_size);
     236                        mplx_write(mx, outbuf, mx->pack_size);
    200237                        ptsinc(&mx->SCR, mx->SCRinc);
    201238                } else mx->startup = 0;
    202239#ifdef OUT_DEBUG
     
    207244        if (mx->finish != 2 && dummy_space(&mx->vdbuf) < mx->data_size){
    208245                return;
    209246        }
     247
    210248        length = viu->length;
    211         while (!mx->is_ts && length  < mx->data_size){
     249        if  (length  < mx->data_size )
     250                dummy_add(&mx->vdbuf, uptsdiff(viu->dts+mx->video_delay,0)
     251                          , length);
     252
     253        while (length  < mx->data_size ){
    212254                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);
    219255                if ( peek_next_video_unit(mx, &nviu)){
    220256                        if (!(nviu.seq_header && nviu.gop &&
    221257                              nviu.frame == I_FRAME)){
    222258                                get_next_video_unit(mx, viu);
    223                                 frame_len = viu->length;
    224259                                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                                 }
     260                                if  (length  < mx->data_size )
     261                                        dummy_add(&mx->vdbuf,
     262                                                  uptsdiff(viu->dts+
     263                                                           mx->video_delay,0)
     264                                                  , viu->length);
    232265                        } else break;
    233266                } else break;
    234267        }
    235268
    236269        if (viu->frame_start){
     270                switch (mx->frame_timestamps){
     271                case TIME_ALWAYS:
     272                        if (viu->frame == I_FRAME || viu->frame == P_FRAME)
     273                                ptsdts = PTS_DTS;
     274                        else
     275                                ptsdts = PTS_ONLY;
     276                        break;
     277
     278                case TIME_IFRAME:
     279                        if (viu->frame == I_FRAME)
     280                                ptsdts = PTS_DTS;
     281                        break;
     282                }
    237283                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         }
    246284                if (mx->VBR) {
    247285                        mx->extra_clock = ptsdiff(viu->dts + mx->video_delay,
    248286                                                  mx->SCR + 500*CLOCK_MS);
    249 #ifdef OUT_DEBUG1
     287#ifdef OUT_DEBUG
    250288                        fprintf(stderr,"EXTRACLOCK2: %lli %lli %lli\n", viu->dts, mx->video_delay, mx->SCR);
    251289                        fprintf(stderr,"EXTRACLOCK2: %lli ", mx->extra_clock);
    252290                        printpts(mx->extra_clock);
     
    259297        }
    260298
    261299
    262         nlength = length;
     300       nlength = length;
     301
     302       written = write_video_pes( mx->pack_size, mx->apidn, mx->ac3n,
     303                                  viu->pts+mx->video_delay,
     304                                  viu->dts+mx->video_delay,
     305                                  mx->SCR, mx->muxr, outbuf, &nlength, ptsdts,
     306                                  mx->vrbuffer);
     307 
     308      length -= nlength;
     309      dummy_add(&mx->vdbuf, uptsdiff( viu->dts+mx->video_delay,0)
     310                 , viu->length-length);
     311      viu->length = length;
     312      if (viu->gop){
     313              pts2time( viu->pts + mx->video_delay, outbuf, written);
     314      }
     315 
     316      mplx_write(mx, outbuf, written);
     317     
     318      if (viu->length == 0){
     319              get_next_video_unit(mx, viu);
     320      }
     321 
     322}
     323 
     324#define INSIZE 6000
     325int add_to_inbuf(uint8_t *inbuf,ringbuffer *arbuffer, int inbc, int off, int length)
     326
     327       int add;
     328       
     329       if (inbc + length > INSIZE) {
     330               fprintf(stderr,"buffer too small in write_out_audio %d %d\n",inbc,length);
     331               return 0;
     332       }
     333       add= ring_peek( arbuffer, inbuf+inbc, length, off);
     334       if (add < length) {
     335               fprintf(stderr,"error while peeking audio ring %d (%d)\n", add,length);
     336               return 0;
     337       }
     338       return add;
     339}
     340 
     341 
     342 static void clear_audio(multiplex_t *mx, int type, int n)
     343{
     344       index_unit *aiu;
     345       int g=0;
     346       ringbuffer *arbuffer;
     347 
     348       switch (type){
     349               
     350       case MPEG_AUDIO:
     351#ifdef OUT_DEBUG
     352               fprintf(stderr,"clear AUDIO%d pack\n",n);
     353#endif
     354               arbuffer = &mx->arbuffer[n];
     355               aiu = &mx->aiu[n];
     356               break;
     357 
     358       case AC3:
     359#ifdef OUT_DEBUG
     360               fprintf(stderr,"clear AC3%d pack\n",n);
     361#endif
     362               arbuffer = &mx->ac3rbuffer[n];
     363               aiu = &mx->ac3iu[n];
     364               break;
     365 
     366       default:
     367               return;
     368       }
     369       while (aiu->err == JUMP_ERR){
     370//            fprintf(stderr,"FOUND ONE\n");
     371               ring_skip(arbuffer, aiu->length);               
     372               if (type == MPEG_AUDIO)
     373                       g = get_next_audio_unit(mx, aiu, n);
     374               else
     375                       g = get_next_ac3_unit(mx, aiu, n);             
     376      }
     377
     378}
     379static void my_memcpy(uint8_t *target, int offset, uint8_t *source, int length, int maxlength)
     380{
     381       uint8_t *targ = NULL;
     382 
     383       targ = target + offset;
     384       
     385       if ( offset+length > maxlength){
     386               fprintf(stderr,"WARNING: buffer overflow in my_memcopy \n");
     387//            fprintf(stderr, "source 0x%x  offset %d target 0x%x  length %d maxlength %d\n"
     388//                    , source, offset, target, length, maxlength);
     389       }
     390       memcpy(targ, source, length);
     391}
     392 
     393static void writeout_audio(multiplex_t *mx, int type, int n)
     394
     395       uint8_t outbuf[3000];
     396       uint8_t inbuf[INSIZE];
     397       int inbc=0;
     398       int written=0;
     399       int length=0;
     400       dummy_buffer *dbuf;
     401       ringbuffer *airbuffer;
     402       ringbuffer *arbuffer;
     403       int nlength=0;
     404       uint64_t pts, dpts=0;
     405       uint64_t adelay;
     406       int aframesize;
     407       int newpts=0;
     408       int nframes=1;
     409       int ac3_off=0;
     410       int rest_data = 5;
     411       uint64_t *apts;
     412       index_unit *aiu;
     413       int g=0;
     414       int add, off=0;
     415       int fakelength = 0;
     416       int droplength = 0;
     417 
     418       switch (type){
     419 
     420       case MPEG_AUDIO:
     421#ifdef OUT_DEBUG
     422               fprintf(stderr,"writing AUDIO%d pack\n",n);
     423#endif
     424               airbuffer = &mx->index_arbuffer[n];
     425               arbuffer = &mx->arbuffer[n];
     426               dbuf = &mx->adbuf[n];
     427               adelay = mx->apts_off[n];
     428               aframesize = mx->aframes[n];   
     429               apts = &mx->apts[n];
     430               aiu = &mx->aiu[n];
     431               break;
     432 
     433       case AC3:
     434#ifdef OUT_DEBUG
     435               fprintf(stderr,"writing AC3%d pack\n",n);
     436#endif
     437               airbuffer = &mx->index_ac3rbuffer[n];
     438               arbuffer = &mx->ac3rbuffer[n];
     439               dbuf = &mx->ac3dbuf[n];
     440               adelay = mx->ac3pts_off[n];
     441               aframesize = mx->ac3frames[n]; 
     442               rest_data = 1; // 4 bytes AC3 header
     443               apts = &mx->ac3pts[n];
     444               aiu = &mx->ac3iu[n];
     445               break;
     446 
     447       default:
     448
     449/*
    263450        if (mx->is_ts)
    264451                written = write_video_ts(  viu->pts+mx->video_delay,
    265452                                           viu->dts+mx->video_delay,
     
    336523                break;
    337524
    338525        default:
     526*/
    339527                return;
    340528        }
    341529       
     
    346534        pts = uptsdiff( aiu->pts + mx->audio_delay, adelay );
    347535        *apts = pts;
    348536        length = aiu->length;
    349         if (length < aiu->framesize){
     537
     538        if (length <  aiu->framesize){
    350539                newpts = 1;
    351540                ac3_off = length;
     541                nframes = 0;
     542        }
     543
     544        switch (aiu->err){
     545               
     546        case NO_ERR:
     547                add = add_to_inbuf(inbuf, arbuffer, inbc, off, aiu->length);
     548                off += add;
     549                inbc += add;
     550                break;
     551        case PTS_ERR:
     552                break;
     553        case FRAME_ERR:
     554        case JUMP_ERR:
     555                break;
     556        case DUMMY_ERR:
     557          if (aiu->fillframe){
     558//                fprintf(stderr,"1. memcopy 0x%x\n",aiu->fillframe);
     559                        my_memcpy(inbuf, inbc
     560                               , aiu->fillframe + aframesize - length
     561                                  , length, INSIZE);
     562                        inbc += length;
     563                        fakelength += length;
     564                } else fprintf(stderr,"no fillframe \n");
     565               
     566                break;
    352567        }
     568
    353569        dummy_add(dbuf, pts, aiu->length);
    354570
    355571#ifdef OUT_DEBUG
     
    363579        printpts(pts);
    364580        fprintf(stderr,"\n");
    365581#endif
    366         while (!mx->is_ts && length  < mx->data_size + rest_data){
     582        while (length  < mx->data_size + rest_data){
    367583                if (ring_read(airbuffer, (uint8_t *)aiu, sizeof(index_unit)) > 0){
     584                       
    368585                        dpts = uptsdiff(aiu->pts +mx->audio_delay, adelay );
    369586                       
    370587                        if (newpts){
    371588                                pts = dpts;
    372589                                newpts=0;
    373590                        }
     591                       
     592                       
     593                        switch(aiu->err)
     594                        {
     595                        case NO_ERR:
     596                                length += aiu->length;
     597                                add = add_to_inbuf(inbuf, arbuffer, inbc, off, aiu->length);
     598                                inbc += add;
     599                                off += add;
     600                                nframes++;
     601                                break;
    374602
    375                         length+= aiu->length;
     603                        case PTS_ERR:
     604                                break;
     605                        case FRAME_ERR:
     606                        case JUMP_ERR:
     607                                droplength += aiu->length;
     608                                off += aiu->length;
     609                                break;
     610                        case DUMMY_ERR:
     611                                length += aframesize;
     612                                if (aiu->fillframe){
     613//                                      fprintf(stderr,"2. memcopy 0x%x\n",aiu->fillframe);
     614                                        my_memcpy(inbuf, inbc, aiu->fillframe, aframesize, INSIZE);
     615                                        inbc += aframesize;
     616                                        fakelength += aframesize;
     617                                        nframes++;
     618                                } else fprintf(stderr,"no fillframe \n");
     619                               
     620                                break;
     621                        }
     622
    376623                        if (length < mx->data_size + rest_data)
    377624                                dummy_add(dbuf, dpts, aiu->length);
    378625                       
    379626                        *apts = dpts;
    380                         nframes++;
     627
     628
    381629#ifdef OUT_DEBUG
    382630                        fprintf(stderr,"start: %d  stop: %d (%d)  length %d ",
    383631                                aiu->start, (aiu->start+aiu->length),
     
    391639                } else if (mx->finish){
    392640                        break;
    393641                } else if (mx->fill_buffers(mx->priv, mx->finish)< 0) {
    394                         fprintf(stderr,"error in writeout ext\n");
     642                        fprintf(stderr,"error in writeout audio\n");
    395643                        exit(1);
    396644                }
    397645        }
    398646
    399647        nlength = length;
    400648
     649/*
     650       if (type == MPEG_AUDIO)
     651               written = write_audio_pes( mx->pack_size, mx->apidn, mx->ac3n
     652                                          , n, pts, mx->SCR, mx->muxr,
     653                                          outbuf, &nlength, PTS_ONLY,
     654                                          arbuffer);
     655       else
     656               written = write_ac3_pes( mx->pack_size, mx->apidn, mx->ac3n
     657                                        , n, pts, mx->SCR, mx->muxr,
     658                                        outbuf, &nlength, PTS_ONLY,
     659                                        nframes, ac3_off,
     660                                        arbuffer, aiu->length);
     661*/
     662 
     663       if (type == MPEG_AUDIO)
     664               written = bwrite_audio_pes( mx->pack_size, mx->apidn, mx->ac3n
     665                                          , n, pts, mx->SCR, mx->muxr,
     666                                          outbuf, &nlength, PTS_ONLY,
     667                                          inbuf, inbc);
     668       else
     669               written = bwrite_ac3_pes( mx->pack_size, mx->apidn, mx->ac3n
     670                                        , n, pts, mx->SCR, mx->muxr,
     671                                        outbuf, &nlength, PTS_ONLY,
     672                                        nframes, ac3_off,
     673                                        inbuf, inbc , aiu->length);
     674       
     675       if (aiu->err == DUMMY_ERR){
     676               fakelength -= length-nlength;
     677       }
     678       length -= nlength;
     679       mplx_write(mx, outbuf, written);
     680       if (nlength-fakelength+droplength){
     681               ring_skip(arbuffer, nlength-fakelength+droplength);
     682       }
     683
     684       dummy_add(dbuf, dpts, aiu->length-length);
     685       aiu->length = length;
     686       aiu->start = ring_rpos(arbuffer);
     687 
     688       if (aiu->length == 0){
     689               if (type == MPEG_AUDIO)
     690                       g = get_next_audio_unit(mx, aiu, n);
     691               else
     692                       g = get_next_ac3_unit(mx, aiu, n);
     693       }
     694 
     695 
     696       *apts = uptsdiff(aiu->pts + mx->audio_delay, adelay);
     697
     698/*
    401699        switch (type) {
    402700        case MPEG_AUDIO:
    403701                if(mx->is_ts)
     
    443741                aiu->pts = uptsdiff(aiu->pts + ((nlength*aiu->ptsrate)>>8), 0);
    444742        }
    445743        *apts = uptsdiff(aiu->pts + mx->audio_delay, adelay);
     744*/
    446745#ifdef OUT_DEBUG
    447         if ((int64_t)*apts < 0) fprintf(stderr,"SCHEISS ");
     746        //if ((int64_t)*apts < 0) fprintf(stderr,"SCHEISS ");
     747        if ((int64_t)*apts < 0) fprintf(stderr,"MIST ");
    448748        fprintf(stderr,"APTS");
    449749        printpts(*apts);
    450750        printpts(aiu->pts);
     
    452752        printpts(adelay);
    453753        fprintf(stderr,"\n");
    454754#endif
     755        int lc=0;
     756        while (aiu->err == JUMP_ERR && lc < 100){
     757                lc++;
     758               
     759                ring_skip(arbuffer, aiu->length);               
     760                if (type == MPEG_AUDIO)
     761                        g = get_next_audio_unit(mx, aiu, n);
     762                else
     763                        g = get_next_ac3_unit(mx, aiu, n);             
     764        }
    455765
    456766        if (mx->fill_buffers(mx->priv, mx->finish)< 0) {
    457                 fprintf(stderr,"error in writeout ext\n");
     767                fprintf(stderr,"error in writeout audio\n");
    458768                exit(1);
    459769        }
    460770}
     
    464774        uint8_t outbuf[3000];
    465775        //fprintf(stderr,"writing PADDING pack\n");
    466776
    467         write_padding_pes( mx->pack_size, mx->extcnt, mx->SCR,
     777        write_padding_pes( mx->pack_size, mx->apidn, mx->ac3n, mx->SCR,
    468778                           mx->muxr, outbuf);
    469         write(mx->fd_out, outbuf, mx->pack_size);
     779        mplx_write(mx, outbuf, mx->pack_size);
    470780}
    471781
    472 void check_times( multiplex_t *mx, int *video_ok, int *ext_ok, int *start)
     782void check_times( multiplex_t *mx, int *video_ok, int *audio_ok, int *ac3_ok,
     783                  int *start)
    473784{
    474785        int i;
    475         int set_ok = 0;
    476 
    477         memset(ext_ok, 0, N_AUDIO*sizeof(int));
     786       
     787        memset(audio_ok, 0, N_AUDIO*sizeof(int));
     788        memset(ac3_ok, 0, N_AC3*sizeof(int));
    478789        *video_ok = 0;
    479790       
    480791        if (mx->fill_buffers(mx->priv, mx->finish)< 0) {
     
    489800        } else *start = 0;
    490801       
    491802        if (mx->VBR) {
    492 #ifdef OUT_DEBUG1
     803#ifdef OUT_DEBUG
    493804                fprintf(stderr,"EXTRACLOCK: %lli ", mx->extra_clock);
    494805                printpts(mx->extra_clock);
    495806                fprintf(stderr,"\n");
     
    506817                if (mx->extra_clock > 0.0) {
    507818                        int64_t temp_scr = mx->extra_clock;
    508819                       
    509                         for (i=0; i<mx->extcnt; i++){
     820                        for (i=0; i<mx->apidn; i++){
    510821                                if (ptscmp(mx->SCR + temp_scr + 100*CLOCK_MS,
    511                                            mx->ext[i].iu.pts) > 0) {
     822                                           mx->aiu[i].pts) > 0) {
    512823                                        while (ptscmp(mx->SCR + temp_scr
    513824                                                      + 100*CLOCK_MS,
    514                                                       mx->ext[i].iu.pts) > 0)
     825                                                      mx->aiu[i].pts) > 0)
    515826                                                temp_scr -= mx->SCRinc;
    516827                                        temp_scr += mx->SCRinc;
    517828                                }
    518829                        }
    519830                       
     831                        for (i=0; i<mx->ac3n; i++){
     832                                if (ptscmp(mx->SCR + temp_scr + 100*CLOCK_MS,
     833                                           mx->ac3iu[i].pts) > 0) {
     834                                        while (ptscmp(mx->SCR + temp_scr
     835                                                      + 100*CLOCK_MS,
     836                                                      mx->ac3iu[i].pts) > 0)
     837                                                temp_scr -= mx->SCRinc;
     838                                        temp_scr += mx->SCRinc;
     839                                }
     840                        }
     841                       
    520842                        if (temp_scr > 0.0) {
    521843                                mx->SCR += temp_scr;
    522844                                mx->extra_clock -= temp_scr;
     
    524846                                mx->extra_clock = 0.0;
    525847                }
    526848        }
    527        
     849
     850
    528851        /* clear decoder buffers up to SCR */
    529852        dummy_delete(&mx->vdbuf, mx->SCR);   
    530853       
    531         for (i=0;i <mx->extcnt; i++)
    532                 dummy_delete(&mx->ext[i].dbuf, mx->SCR);
     854        for (i=0;i <mx->apidn; i++){
     855                dummy_delete(&mx->adbuf[i], mx->SCR);
     856                clear_audio(mx, MPEG_AUDIO, i);
     857        }
     858        for (i=0;i <mx->ac3n; i++) {
     859                dummy_delete(&mx->ac3dbuf[i], mx->SCR);
     860                clear_audio(mx, AC3, i);
     861        }
    533862       
     863       
    534864        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)
     865            (ptscmp(mx->viu.dts + mx->video_delay, 1000*CLOCK_MS +mx->oldSCR)<0)
    536866            && ring_avail(mx->index_vrbuffer)){
    537867                *video_ok = 1;
    538                 set_ok = 1;
    539868        }
    540869       
    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;
     870        for (i = 0; i < mx->apidn; i++){
     871                //fprintf(stdout, "0 check_times AC3 ptscmp: %d apidn: %d ac3n: %d \n",
     872                //              ptscmp(mx->ac3pts[i], 200*CLOCK_MS + mx->oldSCR), mx->apidn, mx->ac3n);
     873                if (dummy_space(&mx->adbuf[i]) > mx->asize &&
     874                    mx->aiu[i].length > 0 &&
     875                    ptscmp(mx->apts[i], 200*CLOCK_MS + mx->oldSCR) < 0
     876                    && ring_avail(&mx->index_arbuffer[i])){
     877                        audio_ok[i] = 1;
    548878                }
    549879        }
    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]);
     880        for (i = 0; i < mx->ac3n; i++){
     881                //fprintf(stdout, "1 check_times AC3 ptscmp: %d \n", ptscmp(mx->ac3pts[i], 200*CLOCK_MS + mx->oldSCR));
     882                if (dummy_space(&mx->ac3dbuf[i]) > mx->asize &&
     883                    mx->ac3iu[i].length > 0 &&
     884                    ptscmp(mx->ac3pts[i], 200*CLOCK_MS + mx->oldSCR) < 0
     885                    && ring_avail(&mx->index_ac3rbuffer[i])){
     886                        ac3_ok[i] = 1;
    562887                }
    563                 fprintf(stderr, "\n");
     888                //else
     889                //    fprintf(stdout, "2 check_times AC3 ptscmp: %d \n", ptscmp(mx->ac3pts[i], 200*CLOCK_MS + mx->oldSCR));
    564890        }
    565 #endif
    566891}
    567 void write_out_packs( multiplex_t *mx, int video_ok, int *ext_ok)
     892
     893void write_out_packs( multiplex_t *mx, int video_ok,
     894                      int *audio_ok, int *ac3_ok)
    568895{
    569896        int i;
    570897
    571         if (video_ok && use_video(mx->viu.dts + mx->video_delay,
    572             mx->ext, ext_ok, mx->extcnt)) {
     898        if (video_ok && /* !all_audio_ok(audio_ok, mx->apidn) &&  */
     899            !all_audio_ok(ac3_ok, mx->ac3n)) {
    573900                writeout_video(mx); 
    574901        } else { // second case(s): audio ok, video in time
    575                 i = which_ext(mx->ext, ext_ok, mx->extcnt);
    576902                int done=0;
    577                 if(i>=0) {
    578                         writeout_ext(mx, i);
    579                         done = 1;
     903                for ( i = 0; i < mx->ac3n; i++){
     904                        if ( ac3_ok[i] && !rest_audio_ok(i,ac3_ok, mx->ac3n)
     905                             && !all_audio_ok(audio_ok, mx->apidn)){
     906
     907                                writeout_audio(mx, AC3, i);
     908                                done = 1;
     909                                break;
     910                        }
    580911                }
     912
     913                for ( i = 0; i < mx->apidn && !done; i++){
     914                        if ( audio_ok[i] && !rest_audio_ok(i, audio_ok,
     915                                                           mx->apidn)){
     916                                writeout_audio(mx, MPEG_AUDIO, i);
     917                                done = 1;
     918                                break;
     919                        }
     920                }
     921
     922
    581923                if (!done && !mx->VBR){
    582924                        writeout_padding(mx);
    583925                }
     
    589931{
    590932        int start=0;
    591933        int video_ok = 0;
    592         int ext_ok[N_AUDIO];
     934        int audio_ok[N_AUDIO];
     935        int ac3_ok[N_AC3];
    593936        int n,nn,old,i;
    594937        uint8_t mpeg_end[4] = { 0x00, 0x00, 0x01, 0xB9 };
    595938                                                                               
    596         memset(ext_ok, 0, N_AUDIO*sizeof(int));
     939        memset(audio_ok, 0, N_AUDIO*sizeof(int));
     940        memset(ac3_ok, 0, N_AC3*sizeof(int));
    597941        mx->finish = 1;
    598942                                                                               
    599943        old = 0;nn=0;
    600         while ((n=buffers_filled(mx)) && nn<1000 ){
     944        while ((n=buffers_filled(mx)) && nn<20 ){
    601945                if (n== old) nn++;
    602                 else  nn=0;
     946                else if (nn) nn--;
    603947                old = n;
    604                 check_times( mx, &video_ok, ext_ok, &start);
    605                 write_out_packs( mx, video_ok, ext_ok);
     948                check_times( mx, &video_ok, audio_ok, ac3_ok, &start);
     949                write_out_packs( mx, video_ok, audio_ok, ac3_ok);
    606950        }
    607951
    608952        old = 0;nn=0;
    609953        while ((n=ring_avail(mx->index_vrbuffer)/sizeof(index_unit))
    610                && nn<1000){
     954               && nn<10){
    611955                if (n== old) nn++;
    612                 else nn= 0;
     956                else if (nn) nn--;
    613957                old = n;
    614958                writeout_video(mx); 
    615959        }
     
    617961// flush the rest
    618962        mx->finish = 2;
    619963        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){
     964        for (i = 0; i < mx->apidn; i++){
     965                while ((n=ring_avail(&mx->index_arbuffer[i])/sizeof(index_unit))
     966                       && nn <10){
    623967                        if (n== old) nn++;
    624                         else nn = 0;
     968                        else if (nn) nn--;
    625969                        old = n;
    626                         writeout_ext(mx, i);
     970                        writeout_audio(mx, MPEG_AUDIO, i);
    627971                }
    628972        }
    629973       
     974        old = 0;nn=0;
     975        for (i = 0; i < mx->ac3n; i++){
     976                while ((n=ring_avail(&mx->index_ac3rbuffer[i])
     977                        /sizeof(index_unit))
     978                        && nn<10){
     979                        if (n== old) nn++;
     980                        else if (nn) nn--;
     981                        old = n;
     982                        writeout_audio(mx, AC3, i);
     983                }
     984        }
     985                       
     986                         
    630987        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);
     988                mplx_write(mx, mpeg_end,4);
    636989}
    637990
    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/frame
    644         numpkt = (framesize + PES_H_MIN + 10 + pktdata -1) / pktdata;
    645         return pktsize- ((pktsize * numpkt) - framesize + numpkt - 1) / numpkt;
    646 }
    647991
    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,
     992void init_multiplex( multiplex_t *mx, sequence_t *seq_head, audio_frame_t *aframe,
     993                     audio_frame_t *ac3frame, int apidn, int ac3n,
    671994                     uint64_t video_delay, uint64_t audio_delay, int fd,
    672995                     int (*fill_buffers)(void *p, int f),
    673996                     ringbuffer *vrbuffer, ringbuffer *index_vrbuffer, 
    674                      ringbuffer *extrbuffer, ringbuffer *index_extrbuffer,
     997                     ringbuffer *arbuffer, ringbuffer *index_arbuffer,
     998                     ringbuffer *ac3rbuffer, ringbuffer *index_ac3rbuffer,
    675999                     int otype)
    6761000{
    6771001        int i;
     
    6821006        mx->audio_delay = audio_delay;
    6831007        mx->fd_out = fd;
    6841008        mx->otype = otype;
     1009        mx->total_written = 0;
     1010        mx->zero_write_count = 0;
     1011        mx->max_write = 0;
     1012        mx->max_reached = 0;
    6851013
    6861014        switch(mx->otype){
    6871015
     
    6981026                mx->reset_clocks = 0;
    6991027                mx->write_end_codes = 0;
    7001028                mx->set_broken_link = 0;
    701                 mx->is_ts = 0;
     1029                //              mx->max_write = 1024*1024*1024; // 1GB max VOB length
    7021030                break;
    7031031
    7041032
     
    7151043                mx->reset_clocks = 1;
    7161044                mx->write_end_codes = 1;
    7171045                mx->set_broken_link = 1;
    718                 mx->is_ts = 0;
    7191046                break;
    7201047
    7211048        case REPLEX_HDTV:
     
    7311058                mx->reset_clocks = 1;
    7321059                mx->write_end_codes = 1;
    7331060                mx->set_broken_link = 1;
    734                 mx->is_ts = 0;
    7351061                break;
     1062        }
    7361063
    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;
     1064        mx->apidn = apidn;
     1065        mx->ac3n = ac3n;
    7521066
    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         }
    7691067
    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 
    7871068        mx->vrbuffer = vrbuffer;
    7881069        mx->index_vrbuffer = index_vrbuffer;
    789         mx->extrbuffer = extrbuffer;
    790         mx->index_extrbuffer = index_extrbuffer;
     1070        mx->arbuffer = arbuffer;
     1071        mx->index_arbuffer = index_arbuffer;
     1072        mx->ac3rbuffer = ac3rbuffer;
     1073        mx->index_ac3rbuffer = index_ac3rbuffer;
    7911074
    7921075        dummy_init(&mx->vdbuf, mx->video_buffer_size);
     1076        for (i=0; i<mx->apidn;i++){
     1077                mx->apts_off[i] = 0;
     1078                dummy_init(&mx->adbuf[i],mx->audio_buffer_size);
     1079        }
     1080        for (i=0; i<mx->ac3n;i++){
     1081                mx->ac3pts_off[i] = 0;
     1082                dummy_init(&mx->ac3dbuf[i], mx->audio_buffer_size);
     1083        }
    7931084
    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         }
     1085        mx->data_size = mx->pack_size - PES_H_MIN -10;
    8071086        mx->vsize = mx->data_size;
     1087        mx->asize = mx->data_size+5; // one less DTS
    8081088       
    809         data_rate += seq_head->bit_rate *400;
     1089        data_rate = seq_head->bit_rate *400;
     1090        for ( i = 0; i < mx->apidn; i++)
     1091                data_rate += aframe[i].bit_rate;
     1092        for ( i = 0; i < mx->ac3n; i++)
     1093                data_rate += ac3frame[i].bit_rate;
    8101094
    811         mx->muxr = ((uint64_t)data_rate / 8 * mx->pack_size) / mx->data_size;
     1095       
     1096        mx->muxr = ((uint64_t)data_rate / 8 * mx->pack_size) / mx->data_size;
     1097//        mx->muxr = (data_rate / 8 * mx->pack_size) / mx->data_size;
    8121098                                     // muxrate of payload in Byte/s
    8131099
    8141100        if (mx->mux_rate) {
     
    8251111
    8261112void setup_multiplex(multiplex_t *mx)
    8271113{
     1114        int packlen;
    8281115        int i;
    8291116
    8301117        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);
     1118        for (i=0; i < mx->apidn; i++){
     1119                get_next_audio_unit(mx, &mx->aiu[i], i);
     1120                mx->apts[i] = uptsdiff(mx->aiu[i].pts +mx->audio_delay,
     1121                                       mx->apts_off[i]);
    8411122        }
     1123        for (i=0; i < mx->ac3n; i++){
     1124                get_next_ac3_unit(mx, &mx->ac3iu[i], i);
     1125                mx->ac3pts[i] = uptsdiff(mx->ac3iu[i].pts +mx->audio_delay,
     1126                                         mx->ac3pts_off[i]);
     1127        }
    8421128
     1129        packlen = mx->pack_size;
     1130
    8431131        mx->SCR = 0;
    8441132
    8451133        // write first VOBU header
    846         if (mx->is_ts) {
     1134        if (mx->navpack){
    8471135                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,
     1136                write_nav_pack(mx->pack_size, mx->apidn, mx->ac3n,
    8551137                               mx->SCR, mx->muxr, outbuf);
    856                 write(mx->fd_out, outbuf, mx->pack_size);
     1138                mplx_write(mx, outbuf, mx->pack_size);
    8571139                ptsinc(&mx->SCR, mx->SCRinc);
    8581140                mx->startup = 1;
    8591141        } else mx->startup = 0;
  • replex/TODO

     
    1 - check for dvdauthor audio PTS errors
     1- fix/replace broken frames
    22
    3 - check/fix/replace broken frames
    4 
    53- split DVD output Files
    64
    75- use more than one input File
    86
    97- add cutting option
    108
    11 - better handling of broken streams
    12 
  • replex/avi.h

     
    22 * avi.h
    33 *       
    44 *
    5  * Copyright (C) 2003 Marcus Metzler <mocm@metzlerbros.de>
     5 * Copyright (C) 2003 - 2006
     6 *                    Marcus Metzler <mocm@metzlerbros.de>
    67 *                    Metzler Brothers Systementwicklung GbR
    78 *
    89 * This program is free software; you can redistribute it and/or
  • replex/ts.c

     
    22 * ts.c: MPEG TS functions for replex
    33 *       
    44 *
    5  * Copyright (C) 2003 Marcus Metzler <mocm@metzlerbros.de>
     5 * Copyright (C) 2003 - 2006
     6 *                    Marcus Metzler <mocm@metzlerbros.de>
    67 *                    Metzler Brothers Systementwicklung GbR
    78 *
    89 * This program is free software; you can redistribute it and/or
     
    2425 *
    2526 */
    2627
    27 #include <stdlib.h>
    2828#include <stdint.h>
    2929#include <string.h>
    3030#include <stdio.h>
    3131
    32 #ifdef USING_MINGW
    33 #include <winsock2.h>
    34 #else
    35 #include <netinet/in.h>
    36 #endif
    37 
    3832#include "ts.h"
    39 #include "element.h"
    40 #include "pes.h"
    4133
    4234uint16_t get_pid(uint8_t *pid)
    4335{
     
    4941        return pp;
    5042}
    5143
     44int 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
    5280int find_pids_pos(uint16_t *vpid, uint16_t *apid, uint16_t *ac3pid,uint8_t *buf, int len, int *vpos, int *apos, int *ac3pos)
    5381{
    5482        int c=0;
     
    123151{
    124152        return find_pids_pos(vpid, apid, ac3pid, buf, len, NULL, NULL, NULL);
    125153}
    126 
    127 //taken and adapted from libdtv, (c) Rolf Hakenes
    128 // CRC32 lookup table for polynomial 0x04c11db7
    129 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 *) &lscr;
    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 frame
    237         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 streams
    265                 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 + PS1
    346         }
    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 0x20
    385         static int count = 0;
    386         int pos, i, pmtpos = 13;
    387         //PMT Program number = 1
    388         //PMT PID = 0x20
    389         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         //PAT
    395         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         //PMT
    403         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 }
  • replex/pes.c

     
    22 * pes.c: MPEG PES functions for replex
    33 *       
    44 *
    5  * Copyright (C) 2003 Marcus Metzler <mocm@metzlerbros.de>
     5 * Copyright (C) 2003 - 2006
     6 *                    Marcus Metzler <mocm@metzlerbros.de>
    67 *                    Metzler Brothers Systementwicklung GbR
     8 *           (C) 2006 Reel Multimedia
    79 *
    810 * This program is free software; you can redistribute it and/or
    911 * modify it under the terms of the GNU General Public License
     
    2628
    2729#include <stdlib.h>
    2830#include <stdio.h>
     31#include <netinet/in.h>
    2932#include <string.h>
    3033
    31 #ifdef USING_MINGW
    32 #include <winsock2.h>
    33 #else
    34 #include <netinet/in.h>
    35 #endif
     34#include "pes.h"
    3635
    37 #include "pes.h"
     36//#define PES_DEBUG
     37
    3838void printpts(int64_t pts)
    3939{
    4040        if (pts < 0){
     
    4343        }
    4444        pts = pts/300;
    4545        pts &= (MAX_PTS-1);
    46         fprintf(stderr,"%2d:%02d:%02d.%04d ",
     46        fprintf(stderr,"%2d:%02d:%02d.%03d ",
    4747                (unsigned int)(pts/90000.)/3600,
    4848                ((unsigned int)(pts/90000.)%3600)/60,
    4949                ((unsigned int)(pts/90000.)%3600)%60,
    50                 (((unsigned int)(pts/9.)%36000000)%600000)%10000
     50                (((unsigned int)(pts/90.)%3600000)%60000)%1000
    5151                );
    5252}
    5353
     
    159159void get_pes (pes_in_t *p, uint8_t *buf, int count, void (*func)(pes_in_t *p))
    160160{
    161161
    162         int l;
    163         unsigned short *pl;
    164         int done;
     162        int l=0;
     163        unsigned short *pl=NULL;
     164        int c=0;
    165165
    166166        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];
    178201                                c++;
    179202                                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;
    185207                                c++;
    186208                                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;
    214211                       
    215212
    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++;
    232219                                p->plen[1] = buf[c];
    233220                                c++;
    234                                 pl = (unsigned short *) p->plen;
    235                                 p->plength = ntohs(*pl);
     221                                p->found+=2;
     222                        } else {
     223                                p->plen[0] = buf[c];
    236224                                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;
    238235
    239236
    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;
    251246                                }
    252                                 break;
     247                        }
     248                        break;
    253249
    254                         case 7:
    255                                 if ( !p->done && p->mpeg == 2){
    256                                         p->flag2 = buf[c];
    257                                         c++;
    258                                         p->found++;
    259                                 }       
    260                                 break;
     250                case 7:
     251                        if ( !p->done && p->mpeg == 2){
     252                                p->flag2 = buf[c];
     253                                c++;
     254                                p->found++;
     255                        }       
     256                        break;
    261257
    262                         case 8:
    263                                 if ( !p->done && p->mpeg == 2){
    264                                         p->hlength = buf[c];
    265                                         c++;
    266                                         p->found++;
    267                                 }
    268                                 break;
     258                case 8:
     259                        if ( !p->done && p->mpeg == 2){
     260                                p->hlength = buf[c];
     261                                c++;
     262                                p->found++;
     263                        }
     264                        break;
    269265                       
    270                         default:
     266                default:
    271267
    272                                 break;
    273                         }
     268                        break;
    274269                }
     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        }
    275275
    276                 if (!p->plength) p->plength = MMAX_PLENGTH-6;
     276        if (!p->plength) p->plength = MMAX_PLENGTH-6;
    277277
    278278
    279                 if ( p->done || (p->mpeg == 2 && p->found >= 9) ){
    280                         switch (p->cid){
     279        if ( p->done || (p->mpeg == 2 && p->found >= 9) ){
     280                switch (p->cid){
    281281                       
    282                         case AUDIO_STREAM_S ... AUDIO_STREAM_E:                 
    283                         case VIDEO_STREAM_S ... VIDEO_STREAM_E:
    284                         case PRIVATE_STREAM1:
     282                case AUDIO_STREAM_S ... AUDIO_STREAM_E:                 
     283                case VIDEO_STREAM_S ... VIDEO_STREAM_E:
     284                case PRIVATE_STREAM1:
    285285
     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){
    286297                                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;
    290301                                } 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;
    294305                                }
     306                        }
    295307
    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++;
    306317                                }
     318                                if (c == count) return;
     319                        }
    307320
    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++;
    319330                                }
     331                                if (c == count) return;
     332                        }
    320333
    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++;
    330                                         }
    331                                         if (c == count) return;
    332                                 }
    333334
    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);
    357351                                                }
     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                                                }
    358359                                        }
     360                                }
    359361
    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);
    367367                        }
     368                        break;
     369                }
    368370
    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;
    377378                        }
     379                }
    378380
    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        }
    389387        return;
    390388}
    391389
     
    459457int cwrite_ps(uint8_t *buf, ps_packet *p, uint32_t length)
    460458{
    461459        long count,i;
    462         (void)length;
    463460        uint8_t headr1[4] = {0x00, 0x00, 0x01, PACK_START };
    464461        uint8_t headr2[4] = {0x00, 0x00, 0x01, SYS_START };
    465462        uint8_t buffy = 0xFF;
     
    556553                p.rate_bound[1] = (uint8_t)(0xff & (muxr >> 7));
    557554                p.rate_bound[2] = (uint8_t)(0x01 | ((muxr & 0x7f)<<1));
    558555
    559        
    560556                p.audio_bound = (uint8_t)((audio_bound << 2)|(fixed << 1)|CSPS);
    561557                p.video_bound = (uint8_t)((audio_lock << 7)|
    562558                                     (video_lock << 6)|0x20|video_bound);
     
    586582}
    587583
    588584
    589 static void get_pespts(uint8_t *spts,uint8_t *pts)
     585void get_pespts(uint8_t *spts,uint8_t *pts)
    590586{
    591         //Make sure to set the 1st 4 bits properly
    592         pts[0] = 0x01 |
     587
     588        pts[0] = 0x21 |
    593589                ((spts[0] & 0xC0) >>5);
    594590        pts[1] = ((spts[0] & 0x3F) << 2) |
    595591                ((spts[1] & 0xC0) >> 6);
     
    647643
    648644        dummy[0] = 0x80;
    649645        dummy[1] = 0;
    650         dummy[2] = stuffing;
     646        dummy[2] = 0;
    651647       
    652648        if (ptsdts == PTS_ONLY){
    653                 dummy[2] += 5;
     649                dummy[2] = 5 + stuffing;
    654650                dummy[1] |= PTS_ONLY;
    655                 ppts[0] |= 0x20;
    656651        } else  if (ptsdts == PTS_DTS){
    657                 dummy[2] += 10;
     652                dummy[2] = 10 + stuffing;
    658653                dummy[1] |= PTS_DTS;
    659                 ppts[0] |= 0x30;
    660                 pdts[0] |= 0x10;
    661654        }
    662                
    663655
    664656        memcpy(obuf+c,dummy,3);
    665657        c += 3;
    666658
     659        memset(obuf+c,0xFF,stuffing);
     660        c += stuffing;
     661
    667662        if (ptsdts == PTS_ONLY){
    668663                memcpy(obuf+c,ppts,5);
    669664                c += 5;
     
    673668                memcpy(obuf+c,pdts,5);
    674669                c += 5;
    675670        }
    676 
    677         memset(obuf+c,0xFF,stuffing);
    678         c += stuffing;
    679 
    680671        return c;
    681672}
    682673
    683 void write_padding_pes( int pack_size, int extcnt,
     674void write_padding_pes( int pack_size, int apidn, int ac3n,
    684675                        uint64_t SCR, uint64_t muxr, uint8_t *buf)
    685676{
    686677        int pos = 0;
    687678
    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,
    689680                              0);
    690681
    691682        pos += write_pes_header( PADDING_STREAM, pack_size-pos, 0, 0, buf+pos,
     
    693684
    694685}
    695686
    696 int write_video_pes( int pack_size, int extcnt, uint64_t vpts,
     687int write_video_pes( int pack_size, int apidn, int ac3n, uint64_t vpts,
    697688                     uint64_t vdts, uint64_t SCR, uint64_t muxr,
    698689                     uint8_t *buf, int *vlength,
    699690                     uint8_t ptsdts, ringbuffer *vrbuffer)
     
    704695        int stuff = 0;
    705696        int length = *vlength;
    706697
     698#ifdef PES_DEBUG
     699        fprintf(stderr,"write video PES ");
     700        printpts(vdts);
     701        fprintf(stderr,"\n");
     702#endif
    707703        if (! length) return 0;
    708704        p = PS_HEADER_L1+PES_H_MIN;
    709705
     
    723719                        length = length+p;
    724720        }
    725721
    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,
    727723                              1, 0);
    728724
    729725        pos += write_pes_header( 0xE0, length-pos, vpts, vdts, buf+pos,
     
    746742        return pos;
    747743}
    748744
    749 int write_audio_pes(  int pack_size, int extcnt, int n, uint64_t pts,
     745int write_audio_pes(  int pack_size, int apidn, int ac3n, int n, uint64_t pts,
    750746                      uint64_t SCR, uint32_t muxr, uint8_t *buf, int *alength,
    751747                      uint8_t ptsdts,   ringbuffer *arbuffer)
    752748{
     
    756752        int stuff = 0;
    757753        int length = *alength;
    758754
     755#ifdef PES_DEBUG
     756        fprintf(stderr,"write audio PES ");
     757        printpts(pts);
     758        fprintf(stderr,"\n");
     759#endif
     760
    759761        if (!length) return 0;
    760762        p = PS_HEADER_L1+PES_H_MIN;
    761763
     
    772774                } else
    773775                        length = length+p;
    774776        }
    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,
    776778                              1, 0);
    777779        pos += write_pes_header( 0xC0+n, length-pos, pts, 0, buf+pos, stuff,
    778780                                 ptsdts);
     
    794796        return pos;
    795797}
    796798
    797 int write_ac3_pes(  int pack_size, int extcnt, int n,
     799
     800
     801int write_ac3_pes(  int pack_size, int apidn, int ac3n, int n,
    798802                    uint64_t pts, uint64_t SCR,
    799803                    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)
    801805{
    802806        int add;
    803807        int pos = 0;
     
    805809        int stuff = 0;
    806810        int length = *alength;
    807811
     812#ifdef PES_DEBUG
     813        fprintf(stderr,"write ac3 PES ");
     814        printpts(pts);
     815        fprintf(stderr,"\n");
     816#endif
     817
    808818        if (!length) return 0;
    809         p = PS_HEADER_L1+PES_H_MIN+4;
     819        p = PS_HEADER_L1+PES_H_MIN;
    810820
    811821        if (ptsdts == PTS_ONLY){
    812822                p += 5;
    813823        }
    814824
    815825        if ( length+p >= pack_size){
     826                if (length+p -pack_size == framelength-4) nframes--;
    816827                length = pack_size;
    817828        } else {
    818829                if (pack_size-length-p <= PES_MIN){
     
    821832                } else
    822833                        length = length+p;
    823834        }
    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,
    825836                              1, 0);
    826837
    827838        pos += write_pes_header( PRIVATE_STREAM1, length-pos, pts, 0,
    828839                                 buf+pos, stuff, ptsdts);
    829         buf[pos] = 0x80 + n;
     840        buf[pos] = 0x80 + n +apidn;
    830841        buf[pos+1] = nframes;
    831842        buf[pos+2] = (ac3_off >> 8)& 0xFF;
    832843        buf[pos+3] = (ac3_off)& 0xFF;
     
    850861        return pos;
    851862}
    852863
    853 int write_nav_pack(int pack_size, int extcnt, uint64_t SCR, uint32_t muxr,
     864
     865int 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
     925int 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
     990int write_nav_pack(int pack_size, int apidn, int ac3n, uint64_t SCR, uint32_t muxr,
    854991                   uint8_t *buf)
    855992{
    856993        int pos = 0;
    857994        uint8_t headr[5] = {0x00, 0x00, 0x01, PRIVATE_STREAM2, 0x03 };
    858         (void)pack_size;
    859995
    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);
    861997        memcpy(buf+pos, headr, 5);
    862998        buf[pos+5] = 0xD4;
    863999        pos += 6;
  • replex/CHANGES

     
     10.1.6
     2DVB wants continuous numbering of audio streams, even for MP2 AC3 mix
     3added handling of too few audio PTS in some streams
     4added audio frame dropping, when video cut is larger than audio cut
     5add the -j option to jump over PTS discontinuities and cuts
     6add -l option to set the minimum time in ms a jump has to have
     7add -g option to set video buffer size in GB
     8fixed MPEG2 and AC3 multiplexing
     9add version information
     10add -p option for filling MPEG audio frames with zero
     11add -q options to set limit for overflow errors
     12
     130.1.5
     14various minor fixes
     15added better audio frame recognition
     16fixed AC3 PTS problem for dvdauthor
     17
    1180.1.4
    219fixed problem with audio PTS which ruined dvdauthor
    320
  • replex/multiplex.h

     
    22 * multiplex.h
    33 *       
    44 *
    5  * Copyright (C) 2003 Marcus Metzler <mocm@metzlerbros.de>
     5 * Copyright (C) 2003 - 2006
     6 *                    Marcus Metzler <mocm@metzlerbros.de>
    67 *                    Metzler Brothers Systementwicklung GbR
     8 *           (C) 2006 Reel Multimedia
    79 *
    810 * This program is free software; you can redistribute it and/or
    911 * modify it under the terms of the GNU General Public License
     
    3335#define N_AUDIO 32
    3436#define N_AC3 8
    3537
     38
    3639typedef struct multiplex_s{
    3740        int fd_out;
    3841#define REPLEX_MPEG2  0
    3942#define REPLEX_DVD    1
    4043#define REPLEX_HDTV   2
    41 #define REPLEX_TS_SD  3
    42 #define REPLEX_TS_HD  4
    4344        int otype;
    4445        int startup;
    4546        int finish;
     
    4849        uint64_t video_delay;
    4950        uint64_t audio_delay;
    5051        int pack_size;
    51         unsigned int data_size;
     52        int data_size;
    5253        uint32_t audio_buffer_size;
    5354        uint32_t video_buffer_size;
    5455        uint32_t mux_rate;
     
    5859#define TIME_IFRAME 2
    5960        int frame_timestamps;
    6061        int VBR;
    61         int is_ts;
    6262        int reset_clocks;
    6363        int write_end_codes;
    6464        int set_broken_link;
    65         unsigned int vsize, extsize;
     65        int vsize, asize;
    6666        int64_t extra_clock;
     67        uint64_t first_vpts;
     68        uint64_t first_apts[N_AUDIO];
     69        uint64_t first_ac3pts[N_AC3];
     70       
    6771        uint64_t SCR;
    6872        uint64_t oldSCR;
    6973        uint64_t SCRinc;
    7074        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;
    7187
     88/* needed from replex */
     89        int apidn;
     90        int ac3n;
     91
    7292        dummy_buffer vdbuf;
     93        dummy_buffer adbuf[N_AUDIO];
     94        dummy_buffer ac3dbuf[N_AC3];