diff options
-rw-r--r-- | media/base/decoder_buffer.cc | 12 | ||||
-rw-r--r-- | media/base/decoder_buffer.h | 10 | ||||
-rw-r--r-- | media/base/decoder_buffer_unittest.cc | 24 | ||||
-rw-r--r-- | media/ffmpeg/ffmpeg_common.cc | 21 |
4 files changed, 42 insertions, 25 deletions
diff --git a/media/base/decoder_buffer.cc b/media/base/decoder_buffer.cc index 527fb65..3c298a4 100644 --- a/media/base/decoder_buffer.cc +++ b/media/base/decoder_buffer.cc @@ -6,8 +6,9 @@ #include "base/logging.h" #include "media/base/decrypt_config.h" + #if !defined(OS_ANDROID) -#include "media/ffmpeg/ffmpeg_common.h" +#include "base/memory/aligned_memory.h" #endif namespace media { @@ -34,7 +35,7 @@ DecoderBuffer::DecoderBuffer(const uint8* data, int buffer_size) DecoderBuffer::~DecoderBuffer() { #if !defined(OS_ANDROID) - av_free(data_); + base::AlignedFree(data_); #else delete[] data_; #endif @@ -43,12 +44,9 @@ DecoderBuffer::~DecoderBuffer() { void DecoderBuffer::Initialize() { DCHECK_GE(buffer_size_, 0); #if !defined(OS_ANDROID) - // Why FF_INPUT_BUFFER_PADDING_SIZE? FFmpeg assumes all input buffers are - // padded. Using av_malloc with padding ensures FFmpeg only recieves data - // padded and aligned to its specifications. data_ = reinterpret_cast<uint8*>( - av_malloc(buffer_size_ + FF_INPUT_BUFFER_PADDING_SIZE)); - memset(data_ + buffer_size_, 0, FF_INPUT_BUFFER_PADDING_SIZE); + base::AlignedAlloc(buffer_size_ + kPaddingSize, kAlignmentSize)); + memset(data_ + buffer_size_, 0, kPaddingSize); #else data_ = new uint8[buffer_size_]; #endif diff --git a/media/base/decoder_buffer.h b/media/base/decoder_buffer.h index e822de5..d0c57ce 100644 --- a/media/base/decoder_buffer.h +++ b/media/base/decoder_buffer.h @@ -14,6 +14,7 @@ #define MEDIA_BASE_DECODER_BUFFER_H_ #include "base/memory/scoped_ptr.h" +#include "build/build_config.h" #include "media/base/buffers.h" #include "media/base/decrypt_config.h" @@ -21,6 +22,15 @@ namespace media { class MEDIA_EXPORT DecoderBuffer : public Buffer { public: + enum { + kPaddingSize = 16, +#if defined(ARCH_CPU_ARM_FAMILY) + kAlignmentSize = 16 +#else + kAlignmentSize = 32 +#endif + }; + // Allocates buffer of size |buffer_size| >= 0. Buffer will be padded and // aligned as necessary. explicit DecoderBuffer(int buffer_size); diff --git a/media/base/decoder_buffer_unittest.cc b/media/base/decoder_buffer_unittest.cc index f7ec578..65a14b6 100644 --- a/media/base/decoder_buffer_unittest.cc +++ b/media/base/decoder_buffer_unittest.cc @@ -4,10 +4,6 @@ #include "base/string_util.h" #include "media/base/decoder_buffer.h" -#if !defined(OS_ANDROID) -#include "media/ffmpeg/ffmpeg_common.h" -#endif - #include "testing/gtest/include/gtest/gtest.h" namespace media { @@ -51,30 +47,22 @@ TEST(DecoderBufferTest, PaddingAlignment) { reinterpret_cast<const uint8*>(&kData), kDataSize)); ASSERT_TRUE(buffer2); - // FFmpeg padding data should always be zeroed. - for(int i = 0; i < FF_INPUT_BUFFER_PADDING_SIZE; i++) + // Padding data should always be zeroed. + for(int i = 0; i < DecoderBuffer::kPaddingSize; i++) EXPECT_EQ((buffer2->GetData() + kDataSize)[i], 0); // If the data is padded correctly we should be able to read and write past - // the end of the data by FF_INPUT_BUFFER_PADDING_SIZE bytes without crashing + // the end of the data by DecoderBuffer::kPaddingSize bytes without crashing // or Valgrind/ASAN throwing errors. const uint8 kFillChar = 0xFF; memset( buffer2->GetWritableData() + kDataSize, kFillChar, - FF_INPUT_BUFFER_PADDING_SIZE); - for(int i = 0; i < FF_INPUT_BUFFER_PADDING_SIZE; i++) + DecoderBuffer::kPaddingSize); + for(int i = 0; i < DecoderBuffer::kPaddingSize; i++) EXPECT_EQ((buffer2->GetData() + kDataSize)[i], kFillChar); - // These alignments will need to be updated to match FFmpeg when it changes. -#if defined(ARCH_CPU_ARM_FAMILY) - // FFmpeg data should be aligned on a 16 byte boundary for ARM. - const int kDataAlignment = 16; -#else - // FFmpeg data should be aligned on a 32 byte boundary for x86. - const int kDataAlignment = 32; -#endif EXPECT_EQ(0u, reinterpret_cast<uintptr_t>( - buffer2->GetData()) & (kDataAlignment - 1)); + buffer2->GetData()) & (DecoderBuffer::kAlignmentSize - 1)); } #endif diff --git a/media/ffmpeg/ffmpeg_common.cc b/media/ffmpeg/ffmpeg_common.cc index b6690cb..00d91f5 100644 --- a/media/ffmpeg/ffmpeg_common.cc +++ b/media/ffmpeg/ffmpeg_common.cc @@ -4,11 +4,32 @@ #include "media/ffmpeg/ffmpeg_common.h" +#include "base/basictypes.h" #include "base/logging.h" +#include "media/base/decoder_buffer.h" #include "media/base/video_util.h" namespace media { +// Why FF_INPUT_BUFFER_PADDING_SIZE? FFmpeg assumes all input buffers are +// padded. Check here to ensure FFmpeg only receives data padded to its +// specifications. +COMPILE_ASSERT(DecoderBuffer::kPaddingSize >= FF_INPUT_BUFFER_PADDING_SIZE, + decoder_buffer_padding_size_does_not_fit_ffmpeg_requirement); + +// Alignment requirement by FFmpeg for input buffers. This need to be updated +// to match FFmpeg when it changes. +#if defined(ARCH_CPU_ARM_FAMILY) +static const int kFFmpegInputBufferAlignmentSize = 16; +#else +static const int kFFmpegInputBufferAlignmentSize = 32; +#endif +// Check here to ensure FFmpeg only receives data aligned to its specifications. +COMPILE_ASSERT( + DecoderBuffer::kAlignmentSize >= kFFmpegInputBufferAlignmentSize && + DecoderBuffer::kAlignmentSize % kFFmpegInputBufferAlignmentSize == 0, + decoder_buffer_alignment_size_does_not_fit_ffmpeg_requirement); + static const AVRational kMicrosBase = { 1, base::Time::kMicrosecondsPerSecond }; base::TimeDelta ConvertFromTimeBase(const AVRational& time_base, |