Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Progressive or Interlace detection in ffmpeg

Tags:

ffmpeg

I am trying to write a decoder using ffmpeg and I want to display some information about the video stream. I can detect if a frame is progressive or interlaced (tff, bff) only after decoding the frame. i.e,

avcodec_decode_video2(pCodecCtx, pFrame, &gotFrame, &packet);
.....(assume we have a frame) 
.....
// print information
printf("prog=%d inter=%d", !pFrame->interlaced_frame, pFrame->interlaced_frame);

This works well.

But I want to know if there is a way of detecting this from the AVFormatContext, AVCodecCtx or AVCodec structs or some other functions. This would be very useful, if for example I want to abort decoding if the file is interlaced. I don't want to decode a frame to get this piece of information.

I am trying to support MPEG2, H.264/AVC and HEVC codecs (either elementary streams or in MP4 container).

Sorry if this is a trivial question! Thank you very much!

like image 429
ponderingfish Avatar asked Jul 24 '14 22:07

ponderingfish


2 Answers

ffmpeg can run in "idet" (interlace detection) mode and gives a summary of frame types it finds in the file. I use:

$ ffmpeg -filter:v idet -frames:v 360 -an -f rawvideo -y /dev/null -i HitchhikersGuide.mp4

(ffmpeg with the idet filter, sample 360 frames, blocking audio, using rawvideo format, send output to /dev/null, with input file HitchhikersGuide.mp4)

which produces a report that contains (in part):

[Parsed_idet_0 @ 0x7fd5f3c121c0] Repeated Fields: Neither:   360 Top:     0 Bottom:     0
[Parsed_idet_0 @ 0x7fd5f3c121c0] Single frame detection: TFF:    30 BFF:     0 Progressive:   330 Undetermined:     0
[Parsed_idet_0 @ 0x7fd5f3c121c0] Multi frame detection: TFF:    22 BFF:     0 Progressive:   338 Undetermined:     0

In this case, 92% of the sampled frames are progressive, and 8% are interlaced, so most services would call this an interlaced video. TFF and BFF are Top-Field-First and Bottom-Field-First, respectively, and both indicate an interlaced frame.

Note that it is possible to encode interlaced video as progressive and progressive video as interlaced, and this method will report on the encoding only. If you want to know if the video was originally interlaced or progressive, then you will need to visually inspect it and look for a "combing" effect where alternate lines don't quite line up with each other (especially when the camera is moving fast), and if you see combing, then the original video is interlaced.

like image 71
Kevin Murray Avatar answered Jan 01 '23 19:01

Kevin Murray


You could use ffprobe, which comes with ffmpeg. I don't know how you would use that from a library, but the command-line version can show the field_order. Example command, with a few additional fields:

ffprobe -v quiet -select_streams v stream=codec_name,height,width,pix_fmt,field_order -of csv=p=0 "$Your_File"

Example output with different files:

prores,1920,1080,yuva444p12le,progressive
h264,1920,1080,yuv420p,unknown              # some progressive files show unknown
prores,720,576,yuv422p10le,tb               # tb = interlaced TFF interleaved
mpeg2video,1920,1080,yuv422p,tt             # tt = interlaced TFF
dvvideo,720,576,yuv420p,bt                  # bt = interlaced BFF interleaved

An alternative would be Mediainfo :

mediainfo --Inform='Video;%ScanType%,%ScanOrder%,%ScanType_StoreMethod%' "$Your_File"

Example output with different files:

Progressive,,
Interlaced,TFF,
Interlaced,TFF,InterleavedFields
Interlaced,BFF,InterleavedFields

Mediainfo's source is available here, and on Github.

like image 23
mivk Avatar answered Jan 01 '23 18:01

mivk