diff options
author | hclam@chromium.org <hclam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-03-17 20:04:29 +0000 |
---|---|---|
committer | hclam@chromium.org <hclam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-03-17 20:04:29 +0000 |
commit | 40e5ac1f115a7905372d3414debaac63a5244886 (patch) | |
tree | 1613d237a6e69e0d1f95b1953b8b2572a9f5b52a /media/base | |
parent | b0c2bda2081e3627baac5814d6c66ef121b88515 (diff) | |
download | chromium_src-40e5ac1f115a7905372d3414debaac63a5244886.zip chromium_src-40e5ac1f115a7905372d3414debaac63a5244886.tar.gz chromium_src-40e5ac1f115a7905372d3414debaac63a5244886.tar.bz2 |
andrew's patch
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@11904 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'media/base')
-rw-r--r-- | media/base/buffers.h | 17 | ||||
-rw-r--r--[-rwxr-xr-x] | media/base/data_buffer.cc | 41 | ||||
-rw-r--r--[-rwxr-xr-x] | media/base/data_buffer.h | 14 | ||||
-rw-r--r-- | media/base/data_buffer_unittest.cc | 47 | ||||
-rw-r--r-- | media/base/media_format.cc | 20 | ||||
-rw-r--r-- | media/base/media_format.h | 4 | ||||
-rw-r--r-- | media/base/mock_filter_host.h | 1 | ||||
-rw-r--r-- | media/base/mock_media_filters.h | 134 | ||||
-rw-r--r-- | media/base/pipeline.h | 7 | ||||
-rw-r--r-- | media/base/pipeline_impl_unittest.cc | 2 | ||||
-rw-r--r-- | media/base/synchronizer.cc | 1 | ||||
-rw-r--r-- | media/base/video_frame_impl.cc | 140 | ||||
-rw-r--r-- | media/base/video_frame_impl.h | 48 | ||||
-rw-r--r-- | media/base/video_frame_impl_unittest.cc | 107 | ||||
-rw-r--r-- | media/base/yuv_convert.cc | 1 | ||||
-rw-r--r-- | media/base/yuv_convert.h | 1 | ||||
-rw-r--r-- | media/base/yuv_convert_unittest.cc | 1 |
17 files changed, 169 insertions, 417 deletions
diff --git a/media/base/buffers.h b/media/base/buffers.h index 901a8a2..dddc5d3 100644 --- a/media/base/buffers.h +++ b/media/base/buffers.h @@ -97,7 +97,7 @@ class StreamSample : public base::RefCountedThreadSafe<StreamSample> { class Buffer : public StreamSample { public: // Returns a read only pointer to the buffer data. - virtual const uint8* GetData() const = 0; + virtual const char* GetData() const = 0; // Returns the size of valid data in bytes. virtual size_t GetDataSize() const = 0; @@ -106,18 +106,15 @@ class Buffer : public StreamSample { class WritableBuffer : public Buffer { public: - // Returns a read-write pointer to the buffer data. When this method is - // called, any pointers previously returned from this method are invalid, and - // any data previously written to the buffer is invalid. The buffer size - // is guaranteed to be at least the size of |buffer_size|. The size - // that the GetDataSize() method will return is set to |buffer_size|. - // If, after filling the buffer, the caller wants to set the size to a smaller - // value then they can call the SetDataSize() method. - virtual uint8* GetWritableData(size_t buffer_size) = 0; + // Returns a read-write pointer to the buffer data. + virtual char* GetWritableData() = 0; // Updates the size of valid data in bytes, which must be less than or equal - // to the |buffer_size| passed to GetWritableData(). + // to GetBufferSize. virtual void SetDataSize(size_t data_size) = 0; + + // Returns the maximum allocated size for this buffer. + virtual size_t GetBufferSize() const = 0; }; diff --git a/media/base/data_buffer.cc b/media/base/data_buffer.cc index b88790f..8c800ea 100755..100644 --- a/media/base/data_buffer.cc +++ b/media/base/data_buffer.cc @@ -7,17 +7,30 @@ namespace media { -DataBuffer::DataBuffer() - : data_(NULL), - buffer_size_(0), - data_size_(0) { +DataBuffer::DataBuffer(char* data, size_t buffer_size, size_t data_size, + const base::TimeDelta& timestamp, + const base::TimeDelta& duration, + DeleteBuffer delete_buffer) + : data_(data), + buffer_size_(buffer_size), + data_size_(data_size), + delete_buffer_(delete_buffer) { + DCHECK(data); + DCHECK(buffer_size >= 0); + DCHECK(data_size <= buffer_size); + SetTimestamp(timestamp); + SetDuration(duration); } DataBuffer::~DataBuffer() { - delete [] data_; + if (delete_buffer_) { + delete_buffer_(data_); + } else { + delete [] data_; + } } -const uint8* DataBuffer::GetData() const { +const char* DataBuffer::GetData() const { return data_; } @@ -25,23 +38,15 @@ size_t DataBuffer::GetDataSize() const { return data_size_; } -uint8* DataBuffer::GetWritableData(size_t buffer_size) { - if (buffer_size > buffer_size_) { - delete [] data_; - data_ = new uint8[buffer_size]; - if (!data_) { - NOTREACHED(); - buffer_size = 0; - } - buffer_size_ = buffer_size; - } - data_size_ = buffer_size; +char* DataBuffer::GetWritableData() { return data_; } +size_t DataBuffer::GetBufferSize() const { + return buffer_size_; +} void DataBuffer::SetDataSize(size_t data_size) { - DCHECK(data_size <= buffer_size_); data_size_ = data_size; } diff --git a/media/base/data_buffer.h b/media/base/data_buffer.h index 8099d14..ab0bfc0 100755..100644 --- a/media/base/data_buffer.h +++ b/media/base/data_buffer.h @@ -16,23 +16,29 @@ namespace media { class DataBuffer : public WritableBuffer { public: - DataBuffer(); + typedef void (*DeleteBuffer)(void*); + + DataBuffer(char* data, size_t buffer_size, size_t data_size, + const base::TimeDelta& timestamp, const base::TimeDelta& duration, + DeleteBuffer delete_buffer = NULL); // Buffer implementation. - virtual const uint8* GetData() const; + virtual const char* GetData() const; virtual size_t GetDataSize() const; // WritableBuffer implementation. - virtual uint8* GetWritableData(size_t buffer_size); + virtual char* GetWritableData(); + virtual size_t GetBufferSize() const; virtual void SetDataSize(size_t data_size); protected: virtual ~DataBuffer(); private: - uint8* data_; + char* data_; size_t buffer_size_; size_t data_size_; + DeleteBuffer delete_buffer_; }; } // namespace media diff --git a/media/base/data_buffer_unittest.cc b/media/base/data_buffer_unittest.cc index 21334f8..b0a45a1 100644 --- a/media/base/data_buffer_unittest.cc +++ b/media/base/data_buffer_unittest.cc @@ -9,6 +9,7 @@ using media::DataBuffer; TEST(DataBufferTest, Basic) { + const size_t kBufferSize = 32; const char kData[] = "hello"; const size_t kDataSize = arraysize(kData); const char kNewData[] = "chromium"; @@ -19,13 +20,18 @@ TEST(DataBufferTest, Basic) { const base::TimeDelta kDurationB = base::TimeDelta::FromMicroseconds(5678); // Create our buffer and copy some data into it. + char* data = new char[kBufferSize]; + ASSERT_TRUE(data); + size_t copied = base::strlcpy(data, kData, kBufferSize); + EXPECT_EQ(kDataSize, copied + 1); + // Create a DataBuffer. - scoped_refptr<DataBuffer> buffer = new DataBuffer(); - ASSERT_TRUE(buffer); + scoped_refptr<DataBuffer> buffer; + buffer = new DataBuffer(data, kBufferSize, kDataSize, + kTimestampA, kDurationA); + ASSERT_TRUE(buffer.get()); // Test StreamSample implementation. - buffer->SetTimestamp(kTimestampA); - buffer->SetDuration(kDurationA); EXPECT_TRUE(kTimestampA == buffer->GetTimestamp()); EXPECT_TRUE(kDurationA == buffer->GetDuration()); EXPECT_FALSE(buffer->IsEndOfStream()); @@ -35,6 +41,19 @@ TEST(DataBufferTest, Basic) { EXPECT_TRUE(kTimestampB == buffer->GetTimestamp()); EXPECT_TRUE(kDurationB == buffer->GetDuration()); + // Test Buffer implementation. + ASSERT_EQ(data, buffer->GetData()); + EXPECT_EQ(kDataSize, buffer->GetDataSize()); + EXPECT_STREQ(kData, buffer->GetData()); + + // Test WritableBuffer implementation. + ASSERT_EQ(data, buffer->GetWritableData()); + EXPECT_EQ(kBufferSize, buffer->GetBufferSize()); + copied = base::strlcpy(data, kNewData, kBufferSize); + EXPECT_EQ(kNewDataSize, copied + 1); + buffer->SetDataSize(kNewDataSize); + EXPECT_EQ(kNewDataSize, buffer->GetDataSize()); + buffer->SetEndOfStream(true); EXPECT_TRUE(buffer->IsEndOfStream()); buffer->SetEndOfStream(false); @@ -43,24 +62,4 @@ TEST(DataBufferTest, Basic) { EXPECT_TRUE(buffer->IsDiscontinuous()); buffer->SetDiscontinuous(false); EXPECT_FALSE(buffer->IsDiscontinuous()); - - // Test WritableBuffer implementation. - EXPECT_FALSE(buffer->GetData()); - uint8* data = buffer->GetWritableData(kDataSize); - ASSERT_TRUE(data); - ASSERT_EQ(buffer->GetDataSize(), kDataSize); - memcpy(data, kData, kDataSize); - const uint8* read_only_data = buffer->GetData(); - ASSERT_EQ(data, read_only_data); - ASSERT_EQ(0, memcmp(read_only_data, kData, kDataSize)); - - data = buffer->GetWritableData(kNewDataSize + 10); - ASSERT_TRUE(data); - ASSERT_EQ(buffer->GetDataSize(), kNewDataSize + 10); - memcpy(data, kNewData, kNewDataSize); - read_only_data = buffer->GetData(); - buffer->SetDataSize(kNewDataSize); - EXPECT_EQ(buffer->GetDataSize(), kNewDataSize); - ASSERT_EQ(data, read_only_data); - EXPECT_EQ(0, memcmp(read_only_data, kNewData, kNewDataSize)); } diff --git a/media/base/media_format.cc b/media/base/media_format.cc index 543ada8..e66e365 100644 --- a/media/base/media_format.cc +++ b/media/base/media_format.cc @@ -51,14 +51,18 @@ const char kMajorTypeAudio[] = "audio/"; } // namespace mime_type // Common keys. -const char MediaFormat::kMimeType[] = "MimeType"; -const char MediaFormat::kURL[] = "URL"; -const char MediaFormat::kSurfaceFormat[] = "SurfaceFormat"; -const char MediaFormat::kSampleRate[] = "SampleRate"; -const char MediaFormat::kSampleBits[] = "SampleBits"; -const char MediaFormat::kChannels[] = "Channels"; -const char MediaFormat::kWidth[] = "Width"; -const char MediaFormat::kHeight[] = "Height"; +const char MediaFormat::kMimeType[] = "MimeType"; +const char MediaFormat::kURL[] = "URL"; +const char MediaFormat::kSurfaceFormat[] = "SurfaceFormat"; +const char MediaFormat::kSampleRate[] = "SampleRate"; +const char MediaFormat::kSampleBits[] = "SampleBits"; +const char MediaFormat::kChannels[] = "Channels"; +const char MediaFormat::kWidth[] = "Width"; +const char MediaFormat::kHeight[] = "Height"; +const char MediaFormat::kBitRate[] = "BitRate"; +const char MediaFormat::kBitsPerCodedSample[] = "BitsPerCodedSample"; +const char MediaFormat::kBlockAlign[] = "BlockAlign"; +const char MediaFormat::kFrameSize[] = "FrameSize"; MediaFormat::MediaFormat() { } diff --git a/media/base/media_format.h b/media/base/media_format.h index 298d68c..f30be02 100644 --- a/media/base/media_format.h +++ b/media/base/media_format.h @@ -52,6 +52,10 @@ class MediaFormat { static const char kChannels[]; static const char kWidth[]; static const char kHeight[]; + static const char kBitRate[]; + static const char kBitsPerCodedSample[]; + static const char kBlockAlign[]; + static const char kFrameSize[]; MediaFormat(); ~MediaFormat(); diff --git a/media/base/mock_filter_host.h b/media/base/mock_filter_host.h index 0a41397..3af36ac 100644 --- a/media/base/mock_filter_host.h +++ b/media/base/mock_filter_host.h @@ -12,7 +12,6 @@ #include <string> -#include "base/scoped_ptr.h" #include "media/base/factory.h" #include "media/base/filter_host.h" #include "media/base/filters.h" diff --git a/media/base/mock_media_filters.h b/media/base/mock_media_filters.h index 5a3c6bf..0620eff 100644 --- a/media/base/mock_media_filters.h +++ b/media/base/mock_media_filters.h @@ -14,7 +14,6 @@ #include "media/base/filters.h" #include "media/base/media_format.h" #include "media/base/pipeline.h" -#include "media/base/video_frame_impl.h" #include "testing/gtest/include/gtest/gtest.h" namespace media { @@ -367,6 +366,75 @@ class MockAudioRenderer : public AudioRenderer { //------------------------------------------------------------------------------ +class MockVideoFrame : public VideoFrame { + public: + MockVideoFrame(size_t video_width, + size_t video_height, + VideoSurface::Format video_surface_format, + base::TimeDelta timestamp, + base::TimeDelta duration, + double ratio_white_to_black) { + surface_locked_ = false; + SetTimestamp(timestamp); + SetDuration(duration); + size_t y_byte_count = video_width * video_height; + size_t uv_byte_count = y_byte_count / 4; + surface_.format = video_surface_format; + surface_.width = video_width; + surface_.height = video_height; + surface_.planes = 3; + surface_.data[0] = new uint8[y_byte_count]; + surface_.data[1] = new uint8[uv_byte_count]; + surface_.data[2] = new uint8[uv_byte_count]; + surface_.strides[0] = video_width; + surface_.strides[1] = video_width / 2; + surface_.strides[2] = video_width / 2; + memset(surface_.data[0], 0, y_byte_count); + memset(surface_.data[1], 0x80, uv_byte_count); + memset(surface_.data[2], 0x80, uv_byte_count); + int64 num_white_pixels = static_cast<int64>(y_byte_count * + ratio_white_to_black); + if (num_white_pixels > y_byte_count) { + ADD_FAILURE(); + num_white_pixels = y_byte_count; + } + if (num_white_pixels < 0) { + ADD_FAILURE(); + num_white_pixels = 0; + } + memset(surface_.data[0], 0xFF, static_cast<size_t>(num_white_pixels)); + } + + virtual ~MockVideoFrame() { + delete[] surface_.data[0]; + delete[] surface_.data[1]; + delete[] surface_.data[2]; + } + + virtual bool Lock(VideoSurface* surface) { + EXPECT_FALSE(surface_locked_); + if (surface_locked_) { + memset(surface, 0, sizeof(*surface)); + return false; + } + surface_locked_ = true; + COMPILE_ASSERT(sizeof(*surface) == sizeof(surface_), surface_size_mismatch); + memcpy(surface, &surface_, sizeof(*surface)); + return true; + } + + virtual void Unlock() { + EXPECT_TRUE(surface_locked_); + surface_locked_ = false; + } + + private: + bool surface_locked_; + VideoSurface surface_; + + DISALLOW_COPY_AND_ASSIGN(MockVideoFrame); +}; + class MockVideoDecoder : public VideoDecoder { public: static FilterFactory* CreateFactory(const MockFilterConfig* config) { @@ -378,35 +446,6 @@ class MockVideoDecoder : public VideoDecoder { return true; // TODO(ralphl): check for a supported format. } - // Helper function that initializes a YV12 frame with white and black scan - // lines based on the |white_to_black| parameter. If 0, then the entire - // frame will be black, if 1 then the entire frame will be white. - static void InitializeYV12Frame(VideoFrame* frame, double white_to_black) { - VideoSurface surface; - if (!frame->Lock(&surface)) { - ADD_FAILURE(); - } else { - EXPECT_EQ(surface.format, VideoSurface::YV12); - size_t first_black_row = static_cast<size_t>(surface.height * - white_to_black); - uint8* y_plane = surface.data[VideoSurface::kYPlane]; - for (size_t row = 0; row < surface.height; ++row) { - int color = (row < first_black_row) ? 0xFF : 0x00; - memset(y_plane, color, surface.width); - y_plane += surface.strides[VideoSurface::kYPlane]; - } - uint8* u_plane = surface.data[VideoSurface::kUPlane]; - uint8* v_plane = surface.data[VideoSurface::kVPlane]; - for (size_t row = 0; row < surface.height; row += 2) { - memset(u_plane, 0x80, surface.width / 2); - memset(v_plane, 0x80, surface.width / 2); - u_plane += surface.strides[VideoSurface::kUPlane]; - v_plane += surface.strides[VideoSurface::kVPlane]; - } - frame->Unlock(); - } - } - explicit MockVideoDecoder(const MockFilterConfig* config) : config_(config) { media_format_.SetAsString(MediaFormat::kMimeType, @@ -438,29 +477,20 @@ class MockVideoDecoder : public VideoDecoder { void DoRead(Assignable<VideoFrame>* buffer) { if (mock_frame_time_ < config_->media_duration) { - // TODO(ralphl): Mock video decoder only works with YV12. Implement other - // formats as needed. - EXPECT_EQ(config_->video_surface_format, VideoSurface::YV12); - scoped_refptr<VideoFrame> frame; - VideoFrameImpl::CreateFrame(config_->video_surface_format, - config_->video_width, - config_->video_height, - mock_frame_time_, - config_->frame_duration, - &frame); - if (!frame) { - host_->Error(PIPELINE_ERROR_OUT_OF_MEMORY); - ADD_FAILURE(); - } else { - mock_frame_time_ += config_->frame_duration; - if (mock_frame_time_ >= config_->media_duration) { - frame->SetEndOfStream(true); - } - InitializeYV12Frame(frame, (mock_frame_time_.InSecondsF() / - config_->media_duration.InSecondsF())); - buffer->SetBuffer(frame); - buffer->OnAssignment(); + VideoFrame* frame = new MockVideoFrame( + config_->video_width, + config_->video_height, + config_->video_surface_format, + mock_frame_time_, + config_->frame_duration, + (mock_frame_time_.InSecondsF() / + config_->media_duration.InSecondsF())); + mock_frame_time_ += config_->frame_duration; + if (mock_frame_time_ >= config_->media_duration) { + frame->SetEndOfStream(true); } + buffer->SetBuffer(frame); + buffer->OnAssignment(); } buffer->Release(); } diff --git a/media/base/pipeline.h b/media/base/pipeline.h index f5b91ff..58883cc 100644 --- a/media/base/pipeline.h +++ b/media/base/pipeline.h @@ -12,12 +12,9 @@ #include <string> #include "base/task.h" +#include "base/time.h" #include "media/base/factory.h" -namespace base { - class TimeDelta; -} - namespace media { // Error definitions for pipeline. All codes indicate an error except: @@ -35,7 +32,7 @@ enum PipelineError { PIPELINE_ERROR_OUT_OF_MEMORY, PIPELINE_ERROR_COULD_NOT_RENDER, PIPELINE_ERROR_READ, - PIPELINE_ERROR_AUDIO_HARDWARE, + // Demuxer related errors. DEMUXER_ERROR_COULD_NOT_OPEN, DEMUXER_ERROR_COULD_NOT_PARSE, diff --git a/media/base/pipeline_impl_unittest.cc b/media/base/pipeline_impl_unittest.cc index 8e300a1..6685896 100644 --- a/media/base/pipeline_impl_unittest.cc +++ b/media/base/pipeline_impl_unittest.cc @@ -4,6 +4,8 @@ #include <string> +#include "base/platform_thread.h" +#include "base/time.h" #include "base/waitable_event.h" #include "media/base/pipeline_impl.h" #include "media/base/media_format.h" diff --git a/media/base/synchronizer.cc b/media/base/synchronizer.cc index abeb8ad..a8caffa 100644 --- a/media/base/synchronizer.cc +++ b/media/base/synchronizer.cc @@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "base/logging.h" #include "media/base/synchronizer.h" namespace media { diff --git a/media/base/video_frame_impl.cc b/media/base/video_frame_impl.cc deleted file mode 100644 index 8d9ae59..0000000 --- a/media/base/video_frame_impl.cc +++ /dev/null @@ -1,140 +0,0 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "media/base/video_frame_impl.h" - -namespace media { - -// static -void VideoFrameImpl::CreateFrame(VideoSurface::Format format, - size_t width, - size_t height, - base::TimeDelta timestamp, - base::TimeDelta duration, - scoped_refptr<VideoFrame>* frame_out) { - DCHECK(width > 0 && height > 0); - DCHECK(width * height < 100000000); - DCHECK(frame_out); - bool alloc_worked = false; - scoped_refptr<VideoFrameImpl> frame = - new VideoFrameImpl(format, width, height); - if (frame) { - frame->SetTimestamp(timestamp); - frame->SetDuration(duration); - switch (format) { - case VideoSurface::RGB555: - case VideoSurface::RGB565: - alloc_worked = frame->AllocateRGB(2u); - break; - case VideoSurface::RGB24: - alloc_worked = frame->AllocateRGB(3u); - break; - case VideoSurface::RGB32: - case VideoSurface::RGBA: - alloc_worked = frame->AllocateRGB(4u); - break; - case VideoSurface::YV12: - case VideoSurface::YV16: - alloc_worked = frame->AllocateYUV(); - break; - default: - NOTREACHED(); - alloc_worked = false; - break; - } - } - *frame_out = alloc_worked ? frame : NULL; -} - -static inline size_t RoundUp(size_t value, size_t alignment) { - // Check that |alignment| is a power of 2. - DCHECK((alignment + (alignment - 1)) == (alignment | (alignment - 1))); - return ((value + (alignment - 1)) & ~(alignment-1)); -} - -bool VideoFrameImpl::AllocateRGB(size_t bytes_per_pixel) { - // Round up to align at a 64-bit (8 byte) boundary for each row. This - // is sufficient for MMX reads (movq). - size_t bytes_per_row = RoundUp(surface_.width * bytes_per_pixel, 8); - surface_.planes = VideoSurface::kNumRGBPlanes; - surface_.strides[VideoSurface::kRGBPlane] = bytes_per_row; - surface_.data[VideoSurface::kRGBPlane] = new uint8[bytes_per_row * - surface_.height]; - DCHECK(surface_.data[VideoSurface::kRGBPlane]); - DCHECK(!(reinterpret_cast<int>(surface_.data[VideoSurface::kRGBPlane]) & 7)); - COMPILE_ASSERT(0 == VideoSurface::kRGBPlane, RGB_data_must_be_index_0); - return (NULL != surface_.data[VideoSurface::kRGBPlane]); -} - -bool VideoFrameImpl::AllocateYUV() { - DCHECK(surface_.format == VideoSurface::YV12 || - surface_.format == VideoSurface::YV16); - // Align Y rows at 32-bit (4 byte) boundaries. The stride for both YV12 and - // YV16 is 1/2 of the stride of Y. For YV12, every row of bytes for U and V - // applies to two rows of Y (one byte of UV for 4 bytes of Y), so in the - // case of YV12 the strides are identical for the same width surface, but the - // number of bytes allocated for YV12 is 1/2 the amount for U & V as YV16. - // We also round the height of the surface allocated to be an even number - // to avoid any potential of faulting by code that attempts to access the Y - // values of the final row, but assumes that the last row of U & V applies to - // a full two rows of Y. - size_t alloc_height = RoundUp(surface_.height, 2); - size_t y_bytes_per_row = RoundUp(surface_.width, 4); - size_t uv_stride = RoundUp(y_bytes_per_row / 2, 4); - size_t y_bytes = alloc_height * y_bytes_per_row; - size_t uv_bytes = alloc_height * uv_stride; - if (surface_.format == VideoSurface::YV12) { - uv_bytes /= 2; - } - uint8* data = new uint8[y_bytes + (uv_bytes * 2)]; - if (data) { - surface_.planes = VideoSurface::kNumYUVPlanes; - COMPILE_ASSERT(0 == VideoSurface::kYPlane, y_plane_data_must_be_index_0); - surface_.data[VideoSurface::kYPlane] = data; - surface_.data[VideoSurface::kUPlane] = data + y_bytes; - surface_.data[VideoSurface::kVPlane] = data + y_bytes + uv_bytes; - surface_.strides[VideoSurface::kYPlane] = y_bytes_per_row; - surface_.strides[VideoSurface::kUPlane] = uv_stride; - surface_.strides[VideoSurface::kVPlane] = uv_stride; - return true; - } - NOTREACHED(); - return false; -} - -VideoFrameImpl::VideoFrameImpl(VideoSurface::Format format, - size_t width, - size_t height) { - locked_ = false; - memset(&surface_, 0, sizeof(surface_)); - surface_.format = format; - surface_.width = width; - surface_.height = height; -} - -VideoFrameImpl::~VideoFrameImpl() { - // In multi-plane allocations, only a single block of memory is allocated - // on the heap, and other |data| pointers point inside the same, single block - // so just delete index 0. - delete[] surface_.data[0]; -} - -bool VideoFrameImpl::Lock(VideoSurface* surface) { - DCHECK(!locked_); - if (locked_) { - memset(surface, 0, sizeof(*surface)); - return false; - } - locked_ = true; - COMPILE_ASSERT(sizeof(*surface) == sizeof(surface_), surface_size_mismatch); - memcpy(surface, &surface_, sizeof(*surface)); - return true; -} - -void VideoFrameImpl::Unlock() { - DCHECK(locked_); - locked_ = false; -} - -} // namespace media diff --git a/media/base/video_frame_impl.h b/media/base/video_frame_impl.h deleted file mode 100644 index 36a2f2c..0000000 --- a/media/base/video_frame_impl.h +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Simple class that implements the VideoFrame interface with memory allocated -// on the system heap. This class supports every format defined in the -// VideoSurface::Format enum. The implementation attempts to properly align -// allocations for maximum system bus efficency. -#ifndef MEDIA_BASE_VIDEO_FRAME_IMPL_H_ -#define MEDIA_BASE_VIDEO_FRAME_IMPL_H_ - -#include "media/base/buffers.h" - -namespace media { - -class VideoFrameImpl : public VideoFrame { - public: - static void CreateFrame(VideoSurface::Format format, - size_t width, - size_t height, - base::TimeDelta timestamp, - base::TimeDelta duration, - scoped_refptr<VideoFrame>* frame_out); - - // Implementation of VideoFrame. - virtual bool Lock(VideoSurface* surface); - virtual void Unlock(); - - private: - // Clients must use the static CreateFrame() method to create a new frame. - VideoFrameImpl(VideoSurface::Format format, - size_t video_width, - size_t video_height); - - virtual ~VideoFrameImpl(); - - bool AllocateRGB(size_t bytes_per_pixel); - bool AllocateYUV(); - - bool locked_; - VideoSurface surface_; - - DISALLOW_COPY_AND_ASSIGN(VideoFrameImpl); -}; - -} // namespace media - -#endif // MEDIA_BASE_VIDEO_FRAME_IMPL_H_ diff --git a/media/base/video_frame_impl_unittest.cc b/media/base/video_frame_impl_unittest.cc deleted file mode 100644 index 352e2368..0000000 --- a/media/base/video_frame_impl_unittest.cc +++ /dev/null @@ -1,107 +0,0 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "media/base/buffers.h" -#include "media/base/mock_media_filters.h" -#include "media/base/video_frame_impl.h" -#include "media/base/yuv_convert.h" -#include "testing/gtest/include/gtest/gtest.h" - -using media::VideoFrameImpl; -using media::VideoSurface; - -namespace { - -// Given a |yv12_frame| this method converts the YV12 frame to RGBA and -// makes sure that all the pixels of the RBG frame equal |expect_rgb_color|. -void ExpectFrameColor(media::VideoFrame* yv12_frame, uint32 expect_rgb_color) { - // On linux and mac builds if you directly compare using EXPECT_EQ and use - // the VideoSurface::kNumxxxPlanes constants, it generates an error when - // linking. These are declared so that we can compare against locals. - const size_t expect_yuv_planes = VideoSurface::kNumYUVPlanes; - const size_t expect_rgb_planes = VideoSurface::kNumRGBPlanes; - - VideoSurface yuv_surface; - EXPECT_TRUE(yv12_frame->Lock(&yuv_surface)); - EXPECT_EQ(yuv_surface.format, VideoSurface::YV12); - EXPECT_EQ(yuv_surface.planes, expect_yuv_planes); - EXPECT_EQ(yuv_surface.strides[VideoSurface::kUPlane], - yuv_surface.strides[VideoSurface::kVPlane]); - - scoped_refptr<media::VideoFrame> rgb_frame; - media::VideoFrameImpl::CreateFrame(VideoSurface::RGBA, - yuv_surface.width, - yuv_surface.height, - yv12_frame->GetTimestamp(), - yv12_frame->GetDuration(), - &rgb_frame); - media::VideoSurface rgb_surface; - EXPECT_TRUE(rgb_frame->Lock(&rgb_surface)); - EXPECT_EQ(rgb_surface.width, yuv_surface.width); - EXPECT_EQ(rgb_surface.height, yuv_surface.height); - EXPECT_EQ(rgb_surface.planes, expect_rgb_planes); - - media::ConvertYV12ToRGB32(yuv_surface.data[VideoSurface::kYPlane], - yuv_surface.data[VideoSurface::kUPlane], - yuv_surface.data[VideoSurface::kVPlane], - rgb_surface.data[VideoSurface::kRGBPlane], - rgb_surface.width, - rgb_surface.height, - yuv_surface.strides[VideoSurface::kYPlane], - yuv_surface.strides[VideoSurface::kUPlane], - rgb_surface.strides[VideoSurface::kRGBPlane]); - - for (size_t row = 0; row < rgb_surface.height; ++row) { - uint32* rgb_row_data = reinterpret_cast<uint32*>( - rgb_surface.data[VideoSurface::kRGBPlane] + - (rgb_surface.strides[VideoSurface::kRGBPlane] * row)); - for (size_t col = 0; col < rgb_surface.width; ++col) { - EXPECT_EQ(rgb_row_data[col], expect_rgb_color); - } - } - rgb_frame->Unlock(); - yv12_frame->Unlock(); -} - -} // namespace - - -TEST(VideoFrameImpl, Basic) { - const size_t kWidth = 64; - const size_t kHeight = 48; - const base::TimeDelta kTimestampA = base::TimeDelta::FromMicroseconds(1337); - const base::TimeDelta kDurationA = base::TimeDelta::FromMicroseconds(1667); - const base::TimeDelta kTimestampB = base::TimeDelta::FromMicroseconds(1234); - const base::TimeDelta kDurationB = base::TimeDelta::FromMicroseconds(5678); - - // Create a YV12 Video Frame. - scoped_refptr<media::VideoFrame> frame; - media::VideoFrameImpl::CreateFrame(media::VideoSurface::YV12, kWidth, kHeight, - kTimestampA, kDurationA, &frame); - ASSERT_TRUE(frame); - - // Test StreamSample implementation. - EXPECT_TRUE(kTimestampA == frame->GetTimestamp()); - EXPECT_TRUE(kDurationA == frame->GetDuration()); - EXPECT_FALSE(frame->IsEndOfStream()); - EXPECT_FALSE(frame->IsDiscontinuous()); - frame->SetTimestamp(kTimestampB); - frame->SetDuration(kDurationB); - EXPECT_TRUE(kTimestampB == frame->GetTimestamp()); - EXPECT_TRUE(kDurationB == frame->GetDuration()); - frame->SetEndOfStream(true); - EXPECT_TRUE(frame->IsEndOfStream()); - frame->SetEndOfStream(false); - EXPECT_FALSE(frame->IsEndOfStream()); - frame->SetDiscontinuous(true); - EXPECT_TRUE(frame->IsDiscontinuous()); - frame->SetDiscontinuous(false); - EXPECT_FALSE(frame->IsDiscontinuous()); - - // Test VideoFrame implementation. - media::MockVideoDecoder::InitializeYV12Frame(frame, 0.0f); - ExpectFrameColor(frame, 0xFF000000); - media::MockVideoDecoder::InitializeYV12Frame(frame, 1.0f); - ExpectFrameColor(frame, 0xFFFFFFFF); -} diff --git a/media/base/yuv_convert.cc b/media/base/yuv_convert.cc index 5b61bf0..e1da09e 100644 --- a/media/base/yuv_convert.cc +++ b/media/base/yuv_convert.cc @@ -186,3 +186,4 @@ void ConvertYV12ToRGB32(const uint8* yplane, } } // namespace media + diff --git a/media/base/yuv_convert.h b/media/base/yuv_convert.h index bd2175d..6b6ea24 100644 --- a/media/base/yuv_convert.h +++ b/media/base/yuv_convert.h @@ -23,3 +23,4 @@ void ConvertYV12ToRGB32(const uint8* yplane, #endif // MEDIA_BASE_YUV_CONVERT_H_ } // namespace media + diff --git a/media/base/yuv_convert_unittest.cc b/media/base/yuv_convert_unittest.cc index 59ceb14..3b1ffec9 100644 --- a/media/base/yuv_convert_unittest.cc +++ b/media/base/yuv_convert_unittest.cc @@ -61,3 +61,4 @@ TEST(YuvConvertTest, Basic) { EXPECT_EQ(rgb_diff, 0); } + |