[FFmpeg-devel] Field order during libavformat write_header

James Almer jamrial at gmail.com
Wed Mar 21 21:33:37 EET 2018


On 3/21/2018 4:18 PM, Marton Balint wrote:
> 
> 
> 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;
>      else
>         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?

No, this is done after that, while processing a packet.
It is also making changes to the output codecpar after write_header()
was called, which is wrong.

libavformat used to delay writing the header until you feed it the first
packet, an internal functionality this code here abused.

> 
>> 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.
> 
> Regards,
> Marton
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel at ffmpeg.org
> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel



More information about the ffmpeg-devel mailing list