summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjrummell <jrummell@chromium.org>2015-11-24 19:10:10 -0800
committerCommit bot <commit-bot@chromium.org>2015-11-25 03:11:56 +0000
commite45d9fa36a51ed750b71b7543563960962d44a90 (patch)
treec330c2834fa2ded7df01e5fd4d1ab9ebc742acf3
parentc321986254c6b5cc4ce919131894b4f67d45f7d3 (diff)
downloadchromium_src-e45d9fa36a51ed750b71b7543563960962d44a90.zip
chromium_src-e45d9fa36a51ed750b71b7543563960962d44a90.tar.gz
chromium_src-e45d9fa36a51ed750b71b7543563960962d44a90.tar.bz2
Define AudioBuffer and VideoFrame for mojo
Adds support so they can be converted to and from the matching classes in media:: BUG=510088 TEST=new tests pass Review URL: https://codereview.chromium.org/1468153003 Cr-Commit-Position: refs/heads/master@{#361530}
-rw-r--r--media/base/audio_buffer.cc32
-rw-r--r--media/base/audio_buffer.h17
-rw-r--r--media/base/sample_format.cc36
-rw-r--r--media/base/sample_format.h6
-rw-r--r--media/mojo/interfaces/decryptor.mojom4
-rw-r--r--media/mojo/interfaces/media_types.mojom55
-rw-r--r--media/mojo/services/BUILD.gn2
-rw-r--r--media/mojo/services/media_type_converters.cc122
-rw-r--r--media/mojo/services/media_type_converters.h28
-rw-r--r--media/mojo/services/media_type_converters_unittest.cc157
10 files changed, 438 insertions, 21 deletions
diff --git a/media/base/audio_buffer.cc b/media/base/audio_buffer.cc
index 564cff15..a497640 100644
--- a/media/base/audio_buffer.cc
+++ b/media/base/audio_buffer.cc
@@ -37,7 +37,8 @@ AudioBuffer::AudioBuffer(SampleFormat sample_format,
timestamp_(timestamp),
duration_(end_of_stream_
? base::TimeDelta()
- : CalculateDuration(adjusted_frame_count_, sample_rate_)) {
+ : CalculateDuration(adjusted_frame_count_, sample_rate_)),
+ data_size_(0) {
CHECK_GE(channel_count_, 0);
CHECK_LE(channel_count_, limits::kMaxChannels);
CHECK_GE(frame_count, 0);
@@ -46,49 +47,46 @@ AudioBuffer::AudioBuffer(SampleFormat sample_format,
int bytes_per_channel = SampleFormatToBytesPerChannel(sample_format);
DCHECK_LE(bytes_per_channel, kChannelAlignment);
- int data_size = frame_count * bytes_per_channel;
// Empty buffer?
if (!create_buffer)
return;
- if (sample_format == kSampleFormatPlanarF32 ||
- sample_format == kSampleFormatPlanarS16 ||
- sample_format == kSampleFormatPlanarS32) {
+ int data_size_per_channel = frame_count * bytes_per_channel;
+ if (IsPlanar(sample_format)) {
// Planar data, so need to allocate buffer for each channel.
// Determine per channel data size, taking into account alignment.
int block_size_per_channel =
- (data_size + kChannelAlignment - 1) & ~(kChannelAlignment - 1);
- DCHECK_GE(block_size_per_channel, data_size);
+ (data_size_per_channel + kChannelAlignment - 1) &
+ ~(kChannelAlignment - 1);
+ DCHECK_GE(block_size_per_channel, data_size_per_channel);
// Allocate a contiguous buffer for all the channel data.
- data_.reset(static_cast<uint8*>(base::AlignedAlloc(
- channel_count_ * block_size_per_channel, kChannelAlignment)));
+ data_size_ = channel_count_ * block_size_per_channel;
+ data_.reset(
+ static_cast<uint8*>(base::AlignedAlloc(data_size_, kChannelAlignment)));
channel_data_.reserve(channel_count_);
// Copy each channel's data into the appropriate spot.
for (int i = 0; i < channel_count_; ++i) {
channel_data_.push_back(data_.get() + i * block_size_per_channel);
if (data)
- memcpy(channel_data_[i], data[i], data_size);
+ memcpy(channel_data_[i], data[i], data_size_per_channel);
}
return;
}
// Remaining formats are interleaved data.
- DCHECK(sample_format_ == kSampleFormatU8 ||
- sample_format_ == kSampleFormatS16 ||
- sample_format_ == kSampleFormatS32 ||
- sample_format_ == kSampleFormatF32) << sample_format_;
+ DCHECK(IsInterleaved(sample_format)) << sample_format_;
// Allocate our own buffer and copy the supplied data into it. Buffer must
// contain the data for all channels.
- data_size *= channel_count_;
+ data_size_ = data_size_per_channel * channel_count_;
data_.reset(
- static_cast<uint8*>(base::AlignedAlloc(data_size, kChannelAlignment)));
+ static_cast<uint8*>(base::AlignedAlloc(data_size_, kChannelAlignment)));
channel_data_.reserve(1);
channel_data_.push_back(data_.get());
if (data)
- memcpy(data_.get(), data[0], data_size);
+ memcpy(data_.get(), data[0], data_size_);
}
AudioBuffer::~AudioBuffer() {}
diff --git a/media/base/audio_buffer.h b/media/base/audio_buffer.h
index 63390d4..bf8e433 100644
--- a/media/base/audio_buffer.h
+++ b/media/base/audio_buffer.h
@@ -15,9 +15,20 @@
#include "media/base/media_export.h"
#include "media/base/sample_format.h"
+namespace mojo {
+template <typename T, typename U>
+struct TypeConverter;
+template <typename T>
+class StructPtr;
+};
+
namespace media {
class AudioBus;
+namespace interfaces {
+class AudioBuffer;
+}
+
// An audio buffer that takes a copy of the data passed to it, holds it, and
// copies it into an AudioBus when needed. Also supports an end of stream
// marker.
@@ -123,6 +134,11 @@ class MEDIA_EXPORT AudioBuffer
private:
friend class base::RefCountedThreadSafe<AudioBuffer>;
+ // mojo::TypeConverter added as a friend so that AudioBuffer can be
+ // transferred across a mojo connection.
+ friend struct mojo::TypeConverter<mojo::StructPtr<interfaces::AudioBuffer>,
+ scoped_refptr<AudioBuffer>>;
+
// Allocates aligned contiguous buffer to hold all channel data (1 block for
// interleaved data, |channel_count| blocks for planar data), copies
// [data,data+data_size) to the allocated buffer(s). If |data| is null, no
@@ -151,6 +167,7 @@ class MEDIA_EXPORT AudioBuffer
// Contiguous block of channel data.
scoped_ptr<uint8, base::AlignedFreeDeleter> data_;
+ size_t data_size_;
// For planar data, points to each channels data.
std::vector<uint8*> channel_data_;
diff --git a/media/base/sample_format.cc b/media/base/sample_format.cc
index 464fc1b..dd0bc1d 100644
--- a/media/base/sample_format.cc
+++ b/media/base/sample_format.cc
@@ -51,4 +51,40 @@ const char* SampleFormatToString(SampleFormat sample_format) {
return "";
}
+bool IsPlanar(SampleFormat sample_format) {
+ switch (sample_format) {
+ case kSampleFormatPlanarS16:
+ case kSampleFormatPlanarF32:
+ case kSampleFormatPlanarS32:
+ return true;
+ case kUnknownSampleFormat:
+ case kSampleFormatU8:
+ case kSampleFormatS16:
+ case kSampleFormatS32:
+ case kSampleFormatF32:
+ return false;
+ }
+
+ NOTREACHED() << "Invalid sample format provided: " << sample_format;
+ return false;
+}
+
+bool IsInterleaved(SampleFormat sample_format) {
+ switch (sample_format) {
+ case kSampleFormatU8:
+ case kSampleFormatS16:
+ case kSampleFormatS32:
+ case kSampleFormatF32:
+ return true;
+ case kUnknownSampleFormat:
+ case kSampleFormatPlanarS16:
+ case kSampleFormatPlanarF32:
+ case kSampleFormatPlanarS32:
+ return false;
+ }
+
+ NOTREACHED() << "Invalid sample format provided: " << sample_format;
+ return false;
+}
+
} // namespace media
diff --git a/media/base/sample_format.h b/media/base/sample_format.h
index 7a48843..0260f169 100644
--- a/media/base/sample_format.h
+++ b/media/base/sample_format.h
@@ -34,6 +34,12 @@ MEDIA_EXPORT int SampleFormatToBytesPerChannel(SampleFormat sample_format);
// Returns the name of the sample format as a string
MEDIA_EXPORT const char* SampleFormatToString(SampleFormat sample_format);
+// Returns true if |sample_format| is planar, false otherwise.
+MEDIA_EXPORT bool IsPlanar(SampleFormat sample_format);
+
+// Returns true if |sample_format| is interleaved, false otherwise.
+MEDIA_EXPORT bool IsInterleaved(SampleFormat sample_format);
+
} // namespace media
#endif // MEDIA_BASE_SAMPLE_FORMAT_H
diff --git a/media/mojo/interfaces/decryptor.mojom b/media/mojo/interfaces/decryptor.mojom
index 9c5d678..e25df3e 100644
--- a/media/mojo/interfaces/decryptor.mojom
+++ b/media/mojo/interfaces/decryptor.mojom
@@ -7,10 +7,6 @@ module media.interfaces;
import "media/mojo/interfaces/demuxer_stream.mojom";
import "media/mojo/interfaces/media_types.mojom";
-// TODO(xhwang): Add mojo types for AudioBuffer and VideoFrame.
-struct AudioBuffer {};
-struct VideoFrame {};
-
// Interface for decrypting (and decoding) encrypted streams.
// See media/base/decryptor.h for details.
interface Decryptor {
diff --git a/media/mojo/interfaces/media_types.mojom b/media/mojo/interfaces/media_types.mojom
index a16203e..78784f9 100644
--- a/media/mojo/interfaces/media_types.mojom
+++ b/media/mojo/interfaces/media_types.mojom
@@ -231,3 +231,58 @@ struct DecoderBuffer {
// Indicates this buffer is part of a splice around |splice_timestamp_usec|.
int64 splice_timestamp_usec;
};
+
+// This defines a mojo transport format for media::AudioBuffer.
+struct AudioBuffer {
+ // Format of the audio.
+ SampleFormat sample_format;
+
+ // How the channels are laid out.
+ ChannelLayout channel_layout;
+
+ // Number of channels.
+ int32 channel_count;
+
+ // Sample rate of the buffer.
+ int32 sample_rate;
+
+ // Number of frames in the buffer.
+ int32 frame_count;
+
+ // True if end of stream.
+ bool end_of_stream;
+
+ // Timestamp in microseconds of the first frame.
+ int64 timestamp_usec;
+
+ // Channel data. Will be null for EOS buffers.
+ array<uint8>? data;
+};
+
+// This defines a mojo transport format for media::VideoFrame.
+// TODO(jrummell): Support shared memory based VideoFrame to avoid copying
+// the data multiple times.
+struct VideoFrame {
+ // Format of the frame.
+ VideoFormat format;
+
+ // Width and height of the video frame, in pixels.
+ mojo.Size coded_size;
+
+ // Visible size of the frame.
+ mojo.Rect visible_rect;
+
+ // Natural size of the frame.
+ mojo.Size natural_size;
+
+ // True if end of stream.
+ bool end_of_stream;
+
+ // Timestamp in microseconds of the associated frame.
+ int64 timestamp_usec;
+
+ // Frame data for each plane. Will be null for EOS buffers.
+ array<uint8>? y_data;
+ array<uint8>? u_data;
+ array<uint8>? v_data;
+};
diff --git a/media/mojo/services/BUILD.gn b/media/mojo/services/BUILD.gn
index 24fcdfc..23690f80 100644
--- a/media/mojo/services/BUILD.gn
+++ b/media/mojo/services/BUILD.gn
@@ -183,8 +183,10 @@ test("media_mojo_unittests") {
"//base",
"//base/test:test_support",
"//media",
+ "//media/base:test_support",
"//media/mojo/interfaces",
"//mojo/environment:chromium",
+ "//testing/gmock",
"//testing/gtest",
"//third_party/mojo/src/mojo/edk/system",
"//third_party/mojo/src/mojo/edk/test:run_all_unittests",
diff --git a/media/mojo/services/media_type_converters.cc b/media/mojo/services/media_type_converters.cc
index 5f84a49..ae2c7e2 100644
--- a/media/mojo/services/media_type_converters.cc
+++ b/media/mojo/services/media_type_converters.cc
@@ -4,6 +4,7 @@
#include "media/mojo/services/media_type_converters.h"
+#include "media/base/audio_buffer.h"
#include "media/base/audio_decoder_config.h"
#include "media/base/buffering_state.h"
#include "media/base/cdm_config.h"
@@ -13,6 +14,7 @@
#include "media/base/demuxer_stream.h"
#include "media/base/media_keys.h"
#include "media/base/video_decoder_config.h"
+#include "media/base/video_frame.h"
#include "media/mojo/interfaces/demuxer_stream.mojom.h"
#include "mojo/converters/geometry/geometry_type_converters.h"
@@ -529,4 +531,124 @@ TypeConverter<media::CdmConfig, media::interfaces::CdmConfigPtr>::Convert(
return config;
}
+// static
+media::interfaces::AudioBufferPtr
+TypeConverter<media::interfaces::AudioBufferPtr,
+ scoped_refptr<media::AudioBuffer>>::
+ Convert(const scoped_refptr<media::AudioBuffer>& input) {
+ media::interfaces::AudioBufferPtr buffer(
+ media::interfaces::AudioBuffer::New());
+ buffer->sample_format =
+ static_cast<media::interfaces::SampleFormat>(input->sample_format_);
+ buffer->channel_layout =
+ static_cast<media::interfaces::ChannelLayout>(input->channel_layout());
+ buffer->channel_count = input->channel_count();
+ buffer->sample_rate = input->sample_rate();
+ buffer->frame_count = input->frame_count();
+ buffer->end_of_stream = input->end_of_stream();
+ buffer->timestamp_usec = input->timestamp().InMicroseconds();
+
+ if (!input->end_of_stream()) {
+ std::vector<uint8_t> input_data(input->data_.get(),
+ input->data_.get() + input->data_size_);
+ buffer->data.Swap(&input_data);
+ }
+
+ return buffer.Pass();
+}
+
+// static
+scoped_refptr<media::AudioBuffer>
+TypeConverter<scoped_refptr<media::AudioBuffer>,
+ media::interfaces::AudioBufferPtr>::
+ Convert(const media::interfaces::AudioBufferPtr& input) {
+ if (input->end_of_stream)
+ return media::AudioBuffer::CreateEOSBuffer();
+
+ // Setup channel pointers. AudioBuffer::CopyFrom() will only use the first
+ // one in the case of interleaved data.
+ std::vector<const uint8_t*> channel_ptrs(input->channel_count, nullptr);
+ std::vector<uint8_t> storage = input->data.storage();
+ const int size_per_channel = storage.size() / input->channel_count;
+ DCHECK_EQ(0u, storage.size() % input->channel_count);
+ for (int i = 0; i < input->channel_count; ++i)
+ channel_ptrs[i] = storage.data() + i * size_per_channel;
+
+ return media::AudioBuffer::CopyFrom(
+ static_cast<media::SampleFormat>(input->sample_format),
+ static_cast<media::ChannelLayout>(input->channel_layout),
+ input->channel_count, input->sample_rate, input->frame_count,
+ &channel_ptrs[0],
+ base::TimeDelta::FromMicroseconds(input->timestamp_usec));
+}
+
+// static
+media::interfaces::VideoFramePtr
+TypeConverter<media::interfaces::VideoFramePtr,
+ scoped_refptr<media::VideoFrame>>::
+ Convert(const scoped_refptr<media::VideoFrame>& input) {
+ media::interfaces::VideoFramePtr buffer(media::interfaces::VideoFrame::New());
+ buffer->end_of_stream =
+ input->metadata()->IsTrue(media::VideoFrameMetadata::END_OF_STREAM);
+ if (buffer->end_of_stream)
+ return buffer.Pass();
+
+ // handle non EOS buffer.
+ buffer->format = static_cast<media::interfaces::VideoFormat>(input->format());
+ buffer->coded_size = Size::From(input->coded_size());
+ buffer->visible_rect = Rect::From(input->visible_rect());
+ buffer->natural_size = Size::From(input->natural_size());
+ buffer->timestamp_usec = input->timestamp().InMicroseconds();
+
+ if (!input->coded_size().IsEmpty()) {
+ // TODO(jrummell): Use a shared buffer rather than copying the data for
+ // each plane.
+ std::vector<uint8_t> y_data(
+ input->data(media::VideoFrame::kYPlane),
+ input->data(media::VideoFrame::kYPlane) +
+ input->rows(media::VideoFrame::kYPlane) *
+ input->stride(media::VideoFrame::kYPlane));
+ buffer->y_data.Swap(&y_data);
+
+ std::vector<uint8_t> u_data(
+ input->data(media::VideoFrame::kUPlane),
+ input->data(media::VideoFrame::kUPlane) +
+ input->rows(media::VideoFrame::kUPlane) *
+ input->stride(media::VideoFrame::kUPlane));
+ buffer->u_data.Swap(&u_data);
+
+ std::vector<uint8_t> v_data(
+ input->data(media::VideoFrame::kVPlane),
+ input->data(media::VideoFrame::kVPlane) +
+ input->rows(media::VideoFrame::kVPlane) *
+ input->stride(media::VideoFrame::kVPlane));
+ buffer->v_data.Swap(&v_data);
+ }
+
+ return buffer.Pass();
+}
+
+// static
+scoped_refptr<media::VideoFrame>
+TypeConverter<scoped_refptr<media::VideoFrame>,
+ media::interfaces::VideoFramePtr>::
+ Convert(const media::interfaces::VideoFramePtr& input) {
+ if (input->end_of_stream)
+ return media::VideoFrame::CreateEOSFrame();
+
+ scoped_refptr<media::VideoFrame> frame = media::VideoFrame::CreateFrame(
+ static_cast<media::VideoPixelFormat>(input->format),
+ input->coded_size.To<gfx::Size>(), input->visible_rect.To<gfx::Rect>(),
+ input->natural_size.To<gfx::Size>(),
+ base::TimeDelta::FromMicroseconds(input->timestamp_usec));
+ memcpy(frame->data(media::VideoFrame::kYPlane),
+ input->y_data.storage().data(), input->y_data.storage().size());
+ memcpy(frame->data(media::VideoFrame::kUPlane),
+ input->u_data.storage().data(), input->u_data.storage().size());
+ memcpy(frame->data(media::VideoFrame::kVPlane),
+ input->v_data.storage().data(), input->v_data.storage().size());
+
+ return frame.Pass();
+}
+
} // namespace mojo
diff --git a/media/mojo/services/media_type_converters.h b/media/mojo/services/media_type_converters.h
index 0133a99..92450c8 100644
--- a/media/mojo/services/media_type_converters.h
+++ b/media/mojo/services/media_type_converters.h
@@ -12,10 +12,12 @@
#include "mojo/public/cpp/bindings/type_converter.h"
namespace media {
+class AudioBuffer;
class AudioDecoderConfig;
class DecoderBuffer;
class DecryptConfig;
class VideoDecoderConfig;
+class VideoFrame;
struct CdmConfig;
struct CdmKeyInformation;
struct SubsampleEntry;
@@ -112,6 +114,32 @@ struct TypeConverter<media::CdmConfig, media::interfaces::CdmConfigPtr> {
static media::CdmConfig Convert(const media::interfaces::CdmConfigPtr& input);
};
+template <>
+struct TypeConverter<media::interfaces::AudioBufferPtr,
+ scoped_refptr<media::AudioBuffer>> {
+ static media::interfaces::AudioBufferPtr Convert(
+ const scoped_refptr<media::AudioBuffer>& input);
+};
+template <>
+struct TypeConverter<scoped_refptr<media::AudioBuffer>,
+ media::interfaces::AudioBufferPtr> {
+ static scoped_refptr<media::AudioBuffer> Convert(
+ const media::interfaces::AudioBufferPtr& input);
+};
+
+template <>
+struct TypeConverter<media::interfaces::VideoFramePtr,
+ scoped_refptr<media::VideoFrame>> {
+ static media::interfaces::VideoFramePtr Convert(
+ const scoped_refptr<media::VideoFrame>& input);
+};
+template <>
+struct TypeConverter<scoped_refptr<media::VideoFrame>,
+ media::interfaces::VideoFramePtr> {
+ static scoped_refptr<media::VideoFrame> Convert(
+ const media::interfaces::VideoFramePtr& input);
+};
+
} // namespace mojo
#endif // MEDIA_MOJO_SERVICES_MEDIA_TYPE_CONVERTERS_H_
diff --git a/media/mojo/services/media_type_converters_unittest.cc b/media/mojo/services/media_type_converters_unittest.cc
index 38559f3..dae82d4 100644
--- a/media/mojo/services/media_type_converters_unittest.cc
+++ b/media/mojo/services/media_type_converters_unittest.cc
@@ -4,14 +4,87 @@
#include "media/mojo/services/media_type_converters.h"
+#include <string.h>
+
+#include "media/base/audio_buffer.h"
#include "media/base/audio_decoder_config.h"
#include "media/base/cdm_config.h"
#include "media/base/decoder_buffer.h"
#include "media/base/media_util.h"
+#include "media/base/sample_format.h"
+#include "media/base/test_helpers.h"
+#include "media/base/video_frame.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace media {
+namespace {
+
+void CompareBytes(uint8* original_data, uint8* result_data, size_t length) {
+ EXPECT_GT(length, 0u);
+ EXPECT_EQ(memcmp(original_data, result_data, length), 0);
+}
+
+void CompareAudioBuffers(SampleFormat sample_format,
+ const scoped_refptr<AudioBuffer>& original,
+ const scoped_refptr<AudioBuffer>& result) {
+ EXPECT_EQ(original->frame_count(), result->frame_count());
+ EXPECT_EQ(original->timestamp(), result->timestamp());
+ EXPECT_EQ(original->duration(), result->duration());
+ EXPECT_EQ(original->sample_rate(), result->sample_rate());
+ EXPECT_EQ(original->channel_count(), result->channel_count());
+ EXPECT_EQ(original->channel_layout(), result->channel_layout());
+ EXPECT_EQ(original->end_of_stream(), result->end_of_stream());
+
+ // Compare bytes in buffer.
+ int bytes_per_channel =
+ original->frame_count() * SampleFormatToBytesPerChannel(sample_format);
+ if (IsPlanar(sample_format)) {
+ for (int i = 0; i < original->channel_count(); ++i) {
+ CompareBytes(original->channel_data()[i], result->channel_data()[i],
+ bytes_per_channel);
+ }
+ return;
+ }
+
+ DCHECK(IsInterleaved(sample_format)) << sample_format;
+ CompareBytes(original->channel_data()[0], result->channel_data()[0],
+ bytes_per_channel * original->channel_count());
+}
+
+void CompareVideoPlane(size_t plane,
+ const scoped_refptr<VideoFrame>& original,
+ const scoped_refptr<VideoFrame>& result) {
+ EXPECT_EQ(original->stride(plane), result->stride(plane));
+ EXPECT_EQ(original->row_bytes(plane), result->row_bytes(plane));
+ EXPECT_EQ(original->rows(plane), result->rows(plane));
+ CompareBytes(original->data(plane), result->data(plane),
+ original->rows(plane) * original->row_bytes(plane));
+}
+
+void CompareVideoFrames(const scoped_refptr<VideoFrame>& original,
+ const scoped_refptr<VideoFrame>& result) {
+ if (original->metadata()->IsTrue(media::VideoFrameMetadata::END_OF_STREAM)) {
+ EXPECT_TRUE(
+ result->metadata()->IsTrue(media::VideoFrameMetadata::END_OF_STREAM));
+ return;
+ }
+
+ EXPECT_EQ(original->format(), result->format());
+ EXPECT_EQ(original->coded_size().height(), result->coded_size().height());
+ EXPECT_EQ(original->coded_size().width(), result->coded_size().width());
+ EXPECT_EQ(original->visible_rect().height(), result->visible_rect().height());
+ EXPECT_EQ(original->visible_rect().width(), result->visible_rect().width());
+ EXPECT_EQ(original->natural_size().height(), result->natural_size().height());
+ EXPECT_EQ(original->natural_size().width(), result->natural_size().width());
+
+ CompareVideoPlane(media::VideoFrame::kYPlane, original, result);
+ CompareVideoPlane(media::VideoFrame::kUPlane, original, result);
+ CompareVideoPlane(media::VideoFrame::kVPlane, original, result);
+}
+
+} // namespace
+
TEST(MediaTypeConvertersTest, ConvertDecoderBuffer_Normal) {
const uint8 kData[] = "hello, world";
const uint8 kSideData[] = "sideshow bob";
@@ -172,4 +245,88 @@ TEST(MediaTypeConvertersTest, ConvertCdmConfig) {
EXPECT_EQ(config.use_hw_secure_codecs, result.use_hw_secure_codecs);
}
+TEST(MediaTypeConvertersTest, ConvertAudioBuffer_EOS) {
+ // Original.
+ scoped_refptr<AudioBuffer> buffer(AudioBuffer::CreateEOSBuffer());
+
+ // Convert to and back.
+ interfaces::AudioBufferPtr ptr(interfaces::AudioBuffer::From(buffer));
+ scoped_refptr<AudioBuffer> result(ptr.To<scoped_refptr<AudioBuffer>>());
+
+ // Compare.
+ EXPECT_TRUE(result->end_of_stream());
+}
+
+TEST(MediaTypeConvertersTest, ConvertAudioBuffer_MONO) {
+ // Original.
+ const ChannelLayout kChannelLayout = CHANNEL_LAYOUT_MONO;
+ const int kSampleRate = 48000;
+ scoped_refptr<AudioBuffer> buffer = MakeAudioBuffer<uint8>(
+ kSampleFormatU8, kChannelLayout,
+ ChannelLayoutToChannelCount(kChannelLayout), kSampleRate, 1, 1,
+ kSampleRate / 100, base::TimeDelta());
+
+ // Convert to and back.
+ interfaces::AudioBufferPtr ptr(interfaces::AudioBuffer::From(buffer));
+ scoped_refptr<AudioBuffer> result(ptr.To<scoped_refptr<AudioBuffer>>());
+
+ // Compare.
+ CompareAudioBuffers(kSampleFormatU8, buffer, result);
+}
+
+TEST(MediaTypeConvertersTest, ConvertAudioBuffer_FLOAT) {
+ // Original.
+ const ChannelLayout kChannelLayout = CHANNEL_LAYOUT_4_0;
+ const int kSampleRate = 48000;
+ const base::TimeDelta start_time = base::TimeDelta::FromSecondsD(1000.0);
+ scoped_refptr<AudioBuffer> buffer = MakeAudioBuffer<float>(
+ kSampleFormatPlanarF32, kChannelLayout,
+ ChannelLayoutToChannelCount(kChannelLayout), kSampleRate, 0.0f, 1.0f,
+ kSampleRate / 10, start_time);
+ // Convert to and back.
+ interfaces::AudioBufferPtr ptr(interfaces::AudioBuffer::From(buffer));
+ scoped_refptr<AudioBuffer> result(ptr.To<scoped_refptr<AudioBuffer>>());
+
+ // Compare.
+ CompareAudioBuffers(kSampleFormatPlanarF32, buffer, result);
+}
+
+TEST(MediaTypeConvertersTest, ConvertVideoFrame_EOS) {
+ // Original.
+ scoped_refptr<VideoFrame> buffer(VideoFrame::CreateEOSFrame());
+
+ // Convert to and back.
+ interfaces::VideoFramePtr ptr(interfaces::VideoFrame::From(buffer));
+ scoped_refptr<VideoFrame> result(ptr.To<scoped_refptr<VideoFrame>>());
+
+ // Compare.
+ CompareVideoFrames(buffer, result);
+}
+
+TEST(MediaTypeConvertersTest, ConvertVideoFrame_BlackFrame) {
+ // Original.
+ scoped_refptr<VideoFrame> buffer(
+ VideoFrame::CreateBlackFrame(gfx::Size(100, 100)));
+
+ // Convert to and back.
+ interfaces::VideoFramePtr ptr(interfaces::VideoFrame::From(buffer));
+ scoped_refptr<VideoFrame> result(ptr.To<scoped_refptr<VideoFrame>>());
+
+ // Compare.
+ CompareVideoFrames(buffer, result);
+}
+
+TEST(MediaTypeConvertersTest, ConvertVideoFrame_ColorFrame) {
+ // Original.
+ scoped_refptr<VideoFrame> buffer(VideoFrame::CreateColorFrame(
+ gfx::Size(50, 100), 255, 128, 128, base::TimeDelta::FromSeconds(26)));
+
+ // Convert to and back.
+ interfaces::VideoFramePtr ptr(interfaces::VideoFrame::From(buffer));
+ scoped_refptr<VideoFrame> result(ptr.To<scoped_refptr<VideoFrame>>());
+
+ // Compare.
+ CompareVideoFrames(buffer, result);
+}
+
} // namespace media