[Bf-blender-cvs] [2b858b4] master: audaspace: use new libavcodec audio encoding API where available

Anton Khirnov noreply at git.blender.org
Tue Jan 28 09:28:46 CET 2014


Commit: 2b858b45c26b52cdbf80528b6445248adc8eb7f1
Author: Anton Khirnov
Date:   Sun Jan 26 13:22:26 2014 +0100
https://developer.blender.org/rB2b858b45c26b52cdbf80528b6445248adc8eb7f1

audaspace: use new libavcodec audio encoding API where available

===================================================================

M	intern/audaspace/ffmpeg/AUD_FFMPEGWriter.cpp
M	intern/audaspace/ffmpeg/AUD_FFMPEGWriter.h
M	intern/ffmpeg/ffmpeg_compat.h

===================================================================

diff --git a/intern/audaspace/ffmpeg/AUD_FFMPEGWriter.cpp b/intern/audaspace/ffmpeg/AUD_FFMPEGWriter.cpp
index d35b6d5..d8f0d83 100644
--- a/intern/audaspace/ffmpeg/AUD_FFMPEGWriter.cpp
+++ b/intern/audaspace/ffmpeg/AUD_FFMPEGWriter.cpp
@@ -183,6 +183,20 @@ AUD_FFMPEGWriter::AUD_FFMPEGWriter(std::string filename, AUD_DeviceSpecs specs,
 				m_input_size = m_codecCtx->frame_size;
 			}
 
+#ifdef FFMPEG_HAVE_ENCODE_AUDIO2
+			m_frame = av_frame_alloc();
+			if (!m_frame)
+				AUD_THROW(AUD_ERROR_FFMPEG, codec_error);
+			m_frame->linesize[0]    = m_input_size * samplesize;
+			m_frame->format         = m_codecCtx->sample_fmt;
+#  ifdef FFMPEG_HAVE_AVFRAME_SAMPLE_RATE
+			m_frame->sample_rate    = m_codecCtx->sample_rate;
+#  endif
+#  ifdef FFMPEG_HAVE_FRAME_CHANNEL_LAYOUT
+			m_frame->channel_layout = m_codecCtx->channel_layout;
+#  endif
+#endif
+
 			try
 			{
 				if(avio_open(&m_formatCtx->pb, filename.c_str(), AVIO_FLAG_WRITE))
@@ -229,6 +243,10 @@ AUD_FFMPEGWriter::~AUD_FFMPEGWriter()
 	av_freep(&m_formatCtx->streams[0]->codec);
 	av_freep(&m_formatCtx->streams[0]);
 
+#ifdef FFMPEG_HAVE_ENCODE_AUDIO2
+	av_frame_free(&m_frame);
+#endif
+
 	avio_close(m_formatCtx->pb);
 	av_free(m_formatCtx);
 }
@@ -245,20 +263,34 @@ AUD_DeviceSpecs AUD_FFMPEGWriter::getSpecs() const
 
 void AUD_FFMPEGWriter::encode(sample_t* data)
 {
-	sample_t* outbuf = m_output_buffer.getBuffer();
-
 	// convert first
 	if(m_input_size)
 		m_convert(reinterpret_cast<data_t*>(data), reinterpret_cast<data_t*>(data), m_input_size * m_specs.channels);
 
-	AVPacket packet;
+	AVPacket packet = { 0 };
 	av_init_packet(&packet);
+
+#ifdef FFMPEG_HAVE_ENCODE_AUDIO2
+	int got_output, ret;
+
+	m_frame->data[0] = reinterpret_cast<uint8_t*>(data);
+	ret = avcodec_encode_audio2(m_codecCtx, &packet, m_frame, &got_output);
+	if (ret < 0)
+		AUD_THROW(AUD_ERROR_FFMPEG, codec_error);
+
+	if (!got_output)
+		return;
+#else
+	sample_t* outbuf = m_output_buffer.getBuffer();
+
 	packet.size = avcodec_encode_audio(m_codecCtx, reinterpret_cast<uint8_t*>(outbuf), m_output_buffer.getSize(), reinterpret_cast<short*>(data));
 	if(m_codecCtx->coded_frame && m_codecCtx->coded_frame->pts != AV_NOPTS_VALUE)
 		packet.pts = av_rescale_q(m_codecCtx->coded_frame->pts, m_codecCtx->time_base, m_stream->time_base);
 	packet.flags |= AV_PKT_FLAG_KEY;
-	packet.stream_index = m_stream->index;
 	packet.data = reinterpret_cast<uint8_t*>(outbuf);
+#endif
+
+	packet.stream_index = m_stream->index;
 
 	if(av_interleaved_write_frame(m_formatCtx, &packet))
 		AUD_THROW(AUD_ERROR_FFMPEG, write_error);
diff --git a/intern/audaspace/ffmpeg/AUD_FFMPEGWriter.h b/intern/audaspace/ffmpeg/AUD_FFMPEGWriter.h
index 1783030..310f692 100644
--- a/intern/audaspace/ffmpeg/AUD_FFMPEGWriter.h
+++ b/intern/audaspace/ffmpeg/AUD_FFMPEGWriter.h
@@ -78,6 +78,11 @@ private:
 	AVStream* m_stream;
 
 	/**
+	 * Frame sent to the encoder.
+	 */
+	AVFrame *m_frame;
+
+	/**
 	 * The input buffer for the format converted data before encoding.
 	 */
 	AUD_Buffer m_input_buffer;
diff --git a/intern/ffmpeg/ffmpeg_compat.h b/intern/ffmpeg/ffmpeg_compat.h
index 91db329..58cf62a 100644
--- a/intern/ffmpeg/ffmpeg_compat.h
+++ b/intern/ffmpeg/ffmpeg_compat.h
@@ -90,6 +90,10 @@
 #define FFMPEG_HAVE_DECODE_AUDIO4
 #endif
 
+#if ((LIBAVCODEC_VERSION_MAJOR > 54) || (LIBAVCODEC_VERSION_MAJOR >= 54) && (LIBAVCODEC_VERSION_MINOR >= 13))
+#define FFMPEG_HAVE_AVFRAME_SAMPLE_RATE
+#endif
+
 #if ((LIBAVUTIL_VERSION_MAJOR > 51) || (LIBAVUTIL_VERSION_MAJOR == 51) && (LIBAVUTIL_VERSION_MINOR >= 21))
 #define FFMPEG_FFV1_ALPHA_SUPPORTED
 #define FFMPEG_SAMPLE_FMT_S16P_SUPPORTED
@@ -267,6 +271,10 @@ void avcodec_free_frame(AVFrame **frame)
 }
 #endif
 
+#if ((LIBAVCODEC_VERSION_MAJOR > 54) || (LIBAVCODEC_VERSION_MAJOR >= 54) && (LIBAVCODEC_VERSION_MINOR >= 13))
+#define FFMPEG_HAVE_AVFRAME_SAMPLE_RATE
+#endif
+
 #if ((LIBAVCODEC_VERSION_MAJOR > 54) || (LIBAVCODEC_VERSION_MAJOR == 54 && LIBAVCODEC_VERSION_MINOR >= 13))
 #define FFMPEG_HAVE_FRAME_CHANNEL_LAYOUT
 #endif
@@ -397,4 +405,18 @@ void avformat_close_input(AVFormatContext **ctx)
 }
 #endif
 
+#if LIBAVUTIL_VERSION_INT < AV_VERSION_INT(52, 8, 0)
+FFMPEG_INLINE
+AVFrame *av_frame_alloc(void)
+{
+    return avcodec_alloc_frame();
+}
+
+FFMPEG_INLINE
+void av_frame_free(AVFrame **frame)
+{
+    av_freep(frame);
+}
+#endif
+
 #endif




More information about the Bf-blender-cvs mailing list