[FFmpeg-user] H.264, keyframes and video copy

Gabriele Greco gabrielegreco at gmail.com
Tue Sep 18 16:54:04 EEST 2018


I have a problem cutting certain H.264 files in a mkv container with frame
precise cuts at the keyframes, this usually works on most other formats and
also on h.264 when the container is not mkv.

Basically what I see is that I can take a picture at a certain keyframe,
but if I try to cut a video segment it starts severals seconds late, I was
quite sure it was the mkv container that contained WRONG keyframe
informations, but, I've tried to re encode it with ffmpeg at a lower
resolution and the problem persists, and also with a small custom program I
wrote I found that I can display the frame at the second I ask using
avformat/avcodec to parse the file, but I cannot get a video starting at
that frame using ffmpeg command line program (git head built today).

Test sample: https://www.dropbox.com/s/u5r3y31ahsodc8e/test_scaled.mkv?dl=0
(just 700kb, encoded with ffmpeg head)

Here is the tool versions (I tried also with 3.4.x  branch with the very
same results):
ffprobe version N-91972-gbd10c1e9a8 Copyright (c) 2007-2018 the FFmpeg
developers
  built with Apple LLVM version 9.1.0 (clang-902.0.39.2)
  configuration: --disable-videotoolbox --disable-audiotoolbox
--enable-libx264 --enable-libfdk-aac --enable-nonfree --enable-gpl
  libavutil      56. 19.101 / 56. 19.101
  libavcodec     58. 30.100 / 58. 30.100
  libavformat    58. 18.101 / 58. 18.101
  libavdevice    58.  4.103 / 58.  4.103
  libavfilter     7. 32.100 /  7. 32.100
  libswscale      5.  2.100 /  5.  2.100
  libswresample   3.  2.100 /  3.  2.100
  libpostproc    55.  2.100 / 55.  2.100

Here is the source file (the one encoded by ffmpeg):
Input #0, matroska,webm, from 'test_scaled.mkv':
  Metadata:
    GENRE           : fast
    ARTIST          : skyde1_FULLHD
    ENCODER         : Lavf57.83.100
  Duration: 00:00:17.60, start: 0.000000, bitrate: 355 kb/s
    Stream #0:0: Video: h264 (High), yuv420p(progressive), 320x180, 25 fps,
25 tbr, 1k tbn, 50 tbc (default)
    Metadata:
      ENCODER         : Lavc57.107.100 libx264
      DURATION        : 00:00:17.600000000


This is the frame I want to cut from (as reported by ffprobe):
~/projects/ffmpeg-head/ffprobe -show_frames test_scaled.mkv
[.... a few FRAME cutted from output ... ]
[FRAME]
media_type=video
stream_index=0
key_frame=1
pkt_pts=9440
pkt_pts_time=9.440000
pkt_dts=9440
pkt_dts_time=9.440000
best_effort_timestamp=9440
best_effort_timestamp_time=9.440000
pkt_duration=40
pkt_duration_time=0.040000
pkt_pos=458874
pkt_size=9291
width=320
height=180
pix_fmt=yuv420p
sample_aspect_ratio=N/A
pict_type=I
coded_picture_number=236
display_picture_number=0
interlaced_frame=0
top_field_first=0
repeat_pict=0
color_range=unknown
color_space=unknown
color_primaries=unknown
color_transfer=unknown
chroma_location=left
[/FRAME]

Here is the ffmpeg operation to get the image at 9.44000 (if I place -ss
before or after the input file the image is the same) (output available at
https://www.dropbox.com/s/kqw9el2lxiemsk1/test_scaled.jpg?dl=0 )

~/projects/ffmpeg-head/ffmpeg -y -i test_scaled.mkv -ss 9.440000 -vframes 1
test_scaled.jpg
ffmpeg version N-91972-gbd10c1e9a8 Copyright (c) 2000-2018 the FFmpeg
developers
  built with Apple LLVM version 9.1.0 (clang-902.0.39.2)
  configuration: --disable-videotoolbox --disable-audiotoolbox
--enable-libx264 --enable-libfdk-aac --enable-nonfree --enable-gpl
  libavutil      56. 19.101 / 56. 19.101
  libavcodec     58. 30.100 / 58. 30.100
  libavformat    58. 18.101 / 58. 18.101
  libavdevice    58.  4.103 / 58.  4.103
  libavfilter     7. 32.100 /  7. 32.100
  libswscale      5.  2.100 /  5.  2.100
  libswresample   3.  2.100 /  3.  2.100
  libpostproc    55.  2.100 / 55.  2.100
Input #0, matroska,webm, from 'test_scaled.mkv':
  Metadata:
    GENRE           : fast
    ARTIST          : skyde1_FULLHD
    ENCODER         : Lavf57.83.100
  Duration: 00:00:17.60, start: 0.000000, bitrate: 355 kb/s
    Stream #0:0: Video: h264 (High), yuv420p(progressive), 320x180, 25 fps,
25 tbr, 1k tbn, 50 tbc (default)
    Metadata:
      ENCODER         : Lavc57.107.100 libx264
      DURATION        : 00:00:17.600000000
Stream mapping:
  Stream #0:0 -> #0:0 (h264 (native) -> mjpeg (native))
Press [q] to stop, [?] for help
[swscaler @ 0x7fb874845a00] deprecated pixel format used, make sure you did
set range correctly
Output #0, image2, to 'test_scaled.jpg':
  Metadata:
    GENRE           : fast
    ARTIST          : skyde1_FULLHD
    encoder         : Lavf58.18.101
    Stream #0:0: Video: mjpeg, yuvj420p(pc), 320x180, q=2-31, 200 kb/s, 25
fps, 25 tbn, 25 tbc (default)
    Metadata:
      DURATION        : 00:00:17.600000000
      encoder         : Lavc58.30.100 mjpeg
    Side data:
      cpb: bitrate max/min/avg: 0/0/200000 buffer size: 0 vbv_delay: -1
frame=    1 fps=0.0 q=3.6 Lsize=N/A time=00:00:00.04 bitrate=N/A
speed=0.757x
video:9kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB
muxing overhead: unknown


Here is the operation I use to create a video from 9.440000 (output
available at
https://www.dropbox.com/s/n4ccqoaxx2l4v2t/test_cut_scaled.mkv?dl=0 ), the
resolution is quite low but in the timer in the top right corner of the
video shows that the starting frame of the video is somehow 4 seconds later
than the image in the previous step...

~/projects/ffmpeg-head/ffmpeg -y -i test_scaled.mkv -ss 9.440000 -c copy
test_cut_scaled.mkv
ffmpeg version N-91972-gbd10c1e9a8 Copyright (c) 2000-2018 the FFmpeg
developers
  built with Apple LLVM version 9.1.0 (clang-902.0.39.2)
  configuration: --disable-videotoolbox --disable-audiotoolbox
--enable-libx264 --enable-libfdk-aac --enable-nonfree --enable-gpl
  libavutil      56. 19.101 / 56. 19.101
  libavcodec     58. 30.100 / 58. 30.100
  libavformat    58. 18.101 / 58. 18.101
  libavdevice    58.  4.103 / 58.  4.103
  libavfilter     7. 32.100 /  7. 32.100
  libswscale      5.  2.100 /  5.  2.100
  libswresample   3.  2.100 /  3.  2.100
  libpostproc    55.  2.100 / 55.  2.100
Input #0, matroska,webm, from 'test_scaled.mkv':
  Metadata:
    GENRE           : fast
    ARTIST          : skyde1_FULLHD
    ENCODER         : Lavf57.83.100
  Duration: 00:00:17.60, start: 0.000000, bitrate: 355 kb/s
    Stream #0:0: Video: h264 (High), yuv420p(progressive), 320x180, 25 fps,
25 tbr, 1k tbn, 50 tbc (default)
    Metadata:
      ENCODER         : Lavc57.107.100 libx264
      DURATION        : 00:00:17.600000000
Output #0, matroska, to 'test_cut_scaled.mkv':
  Metadata:
    GENRE           : fast
    ARTIST          : skyde1_FULLHD
    encoder         : Lavf58.18.101
    Stream #0:0: Video: h264 (High) (H264 / 0x34363248),
yuv420p(progressive), 320x180, q=2-31, 25 fps, 25 tbr, 1k tbn, 1k tbc
(default)
    Metadata:
      ENCODER         : Lavc57.107.100 libx264
      DURATION        : 00:00:17.600000000
Stream mapping:
  Stream #0:0 -> #0:0 (copy)
Press [q] to stop, [?] for help
frame=   79 fps=0.0 q=-1.0 Lsize=     143kB time=00:00:08.04 bitrate=
145.4kbits/s speed=2.81e+03x
video:141kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB
muxing overhead: 0.971987%



-- 
Bye,
 Gabry


More information about the ffmpeg-user mailing list