summaryrefslogtreecommitdiffstats
path: root/media/base
diff options
context:
space:
mode:
authorhclam@chromium.org <hclam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-03-17 20:04:29 +0000
committerhclam@chromium.org <hclam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-03-17 20:04:29 +0000
commit40e5ac1f115a7905372d3414debaac63a5244886 (patch)
tree1613d237a6e69e0d1f95b1953b8b2572a9f5b52a /media/base
parentb0c2bda2081e3627baac5814d6c66ef121b88515 (diff)
downloadchromium_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.h17
-rw-r--r--[-rwxr-xr-x]media/base/data_buffer.cc41
-rw-r--r--[-rwxr-xr-x]media/base/data_buffer.h14
-rw-r--r--media/base/data_buffer_unittest.cc47
-rw-r--r--media/base/media_format.cc20
-rw-r--r--media/base/media_format.h4
-rw-r--r--media/base/mock_filter_host.h1
-rw-r--r--media/base/mock_media_filters.h134
-rw-r--r--media/base/pipeline.h7
-rw-r--r--media/base/pipeline_impl_unittest.cc2
-rw-r--r--media/base/synchronizer.cc1
-rw-r--r--media/base/video_frame_impl.cc140
-rw-r--r--media/base/video_frame_impl.h48
-rw-r--r--media/base/video_frame_impl_unittest.cc107
-rw-r--r--media/base/yuv_convert.cc1
-rw-r--r--media/base/yuv_convert.h1
-rw-r--r--media/base/yuv_convert_unittest.cc1
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);
}
+