FFmpeg: how to use C++ code to change the frame rate of a video file?












2















I know it would be easier to use FFmpeg commands to change the frame rate of a video file.
But anyway, if I want to do it in C++ code, and use FFmpeg libraries, how could I do it?



I think I should've be able to find out the clue in the source code.
Just before proceeding, I hope there would be some good introductions or examples.










share|improve this question



























    2















    I know it would be easier to use FFmpeg commands to change the frame rate of a video file.
    But anyway, if I want to do it in C++ code, and use FFmpeg libraries, how could I do it?



    I think I should've be able to find out the clue in the source code.
    Just before proceeding, I hope there would be some good introductions or examples.










    share|improve this question

























      2












      2








      2


      1






      I know it would be easier to use FFmpeg commands to change the frame rate of a video file.
      But anyway, if I want to do it in C++ code, and use FFmpeg libraries, how could I do it?



      I think I should've be able to find out the clue in the source code.
      Just before proceeding, I hope there would be some good introductions or examples.










      share|improve this question














      I know it would be easier to use FFmpeg commands to change the frame rate of a video file.
      But anyway, if I want to do it in C++ code, and use FFmpeg libraries, how could I do it?



      I think I should've be able to find out the clue in the source code.
      Just before proceeding, I hope there would be some good introductions or examples.







      video ffmpeg






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Mar 25 '14 at 18:53









      user1914692user1914692

      1,46852451




      1,46852451
























          1 Answer
          1






          active

          oldest

          votes


















          2














          This is fairly easy, all you need is to modify the time_base of the video stream. For simple container formats such as AVI you only need to do it in the header. If you insist to do it via ffmpeg API, you'd need to loop through all the frames in the input stream, and copy them to the output stream.



          The above assumes you only want to change the FPS (i.e. slow down or speed up the video) without dropping frames. However if you want to keep the video playback at the original speed while changing the FPS, you'd need to recode the video, i.e. decode and encode each frame, while inserting extra frames or removing some frames. You cannot simply remove the frames from the video - for example when converting from 30FPS to 15FPS you cannot simply remove every 2nd frame, since it may be a keyframe and it will break all frames after it until the next keyframe is encountered. Same way, you cannot simply duplicate a frame when upping the FPS, as P frames apply only to the frame before it, so duplicating it would break your video. For this which I'd suggest to look at my Karaoke Lyric Editor source code, notably video decoding and video encoding.






          share|improve this answer
























          • What I wanted is the second explanation of yours. The play speed is the same, just with change in the FPS. For example, the original fps is 20, and I want to change to 30 fps. So you mean I need to decode to frames, and do some inserting (not a trivial algorithm) to get frames for 30 fps. The feed those frames to encode to a video file. But if I want to do it real time, I need to figure out how many frames to decode and how many frames to encode. So how to synchronize the two processes? Android MediaCodec seems to use EGL to help Synchronization of the two.

            – user1914692
            Mar 27 '14 at 20:21






          • 1





            That's fairly easy. Assuming you upscale from 20FPS to 30FPS, this would mean for every 20 frames decoded you need to add 10 frames - so every 20/10 = 2 frames you need to add a frame. So you get the counter from 2 to 0 which you decrease with each encode frame. Once it hits zero, you encode again the same frame (but with increased PTS of course) and set the counter to 2 again. So the source frame sequence SSSS turn into SSDSSD, where D is a duplicate frame.

            – George Y.
            Mar 27 '14 at 22:45













          • Thanks for your input. Although for now I am not convinced by the answer, but it is very helpful; so I vote it. So here is my question. I thought it would use sampling to get the correct frame at a specific time point. For example, in the 20 fps video file the frame 1, frame 2, frame 3 are at: 0/20sec, 1/20sec, 2/20sec. Now for the 30 fps video file, the frame a, frame b, frame c should be: 0/30sec, 1/30sec, 2/30sec. So for the frame at 1/30sec, we should use some interpolation between 0/20sec frame and 1/20sec frame. I think simply adding a new frame is not ideal.

            – user1914692
            Mar 28 '14 at 22:13











          Your Answer






          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "1"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f22643769%2fffmpeg-how-to-use-c-code-to-change-the-frame-rate-of-a-video-file%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          1 Answer
          1






          active

          oldest

          votes








          1 Answer
          1






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes









          2














          This is fairly easy, all you need is to modify the time_base of the video stream. For simple container formats such as AVI you only need to do it in the header. If you insist to do it via ffmpeg API, you'd need to loop through all the frames in the input stream, and copy them to the output stream.



          The above assumes you only want to change the FPS (i.e. slow down or speed up the video) without dropping frames. However if you want to keep the video playback at the original speed while changing the FPS, you'd need to recode the video, i.e. decode and encode each frame, while inserting extra frames or removing some frames. You cannot simply remove the frames from the video - for example when converting from 30FPS to 15FPS you cannot simply remove every 2nd frame, since it may be a keyframe and it will break all frames after it until the next keyframe is encountered. Same way, you cannot simply duplicate a frame when upping the FPS, as P frames apply only to the frame before it, so duplicating it would break your video. For this which I'd suggest to look at my Karaoke Lyric Editor source code, notably video decoding and video encoding.






          share|improve this answer
























          • What I wanted is the second explanation of yours. The play speed is the same, just with change in the FPS. For example, the original fps is 20, and I want to change to 30 fps. So you mean I need to decode to frames, and do some inserting (not a trivial algorithm) to get frames for 30 fps. The feed those frames to encode to a video file. But if I want to do it real time, I need to figure out how many frames to decode and how many frames to encode. So how to synchronize the two processes? Android MediaCodec seems to use EGL to help Synchronization of the two.

            – user1914692
            Mar 27 '14 at 20:21






          • 1





            That's fairly easy. Assuming you upscale from 20FPS to 30FPS, this would mean for every 20 frames decoded you need to add 10 frames - so every 20/10 = 2 frames you need to add a frame. So you get the counter from 2 to 0 which you decrease with each encode frame. Once it hits zero, you encode again the same frame (but with increased PTS of course) and set the counter to 2 again. So the source frame sequence SSSS turn into SSDSSD, where D is a duplicate frame.

            – George Y.
            Mar 27 '14 at 22:45













          • Thanks for your input. Although for now I am not convinced by the answer, but it is very helpful; so I vote it. So here is my question. I thought it would use sampling to get the correct frame at a specific time point. For example, in the 20 fps video file the frame 1, frame 2, frame 3 are at: 0/20sec, 1/20sec, 2/20sec. Now for the 30 fps video file, the frame a, frame b, frame c should be: 0/30sec, 1/30sec, 2/30sec. So for the frame at 1/30sec, we should use some interpolation between 0/20sec frame and 1/20sec frame. I think simply adding a new frame is not ideal.

            – user1914692
            Mar 28 '14 at 22:13
















          2














          This is fairly easy, all you need is to modify the time_base of the video stream. For simple container formats such as AVI you only need to do it in the header. If you insist to do it via ffmpeg API, you'd need to loop through all the frames in the input stream, and copy them to the output stream.



          The above assumes you only want to change the FPS (i.e. slow down or speed up the video) without dropping frames. However if you want to keep the video playback at the original speed while changing the FPS, you'd need to recode the video, i.e. decode and encode each frame, while inserting extra frames or removing some frames. You cannot simply remove the frames from the video - for example when converting from 30FPS to 15FPS you cannot simply remove every 2nd frame, since it may be a keyframe and it will break all frames after it until the next keyframe is encountered. Same way, you cannot simply duplicate a frame when upping the FPS, as P frames apply only to the frame before it, so duplicating it would break your video. For this which I'd suggest to look at my Karaoke Lyric Editor source code, notably video decoding and video encoding.






          share|improve this answer
























          • What I wanted is the second explanation of yours. The play speed is the same, just with change in the FPS. For example, the original fps is 20, and I want to change to 30 fps. So you mean I need to decode to frames, and do some inserting (not a trivial algorithm) to get frames for 30 fps. The feed those frames to encode to a video file. But if I want to do it real time, I need to figure out how many frames to decode and how many frames to encode. So how to synchronize the two processes? Android MediaCodec seems to use EGL to help Synchronization of the two.

            – user1914692
            Mar 27 '14 at 20:21






          • 1





            That's fairly easy. Assuming you upscale from 20FPS to 30FPS, this would mean for every 20 frames decoded you need to add 10 frames - so every 20/10 = 2 frames you need to add a frame. So you get the counter from 2 to 0 which you decrease with each encode frame. Once it hits zero, you encode again the same frame (but with increased PTS of course) and set the counter to 2 again. So the source frame sequence SSSS turn into SSDSSD, where D is a duplicate frame.

            – George Y.
            Mar 27 '14 at 22:45













          • Thanks for your input. Although for now I am not convinced by the answer, but it is very helpful; so I vote it. So here is my question. I thought it would use sampling to get the correct frame at a specific time point. For example, in the 20 fps video file the frame 1, frame 2, frame 3 are at: 0/20sec, 1/20sec, 2/20sec. Now for the 30 fps video file, the frame a, frame b, frame c should be: 0/30sec, 1/30sec, 2/30sec. So for the frame at 1/30sec, we should use some interpolation between 0/20sec frame and 1/20sec frame. I think simply adding a new frame is not ideal.

            – user1914692
            Mar 28 '14 at 22:13














          2












          2








          2







          This is fairly easy, all you need is to modify the time_base of the video stream. For simple container formats such as AVI you only need to do it in the header. If you insist to do it via ffmpeg API, you'd need to loop through all the frames in the input stream, and copy them to the output stream.



          The above assumes you only want to change the FPS (i.e. slow down or speed up the video) without dropping frames. However if you want to keep the video playback at the original speed while changing the FPS, you'd need to recode the video, i.e. decode and encode each frame, while inserting extra frames or removing some frames. You cannot simply remove the frames from the video - for example when converting from 30FPS to 15FPS you cannot simply remove every 2nd frame, since it may be a keyframe and it will break all frames after it until the next keyframe is encountered. Same way, you cannot simply duplicate a frame when upping the FPS, as P frames apply only to the frame before it, so duplicating it would break your video. For this which I'd suggest to look at my Karaoke Lyric Editor source code, notably video decoding and video encoding.






          share|improve this answer













          This is fairly easy, all you need is to modify the time_base of the video stream. For simple container formats such as AVI you only need to do it in the header. If you insist to do it via ffmpeg API, you'd need to loop through all the frames in the input stream, and copy them to the output stream.



          The above assumes you only want to change the FPS (i.e. slow down or speed up the video) without dropping frames. However if you want to keep the video playback at the original speed while changing the FPS, you'd need to recode the video, i.e. decode and encode each frame, while inserting extra frames or removing some frames. You cannot simply remove the frames from the video - for example when converting from 30FPS to 15FPS you cannot simply remove every 2nd frame, since it may be a keyframe and it will break all frames after it until the next keyframe is encountered. Same way, you cannot simply duplicate a frame when upping the FPS, as P frames apply only to the frame before it, so duplicating it would break your video. For this which I'd suggest to look at my Karaoke Lyric Editor source code, notably video decoding and video encoding.







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Mar 27 '14 at 7:01









          George Y.George Y.

          8,71031621




          8,71031621













          • What I wanted is the second explanation of yours. The play speed is the same, just with change in the FPS. For example, the original fps is 20, and I want to change to 30 fps. So you mean I need to decode to frames, and do some inserting (not a trivial algorithm) to get frames for 30 fps. The feed those frames to encode to a video file. But if I want to do it real time, I need to figure out how many frames to decode and how many frames to encode. So how to synchronize the two processes? Android MediaCodec seems to use EGL to help Synchronization of the two.

            – user1914692
            Mar 27 '14 at 20:21






          • 1





            That's fairly easy. Assuming you upscale from 20FPS to 30FPS, this would mean for every 20 frames decoded you need to add 10 frames - so every 20/10 = 2 frames you need to add a frame. So you get the counter from 2 to 0 which you decrease with each encode frame. Once it hits zero, you encode again the same frame (but with increased PTS of course) and set the counter to 2 again. So the source frame sequence SSSS turn into SSDSSD, where D is a duplicate frame.

            – George Y.
            Mar 27 '14 at 22:45













          • Thanks for your input. Although for now I am not convinced by the answer, but it is very helpful; so I vote it. So here is my question. I thought it would use sampling to get the correct frame at a specific time point. For example, in the 20 fps video file the frame 1, frame 2, frame 3 are at: 0/20sec, 1/20sec, 2/20sec. Now for the 30 fps video file, the frame a, frame b, frame c should be: 0/30sec, 1/30sec, 2/30sec. So for the frame at 1/30sec, we should use some interpolation between 0/20sec frame and 1/20sec frame. I think simply adding a new frame is not ideal.

            – user1914692
            Mar 28 '14 at 22:13



















          • What I wanted is the second explanation of yours. The play speed is the same, just with change in the FPS. For example, the original fps is 20, and I want to change to 30 fps. So you mean I need to decode to frames, and do some inserting (not a trivial algorithm) to get frames for 30 fps. The feed those frames to encode to a video file. But if I want to do it real time, I need to figure out how many frames to decode and how many frames to encode. So how to synchronize the two processes? Android MediaCodec seems to use EGL to help Synchronization of the two.

            – user1914692
            Mar 27 '14 at 20:21






          • 1





            That's fairly easy. Assuming you upscale from 20FPS to 30FPS, this would mean for every 20 frames decoded you need to add 10 frames - so every 20/10 = 2 frames you need to add a frame. So you get the counter from 2 to 0 which you decrease with each encode frame. Once it hits zero, you encode again the same frame (but with increased PTS of course) and set the counter to 2 again. So the source frame sequence SSSS turn into SSDSSD, where D is a duplicate frame.

            – George Y.
            Mar 27 '14 at 22:45













          • Thanks for your input. Although for now I am not convinced by the answer, but it is very helpful; so I vote it. So here is my question. I thought it would use sampling to get the correct frame at a specific time point. For example, in the 20 fps video file the frame 1, frame 2, frame 3 are at: 0/20sec, 1/20sec, 2/20sec. Now for the 30 fps video file, the frame a, frame b, frame c should be: 0/30sec, 1/30sec, 2/30sec. So for the frame at 1/30sec, we should use some interpolation between 0/20sec frame and 1/20sec frame. I think simply adding a new frame is not ideal.

            – user1914692
            Mar 28 '14 at 22:13

















          What I wanted is the second explanation of yours. The play speed is the same, just with change in the FPS. For example, the original fps is 20, and I want to change to 30 fps. So you mean I need to decode to frames, and do some inserting (not a trivial algorithm) to get frames for 30 fps. The feed those frames to encode to a video file. But if I want to do it real time, I need to figure out how many frames to decode and how many frames to encode. So how to synchronize the two processes? Android MediaCodec seems to use EGL to help Synchronization of the two.

          – user1914692
          Mar 27 '14 at 20:21





          What I wanted is the second explanation of yours. The play speed is the same, just with change in the FPS. For example, the original fps is 20, and I want to change to 30 fps. So you mean I need to decode to frames, and do some inserting (not a trivial algorithm) to get frames for 30 fps. The feed those frames to encode to a video file. But if I want to do it real time, I need to figure out how many frames to decode and how many frames to encode. So how to synchronize the two processes? Android MediaCodec seems to use EGL to help Synchronization of the two.

          – user1914692
          Mar 27 '14 at 20:21




          1




          1





          That's fairly easy. Assuming you upscale from 20FPS to 30FPS, this would mean for every 20 frames decoded you need to add 10 frames - so every 20/10 = 2 frames you need to add a frame. So you get the counter from 2 to 0 which you decrease with each encode frame. Once it hits zero, you encode again the same frame (but with increased PTS of course) and set the counter to 2 again. So the source frame sequence SSSS turn into SSDSSD, where D is a duplicate frame.

          – George Y.
          Mar 27 '14 at 22:45







          That's fairly easy. Assuming you upscale from 20FPS to 30FPS, this would mean for every 20 frames decoded you need to add 10 frames - so every 20/10 = 2 frames you need to add a frame. So you get the counter from 2 to 0 which you decrease with each encode frame. Once it hits zero, you encode again the same frame (but with increased PTS of course) and set the counter to 2 again. So the source frame sequence SSSS turn into SSDSSD, where D is a duplicate frame.

          – George Y.
          Mar 27 '14 at 22:45















          Thanks for your input. Although for now I am not convinced by the answer, but it is very helpful; so I vote it. So here is my question. I thought it would use sampling to get the correct frame at a specific time point. For example, in the 20 fps video file the frame 1, frame 2, frame 3 are at: 0/20sec, 1/20sec, 2/20sec. Now for the 30 fps video file, the frame a, frame b, frame c should be: 0/30sec, 1/30sec, 2/30sec. So for the frame at 1/30sec, we should use some interpolation between 0/20sec frame and 1/20sec frame. I think simply adding a new frame is not ideal.

          – user1914692
          Mar 28 '14 at 22:13





          Thanks for your input. Although for now I am not convinced by the answer, but it is very helpful; so I vote it. So here is my question. I thought it would use sampling to get the correct frame at a specific time point. For example, in the 20 fps video file the frame 1, frame 2, frame 3 are at: 0/20sec, 1/20sec, 2/20sec. Now for the 30 fps video file, the frame a, frame b, frame c should be: 0/30sec, 1/30sec, 2/30sec. So for the frame at 1/30sec, we should use some interpolation between 0/20sec frame and 1/20sec frame. I think simply adding a new frame is not ideal.

          – user1914692
          Mar 28 '14 at 22:13


















          draft saved

          draft discarded




















































          Thanks for contributing an answer to Stack Overflow!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f22643769%2fffmpeg-how-to-use-c-code-to-change-the-frame-rate-of-a-video-file%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          A CLEAN and SIMPLE way to add appendices to Table of Contents and bookmarks

          Calculate evaluation metrics using cross_val_predict sklearn

          Insert data from modal to MySQL (multiple modal on website)