Index: media/mojo/interfaces/video_frame_struct_traits.h |
diff --git a/media/mojo/interfaces/video_frame_struct_traits.h b/media/mojo/interfaces/video_frame_struct_traits.h |
new file mode 100644 |
index 0000000000000000000000000000000000000000..b553587d6097ecee9247406b73c00f83361b301b |
--- /dev/null |
+++ b/media/mojo/interfaces/video_frame_struct_traits.h |
@@ -0,0 +1,168 @@ |
+// Copyright 2017 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. |
+ |
+#ifndef MEDIA_MOJO_INTERFACES_VIDEO_FRAME_STRUCT_TRAITS_H_ |
+#define MEDIA_MOJO_INTERFACES_VIDEO_FRAME_STRUCT_TRAITS_H_ |
+ |
+#include "base/logging.h" |
+#include "base/memory/ref_counted.h" |
+#include "media/base/video_frame.h" |
+#include "media/mojo/common/mojo_shared_buffer_video_frame.h" |
+#include "media/mojo/interfaces/media_types.mojom.h" |
+#include "mojo/public/cpp/bindings/struct_traits.h" |
+ |
+namespace mojo { |
+ |
+template <> |
+struct StructTraits<media::mojom::VideoFrameDataView, |
+ scoped_refptr<media::VideoFrame>> { |
+ static bool IsNull(const scoped_refptr<media::VideoFrame>& input) { |
+ return !!input; |
+ } |
+ |
+ static void SetToNull(scoped_refptr<media::VideoFrame>* input) { |
+ *input = nullptr; |
+ } |
+ |
+ static media::VideoPixelFormat format( |
+ const scoped_refptr<media::VideoFrame>& input) { |
+ return input->format(); |
+ } |
+ |
+ static gfx::Size coded_size(const scoped_refptr<media::VideoFrame>& input) { |
dcheng
2017/06/05 20:33:02
Nit: return non-trivial types by const ref: due to
sandersd (OOO until July 31)
2017/06/06 01:05:47
This is the first time I've heard gfx::Size referr
|
+ return input->coded_size(); |
+ } |
+ |
+ static gfx::Rect visible_rect(const scoped_refptr<media::VideoFrame>& input) { |
+ return input->visible_rect(); |
+ } |
+ |
+ static gfx::Size natural_size(const scoped_refptr<media::VideoFrame>& input) { |
+ return input->natural_size(); |
+ } |
+ |
+ static bool end_of_stream(const scoped_refptr<media::VideoFrame>& input) { |
+ return input->metadata()->IsTrue(media::VideoFrameMetadata::END_OF_STREAM); |
dcheng
2017/06/05 20:33:01
I'm assuming this is a cheap calculation (otherwis
sandersd (OOO until July 31)
2017/06/05 20:46:13
This one should be fine.
|
+ } |
+ |
+ static base::TimeDelta timestamp( |
dcheng
2017/06/05 20:33:01
But returning base::Time* by value is fine.
sandersd (OOO until July 31)
2017/06/06 01:05:47
Acknowledged.
|
+ const scoped_refptr<media::VideoFrame>& input) { |
+ return input->timestamp(); |
+ } |
+ |
+ static media::mojom::VideoFrameDataPtr data( |
+ const scoped_refptr<media::VideoFrame>& input) { |
dcheng
2017/06/05 20:33:02
Hmm, isn't this in the .cc as well? I'm assuming t
sandersd (OOO until July 31)
2017/06/05 20:46:13
Yes, it is, but they should have identical content
|
+ // EOS frames contain no data. |
+ if (input->metadata()->IsTrue(media::VideoFrameMetadata::END_OF_STREAM)) |
+ return nullptr; |
+ |
+ if (input->storage_type() == |
+ media::VideoFrame::STORAGE_MOJO_SHARED_BUFFER) { |
+ media::MojoSharedBufferVideoFrame* mojo_frame = |
+ static_cast<media::MojoSharedBufferVideoFrame*>(input.get()); |
+ |
+ // TODO(jrummell): Should this really be a writable clone? |
+ mojo::ScopedSharedBufferHandle duplicated_handle = |
+ mojo_frame->Handle().Clone(); |
+ DCHECK(duplicated_handle.is_valid()); |
+ |
+ return media::mojom::VideoFrameData::NewSharedBufferData( |
+ media::mojom::SharedBufferVideoFrameData::New( |
+ std::move(duplicated_handle), mojo_frame->MappedSize(), |
+ mojo_frame->stride(media::VideoFrame::kYPlane), |
+ mojo_frame->stride(media::VideoFrame::kUPlane), |
+ mojo_frame->stride(media::VideoFrame::kVPlane), |
+ mojo_frame->PlaneOffset(media::VideoFrame::kYPlane), |
+ mojo_frame->PlaneOffset(media::VideoFrame::kUPlane), |
+ mojo_frame->PlaneOffset(media::VideoFrame::kVPlane))); |
+ } |
+ |
+ if (input->HasTextures()) { |
+ // TODO(sandersd): Friend VideoFrame so that we can access the array? |
+ std::vector<gpu::MailboxHolder> mailbox_holder( |
+ media::VideoFrame::kMaxPlanes); |
+ for (size_t i = 0; i < media::VideoFrame::kMaxPlanes; i++) |
+ mailbox_holder.push_back(input->mailbox_holder(i)); |
+ return media::mojom::VideoFrameData::NewMailboxData( |
+ media::mojom::MailboxVideoFrameData::New(std::move(mailbox_holder))); |
+ } |
+ |
+ NOTREACHED() << "Unsupported VideoFrame conversion"; |
+ return nullptr; |
+ } |
+ |
+ static bool Read(media::mojom::VideoFrameDataView input, |
dcheng
2017/06/05 20:33:02
Ditto.
sandersd (OOO until July 31)
2017/06/06 01:05:47
Acknowledged.
|
+ scoped_refptr<media::VideoFrame>* output) { |
+ // View of the |data| member of the input media::mojom::VideoFrame. |
+ media::mojom::VideoFrameDataDataView data; |
+ input.GetDataDataView(&data); |
+ |
+ DCHECK_EQ(input.end_of_stream(), data.is_null()); |
+ if (input.end_of_stream()) { |
+ *output = media::VideoFrame::CreateEOSFrame(); |
+ return true; |
+ } |
+ |
+ media::VideoPixelFormat format; |
+ if (!input.ReadFormat(&format)) |
+ return false; |
+ |
+ gfx::Size coded_size; |
+ if (!input.ReadCodedSize(&coded_size)) |
+ return false; |
+ |
+ gfx::Rect visible_rect; |
+ if (!input.ReadVisibleRect(&visible_rect)) |
+ return false; |
+ |
+ gfx::Size natural_size; |
+ if (!input.ReadNaturalSize(&natural_size)) |
+ return false; |
+ |
+ base::TimeDelta timestamp; |
+ if (!input.ReadTimestamp(×tamp)) |
+ return false; |
+ |
+ if (data.is_shared_buffer_data()) { |
+ media::mojom::SharedBufferVideoFrameDataDataView shared_buffer_data; |
+ data.GetSharedBufferDataDataView(&shared_buffer_data); |
+ |
+ *output = media::MojoSharedBufferVideoFrame::Create( |
+ format, coded_size, visible_rect, natural_size, |
+ shared_buffer_data.TakeFrameData(), |
+ shared_buffer_data.frame_data_size(), shared_buffer_data.y_offset(), |
+ shared_buffer_data.u_offset(), shared_buffer_data.v_offset(), |
+ shared_buffer_data.y_stride(), shared_buffer_data.u_stride(), |
+ shared_buffer_data.v_stride(), timestamp); |
+ return true; |
+ } |
+ |
+ if (data.is_mailbox_data()) { |
+ media::mojom::MailboxVideoFrameDataDataView mailbox_data; |
+ data.GetMailboxDataDataView(&mailbox_data); |
+ |
+ std::vector<gpu::MailboxHolder> mailbox_holder; |
+ if (!mailbox_data.ReadMailboxHolder(&mailbox_holder)) |
+ return false; |
+ |
+ DCHECK_EQ(mailbox_holder.size(), media::VideoFrame::kMaxPlanes); |
+ gpu::MailboxHolder mailbox_holder_array[media::VideoFrame::kMaxPlanes]; |
+ for (size_t i = 0; i < media::VideoFrame::kMaxPlanes; i++) |
+ mailbox_holder_array[i] = mailbox_holder[i]; |
+ |
+ *output = media::VideoFrame::WrapNativeTextures( |
+ format, mailbox_holder_array, media::VideoFrame::ReleaseMailboxCB(), |
+ coded_size, visible_rect, natural_size, timestamp); |
+ return true; |
+ } |
+ |
+ // TODO(sandersd): Switch on the union tag to avoid this ugliness? |
+ NOTREACHED(); |
+ return false; |
+ } |
+}; |
+ |
+} // namespace mojo |
+ |
+#endif // MEDIA_MOJO_INTERFACES_VIDEO_FRAME_STRUCT_TRAITS_H_ |