summaryrefslogtreecommitdiffstats
path: root/media/base
diff options
context:
space:
mode:
Diffstat (limited to 'media/base')
-rw-r--r--media/base/video_frame.cc27
-rw-r--r--media/base/video_frame.h16
-rw-r--r--media/base/video_frame_unittest.cc20
3 files changed, 62 insertions, 1 deletions
diff --git a/media/base/video_frame.cc b/media/base/video_frame.cc
index 3e2164e..a7eeb1e 100644
--- a/media/base/video_frame.cc
+++ b/media/base/video_frame.cc
@@ -47,6 +47,29 @@ void VideoFrame::CreateFrame(VideoFrame::Format format,
*frame_out = alloc_worked ? frame : NULL;
}
+void VideoFrame::CreateFrameExternal(VideoFrame::Format format,
+ size_t width,
+ size_t height,
+ uint8* const data[kMaxPlanes],
+ const int32 strides[kMaxPlanes],
+ base::TimeDelta timestamp,
+ base::TimeDelta duration,
+ scoped_refptr<VideoFrame>* frame_out) {
+ DCHECK(frame_out);
+ scoped_refptr<VideoFrame> frame =
+ new VideoFrame(VideoFrame::TYPE_SYSTEM_MEMORY, format, width, height);
+ if (frame) {
+ frame->SetTimestamp(timestamp);
+ frame->SetDuration(duration);
+ frame->external_memory_ = true;
+ for (size_t i = 0; i < kMaxPlanes; ++i) {
+ frame->data_[i] = data[i];
+ frame->strides_[i] = strides[i];
+ }
+ }
+ *frame_out = frame;
+}
+
// static
void VideoFrame::CreateEmptyFrame(scoped_refptr<VideoFrame>* frame_out) {
*frame_out = new VideoFrame(VideoFrame::TYPE_SYSTEM_MEMORY,
@@ -179,6 +202,7 @@ VideoFrame::VideoFrame(VideoFrame::BufferType type,
planes_ = 0;
memset(&strides_, 0, sizeof(strides_));
memset(&data_, 0, sizeof(data_));
+ external_memory_ = false;
private_buffer_ = NULL;
}
@@ -186,7 +210,8 @@ VideoFrame::~VideoFrame() {
// 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[] data_[0];
+ if (!external_memory_)
+ delete[] data_[0];
}
bool VideoFrame::IsEndOfStream() const {
diff --git a/media/base/video_frame.h b/media/base/video_frame.h
index 77563a9..d4f3b94 100644
--- a/media/base/video_frame.h
+++ b/media/base/video_frame.h
@@ -52,6 +52,18 @@ class VideoFrame : public StreamSample {
base::TimeDelta duration,
scoped_refptr<VideoFrame>* frame_out);
+ // Creates a new frame with given parameters. Buffers for the frame are
+ // provided externally. Reference to the buffers and strides are copied
+ // from |data| and |strides| respectively.
+ static void CreateFrameExternal(Format format,
+ size_t width,
+ size_t height,
+ uint8* const data[kMaxPlanes],
+ const int32 strides[kMaxPlanes],
+ base::TimeDelta timestamp,
+ base::TimeDelta duration,
+ scoped_refptr<VideoFrame>* frame_out);
+
// Creates a frame with format equals to VideoFrame::EMPTY, width, height
// timestamp and duration are all 0.
static void CreateEmptyFrame(scoped_refptr<VideoFrame>* frame_out);
@@ -127,6 +139,10 @@ class VideoFrame : public StreamSample {
// Array of data pointers to each plane.
uint8* data_[kMaxPlanes];
+ // True of memory referenced by |data_| is provided externally and shouldn't
+ // be deleted.
+ bool external_memory_;
+
// Private buffer pointer, can be used for EGLImage.
void* private_buffer_;
diff --git a/media/base/video_frame_unittest.cc b/media/base/video_frame_unittest.cc
index caa5675..1cacdd1 100644
--- a/media/base/video_frame_unittest.cc
+++ b/media/base/video_frame_unittest.cc
@@ -195,4 +195,24 @@ TEST(VideoFrame, CreatePrivateFrame) {
EXPECT_EQ(NULL, frame->data(VideoFrame::kYPlane));
}
+TEST(VideoFram, CreateExternalFrame) {
+ scoped_array<uint8> memory(new uint8[1]);
+
+ scoped_refptr<media::VideoFrame> frame;
+ uint8* data[3] = {memory.get(), NULL, NULL};
+ int strides[3] = {1, 0, 0};
+ VideoFrame::CreateFrameExternal(media::VideoFrame::RGB32, 0, 0,
+ data, strides,
+ base::TimeDelta(), base::TimeDelta(), &frame);
+ ASSERT_TRUE(frame);
+
+ // Test frame properties.
+ EXPECT_EQ(1, frame->stride(VideoFrame::kRGBPlane));
+ EXPECT_EQ(memory.get(), frame->data(VideoFrame::kRGBPlane));
+
+ // Delete |memory| and then |frame|.
+ memory.reset();
+ frame = NULL;
+}
+
} // namespace media