On Mon, Mar 28, 2011 at 2:19 PM, Justin Ruggles <[email protected]> wrote: > On 03/28/2011 04:54 PM, Alex Converse wrote: > >> --- >> doc/ffmpeg.texi | 2 ++ >> ffmpeg.c | 47 +++++++++++++++++++++++++++++++++++++++++++++-- >> 2 files changed, 47 insertions(+), 2 deletions(-) >> >> >> >> 0001-Add-an-apad-option-to-ffmpeg-to-pad-audio-to-video-l.patch >> >> >> diff --git a/doc/ffmpeg.texi b/doc/ffmpeg.texi >> index 21c6f2c..2927017 100644 >> --- a/doc/ffmpeg.texi >> +++ b/doc/ffmpeg.texi >> @@ -579,6 +579,8 @@ ffmpeg -i file.mpg -vcodec copy -acodec ac3 -ab 384k >> test.mpg -acodec mp2 -ab 19 >> @end example >> @item -alang @var{code} >> Set the ISO 639 language code (3 letters) of the current audio stream. >> +@item -apad >> +Pad audio to video length. >> @end table >> >> @section Advanced Audio options: >> diff --git a/ffmpeg.c b/ffmpeg.c >> index 5e50db3..84a278e 100644 >> --- a/ffmpeg.c >> +++ b/ffmpeg.c >> @@ -176,6 +176,7 @@ static int64_t channel_layout = 0; >> #define QSCALE_NONE -99999 >> static float audio_qscale = QSCALE_NONE; >> static int audio_disable = 0; >> +static int audio_pad = 0; >> static int audio_channels = 1; >> static char *audio_codec_name = NULL; >> static unsigned int audio_codec_tag = 0; >> @@ -297,6 +298,7 @@ typedef struct AVOutputStream { >> int reformat_pair; >> AVAudioConvert *reformat_ctx; >> AVFifoBuffer *fifo; /* for compression: one audio fifo per codec */ >> + >> FILE *logfile; >> } AVOutputStream; >> >> @@ -702,7 +704,8 @@ static void write_frame(AVFormatContext *s, AVPacket >> *pkt, AVCodecContext *avctx >> static void do_audio_out(AVFormatContext *s, >> AVOutputStream *ost, >> AVInputStream *ist, >> - unsigned char *buf, int size) >> + unsigned char *buf, int size, >> + int skip_resample_reformat) >> { >> uint8_t *buftmp; >> int64_t audio_out_size, audio_buf_size; >> @@ -739,6 +742,7 @@ need_realloc: >> ffmpeg_exit(1); >> } >> >> + if (!skip_resample_reformat) { >> if (enc->channels != dec->channels) >> ost->audio_resample = 1; >> >> @@ -871,6 +875,10 @@ need_realloc: >> buftmp = audio_buf; >> size_out = len*osize; >> } >> + } else { >> + buftmp = buf; >> + size_out = size; >> + } >> >> /* now encode as many frames as possible */ >> if (enc->frame_size > 1) { >> @@ -1603,7 +1611,7 @@ static int output_packet(AVInputStream *ist, int >> ist_index, >> av_assert0(ist->decoding_needed); >> switch(ost->st->codec->codec_type) { >> case AVMEDIA_TYPE_AUDIO: >> - do_audio_out(os, ost, ist, decoded_data_buf, >> decoded_data_size); >> + do_audio_out(os, ost, ist, decoded_data_buf, >> decoded_data_size, 0); >> break; >> case AVMEDIA_TYPE_VIDEO: >> #if CONFIG_AVFILTER >> @@ -1697,8 +1705,18 @@ static int output_packet(AVInputStream *ist, int >> ist_index, >> discard_packet: >> if (pkt == NULL) { >> /* EOF handling */ >> + double vpts = 0.0; >> + >> + for(i=0;i<nb_ostreams;i++) { >> + ost = ost_table[i]; >> + if(ost->st->codec->codec_type == AVMEDIA_TYPE_VIDEO) { >> + double opts = ost->st->pts.val * av_q2d(ost->st->time_base); >> + vpts = FFMAX(opts, vpts); >> + } >> + } >> >> for(i=0;i<nb_ostreams;i++) { >> + int ost_pad_audio = audio_pad; >> ost = ost_table[i]; >> if (ost->source_index == ist_index) { >> AVCodecContext *enc= ost->st->codec; >> @@ -1713,13 +1731,37 @@ static int output_packet(AVInputStream *ist, int >> ist_index, >> for(;;) { >> AVPacket pkt; >> int fifo_bytes; >> + double opts; >> av_init_packet(&pkt); >> pkt.stream_index= ost->index; >> >> switch(ost->st->codec->codec_type) { >> case AVMEDIA_TYPE_AUDIO: >> + opts = ost->st->pts.val * >> av_q2d(ost->st->time_base); >> fifo_bytes = av_fifo_size(ost->fifo); >> ret = 0; >> + >> + if (ost_pad_audio && opts < vpts) { >> + int osize = >> av_get_bits_per_sample_fmt(enc->sample_fmt) >> 3; >> + int frame_bytes = >> enc->frame_size*osize*enc->channels; >> + ost_pad_audio = 0; >> + if (samples_size < frame_bytes) >> + ffmpeg_exit(1); >> + memset(samples, 0, frame_bytes); >> + /* finish the current frame in the fifo, >> then send whole frames */ >> + if (fifo_bytes > 0) { >> + do_audio_out(os, ost, ist, samples, >> frame_bytes-fifo_bytes, 1); >> + opts = ost->st->pts.val * >> av_q2d(ost->st->time_base); >> + } >> + while (opts < vpts) { >> + do_audio_out(os, ost, ist, samples, >> frame_bytes, 1); >> + opts = ost->st->pts.val * >> av_q2d(ost->st->time_base); >> + } >> + fifo_bytes = av_fifo_size(ost->fifo); >> + if (fifo_bytes != 0) >> + ffmpeg_exit(1); >> + } >> + >> /* encode any samples remaining in fifo */ >> if (fifo_bytes > 0) { >> int osize = >> av_get_bits_per_sample_fmt(enc->sample_fmt) >> 3; >> @@ -4233,6 +4275,7 @@ static const OptionDef options[] = { >> { "vol", OPT_INT | HAS_ARG | OPT_AUDIO, {(void*)&audio_volume}, "change >> audio volume (256=normal)" , "volume" }, // >> { "newaudio", OPT_AUDIO | OPT_FUNC2, {(void*)opt_new_stream}, "add a >> new audio stream to the current output stream" }, >> { "alang", HAS_ARG | OPT_STRING | OPT_AUDIO, {(void *)&audio_language}, >> "set the ISO 639 language code (3 letters) of the current audio stream" , >> "code" }, >> + { "apad", OPT_BOOL | OPT_AUDIO, {(void*)&audio_pad}, "pad audio to >> video length", "pad" }, >> { "sample_fmt", HAS_ARG | OPT_EXPERT | OPT_AUDIO, >> {(void*)opt_audio_sample_fmt}, "set sample format, 'list' as argument shows >> all the sample formats supported", "format" }, >> >> /* subtitle options */ > > > Based on how you're using skip_resample_reformat, it seems this patch > doesn't work when changing sample format or sample rate when encoding, > correct? > > -Justin
The silence is generated in the output sample format domain to allow appending silence one audio block at a time (based on the encoder's frame size). So it should work with changing sample format and sample rate. --Alex _______________________________________________ libav-devel mailing list [email protected] https://lists.libav.org/mailman/listinfo/libav-devel
