From e659c51563afd0d639c228ac02280cb72394563a Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Wed, 17 Aug 2011 18:35:43 +0200 Subject: [PATCH 01/12] avconv: remove two unused macros. --- avconv.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/avconv.c b/avconv.c index b9410e110f..6516da21e1 100644 --- a/avconv.c +++ b/avconv.c @@ -681,8 +681,6 @@ static void write_frame(AVFormatContext *s, AVPacket *pkt, AVCodecContext *avctx } } -#define MAX_AUDIO_PACKET_SIZE (128 * 1024) - static void do_audio_out(AVFormatContext *s, OutputStream *ost, InputStream *ist, @@ -966,9 +964,6 @@ static void pre_process_video_frame(InputStream *ist, AVPicture *picture, void * *bufp = buf; } -/* we begin to correct av delay at this threshold */ -#define AV_DELAY_MAX 0.100 - static void do_subtitle_out(AVFormatContext *s, OutputStream *ost, InputStream *ist, From 6494c001bec82fbd1f6835941c54e479cc081ccc Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Wed, 17 Aug 2011 18:40:40 +0200 Subject: [PATCH 02/12] avconv: cosmetics, move OutputStream. Allows us to get rid of forward InputStream declaration. --- avconv.c | 51 +++++++++++++++++++++++++-------------------------- 1 file changed, 25 insertions(+), 26 deletions(-) diff --git a/avconv.c b/avconv.c index 6516da21e1..24e9521131 100644 --- a/avconv.c +++ b/avconv.c @@ -218,7 +218,31 @@ static AVBitStreamFilterContext *subtitle_bitstream_filters=NULL; #define DEFAULT_PASS_LOGFILENAME_PREFIX "av2pass" -struct InputStream; +typedef struct InputStream { + int file_index; + AVStream *st; + int discard; /* true if stream data should be discarded */ + int decoding_needed; /* true if the packets must be decoded in 'raw_fifo' */ + AVCodec *dec; + + int64_t start; /* time when read started */ + int64_t next_pts; /* synthetic pts for cases where pkt.pts + is not defined */ + int64_t pts; /* current pts */ + PtsCorrectionContext pts_ctx; + double ts_scale; + int is_start; /* is 1 at the start and after a discontinuity */ + int showed_multi_packet_warning; + AVDictionary *opts; +} InputStream; + +typedef struct InputFile { + AVFormatContext *ctx; + int eof_reached; /* true if eof reached */ + int ist_index; /* index of first stream in ist_table */ + int buffer_size; /* current total buffer size */ + int64_t ts_offset; +} InputFile; typedef struct OutputStream { int file_index; /* file index */ @@ -275,31 +299,6 @@ typedef struct OutputStream { int is_past_recording_time; } OutputStream; -typedef struct InputStream { - int file_index; - AVStream *st; - int discard; /* true if stream data should be discarded */ - int decoding_needed; /* true if the packets must be decoded in 'raw_fifo' */ - AVCodec *dec; - - int64_t start; /* time when read started */ - int64_t next_pts; /* synthetic pts for cases where pkt.pts - is not defined */ - int64_t pts; /* current pts */ - PtsCorrectionContext pts_ctx; - double ts_scale; - int is_start; /* is 1 at the start and after a discontinuity */ - int showed_multi_packet_warning; - AVDictionary *opts; -} InputStream; - -typedef struct InputFile { - AVFormatContext *ctx; - int eof_reached; /* true if eof reached */ - int ist_index; /* index of first stream in ist_table */ - int buffer_size; /* current total buffer size */ - int64_t ts_offset; -} InputFile; typedef struct OutputFile { AVFormatContext *ctx; From c5ad2c2cc6262b64dc3866d0de13fbac97e6da40 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Wed, 17 Aug 2011 18:46:36 +0200 Subject: [PATCH 03/12] avconv: make timer_start a local var in transcode(). --- avconv.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/avconv.c b/avconv.c index 24e9521131..12ee3dc9f3 100644 --- a/avconv.c +++ b/avconv.c @@ -204,8 +204,6 @@ static char *forced_key_frames = NULL; static float dts_delta_threshold = 10; -static int64_t timer_start; - static uint8_t *audio_buf; static uint8_t *audio_out; static unsigned int allocated_audio_out_size, allocated_audio_buf_size; @@ -1272,7 +1270,7 @@ static void do_video_stats(AVFormatContext *os, OutputStream *ost, static void print_report(OutputFile *output_files, OutputStream *ost_table, int nb_ostreams, - int is_last_report) + int is_last_report, int64_t timer_start) { char buf[1024]; OutputStream *ost; @@ -1837,6 +1835,7 @@ static int transcode(OutputFile *output_files, 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); @@ -2352,7 +2351,7 @@ static int transcode(OutputFile *output_files, av_free_packet(&pkt); /* dump report by using the output first video and audio streams */ - print_report(output_files, output_streams, nb_output_streams, 0); + print_report(output_files, output_streams, nb_output_streams, 0, timer_start); } /* at the end of stream, we must flush the decoder buffers */ @@ -2372,7 +2371,7 @@ static int transcode(OutputFile *output_files, } /* dump report by using the first video and audio streams */ - print_report(output_files, output_streams, nb_output_streams, 1); + print_report(output_files, output_streams, nb_output_streams, 1, timer_start); /* close each encoder */ for (i = 0; i < nb_output_streams; i++) { From e922bbfa769cc0f84f09d4027559a23b83e8478c Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Wed, 17 Aug 2011 19:11:54 +0200 Subject: [PATCH 04/12] avconv: reset streamid_map between output files. --- avconv.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/avconv.c b/avconv.c index 12ee3dc9f3..4a5830f326 100644 --- a/avconv.c +++ b/avconv.c @@ -457,7 +457,6 @@ static int exit_program(int ret) fclose(vstats_file); av_free(vstats_filename); - av_free(streamid_map); av_free(meta_data_maps); av_freep(&input_streams); @@ -3695,6 +3694,8 @@ static void opt_output_file(const char *filename) metadata_chapters_autocopy = 1; av_freep(&stream_maps); nb_stream_maps = 0; + av_freep(&streamid_map); + nb_streamid_map = 0; av_dict_free(&codec_names); From ddf5ef02638daf115775c1300557ee102e3f9abe Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Wed, 17 Aug 2011 19:26:49 +0200 Subject: [PATCH 05/12] avconv: remove -intra option. It's equivalent to -g 0. --- Changelog | 1 + avconv.c | 4 ---- doc/avconv.texi | 2 -- tests/lavf-regression.sh | 2 +- 4 files changed, 2 insertions(+), 7 deletions(-) diff --git a/Changelog b/Changelog index 293376a2d7..636cdbb5a8 100644 --- a/Changelog +++ b/Changelog @@ -39,6 +39,7 @@ easier to use. The changes are: * Presets in avconv are disabled, because only libx264 used them and presets for libx264 can now be specified using a private option '-preset '. + * -intra option was removed, it's equivalent to -g 0. - XMV demuxer diff --git a/avconv.c b/avconv.c index 4a5830f326..e81e318069 100644 --- a/avconv.c +++ b/avconv.c @@ -143,7 +143,6 @@ static int qp_hist = 0; static char *vfilters = NULL; #endif -static int intra_only = 0; static int audio_sample_rate = 0; #define QSCALE_NONE -99999 static float audio_qscale = QSCALE_NONE; @@ -3166,8 +3165,6 @@ static OutputStream *new_video_stream(AVFormatContext *oc) video_enc->pix_fmt = frame_pix_fmt; st->sample_aspect_ratio = video_enc->sample_aspect_ratio; - if (intra_only) - video_enc->gop_size = 0; if (video_qscale || same_quant) { video_enc->flags |= CODEC_FLAG_QSCALE; video_enc->global_quality = FF_QP2LAMBDA * video_qscale; @@ -4089,7 +4086,6 @@ static const OptionDef options[] = { { "padleft", HAS_ARG | OPT_VIDEO, {(void*)opt_pad}, "Removed, use the pad filter instead", "size" }, { "padright", HAS_ARG | OPT_VIDEO, {(void*)opt_pad}, "Removed, use the pad filter instead", "size" }, { "padcolor", HAS_ARG | OPT_VIDEO, {(void*)opt_pad}, "Removed, use the pad filter instead", "color" }, - { "intra", OPT_BOOL | OPT_EXPERT | OPT_VIDEO, {(void*)&intra_only}, "use only intra frames"}, { "vn", OPT_BOOL | OPT_VIDEO, {(void*)&video_disable}, "disable video" }, { "vdt", OPT_INT | HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)&video_discard}, "discard threshold", "n" }, { "qscale", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_qscale}, "use fixed video quantizer scale (VBR)", "q" }, diff --git a/doc/avconv.texi b/doc/avconv.texi index 93f353a24b..97ba88144d 100644 --- a/doc/avconv.texi +++ b/doc/avconv.texi @@ -354,8 +354,6 @@ pixel formats. Set SwScaler flags. @item -g @var{gop_size} Set the group of pictures size. -@item -intra -Use only intra frames. @item -vdt @var{n} Discard threshold. @item -qscale @var{q} diff --git a/tests/lavf-regression.sh b/tests/lavf-regression.sh index bb7a497979..859ccb946e 100755 --- a/tests/lavf-regression.sh +++ b/tests/lavf-regression.sh @@ -67,7 +67,7 @@ do_lavf mxf "-ar 48000 -bf 2 -timecode_frame_start 264363" fi if [ -n "$do_mxf_d10" ]; then -do_lavf mxf_d10 "-ar 48000 -ac 2 -r 25 -s 720x576 -vf pad=720:608:0:32 -vcodec mpeg2video -intra -flags +ildct+low_delay -dc 10 -flags2 +ivlc+non_linear_q -qscale 1 -ps 1 -qmin 1 -rc_max_vbv_use 1 -rc_min_vbv_use 1 -pix_fmt yuv422p -minrate 30000k -maxrate 30000k -b 30000k -bufsize 1200000 -top 1 -rc_init_occupancy 1200000 -qmax 12 -f mxf_d10" +do_lavf mxf_d10 "-ar 48000 -ac 2 -r 25 -s 720x576 -vf pad=720:608:0:32 -vcodec mpeg2video -g 0 -flags +ildct+low_delay -dc 10 -flags2 +ivlc+non_linear_q -qscale 1 -ps 1 -qmin 1 -rc_max_vbv_use 1 -rc_min_vbv_use 1 -pix_fmt yuv422p -minrate 30000k -maxrate 30000k -b 30000k -bufsize 1200000 -top 1 -rc_init_occupancy 1200000 -qmax 12 -f mxf_d10" fi if [ -n "$do_ts" ] ; then From 630902a1e1336e7ee0cf3dcbcb6eb07af8edf660 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Wed, 6 Jul 2011 08:49:07 +0200 Subject: [PATCH 06/12] avconv: factor out initializing input streams. --- avconv.c | 93 ++++++++++++++++++++++++++++---------------------------- 1 file changed, 47 insertions(+), 46 deletions(-) diff --git a/avconv.c b/avconv.c index e81e318069..fb0871743b 100644 --- a/avconv.c +++ b/avconv.c @@ -1816,6 +1816,48 @@ static void print_sdp(OutputFile *output_files, int n) av_freep(&avc); } +static int init_input_stream(int ist_index, OutputStream *output_streams, int nb_output_streams, + char *error, int error_len) +{ + int i; + InputStream *ist = &input_streams[ist_index]; + if (ist->decoding_needed) { + AVCodec *codec = ist->dec; + if (!codec) + codec = avcodec_find_decoder(ist->st->codec->codec_id); + if (!codec) { + snprintf(error, sizeof(error), "Decoder (codec id %d) not found for input stream #%d.%d", + ist->st->codec->codec_id, ist->file_index, ist->st->index); + return AVERROR(EINVAL); + } + + /* update requested sample format for the decoder based on the + corresponding encoder sample format */ + for (i = 0; i < nb_output_streams; i++) { + OutputStream *ost = &output_streams[i]; + if (ost->source_index == ist_index) { + update_sample_fmt(ist->st->codec, codec, ost->st->codec); + break; + } + } + + if (avcodec_open2(ist->st->codec, codec, &ist->opts) < 0) { + snprintf(error, sizeof(error), "Error while opening decoder for input stream #%d.%d", + ist->file_index, ist->st->index); + return AVERROR(EINVAL); + } + assert_codec_experimental(ist->st->codec, 0); + assert_avoptions(ist->opts); + } + + ist->pts = ist->st->avg_frame_rate.num ? - ist->st->codec->has_b_frames*AV_TIME_BASE / av_q2d(ist->st->avg_frame_rate) : 0; + ist->next_pts = AV_NOPTS_VALUE; + init_pts_correction(&ist->pts_ctx); + ist->is_start = 1; + + return 0; +} + /* * The following code is the main loop of the file converter */ @@ -1824,7 +1866,7 @@ static int transcode(OutputFile *output_files, InputFile *input_files, int nb_input_files) { - int ret = 0, i, j; + int ret = 0, i; AVFormatContext *is, *os; AVCodecContext *codec, *icodec; OutputStream *ost; @@ -2118,51 +2160,10 @@ static int transcode(OutputFile *output_files, } } - /* open each decoder */ - for (i = 0; i < nb_input_streams; i++) { - ist = &input_streams[i]; - if (ist->decoding_needed) { - AVCodec *codec = ist->dec; - if (!codec) - codec = avcodec_find_decoder(ist->st->codec->codec_id); - if (!codec) { - snprintf(error, sizeof(error), "Decoder (codec id %d) not found for input stream #%d.%d", - ist->st->codec->codec_id, ist->file_index, ist->st->index); - ret = AVERROR(EINVAL); - goto dump_format; - } - - /* update requested sample format for the decoder based on the - corresponding encoder sample format */ - for (j = 0; j < nb_output_streams; j++) { - ost = &output_streams[j]; - if (ost->source_index == i) { - update_sample_fmt(ist->st->codec, codec, ost->st->codec); - break; - } - } - - if (avcodec_open2(ist->st->codec, codec, &ist->opts) < 0) { - snprintf(error, sizeof(error), "Error while opening decoder for input stream #%d.%d", - ist->file_index, ist->st->index); - ret = AVERROR(EINVAL); - goto dump_format; - } - assert_codec_experimental(ist->st->codec, 0); - assert_avoptions(ost->opts); - } - } - - /* init pts */ - for (i = 0; i < nb_input_streams; i++) { - AVStream *st; - ist = &input_streams[i]; - st= ist->st; - ist->pts = st->avg_frame_rate.num ? - st->codec->has_b_frames*AV_TIME_BASE / av_q2d(st->avg_frame_rate) : 0; - ist->next_pts = AV_NOPTS_VALUE; - init_pts_correction(&ist->pts_ctx); - ist->is_start = 1; - } + /* init input streams */ + for (i = 0; i < nb_input_streams; i++) + if ((ret = init_input_stream(i, output_streams, nb_output_streams, error, sizeof(error)) < 0)) + goto dump_format; /* open files and write file headers */ for (i = 0; i < nb_output_files; i++) { From 4a4ce2e743948f62672253c63aee95a42dd4c833 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Thu, 18 Aug 2011 08:55:29 +0200 Subject: [PATCH 07/12] avconv: factor flushing encoders out of output_packet(). --- avconv.c | 169 +++++++++++++++++++++++++++++-------------------------- 1 file changed, 88 insertions(+), 81 deletions(-) diff --git a/avconv.c b/avconv.c index fb0871743b..432f5d6197 100644 --- a/avconv.c +++ b/avconv.c @@ -1396,6 +1396,93 @@ static void generate_silence(uint8_t* buf, enum AVSampleFormat sample_fmt, size_ memset(buf, fill_char, size); } +static void flush_encoders(int ist_index, OutputStream *ost_table, int nb_ostreams) +{ + int i, ret; + + for (i = 0; i < nb_ostreams; i++) { + OutputStream *ost = &ost_table[i]; + + if (ost->source_index == ist_index) { + AVCodecContext *enc = ost->st->codec; + AVFormatContext *os = output_files[ost->file_index].ctx; + + if(ost->st->codec->codec_type == AVMEDIA_TYPE_AUDIO && enc->frame_size <=1) + continue; + if(ost->st->codec->codec_type == AVMEDIA_TYPE_VIDEO && (os->oformat->flags & AVFMT_RAWPICTURE)) + continue; + + if (ost->encoding_needed) { + for(;;) { + AVPacket pkt; + int fifo_bytes; + av_init_packet(&pkt); + pkt.stream_index= ost->index; + + switch (ost->st->codec->codec_type) { + case AVMEDIA_TYPE_AUDIO: + fifo_bytes = av_fifo_size(ost->fifo); + ret = 0; + /* encode any samples remaining in fifo */ + if (fifo_bytes > 0) { + int osize = av_get_bytes_per_sample(enc->sample_fmt); + int fs_tmp = enc->frame_size; + + av_fifo_generic_read(ost->fifo, audio_buf, fifo_bytes, NULL); + if (enc->codec->capabilities & CODEC_CAP_SMALL_LAST_FRAME) { + enc->frame_size = fifo_bytes / (osize * enc->channels); + } else { /* pad */ + int frame_bytes = enc->frame_size*osize*enc->channels; + if (allocated_audio_buf_size < frame_bytes) + exit_program(1); + generate_silence(audio_buf+fifo_bytes, enc->sample_fmt, frame_bytes - fifo_bytes); + } + + ret = avcodec_encode_audio(enc, bit_buffer, bit_buffer_size, (short *)audio_buf); + pkt.duration = av_rescale((int64_t)enc->frame_size*ost->st->time_base.den, + ost->st->time_base.num, enc->sample_rate); + enc->frame_size = fs_tmp; + } + if (ret <= 0) { + ret = avcodec_encode_audio(enc, bit_buffer, bit_buffer_size, NULL); + } + if (ret < 0) { + fprintf(stderr, "Audio encoding failed\n"); + exit_program(1); + } + audio_size += ret; + pkt.flags |= AV_PKT_FLAG_KEY; + break; + case AVMEDIA_TYPE_VIDEO: + ret = avcodec_encode_video(enc, bit_buffer, bit_buffer_size, NULL); + if (ret < 0) { + fprintf(stderr, "Video encoding failed\n"); + exit_program(1); + } + video_size += ret; + if(enc->coded_frame && enc->coded_frame->key_frame) + pkt.flags |= AV_PKT_FLAG_KEY; + if (ost->logfile && enc->stats_out) { + fprintf(ost->logfile, "%s", enc->stats_out); + } + break; + default: + ret=-1; + } + + if (ret <= 0) + break; + pkt.data = bit_buffer; + pkt.size = ret; + if (enc->coded_frame && enc->coded_frame->pts != AV_NOPTS_VALUE) + pkt.pts= av_rescale_q(enc->coded_frame->pts, enc->time_base, ost->st->time_base); + write_frame(os, &pkt, ost->st->codec, ost->bitstream_filters); + } + } + } + } +} + /* pkt = NULL means EOF (needed to flush decoder buffers) */ static int output_packet(InputStream *ist, int ist_index, OutputStream *ost_table, int nb_ostreams, @@ -1713,87 +1800,7 @@ static int output_packet(InputStream *ist, int ist_index, discard_packet: if (pkt == NULL) { /* EOF handling */ - - for(i=0;isource_index == ist_index) { - AVCodecContext *enc= ost->st->codec; - os = output_files[ost->file_index].ctx; - - if(ost->st->codec->codec_type == AVMEDIA_TYPE_AUDIO && enc->frame_size <=1) - continue; - if(ost->st->codec->codec_type == AVMEDIA_TYPE_VIDEO && (os->oformat->flags & AVFMT_RAWPICTURE)) - continue; - - if (ost->encoding_needed) { - for(;;) { - AVPacket pkt; - int fifo_bytes; - av_init_packet(&pkt); - pkt.stream_index= ost->index; - - switch(ost->st->codec->codec_type) { - case AVMEDIA_TYPE_AUDIO: - fifo_bytes = av_fifo_size(ost->fifo); - ret = 0; - /* encode any samples remaining in fifo */ - if (fifo_bytes > 0) { - int osize = av_get_bytes_per_sample(enc->sample_fmt); - int fs_tmp = enc->frame_size; - - av_fifo_generic_read(ost->fifo, audio_buf, fifo_bytes, NULL); - if (enc->codec->capabilities & CODEC_CAP_SMALL_LAST_FRAME) { - enc->frame_size = fifo_bytes / (osize * enc->channels); - } else { /* pad */ - int frame_bytes = enc->frame_size*osize*enc->channels; - if (allocated_audio_buf_size < frame_bytes) - exit_program(1); - generate_silence(audio_buf+fifo_bytes, enc->sample_fmt, frame_bytes - fifo_bytes); - } - - ret = avcodec_encode_audio(enc, bit_buffer, bit_buffer_size, (short *)audio_buf); - pkt.duration = av_rescale((int64_t)enc->frame_size*ost->st->time_base.den, - ost->st->time_base.num, enc->sample_rate); - enc->frame_size = fs_tmp; - } - if(ret <= 0) { - ret = avcodec_encode_audio(enc, bit_buffer, bit_buffer_size, NULL); - } - if (ret < 0) { - fprintf(stderr, "Audio encoding failed\n"); - exit_program(1); - } - audio_size += ret; - pkt.flags |= AV_PKT_FLAG_KEY; - break; - case AVMEDIA_TYPE_VIDEO: - ret = avcodec_encode_video(enc, bit_buffer, bit_buffer_size, NULL); - if (ret < 0) { - fprintf(stderr, "Video encoding failed\n"); - exit_program(1); - } - video_size += ret; - if(enc->coded_frame && enc->coded_frame->key_frame) - pkt.flags |= AV_PKT_FLAG_KEY; - if (ost->logfile && enc->stats_out) { - fprintf(ost->logfile, "%s", enc->stats_out); - } - break; - default: - ret=-1; - } - - if(ret<=0) - break; - pkt.data= bit_buffer; - pkt.size= ret; - if(enc->coded_frame && enc->coded_frame->pts != AV_NOPTS_VALUE) - pkt.pts= av_rescale_q(enc->coded_frame->pts, enc->time_base, ost->st->time_base); - write_frame(os, &pkt, ost->st->codec, ost->bitstream_filters); - } - } - } - } + flush_encoders(ist_index, ost_table, nb_ostreams); } return 0; From 6f1c66d526faa9ed707f4b7b0a7a26fba57de8b6 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Tue, 16 Aug 2011 11:19:20 +0200 Subject: [PATCH 08/12] avconv: save two levels of indentation in flush_encoders() By replacing if (foo) with if (!foo) continue; --- avconv.c | 134 +++++++++++++++++++++++++++---------------------------- 1 file changed, 66 insertions(+), 68 deletions(-) diff --git a/avconv.c b/avconv.c index 432f5d6197..639ff87410 100644 --- a/avconv.c +++ b/avconv.c @@ -1401,84 +1401,82 @@ static void flush_encoders(int ist_index, OutputStream *ost_table, int nb_ostrea int i, ret; for (i = 0; i < nb_ostreams; i++) { - OutputStream *ost = &ost_table[i]; + OutputStream *ost = &ost_table[i]; + AVCodecContext *enc = ost->st->codec; + AVFormatContext *os = output_files[ost->file_index].ctx; - if (ost->source_index == ist_index) { - AVCodecContext *enc = ost->st->codec; - AVFormatContext *os = output_files[ost->file_index].ctx; + if (ost->source_index != ist_index || !ost->encoding_needed) + continue; - if(ost->st->codec->codec_type == AVMEDIA_TYPE_AUDIO && enc->frame_size <=1) - continue; - if(ost->st->codec->codec_type == AVMEDIA_TYPE_VIDEO && (os->oformat->flags & AVFMT_RAWPICTURE)) - continue; + if (ost->st->codec->codec_type == AVMEDIA_TYPE_AUDIO && enc->frame_size <=1) + continue; + if (ost->st->codec->codec_type == AVMEDIA_TYPE_VIDEO && (os->oformat->flags & AVFMT_RAWPICTURE)) + continue; - if (ost->encoding_needed) { - for(;;) { - AVPacket pkt; - int fifo_bytes; - av_init_packet(&pkt); - pkt.stream_index= ost->index; + for(;;) { + AVPacket pkt; + int fifo_bytes; + av_init_packet(&pkt); + pkt.stream_index= ost->index; - switch (ost->st->codec->codec_type) { - case AVMEDIA_TYPE_AUDIO: - fifo_bytes = av_fifo_size(ost->fifo); - ret = 0; - /* encode any samples remaining in fifo */ - if (fifo_bytes > 0) { - int osize = av_get_bytes_per_sample(enc->sample_fmt); - int fs_tmp = enc->frame_size; + switch (ost->st->codec->codec_type) { + case AVMEDIA_TYPE_AUDIO: + fifo_bytes = av_fifo_size(ost->fifo); + ret = 0; + /* encode any samples remaining in fifo */ + if (fifo_bytes > 0) { + int osize = av_get_bytes_per_sample(enc->sample_fmt); + int fs_tmp = enc->frame_size; - av_fifo_generic_read(ost->fifo, audio_buf, fifo_bytes, NULL); - if (enc->codec->capabilities & CODEC_CAP_SMALL_LAST_FRAME) { - enc->frame_size = fifo_bytes / (osize * enc->channels); - } else { /* pad */ - int frame_bytes = enc->frame_size*osize*enc->channels; - if (allocated_audio_buf_size < frame_bytes) - exit_program(1); - generate_silence(audio_buf+fifo_bytes, enc->sample_fmt, frame_bytes - fifo_bytes); - } - - ret = avcodec_encode_audio(enc, bit_buffer, bit_buffer_size, (short *)audio_buf); - pkt.duration = av_rescale((int64_t)enc->frame_size*ost->st->time_base.den, - ost->st->time_base.num, enc->sample_rate); - enc->frame_size = fs_tmp; - } - if (ret <= 0) { - ret = avcodec_encode_audio(enc, bit_buffer, bit_buffer_size, NULL); - } - if (ret < 0) { - fprintf(stderr, "Audio encoding failed\n"); + av_fifo_generic_read(ost->fifo, audio_buf, fifo_bytes, NULL); + if (enc->codec->capabilities & CODEC_CAP_SMALL_LAST_FRAME) { + enc->frame_size = fifo_bytes / (osize * enc->channels); + } else { /* pad */ + int frame_bytes = enc->frame_size*osize*enc->channels; + if (allocated_audio_buf_size < frame_bytes) exit_program(1); - } - audio_size += ret; - pkt.flags |= AV_PKT_FLAG_KEY; - break; - case AVMEDIA_TYPE_VIDEO: - ret = avcodec_encode_video(enc, bit_buffer, bit_buffer_size, NULL); - if (ret < 0) { - fprintf(stderr, "Video encoding failed\n"); - exit_program(1); - } - video_size += ret; - if(enc->coded_frame && enc->coded_frame->key_frame) - pkt.flags |= AV_PKT_FLAG_KEY; - if (ost->logfile && enc->stats_out) { - fprintf(ost->logfile, "%s", enc->stats_out); - } - break; - default: - ret=-1; + generate_silence(audio_buf+fifo_bytes, enc->sample_fmt, frame_bytes - fifo_bytes); } - if (ret <= 0) - break; - pkt.data = bit_buffer; - pkt.size = ret; - if (enc->coded_frame && enc->coded_frame->pts != AV_NOPTS_VALUE) - pkt.pts= av_rescale_q(enc->coded_frame->pts, enc->time_base, ost->st->time_base); - write_frame(os, &pkt, ost->st->codec, ost->bitstream_filters); + ret = avcodec_encode_audio(enc, bit_buffer, bit_buffer_size, (short *)audio_buf); + pkt.duration = av_rescale((int64_t)enc->frame_size*ost->st->time_base.den, + ost->st->time_base.num, enc->sample_rate); + enc->frame_size = fs_tmp; } + if (ret <= 0) { + ret = avcodec_encode_audio(enc, bit_buffer, bit_buffer_size, NULL); + } + if (ret < 0) { + fprintf(stderr, "Audio encoding failed\n"); + exit_program(1); + } + audio_size += ret; + pkt.flags |= AV_PKT_FLAG_KEY; + break; + case AVMEDIA_TYPE_VIDEO: + ret = avcodec_encode_video(enc, bit_buffer, bit_buffer_size, NULL); + if (ret < 0) { + fprintf(stderr, "Video encoding failed\n"); + exit_program(1); + } + video_size += ret; + if(enc->coded_frame && enc->coded_frame->key_frame) + pkt.flags |= AV_PKT_FLAG_KEY; + if (ost->logfile && enc->stats_out) { + fprintf(ost->logfile, "%s", enc->stats_out); + } + break; + default: + ret=-1; } + + if (ret <= 0) + break; + pkt.data = bit_buffer; + pkt.size = ret; + if (enc->coded_frame && enc->coded_frame->pts != AV_NOPTS_VALUE) + pkt.pts= av_rescale_q(enc->coded_frame->pts, enc->time_base, ost->st->time_base); + write_frame(os, &pkt, ost->st->codec, ost->bitstream_filters); } } } From d8425ed4af6d8fce62ff363cc590f85e57bac06b Mon Sep 17 00:00:00 2001 From: Alex Converse Date: Tue, 16 Aug 2011 11:03:26 -0700 Subject: [PATCH 09/12] aac: Only output configure if audio was found. Audio found is not triggered on a CCE because a CCE alone has no output. Signed-off-by: Luca Barbato --- libavcodec/aacdec.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/libavcodec/aacdec.c b/libavcodec/aacdec.c index 0cae1550fa..a380e9d664 100644 --- a/libavcodec/aacdec.c +++ b/libavcodec/aacdec.c @@ -2114,7 +2114,7 @@ static int aac_decode_frame_int(AVCodecContext *avctx, void *data, ChannelElement *che = NULL, *che_prev = NULL; enum RawDataBlockType elem_type, elem_type_prev = TYPE_END; int err, elem_id, data_size_tmp; - int samples = 0, multiplier; + int samples = 0, multiplier, audio_found = 0; if (show_bits(gb, 12) == 0xfff) { if (parse_adts_frame_header(ac, gb) < 0) { @@ -2145,10 +2145,12 @@ static int aac_decode_frame_int(AVCodecContext *avctx, void *data, case TYPE_SCE: err = decode_ics(ac, &che->ch[0], gb, 0, 0); + audio_found = 1; break; case TYPE_CPE: err = decode_cpe(ac, gb, che); + audio_found = 1; break; case TYPE_CCE: @@ -2157,6 +2159,7 @@ static int aac_decode_frame_int(AVCodecContext *avctx, void *data, case TYPE_LFE: err = decode_ics(ac, &che->ch[0], gb, 0, 0); + audio_found = 1; break; case TYPE_DSE: @@ -2233,7 +2236,7 @@ static int aac_decode_frame_int(AVCodecContext *avctx, void *data, samples, avctx->channels); } - if (ac->output_configured) + if (ac->output_configured && audio_found) ac->output_configured = OC_LOCKED; return 0; From 06d37fede4d36ea528ef69e4358a5775df016df0 Mon Sep 17 00:00:00 2001 From: Alex Converse Date: Wed, 10 Aug 2011 16:37:32 -0700 Subject: [PATCH 10/12] aac: Set SBR and PS to unsignalled during headerless and ADTS initialization. Signed-off-by: Luca Barbato --- libavcodec/aacdec.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libavcodec/aacdec.c b/libavcodec/aacdec.c index a380e9d664..d554f41e2e 100644 --- a/libavcodec/aacdec.c +++ b/libavcodec/aacdec.c @@ -579,6 +579,8 @@ static av_cold int aac_decode_init(AVCodecContext *avctx) sr = sample_rate_idx(avctx->sample_rate); ac->m4ac.sampling_index = sr; ac->m4ac.channels = avctx->channels; + ac->m4ac.sbr = -1; + ac->m4ac.ps = -1; for (i = 0; i < FF_ARRAY_ELEMS(ff_mpeg4audio_channels); i++) if (ff_mpeg4audio_channels[i] == avctx->channels) From 44920d04ba3ffeefc6943fc31d6d685bfc7240b1 Mon Sep 17 00:00:00 2001 From: Alex Converse Date: Tue, 16 Aug 2011 11:04:03 -0700 Subject: [PATCH 11/12] aac: Only set sample rate and object type from ADTS if output hasn't been configured. Long term it would be nice to support error resilient reconfiguration but right now setting this every frame does more harm than help. Signed-off-by: Luca Barbato --- libavcodec/aacdec.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libavcodec/aacdec.c b/libavcodec/aacdec.c index d554f41e2e..ef5daed5ca 100644 --- a/libavcodec/aacdec.c +++ b/libavcodec/aacdec.c @@ -2092,10 +2092,10 @@ static int parse_adts_frame_header(AACContext *ac, GetBitContext *gb) if (ac->output_configured != OC_LOCKED) { ac->m4ac.sbr = -1; ac->m4ac.ps = -1; + ac->m4ac.sample_rate = hdr_info.sample_rate; + ac->m4ac.sampling_index = hdr_info.sampling_index; + ac->m4ac.object_type = hdr_info.object_type; } - ac->m4ac.sample_rate = hdr_info.sample_rate; - ac->m4ac.sampling_index = hdr_info.sampling_index; - ac->m4ac.object_type = hdr_info.object_type; if (!ac->avctx->sample_rate) ac->avctx->sample_rate = hdr_info.sample_rate; if (hdr_info.num_aac_frames == 1) { From bb337b4fbceb6af7f70ef2f9476733cc2fa5350b Mon Sep 17 00:00:00 2001 From: Alex Converse Date: Thu, 18 Aug 2011 12:09:17 -0700 Subject: [PATCH 12/12] avconv: Fix spelling errors. Signed-off-by: Luca Barbato --- avconv.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/avconv.c b/avconv.c index 639ff87410..fe328a5d22 100644 --- a/avconv.c +++ b/avconv.c @@ -393,7 +393,7 @@ static int configure_video_filters(InputStream *ist, OutputStream *ost) codec->width = ost->output_video_filter->inputs[0]->w; codec->height = ost->output_video_filter->inputs[0]->h; codec->sample_aspect_ratio = ost->st->sample_aspect_ratio = - ost->frame_aspect_ratio ? // overriden by the -aspect cli option + ost->frame_aspect_ratio ? // overridden by the -aspect cli option av_d2q(ost->frame_aspect_ratio*codec->height/codec->width, 255) : ost->output_video_filter->inputs[0]->sample_aspect_ratio; @@ -1074,7 +1074,7 @@ static void do_video_resample(OutputStream *ost, if (resample_changed) { avfilter_graph_free(&ost->graph); if (configure_video_filters(ist, ost)) { - fprintf(stderr, "Error reinitialising filters!\n"); + fprintf(stderr, "Error reinitializing filters!\n"); exit_program(1); } } @@ -1151,7 +1151,7 @@ static void do_video_out(AVFormatContext *s, if (s->oformat->flags & AVFMT_RAWPICTURE) { /* raw pictures are written as AVPicture structure to - avoid any copies. We support temorarily the older + avoid any copies. We support temporarily the older method. */ AVFrame* old_frame = enc->coded_frame; enc->coded_frame = dec->coded_frame; //FIXME/XXX remove this hack @@ -4097,7 +4097,7 @@ static const OptionDef options[] = { { "qscale", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_qscale}, "use fixed video quantizer scale (VBR)", "q" }, { "rc_override", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_video_rc_override_string}, "rate control override for specific intervals", "override" }, { "vcodec", HAS_ARG | OPT_VIDEO, {(void*)opt_video_codec}, "force video codec ('copy' to copy stream)", "codec" }, - { "me_threshold", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_me_threshold}, "motion estimaton threshold", "threshold" }, + { "me_threshold", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_me_threshold}, "motion estimation threshold", "threshold" }, { "same_quant", OPT_BOOL | OPT_VIDEO, {(void*)&same_quant}, "use same quantizer as source (implies VBR)" }, { "pass", HAS_ARG | OPT_VIDEO, {(void*)opt_pass}, "select the pass number (1 or 2)", "n" },