On Mon, Mar 28, 2011 at 6:02 PM, Justin Ruggles
<[email protected]> wrote:
> On 03/28/2011 06:14 PM, Alex Converse wrote:
>
>> On Mon, Mar 28, 2011 at 2:37 PM, Justin Ruggles
>> <[email protected]> wrote:
>>> On 03/28/2011 05:27 PM, Alex Converse wrote:
>>>
>>>> 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.
>>>
>>>
>>> I see. But it uses memset(0), so this wouldn't work with SAMPLE_FMT_U8.
>>>
>>
>> Actually it turns out this code does not run at all for PCM codecs because of
>>                 if(ost->st->codec->codec_type == AVMEDIA_TYPE_AUDIO &&
>> enc->frame_size <=1)
>>                     continue;
>>
>> So I do need to fix that part.
>
> Yeah, that frame_size==1 (but not really) for pcm thing really sucks.
> It's on my list of things to get rid of.
>

Our PCM handling code is subtly broken in a variety of ways.

I have some code to force PCM to go through the FIFO based on some
semi-arbitrary chunking.

I'm not sure if we want it.

I think the ideal fifo situation would be an avfilter that sits
between the remixer and the encoder but that being feasible is quite a
while off.

>> Do we have any non-PCM *encoders* that support SAMPLE_FMT_U8. FWIW
>> they are broken already if they don't support
>> CODEC_CAP_SMALL_LAST_FRAME. Still it should be fairly trivial to add a
>> small generate silence function that works for any (sane) sample
>> format.
>
> I don't know if we have non-PCM encoders that support SAMPLE_FMT_U8, but
> I do think we should support it.
>

So we now have silence generation support for AV_SAMPLE_FMT_U8.

I'm not sure where to go from here. What should the next step be. For
the time being I can't fix-the-world to implement this.
_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel

Reply via email to