From eaf2d37acc332809efe9313d72d3f14117427ef9 Mon Sep 17 00:00:00 2001 From: Alex Converse Date: Fri, 19 Aug 2011 14:45:02 -0700 Subject: [PATCH 1/4] avconv: Separate initialization from the main transcode loop. --- avconv.c | 62 +++++++++++++++++++++++++++++++++----------------------- 1 file changed, 37 insertions(+), 25 deletions(-) diff --git a/avconv.c b/avconv.c index 4d1c1a4494..fc0a311a80 100644 --- a/avconv.c +++ b/avconv.c @@ -1860,27 +1860,18 @@ static int init_input_stream(int ist_index, OutputStream *output_streams, int nb return 0; } -/* - * The following code is the main loop of the file converter - */ -static int transcode(OutputFile *output_files, - int nb_output_files, - InputFile *input_files, - int nb_input_files) +static int transcode_init(OutputFile *output_files, + int nb_output_files, + InputFile *input_files, + int nb_input_files) { int ret = 0, i; - AVFormatContext *is, *os; + AVFormatContext *os; AVCodecContext *codec, *icodec; OutputStream *ost; InputStream *ist; char error[1024]; int want_sdp = 1; - uint8_t *no_packet; - int no_packet_count=0; - int64_t timer_start; - - if (!(no_packet = av_mallocz(nb_input_files))) - exit_program(1); if (rate_emu) for (i = 0; i < nb_input_streams; i++) @@ -1892,8 +1883,7 @@ static int transcode(OutputFile *output_files, if (!os->nb_streams && !(os->oformat->flags & AVFMT_NOSTREAMS)) { av_dump_format(os, i, os->filename, 1); fprintf(stderr, "Output file #%d does not contain any stream\n", i); - ret = AVERROR(EINVAL); - goto fail; + return AVERROR(EINVAL); } } @@ -1914,8 +1904,7 @@ static int transcode(OutputFile *output_files, uint64_t extra_size = (uint64_t)icodec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE; if (extra_size > INT_MAX) { - ret = AVERROR(EINVAL); - goto fail; + return AVERROR(EINVAL); } /* if stream_copy is selected, no need to decode or encode */ @@ -1934,8 +1923,7 @@ static int transcode(OutputFile *output_files, codec->rc_buffer_size = icodec->rc_buffer_size; codec->extradata= av_mallocz(extra_size); if (!codec->extradata) { - ret = AVERROR(ENOMEM); - goto fail; + return AVERROR(ENOMEM); } memcpy(codec->extradata, icodec->extradata, icodec->extradata_size); codec->extradata_size= icodec->extradata_size; @@ -1992,8 +1980,7 @@ static int transcode(OutputFile *output_files, case AVMEDIA_TYPE_AUDIO: ost->fifo= av_fifo_alloc(1024); if (!ost->fifo) { - ret = AVERROR(ENOMEM); - goto fail; + return AVERROR(ENOMEM); } ost->reformat_pair = MAKE_SFMT_PAIR(AV_SAMPLE_FMT_NONE,AV_SAMPLE_FMT_NONE); if (!codec->sample_rate) { @@ -2128,8 +2115,7 @@ static int transcode(OutputFile *output_files, if (!bit_buffer) { fprintf(stderr, "Cannot allocate %d bytes output buffer\n", bit_buffer_size); - ret = AVERROR(ENOMEM); - goto fail; + return AVERROR(ENOMEM); } /* open each encoder */ @@ -2216,13 +2202,39 @@ static int transcode(OutputFile *output_files, if (ret) { fprintf(stderr, "%s\n", error); - goto fail; + return ret; } if (want_sdp) { print_sdp(output_files, nb_output_files); } + return 0; +} + +/* + * The following code is the main loop of the file converter + */ +static int transcode(OutputFile *output_files, + int nb_output_files, + InputFile *input_files, + int nb_input_files) +{ + int ret, i; + AVFormatContext *is, *os; + OutputStream *ost; + InputStream *ist; + uint8_t *no_packet; + int no_packet_count=0; + int64_t timer_start; + + if (!(no_packet = av_mallocz(nb_input_files))) + exit_program(1); + + ret = transcode_init(output_files, nb_output_files, input_files, nb_input_files); + if (ret < 0) + goto fail; + if (verbose >= 0) fprintf(stderr, "Press ctrl-c to stop encoding\n"); term_init(); From 4ba8c521b1119c8235f8ad83c4edecb0bf9feb10 Mon Sep 17 00:00:00 2001 From: Kostya Shishkov Date: Sat, 20 Aug 2011 18:14:44 +0200 Subject: [PATCH 2/4] WavPack decoder: implement flush function Signed-off-by: Luca Barbato --- libavcodec/wavpack.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/libavcodec/wavpack.c b/libavcodec/wavpack.c index bd1e435d86..62f68804b3 100644 --- a/libavcodec/wavpack.c +++ b/libavcodec/wavpack.c @@ -1189,6 +1189,15 @@ static int wavpack_decode_frame(AVCodecContext *avctx, return s->samples_left > 0 ? 0 : avpkt->size; } +static void wavpack_decode_flush(AVCodecContext *avctx) +{ + WavpackContext *s = avctx->priv_data; + int i; + + for (i = 0; i < s->fdec_num; i++) + s->fdec[i]->samples_left = 0; +} + AVCodec ff_wavpack_decoder = { .name = "wavpack", .type = AVMEDIA_TYPE_AUDIO, @@ -1197,6 +1206,7 @@ AVCodec ff_wavpack_decoder = { .init = wavpack_decode_init, .close = wavpack_decode_end, .decode = wavpack_decode_frame, + .flush = wavpack_decode_flush, .capabilities = CODEC_CAP_SUBFRAMES, .long_name = NULL_IF_CONFIG_SMALL("WavPack"), }; From 5561fe487f0a2d522fd5655c129acf99b0d59490 Mon Sep 17 00:00:00 2001 From: Kostya Shishkov Date: Sat, 20 Aug 2011 18:14:58 +0200 Subject: [PATCH 3/4] WavPack demuxer: store position of the first block in index. Currently for multichannel audio position for the last block position is stored in index (and used for seeking), which is obviously not correct. Signed-off-by: Luca Barbato --- libavformat/wv.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libavformat/wv.c b/libavformat/wv.c index 7cace17f0b..5c9c31c72a 100644 --- a/libavformat/wv.c +++ b/libavformat/wv.c @@ -250,6 +250,7 @@ static int wv_read_packet(AVFormatContext *s, WVContext *wc = s->priv_data; int ret; int size, ver, off; + int64_t pos; if (s->pb->eof_reached) return AVERROR(EIO); @@ -258,6 +259,7 @@ static int wv_read_packet(AVFormatContext *s, return -1; } + pos = wc->pos; off = wc->multichannel ? 4 : 0; if(av_new_packet(pkt, wc->blksize + WV_EXTRA_SIZE + off) < 0) return AVERROR(ENOMEM); @@ -314,7 +316,7 @@ static int wv_read_packet(AVFormatContext *s, pkt->stream_index = 0; wc->block_parsed = 1; pkt->pts = wc->soff; - av_add_index_entry(s->streams[0], wc->pos, pkt->pts, 0, 0, AVINDEX_KEYFRAME); + av_add_index_entry(s->streams[0], pos, pkt->pts, 0, 0, AVINDEX_KEYFRAME); return 0; } From ccb919e34b1276db5cfcd903e405e47ccb932d58 Mon Sep 17 00:00:00 2001 From: Kostya Shishkov Date: Sat, 20 Aug 2011 13:11:14 +0200 Subject: [PATCH 4/4] WavPack demuxer: do not rely on index when timestamp is not in indexed range. This fixes the situation when there are not enough entries in the index (e.g. on initial seek there's only one index entry in the index) and index search returns just the last known entry. That causes seeking function just to seek there instead of trying harder to get at the requested position. Signed-off-by: Luca Barbato --- libavformat/wv.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libavformat/wv.c b/libavformat/wv.c index 5c9c31c72a..d057262029 100644 --- a/libavformat/wv.c +++ b/libavformat/wv.c @@ -330,7 +330,8 @@ static int wv_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int64_t pos, pts; /* if found, seek there */ - if (index >= 0){ + if (index >= 0 && + timestamp <= st->index_entries[st->nb_index_entries - 1].timestamp) { wc->block_parsed = 1; avio_seek(s->pb, st->index_entries[index].pos, SEEK_SET); return 0;