1

I am absolutely new to video processing, I am building a video streaming site and worked with ffmpeg to generate the formats I need for ShakaPackager.

Sadly I don't understand some of the options being provided, especially keyInt, min-keyint and no-scenecut.

Below you will find the code I use to generate the required formats for my videos.

ffmpeg -y -i ${1} -c:a aac -ac 2 -ab 256k -ar 48000 -c:v libx264 -x264opts "keyint=24:min-keyint=24:no-scenecut" -b:v 1500k -maxrate 1500k -bufsize 1000k -vf "scale=-2:720" "${2}/${3}720.mp4"

I did a bit of research and they talked about IDR-frames I don't even understand those, maybe my needs go way more than that?

2

The frames in your H.264 video are grouped into units called GOPs (Group Of Pictures). Inside these GOPs frames are classified into three types:

  • I-frame: frame that stores the whole picture
  • P-frame: frame that stores only the changes between the current picture and previous ones
  • B-frame: frame that stores differences with previous or future pictures

Additionally, I-frames can be classified as IDR frames and non-IDR frames. The difference is that frames following an IDR frame cannot reference any frame that comes before the IDR frame, while in the case of a non-IDR frame there are no limitations.

Every GOP starts with an I-frame, also called a keyframe, but may contain more than one. To create further confusion, a GOP can start with an IDR frame or with a non-IDR frame. This means that frames in the GOP can sometimes refer to previous GOPs (in this case the GOP is said to be "open"), and sometimes not (in this case it's closed).

It's common to see the structure of a GOP represented as in this example: IBBBPBBBPBBBI. Here the length of the the GOP is 12 frames, with 3 B-frames between each P-frame.

Now your questions:

  • keyint specifies the maximum length of the GOP, so the maximum interval between each keyframe, which remember that can be either an IDR frame or a non-IDR frame. I'm not completely sure but I think that by default ffmpeg will require every I-frame to be an IDR frame, so in practice you can use the terms IDR frame and I-frame interchangeably
  • min-keyint specifies the minimum length of the GOP. This is because the encoder might decide that it makes sense to add a keyframe before the keyint value, so you can put a limit
  • no-scenecut. When the encoder determines that there's been a scene cut, it may decide to insert an additional I-frame. The issue is that I-frames are very expensive if compared to other frame types, so when encoding for streaming you want to disable it.

A couple of other related parameters:

  • bframes specifies the number of consecutive B-frames
  • ref specifies the number of references frames that are used when encoding. It means that when encoding a picture, ref previous frames are looked at for encoding the current frame
  • In the OP's command, these are x264 options, so keyint and min-keyint relate to IDR placement, not non-RAP I frames. – Gyan Aug 20 '18 at 19:25
  • Thanks for the amazing response... I have learnt so much. – James Okpe George Aug 20 '18 at 20:46
  • My question now is how did you learn all of these, how do I learn too? – James Okpe George Aug 20 '18 at 20:48
  • Since you're working on video streaming, I would point you to Video encoding by the numbers by Jan Ozer. It covers pretty much everything you need to know about encoding for streaming – mcont Aug 20 '18 at 21:19
2

Most video encoders apply temporal compression i.e. most frames only store the difference in image content relative to other frames, thus saving storage space, while a few frames store the whole image. The frames with whole pictures are called key frames since they are required in order to reconstruct the whole picture of frames which only store differences. IDR frame in H264 stream denotes a keyframe.

Your code tells ffmpeg to generate a H264 video stream using the x264 encoder, and the options below are used by the encoder to decide keyframe placement.

-x264opts "keyint=24:min-keyint=24:no-scenecut"

keyint=24 tells x264 to forcibly generate a keyframe 24 frames after the last keyframe.

min-keyint=24 sets the minimum keyframe distance. The encoder may decide to place a keyframe on its own even if keyint # of frames haven't elapsed if it comes across an image which is more efficient to store as a complete picture rather than as a set of differences. min-keyint tells the encoder to never do this if the distance isn't at least 24. Since in this case keyint is the same value as min-keyint, all KFs will be 24 frames apart.

no-scenecut - scenecut is the value used by the encoder to calculate if it should force a keyframe if min-keyint allows it to. It can range from 0-100. no-scenecut tells the encoder to skip this evaluation.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.