FFmpeg: how to use C++ code to change the frame rate of a video file?
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
add a comment |
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
add a comment |
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
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
video ffmpeg
asked Mar 25 '14 at 18:53
user1914692user1914692
1,46852451
1,46852451
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
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.
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
add a comment |
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
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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.
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
add a comment |
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.
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
add a comment |
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.
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.
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
add a comment |
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
add a comment |
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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