VideoHelp Forum




+ Reply to Thread
Results 1 to 16 of 16
  1. Member Budman1's Avatar
    Join Date
    Jul 2012
    Location
    NORTHWEST ILLINOIS, USA
    Search Comp PM
    Good morning all
    For purposes of programming, I need to re-encode a short video with ffmpeg and join it with a longer video but unfortunately the larger video is variable frame rate. Consequently problems arise joining vfr with cfr. I have copied ALL x264 parameter and used vsync 0,1 and 2. Ffmpeg seems to always encode constant frame rate.

    I would rather not encode both for quality loss reasons. Does anyone know a method to use FFMPEG to create a variable frame rate video?

    Thank you
    Quote Quote  
  2. One way is to edit the timecodes (timestamps), then use mkvmerge or mp4fpsmod

    I don't know of a way to do this in ffmpeg only
    Quote Quote  
  3. Try
    ffmpeg -i inputvideo -c copy outputvideo
    (with the longer video).
    ffmpeg corrects minor errors when copying.
    Maybe the result is a crf encoded video.
    Quote Quote  
  4. Try
    Code:
    ffmpeg -f concat -safe 0 -i mylist.txt -c copy out.mp4
    The .mp4 container should preserve the VFR timestamps of the source files AFAIK.

    Perhaps you can collect some ideas from here:
    https://trac.ffmpeg.org/wiki/Concatenate
    Last edited by Sharc; 4th Mar 2020 at 04:06.
    Quote Quote  
  5. As a side note: do not rely on mediainfo when you add a cfr video before a vfr video to check whether the content is vfr or not since mediainfo will only check a few timecodes at the beginning on the file which will report cfr if your cfr video at the front is long enough.

    If everything fails your could always:
    1. extract the time codes or the vfr part
    2. extend the time codes to accommodate the cfr part
    3. append the files without the time codes and add the new time codes to the output.

    Cu Selur

    Ps.: You could probably also first append the files with mkvmerge and then repackage the file to your target container using ffmpeg.
    users currently on my ignore list: deadrats, Stears555, marcorocchini
    Quote Quote  
  6. Member Budman1's Avatar
    Join Date
    Jul 2012
    Location
    NORTHWEST ILLINOIS, USA
    Search Comp PM
    I appreciate all the responses but it seems I need to explain a little better. I am writing a program in Visual Basic that cuts precisely on 'I' frames and if the cut is between 'I' Frames, it encodes the necessary parts to be joined to the following Key frame segment.

    IBBBPBBBPBBBP Original
    IBBBPBBBP Cut portion

    BBBPBBBPBBBPIBBBPBBBPBBBP Original
    IBBPBBBPBBBP IBBBPBBBPBBBP Encoded/Copied portions

    I am using FFMPEG because It can be called behind the scenes with the necessary string to accomplish everything. With a constant Frame rate everything works flawlessly and is frame accurate. Merging is no problem.

    Variable frame rate is another problem. Copied portions are variable frame rate and Encoded portions are Constant frame rate. I tried -Vsync 2 and some of the encoded sections do indeed end up variable frame rate but others are constant. The problem with joining:

    Constant + variable = Constant + section that jumps and runs in fraction of what it should. (Very Fast)

    Variable + Constant = Variable + freeze frame for far longer than the 2 sections together.

    I have been able to copy the format, codec wise and the only difference in the MediaInfo output is the Frame rate.
    Is it just impossible to encode a variable frame rate with FFMpeg?
    Quote Quote  
  7. As far as I know if you don't want to adjust the time codes manually you indeed can't simply use ffmpeg. (at least with mp4 as output, not sure about the mkv muxer in ffmpeg)
    users currently on my ignore list: deadrats, Stears555, marcorocchini
    Quote Quote  
  8. Try to work with the video track only, without audio and subtitles.
    This should give you a cfr in both the copied and encoded parts.
    Quote Quote  
  9. Member Budman1's Avatar
    Join Date
    Jul 2012
    Location
    NORTHWEST ILLINOIS, USA
    Search Comp PM
    I Thought I would list my apparent fix here so anyone else might have the information. Apparently it is impossible to encode an MP4 with variable frame rate but one may be created by merging 2 constant rate videos. The is further problematic if someone tries to cut and merge the merged video, some segments may be constant frame rate and some variable.

    Example:
    I merged a contant frame rate, 30 minute video with another Constant frame rate 30 minute video. Everything played well but the result was listed as variable frame rate. Checking the entire video for PKT_PTS Times and there was a slight deviation at the merge point. (30 FPS was .0333 duration but at the merge point it jumped for 1 frame by .0333111. and then returned to .0333)

    If I cut the first 15 minutes it was constant frame rate. If I cut from 20 minutes to 40 minutes (over the deviation) the result was listed as variable.

    Since there is no way, apparently to make the constant video variable, so the only option left for cutting and merging without play back problems was to change the Variable frame rate video
    PTS times without encoding. Luckily I found a buried post that seems to work.

    In this example, I'm using MP4 containers. First, extract the stream:

    ffmpeg -i source.mp4 -map 0:v -vcodec copy -bsf:v h264_mp4toannexb source-video.h264
    Next, take that stream and re-mux it, but with a specific frame rate and generated timestamps.

    ffmpeg -fflags +genpts -r 30 -i source-video.h264 -vcodec copy output.mp4
    I'm assuming (set me straight if I'm wrong) that by changing the glitch frame to 30 frames instead of 32 fps, it will cause a slight sync problem in the area of milliseconds. I'm also assuming that if another video lists its variable rate at 30 FPS with lowest being 15 (0.066666 duration) and highest 30 FPS (0.033333 duration) there will be worst case 0.033333 sync change.

    ?? I do not know what the range that would be noticeable but I think this would be well below what would be detectable that unless there were many such areas.

    If I am correct, I can alter my program to copy from I frames and encode only the segment between I Frames if necessary and insure all are mergeable.
    Any information that may help would be appreciated.
    Quote Quote  
  10. Apparently it is impossible to encode an MP4 with variable frame rate but one may be created by merging 2 constant rate videos.
    Sure if you merge two cfr clips with different frame rate this should happen.

    Code:
    +genpts -r 30 -i
    will generate fixed time codes with 30fps for the input.
    -> So using this will only avoid creating vfr when appending cfr parts (which both have 30fps).


    The is further problematic if someone tries to cut and merge the merged video, some segments may be constant frame rate and some variable.
    That can always happen if you handle vfr content. (If just one frame is not cfr in relation to its neighbor frame the clip is vfr.)

    Since you now mentioned that you use mp4:
    Last I checked '-vsync vfr' was default for mkv but not for mp4 and I don't think that changed.
    So just to make sure: You are using '-vsync vfr' as an output option when messing with vfr and trying to keep the time codes during cutting and reencoding etc. right?


    Cu Selur
    users currently on my ignore list: deadrats, Stears555, marcorocchini
    Quote Quote  
  11. Member Budman1's Avatar
    Join Date
    Jul 2012
    Location
    NORTHWEST ILLINOIS, USA
    Search Comp PM
    Thank you for the information. It helps clarify what I had but didnt quite understand.

    [QUOTE]So just to make sure: You are using '-vsync vfr' as an output option when messing with vfr and trying[ to keep the time codes during cutting and reencoding etc. right?/QUOTE]

    I am trying to prevent having to reencode and it seemed that during my testing, vsync 2 or vsync cfr worked about like just copying, sometime yes sometimes no. It only seemed to work if I was encoding. So I could encode either ENCODE Cfr to cfr with vsync or encode vfr to cfr most any way.

    The method above at least, doesn't seem to encode but does take quite a while to change a 2 hr movie.

    Am I correct in assuming changing pts will result in slight sync change?
    Quote Quote  
  12. Am I correct in assuming changing pts will result in slight sync change?
    yes

    When you cut and/or reencode a part of vfr clip and save it as mp4 you either need to set the output frame rate this way ffmpeg will make sure it creates cfr output or you need to specify '-vsync vfr' otherwise the time codes might be messed up.
    If you append cfr and vfr content to mp4 you should also add '-vsync vfr'.
    Combining raw H.264 content with vfr content will likely cause problems.

    "+genpts -r 30" will only adjust the time stamps and not do any reencoding, but you should not apply this on vfr content since then your output will get async.

    Cu Selur
    users currently on my ignore list: deadrats, Stears555, marcorocchini
    Quote Quote  
  13. Out of curiosity:
    What is the difference between
    -fflags +genpts -r 29.97 -i input
    and simply
    -r 29.97 -i input

    Don't both replace the source timestamps with new timestamps and eventually have the same effect as assumefps(29.97) in avisynth?
    Quote Quote  
  14. '-fflags +genpts' also works on raw content which has no time stamps, '-r XX -i ...' otherwise only overwrites existing time stamps.
    (iirc without genpts you will also have problems if your source is missing time stamps like it sometimes happens with stream captures)
    users currently on my ignore list: deadrats, Stears555, marcorocchini
    Quote Quote  
  15. I see, Thank you.
    Quote Quote  
  16. Originally Posted by Budman1 View Post
    I am trying to prevent having to reencode and it seemed that during my testing, vsync 2 or vsync cfr worked about like just copying, sometime yes sometimes no. It only seemed to work if I was encoding. So I could encode either ENCODE Cfr to cfr with vsync or encode vfr to cfr most any way.

    The method above at least, doesn't seem to encode but does take quite a while to change a 2 hr movie.
    You may also want to pack each of your .mp4 source files into an intermediate .ts container, then merge (concatenate) the .ts files and output as .mp4 (if .mp4 is your taget container). The merged .mp4 output will be vfr.
    Quote Quote  



Similar Threads

Visit our sponsor! Try DVDFab and backup Blu-rays!