decoder/ffmpeg: move code to class FfmpegBuffer
This commit is contained in:
		| @@ -799,6 +799,7 @@ endif | ||||
| if HAVE_FFMPEG | ||||
| noinst_LIBRARIES += libffmpeg.a | ||||
| libffmpeg_a_SOURCES = \ | ||||
| 	src/lib/ffmpeg/Buffer.hxx \ | ||||
| 	src/lib/ffmpeg/LogError.cxx src/lib/ffmpeg/LogError.hxx \ | ||||
| 	src/lib/ffmpeg/Error.cxx src/lib/ffmpeg/Error.hxx \ | ||||
| 	src/lib/ffmpeg/Domain.cxx src/lib/ffmpeg/Domain.hxx | ||||
|   | ||||
| @@ -24,6 +24,7 @@ | ||||
| #include "FfmpegDecoderPlugin.hxx" | ||||
| #include "lib/ffmpeg/Domain.hxx" | ||||
| #include "lib/ffmpeg/LogError.hxx" | ||||
| #include "lib/ffmpeg/Buffer.hxx" | ||||
| #include "../DecoderAPI.hxx" | ||||
| #include "FfmpegMetaData.hxx" | ||||
| #include "tag/TagHandler.hxx" | ||||
| @@ -281,7 +282,7 @@ static int | ||||
| copy_interleave_frame(const AVCodecContext &codec_context, | ||||
| 		      const AVFrame &frame, | ||||
| 		      uint8_t **output_buffer, | ||||
| 		      uint8_t **global_buffer, int *global_buffer_size) | ||||
| 		      FfmpegBuffer &global_buffer) | ||||
| { | ||||
| 	int plane_size; | ||||
| 	const int data_size = | ||||
| @@ -294,17 +295,11 @@ copy_interleave_frame(const AVCodecContext &codec_context, | ||||
|  | ||||
| 	if (av_sample_fmt_is_planar(codec_context.sample_fmt) && | ||||
| 	    codec_context.channels > 1) { | ||||
| 		if(*global_buffer_size < data_size) { | ||||
| 			av_freep(global_buffer); | ||||
| 		*output_buffer = global_buffer.GetT<uint8_t>(data_size); | ||||
| 		if (*output_buffer == nullptr) | ||||
| 			/* Not enough memory - shouldn't happen */ | ||||
| 			return AVERROR(ENOMEM); | ||||
|  | ||||
| 			*global_buffer = (uint8_t*)av_malloc(data_size); | ||||
|  | ||||
| 			if (!*global_buffer) | ||||
| 				/* Not enough memory - shouldn't happen */ | ||||
| 				return AVERROR(ENOMEM); | ||||
| 			*global_buffer_size = data_size; | ||||
| 		} | ||||
| 		*output_buffer = *global_buffer; | ||||
| 		copy_interleave_frame2(*output_buffer, frame.extended_data, | ||||
| 				       frame.nb_samples, | ||||
| 				       codec_context.channels, | ||||
| @@ -356,7 +351,7 @@ ffmpeg_send_packet(Decoder &decoder, InputStream &is, | ||||
| 		   const AVStream &stream, | ||||
| 		   AVFrame *frame, | ||||
| 		   uint64_t min_frame, size_t pcm_frame_size, | ||||
| 		   uint8_t **buffer, int *buffer_size) | ||||
| 		   FfmpegBuffer &buffer) | ||||
| { | ||||
| 	size_t skip_bytes = 0; | ||||
|  | ||||
| @@ -390,7 +385,7 @@ ffmpeg_send_packet(Decoder &decoder, InputStream &is, | ||||
| 			audio_size = copy_interleave_frame(codec_context, | ||||
| 							   *frame, | ||||
| 							   &output_buffer, | ||||
| 							   buffer, buffer_size); | ||||
| 							   buffer); | ||||
| 			if (audio_size < 0) { | ||||
| 				/* this must be a serious error, | ||||
| 				   e.g. OOM */ | ||||
| @@ -619,8 +614,7 @@ ffmpeg_decode(Decoder &decoder, InputStream &input) | ||||
| 		return; | ||||
| 	} | ||||
|  | ||||
| 	uint8_t *interleaved_buffer = nullptr; | ||||
| 	int interleaved_buffer_size = 0; | ||||
| 	FfmpegBuffer interleaved_buffer; | ||||
|  | ||||
| 	uint64_t min_frame = 0; | ||||
|  | ||||
| @@ -638,7 +632,7 @@ ffmpeg_decode(Decoder &decoder, InputStream &input) | ||||
| 						 *av_stream, | ||||
| 						 frame, | ||||
| 						 min_frame, audio_format.GetFrameSize(), | ||||
| 						 &interleaved_buffer, &interleaved_buffer_size); | ||||
| 						 interleaved_buffer); | ||||
| 			min_frame = 0; | ||||
| 		} else | ||||
| 			cmd = decoder_get_command(decoder); | ||||
| @@ -677,7 +671,6 @@ ffmpeg_decode(Decoder &decoder, InputStream &input) | ||||
| #else | ||||
| 	av_freep(&frame); | ||||
| #endif | ||||
| 	av_freep(&interleaved_buffer); | ||||
|  | ||||
| 	avcodec_close(codec_context); | ||||
| 	avformat_close_input(&format_context); | ||||
|   | ||||
							
								
								
									
										72
									
								
								src/lib/ffmpeg/Buffer.hxx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										72
									
								
								src/lib/ffmpeg/Buffer.hxx
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,72 @@ | ||||
| /* | ||||
|  * Copyright (C) 2003-2014 The Music Player Daemon Project | ||||
|  * http://www.musicpd.org | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  * the Free Software Foundation; either version 2 of the License, or | ||||
|  * (at your option) any later version. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License along | ||||
|  * with this program; if not, write to the Free Software Foundation, Inc., | ||||
|  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||||
|  */ | ||||
|  | ||||
| #ifndef MPD_FFMPEG_BUFFER_HXX | ||||
| #define MPD_FFMPEG_BUFFER_HXX | ||||
|  | ||||
| extern "C" { | ||||
| #include <libavutil/mem.h> | ||||
|  | ||||
| #if LIBAVUTIL_VERSION_INT >= AV_VERSION_INT(52, 18, 0) | ||||
| #define HAVE_AV_FAST_MALLOC | ||||
| #else | ||||
| #include <libavcodec/avcodec.h> | ||||
| #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(52, 25, 0) | ||||
| #define HAVE_AV_FAST_MALLOC | ||||
| #endif | ||||
| #endif | ||||
| } | ||||
|  | ||||
| #include <stddef.h> | ||||
|  | ||||
| /* suppress the ffmpeg compatibility macro */ | ||||
| #ifdef SampleFormat | ||||
| #undef SampleFormat | ||||
| #endif | ||||
|  | ||||
| class FfmpegBuffer { | ||||
| 	void *data; | ||||
| 	unsigned size; | ||||
|  | ||||
| public: | ||||
| 	FfmpegBuffer():data(nullptr), size(0) {} | ||||
|  | ||||
| 	~FfmpegBuffer() { | ||||
| 		av_free(data); | ||||
| 	} | ||||
|  | ||||
| 	void *Get(size_t min_size) { | ||||
| #ifdef HAVE_AV_FAST_MALLOC | ||||
| 		av_fast_malloc(&data, &size, min_size); | ||||
| #else | ||||
| 		void *new_data = av_fast_realloc(data, &size, min_size); | ||||
| 		if (new_data == nullptr) | ||||
| 			return AVERROR(ENOMEM); | ||||
| 		data = new_data; | ||||
| #endif | ||||
| 		return data; | ||||
| 	} | ||||
|  | ||||
| 	template<typename T> | ||||
| 	T *GetT(size_t n) { | ||||
| 		return (T *)Get(n * sizeof(T)); | ||||
| 	} | ||||
| }; | ||||
|  | ||||
| #endif | ||||
		Reference in New Issue
	
	Block a user
	 Max Kellermann
					Max Kellermann