Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Add transcoding example #54

Merged
merged 17 commits into from
Jan 6, 2020
Merged

Add transcoding example #54

merged 17 commits into from
Jan 6, 2020

Conversation

leandromoreira
Copy link
Owner

@leandromoreira leandromoreira commented Jan 1, 2020

After I learned a little I think this is the best examples to write/show the transcoding chapter:

  • 1 - a transmuxing example - mp4 -> mp4 dbab188
  • 2 - a transmuxing example - mp4 -> fmp4 9f31610
  • 3 - a transcoding example - h264 -> h264 (fixed gop, no scenecut) 6ad6a82
  • 4 - a transrating example - h264 -> h264 (fixed gop & CBR bit rate) 8ed2c1f

    -b:v 1M -minrate 1M -maxrate 1M -bufsize 2M

  • 5 - a transcoding example - h264 -> h265 6060871
  • 6 - add the markdown chapter explanning the process
  • 7 - (Bonus) a complete transmux|cod|ing example - mp4 -> webm, h264 -> vp9, aac -> opus

Issues

Trying to achieve 3 & 4

  • high bit rate (10.6 Mb/s) fixed ✅ by b5378f3 (had to use force-cfr 😢 I really don't understand rate control at this level)
  • warning messages (forced frame type (5) at 80 was changed to frame type (3)) fixed ✅ by 0abee08
  • variable FPS (59.99 fps) fixed ✅ by 8ed2c1f

Trying to achieve 3 & 4

  • warning messages specified frame type (5) at 180 is not compatible with keyframe interval ✅ by 0abee08

Wanna help me?

If you want to test or run it locally make sure you have docker installed and that you had ran make fetch_small_bunny_video to download the sample video.

git clone --single-branch --branch transcoding-chapter https://github.com/leandromoreira/ffmpeg-libav-tutorial.git

make run_transcoding

# this is going to create the file bunny_1s_gop.mp4

@leandromoreira
Copy link
Owner Author

Simple transmuxing and fmp4 is working!

Screen Shot 2020-01-01 at 20 09 28

Screen Shot 2020-01-01 at 20 09 40

@leandromoreira
Copy link
Owner Author

#52

@leandromoreira
Copy link
Owner Author

leandromoreira commented Jan 2, 2020

While coding the 3 38c6c78 I faced the following issues but it works:

  • the fps has changed 59.99 fps
Video: h264, yuv420p, 1920x1080, 7632 kb/s, 59.99 fps, 60 tbr, 16384 tbn, 0.03 tbc (default)
  • a single warning message has appeared
[libx264 @ 0x1e78200] forced frame type (5) at 597 was changed to frame type (3)

✅ Playable in VLC

@leandromoreira
Copy link
Owner Author

leandromoreira commented Jan 2, 2020

While dealing with 3 6ad6a82 now it seems that the gop is fixed but other issues arrived:

  • bit rate is high
Bit rate                                 : 10.6 Mb/s
  • fps still seems to be variable
Frame rate mode                          : Variable
Frame rate                               : 60.000 FPS
Minimum frame rate                       : 56.302 FPS
Maximum frame rate                       : 60.015 FPS
  • a lot of warning messages have appeared:
[libx264 @ 0x1a5a200] forced frame type (5) at 80 was changed to frame type (3)
[libx264 @ 0x1a5a200] forced frame type (3) at 81 was changed to frame type (1)
[libx264 @ 0x1a5a200] forced frame type (5) at 140 was changed to frame type (3)
[libx264 @ 0x1a5a200] forced frame type (3) at 141 was changed to frame type (1)
[libx264 @ 0x1a5a200] forced frame type (5) at 200 was changed to frame type (3)
[libx264 @ 0x1a5a200] forced frame type (3) at 201 was changed to frame type (1)
[libx264 @ 0x1a5a200] forced frame type (5) at 310 was changed to frame type (1)
[libx264 @ 0x1a5a200] forced frame type (5) at 369 was changed to frame type (3)
[libx264 @ 0x1a5a200] forced frame type (5) at 370 was changed to frame type (1)
[libx264 @ 0x1a5a200] forced frame type (5) at 429 was changed to frame type (3)
[libx264 @ 0x1a5a200] forced frame type (5) at 430 was changed to frame type (1)
[libx264 @ 0x1a5a200] forced frame type (5) at 489 was changed to frame type (3)
...

✅ Playable in VLC

@leandromoreira
Copy link
Owner Author

leandromoreira commented Jan 2, 2020

When trying to change the bit rate. If you change only the AVCodecContext->bit_rate this is going to only change the nominal bit rate:

mediainfo bunny_1s_gop.mp4
Bit rate                                 : 39.9 Mb/s
Nominal bit rate                         : 2 000 kb/s
Width                                    : 1 920 pixels
Height                                   : 1 080 pixels

Changing more AVCodecContext rate controls parameters don't seem to affect:

AVCodecContext->bit_rate = 2000 * 1000;
AVCodecContext->rc_max_rate = 2000 * 1000;
AVCodecContext->rc_min_rate = 2000 * 1000;
AVCodecContext->rc_buffer_size = 2 * 2000 * 1000;

mediainfo
Bit rate                                 : 27.8 Mb/s
Nominal bit rate                         : 2 000 kb/s

Or even the x264opts bitrate:

  av_opt_set(sc->video_avcc->priv_data, "x264opts", "bitrate=2000:keyint=60:min-keyint=60:scenecut=-1", 0);

Or the generic options (minrate, maxrate, bufsize) via priv_data:

  av_opt_set(sc->video_avcc->priv_data, "minrate", "2M", 0);
  av_opt_set(sc->video_avcc->priv_data, "maxrate", "2M", 0);
  av_opt_set(sc->video_avcc->priv_data, "bufsize", "4M", 0);

mediainfo 
Bit rate                                 : 10.6 Mb/s

Tried codec private options, it didn't work as well:

  av_dict_set(&encoder_private_options , "b", "2.0M", 0);
  av_dict_set(&encoder_private_options , "minrate", "2.0M", 0);
  av_dict_set(&encoder_private_options , "maxrate", "2.0M", 0);
  av_dict_set(&encoder_private_options , "bufsize", "4.0M", 0);

@leandromoreira
Copy link
Owner Author

leandromoreira commented Jan 3, 2020

I tried to control rate by:

  int M = 100; // when I use 1000 it gets worst.
  sc->video_avcc->bit_rate = 2100 * M;
  sc->video_avcc->rc_max_rate = 2600 * M;
  sc->video_avcc->rc_min_rate = 2600 * M;
  sc->video_avcc->rc_buffer_size = 2 * 2600 * M;

The final bit rate is still no how it was suppose to be:

Bit rate                                 : 4 932 kb/s
Nominal bit rate                         : 210 kb/s

When I set `force-crf

av_opt_set(sc->video_avcc->priv_data, "x264opts", "keyint=60:min-keyint=60:scenecut=-1:bitrate=1700:force-cfr=1", 0);

It behaves better but not as expected:

Bit rate                                 : 1 388 kb/s
Nominal bit rate                         : 1 700 kb/s

Only after I set up force-cfrplus AVCodecContext->rc_*:

av_opt_set(sc->video_avcc->priv_data, "x264opts", "keyint=60:min-keyint=60:scenecut=-1:force-cfr=1", 0);

AVCodecContext->video_avcc->bit_rate = 2 * 1000 * 1000;
AVCodecContext->video_avcc->rc_buffer_size = 4 * 1000 * 1000;
AVCodecContext->video_avcc->rc_max_rate = 2 * 1000 * 1000;
AVCodecContext->video_avcc->rc_min_rate = 2.5 * 1000 * 1000;

Bit rate                                 : 2 000 kb/s

@leandromoreira
Copy link
Owner Author

While I'm trying to figure out all the issues I went deeper into ffmpeg (the command line) "transcode" path source code:

And I noticed that there are lots of lines of code to take care of guessing the frame rate, set up the context (timing, streaming params) to encode a video stream and many others checks and adjustments.

I think maybe it'll be too time-consuming for me and too hard for the readers to grasp 😞 therefore I think I'll reduce the chapter to: transmuxing (mp4->mp4, mp4->fmp4) and transcoding (h264->h264 fixed gop, h264->h265)

@leandromoreira
Copy link
Owner Author

leandromoreira commented Jan 5, 2020

I just put libvpx-vp9 as the video codec and it worked BUT again with a huge bit rate 😕 and it took too long even for a 10 second video.

Stream #0:0(und): Video: vp9, yuv420p(tv), 1920x1080, 93847 kb/s, 60 fps, 60 tbr, 15360 tbn, 15360 tbc (default)

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant