Skip to content

Commit

Permalink
* Get rid of deprecated calls in FFmpegFrameGrabber and `FFmpegFra…
Browse files Browse the repository at this point in the history
…meRecorder` (issue #607)
  • Loading branch information
saudet committed Feb 4, 2017
1 parent e80f204 commit f1620c9
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 37 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@

* Get rid of deprecated calls in `FFmpegFrameFilter`, `FFmpegFrameGrabber` and `FFmpegFrameRecorder` ([issue #607](https://github.com/bytedeco/javacv/issues/607))
* Fix crash in `FFmpegFrameGrabber.restart()` ([issue #605](https://github.com/bytedeco/javacv/issues/605))
* Upgrade dependencies for OpenCV 3.2.0, libdc1394 2.2.5

Expand Down
11 changes: 6 additions & 5 deletions src/main/java/org/bytedeco/javacv/FFmpegFrameFilter.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2015 Samuel Audet
* Copyright (C) 2015-2017 Samuel Audet
*
* Licensed either under the Apache License, Version 2.0, or (at your option)
* under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -53,6 +53,7 @@
import org.bytedeco.javacpp.BytePointer;
import org.bytedeco.javacpp.Loader;
import org.bytedeco.javacpp.Pointer;
import org.bytedeco.javacpp.PointerPointer;

import static org.bytedeco.javacpp.avcodec.*;
import static org.bytedeco.javacpp.avfilter.*;
Expand Down Expand Up @@ -283,7 +284,7 @@ public void pushImage(int width, int height, int depth, int channels, int stride
}
}

avpicture_fill(new AVPicture(image_frame), data, pixelFormat, width, height);
av_image_fill_arrays(new PointerPointer(image_frame), image_frame.linesize(), data, pixelFormat, width, height, 1);
image_frame.linesize(0, step);
image_frame.format(pixelFormat);
image_frame.width(width);
Expand Down Expand Up @@ -321,16 +322,16 @@ public Frame pull() throws Exception {
frame.imageChannels = frame.imageStride / frame.imageWidth;
} else {
frame.imageStride = frame.imageWidth;
int size = avpicture_get_size(filt_frame.format(), frame.imageWidth, frame.imageHeight);
int size = av_image_get_buffer_size(filt_frame.format(), frame.imageWidth, frame.imageHeight, 1);
// Fix bug on Android4.0,check out https://github.com/bytedeco/javacpp/issues/39
if (image_buf[0] == null || image_buf[0].capacity() < size) {
image_buf[0] = ByteBuffer.allocateDirect(size).order(ByteOrder.nativeOrder());
}
frame.image = image_buf;
frame.image[0].position(0).limit(size);
frame.imageChannels = (size + frame.imageWidth * frame.imageHeight - 1) / (frame.imageWidth * frame.imageHeight);
ret = avpicture_layout(new AVPicture(filt_frame), filt_frame.format(),
frame.imageWidth, frame.imageHeight, (ByteBuffer) frame.image[0].position(0), frame.image[0].capacity());
ret = av_image_copy_to_buffer(new BytePointer((ByteBuffer) frame.image[0].position(0)), frame.image[0].capacity(),
new PointerPointer(filt_frame), filt_frame.linesize(), filt_frame.format(), frame.imageWidth, frame.imageHeight, 1);
}
return frame;
}
Expand Down
61 changes: 42 additions & 19 deletions src/main/java/org/bytedeco/javacv/FFmpegFrameGrabber.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2009-2016 Samuel Audet
* Copyright (C) 2009-2017 Samuel Audet
*
* Licensed either under the Apache License, Version 2.0, or (at your option)
* under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -136,7 +136,7 @@ public void release() throws Exception {
void releaseUnsafe() throws Exception {
if (pkt != null && pkt2 != null) {
if (pkt2.size() > 0) {
av_free_packet(pkt);
av_packet_unref(pkt);
}
pkt = pkt2 = null;
}
Expand All @@ -161,7 +161,7 @@ void releaseUnsafe() throws Exception {

// Close the video codec
if (video_c != null) {
avcodec_close(video_c);
avcodec_free_context(video_c);
video_c = null;
}

Expand All @@ -173,7 +173,7 @@ void releaseUnsafe() throws Exception {

// Close the audio codec
if (audio_c != null) {
avcodec_close(audio_c);
avcodec_free_context(audio_c);
audio_c = null;
}

Expand Down Expand Up @@ -427,7 +427,7 @@ static class SeekCallback extends Seek_Pointer_long_int {
}
if (pkt2.size() > 0) {
pkt2.size(0);
av_free_packet(pkt);
av_packet_unref(pkt);
}
/* comparing to timestamp +/- 1 avoids rouding issues for framerates
which are no proper divisors of 1000000, e.g. where
Expand Down Expand Up @@ -547,17 +547,18 @@ void startUnsafe() throws Exception {

// Find the first video and audio stream, unless the user specified otherwise
video_st = audio_st = null;
AVCodecParameters video_par = null, audio_par = null;
int nb_streams = oc.nb_streams();
for (int i = 0; i < nb_streams; i++) {
AVStream st = oc.streams(i);
// Get a pointer to the codec context for the video or audio stream
AVCodecContext c = st.codec();
if (video_st == null && c.codec_type() == AVMEDIA_TYPE_VIDEO && (videoStream < 0 || videoStream == i)) {
AVCodecParameters par = st.codecpar();
if (video_st == null && par.codec_type() == AVMEDIA_TYPE_VIDEO && (videoStream < 0 || videoStream == i)) {
video_st = st;
video_c = c;
} else if (audio_st == null && c.codec_type() == AVMEDIA_TYPE_AUDIO && (audioStream < 0 || audioStream == i)) {
video_par = par;
} else if (audio_st == null && par.codec_type() == AVMEDIA_TYPE_AUDIO && (audioStream < 0 || audioStream == i)) {
audio_st = st;
audio_c = c;
audio_par = par;
}
}
if (video_st == null && audio_st == null) {
Expand All @@ -567,9 +568,20 @@ void startUnsafe() throws Exception {

if (video_st != null) {
// Find the decoder for the video stream
AVCodec codec = avcodec_find_decoder(video_c.codec_id());
AVCodec codec = avcodec_find_decoder(video_par.codec_id());
if (codec == null) {
throw new Exception("avcodec_find_decoder() error: Unsupported video format or codec not found: " + video_c.codec_id() + ".");
throw new Exception("avcodec_find_decoder() error: Unsupported video format or codec not found: " + video_par.codec_id() + ".");
}

/* Allocate a codec context for the decoder */
if ((video_c = avcodec_alloc_context3(codec)) == null) {
throw new Exception("avcodec_alloc_context3() error: Could not allocate video decoding context.");
}

/* copy the stream parameters from the muxer */
if ((ret = avcodec_parameters_to_context(video_c, video_st.codecpar())) < 0) {
release();
throw new Exception("avcodec_parameters_to_context() error: Could not copy the video stream parameters.");
}

options = new AVDictionary(null);
Expand Down Expand Up @@ -604,13 +616,13 @@ void startUnsafe() throws Exception {
int fmt = getPixelFormat();

// Determine required buffer size and allocate buffer
int size = avpicture_get_size(fmt, width, height);
int size = av_image_get_buffer_size(fmt, width, height, 1);
image_ptr = new BytePointer[] { new BytePointer(av_malloc(size)).capacity(size) };
image_buf = new Buffer[] { image_ptr[0].asBuffer() };

// Assign appropriate parts of buffer to image planes in picture_rgb
// Note that picture_rgb is an AVFrame, but AVFrame is a superset of AVPicture
avpicture_fill(new AVPicture(picture_rgb), image_ptr[0], fmt, width, height);
av_image_fill_arrays(new PointerPointer(picture_rgb), picture_rgb.linesize(), image_ptr[0], fmt, width, height, 1);
picture_rgb.format(fmt);
picture_rgb.width(width);
picture_rgb.height(height);
Expand All @@ -628,9 +640,20 @@ void startUnsafe() throws Exception {

if (audio_st != null) {
// Find the decoder for the audio stream
AVCodec codec = avcodec_find_decoder(audio_c.codec_id());
AVCodec codec = avcodec_find_decoder(audio_par.codec_id());
if (codec == null) {
throw new Exception("avcodec_find_decoder() error: Unsupported audio format or codec not found: " + audio_c.codec_id() + ".");
throw new Exception("avcodec_find_decoder() error: Unsupported audio format or codec not found: " + audio_par.codec_id() + ".");
}

/* Allocate a codec context for the decoder */
if ((audio_c = avcodec_alloc_context3(codec)) == null) {
throw new Exception("avcodec_alloc_context3() error: Could not allocate audio decoding context.");
}

/* copy the stream parameters from the muxer */
if ((ret = avcodec_parameters_to_context(audio_c, audio_st.codecpar())) < 0) {
release();
throw new Exception("avcodec_parameters_to_context() error: Could not copy the audio stream parameters.");
}

options = new AVDictionary(null);
Expand Down Expand Up @@ -660,13 +683,13 @@ public void trigger() throws Exception {
}
if (pkt2.size() > 0) {
pkt2.size(0);
av_free_packet(pkt);
av_packet_unref(pkt);
}
for (int i = 0; i < numBuffers+1; i++) {
if (av_read_frame(oc, pkt) < 0) {
return;
}
av_free_packet(pkt);
av_packet_unref(pkt);
}
}

Expand Down Expand Up @@ -856,7 +879,7 @@ public Frame grabFrame(boolean doAudio, boolean doVideo, boolean processImage, b

if (pkt2.size() <= 0) {
// Free the packet that was allocated by av_read_frame
av_free_packet(pkt);
av_packet_unref(pkt);
}
}
return frame;
Expand Down
44 changes: 31 additions & 13 deletions src/main/java/org/bytedeco/javacv/FFmpegFrameRecorder.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2009-2015 Samuel Audet
* Copyright (C) 2009-2017 Samuel Audet
*
* Licensed either under the Apache License, Version 2.0, or (at your option)
* under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -172,11 +172,11 @@ public void release() throws Exception {
void releaseUnsafe() throws Exception {
/* close each codec */
if (video_c != null) {
avcodec_close(video_c);
avcodec_free_context(video_c);
video_c = null;
}
if (audio_c != null) {
avcodec_close(audio_c);
avcodec_free_context(audio_c);
audio_c = null;
}
if (picture_buf != null) {
Expand Down Expand Up @@ -449,12 +449,15 @@ void startUnsafe() throws Exception {
}

/* add a video output stream */
if ((video_st = avformat_new_stream(oc, video_codec)) == null) {
if ((video_st = avformat_new_stream(oc, null)) == null) {
release();
throw new Exception("avformat_new_stream() error: Could not allocate video stream.");
}

video_c = video_st.codec();
if ((video_c = avcodec_alloc_context3(video_codec)) == null) {
release();
throw new Exception("avcodec_alloc_context3() error: Could not allocate video encoding context.");
}

if (inpVideoStream != null) {
if ((ret = avcodec_copy_context(video_st.codec(), inpVideoStream.codec())) < 0) {
Expand Down Expand Up @@ -572,12 +575,15 @@ void startUnsafe() throws Exception {
}
oformat.audio_codec(audio_codec.id());

if ((audio_st = avformat_new_stream(oc, audio_codec)) == null) {
if ((audio_st = avformat_new_stream(oc, null)) == null) {
release();
throw new Exception("avformat_new_stream() error: Could not allocate audio stream.");
}

audio_c = audio_st.codec();
if ((audio_c = avcodec_alloc_context3(audio_codec)) == null) {
release();
throw new Exception("avcodec_alloc_context3() error: Could not allocate audio encoding context.");
}

if(inpAudioStream != null && audioChannels > 0){
if ((ret = avcodec_copy_context(audio_st.codec(), inpAudioStream.codec())) < 0) {
Expand Down Expand Up @@ -687,7 +693,7 @@ void startUnsafe() throws Exception {
}
picture.pts(0); // magic required by libx264

int size = avpicture_get_size(video_c.pix_fmt(), video_c.width(), video_c.height());
int size = av_image_get_buffer_size(video_c.pix_fmt(), video_c.width(), video_c.height(), 1);
if ((picture_buf = new BytePointer(av_malloc(size))).isNull()) {
release();
throw new Exception("av_malloc() error: Could not allocate picture buffer.");
Expand All @@ -700,6 +706,12 @@ void startUnsafe() throws Exception {
throw new Exception("av_frame_alloc() error: Could not allocate temporary picture.");
}

/* copy the stream parameters to the muxer */
if ((ret = avcodec_parameters_from_context(video_st.codecpar(), video_c)) < 0) {
release();
throw new Exception("avcodec_parameters_from_context() error: Could not copy the video stream parameters.");
}

AVDictionary metadata = new AVDictionary(null);
for (Entry<String, String> e : videoMetadata.entrySet()) {
av_dict_set(metadata, e.getKey(), e.getValue(), 0);
Expand Down Expand Up @@ -729,7 +741,7 @@ void startUnsafe() throws Exception {
/* ugly hack for PCM codecs (will be removed ASAP with new PCM
support to compute the input frame size in samples */
if (audio_c.frame_size() <= 1) {
audio_outbuf_size = FF_MIN_BUFFER_SIZE;
audio_outbuf_size = AV_INPUT_BUFFER_MIN_SIZE;
audio_input_frame_size = audio_outbuf_size / audio_c.channels();
switch (audio_c.codec_id()) {
case AV_CODEC_ID_PCM_S16LE:
Expand Down Expand Up @@ -763,6 +775,12 @@ void startUnsafe() throws Exception {
}
frame.pts(0); // magic required by libvorbis and webm

/* copy the stream parameters to the muxer */
if ((ret = avcodec_parameters_from_context(audio_st.codecpar(), audio_c)) < 0) {
release();
throw new Exception("avcodec_parameters_from_context() error: Could not copy the audio stream parameters.");
}

AVDictionary metadata = new AVDictionary(null);
for (Entry<String, String> e : audioMetadata.entrySet()) {
av_dict_set(metadata, e.getKey(), e.getValue(), 0);
Expand Down Expand Up @@ -875,8 +893,8 @@ public boolean recordImage(int width, int height, int depth, int channels, int s
if (img_convert_ctx == null) {
throw new Exception("sws_getCachedContext() error: Cannot initialize the conversion context.");
}
avpicture_fill(new AVPicture(tmp_picture), data, pixelFormat, width, height);
avpicture_fill(new AVPicture(picture), picture_buf, video_c.pix_fmt(), video_c.width(), video_c.height());
av_image_fill_arrays(new PointerPointer(tmp_picture), tmp_picture.linesize(), data, pixelFormat, width, height, 1);
av_image_fill_arrays(new PointerPointer(picture), picture.linesize(), picture_buf, video_c.pix_fmt(), video_c.width(), video_c.height(), 1);
tmp_picture.linesize(0, step);
tmp_picture.format(pixelFormat);
tmp_picture.width(width);
Expand All @@ -887,7 +905,7 @@ public boolean recordImage(int width, int height, int depth, int channels, int s
sws_scale(img_convert_ctx, new PointerPointer(tmp_picture), tmp_picture.linesize(),
0, height, new PointerPointer(picture), picture.linesize());
} else {
avpicture_fill(new AVPicture(picture), data, pixelFormat, width, height);
av_image_fill_arrays(new PointerPointer(picture), picture.linesize(), data, pixelFormat, width, height, 1);
picture.linesize(0, step);
picture.format(pixelFormat);
picture.width(width);
Expand All @@ -904,7 +922,7 @@ public boolean recordImage(int width, int height, int depth, int channels, int s
video_pkt.flags(video_pkt.flags() | AV_PKT_FLAG_KEY);
video_pkt.stream_index(video_st.index());
video_pkt.data(new BytePointer(picture));
video_pkt.size(Loader.sizeof(AVPicture.class));
video_pkt.size(Loader.sizeof(AVFrame.class));
} else {
/* encode the image */
av_init_packet(video_pkt);
Expand Down

0 comments on commit f1620c9

Please sign in to comment.