Репозиторий Sisyphus
Последнее обновление: 1 октября 2023 | Пакетов: 18631 | Посещений: 37758353
en ru br
Репозитории ALT

Группа :: Система/Библиотеки
Пакет: libopenshot

 Главная   Изменения   Спек   Патчи   Sources   Загрузить   Gear   Bugs and FR  Repocop 

Патч: libopenshot-0.1.9-774eb365b3f663b1f53dd24c1650fafb3c445ea6.patch
Скачать


commit 774eb365b3f663b1f53dd24c1650fafb3c445ea6
Author: Jonathan Thomas <jonathan@openshot.org>
Date:   Wed Mar 21 02:10:46 2018 -0500
    FFMPEG 3.2 support for FFmpegReader (writer support coming soon)
diff --git a/include/FFmpegReader.h b/include/FFmpegReader.h
index beed9bc..6072756 100644
--- a/include/FFmpegReader.h
+++ b/include/FFmpegReader.h
@@ -99,7 +99,7 @@ namespace openshot
 		AVCodecContext *pCodecCtx, *aCodecCtx;
 		AVStream *pStream, *aStream;
 		AVPacket *packet;
-		AVPicture *pFrame;
+		AVFrame *pFrame;
 		bool is_open;
 		bool is_duration_known;
 		bool check_interlace;
@@ -154,9 +154,6 @@ namespace openshot
 		/// Check the working queue, and move finished frames to the finished queue
 		void CheckWorkingFrames(bool end_of_stream, int64_t requested_frame);
 
-		/// Convert image to RGB format
-		void convert_image(int64_t current_frame, AVPicture *copyFrame, int width, int height, PixelFormat pix_fmt);
-
 		/// Convert Frame Number into Audio PTS
 		int64_t ConvertFrameToAudioPTS(int64_t frame_number);
 
@@ -200,7 +197,7 @@ namespace openshot
 		std::shared_ptr<Frame> ReadStream(int64_t requested_frame);
 
 		/// Remove AVFrame from cache (and deallocate it's memory)
-		void RemoveAVFrame(AVPicture*);
+		void RemoveAVFrame(AVFrame*);
 
 		/// Remove AVPacket from cache (and deallocate it's memory)
 		void RemoveAVPacket(AVPacket*);
diff --git a/include/FFmpegUtilities.h b/include/FFmpegUtilities.h
index 103aceb..b38132f 100644
--- a/include/FFmpegUtilities.h
+++ b/include/FFmpegUtilities.h
@@ -34,6 +34,10 @@
 	#define UINT64_C(c) (c ## ULL)
 	#endif
 
+	#ifndef IS_FFMPEG_3_2
+	#define IS_FFMPEG_3_2 (LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 64, 101))
+	#endif
+
 	// Include the FFmpeg headers
 	extern "C" {
 		#include <libavcodec/avcodec.h>
@@ -55,6 +59,10 @@
 		#if LIBAVFORMAT_VERSION_MAJOR >= 54
 			#include <libavutil/channel_layout.h>
 		#endif
+
+		#if IS_FFMPEG_3_2
+			#include "libavutil/imgutils.h"
+		#endif
 	}
 
 	// This was removed from newer versions of FFmpeg (but still used in libopenshot)
@@ -98,16 +106,55 @@
 		#define PIX_FMT_YUV420P AV_PIX_FMT_YUV420P
 	#endif
 
-	#if LIBAVFORMAT_VERSION_MAJOR >= 55
+	#if IS_FFMPEG_3_2
+		#define AV_ALLOCATE_FRAME() av_frame_alloc()
+		#define AV_ALLOCATE_IMAGE(av_frame, pix_fmt, width, height) av_image_alloc(av_frame->data, av_frame->linesize, width, height, pix_fmt, 1);
+		#define AV_RESET_FRAME(av_frame) av_frame_unref(av_frame)
+    	#define AV_FREE_FRAME(av_frame) av_frame_free(av_frame)
+		#define AV_FREE_PACKET(av_packet) av_packet_unref(av_packet)
+		#define AV_FREE_CONTEXT(av_context) avcodec_free_context(&av_context);
+		#define AV_GET_CODEC_TYPE(av_stream) av_stream->codecpar->codec_type
+		#define AV_FIND_DECODER_CODEC_ID(av_stream) av_stream->codecpar->codec_id;
+		auto AV_GET_CODEC_CONTEXT = [](AVStream* av_stream, AVCodec* av_codec) { \
+			AVCodecContext *context = avcodec_alloc_context3(av_codec); \
+			avcodec_parameters_to_context(context, av_stream->codecpar); \
+			return context; \
+		};
+		#define AV_GET_CODEC_ATTRIBUTES(av_stream, av_context) av_stream->codecpar
+		#define AV_GET_CODEC_PIXEL_FORMAT(av_stream, av_context) (AVPixelFormat) av_stream->codecpar->format
+		#define AV_GET_SAMPLE_FORMAT(av_stream, av_context) av_stream->codecpar->format
+		#define AV_GET_IMAGE_SIZE(pix_fmt, width, height) av_image_get_buffer_size(pix_fmt, width, height, 1)
+		#define AV_COPY_PICTURE_DATA(av_frame, buffer, pix_fmt, width, height) av_image_fill_arrays(av_frame->data, av_frame->linesize, buffer, pix_fmt, width, height, 1);
+	#elif LIBAVFORMAT_VERSION_MAJOR >= 55
 		#define AV_ALLOCATE_FRAME() av_frame_alloc()
+		#define AV_ALLOCATE_IMAGE(av_frame, pix_fmt, width, height) avpicture_alloc((AVPicture *) av_frame, pix_fmt, width, height);
 		#define AV_RESET_FRAME(av_frame) av_frame_unref(av_frame)
     	#define AV_FREE_FRAME(av_frame) av_frame_free(av_frame)
 		#define AV_FREE_PACKET(av_packet) av_packet_unref(av_packet)
+		#define AV_FREE_CONTEXT(av_context) avcodec_close(av_context);
+		#define AV_GET_CODEC_TYPE(av_stream) av_stream->codec->codec_type
+		#define AV_FIND_DECODER_CODEC_ID(av_stream) av_stream->codec->codec_id;
+		#define AV_GET_CODEC_CONTEXT(av_stream, av_codec) av_stream->codec;
+		#define AV_GET_CODEC_ATTRIBUTES(av_stream, av_context) av_context
+		#define AV_GET_CODEC_PIXEL_FORMAT(av_stream, av_context) av_context->pix_fmt
+		#define AV_GET_SAMPLE_FORMAT(av_stream, av_context) av_context->sample_fmt
+		#define AV_GET_IMAGE_SIZE(pix_fmt, width, height) avpicture_get_size(pix_fmt, width, height)
+		#define AV_COPY_PICTURE_DATA(av_frame, buffer, pix_fmt, width, height) avpicture_fill((AVPicture *) av_frame, buffer, pix_fmt, width, height);
 	#else
 		#define AV_ALLOCATE_FRAME() avcodec_alloc_frame()
+		#define AV_ALLOCATE_IMAGE(av_frame, pix_fmt, width, height) avpicture_alloc((AVPicture *) av_frame, pix_fmt, width, height);
 		#define AV_RESET_FRAME(av_frame) avcodec_get_frame_defaults(av_frame)
 		#define AV_FREE_FRAME(av_frame) avcodec_free_frame(av_frame)
 		#define AV_FREE_PACKET(av_packet) av_free_packet(av_packet)
+		#define AV_FREE_CONTEXT(av_context) avcodec_close(av_context);
+		#define AV_GET_CODEC_TYPE(av_stream) av_stream->codec->codec_type
+		#define AV_FIND_DECODER_CODEC_ID(av_stream) av_stream->codec->codec_id;
+		#define AV_GET_CODEC_CONTEXT(av_stream, av_codec) av_stream->codec;
+		#define AV_GET_CODEC_ATTRIBUTES(av_stream, av_context) av_context
+		#define AV_GET_CODEC_PIXEL_FORMAT(av_stream, av_context) av_context->pix_fmt
+		#define AV_GET_SAMPLE_FORMAT(av_stream, av_context) av_context->sample_fmt
+		#define AV_GET_IMAGE_SIZE(pix_fmt, width, height) avpicture_get_size(pix_fmt, width, height)
+		#define AV_COPY_PICTURE_DATA(av_frame, buffer, pix_fmt, width, height) avpicture_fill((AVPicture *) av_frame, buffer, pix_fmt, width, height);
 	#endif
 
 
diff --git a/src/FFmpegReader.cpp b/src/FFmpegReader.cpp
index f803c86..57dffc2 100644
--- a/src/FFmpegReader.cpp
+++ b/src/FFmpegReader.cpp
@@ -123,11 +123,11 @@ void FFmpegReader::Open()
 		for (unsigned int i = 0; i < pFormatCtx->nb_streams; i++)
 		{
 			// Is this a video stream?
-			if (pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO && videoStream < 0) {
+			if (AV_GET_CODEC_TYPE(pFormatCtx->streams[i]) == AVMEDIA_TYPE_VIDEO && videoStream < 0) {
 				videoStream = i;
 			}
 			// Is this an audio stream?
-			if (pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO && audioStream < 0) {
+			if (AV_GET_CODEC_TYPE(pFormatCtx->streams[i]) == AVMEDIA_TYPE_AUDIO && audioStream < 0) {
 				audioStream = i;
 			}
 		}
@@ -142,13 +142,17 @@ void FFmpegReader::Open()
 
 			// Set the codec and codec context pointers
 			pStream = pFormatCtx->streams[videoStream];
-			pCodecCtx = pFormatCtx->streams[videoStream]->codec;
+
+			// Find the codec ID from stream
+			AVCodecID codecId = AV_FIND_DECODER_CODEC_ID(pStream);
+
+			// Get codec and codec context from stream
+			AVCodec *pCodec = avcodec_find_decoder(codecId);
+			pCodecCtx = AV_GET_CODEC_CONTEXT(pStream, pCodec);
 
 			// Set number of threads equal to number of processors (not to exceed 16)
 			pCodecCtx->thread_count = min(OPEN_MP_NUM_PROCESSORS, 16);
 
-			// Find the decoder for the video stream
-			AVCodec *pCodec = avcodec_find_decoder(pCodecCtx->codec_id);
 			if (pCodec == NULL) {
 				throw InvalidCodec("A valid video codec could not be found for this file.", path);
 			}
@@ -168,13 +172,17 @@ void FFmpegReader::Open()
 
 			// Get a pointer to the codec context for the audio stream
 			aStream = pFormatCtx->streams[audioStream];
-			aCodecCtx = pFormatCtx->streams[audioStream]->codec;
+
+			// Find the codec ID from stream
+			AVCodecID codecId = AV_FIND_DECODER_CODEC_ID(aStream);
+
+			// Get codec and codec context from stream
+			AVCodec *aCodec = avcodec_find_decoder(codecId);
+			aCodecCtx = AV_GET_CODEC_CONTEXT(aStream, aCodec);
 
 			// Set number of threads equal to number of processors (not to exceed 16)
 			aCodecCtx->thread_count = min(OPEN_MP_NUM_PROCESSORS, 16);
 
-			// Find the decoder for the audio stream
-			AVCodec *aCodec = avcodec_find_decoder(aCodecCtx->codec_id);
 			if (aCodec == NULL) {
 				throw InvalidCodec("A valid audio codec could not be found for this file.", path);
 			}
@@ -222,12 +230,12 @@ void FFmpegReader::Close()
 		if (info.has_video)
 		{
 			avcodec_flush_buffers(pCodecCtx);
-			avcodec_close(pCodecCtx);
+			AV_FREE_CONTEXT(pCodecCtx);
 		}
 		if (info.has_audio)
 		{
 			avcodec_flush_buffers(aCodecCtx);
-			avcodec_close(aCodecCtx);
+			AV_FREE_CONTEXT(aCodecCtx);
 		}
 
 		// Clear final cache
@@ -269,12 +277,12 @@ void FFmpegReader::UpdateAudioInfo()
 	info.has_audio = true;
 	info.file_size = pFormatCtx->pb ? avio_size(pFormatCtx->pb) : -1;
 	info.acodec = aCodecCtx->codec->name;
-	info.channels = aCodecCtx->channels;
-	if (aCodecCtx->channel_layout == 0)
-		aCodecCtx->channel_layout = av_get_default_channel_layout( aCodecCtx->channels );
-	info.channel_layout = (ChannelLayout) aCodecCtx->channel_layout;
-	info.sample_rate = aCodecCtx->sample_rate;
-	info.audio_bit_rate = aCodecCtx->bit_rate;
+	info.channels = AV_GET_CODEC_ATTRIBUTES(aStream, aCodecCtx)->channels;
+	if (AV_GET_CODEC_ATTRIBUTES(aStream, aCodecCtx)->channel_layout == 0)
+		AV_GET_CODEC_ATTRIBUTES(aStream, aCodecCtx)->channel_layout = av_get_default_channel_layout( AV_GET_CODEC_ATTRIBUTES(aStream, aCodecCtx)->channels );
+	info.channel_layout = (ChannelLayout) AV_GET_CODEC_ATTRIBUTES(aStream, aCodecCtx)->channel_layout;
+	info.sample_rate = AV_GET_CODEC_ATTRIBUTES(aStream, aCodecCtx)->sample_rate;
+	info.audio_bit_rate = AV_GET_CODEC_ATTRIBUTES(aStream, aCodecCtx)->bit_rate;
 
 	// Set audio timebase
 	info.audio_timebase.num = aStream->time_base.num;
@@ -318,8 +326,8 @@ void FFmpegReader::UpdateVideoInfo()
 	// Set values of FileInfo struct
 	info.has_video = true;
 	info.file_size = pFormatCtx->pb ? avio_size(pFormatCtx->pb) : -1;
-	info.height = pCodecCtx->height;
-	info.width = pCodecCtx->width;
+	info.height = AV_GET_CODEC_ATTRIBUTES(pStream, pCodecCtx)->height;
+	info.width = AV_GET_CODEC_ATTRIBUTES(pStream, pCodecCtx)->width;
 	info.vcodec = pCodecCtx->codec->name;
 	info.video_bit_rate = pFormatCtx->bit_rate;
 	if (!check_fps)
@@ -334,18 +342,17 @@ void FFmpegReader::UpdateVideoInfo()
 		info.pixel_ratio.num = pStream->sample_aspect_ratio.num;
 		info.pixel_ratio.den = pStream->sample_aspect_ratio.den;
 	}
-	else if (pCodecCtx->sample_aspect_ratio.num != 0)
+	else if (AV_GET_CODEC_ATTRIBUTES(pStream, pCodecCtx)->sample_aspect_ratio.num != 0)
 	{
-		info.pixel_ratio.num = pCodecCtx->sample_aspect_ratio.num;
-		info.pixel_ratio.den = pCodecCtx->sample_aspect_ratio.den;
+		info.pixel_ratio.num = AV_GET_CODEC_ATTRIBUTES(pStream, pCodecCtx)->sample_aspect_ratio.num;
+		info.pixel_ratio.den = AV_GET_CODEC_ATTRIBUTES(pStream, pCodecCtx)->sample_aspect_ratio.den;
 	}
 	else
 	{
 		info.pixel_ratio.num = 1;
 		info.pixel_ratio.den = 1;
 	}
-
-	info.pixel_format = pCodecCtx->pix_fmt;
+	info.pixel_format = AV_GET_CODEC_PIXEL_FORMAT(pStream, pCodecCtx);
 
 	// Calculate the DAR (display aspect ratio)
 	Fraction size(info.width * info.pixel_ratio.num, info.height * info.pixel_ratio.den);
@@ -697,28 +704,60 @@ int FFmpegReader::GetNextPacket()
 bool FFmpegReader::GetAVFrame()
 {
 	int frameFinished = -1;
+	int ret = 0;
 
 	// Decode video frame
 	AVFrame *next_frame = AV_ALLOCATE_FRAME();
 	#pragma omp critical (packet_cache)
-	avcodec_decode_video2(pCodecCtx, next_frame, &frameFinished, packet);
-
-	// is frame finished
-	if (frameFinished)
 	{
-		// AVFrames are clobbered on the each call to avcodec_decode_video, so we
-		// must make a copy of the image data before this method is called again.
-		pFrame = new AVPicture();
-		avpicture_alloc(pFrame, pCodecCtx->pix_fmt, info.width, info.height);
-		av_picture_copy(pFrame, (AVPicture *) next_frame, pCodecCtx->pix_fmt, info.width, info.height);
-
-		// Detect interlaced frame (only once)
-		if (!check_interlace)
-		{
-			check_interlace = true;
-			info.interlaced_frame = next_frame->interlaced_frame;
-			info.top_field_first = next_frame->top_field_first;
+	#if IS_FFMPEG_3_2
+		frameFinished = 0;
+		ret = avcodec_send_packet(pCodecCtx, packet);
+		if (ret < 0 || ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
+			ZmqLogger::Instance()->AppendDebugMethod("FFmpegReader::GetAVFrame (Packet not sent)", "", -1, "", -1, "", -1, "", -1, "", -1, "", -1);
+		}
+		else {
+			pFrame = new AVFrame();
+			while (ret >= 0) {
+				ret =  avcodec_receive_frame(pCodecCtx, next_frame);
+		  if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
+		  break;
+				}
+				// TODO also handle possible further frames
+				// Use only the first frame like avcodec_decode_video2
+				if (frameFinished == 0 ) {
+					frameFinished = 1;
+					av_image_alloc(pFrame->data, pFrame->linesize, info.width, info.height, (AVPixelFormat)(pStream->codecpar->format), 1);
+					av_image_copy(pFrame->data, pFrame->linesize, (const uint8_t**)next_frame->data, next_frame->linesize,
+												(AVPixelFormat)(pStream->codecpar->format), info.width, info.height);
+					if (!check_interlace)	{
+						check_interlace = true;
+						info.interlaced_frame = next_frame->interlaced_frame;
+						info.top_field_first = next_frame->top_field_first;
+					}
+				}
+			}
+		}
+	#else
+		avcodec_decode_video2(pCodecCtx, next_frame, &frameFinished, packet);
+
+		// is frame finished
+		if (frameFinished) {
+			// AVFrames are clobbered on the each call to avcodec_decode_video, so we
+			// must make a copy of the image data before this method is called again.
+			pFrame = AV_ALLOCATE_FRAME();
+			avpicture_alloc((AVPicture *) pFrame, pCodecCtx->pix_fmt, info.width, info.height);
+			av_picture_copy((AVPicture *) pFrame, (AVPicture *) next_frame, pCodecCtx->pix_fmt, info.width,
+							info.height);
+
+			// Detect interlaced frame (only once)
+			if (!check_interlace) {
+				check_interlace = true;
+				info.interlaced_frame = next_frame->interlaced_frame;
+				info.top_field_first = next_frame->top_field_first;
+			}
 		}
+	#endif
 	}
 
 	// deallocate the frame
@@ -800,11 +839,11 @@ void FFmpegReader::ProcessVideoPacket(int64_t requested_frame)
 	ZmqLogger::Instance()->AppendDebugMethod("FFmpegReader::ProcessVideoPacket (Before)", "requested_frame", requested_frame, "current_frame", current_frame, "", -1, "", -1, "", -1, "", -1);
 
 	// Init some things local (for OpenMP)
-	PixelFormat pix_fmt = pCodecCtx->pix_fmt;
+	PixelFormat pix_fmt = AV_GET_CODEC_PIXEL_FORMAT(pStream, pCodecCtx);
 	int height = info.height;
 	int width = info.width;
 	int64_t video_length = info.video_length;
-    AVPicture *my_frame = pFrame;
+	AVFrame *my_frame = pFrame;
 
 	// Add video frame to list of processing video frames
 	const GenericScopedLock<CriticalSection> lock(processingCriticalSection);
@@ -844,17 +883,16 @@ void FFmpegReader::ProcessVideoPacket(int64_t requested_frame)
 		}
 
 		// Determine required buffer size and allocate buffer
-		numBytes = avpicture_get_size(PIX_FMT_RGBA, width, height);
+		numBytes = AV_GET_IMAGE_SIZE(PIX_FMT_RGBA, width, height);
+
 		#pragma omp critical (video_buffer)
 		buffer = (uint8_t *) av_malloc(numBytes * sizeof(uint8_t));
 
-		// Assign appropriate parts of buffer to image planes in pFrameRGB
-		// Note that pFrameRGB is an AVFrame, but AVFrame is a superset
-		// of AVPicture
-		avpicture_fill((AVPicture *) pFrameRGB, buffer, PIX_FMT_RGBA, width, height);
+		// Copy picture data from one AVFrame (or AVPicture) to another one.
+		AV_COPY_PICTURE_DATA(pFrameRGB, buffer, PIX_FMT_RGBA, width, height);
 
-		SwsContext *img_convert_ctx = sws_getContext(info.width, info.height, pCodecCtx->pix_fmt, width,
-													  height, PIX_FMT_RGBA, SWS_BILINEAR, NULL, NULL, NULL);
+		SwsContext *img_convert_ctx = sws_getContext(info.width, info.height, AV_GET_CODEC_PIXEL_FORMAT(pStream, pCodecCtx), width,
+															  height, PIX_FMT_RGBA, SWS_BILINEAR, NULL, NULL, NULL);
 
 		// Resize / Convert to RGB
 		sws_scale(img_convert_ctx, my_frame->data, my_frame->linesize, 0,
@@ -925,20 +963,52 @@ void FFmpegReader::ProcessAudioPacket(int64_t requested_frame, int64_t target_fr
 
 	// re-initialize buffer size (it gets changed in the avcodec_decode_audio2 method call)
 	int buf_size = AVCODEC_MAX_AUDIO_FRAME_SIZE + FF_INPUT_BUFFER_PADDING_SIZE;
-	int used = avcodec_decode_audio4(aCodecCtx, audio_frame, &frame_finished, packet);
+	#pragma omp critical (ProcessAudioPacket)
+	{
+	#if IS_FFMPEG_3_2
+		int ret = 0;
+		frame_finished = 1;
+		while((packet->size > 0 || (!packet->data && frame_finished)) && ret >= 0) {
+			frame_finished = 0;
+			ret =  avcodec_send_packet(aCodecCtx, packet);
+			if (ret < 0 && ret !=  AVERROR(EINVAL) && ret != AVERROR_EOF) {
+				avcodec_send_packet(aCodecCtx, NULL);
+				break;
+			}
+			if (ret >= 0)
+				packet->size = 0;
+			ret =  avcodec_receive_frame(aCodecCtx, audio_frame);
+			if (ret >= 0)
+				frame_finished = 1;
+			if(ret == AVERROR(EINVAL) || ret == AVERROR_EOF) {
+				avcodec_flush_buffers(aCodecCtx);
+				ret = 0;
+			}
+			if (ret >= 0) {
+				ret = frame_finished;
+			}
+		}
+		if (!packet->data && !frame_finished)
+		{
+			ret = -1;
+		}
+	#else
+		int used = avcodec_decode_audio4(aCodecCtx, audio_frame, &frame_finished, packet);
+#endif
+	}
 
 	if (frame_finished) {
 
 		// determine how many samples were decoded
-		int planar = av_sample_fmt_is_planar(aCodecCtx->sample_fmt);
+		int planar = av_sample_fmt_is_planar((AVSampleFormat)AV_GET_CODEC_PIXEL_FORMAT(aStream, aCodecCtx));
 		int plane_size = -1;
 		data_size = av_samples_get_buffer_size(&plane_size,
-				aCodecCtx->channels,
+				AV_GET_CODEC_ATTRIBUTES(aStream, aCodecCtx)->channels,
 				audio_frame->nb_samples,
-				aCodecCtx->sample_fmt, 1);
+				(AVSampleFormat)(AV_GET_SAMPLE_FORMAT(aStream, aCodecCtx)), 1);
 
 		// Calculate total number of samples
-		packet_samples = audio_frame->nb_samples * aCodecCtx->channels;
+		packet_samples = audio_frame->nb_samples * AV_GET_CODEC_ATTRIBUTES(aStream, aCodecCtx)->channels;
 	}
 
 	// Estimate the # of samples and the end of this packet's location (to prevent GAPS for the next timestamp)
@@ -999,7 +1069,7 @@ void FFmpegReader::ProcessAudioPacket(int64_t requested_frame, int64_t target_fr
 	// Allocate audio buffer
 	int16_t *audio_buf = new int16_t[AVCODEC_MAX_AUDIO_FRAME_SIZE + FF_INPUT_BUFFER_PADDING_SIZE];
 
-	ZmqLogger::Instance()->AppendDebugMethod("FFmpegReader::ProcessAudioPacket (ReSample)", "packet_samples", packet_samples, "info.channels", info.channels, "info.sample_rate", info.sample_rate, "aCodecCtx->sample_fmt", aCodecCtx->sample_fmt, "AV_SAMPLE_FMT_S16", AV_SAMPLE_FMT_S16, "", -1);
+	ZmqLogger::Instance()->AppendDebugMethod("FFmpegReader::ProcessAudioPacket (ReSample)", "packet_samples", packet_samples, "info.channels", info.channels, "info.sample_rate", info.sample_rate, "aCodecCtx->sample_fmt", AV_GET_SAMPLE_FORMAT(aStream, aCodecCtx), "AV_SAMPLE_FMT_S16", AV_SAMPLE_FMT_S16, "", -1);
 
 	// Create output frame
 	AVFrame *audio_converted = AV_ALLOCATE_FRAME();
@@ -1012,9 +1082,9 @@ void FFmpegReader::ProcessAudioPacket(int64_t requested_frame, int64_t target_fr
 
 	// setup resample context
 	avr = avresample_alloc_context();
-	av_opt_set_int(avr,  "in_channel_layout", aCodecCtx->channel_layout, 0);
-	av_opt_set_int(avr, "out_channel_layout", aCodecCtx->channel_layout, 0);
-	av_opt_set_int(avr,  "in_sample_fmt",     aCodecCtx->sample_fmt,     0);
+	av_opt_set_int(avr,  "in_channel_layout", AV_GET_CODEC_ATTRIBUTES(aStream, aCodecCtx)->channel_layout, 0);
+	av_opt_set_int(avr, "out_channel_layout", AV_GET_CODEC_ATTRIBUTES(aStream, aCodecCtx)->channel_layout, 0);
+	av_opt_set_int(avr,  "in_sample_fmt",     AV_GET_SAMPLE_FORMAT(aStream, aCodecCtx), 0);
 	av_opt_set_int(avr, "out_sample_fmt",     AV_SAMPLE_FMT_S16,     0);
 	av_opt_set_int(avr,  "in_sample_rate",    info.sample_rate,    0);
 	av_opt_set_int(avr, "out_sample_rate",    info.sample_rate,    0);
@@ -1767,7 +1837,7 @@ void FFmpegReader::CheckWorkingFrames(bool end_of_stream, int64_t requested_fram
 void FFmpegReader::CheckFPS()
 {
 	check_fps = true;
-	avpicture_alloc(pFrame, pCodecCtx->pix_fmt, info.width, info.height);
+	AV_ALLOCATE_IMAGE(pFrame, AV_GET_CODEC_PIXEL_FORMAT(pStream, pCodecCtx), info.width, info.height);
 
 	int first_second_counter = 0;
 	int second_second_counter = 0;
@@ -1878,17 +1948,14 @@ void FFmpegReader::CheckFPS()
 }
 
 // Remove AVFrame from cache (and deallocate it's memory)
-void FFmpegReader::RemoveAVFrame(AVPicture* remove_frame)
+void FFmpegReader::RemoveAVFrame(AVFrame* remove_frame)
 {
     // Remove pFrame (if exists)
     if (remove_frame)
     {
         // Free memory
-        avpicture_free(remove_frame);
-
-        // Delete the object
-        delete remove_frame;
-    }
+		av_freep(&remove_frame->data[0]);
+	}
 }
 
 // Remove AVPacket from cache (and deallocate it's memory)
diff --git a/tests/FFmpegReader_Tests.cpp b/tests/FFmpegReader_Tests.cpp
index 54017e8..82e8573 100644
--- a/tests/FFmpegReader_Tests.cpp
+++ b/tests/FFmpegReader_Tests.cpp
@@ -72,8 +72,8 @@ TEST(FFmpegReader_Check_Audio_File)
 	CHECK_CLOSE(0.0f, samples[50], 0.00001);
 	CHECK_CLOSE(0.0f, samples[100], 0.00001);
 	CHECK_CLOSE(0.0f, samples[200], 0.00001);
-	CHECK_CLOSE(0.160781, samples[230], 0.00001);
-	CHECK_CLOSE(-0.06125f, samples[300], 0.00001);
+	CHECK_CLOSE(0.164062f, samples[230], 0.00001);
+	CHECK_CLOSE(-0.0625f, samples[300], 0.00001);
 
 	// Close reader
 	r.Close();
 
дизайн и разработка: Vladimir Lettiev aka crux © 2004-2005, Andrew Avramenko aka liks © 2007-2008
текущий майнтейнер: Michael Shigorin