Add support for ffmpeg 3.0.

This commit is contained in:
Peter Rekdal Sunde 2016-03-22 13:26:55 +01:00
parent fd1b66b37d
commit 278747ba45

View File

@ -70,6 +70,11 @@ extern "C" {
#include <libavutil/opt.h>
#endif
#if LIBAVUTIL_BUILD >= (LIBAVUTIL_VERSION_MICRO >= 100 \
? CALC_FFMPEG_VERSION(51, 63, 100) : CALC_FFMPEG_VERSION(54, 6, 0))
#include <libavutil/imgutils.h>
#endif
#ifdef WIN32
#define HAVE_FFMPEG_SWSCALE 1
#include <libavcodec/avcodec.h>
@ -398,6 +403,39 @@ inline int _opencv_ffmpeg_interrupt_callback(void *ptr)
}
#endif
static
inline void _opencv_ffmpeg_av_packet_unref(AVPacket *pkt)
{
#if LIBAVCODEC_BUILD >= (LIBAVCODEC_VERSION_MICRO >= 100 \
? CALC_FFMPEG_VERSION(55, 25, 100) : CALC_FFMPEG_VERSION(55, 16, 0))
av_packet_unref(pkt);
#else
av_free_packet(pkt);
#endif
};
static
inline void _opencv_ffmpeg_av_image_fill_arrays(void *frame, uint8_t *ptr, enum AVPixelFormat pix_fmt, int width, int height)
{
#if LIBAVUTIL_BUILD >= (LIBAVUTIL_VERSION_MICRO >= 100 \
? CALC_FFMPEG_VERSION(51, 63, 100) : CALC_FFMPEG_VERSION(54, 6, 0))
av_image_fill_arrays(((AVFrame*)frame)->data, ((AVFrame*)frame)->linesize, ptr, pix_fmt, width, height, 1);
#else
avpicture_fill((AVPicture*)frame, ptr, pix_fmt, width, height);
#endif
};
static
inline int _opencv_ffmpeg_av_image_get_buffer_size(enum AVPixelFormat pix_fmt, int width, int height)
{
#if LIBAVUTIL_BUILD >= (LIBAVUTIL_VERSION_MICRO >= 100 \
? CALC_FFMPEG_VERSION(51, 63, 100) : CALC_FFMPEG_VERSION(54, 6, 0))
return av_image_get_buffer_size(pix_fmt, width, height, 1);
#else
return avpicture_get_size(pix_fmt, width, height);
#endif
};
struct CvCapture_FFMPEG
{
@ -538,7 +576,7 @@ void CvCapture_FFMPEG::close()
// free last packet if exist
if (packet.data) {
av_free_packet (&packet);
_opencv_ffmpeg_av_packet_unref (&packet);
packet.data = NULL;
}
@ -874,7 +912,7 @@ bool CvCapture_FFMPEG::grabFrame()
while (!valid)
{
av_free_packet (&packet);
_opencv_ffmpeg_av_packet_unref (&packet);
#if USE_AV_INTERRUPT_CALLBACK
if (interrupt_metadata.timeout)
@ -891,7 +929,7 @@ bool CvCapture_FFMPEG::grabFrame()
if( packet.stream_index != video_stream )
{
av_free_packet (&packet);
_opencv_ffmpeg_av_packet_unref (&packet);
count_errs++;
if (count_errs > max_number_of_attempts)
break;
@ -982,9 +1020,9 @@ bool CvCapture_FFMPEG::retrieveFrame(int, unsigned char** data, int* step, int*
int aligns[AV_NUM_DATA_POINTERS];
avcodec_align_dimensions2(video_st->codec, &buffer_width, &buffer_height, aligns);
rgb_picture.data[0] = (uint8_t*)realloc(rgb_picture.data[0],
avpicture_get_size( AV_PIX_FMT_BGR24,
_opencv_ffmpeg_av_image_get_buffer_size( AV_PIX_FMT_BGR24,
buffer_width, buffer_height ));
avpicture_fill( (AVPicture*)&rgb_picture, rgb_picture.data[0],
_opencv_ffmpeg_av_image_fill_arrays(&rgb_picture, rgb_picture.data[0],
AV_PIX_FMT_BGR24, buffer_width, buffer_height );
#endif
frame.width = video_st->codec->width;
@ -1371,7 +1409,7 @@ static AVFrame * icv_alloc_picture_FFMPEG(int pix_fmt, int width, int height, bo
picture->width = width;
picture->height = height;
size = avpicture_get_size( (AVPixelFormat) pix_fmt, width, height);
size = _opencv_ffmpeg_av_image_get_buffer_size( (AVPixelFormat) pix_fmt, width, height);
if(alloc){
picture_buf = (uint8_t *) malloc(size);
if (!picture_buf)
@ -1379,7 +1417,7 @@ static AVFrame * icv_alloc_picture_FFMPEG(int pix_fmt, int width, int height, bo
av_free(picture);
return NULL;
}
avpicture_fill((AVPicture *)picture, picture_buf,
_opencv_ffmpeg_av_image_fill_arrays(picture, picture_buf,
(AVPixelFormat) pix_fmt, width, height);
}
else {
@ -1579,7 +1617,7 @@ static int icv_av_write_frame_FFMPEG( AVFormatContext * oc, AVStream * video_st,
pkt.duration = av_rescale_q(pkt.duration, c->time_base, video_st->time_base);
pkt.stream_index= video_st->index;
ret = av_write_frame(oc, &pkt);
av_free_packet(&pkt);
_opencv_ffmpeg_av_packet_unref(&pkt);
}
else
ret = OPENCV_NO_FRAMES_WRITTEN_CODE;
@ -1681,7 +1719,7 @@ bool CvVideoWriter_FFMPEG::writeFrame( const unsigned char* data, int step, int
if ( c->pix_fmt != input_pix_fmt ) {
assert( input_picture );
// let input_picture point to the raw data buffer of 'image'
avpicture_fill((AVPicture *)input_picture, (uint8_t *) data,
_opencv_ffmpeg_av_image_fill_arrays(input_picture, (uint8_t *) data,
(AVPixelFormat)input_pix_fmt, width, height);
if( !img_convert_ctx )
@ -1705,7 +1743,7 @@ bool CvVideoWriter_FFMPEG::writeFrame( const unsigned char* data, int step, int
return false;
}
else{
avpicture_fill((AVPicture *)picture, (uint8_t *) data,
_opencv_ffmpeg_av_image_fill_arrays(picture, (uint8_t *) data,
(AVPixelFormat)input_pix_fmt, width, height);
}
@ -2637,14 +2675,14 @@ void InputMediaStream_FFMPEG::close()
// free last packet if exist
if (pkt_.data)
av_free_packet(&pkt_);
_opencv_ffmpeg_av_packet_unref(&pkt_);
}
bool InputMediaStream_FFMPEG::read(unsigned char** data, int* size, int* endOfFile)
{
// free last packet if exist
if (pkt_.data)
av_free_packet(&pkt_);
_opencv_ffmpeg_av_packet_unref(&pkt_);
// get the next frame
for (;;)
@ -2675,7 +2713,7 @@ bool InputMediaStream_FFMPEG::read(unsigned char** data, int* size, int* endOfFi
if (pkt_.stream_index != video_stream_id_)
{
av_free_packet(&pkt_);
_opencv_ffmpeg_av_packet_unref(&pkt_);
continue;
}