Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Sharybin <sergey.vfx@gmail.com>2014-02-28 13:15:04 +0400
committerSergey Sharybin <sergey.vfx@gmail.com>2014-02-28 13:16:30 +0400
commit5ac1b38b4b21959b552c0787e2f86a104624c615 (patch)
treec3cc7a4896deaaa89067d7d960aa187dc321a095 /intern/audaspace
parent1e05956a0bbba43b5a91068447ec7ceae755a34c (diff)
Support planar sample formats in audio mixdown
Now libav-10 should work for output of ac3 container.
Diffstat (limited to 'intern/audaspace')
-rw-r--r--intern/audaspace/ffmpeg/AUD_FFMPEGWriter.cpp29
-rw-r--r--intern/audaspace/ffmpeg/AUD_FFMPEGWriter.h9
2 files changed, 36 insertions, 2 deletions
diff --git a/intern/audaspace/ffmpeg/AUD_FFMPEGWriter.cpp b/intern/audaspace/ffmpeg/AUD_FFMPEGWriter.cpp
index dcacf71a2d3..d30835da4e5 100644
--- a/intern/audaspace/ffmpeg/AUD_FFMPEGWriter.cpp
+++ b/intern/audaspace/ffmpeg/AUD_FFMPEGWriter.cpp
@@ -169,6 +169,19 @@ AUD_FFMPEGWriter::AUD_FFMPEGWriter(std::string filename, AUD_DeviceSpecs specs,
if(!codec)
AUD_THROW(AUD_ERROR_FFMPEG, codec_error);
+ if(codec->sample_fmts) {
+ // Check if the prefered sample format for this codec is supported.
+ const enum AVSampleFormat *p = codec->sample_fmts;
+ for(; *p != -1; p++) {
+ if(*p == m_stream->codec->sample_fmt)
+ break;
+ }
+ if(*p == -1) {
+ // Sample format incompatible with codec. Defaulting to a format known to work.
+ m_stream->codec->sample_fmt = codec->sample_fmts[0];
+ }
+ }
+
if(avcodec_open2(m_codecCtx, codec, NULL))
AUD_THROW(AUD_ERROR_FFMPEG, codec_error);
@@ -199,8 +212,11 @@ AUD_FFMPEGWriter::AUD_FFMPEGWriter(std::string filename, AUD_DeviceSpecs specs,
# ifdef FFMPEG_HAVE_FRAME_CHANNEL_LAYOUT
m_frame->channel_layout = m_codecCtx->channel_layout;
# endif
- m_audio_sample_size = av_get_bytes_per_sample(m_codecCtx->sample_fmt);
+ m_sample_size = av_get_bytes_per_sample(m_codecCtx->sample_fmt);
m_frame_pts = 0;
+ m_deinterleave = av_sample_fmt_is_planar(m_codecCtx->sample_fmt);
+ if(m_deinterleave)
+ m_deinterleave_buffer.resize(m_input_size * m_codecCtx->channels * m_sample_size);
#endif
try
@@ -284,6 +300,17 @@ void AUD_FFMPEGWriter::encode(sample_t* data)
m_frame->channel_layout = m_codecCtx->channel_layout;
#endif
+ if(m_deinterleave) {
+ for(int channel = 0; channel < m_codecCtx->channels; channel++) {
+ for(int i = 0; i < m_frame->nb_samples; i++) {
+ memcpy(reinterpret_cast<uint8_t*>(m_deinterleave_buffer.getBuffer()) + (i + channel * m_frame->nb_samples) * m_sample_size,
+ reinterpret_cast<uint8_t*>(data) + (m_codecCtx->channels * i + channel) * m_sample_size, m_sample_size);
+ }
+ }
+
+ data = m_deinterleave_buffer.getBuffer();
+ }
+
avcodec_fill_audio_frame(m_frame, m_codecCtx->channels, m_codecCtx->sample_fmt, reinterpret_cast<uint8_t*>(data),
m_frame->nb_samples * av_get_bytes_per_sample(m_codecCtx->sample_fmt) * m_codecCtx->channels, 1);
diff --git a/intern/audaspace/ffmpeg/AUD_FFMPEGWriter.h b/intern/audaspace/ffmpeg/AUD_FFMPEGWriter.h
index 743d885fca8..492aa35ff12 100644
--- a/intern/audaspace/ffmpeg/AUD_FFMPEGWriter.h
+++ b/intern/audaspace/ffmpeg/AUD_FFMPEGWriter.h
@@ -90,7 +90,14 @@ private:
/**
* Number of bytes per sample.
*/
- int m_audio_sample_size;
+ int m_sample_size;
+
+ /**
+ * Need to de-interleave audio for planar sample formats.
+ */
+ bool m_deinterleave;
+
+ AUD_Buffer m_deinterleave_buffer;
/**
* The input buffer for the format converted data before encoding.