hqq128/javacv

Encode a video with all(or selective) keyframes

Opened this issue · 5 comments

FFmpegFrameRecorder should record a frame data as keyframe if supplied with the 
flag.
e.g.
Frame frame = new Frame();
frame.image = yuvIplimage;
frame.keyFrame = true;  

Or there should be a way to set the frequency of occurrence of keyframes in a 
video being encoded.

Original issue reported on code.google.com by sabirock...@gmail.com on 14 Apr 2014 at 6:21

Right, the encoder doesn't take into account the keyframe flag. That would be a 
good idea to implement. I'm guessing we could do something that looks like what 
FFmpeg does to force key frames with the "force_key_frames" option:
    http://ffmpeg.org/ffmpeg.html  
If anyone has more information about that, please let us know, thank you!

Otherwise, we can set the maximum interval between keyframes with the GOP size, 
where a value of 0 should create a video file with only keyframes. 
Incidentally, I've added a setter/getter pair recently in this revision:
    http://code.google.com/p/javacv/source/detail?r=9f9f82497b661170d29d43784f04fdcb3ad1f9c3

Original comment by samuel.a...@gmail.com on 18 Apr 2014 at 11:40

  • Changed state: Accepted
  • Added labels: Type-Enhancement
  • Removed labels: Type-Defect
I had tried the GOP setting that didn't help moreover the timestamps on the 
frames got screwed up.

Original comment by sabirock...@gmail.com on 18 Apr 2014 at 2:25

That might be a bug you may want to report upstream to the FFmpeg developers...

Original comment by samuel.a...@gmail.com on 18 Apr 2014 at 2:48

Can you provide the few lines of code that are failing to encode properly? 
Thanks!

Original comment by samuel.a...@gmail.com on 29 Apr 2014 at 1:49

I initialise the recorder and then keep on supplying frames to it either using 
another grabber or camera preview data as input for encoding

recorder = new FFmpegFrameRecorder(movieFile, imageWidth, imageHeight, 1);
recorder.setFormat("mp4");
recorder.setVideoCodec(avcodec.AV_CODEC_ID_MPEG4);
recorder.setFrameRate(frameRate);

//For best quality video set this to 0 i.e. get the maximum lossless output
recorder.setVideoQuality(0);
...
...
long t = (System.nanoTime() - startTime) / 1000;
if (t > recorder.getTimestamp()) {
    recorder.setTimestamp(t);
}
Frame frame = new Frame();
frame.image = yuvIplimage;
frame.keyFrame = true;      // TODO: Is this actually setting every frame to be 
a keyframe?
recorder.record(frame);

Thanks

Original comment by sabirock...@gmail.com on 30 Apr 2014 at 4:09