[FFmpeg-devel] Field order during libavformat write_header

Marton Balint cus at passwd.hu
Wed Mar 21 21:18:58 EET 2018

On Wed, 21 Mar 2018, Devin Heitmueller wrote:

> Hello,
> I’m doing some debugging of format selection for the decklink device, 
> and in particular trying to get it to properly support interlaced 
> formats.  One thing that came to my attention was the following commit:
> https://github.com/FFmpeg/FFmpeg/commit/48f8ad329010a93c323569cad695090a5930277b <https://github.com/FFmpeg/FFmpeg/commit/48f8ad329010a93c323569cad695090a5930277b>
> This patch in principle sets the output format based on the 
> AVCodecParameters field_order member when the write_header() callback is 
> invoked.  However, I’ve been doing testing with various transport 
> streams containing MPEG-2 and H.264, and in all cases it seems that the 
> field_order member is always AV_FIELD_UNKNOWN at that point (regardless 
> of whether the content is progressive or interlaced).
> Marton, when you wrote this patch, what type of content were you testing 
> with?  I’m just trying to understand whether this works with some 
> content but not others (in which case I can compare the behavior and 
> make a fix), or if the functionality has *never* actually worked.

I think I mostly did my tests with manually specifying the field order on 
the command line. I am not 100% sure if the source field order 
was propagated correctly or not. I am suprised if it's not propagated now.

> It seems like at the write_header() phase, we’re never going to actually 
> know what the field order is because we haven’t actually processed any 
> frames and thus don’t know what impact filters might have.

As far as I remember ffmpeg.c has code for this around line 1220:

   if (in_picture->interlaced_frame) {
      if (enc->codec->id == AV_CODEC_ID_MJPEG)
         mux_par->field_order = in_picture->top_field_first ? AV_FIELD_TT:AV_FIELD_BB;
         mux_par->field_order = in_picture->top_field_first ? AV_FIELD_TB:AV_FIELD_BT;
   } else
      mux_par->field_order = AV_FIELD_PROGRESSIVE;

Isn't this supposed to set the muxer field order prior to 
calling write_header? Why doesn't this work for decklink?

> Hence I would need to defer setting the output format and enabling the 
> output until we have received the first frame of real video (relying on 
> the AVFrame’s interlaced property), moving the functionality from the 
> write_header() callback to write_packet().  Alternatively I could let 
> write_header() enable the output, and then be prepared to reconfigure 
> the output if I receive a frame where the interlaced property differs.
> Thoughts?

As I said, ffmpeg.c should handle this properly. Delayed initialization of 
the video device might be an option, but generally I'd avoid it unless we 
have a very good reason for it.


More information about the ffmpeg-devel mailing list