[patch] Code upgrade with current ffmpeg
Opened this issue · 0 comments
ebachard commented
Hello,
I tested your code, and I had to fix some build issues + some warnings => see below (attached as a txt file, to simplify its application). Recent ffmpeg means current (28th August 2018) master ffmpeg version from github repo. Last, consider the changes are under MIT license.
As a patch : ffmpeg-OpenCV.diff.txt
Current status : the current code is warning free on Linux, but untested. Please tell me whethere there is crash in runtime, and I'll have a look.
diff --git a/README.md b/README.md
index f0569c5..4098f86 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,16 @@
ffmpegOpencv
============
This is a simple class for the interface between ffmpeg and openCV.
+
+Linux compilation instructions
+
+1. uncomment the main() in the .cpp file
+2. type (in one line) :
+
+g++ -Wall -I . -o ffcvmat videoCodec.cpp `pkg-config --cflags --libs opencv libavformat libavcodec libavutil libavdevice libswscale`
+
+3. if nothinggoes wrong, a binary named ffcvmat should be built
+
+4. ./ffcvmat does nothing, just complete it !
+
+ericb / 28th August 2018
diff --git a/videoCodec.cpp b/videoCodec.cpp
index 156516c..5c6d3be 100644
--- a/videoCodec.cpp
+++ b/videoCodec.cpp
@@ -7,7 +7,7 @@ void VideoCodec::destory()
av_free(c);
av_free(frame);
av_freep(&frameRescaled->data[0]);
- avcodec_free_frame(&frameRescaled);
+ av_frame_free(&frameRescaled);
}
bool VideoCodec::initBase(bool isEncoder)
@@ -15,12 +15,12 @@ bool VideoCodec::initBase(bool isEncoder)
encoder = isEncoder;
- orgFormat = PIX_FMT_RGB24;
+ orgFormat = AV_PIX_FMT_RGB24;
- frame = avcodec_alloc_frame();
+ frame = av_frame_alloc();
frame->format = orgFormat;
- frameRescaled = avcodec_alloc_frame();
+ frameRescaled = av_frame_alloc();
avWidth = AVW;
avHeight = AVH;
@@ -62,8 +62,9 @@ VideoEncode::VideoEncode(AVCodecID id)
bool VideoEncode::init(int w, int h)
{
+#if LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(58, 9, 100)
avcodec_register_all();
-
+#endif
if (!initBase(encoder)) return false;
c->bit_rate = 6500000;
@@ -125,11 +126,22 @@ bool VideoEncode::loadcvFrame(cv::Mat input)
if (input.channels() != 3)
cvtColor(cvFrame, cvFrame, CV_GRAY2BGR);
- avpicture_fill((AVPicture *)frame, cvFrame.data, orgFormat, cvFrame.cols, cvFrame.rows);
+// avpicture_fill((AVPicture *)frame, cvFrame.data, orgFormat, cvFrame.cols, cvFrame.rows);
+
+ AVFrame frame;
+ av_image_fill_arrays( frame.data,
+ frame.linesize,
+ &cvFrame.data[0],
+ orgFormat,
+ cvFrame.cols,
+ cvFrame.rows,
+ 1
+ );
+
// rescale to outStream format
- int h = sws_scale(swsCtx, ((AVPicture*)frame)->data, ((AVPicture*)frame)->linesize,
- 0, c->height, ((AVPicture*)frameRescaled)->data, ((AVPicture*)frameRescaled) ->linesize);
+ int h = sws_scale(swsCtx, frame.data, frame.linesize,
+ 0, c->height, frameRescaled->data, frameRescaled ->linesize);
if (h ==0) {
fprintf(stderr, "Fail to rescale\n");
@@ -155,19 +167,28 @@ int VideoEncode::encode(cv::Mat input, int index, unsigned char cdata[])
pkt.size = 0;
/* encode the image */
- int got_output;
- int ret = avcodec_encode_video2(c, &pkt, frameRescaled, &got_output);
- if (ret < 0) {
- fprintf(stderr, "Error encoding frame\n");
- return -1;
- }
+ int got_output = 0;
+ int ret = avcodec_send_packet(c, &pkt);
+
+ if (ret < 0) {
+ fprintf(stderr, "Error encoding frame\n");
+ return -1;
+ }
+
+ ret = avcodec_receive_frame(c, frameRescaled);
+
+ if ((ret == AVERROR_EOF))
+ got_output = 0;
+ else
+ got_output = 1;
+
if (got_output) {
size = pkt.size;
memcpy ( cdata, pkt.data, pkt.size*sizeof(unsigned char));
//fprintf(stderr, "Encoding %d bytes\n", size);
}
- av_free_packet(&pkt);
+ av_packet_unref(&pkt);
return size;
}
@@ -181,8 +202,9 @@ VideoDecode::VideoDecode(AVCodecID id)
bool VideoDecode::init(int w, int h)
{
+#if LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(58, 9, 100)
avcodec_register_all();
-
+#endif
if (!initBase(encoder)) return false;
c->pix_fmt = codecFormat;
@@ -220,22 +242,41 @@ int VideoDecode::decode(cv::Mat &output, const unsigned char cdata[], int pkgSiz
/* encode the image */
int got_frame;
- int len = avcodec_decode_video2(c, frame, &got_frame, &pkt);
+
+ int len = avcodec_send_packet(c, &pkt);
+
if (len < 0) {
- fprintf(stderr, "Error decoding frame\n");
+ fprintf(stderr, "Error encoding frame\n");
return -1;
}
+
+ len = avcodec_receive_frame(c, frame);
+
+ if ((len == AVERROR_EOF))
+ got_frame = 0;
+ else
+ got_frame = 1;
+
if (got_frame) {
int h = sws_scale(swsCtx, frame->data, frame->linesize, 0, c->height,
frameRescaled->data, frameRescaled ->linesize);
-
+ if (h != 0)
+ fprintf(stderr, "error with swscale");
output = cv::Mat(cvHeight, cvWidth, CV_8UC3, frameRescaled->data[0]);
}
- av_free_packet(&pkt);
+ av_packet_unref(&pkt);
return len;
}
+// uncomment for compilation tests
+/*
+int main (void)
+{
+ // do nothing
+ return EXIT_SUCCESS;
+}
+*/
diff --git a/videoCodec.h b/videoCodec.h
index fac96af..121b39d 100644
--- a/videoCodec.h
+++ b/videoCodec.h
@@ -15,9 +15,10 @@ extern "C" {
#include <math.h>
#include <stdio.h>
-#include "timer.h"
+//#include "timer.h"
#include "opencv/cv.h"
-#include "opencv/highgui.h"
+#include <opencv2/opencv.hpp>
+#include <opencv2/highgui.hpp>
#define inline __inline
HTH
--
ericb