|
|
|
@ -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; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|