| Index: webkit/plugins/ppapi/ppb_video_decoder_impl.cc
|
| diff --git a/webkit/plugins/ppapi/ppb_video_decoder_impl.cc b/webkit/plugins/ppapi/ppb_video_decoder_impl.cc
|
| index ec2d3f10e07813bb12b4fc99a09f190227240200..44f4b3894e42dacb803e6ecf130bdece96a49a73 100644
|
| --- a/webkit/plugins/ppapi/ppb_video_decoder_impl.cc
|
| +++ b/webkit/plugins/ppapi/ppb_video_decoder_impl.cc
|
| @@ -7,15 +7,18 @@
|
| #include <string>
|
|
|
| #include "base/logging.h"
|
| +#include "media/video/picture.h"
|
| #include "ppapi/c/dev/pp_video_dev.h"
|
| #include "ppapi/c/dev/ppb_video_decoder_dev.h"
|
| +#include "ppapi/c/dev/ppp_video_decoder_dev.h"
|
| #include "ppapi/c/pp_completion_callback.h"
|
| #include "ppapi/c/pp_errors.h"
|
| #include "webkit/plugins/ppapi/common.h"
|
| -#include "webkit/plugins/ppapi/var.h"
|
| +#include "webkit/plugins/ppapi/plugin_module.h"
|
| #include "webkit/plugins/ppapi/ppapi_plugin_instance.h"
|
| -#include "webkit/plugins/ppapi/ppb_file_ref_impl.h"
|
| +#include "webkit/plugins/ppapi/ppb_buffer_impl.h"
|
| #include "webkit/plugins/ppapi/resource_tracker.h"
|
| +#include "webkit/plugins/ppapi/var.h"
|
|
|
| namespace webkit {
|
| namespace ppapi {
|
| @@ -23,10 +26,10 @@ namespace ppapi {
|
| namespace {
|
|
|
| PP_Bool GetConfigs(PP_Instance instance_id,
|
| - PP_VideoDecoderConfig_Dev* proto_config,
|
| - PP_VideoDecoderConfig_Dev* matching_configs,
|
| - int32_t matching_configs_size,
|
| - int32_t* num_of_matching_configs) {
|
| + PP_VideoConfigElement* proto_config,
|
| + PP_VideoConfigElement* matching_configs,
|
| + uint32_t matching_configs_size,
|
| + uint32_t* num_of_matching_configs) {
|
| PluginInstance* instance = ResourceTracker::Get()->GetInstance(instance_id);
|
| if (!instance)
|
| return PP_FALSE;
|
| @@ -41,7 +44,7 @@ PP_Bool GetConfigs(PP_Instance instance_id,
|
| }
|
|
|
| PP_Resource Create(PP_Instance instance_id,
|
| - PP_VideoDecoderConfig_Dev* decoder_config) {
|
| + PP_VideoConfigElement* decoder_config) {
|
| PluginInstance* instance = ResourceTracker::Get()->GetInstance(instance_id);
|
| if (!instance)
|
| return 0;
|
| @@ -49,7 +52,7 @@ PP_Resource Create(PP_Instance instance_id,
|
| scoped_refptr<PPB_VideoDecoder_Impl> decoder(
|
| new PPB_VideoDecoder_Impl(instance));
|
|
|
| - if (!decoder->Init(const_cast<PP_VideoDecoderConfig_Dev*>(decoder_config)))
|
| + if (!decoder->Init(const_cast<PP_VideoConfigElement*>(decoder_config)))
|
| return 0;
|
|
|
| return decoder->GetReference();
|
| @@ -72,7 +75,7 @@ PP_Bool Decode(PP_Resource decoder_id,
|
|
|
| void AssignPictureBuffer(PP_Resource video_decoder,
|
| uint32_t no_of_buffers,
|
| - union PP_PictureData_Dev* picture_buffer) {
|
| + PP_PictureBuffer_Dev* picture_buffer) {
|
| scoped_refptr<PPB_VideoDecoder_Impl> decoder(
|
| Resource::GetAs<PPB_VideoDecoder_Impl>(video_decoder));
|
| if (!decoder)
|
| @@ -81,18 +84,16 @@ void AssignPictureBuffer(PP_Resource video_decoder,
|
| decoder->AssignPictureBuffer(no_of_buffers, picture_buffer);
|
| }
|
|
|
| -void ReusePictureBuffer(PP_Resource video_decoder,
|
| - union PP_PictureData_Dev* picture_buffer) {
|
| +void ReusePictureBuffer(PP_Resource video_decoder, int32_t picture_buffer_id) {
|
| scoped_refptr<PPB_VideoDecoder_Impl> decoder(
|
| Resource::GetAs<PPB_VideoDecoder_Impl>(video_decoder));
|
| if (!decoder)
|
| return;
|
|
|
| - decoder->ReusePictureBuffer(picture_buffer);
|
| + decoder->ReusePictureBuffer(picture_buffer_id);
|
| }
|
|
|
| -PP_Bool Flush(PP_Resource video_decoder,
|
| - PP_CompletionCallback callback) {
|
| +PP_Bool Flush(PP_Resource video_decoder, PP_CompletionCallback callback) {
|
| scoped_refptr<PPB_VideoDecoder_Impl> decoder(
|
| Resource::GetAs<PPB_VideoDecoder_Impl>(video_decoder));
|
| if (!decoder)
|
| @@ -131,6 +132,9 @@ PPB_VideoDecoder_Impl::PPB_VideoDecoder_Impl(PluginInstance* instance)
|
| abort_callback_(PP_BlockUntilComplete()),
|
| flush_callback_(PP_BlockUntilComplete()),
|
| bitstream_buffer_callback_(PP_BlockUntilComplete()) {
|
| + ppp_videodecoder_ =
|
| + static_cast<const PPP_VideoDecoder_Dev*>(instance->module()->
|
| + GetPluginInterface(PPP_VIDEODECODER_DEV_INTERFACE));
|
| }
|
|
|
| PPB_VideoDecoder_Impl::~PPB_VideoDecoder_Impl() {
|
| @@ -146,27 +150,35 @@ PPB_VideoDecoder_Impl* PPB_VideoDecoder_Impl::AsPPB_VideoDecoder_Impl() {
|
| }
|
|
|
| bool PPB_VideoDecoder_Impl::GetConfigs(
|
| - PP_VideoDecoderConfig_Dev* proto_config,
|
| - PP_VideoDecoderConfig_Dev* matching_configs,
|
| - int32_t matching_configs_size,
|
| - int32_t* num_of_matching_configs) {
|
| + PP_VideoConfigElement* proto_configs,
|
| + PP_VideoConfigElement* matching_configs,
|
| + uint32_t matching_configs_size,
|
| + uint32_t* num_of_matching_configs) {
|
| if (!instance())
|
| return false;
|
| if (!platform_video_decoder_.get())
|
| return false;
|
| + if (!matching_configs)
|
| + return false;
|
|
|
| - // TODO(vmr): Implement.
|
| - NOTIMPLEMENTED();
|
| + std::vector<uint32> requested;
|
| + CopyToConfigList(proto_configs, requested);
|
| + std::vector<uint32> matched = platform_video_decoder_->GetConfigs(requested);
|
|
|
| - return false;
|
| + int i;
|
| + for (i = 0; i < matched.size() && i < matching_configs_size; i++)
|
| + matching_configs[i] = matched[i];
|
| + *num_of_matching_configs = i;
|
| +
|
| + return true;
|
| }
|
|
|
| -bool PPB_VideoDecoder_Impl::Init(PP_VideoDecoderConfig_Dev* decoder_config) {
|
| +bool PPB_VideoDecoder_Impl::Init(PP_VideoConfigElement* decoder_config) {
|
| if (!instance())
|
| return false;
|
|
|
| platform_video_decoder_.reset(
|
| - instance()->delegate()->CreateVideoDecoder(decoder_config));
|
| + instance()->delegate()->CreateVideoDecoder(decoder_config, this));
|
|
|
| return platform_video_decoder_.get()? true : false;
|
| }
|
| @@ -177,9 +189,12 @@ bool PPB_VideoDecoder_Impl::Decode(
|
| if (!platform_video_decoder_.get())
|
| return false;
|
|
|
| - media::BitstreamBuffer* decode_buffer = NULL;
|
| - // TODO(vmr): Convert bitstream_buffer to BitstreamBuffer object.
|
| - NOTIMPLEMENTED();
|
| + scoped_refptr<PPB_Buffer_Impl> pepper_buffer =
|
| + Resource::GetAs<PPB_Buffer_Impl>(bitstream_buffer->bitstream);
|
| +
|
| + media::BitstreamBuffer decode_buffer(pepper_buffer->mapped_buffer(),
|
| + bitstream_buffer->bitstream_size,
|
| + bitstream_buffer->user_handle);
|
|
|
| // Store the callback to inform when bitstream buffer has been processed.
|
| // TODO(vmr): handle simultaneous decodes + callbacks.
|
| @@ -193,27 +208,24 @@ bool PPB_VideoDecoder_Impl::Decode(
|
|
|
| void PPB_VideoDecoder_Impl::AssignPictureBuffer(
|
| uint32_t no_of_picture_buffers,
|
| - PP_PictureData_Dev* picture_buffers) {
|
| + PP_PictureBuffer_Dev* picture_buffers) {
|
| if (!platform_video_decoder_.get())
|
| return;
|
|
|
| - // TODO(vmr): Map PP_PictureData_Dev into PictureBuffer object.
|
| - NOTIMPLEMENTED();
|
| -
|
| - media::VideoDecodeAccelerator::PictureBuffer* buffer = NULL;
|
| - platform_video_decoder_->ReusePictureBuffer(buffer);
|
| + std::vector<media::PictureBuffer> wrapped_buffers;
|
| + for (uint i = 0; i < no_of_picture_buffers; i++) {
|
| + PP_PictureBuffer_Dev in_buf = picture_buffers[i];
|
| + media::PictureBuffer buffer;
|
| + if (CopyToMediaPictureBuffer(in_buf, buffer))
|
| + wrapped_buffers.push_back(buffer);
|
| + }
|
| + platform_video_decoder_->AssignPictureBuffer(wrapped_buffers);
|
| }
|
|
|
| -void PPB_VideoDecoder_Impl::ReusePictureBuffer(
|
| - PP_PictureData_Dev* picture_buffer) {
|
| +void PPB_VideoDecoder_Impl::ReusePictureBuffer(int32_t picture_buffer_id) {
|
| if (!platform_video_decoder_.get())
|
| return;
|
| -
|
| - // TODO(vmr): Map PP_PictureData_Dev into PictureBuffer object.
|
| - NOTIMPLEMENTED();
|
| -
|
| - media::VideoDecodeAccelerator::PictureBuffer* buffer = NULL;
|
| - platform_video_decoder_->ReusePictureBuffer(buffer);
|
| + platform_video_decoder_->ReusePictureBuffer(picture_buffer_id);
|
| }
|
|
|
| bool PPB_VideoDecoder_Impl::Flush(PP_CompletionCallback callback) {
|
| @@ -243,54 +255,128 @@ bool PPB_VideoDecoder_Impl::Abort(PP_CompletionCallback callback) {
|
| }
|
|
|
| void PPB_VideoDecoder_Impl::ProvidePictureBuffers(
|
| - uint32_t requested_num_of_buffers,
|
| - const std::vector<uint32_t>& buffer_properties) {
|
| - // TODO(vmr): Implement.
|
| - NOTIMPLEMENTED();
|
| + uint32 requested_num_of_buffers,
|
| + gfx::Size dimensions,
|
| + media::PictureBuffer::MemoryType type) {
|
| + if (!ppp_videodecoder_)
|
| + return;
|
| +
|
| + // TODO(vrk): Compiler assert or use switch statement instead of making
|
| + // a blind cast.
|
| + PP_PictureBufferType_Dev out_type =
|
| + static_cast<PP_PictureBufferType_Dev>(type);
|
| + PP_Size out_dim = PP_MakeSize(dimensions.width(), dimensions.height());
|
| + ScopedResourceId resource(this);
|
| + ppp_videodecoder_->ProvidePictureBuffers(
|
| + resource.id, requested_num_of_buffers, out_dim, out_type);
|
| }
|
|
|
| void PPB_VideoDecoder_Impl::PictureReady(
|
| - media::VideoDecodeAccelerator::Picture* picture) {
|
| - // TODO(vmr): Implement.
|
| - NOTIMPLEMENTED();
|
| -
|
| - // Convert the picture.
|
| - // Get plugin's PPP interface function pointers.
|
| - // PPP_VideoDecoder* ppp_videodecoder;
|
| - // Call ProvidePictureBuffers function pointer and return.
|
| - // ppp_videodecoder->PictureReady(resource_decoder, picture,
|
| - // pic_buffer_used_again);
|
| + const media::Picture& picture) {
|
| + if (!ppp_videodecoder_)
|
| + return;
|
| +
|
| + ScopedResourceId resource(this);
|
| + PP_Picture_Dev out_pic;
|
| + CopyToPictureDev(picture, out_pic);
|
| + ppp_videodecoder_->PictureReady(resource.id, out_pic);
|
| }
|
|
|
| -void PPB_VideoDecoder_Impl::DismissPictureBuffer(
|
| - media::VideoDecodeAccelerator::PictureBuffer* picture_buffer) {
|
| - // TODO(vmr): Implement.
|
| - NOTIMPLEMENTED();
|
| +void PPB_VideoDecoder_Impl::DismissPictureBuffer(int32 picture_buffer_id) {
|
| + if (!ppp_videodecoder_)
|
| + return;
|
| +
|
| + ScopedResourceId resource(this);
|
| + ppp_videodecoder_->DismissPictureBuffer(resource.id, picture_buffer_id);
|
| }
|
|
|
| void PPB_VideoDecoder_Impl::NotifyEndOfStream() {
|
| - // TODO(vmr): Implement.
|
| - NOTIMPLEMENTED();
|
| -
|
| - // Get decoder's resource handle.
|
| - // PP_Resource resource_decoder;
|
| - // Get plugin's PPP interface function pointers.
|
| - // PPP_VideoDecoder* ppp_videodecoder;
|
| - // Call EndOfStream function pointer and return.
|
| - // ppp_videodecoder->EndOfStream(resource_decoder);
|
| + if (!ppp_videodecoder_)
|
| + return;
|
| +
|
| + ScopedResourceId resource(this);
|
| + ppp_videodecoder_->EndOfStream(resource.id);
|
| }
|
|
|
| void PPB_VideoDecoder_Impl::NotifyError(
|
| media::VideoDecodeAccelerator::Error error) {
|
| - // TODO(vmr): Implement.
|
| - NOTIMPLEMENTED();
|
| -
|
| - // Get decoder's resource handle.
|
| - // PP_Resource resource_decoder;
|
| - // Get plugin's PPP interface function pointers.
|
| - // PPP_VideoDecoder* ppp_videodecoder;
|
| - // Call NotifyError function pointer.
|
| - // ppp_videodecoder->NotifyError(error, error_data, data_size);
|
| + if (!ppp_videodecoder_)
|
| + return;
|
| +
|
| + ScopedResourceId resource(this);
|
| + // TODO(vrk): This is assuming VideoDecodeAccelerator::Error and
|
| + // PP_VideoDecodeError_Dev have identical enum values. There is no compiler
|
| + // assert to guarantee this. We either need to add such asserts or
|
| + // merge these two enums.
|
| + ppp_videodecoder_->NotifyError(resource.id,
|
| + static_cast<PP_VideoDecodeError_Dev>(error));
|
| +}
|
| +
|
| +bool PPB_VideoDecoder_Impl::CopyToMediaPictureBuffer(
|
| + const PP_PictureBuffer_Dev& input, media::PictureBuffer& output) {
|
| + media::PictureBuffer::Data out_data;
|
| + media::PictureBuffer::MemoryType memory_type;
|
| + switch (input.storage_type) {
|
| + case PP_PICTUREBUFFERTYPE_SYSTEM: {
|
| + memory_type = media::PictureBuffer::PICTUREBUFFER_MEMORYTYPE_SYSTEM;
|
| + scoped_refptr<PPB_Buffer_Impl> pepper_buffer =
|
| + Resource::GetAs<PPB_Buffer_Impl>(input.data.sysmem);
|
| + assert(pepper_buffer->is_mapped());
|
| + out_data.sysmem = static_cast<void*>(pepper_buffer->mapped_buffer());
|
| + break;
|
| + }
|
| + case PP_PICTUREBUFFERTYPE_GLESTEXTURE: {
|
| + memory_type = media::PictureBuffer::PICTUREBUFFER_MEMORYTYPE_GL_TEXTURE;
|
| + out_data.gles2_texture.texture_id =
|
| + input.data.gles2_texture.texture_id;
|
| + out_data.gles2_texture.context_id =
|
| + input.data.gles2_texture.context_id;
|
| + break;
|
| + }
|
| + case PP_PICTUREBUFFERTYPE_NONE: {
|
| + NOTREACHED();
|
| + return false;
|
| + }
|
| + }
|
| + gfx::Size dimensions(input.dimensions.width, input.dimensions.height);
|
| + output.Initialize(input.id, memory_type, dimensions, out_data);
|
| + return true;
|
| +}
|
| +
|
| +bool PPB_VideoDecoder_Impl::CopyToMediaPicture(
|
| + const PP_Picture_Dev& input, media::Picture& output) {
|
| + gfx::Size visible_size(input.visible_size.width, input.visible_size.height);
|
| + gfx::Size decoded_size(input.decoded_size.width, input.decoded_size.height);
|
| + output.Initialize(input.picture_buffer_id, decoded_size,
|
| + visible_size, input.bitstream_user_handle);
|
| + return true;
|
| +}
|
| +
|
| +bool PPB_VideoDecoder_Impl::CopyToPictureDev(
|
| + const media::Picture& input, PP_Picture_Dev& output) {
|
| + output.picture_buffer_id = input.GetId();
|
| + output.bitstream_user_handle = input.GetUserHandle();
|
| + output.visible_size =
|
| + PP_MakeSize(input.GetVisibleSize().width(),
|
| + input.GetVisibleSize().height());
|
| + output.decoded_size =
|
| + PP_MakeSize(input.GetDecodedSize().width(),
|
| + input.GetDecodedSize().height());
|
| + return true;
|
| +}
|
| +
|
| +bool PPB_VideoDecoder_Impl::CopyToConfigList(
|
| + const PP_VideoConfigElement* configs, std::vector<uint32>& output) {
|
| + // TODO(vrk): This is assuming PP_VideoAttributeDictionary and
|
| + // VideoAttributeKey have identical enum values. There is no compiler
|
| + // assert to guarantee this. We either need to add such asserts or
|
| + // merge PP_VideoAttributeDictionary and VideoAttributeKey.
|
| + const PP_VideoConfigElement* current = configs;
|
| + while (*current != PP_VIDEOATTR_DICTIONARY_TERMINATOR) {
|
| + output.push_back(static_cast<uint32>(*configs));
|
| + current++;
|
| + }
|
| + return true;
|
| }
|
|
|
| void PPB_VideoDecoder_Impl::OnAbortComplete() {
|
|
|