Ticket #2024: ffmpeg_dvbsubs_queue_clear.patch

File ffmpeg_dvbsubs_queue_clear.patch, 3.0 KB (added by Wim Vander Schelden, 12 years ago)

A patch that adds queueing to OutputStream to sidestep this bug.

  • ffmpeg.c

    diff --git a/ffmpeg.c b/ffmpeg.c
    index b1052c0..509b945 100644
    a b static void update_benchmark(const char *fmt, ...)  
    544544    }
    545545}
    546546
     547#define STAMP(pkt) ( ((pkt)->dts == AV_NOPTS_VALUE) ? (pkt)->pts : (pkt)->dts)
     548
     549static void write_frame(AVFormatContext *s, AVPacket *pkt, OutputStream *ost);
     550static void queue_frame(AVFormatContext *s, AVPacket *pkt, OutputStream *ost)
     551{
     552    PacketQueue *last = ost->queue, *new;
     553    new = av_mallocz(sizeof(PacketQueue));
     554    new->s   = s;
     555    new->pkt = av_memdup(pkt, sizeof(AVPacket));
     556    new->ost = ost;
     557
     558    if(STAMP(pkt) == AV_NOPTS_VALUE) {
     559        write_frame(s, pkt, ost);
     560        return;
     561    }
     562
     563    if(!last) {
     564        ost->queue = new;
     565        return;
     566    }
     567
     568    while(last && last->next && STAMP(last->next->pkt) < STAMP(pkt)) {
     569        last = last->next;
     570    }
     571
     572    new->next  = last->next;
     573    last->next = new;
     574}
     575
     576static void flush_queue(OutputStream *ost, int64_t ts)
     577{
     578    PacketQueue *last;
     579   
     580    if(ts == AV_NOPTS_VALUE)
     581        return;
     582   
     583    while(ost->queue && STAMP(ost->queue->pkt) <= ts) {
     584        last = ost->queue;
     585        ost->queue = ost->queue->next;
     586        write_frame(last->s, last->pkt, last->ost);
     587        av_free(last->pkt);
     588        av_free(last);
     589    }
     590}
     591
    547592static void write_frame(AVFormatContext *s, AVPacket *pkt, OutputStream *ost)
    548593{
    549594    AVBitStreamFilterContext *bsfc = ost->bitstream_filters;
    static void write_frame(AVFormatContext *s, AVPacket *pkt, OutputStream *ost)  
    605650        bsfc = bsfc->next;
    606651    }
    607652
     653    flush_queue(ost, STAMP(pkt));
     654
    608655    if (!(s->oformat->flags & AVFMT_NOTIMESTAMPS) &&
    609656        (avctx->codec_type == AVMEDIA_TYPE_AUDIO || avctx->codec_type == AVMEDIA_TYPE_VIDEO) &&
    610657        pkt->dts != AV_NOPTS_VALUE &&
    static void close_output_stream(OutputStream *ost)  
    652699{
    653700    OutputFile *of = output_files[ost->file_index];
    654701
     702    flush_queue(ost, INT64_MAX);
     703
    655704    ost->finished = 1;
    656705    if (of->shortest) {
    657706        int64_t end = av_rescale_q(ost->sync_opts - ost->first_pts, ost->st->codec->time_base, AV_TIME_BASE_Q);
    static void do_subtitle_out(AVFormatContext *s,  
    789838                pkt.pts += 90 * sub->end_display_time;
    790839        }
    791840        subtitle_size += pkt.size;
    792         write_frame(s, &pkt, ost);
     841        if(i == 0)
     842            write_frame(s, &pkt, ost);
     843        else
     844            queue_frame(s, &pkt, ost);
    793845    }
    794846}
    795847
  • ffmpeg.h

    diff --git a/ffmpeg.h b/ffmpeg.h
    index c001d2c..d614c79 100644
    a b enum forced_keyframes_const {  
    312312
    313313extern const char *const forced_keyframes_const_names[];
    314314
     315struct OutputStream;
     316typedef struct PacketQueue {
     317    AVFormatContext *s;
     318    AVPacket *pkt;
     319    struct OutputStream *ost;
     320    struct PacketQueue *next;
     321} PacketQueue;
     322
    315323typedef struct OutputStream {
    316324    int file_index;          /* file index */
    317325    int index;               /* stream index in the output file */
    typedef struct OutputStream {  
    373381    int keep_pix_fmt;
    374382
    375383    AVCodecParserContext *parser;
     384    PacketQueue *queue;
    376385} OutputStream;
    377386
    378387typedef struct OutputFile {