diff options
Diffstat (limited to 'media/base')
-rw-r--r-- | media/base/video_frame.cc | 27 | ||||
-rw-r--r-- | media/base/video_frame.h | 16 | ||||
-rw-r--r-- | media/base/video_frame_unittest.cc | 20 |
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 |