diff options
author | scherkus@chromium.org <scherkus@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-03-31 18:32:13 +0000 |
---|---|---|
committer | scherkus@chromium.org <scherkus@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-03-31 18:32:13 +0000 |
commit | acda308500fea6641a79f7584516d7d153a4a241 (patch) | |
tree | 7ce924637edc497b81c96829f6c754c60f2575e6 | |
parent | 100421d5653b09d8b61f14bee5465dfe9d1b934c (diff) | |
download | chromium_src-acda308500fea6641a79f7584516d7d153a4a241.zip chromium_src-acda308500fea6641a79f7584516d7d153a4a241.tar.gz chromium_src-acda308500fea6641a79f7584516d7d153a4a241.tar.bz2 |
Checking in major revision of Pepper video decode APIs.
Part of a patch by vmr@chromium.org:
http://codereview.chromium.org/6541068/
BUG=none
TEST=none
Review URL: http://codereview.chromium.org/6776008
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@80028 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | content/renderer/pepper_plugin_delegate_impl.cc | 99 | ||||
-rw-r--r-- | content/renderer/pepper_plugin_delegate_impl.h | 2 | ||||
-rw-r--r-- | ppapi/c/dev/pp_video_dev.h | 598 | ||||
-rw-r--r-- | ppapi/c/dev/ppb_video_decoder_dev.h | 223 | ||||
-rw-r--r-- | ppapi/c/dev/ppp_video_decoder_dev.h | 70 | ||||
-rw-r--r-- | ppapi/cpp/dev/video_decoder_dev.cc | 69 | ||||
-rw-r--r-- | ppapi/cpp/dev/video_decoder_dev.h | 168 | ||||
-rw-r--r-- | ppapi/ppapi_cpp.gypi | 1 | ||||
-rw-r--r-- | ppapi/proxy/interface_id.h | 2 | ||||
-rw-r--r-- | ppapi/tests/all_c_includes.h | 1 | ||||
-rw-r--r-- | ppapi/tests/arch_dependent_sizes_32.h | 11 | ||||
-rw-r--r-- | ppapi/tests/arch_dependent_sizes_64.h | 13 | ||||
-rw-r--r-- | webkit/plugins/ppapi/DEPS | 1 | ||||
-rw-r--r-- | webkit/plugins/ppapi/mock_plugin_delegate.cc | 4 | ||||
-rw-r--r-- | webkit/plugins/ppapi/mock_plugin_delegate.h | 4 | ||||
-rw-r--r-- | webkit/plugins/ppapi/plugin_delegate.h | 15 | ||||
-rw-r--r-- | webkit/plugins/ppapi/ppb_video_decoder_impl.cc | 263 | ||||
-rw-r--r-- | webkit/plugins/ppapi/ppb_video_decoder_impl.h | 50 |
18 files changed, 1020 insertions, 574 deletions
diff --git a/content/renderer/pepper_plugin_delegate_impl.cc b/content/renderer/pepper_plugin_delegate_impl.cc index 28bf23e..9bf35ce 100644 --- a/content/renderer/pepper_plugin_delegate_impl.cc +++ b/content/renderer/pepper_plugin_delegate_impl.cc @@ -282,94 +282,6 @@ void PlatformAudioImpl::OnLowLatencyCreated( } } -// Implements the VideoDecoder. -class PlatformVideoDecoderImpl - : public webkit::ppapi::PluginDelegate::PlatformVideoDecoder { - public: - PlatformVideoDecoderImpl() - : input_buffer_size_(0), - next_dib_id_(0), - dib_(NULL) { - memset(&decoder_config_, 0, sizeof(decoder_config_)); - memset(&flush_callback_, 0, sizeof(flush_callback_)); - } - - virtual bool Init(const PP_VideoDecoderConfig_Dev& decoder_config) { - decoder_config_ = decoder_config; - input_buffer_size_ = 1024 << 4; - - // Allocate the transport DIB. - TransportDIB* dib = TransportDIB::Create(input_buffer_size_, - next_dib_id_++); - if (!dib) - return false; - - // TODO(wjia): Create video decoder in GPU process. - // Meanwhile, delete |dib| to free the resource. - delete dib; - - return true; - } - - virtual bool Decode(PP_VideoCompressedDataBuffer_Dev& input_buffer) { - // TODO(wjia): Implement me! - NOTIMPLEMENTED(); - - input_buffers_.push(&input_buffer); - - // Copy input data to dib_ and send it to GPU video decoder. - - return false; - } - - virtual int32_t Flush(PP_CompletionCallback& callback) { - // TODO(wjia): Implement me! - NOTIMPLEMENTED(); - - // Do nothing if there is a flush pending. - if (flush_callback_.func) - return PP_ERROR_BADARGUMENT; - - flush_callback_ = callback; - - // Call GPU video decoder to flush. - - return PP_ERROR_WOULDBLOCK; - } - - virtual bool ReturnUncompressedDataBuffer( - PP_VideoUncompressedDataBuffer_Dev& buffer) { - // TODO(wjia): Implement me! - NOTIMPLEMENTED(); - - // Deliver the buffer to GPU video decoder. - - return false; - } - - void OnFlushDone() { - if (!flush_callback_.func) - return; - - flush_callback_.func(flush_callback_.user_data, PP_OK); - flush_callback_.func = NULL; - } - - virtual intptr_t GetSharedMemoryHandle() const { - return reinterpret_cast<intptr_t>(dib_.get()); - } - - private: - size_t input_buffer_size_; - int next_dib_id_; - scoped_ptr<TransportDIB> dib_; - PP_VideoDecoderConfig_Dev decoder_config_; - std::queue<PP_VideoCompressedDataBuffer_Dev*> input_buffers_; - PP_CompletionCallback flush_callback_; - - DISALLOW_COPY_AND_ASSIGN(PlatformVideoDecoderImpl); -}; - class DispatcherWrapper : public webkit::ppapi::PluginDelegate::OutOfProcessProxy { public: @@ -603,13 +515,10 @@ webkit::ppapi::PluginDelegate::PlatformContext3D* webkit::ppapi::PluginDelegate::PlatformVideoDecoder* PepperPluginDelegateImpl::CreateVideoDecoder( - const PP_VideoDecoderConfig_Dev& decoder_config) { - scoped_ptr<PlatformVideoDecoderImpl> decoder(new PlatformVideoDecoderImpl()); - - if (!decoder->Init(decoder_config)) - return NULL; - - return decoder.release(); + PP_VideoDecoderConfig_Dev* decoder_config) { + // TODO(vmr): Implement. + NOTIMPLEMENTED(); + return NULL; } void PepperPluginDelegateImpl::NumberOfFindResultsChanged(int identifier, diff --git a/content/renderer/pepper_plugin_delegate_impl.h b/content/renderer/pepper_plugin_delegate_impl.h index f0a5284..2d65ac992 100644 --- a/content/renderer/pepper_plugin_delegate_impl.h +++ b/content/renderer/pepper_plugin_delegate_impl.h @@ -89,7 +89,7 @@ class PepperPluginDelegateImpl virtual PlatformImage2D* CreateImage2D(int width, int height); virtual PlatformContext3D* CreateContext3D(); virtual PlatformVideoDecoder* CreateVideoDecoder( - const PP_VideoDecoderConfig_Dev& decoder_config); + PP_VideoDecoderConfig_Dev* decoder_config); virtual void NumberOfFindResultsChanged(int identifier, int total, bool final_result); diff --git a/ppapi/c/dev/pp_video_dev.h b/ppapi/c/dev/pp_video_dev.h index 0699994..f568105 100644 --- a/ppapi/c/dev/pp_video_dev.h +++ b/ppapi/c/dev/pp_video_dev.h @@ -1,337 +1,339 @@ -/* Copyright (c) 2010 The Chromium Authors. All rights reserved. +/* Copyright (c) 2011 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 PPAPI_C_DEV_PP_VIDEO_DEV_H_ #define PPAPI_C_DEV_PP_VIDEO_DEV_H_ +#include "ppapi/c/dev/ppb_opengles_dev.h" #include "ppapi/c/pp_bool.h" #include "ppapi/c/pp_instance.h" #include "ppapi/c/pp_macros.h" #include "ppapi/c/pp_resource.h" +#include "ppapi/c/pp_size.h" #include "ppapi/c/pp_stdint.h" -enum PP_VideoKey_Dev { - PP_VIDEOKEY_NONE = 0, - // Value is type of PP_VideoCodecId. - PP_VIDEOKEY_CODECID, - // Value is type of PP_VideoOperation. - PP_VIDEOKEY_OPERATION, - // Value is type of PP_VideoCodecProfile. - PP_VIDEOKEY_CODECPROFILE, - // Value is type of PP_VideoCodecLevel. - PP_VIDEOKEY_CODECLEVEL, - // Value is 0 or 1. - PP_VIDEOKEY_ACCELERATION, - // Value is type of PP_VideoPayloadFormat. - PP_VIDEOKEY_PAYLOADFORMAT, - // Value is type of PP_VideoFrameColorType. - PP_VIDEOKEY_COLORTYPE, - // Value is type of PP_VideoFrameSurfaceType. - PP_VIDEOKEY_SURFACETYPE, - // Value is type of PP_VideoFrameInfoFlag. - PP_VIDEOKEY_FRAMEINFOFLAG, - - // Subset for H.264 features, value of 1 means supported. This is needed in - // case decoder has partial support for certain profile. - PP_VIDEOKEY_H264FEATURE_FMO = 0x100, - PP_VIDEOKEY_H264FEATURE_ASO, - PP_VIDEOKEY_H264FEATURE_INTERLACE, - PP_VIDEOKEY_H264FEATURE_CABAC, - PP_VIDEOKEY_H264FEATURE_WEIGHTEDPREDICTION -}; -PP_COMPILE_ASSERT_ENUM_SIZE_IN_BYTES(PP_VideoKey_Dev, 4); - -enum PP_VideoDecoderEvent_Dev { - PP_VIDEODECODEREVENT_NONE = 0, - // Signaling that an error has been hit. - PP_VIDEODECODEREVENT_ERROR, - // Signaling new width/height of video frame - PP_VIDEODECODEREVENT_NEWDIMENSION, - // Signaling new cropping rectangle - PP_VIDEODECODEREVENT_NEWCROP +// Enumeration defining global dictionary ranges for various purposes that are +// used to handle the configurations of the video decoder. +enum PP_VideoAttributeDictionary { + PP_VIDEOATTR_DICTIONARY_TERMINATOR = 0, + + PP_VIDEOATTR_DICTIONARY_BITSTREAM_FORMAT_BASE = 0x100, + // Array of key/value pairs describing video configuration. + // It could include any keys from PP_VideoKey. Its last element shall be + // PP_VIDEOATTR_BITSTREAMFORMATKEY_NONE with no corresponding value. + // An example: + // { + // PP_VIDEOATTR_BITSTREAMFORMATKEY_FOURCC, PP_VIDEODECODECID_VP8, + // PP_VIDEOATTR_BITSTREAMFORMATKEY_VP8_PROFILE, (PP_VP8PROFILE_1 | + // PP_VP8PROFILE_2 | + // PP_VP8PROFILE_3), + // PP_VIDEOATTR_DICTIONARY_TERMINATOR + // }; + // Keys for defining video bitstream format. + // Terminating entry for bitstream format descriptions. + PP_VIDEOATTR_BITSTREAMFORMATKEY_NONE, + // Value is type of PP_VideoCodecFourcc. Commonly known attributes values are + // defined in PP_VideoCodecFourcc enumeration. + PP_VIDEOATTR_BITSTREAMFORMATKEY_FOURCC, + // Bitrate in bits/s. Attribute value is 32-bit unsigned integer. + PP_VIDEOATTR_BITSTREAMFORMATKEY_BITRATE, + // Width and height of the input video bitstream, if known by the application. + // Decoder will expect the bitstream to match these values and does memory + // considerations accordingly. + PP_VIDEOATTR_BITSTREAMFORMATKEY_WIDTH, + PP_VIDEOATTR_BITSTREAMFORMATKEY_HEIGHT, + // Following attributes are applicable only in case of VP8. + // Key for VP8 profile attribute. Attribute value is bitmask of flags defined + // in PP_VP8Profile_Dev enumeration. + PP_VIDEOATTR_BITSTREAMFORMATKEY_VP8_PROFILE, + // Number of partitions per picture. Attribute value is unsigned 32-bit + // integer. + PP_VIDEOATTR_BITSTREAMFORMATKEY_VP8_NUM_OF_PARTITIONS, + // Following attributes are applicable only in case of H.264. + // Value is bitmask collection from the flags defined in PP_H264Profile. + PP_VIDEOATTR_BITSTREAMFORMATKEY_H264_PROFILE, + // Value is type of PP_H264Level. + PP_VIDEOATTR_BITSTREAMFORMATKEY_H264_LEVEL, + // Value is type of PP_H264PayloadFormat_Dev. + PP_VIDEOATTR_BITSTREAMFORMATKEY_H264_PAYLOADFORMAT, + // Subset for H.264 features, attribute value 0 signifies unsupported. + // This is needed in case decoder has partial support for certain profile. + // Default for features are enabled if they're part of supported profile. + // H264 tool called Flexible Macroblock Ordering. + PP_VIDEOATTR_BITSTREAMFORMATKEY_H264_FEATURE_FMO, + // H264 tool called Arbitrary Slice Ordering. + PP_VIDEOATTR_BITSTREAMFORMATKEY_H264_FEATURE_ASO, + // H264 tool called Interlacing. + PP_VIDEOATTR_BITSTREAMFORMATKEY_H264_FEATURE_INTERLACE, + // H264 tool called Context-Adaptive Binary Arithmetic Coding. + PP_VIDEOATTR_BITSTREAMFORMATKEY_H264_FEATURE_CABAC, + // H264 tool called Weighted Prediction. + PP_VIDEOATTR_BITSTREAMFORMATKEY_H264_FEATURE_WEIGHTEDPREDICTION, + + PP_VIDEOATTR_DICTIONARY_COLOR_CORMAT_BASE = 0x1000, + // Keys for definining attributes of a color buffer. Using these attributes + // users can define color spaces in terms of red, green, blue and alpha + // components as well as with combination of luma and chroma values with + // different subsampling schemes. Also planar, semiplanar and interleaved + // formats can be described by using the provided keys as instructed. + // + // Rules for describing the color planes (1 or more) that constitute the whole + // picture are: + // 1. Each plane starts with PP_VIDEOATTR_COLORFORMATKEY_PLANE_PIXEL_SIZE + // attribute telling how many bits per pixel the plane contains. + // 2. PP_VIDEOATTR_COLORFORMATKEY_PLANE_PIXEL_SIZE attribute must be + // followed either by + // a. Red, green and blue components followed optionally by alpha size + // attribute. + // OR + // b. Luma, blue difference chroma and red difference chroma components as + // well as three sampling reference factors that tell how the chroma may + // have been subsampled with respect to luma. + // 3. Description must be terminated with PP_VIDEOATTR_COLORFORMATKEY_NONE + // key with no value for attribute. + // + // For example, semiplanar YCbCr 4:2:2 (2 planes, one containing 8-bit luma, + // the other containing two interleaved chroma data components) may be + // described with the following attributes: + // { + // PP_VIDEOATTR_COLORFORMATKEY_PLANE_PIXEL_SIZE, 8, + // PP_VIDEOATTR_COLORFORMATKEY_LUMA_SIZE, 8, + // PP_VIDEOATTR_COLORFORMATKEY_PLANE_PIXEL_SIZE, 16, + // PP_VIDEOATTR_COLORFORMATKEY_CHROMA_BLUE_SIZE, 8, + // PP_VIDEOATTR_COLORFORMATKEY_CHROMA_RED_SIZE, 8, + // PP_VIDEOATTR_COLORFORMATKEY_HORIZONTAL_SAMPLING_FACTOR_REFERENCE, 4, + // PP_VIDEOATTR_COLORFORMATKEY_CHROMA_HORIZONTAL_SUBSAMPLING_FACTOR, 2, + // PP_VIDEOATTR_COLORFORMATKEY_CHROMA_VERTICAL_SUBSAMPLING_FACTOR, 2 + // PP_VIDEOATTR_DICTIONARY_TERMINATOR + // } + // + // Another example, commonly known 16-bit RGB 565 color format may be + // specified as follows: + // { + // PP_VIDEOATTR_COLORFORMATKEY_PLANE_PIXEL_SIZE, 16, + // PP_VIDEOATTR_COLORFORMATKEY_RED_SIZE, 5, + // PP_VIDEOATTR_COLORFORMATKEY_GREEN_SIZE, 6, + // PP_VIDEOATTR_COLORFORMATKEY_BLUE_SIZE, 5, + // PP_VIDEOATTR_DICTIONARY_TERMINATOR + // } + // Total color component bits per pixel in the picture buffer. + PP_VIDEOATTR_COLORFORMATKEY_PLANE_PIXEL_SIZE, + // Bits of red per pixel in picture buffer. + PP_VIDEOATTR_COLORFORMATKEY_RED_SIZE, + // Bits of green per pixel in picture buffer. + PP_VIDEOATTR_COLORFORMATKEY_GREEN_SIZE, + // Bits of blue per pixel in picture buffer. + PP_VIDEOATTR_COLORFORMATKEY_BLUE_SIZE, + // Bits of alpha in color buffer. + PP_VIDEOATTR_COLORFORMATKEY_ALPHA_SIZE, + // Bits of luma per pixel in color buffer. + PP_VIDEOATTR_COLORFORMATKEY_LUMA_SIZE, + // Bits of blue difference chroma (Cb) data in color buffer. + PP_VIDEOATTR_COLORFORMATKEY_CHROMA_BLUE_SIZE, + // Bits of blue difference chroma (Cr) data in color buffer. + PP_VIDEOATTR_COLORFORMATKEY_CHROMA_RED_SIZE, + // Three keys to describe the subsampling of YCbCr sampled digital video + // signal. For example, 4:2:2 sampling could be defined by setting: + // PP_VIDEOATTR_COLORFORMATKEY_HORIZONTAL_SAMPLING_FACTOR_REFERENCE = 4 + // PP_VIDEOATTR_COLORFORMATKEY_CHROMINANCE_HORIZONTAL_SUBSAMPLING_FACTOR = 2 + // PP_VIDEOATTR_COLORFORMATKEY_CHROMINANCE_VERTICAL_SUBSAMPLING_FACTOR = 2 + PP_VIDEOATTR_COLORFORMATKEY_HORIZONTAL_SAMPLING_FACTOR_REFERENCE, + PP_VIDEOATTR_COLORFORMATKEY_CHROMA_HORIZONTAL_SUBSAMPLING_FACTOR, + PP_VIDEOATTR_COLORFORMATKEY_CHROMA_VERTICAL_SUBSAMPLING_FACTOR, + // Base for telling implementation specific information about the optimal + // number of picture buffers to be provided to the implementation. + PP_VIDEOATTR_DICTIONARY_PICTUREBUFFER_REQUIREMENTS_BASE = 0x10000, + // Following two keys are used to signal how many buffers are needed by the + // implementation as a function of the maximum number of reference frames set + // by the stream. Number of required buffers is + // MAX_REF_FRAMES * REFERENCE_PIC_MULTIPLIER + ADDITIONAL_BUFFERS + PP_VIDEOATTR_PICTUREBUFFER_REQUIREMENTS_ADDITIONAL_BUFFERS, + PP_VIDEOATTR_PICTUREBUFFER_REQUIREMENTS_REFERENCE_PIC_MULTIPLIER, + // If decoder does not support pixel accurate strides for picture buffer, this + // parameter tells the stride multiple that is needed by the decoder. Plugin + // must obey the given stride in its picture buffer allocations. + PP_VIDEOATTR_PICTUREBUFFER_REQUIREMENTS_STRIDE_MULTIPLE }; -PP_COMPILE_ASSERT_ENUM_SIZE_IN_BYTES(PP_VideoDecoderEvent_Dev, 4); +PP_COMPILE_ASSERT_ENUM_SIZE_IN_BYTES(PP_VideoAttributeDictionary, 4); +typedef int32_t* PP_VideoConfigElement; -enum PP_VideoDecodeError_Dev { - PP_VIDEODECODEERROR_NONE = 0, - PP_VIDEODECODEERROR_NOTSUPPORTED, - PP_VIDEODECODEERROR_INSUFFICIENTRESOURCES, - PP_VIDEODECODEERROR_UNDEFINED, - PP_VIDEODECODEERROR_BADINPUT, - PP_VIDEODECODEERROR_HARDWARE +enum PP_VideoCodecFourcc { + PP_VIDEOCODECFOURCC_NONE = 0, + PP_VIDEOCODECFOURCC_VP8 = 0x00385056, // a.k.a. Fourcc 'VP8\0'. + PP_VIDEOCODECFOURCC_H264 = 0x31637661 // a.k.a. Fourcc 'avc1'. }; -PP_COMPILE_ASSERT_ENUM_SIZE_IN_BYTES(PP_VideoDecodeError_Dev, 4); - -enum PP_VideoCodecId_Dev { - PP_VIDEODECODECID_NONE = 0, - PP_VIDEODECODECID_H264, - PP_VIDEODECODECID_VC1, - PP_VIDEODECODECID_MPEG2, - PP_VIDEODECODECID_VP8 +PP_COMPILE_ASSERT_ENUM_SIZE_IN_BYTES(PP_VideoCodecFourcc, 4); + +// VP8 specific information to be carried over the APIs. +// Enumeration for flags defining supported VP8 profiles. +enum PP_VP8Profile_Dev { + PP_VP8PROFILE_NONE = 0, + PP_VP8PROFILE_0 = 1, + PP_VP8PROFILE_1 = 1 << 1, + PP_VP8PROFILE_2 = 1 << 2, + PP_VP8PROFILE_3 = 1 << 3 }; -PP_COMPILE_ASSERT_ENUM_SIZE_IN_BYTES(PP_VideoCodecId_Dev, 4); - -enum PP_VideoOperation_Dev { - PP_VIDEOOPERATION_NONE = 0, - PP_VIDEOOPERATION_DECODE, - PP_VIDEOOPERATION_ENCODE +PP_COMPILE_ASSERT_ENUM_SIZE_IN_BYTES(PP_VP8Profile_Dev, 4); + +// H.264 specific information to be carried over the APIs. +// Enumeration for flags defining supported H.264 profiles. +enum PP_H264Profile_Dev { + PP_H264PROFILE_NONE = 0, + PP_H264PROFILE_BASELINE = 1, + PP_H264PROFILE_MAIN = 1 << 2, + PP_H264PROFILE_EXTENDED = 1 << 3, + PP_H264PROFILE_HIGH = 1 << 4, + PP_H264PROFILE_HIGH10PROFILE = 1 << 5, + PP_H264PROFILE_HIGH422PROFILE = 1 << 6, + PP_H264PROFILE_HIGH444PREDICTIVEPROFILE = 1 << 7, + PP_H264PROFILE_SCALABLEBASELINE = 1 << 8, + PP_H264PROFILE_SCALABLEHIGH = 1 << 9, + PP_H264PROFILE_STEREOHIGH = 1 << 10, + PP_H264PROFILE_MULTIVIEWHIGH = 1 << 11 }; -PP_COMPILE_ASSERT_ENUM_SIZE_IN_BYTES(PP_VideoOperation_Dev, 4); - -enum PP_VideoCodecProfile_Dev { - PP_VIDEOCODECPROFILE_NONE = 0, - PP_VIDEOCODECPROFILE_H264_BASELINE, - PP_VIDEOCODECPROFILE_H264_MAIN, - PP_VIDEOCODECPROFILE_H264_EXTENDED, - PP_VIDEOCODECPROFILE_H264_HIGH, - PP_VIDEOCODECPROFILE_H264_SCALABLEBASELINE, - PP_VIDEOCODECPROFILE_H264_SCALABLEHIGH, - PP_VIDEOCODECPROFILE_H264_STEREOHIGH, - PP_VIDEOCODECPROFILE_H264_MULTIVIEWHIGH, - - PP_VIDEOCODECPROFILE_VC1_SIMPLE = 0x40, - PP_VIDEOCODECPROFILE_VC1_MAIN, - PP_VIDEOCODECPROFILE_VC1_ADVANCED, - - PP_VIDEOCODECPROFILE_MPEG2_SIMPLE = 0x80, - PP_VIDEOCODECPROFILE_MPEG2_MAIN, - PP_VIDEOCODECPROFILE_MPEG2_SNR, - PP_VIDEOCODECPROFILE_MPEG2_SPATIAL, - PP_VIDEOCODECPROFILE_MPEG2_HIGH +PP_COMPILE_ASSERT_ENUM_SIZE_IN_BYTES(PP_H264Profile_Dev, 4); + +// Enumeration for defining H.264 level of decoder implementation. +enum PP_H264Level_Dev { + PP_H264LEVEL_NONE = 0, + PP_H264LEVEL_10 = 1, + PP_H264LEVEL_1B = PP_H264LEVEL_10 | 1 << 1, + PP_H264LEVEL_11 = PP_H264LEVEL_1B | 1 << 2, + PP_H264LEVEL_12 = PP_H264LEVEL_11 | 1 << 3, + PP_H264LEVEL_13 = PP_H264LEVEL_12 | 1 << 4, + PP_H264LEVEL_20 = PP_H264LEVEL_13 | 1 << 5, + PP_H264LEVEL_21 = PP_H264LEVEL_20 | 1 << 6, + PP_H264LEVEL_22 = PP_H264LEVEL_21 | 1 << 7, + PP_H264LEVEL_30 = PP_H264LEVEL_22 | 1 << 8, + PP_H264LEVEL_31 = PP_H264LEVEL_30 | 1 << 9, + PP_H264LEVEL_32 = PP_H264LEVEL_31 | 1 << 10, + PP_H264LEVEL_40 = PP_H264LEVEL_32 | 1 << 11, + PP_H264LEVEL_41 = PP_H264LEVEL_40 | 1 << 12, + PP_H264LEVEL_42 = PP_H264LEVEL_41 | 1 << 13, + PP_H264LEVEL_50 = PP_H264LEVEL_42 | 1 << 14, + PP_H264LEVEL_51 = PP_H264LEVEL_50 | 1 << 15 }; -PP_COMPILE_ASSERT_ENUM_SIZE_IN_BYTES(PP_VideoCodecProfile_Dev, 4); - -enum PP_VideoCodecLevel_Dev { - PP_VIDEOCODECLEVEL_NONE = 0, - PP_VIDEOCODECLEVEL_H264_10, - PP_VIDEOCODECLEVEL_H264_1B, - PP_VIDEOCODECLEVEL_H264_11, - PP_VIDEOCODECLEVEL_H264_12, - PP_VIDEOCODECLEVEL_H264_13, - PP_VIDEOCODECLEVEL_H264_20, - PP_VIDEOCODECLEVEL_H264_21, - PP_VIDEOCODECLEVEL_H264_22, - PP_VIDEOCODECLEVEL_H264_30, - PP_VIDEOCODECLEVEL_H264_31, - PP_VIDEOCODECLEVEL_H264_32, - PP_VIDEOCODECLEVEL_H264_40, - PP_VIDEOCODECLEVEL_H264_41, - PP_VIDEOCODECLEVEL_H264_42, - PP_VIDEOCODECLEVEL_H264_50, - PP_VIDEOCODECLEVEL_H264_51, - - PP_VIDEOCODECLEVEL_VC1_LOW = 0x40, - PP_VIDEOCODECLEVEL_VC1_MEDIUM, - PP_VIDEOCODECLEVEL_VC1_HIGH, - PP_VIDEOCODECLEVEL_VC1_L0, - PP_VIDEOCODECLEVEL_VC1_L1, - PP_VIDEOCODECLEVEL_VC1_L2, - PP_VIDEOCODECLEVEL_VC1_L3, - PP_VIDEOCODECLEVEL_VC1_L4, - - PP_VIDEOCODECLEVEL_MPEG2_LOW = 0x80, - PP_VIDEOCODECLEVEL_MPEG2_MAIN, - PP_VIDEOCODECLEVEL_MPEG2_HIGH1440, - PP_VIDEOCODECLEVEL_MPEG2_HIGH +PP_COMPILE_ASSERT_ENUM_SIZE_IN_BYTES(PP_H264Level_Dev, 4); + +// Enumeration to describe which payload format is used within the exchanged +// bitstream buffers. +enum PP_H264PayloadFormat_Dev { + PP_H264PAYLOADFORMAT_NONE = 0, + // NALUs separated by Start Code. + PP_H264PAYLOADFORMAT_BYTESTREAM = 1, + // Exactly one raw NALU per buffer. + PP_H264PAYLOADFORMAT_ONE_NALU_PER_BUFFER = 1 << 1, + // NALU separated by 1-byte interleaved length field. + PP_H264PAYLOADFORMAT_ONE_BYTE_INTERLEAVED_LENGTH = 1 << 2, + // NALU separated by 2-byte interleaved length field. + PP_H264PAYLOADFORMAT_TWO_BYTE_INTERLEAVED_LENGTH = 1 << 3, + // NALU separated by 4-byte interleaved length field. + PP_H264PAYLOADFORMAT_FOUR_BYTE_INTERLEAVED_LENGTH = 1 << 4 }; -PP_COMPILE_ASSERT_ENUM_SIZE_IN_BYTES(PP_VideoCodecLevel_Dev, 4); - -enum PP_VideoPayloadFormat_Dev { - PP_VIDEOPAYLOADFORMAT_NONE = 0, - PP_VIDEOPAYLOADFORMAT_BYTESTREAM, - PP_VIDEOPAYLOADFORMAT_RTPPAYLOAD +PP_COMPILE_ASSERT_ENUM_SIZE_IN_BYTES(PP_H264PayloadFormat_Dev, 4); + +// Enumeration to determine which type of memory for buffer is used. +enum PP_PictureBufferType_Dev { + PP_PICTUREBUFFERTYPE_NONE = 0, + // System memory a.k.a. RAM. + PP_PICTUREBUFFERTYPE_SYSTEM = 1, + // GLES texture allocated using OpenGL ES APIs. + PP_PICTUREBUFFERTYPE_GLESTEXTURE = 1 << 1 }; -PP_COMPILE_ASSERT_ENUM_SIZE_IN_BYTES(PP_VideoPayloadFormat_Dev, 4); +PP_COMPILE_ASSERT_ENUM_SIZE_IN_BYTES(PP_PictureBufferType_Dev, 4); -enum PP_VideoFrameColorType_Dev { - PP_VIDEOFRAMECOLORTYPE_NONE = 0, - PP_VIDEOFRAMECOLORTYPE_RGB565, - PP_VIDEOFRAMECOLORTYPE_ARGB8888, - PP_VIDEOFRAMECOLORTYPE_YUV, - PP_VIDEOFRAMECOLORTYPE_Monochrome, - PP_VIDEOFRAMECOLORTYPE_YUV420PLANAR, - PP_VIDEOFRAMECOLORTYPE_YUV422PLANAR, - PP_VIDEOFRAMECOLORTYPE_YUV444PLANAR -}; -PP_COMPILE_ASSERT_ENUM_SIZE_IN_BYTES(PP_VideoFrameColorType_Dev, 4); +// Structure to describe storage properties for a picture. +struct PP_PictureBufferProperties_Dev { + // Size of the storage (as per width & height in pixels). + struct PP_Size size; -enum PP_VideoFrameSurfaceType_Dev { - PP_VIDEOFRAMESURFACETYPE_NONE = 0, - PP_VIDEOFRAMESURFACETYPE_SYSTEMMEMORY, - PP_VIDEOFRAMESURFACETYPE_GLTEXTURE, - PP_VIDEOFRAMESURFACETYPE_PIXMAP -}; -PP_COMPILE_ASSERT_ENUM_SIZE_IN_BYTES(PP_VideoFrameSurfaceType_Dev, 4); + // Type of the picture buffer (GLES, system memory). + enum PP_PictureBufferType_Dev type; -enum PP_VideoFrameInfoFlag_Dev { - PP_VIDEOFRAMEINFOFLAG_NONE = 0, - // Indicate this is the end of stream. Used by both plugin and browser. - PP_VIDEOFRAMEINFOFLAG_EOS = 1 << 0, - // Decode the frame only, don't return decoded frame. Used by plugin. - PP_VIDEOFRAMEINFOFLAG_NOEMIT = 1 << 1, - // Indicate this is an anchor frame. Used by plugin. - PP_VIDEOFRAMEINFOFLAG_SYNCFRAME = 1 << 2, - // Indicate the decoded frame has data corruption. Used by browser. - PP_VIDEOFRAMEINFOFLAG_DATACORRUPT = 1 << 3 + // Key-attribute pairs defining color format for the buffer. + PP_VideoConfigElement color_format; }; -PP_COMPILE_ASSERT_ENUM_SIZE_IN_BYTES(PP_VideoFrameInfoFlag_Dev, 4); - -enum PP_VideoFrameBufferConst_Dev { - // YUV formats - PP_VIDEOFRAMEBUFFER_YPLANE = 0, - PP_VIDEOFRAMEBUFFER_UPLANE = 1, - PP_VIDEOFRAMEBUFFER_VPLANE = 2, - PP_VIDEOFRAMEBUFFER_NUMBERYUVPLANES = 3, - - // RGBA formats - PP_VIDEOFRAMEBUFFER_RGBAPLANE = 0, - PP_VIDEOFRAMEBUFFER_NUMBERRGBAPLANES = 1, - PP_VIDEOFRAMEBUFFER_MAXNUMBERPLANES = 4 +// Requested decoder configuration and callback from plugin. +struct PP_VideoDecoderConfig_Dev { + // Input bitstream properties. + PP_VideoConfigElement bitstream_properties; + // Output picture properties. + struct PP_PictureBufferProperties_Dev picture_properties; }; -PP_COMPILE_ASSERT_ENUM_SIZE_IN_BYTES(PP_VideoFrameBufferConst_Dev, 4); - -typedef int64_t PP_VideoDecodeData_Dev; -PP_COMPILE_ASSERT_SIZE_IN_BYTES(PP_VideoDecodeData_Dev, 8); -// Array of key/value pairs describing video configuration. -// It could include any keys from PP_VideoKey. Its last element shall be -// PP_VIDEOKEY_NONE with no corresponding value. -// An example: -// { -// PP_VIDEOKEY_CODECID, PP_VIDEODECODECID_H264, -// PP_VIDEOKEY_OPERATION, PP_VIDEOOPERATION_DECODE, -// PP_VIDEOKEY_CODECPROFILE, PP_VIDEOCODECPROFILE_H264_HIGH, -// PP_VIDEOKEY_CODECLEVEL, PP_VIDEOCODECLEVEL_H264_41, -// PP_VIDEOKEY_ACCELERATION, 1 -// PP_VIDEOKEY_NONE, -// }; -typedef int32_t* PP_VideoConfig_Dev; -typedef int32_t PP_VideoConfigElement_Dev; -PP_COMPILE_ASSERT_SIZE_IN_BYTES(PP_VideoConfigElement_Dev, 4); +// The data structure for video bitstream buffer. +struct PP_VideoBitstreamBuffer_Dev { + // Buffer to hold the bitstream data. Should be allocated using the PPB_Buffer + // interface for consistent interprocess behaviour. + PP_Resource bitstream; -// The data structure for compressed data buffer. -struct PP_VideoCompressedDataBuffer_Dev { - // The buffer is created through PPB_Buffer API. - // TODO(wjia): would uint8_t* be good, too? - PP_Resource buffer; + // Size of the bitstream contained in buffer (in bytes). + int32_t bitstream_size; - // number of bytes with real data in the buffer. - int32_t filled_size; + // Optional pointer for application to associate information with a sample. + // The pointer will be associated with the resulting decoded picture. + // Typically applications associate timestamps with buffers. + void* user_handle; - // Bit mask of PP_VideoFrameInfoFlag. - uint32_t flags; - - // Padding to ensure the PP_Resource is 8-byte aligned relative to the - // start of the struct. This helps ensure PP_VideoFrameBuffer_Dev has - // consistent size and alignment across compilers. - int32_t padding; - - // Time stamp of the frame in microsecond. - uint64_t time_stamp_us; + // TODO(vmr): Add information about access unit boundaries. }; -PP_COMPILE_ASSERT_STRUCT_SIZE_IN_BYTES(PP_VideoCompressedDataBuffer_Dev, 24); - -struct PP_VideoFrameBuffer_Dev { - union { - struct { - struct { - int32_t width; - int32_t height; - int32_t stride; - - // TODO(wjia): uint8* would be better for some cases. - PP_Resource buffer; - } data_plane[PP_VIDEOFRAMEBUFFER_MAXNUMBERPLANES]; - - int32_t planes; - - // This padding makes sure the sys_mem struct's size is a multiple of 8 - // bytes, ensuring that handle is always 8-byte aligned relative to the - // start of the PP_VideoFrameBuffer_Dev struct. - int32_t padding; - } sys_mem; - // Handle for pixmap, gl texture, etc. - void* handle; - } buffer; - - // Storage for decoder to save some private data. It could be useful when - // plugin returns frame buffer to decoder. - void* private_handle; - - // In some 32-bit platforms (NaCl and Win32), this struct is 8-byte aligned - // due to the PP_Resource above. That causes the compiler to pad it an extra - // 4 bytes on the end. In other 32-bit platforms, there is no such pad. This - // padding ensures that the size is consistent on 32-bit platforms (and it - // is still consistent on 64-bit platforms, just bigger than it would be - // without the padding). - int32_t padding; +// Union for specifying picture data. +union PP_PictureData_Dev { + // Resource representing system memory from shared memory address space. + // Use PPB_Buffer_Dev interface to handle this resource. + PP_Resource sysmem; + // Structure to define explicitly a GLES2 context. + struct { + // Context allocated using. Use PPB_Context3D_Dev interface to handle this + // resource. + PP_Resource context; + // Texture ID in the given context where picture is stored. + GLuint textureId; + } gles2_texture; + // Client-specified id for the picture buffer. By using this value client can + // keep track of the buffers it has assigned to the video decoder and how they + // are passed back to it. + int32_t id; }; -struct PP_VideoUncompressedDataBuffer_Dev { - PP_VideoConfig_Dev format; - - // Bit mask of PP_VideoFrameInfoFlag. - uint32_t flags; - - // Time stamp of the frame in microsecond. - uint64_t time_stamp_us; - - struct PP_VideoFrameBuffer_Dev buffer; - - // Output from decoder, indicating the decoded frame has error pixels. This - // could be resulted from corrupted input bit stream and error concealment - // in decoding. PP_TRUE indicates error. - // TODO(wjia): add more info about error pixels, such as error MB map, etc. - PP_Bool error; - - // In some 32-bit platforms (NaCl and Win32), this struct is 8-byte aligned - // due to the uint64_t and buffer above. That causes the compiler to pad it - // an extra 4 bytes on the end. In other 32-bit platforms, there is no such - // pad. This padding ensures that the size is consistent on 32-bit platforms - // (and it is still consistent on 64-bit platforms, just bigger than it would - // be without the padding). - int32_t padding; +// Structure to describe the decoded output picture for the plug-in along with +// optional metadata associated with the picture. +struct PP_Picture_Dev { + // Resource that represents the buffer where the picture data is stored. + // Actual implementation style of the picture buffer may be OpenGL ES texture + // (allocated using PPB_OpenGLES2_Dev) or system memory (allocated using + // PPB_Buffer_Dev). + union PP_PictureData_Dev picture_data; + + // Optional pointer to associated metadata with the picture. Typical + // information carried over metadata includes timestamps. If there is + // multiple NAL units each with their own respective metadata, only the + // metadata from the latest call to Decode will be carried over. + void* metadata; }; -// Plugin callback for decoder to deliver decoded frame buffers. -// |format| in |buffer| specifies the format of decoded frame, with -// PP_VIDEOKEY_COLORTYPE and PP_VIDEOKEY_SURFACETYPE required. -typedef void (*PP_VideoDecodeOutputCallback_Func_Dev)( - PP_Instance instance, - struct PP_VideoUncompressedDataBuffer_Dev* buffer); - -// Plugin callback for decoder to return input data buffers. -// Plugin can optionally provide this callback only when it wants to recycle -// input data buffers. -typedef void (*PP_VideoDecodeInputCallback_Func_Dev)( - PP_Instance instance, - struct PP_VideoCompressedDataBuffer_Dev* buffer); - -// Event handling Function for decoder to deliver events to plugin. -// The correspondence between event and data1, data2: -// When event == PP_VIDEODECODEREVENT_ERROR, -// data1 is type of PP_VideoDecodeError id and data2 is ignored; -// When event == PP_VIDEODECODEREVENT_NEWDIMENSION, -// data1 is type of PP_Size*, data2 is ignored; -// When event == PP_VIDEODECODEREVENT_NEWCROP, -// data1 is type of PP_Rect*, data2 is ignored; -typedef void (*PP_VideoDecodeEventHandler_Func_Dev)( - PP_Instance instance, - enum PP_VideoDecoderEvent_Dev event, - PP_VideoDecodeData_Dev data1, - PP_VideoDecodeData_Dev data2); - -// Requested decoder configuration and callback from plugin. -struct PP_VideoDecoderConfig_Dev { - PP_VideoConfig_Dev input_format; - PP_VideoConfig_Dev output_format; - PP_VideoDecodeOutputCallback_Func_Dev output_callback; - PP_VideoDecodeInputCallback_Func_Dev input_callback; - PP_VideoDecodeEventHandler_Func_Dev event_handler; +// Enumeration for error events that may be reported through +// PP_VideoDecodeErrorHandler_Func_Dev callback function to the plugin. Default +// error handling functionality expected from the plugin is to Flush and Destroy +// the decoder. +enum PP_VideoDecodeError_Dev { + PP_VIDEODECODEERROR_NONE = 0, + // Decoder has not been initialized and configured properly. + PP_VIDEODECODEERROR_UNINITIALIZED, + // Decoder does not support feature of configuration or bitstream. + PP_VIDEODECODEERROR_UNSUPPORTED, + // Decoder was given bitstream that would result in output pictures but it + // has not been provided buffers to do all this. + PP_VIDEODECODEERROR_INSUFFICIENT_BUFFERS, + // Decoder cannot continue operation due to insufficient resources for the + // current configuration. + PP_VIDEODECODEERROR_INSUFFICIENTRESOURCES, + // Decoder hardware has reported hardware error. + PP_VIDEODECODEERROR_HARDWARE }; +PP_COMPILE_ASSERT_ENUM_SIZE_IN_BYTES(PP_VideoDecodeError_Dev, 4); #endif /* PPAPI_C_DEV_PP_VIDEO_DEV_H_ */ - diff --git a/ppapi/c/dev/ppb_video_decoder_dev.h b/ppapi/c/dev/ppb_video_decoder_dev.h index ceb4c80..9e9d239 100644 --- a/ppapi/c/dev/ppb_video_decoder_dev.h +++ b/ppapi/c/dev/ppb_video_decoder_dev.h @@ -1,38 +1,78 @@ -/* Copyright (c) 2010 The Chromium Authors. All rights reserved. +/* Copyright (c) 2011 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 PPAPI_C_DEV_PPB_VIDEO_DECODER_DEV_H_ #define PPAPI_C_DEV_PPB_VIDEO_DECODER_DEV_H_ -#include "ppapi/c/pp_bool.h" #include "ppapi/c/dev/pp_video_dev.h" -#include "ppapi/c/pp_module.h" -#include "ppapi/c/pp_resource.h" -#include "ppapi/c/pp_stdint.h" #include "ppapi/c/pp_completion_callback.h" +#include "ppapi/c/pp_var.h" -#define PPB_VIDEODECODER_DEV_INTERFACE "PPB_VideoDecoder(Dev);0.4" +#define PPB_VIDEODECODER_DEV_INTERFACE "PPB_VideoDecoder(Dev);0.5" +// Video decoder interface. +// +// Basic usage: +// 1. Use GetConfigs() to query potential configurations. Configuration +// information includes: +// a. Bitstream format. +// b. Output picture format. +// c. Output picture buffer storage type. +// 2. Select configuration that suits you and Create() the decoder with the +// chosen configuration. +// 3. Get the input bitstream data and Decode() it until streaming should +// stop or pause. +// +// Once decoder has processed a data from the bitstream buffer provided for +// decoding, it will call callback provided by the plug-in for letting the +// plug-in to know when it can release or recycle each buffer. +// +// Once decoder knows the output picture properties it needs, it will call +// callback provided by the plug-in for providing the needed buffers. Plug-in +// must provide there to the decoder. +// +// Errors are reported asynchronously to plug-in by calling the callback +// provided by the plug-in for error handling. +// +// Information to be conveyed over the API: +// 1. Bitstream format. +// 2. Output picture format. +// 3. Output picture buffer storage type. +// struct PPB_VideoDecoder_Dev { - // Queries capability of the decoder for |codec|. - // |codec| is the requested codec id. - // |configs| is a pointer to a buffer containing |config_size| elements. - // The number of configurations is returned in |num_config|. Element 0 through - // |num_config| - 1 of |configs| are filled in with valid PP_VideoConfig's. - // No more than |config_size| PP_VideoConfig's will be returned even if more - // are available on the device. - // When this function is called with |configs| = NULL, then no configurations - // are returned, but the total number of configurations available will be - // returned in |num_config|. + // Queries capability of the decoder implementation for a specific codec. + // + // Parameters: + // |instance| is the instance handle for the plugin. + // |proto_config| is a pointer to a prototype decoder configuration + // whose values are matched against supported configs. The intersection + // of prototype configuration and supported configs is stored in + // |matching_configs|. + // |matching_configs| is a pointer to a buffer where information about + // supported configuration elements that match the |proto_config| are + // stored. + // |matching_configs_size| tells for how many PP_VideoConfig_Dev elements + // the buffer pointed by |matching_configs| has space for. + // |num_of_matching_configs| is output parameter telling how many configs + // are filled with valid video config elements in the buffer pointed by + // |matching_configs| after successful call to the function. + // + // After the call |num_config| - 1 of PP_VideoConfig_Dev elements are filled + // with valid elements to the buffer pointed by |matching_configs|. No more + // than |config_size| PP_VideoConfig_Devs will be returned even if more would + // be available for the decoder device. + // + // When this function is called with |matching_configs| = NULL, then no + // configurations are returned, but the total number of PP_VideoConfig_Devs + // available will be returned in |num_of_matching_configs|. // // Returns PP_TRUE on success, PP_FALSE otherwise. - // NOTE: browser owns the memory of all PP_VideoConfig's. - PP_Bool (*GetConfig)(PP_Instance instance, - enum PP_VideoCodecId_Dev codec, - PP_VideoConfig_Dev* configs, - int32_t config_size, - int32_t* num_config); + PP_Bool (*GetConfigs)(PP_Instance instance, + struct PP_VideoDecoderConfig_Dev* proto_config, + struct PP_VideoDecoderConfig_Dev* matching_configs, + int32_t matching_configs_size, + int32_t* num_of_matching_configs); // Creates a video decoder with requested |decoder_config|. // |input_format| in |decoder_config| specifies the format of input access @@ -41,48 +81,121 @@ struct PPB_VideoDecoder_Dev { // information such as PP_VIDEOKEY_ACCELERATION, to let browser choose // the most appropriate decoder. // - // |output_format| in |decoder_config| specifies desired decoded frame buffer - // format, with PP_VIDEOKEY_COLORTYPE and PP_VIDEOKEY_SURFACETYPE required. - // - // |output_callback| in |decoder_config| specifies the callback function - // for decoder to deliver decoded frame buffers. Decoder shall retain it. - // - // |input_callback| in |decoder_config| specifies the callback function - // for decoder to return compressed data buffers to plugin. Decoder shall - // retain it. When plugin doesn't expect buffer recycling, it shall set - // |input_callback| to NULL. In this case, plugin shall allocate buffer via - // |MemAlloc| in PPB_Core interface, and decoder will free buffer via - // |MemFree| in the same API. - // - // |event_handler| in |decoder_config| specifies the function for decoder - // to deliver events to plugin. Decoder shall retain it. + // Parameters: + // |instance| pointer to the plugin instance. + // |dec_config| the configuration which to use to initialize the decoder. // // The created decoder is returned as PP_Resource. NULL means failure. PP_Resource (*Create)(PP_Instance instance, - const struct PP_VideoDecoderConfig_Dev* decoder_config); + struct PP_VideoDecoderConfig_Dev* dec_config); + + // Tests whether |resource| is a video decoder created through Create + // function of this interface. + // + // Parameters: + // |resource| is handle to resource to test. + // + // Returns true if is a video decoder, false otherwise. + PP_Bool (*IsVideoDecoder)(PP_Resource resource); - // Sends bit stream in |input_buffer| to the decoder. - // This is a non-blocking call. - // The decoded frame will be returned by decoder calling |output_callback| - // provided by plugin during creation of decoder. - // The input data buffer is returned to plugin by decoder only when plugin - // provides |input_callback|. + // Dispatches bitstream buffer to the decoder. This is asynchronous and + // non-blocking function. + // + // Parameters: + // |video_decoder| is the previously created handle to the decoder instance. + // |bitstream_buffer| is the bitstream buffer that contains the input data. + // |callback| will be called when |bitstream_buffer| has been processed by + // the decoder. + // // Returns PP_TRUE on decoder successfully accepting buffer, PP_FALSE // otherwise. + PP_Bool (*Decode)(PP_Resource video_decoder, + struct PP_VideoBitstreamBuffer_Dev* bitstream_buffer, + struct PP_CompletionCallback callback); + + // Provides the decoder with picture buffers for video decoding. This + // function should be called when decoder has issued ProvidePictureBuffers + // callback to the plugin with buffer requirements. + // + // If the plugin is can determine how many and what kind of buffers are + // needed by the decoder it can provide them in advance. For this purpose + // the configuration map can provide how many extra buffers the decoder + // implementation requires for seamless operation. + // + // The decoder will pause if AssignPictureBuffer hasn't been called with + // sufficient buffers. // - PP_Bool (*Decode)(PP_Resource decoder, - struct PP_VideoCompressedDataBuffer_Dev* input_buffer); + // If the decoder rejects the buffers it will return the buffers and issue + // ProvidePictureBuffers again. + // + // If AssignPictureBuffer is called multiple times the decoder will add them + // to its pool of output pictures. + // + // TODO(vmr): this API feels too flexible... should we make it more strict + // where the decoder errors on bad buffers/duplicate buffers? Perhaps + // AssignPictureBuffer should only get called in response to + // ProvidePictureBuffer? + // + // Parameters: + // |video_decoder| is the previously created handle to the decoder instance. + // |no_of_buffers| how many buffers are behind picture buffer pointer. + // |picture_buffer| contains the reference to the picture buffer that was + // processed. + void (*AssignPictureBuffer)(PP_Resource video_decoder, + uint32_t no_of_buffers, + union PP_PictureData_Dev* picture_buffer); - // Requests the decoder to flush its input and output buffers. Once done with - // flushing, the decode will call the |callback|. - int32_t (*Flush)(PP_Resource decoder, struct PP_CompletionCallback callback); + // Tells the decoder to reuse given picture buffer. Typical use of this + // function is to call from PictureReady callback to recycle picture buffer + // back to the decoder after blitting the image so that decoder can use the + // image for output again. + // + // The decoder will ignore any picture buffer not previously provided via + // AssignPictureBuffer. + // + // TODO(vmr): figure out how the sync will be handled with command buffer as + // there will be possibly lag due to command buffer implementation + // to actual GL swap. At that moment decoder may have already taken + // the GL textures for writing output again. + // + // Parameters: + // |video_decoder| is the previously created handle to the decoder instance. + // |picture_buffer| contains the reference to the picture buffer that was + // processed. + void (*ReusePictureBuffer)(PP_Resource video_decoder, + union PP_PictureData_Dev* picture_buffer); - // Plugin sends uncompressed data buffers to the decoder. - // Returns PP_TRUE on decoder successfully accepting the buffer, PP_FALSE - // otherwise. - PP_Bool (*ReturnUncompressedDataBuffer)(PP_Resource decoder, - struct PP_VideoUncompressedDataBuffer_Dev* buffer); + // Dispatches flushing request to the decoder to flush both input and output + // buffers. Successful flushing will result in output of the pictures and + // buffers held inside the decoder and returning of bitstream buffers using + // the callbacks implemented by the plug-in. Once done with flushing, the + // decode will call the |callback|. + // + // Parameters: + // |video_decoder| is the previously created handle to the decoder instance. + // |callback| is one-time callback that will be called once the flushing + // request has been completed. + // + // Returns PP_TRUE on acceptance of flush request and PP_FALSE if request to + // flush is rejected by the decoder. + PP_Bool (*Flush)(PP_Resource video_decoder, + struct PP_CompletionCallback callback); + + // Dispatches abortion request to the decoder to abort decoding as soon as + // possible and will not output anything or generate new callbacks. |callback| + // will be called as soon as abortion has been finished. After abortion all + // buffers can be considered dismissed even when there has not been callbacks + // to dismiss them. + // + // Parameters: + // |video_decoder| is the previously created handle to the decoder instance. + // |callback| is one-time callback that will be called once the abortion + // request has been completed. + // + // Returns PP_TRUE on acceptance of abort request and PP_FALSE if request to + // abort is rejected by the decoder. + PP_Bool (*Abort)(PP_Resource video_decoder, + struct PP_CompletionCallback callback); }; #endif /* PPAPI_C_DEV_PPB_VIDEO_DECODER_DEV_H_ */ - diff --git a/ppapi/c/dev/ppp_video_decoder_dev.h b/ppapi/c/dev/ppp_video_decoder_dev.h new file mode 100644 index 0000000..3fb265c --- /dev/null +++ b/ppapi/c/dev/ppp_video_decoder_dev.h @@ -0,0 +1,70 @@ +/* Copyright (c) 2011 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 PPAPI_C_DEV_PPP_VIDEO_DECODER_DEV_H_ +#define PPAPI_C_DEV_PPP_VIDEO_DECODER_DEV_H_ + +#include "ppapi/c/dev/pp_video_dev.h" + +#define PPP_VIDEODECODER_DEV_INTERFACE "PPP_VideoDecoder(Dev);0.1" + +// PPP_VideoDecoder_Dev structure contains the function pointers that the +// plugin MUST implement to provide services needed by the video decoder +// implementation. +struct PPP_VideoDecoder_Dev { + // Callback function to provide buffers for the decoded output pictures. If + // succeeds plugin must provide buffers through AssignPictureBuffers function + // to the API. If |req_num_of_bufs| matching exactly the specification + // given in |props| cannot be allocated decoder should be destroyed. + // + // Decoding will not proceed until buffers have been provided. + // + // Parameters: + // |decoder| is pointer to the Pepper Video Decoder instance. + // |req_num_of_bufs| tells how many buffers are needed by the decoder. + // |props| tells the properties that are required from the textures. + void (*ProvidePictureBuffers)( + PP_Resource decoder, + uint32_t req_num_of_bufs, + const struct PP_PictureBufferProperties_Dev* props); + + // Callback function for decoder to deliver unneeded picture buffers back to + // the plugin. + // + // Parameters: + // |decoder| is pointer to the Pepper Video Decoder instance. + // |picture_buffer| points to the picture buffer that is no longer needed. + void (*DismissPictureBuffer)(PP_Resource decoder, + union PP_PictureData_Dev* picture_buffer); + + // Callback function for decoder to deliver decoded pictures ready to be + // displayed. Decoder expects the plugin to return the buffer back to the + // decoder through ReusePictureBuffer function in PPB Video Decoder API. + // + // Parameters: + // |decoder| is pointer to the Pepper Video Decoder instance. + // |picture| is the picture that is ready. + void (*PictureReady)(PP_Resource decoder, + struct PP_Picture_Dev* picture); + + // Callback function to tell the plugin that decoder has decoded end of stream + // marker and output all the pictures that should be displayed from the + // stream. + // + // Parameters: + // |decoder| is pointer to the Pepper Video Decoder instance. + void (*EndOfStream)(PP_Resource decoder); + + // Error handler callback for decoder to deliver information about detected + // errors to the plugin. + // + // TODO(vmr): Fill out error result codes and corresponding actions. + // + // Parameters: + // |decoder| is pointer to the Pepper Video Decoder instance. + // |error| error is the enumeration specifying the error. + void (*NotifyError)(PP_Resource decoder, enum PP_VideoDecodeError_Dev error); +}; + +#endif /* PPAPI_C_DEV_PPP_VIDEO_DECODER_DEV_H_ */ diff --git a/ppapi/cpp/dev/video_decoder_dev.cc b/ppapi/cpp/dev/video_decoder_dev.cc index 503b446..f0d10b6 100644 --- a/ppapi/cpp/dev/video_decoder_dev.cc +++ b/ppapi/cpp/dev/video_decoder_dev.cc @@ -1,15 +1,22 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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 "ppapi/cpp/dev/video_decoder_dev.h" +#include <algorithm> +#include <iterator> + +#include "ppapi/c/dev/ppb_video_decoder_dev.h" +#include "ppapi/c/dev/ppp_video_decoder_dev.h" #include "ppapi/c/pp_errors.h" #include "ppapi/cpp/common.h" #include "ppapi/cpp/instance.h" #include "ppapi/cpp/module.h" #include "ppapi/cpp/module_impl.h" +using std::vector; + namespace pp { namespace { @@ -20,54 +27,54 @@ template <> const char* interface_name<PPB_VideoDecoder_Dev>() { } // namespace -VideoDecoder_Dev::VideoDecoder_Dev(PP_Resource resource) : Resource(resource) { -} - -VideoDecoder_Dev::VideoDecoder_Dev( - const Instance& instance, - const PP_VideoDecoderConfig_Dev& decoder_config) { +VideoDecoder::VideoDecoder( + const Instance* /* instance */, + VideoDecoderClient* /* picture_interface */) { if (!has_interface<PPB_VideoDecoder_Dev>()) return; - PassRefFromConstructor(get_interface<PPB_VideoDecoder_Dev>()->Create( - instance.pp_instance(), &decoder_config)); } -VideoDecoder_Dev::VideoDecoder_Dev(const VideoDecoder_Dev& other) - : Resource(other) { +VideoDecoder::~VideoDecoder() {} + +vector<uint32_t> VideoDecoder::GetConfig( + Instance* /* instance */, + const vector<uint32_t>& /* prototype_config */) { + vector<uint32_t> matching_configs; + if (!has_interface<PPB_VideoDecoder_Dev>()) + return matching_configs; + return matching_configs; } -// static -bool VideoDecoder_Dev::GetConfig(const Instance& instance, - PP_VideoCodecId_Dev codec, - PP_VideoConfig_Dev* configs, - int32_t config_size, - int32_t* num_config) { +bool VideoDecoder::Initialize(const std::vector<uint32_t>& /* config */) { if (!has_interface<PPB_VideoDecoder_Dev>()) return false; - return PPBoolToBool(get_interface<PPB_VideoDecoder_Dev>()->GetConfig( - instance.pp_instance(), codec, configs, config_size, num_config)); + return false; } -bool VideoDecoder_Dev::Decode(PP_VideoCompressedDataBuffer_Dev& input_buffer) { +bool VideoDecoder::Decode( + const PP_VideoBitstreamBuffer_Dev& /* bitstream_buffer */, + PP_CompletionCallback /* callback */) { if (!has_interface<PPB_VideoDecoder_Dev>() || !pp_resource()) return false; - return PPBoolToBool(get_interface<PPB_VideoDecoder_Dev>()->Decode( - pp_resource(), &input_buffer)); + return false; } -int32_t VideoDecoder_Dev::Flush(PP_CompletionCallback callback) { +int32_t VideoDecoder::Flush(PP_CompletionCallback /* callback */) { if (!has_interface<PPB_VideoDecoder_Dev>()) return PP_ERROR_NOINTERFACE; - return get_interface<PPB_VideoDecoder_Dev>()->Flush(pp_resource(), callback); + return PP_ERROR_ABORTED; } -bool VideoDecoder_Dev::ReturnUncompressedDataBuffer( - PP_VideoUncompressedDataBuffer_Dev& buffer) { - if (!has_interface<PPB_VideoDecoder_Dev>() || !pp_resource()) - return false; - return PPBoolToBool( - get_interface<PPB_VideoDecoder_Dev>()->ReturnUncompressedDataBuffer( - pp_resource(), &buffer)); +int32_t VideoDecoder::Abort(PP_CompletionCallback /* callback */) { + if (!has_interface<PPB_VideoDecoder_Dev>()) + return PP_ERROR_NOINTERFACE; + return PP_ERROR_ABORTED; } +void VideoDecoder::EventPicture(struct PP_Picture_Dev* /* picture */) {} + +void VideoDecoder::EventEndOfStream() {} + +void VideoDecoder::EventError(PP_VideoDecodeError_Dev /* error */) {} + } // namespace pp diff --git a/ppapi/cpp/dev/video_decoder_dev.h b/ppapi/cpp/dev/video_decoder_dev.h index ea7d052..698e81e 100644 --- a/ppapi/cpp/dev/video_decoder_dev.h +++ b/ppapi/cpp/dev/video_decoder_dev.h @@ -1,42 +1,174 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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 PPAPI_CPP_DEV_VIDEO_DECODER_DEV_H_ #define PPAPI_CPP_DEV_VIDEO_DECODER_DEV_H_ +#include <map> +#include <set> +#include <vector> + #include "ppapi/c/dev/pp_video_dev.h" -#include "ppapi/c/dev/ppb_video_decoder_dev.h" +#include "ppapi/c/pp_completion_callback.h" +#include "ppapi/c/pp_var.h" +#include "ppapi/cpp/dev/buffer_dev.h" #include "ppapi/cpp/resource.h" namespace pp { class Instance; -// Provides access to video decoders. -class VideoDecoder_Dev : public Resource { +// Convenience C++ wrapper around video decoder output picture that allows easy +// manipulation of the object properties. +class VideoDecoderPicture { + public: + explicit VideoDecoderPicture(struct PP_Picture_Dev* picture); + ~VideoDecoderPicture(); + + // Picture size related functions. + // There are three types of logical picture sizes that applications using + // video decoder should be aware of: + // - Visible picture size, + // - Decoded picture size, and + // - Picture buffer size. + // + // Visible picture size means the actual picture size that is intended to be + // displayed from the decoded output. + // + // Decoded picture size might vary from the visible size of the picture, + // because of the underlying properties of the codec. Vast majority of modern + // video compression algorithms are based on (macro)block-based transforms and + // therefore process the picture in small windows (usually of size 16x16 + // pixels) one by one. However, if the native picture size does not happen to + // match the block-size of the algorithm, there may be redundant data left on + // the sides of the output picture, which are not intended for display. For + // example, this happens to video of size 854x480 and H.264 codec. Since the + // width (854 pixels) is not multiple of the block size of the coding format + // (16 pixels), pixel columns 854-863 contain garbage data which is not + // intended for display. + // + // Plugin is providing the buffers for output decoding and it should know the + // picture buffer size it has provided to the decoder. Thus, there is no + // function to query the buffer size from this class. + // + // GetDecodedPictureSize returns the decoded size of the decoded picture. + // Returns PP_Size telling the decoded size of the picture in pixels. + PP_Size GetDecodedPictureSize() const; + + // GetVisiblePictureSize returns the visible size of the decoded picture. + // Returns PP_Size telling the visible size of the picture in pixels. + PP_Size GetVisiblePictureSize() const; + + // GetPictureFlags returns flags associated with the picture. + // Returns bitmask containing values from PP_PictureInfoFlag_Dev enumeration. + uint32_t GetPictureFlags() const; + + // GetMetadata returns metadata associated with the picture. + // Returns Buffer_Dev object representing the buffer with the metadata. + Buffer_Dev GetMetadata() const; + + private: + PP_Picture_Dev picture; +}; + +// Interface for collaborating with picture interface to provide memory for +// output picture and blitting them. +class VideoDecoderClient { public: - // Creates an is_null() VideoDecoder object. - VideoDecoder_Dev() {} + virtual ~VideoDecoderClient(); - explicit VideoDecoder_Dev(PP_Resource resource); + // Callback to provide buffers for the decoded output pictures. + virtual std::vector<Resource> ProvidePictureBuffers( + uint32_t requested_num_of_buffers, + const std::vector<uint32_t>& buffer_properties) = 0; - VideoDecoder_Dev(const Instance& instance, - const PP_VideoDecoderConfig_Dev& decoder_config); - VideoDecoder_Dev(const VideoDecoder_Dev& other); + // Callback to deliver decoded pictures ready to be displayed. + virtual void PictureReady(struct PP_Picture_Dev* picture) = 0; - // PPB_VideoDecoder methods: - static bool GetConfig(const Instance& instance, - PP_VideoCodecId_Dev codec, - PP_VideoConfig_Dev* configs, - int32_t config_size, - int32_t* num_config); + // Callback to notify that decoder has decoded end of stream marker and has + // outputted all displayable pictures. + virtual void NotifyEndOfStream() = 0; - bool Decode(PP_VideoCompressedDataBuffer_Dev& input_buffer); + // Callback to notify about decoding errors. + virtual void NotifyError(PP_VideoDecodeError_Dev error) = 0; +}; + +// C++ wrapper for the Pepper Video Decoder interface. +class VideoDecoder : public Resource { + public: + VideoDecoder(const Instance* instance, + VideoDecoderClient* picture_interface); + ~VideoDecoder(); + + // GetConfig returns supported configurations that are subsets of given + // |prototype_config|. + // Parameters: + // |instance| is the pointer to the plug-in instance. + // |prototype_config| is the prototypical configuration. + // + // Returns std::vector containing all the configurations that match the + // prototypical configuration. + std::vector<uint32_t> GetConfig( + Instance* instance, + const std::vector<uint32_t>& prototype_config); + + // Initializes the video decoder with specific configuration. + // Parameters: + // |config| is the configuration on which the decoder should be initialized. + // + // Returns true when command successfully accepted. Otherwise false. + bool Initialize(const std::vector<uint32_t>& config); + // Decodes given bitstream buffer. Once decoder is done with processing + // |bitstream_buffer| is will call |callback| with provided user data. + // Parameters: + // |bitstream_buffer| is the input bitstream that is sent for decoding. + // |callback| contains the callback function pointer with the custom userdata + // plugin wants to associate with the callback. + // + // Returns true when command successfully accepted. Otherwise false. + bool Decode(const PP_VideoBitstreamBuffer_Dev& bitstream_buffer, + PP_CompletionCallback callback); + + // Flushes the decoder. Once decoder has released pending bitstream buffers + // and pictures and reset internal picture state it will call |callback| with + // the user provided user data. + // Parameters: + // |callback| contains the callback function pointer with the custom userdata + // plugin wants to associate with the callback. + // + // Returns true when command successfully accepted. Otherwise false. int32_t Flush(PP_CompletionCallback callback); - bool ReturnUncompressedDataBuffer(PP_VideoUncompressedDataBuffer_Dev& buffer); + // Dispatches abortion request to the decoder to abort decoding as soon as + // possible and will not output anything or generate new callbacks. |callback| + // will be called as soon as abortion has been finished. After abortion all + // buffers can be considered dismissed even when there has not been callbacks + // to dismiss them. + // + // Parameters: + // |callback| is one-time callback that will be called once the abortion + // request has been completed. + // + // Returns true when command successfully accepted. Otherwise false. + int32_t Abort(PP_CompletionCallback callback); + + private: + // Functions that handle event notification to all the relevant interfaces. + // Function to handle event when a picture is ready. + virtual void EventPicture(struct PP_Picture_Dev* picture); + // Function to handle event when end of stream occurs. + virtual void EventEndOfStream(); + // Function to handle event when error occurs. + virtual void EventError(PP_VideoDecodeError_Dev error); + + // Pointer to the plugin's video decoder support interface for providing the + // buffers for video decoding. + VideoDecoderClient* picture_if_; + + VideoDecoder(const VideoDecoder&); + void operator=(const VideoDecoder&); }; } // namespace pp diff --git a/ppapi/ppapi_cpp.gypi b/ppapi/ppapi_cpp.gypi index 93b8444..ecd9fa0 100644 --- a/ppapi/ppapi_cpp.gypi +++ b/ppapi/ppapi_cpp.gypi @@ -80,6 +80,7 @@ 'c/dev/ppp_scrollbar_dev.h', 'c/dev/ppp_selection_dev.h', 'c/dev/ppp_printing_dev.h', + 'c/dev/ppp_video_decoder_dev.h', 'c/dev/ppp_widget_dev.h', 'c/dev/ppp_zoom_dev.h', diff --git a/ppapi/proxy/interface_id.h b/ppapi/proxy/interface_id.h index 6e8c6e3..3e33314 100644 --- a/ppapi/proxy/interface_id.h +++ b/ppapi/proxy/interface_id.h @@ -47,9 +47,11 @@ enum InterfaceID { INTERFACE_ID_PPB_URL_UTIL, INTERFACE_ID_PPB_VAR, INTERFACE_ID_PPB_VAR_DEPRECATED, + INTERFACE_ID_PPB_VIDEO_DECODER_DEV, INTERFACE_ID_PPP_CLASS, INTERFACE_ID_PPP_INSTANCE, + INTERFACE_ID_PPP_VIDEO_DECODER_DEV, // Must be last to indicate the number of interface IDs. INTERFACE_ID_COUNT diff --git a/ppapi/tests/all_c_includes.h b/ppapi/tests/all_c_includes.h index b181fc6..2d421e0 100644 --- a/ppapi/tests/all_c_includes.h +++ b/ppapi/tests/all_c_includes.h @@ -47,6 +47,7 @@ #include "ppapi/c/dev/ppp_printing_dev.h" #include "ppapi/c/dev/ppp_scrollbar_dev.h" #include "ppapi/c/dev/ppp_selection_dev.h" +#include "ppapi/c/dev/ppp_video_decoder_dev.h" #include "ppapi/c/dev/ppp_widget_dev.h" #include "ppapi/c/dev/ppp_zoom_dev.h" #include "ppapi/c/pp_bool.h" diff --git a/ppapi/tests/arch_dependent_sizes_32.h b/ppapi/tests/arch_dependent_sizes_32.h index 8ae7a50..25252d8 100644 --- a/ppapi/tests/arch_dependent_sizes_32.h +++ b/ppapi/tests/arch_dependent_sizes_32.h @@ -15,14 +15,13 @@ PP_COMPILE_ASSERT_SIZE_IN_BYTES(GLintptr, 4); PP_COMPILE_ASSERT_SIZE_IN_BYTES(GLsizeiptr, 4); PP_COMPILE_ASSERT_SIZE_IN_BYTES(PP_CompletionCallback_Func, 4); PP_COMPILE_ASSERT_SIZE_IN_BYTES(PP_URLLoaderTrusted_StatusCallback, 4); -PP_COMPILE_ASSERT_SIZE_IN_BYTES(PP_VideoConfig_Dev, 4); -PP_COMPILE_ASSERT_SIZE_IN_BYTES(PP_VideoDecodeEventHandler_Func_Dev, 4); -PP_COMPILE_ASSERT_SIZE_IN_BYTES(PP_VideoDecodeInputCallback_Func_Dev, 4); -PP_COMPILE_ASSERT_SIZE_IN_BYTES(PP_VideoDecodeOutputCallback_Func_Dev, 4); PP_COMPILE_ASSERT_STRUCT_SIZE_IN_BYTES(PP_CompletionCallback, 8); PP_COMPILE_ASSERT_STRUCT_SIZE_IN_BYTES(PP_FileChooserOptions_Dev, 8); +PP_COMPILE_ASSERT_STRUCT_SIZE_IN_BYTES(PP_Picture_Dev, 12); +PP_COMPILE_ASSERT_STRUCT_SIZE_IN_BYTES(PP_PictureBufferProperties_Dev, 16); +PP_COMPILE_ASSERT_STRUCT_SIZE_IN_BYTES(PP_VideoBitstreamBuffer_Dev, 12); PP_COMPILE_ASSERT_STRUCT_SIZE_IN_BYTES(PP_VideoDecoderConfig_Dev, 20); -PP_COMPILE_ASSERT_STRUCT_SIZE_IN_BYTES(PP_VideoFrameBuffer_Dev, 80); -PP_COMPILE_ASSERT_STRUCT_SIZE_IN_BYTES(PP_VideoUncompressedDataBuffer_Dev, 104); +PP_COMPILE_ASSERT_STRUCT_SIZE_IN_BYTES(PPB_VideoDecoder_Dev, 32); +PP_COMPILE_ASSERT_STRUCT_SIZE_IN_BYTES(PPP_VideoDecoder_Dev, 20); #endif /* PPAPI_TESTS_ARCH_DEPENDENT_SIZES_32_H_ */ diff --git a/ppapi/tests/arch_dependent_sizes_64.h b/ppapi/tests/arch_dependent_sizes_64.h index dd419d1..79f87618 100644 --- a/ppapi/tests/arch_dependent_sizes_64.h +++ b/ppapi/tests/arch_dependent_sizes_64.h @@ -15,14 +15,13 @@ PP_COMPILE_ASSERT_SIZE_IN_BYTES(GLintptr, 8); PP_COMPILE_ASSERT_SIZE_IN_BYTES(GLsizeiptr, 8); PP_COMPILE_ASSERT_SIZE_IN_BYTES(PP_CompletionCallback_Func, 8); PP_COMPILE_ASSERT_SIZE_IN_BYTES(PP_URLLoaderTrusted_StatusCallback, 8); -PP_COMPILE_ASSERT_SIZE_IN_BYTES(PP_VideoConfig_Dev, 8); -PP_COMPILE_ASSERT_SIZE_IN_BYTES(PP_VideoDecodeEventHandler_Func_Dev, 8); -PP_COMPILE_ASSERT_SIZE_IN_BYTES(PP_VideoDecodeInputCallback_Func_Dev, 8); -PP_COMPILE_ASSERT_SIZE_IN_BYTES(PP_VideoDecodeOutputCallback_Func_Dev, 8); PP_COMPILE_ASSERT_STRUCT_SIZE_IN_BYTES(PP_CompletionCallback, 16); PP_COMPILE_ASSERT_STRUCT_SIZE_IN_BYTES(PP_FileChooserOptions_Dev, 16); -PP_COMPILE_ASSERT_STRUCT_SIZE_IN_BYTES(PP_VideoDecoderConfig_Dev, 40); -PP_COMPILE_ASSERT_STRUCT_SIZE_IN_BYTES(PP_VideoFrameBuffer_Dev, 88); -PP_COMPILE_ASSERT_STRUCT_SIZE_IN_BYTES(PP_VideoUncompressedDataBuffer_Dev, 120); +PP_COMPILE_ASSERT_STRUCT_SIZE_IN_BYTES(PP_Picture_Dev, 16); +PP_COMPILE_ASSERT_STRUCT_SIZE_IN_BYTES(PP_PictureBufferProperties_Dev, 24); +PP_COMPILE_ASSERT_STRUCT_SIZE_IN_BYTES(PP_VideoBitstreamBuffer_Dev, 16); +PP_COMPILE_ASSERT_STRUCT_SIZE_IN_BYTES(PP_VideoDecoderConfig_Dev, 32); +PP_COMPILE_ASSERT_STRUCT_SIZE_IN_BYTES(PPB_VideoDecoder_Dev, 64); +PP_COMPILE_ASSERT_STRUCT_SIZE_IN_BYTES(PPP_VideoDecoder_Dev, 40); #endif /* PPAPI_TESTS_ARCH_DEPENDENT_SIZES_64_H_ */ diff --git a/webkit/plugins/ppapi/DEPS b/webkit/plugins/ppapi/DEPS index 5c56369..baf1b82 100644 --- a/webkit/plugins/ppapi/DEPS +++ b/webkit/plugins/ppapi/DEPS @@ -3,6 +3,7 @@ include_rules = [ "+ppapi/c", "+ppapi/shared_impl", "+printing", + "+media/video", "+skia", "+ui/base", ] diff --git a/webkit/plugins/ppapi/mock_plugin_delegate.cc b/webkit/plugins/ppapi/mock_plugin_delegate.cc index 77b66ac..10aee19 100644 --- a/webkit/plugins/ppapi/mock_plugin_delegate.cc +++ b/webkit/plugins/ppapi/mock_plugin_delegate.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -41,7 +41,7 @@ MockPluginDelegate::PlatformContext3D* MockPluginDelegate::CreateContext3D() { MockPluginDelegate::PlatformVideoDecoder* MockPluginDelegate::CreateVideoDecoder( - const PP_VideoDecoderConfig_Dev& decoder_config) { + PP_VideoDecoderConfig_Dev* decoder_config) { return NULL; } diff --git a/webkit/plugins/ppapi/mock_plugin_delegate.h b/webkit/plugins/ppapi/mock_plugin_delegate.h index 9a4113f..9e91160 100644 --- a/webkit/plugins/ppapi/mock_plugin_delegate.h +++ b/webkit/plugins/ppapi/mock_plugin_delegate.h @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -22,7 +22,7 @@ class MockPluginDelegate : public PluginDelegate { virtual PlatformImage2D* CreateImage2D(int width, int height); virtual PlatformContext3D* CreateContext3D(); virtual PlatformVideoDecoder* CreateVideoDecoder( - const PP_VideoDecoderConfig_Dev& decoder_config); + PP_VideoDecoderConfig_Dev* decoder_config); virtual PlatformAudio* CreateAudio(uint32_t sample_rate, uint32_t sample_count, PlatformAudio::Client* client); diff --git a/webkit/plugins/ppapi/plugin_delegate.h b/webkit/plugins/ppapi/plugin_delegate.h index 5bf0d07..6112d53 100644 --- a/webkit/plugins/ppapi/plugin_delegate.h +++ b/webkit/plugins/ppapi/plugin_delegate.h @@ -13,6 +13,7 @@ #include "base/shared_memory.h" #include "base/sync_socket.h" #include "googleurl/src/gurl.h" +#include "media/video/video_decode_accelerator.h" #include "ppapi/c/pp_completion_callback.h" #include "ppapi/c/pp_errors.h" #include "ppapi/c/pp_instance.h" @@ -54,9 +55,7 @@ struct WebFileChooserParams; } struct PP_Flash_NetAddress; -struct PP_VideoCompressedDataBuffer_Dev; struct PP_VideoDecoderConfig_Dev; -struct PP_VideoUncompressedDataBuffer_Dev; class TransportDIB; @@ -198,15 +197,11 @@ class PluginDelegate { virtual ~PlatformAudio() {} }; - class PlatformVideoDecoder { + // Interface for PlatformVideoDecoder is directly inherited from general media + // VideoDecodeAccelerator interface. + class PlatformVideoDecoder : public media::VideoDecodeAccelerator { public: virtual ~PlatformVideoDecoder() {} - - // Returns false on failure. - virtual bool Decode(PP_VideoCompressedDataBuffer_Dev& input_buffer) = 0; - virtual int32_t Flush(PP_CompletionCallback& callback) = 0; - virtual bool ReturnUncompressedDataBuffer( - PP_VideoUncompressedDataBuffer_Dev& buffer) = 0; }; // Notification that the given plugin has crashed. When a plugin crashes, all @@ -234,7 +229,7 @@ class PluginDelegate { // The caller will own the pointer returned from this. virtual PlatformVideoDecoder* CreateVideoDecoder( - const PP_VideoDecoderConfig_Dev& decoder_config) = 0; + PP_VideoDecoderConfig_Dev* decoder_config) = 0; // The caller is responsible for calling Shutdown() on the returned pointer // to clean up the corresponding resources allocated during this call. diff --git a/webkit/plugins/ppapi/ppb_video_decoder_impl.cc b/webkit/plugins/ppapi/ppb_video_decoder_impl.cc index 9d6add6..d6c1b62 100644 --- a/webkit/plugins/ppapi/ppb_video_decoder_impl.cc +++ b/webkit/plugins/ppapi/ppb_video_decoder_impl.cc @@ -1,15 +1,18 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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 "webkit/plugins/ppapi/ppb_video_decoder_impl.h" +#include <string> + #include "base/logging.h" #include "ppapi/c/dev/pp_video_dev.h" #include "ppapi/c/dev/ppb_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/ppapi_plugin_instance.h" #include "webkit/plugins/ppapi/ppb_file_ref_impl.h" #include "webkit/plugins/ppapi/resource_tracker.h" @@ -19,29 +22,26 @@ namespace ppapi { namespace { -PP_Bool GetConfig(PP_Instance instance_id, - PP_VideoCodecId_Dev codec, - PP_VideoConfig_Dev* configs, - int32_t config_size, - int32_t *num_config) { +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) { PluginInstance* instance = ResourceTracker::Get()->GetInstance(instance_id); - *num_config = 0; if (!instance) return PP_FALSE; - // Get configs based on codec. - - if (configs) { - // Fill in the array of configs. - } - - // Update *num_config. + scoped_refptr<PPB_VideoDecoder_Impl> decoder( + new PPB_VideoDecoder_Impl(instance)); - return PP_TRUE; + return BoolToPPBool(decoder->GetConfigs(proto_config, + matching_configs, + matching_configs_size, + num_of_matching_configs)); } PP_Resource Create(PP_Instance instance_id, - const PP_VideoDecoderConfig_Dev* decoder_config) { + PP_VideoDecoderConfig_Dev* decoder_config) { PluginInstance* instance = ResourceTracker::Get()->GetInstance(instance_id); if (!instance) return 0; @@ -49,55 +49,88 @@ PP_Resource Create(PP_Instance instance_id, scoped_refptr<PPB_VideoDecoder_Impl> decoder( new PPB_VideoDecoder_Impl(instance)); - if (!decoder->Init(*decoder_config)) + if (!decoder->Init(const_cast<PP_VideoDecoderConfig_Dev*>(decoder_config))) return 0; return decoder->GetReference(); } +PP_Bool IsVideoDecoder(PP_Resource resource) { + return BoolToPPBool(!!Resource::GetAs<PPB_VideoDecoder_Impl>(resource)); +} + PP_Bool Decode(PP_Resource decoder_id, - PP_VideoCompressedDataBuffer_Dev* input_buffer) { + PP_VideoBitstreamBuffer_Dev* bitstream_buffer, + PP_CompletionCallback callback) { scoped_refptr<PPB_VideoDecoder_Impl> decoder( Resource::GetAs<PPB_VideoDecoder_Impl>(decoder_id)); if (!decoder) return PP_FALSE; - decoder->Decode(*input_buffer); - return PP_TRUE; + return BoolToPPBool(decoder->Decode(bitstream_buffer, callback)); +} + +void AssignPictureBuffer(PP_Resource video_decoder, + uint32_t no_of_buffers, + union PP_PictureData_Dev* picture_buffer) { + scoped_refptr<PPB_VideoDecoder_Impl> decoder( + Resource::GetAs<PPB_VideoDecoder_Impl>(video_decoder)); + if (!decoder) + return; + + decoder->AssignPictureBuffer(no_of_buffers, picture_buffer); +} + +void ReusePictureBuffer(PP_Resource video_decoder, + union PP_PictureData_Dev* picture_buffer) { + scoped_refptr<PPB_VideoDecoder_Impl> decoder( + Resource::GetAs<PPB_VideoDecoder_Impl>(video_decoder)); + if (!decoder) + return; + + decoder->ReusePictureBuffer(picture_buffer); } -int32_t Flush(PP_Resource decoder_id, PP_CompletionCallback callback) { +PP_Bool Flush(PP_Resource decoder_id, + PP_CompletionCallback callback) { scoped_refptr<PPB_VideoDecoder_Impl> decoder( Resource::GetAs<PPB_VideoDecoder_Impl>(decoder_id)); if (!decoder) - return PP_ERROR_BADRESOURCE; + return PP_FALSE; - return decoder->Flush(callback); + return BoolToPPBool(decoder->Flush(callback)); } -PP_Bool ReturnUncompressedDataBuffer( - PP_Resource decoder_id, - PP_VideoUncompressedDataBuffer_Dev* buffer) { +PP_Bool Abort(PP_Resource decoder_id, + PP_CompletionCallback callback) { scoped_refptr<PPB_VideoDecoder_Impl> decoder( Resource::GetAs<PPB_VideoDecoder_Impl>(decoder_id)); if (!decoder) return PP_FALSE; - return BoolToPPBool(decoder->ReturnUncompressedDataBuffer(*buffer)); + return BoolToPPBool(decoder->Abort(callback)); } + const PPB_VideoDecoder_Dev ppb_videodecoder = { - &GetConfig, + &GetConfigs, &Create, + &IsVideoDecoder, &Decode, + &AssignPictureBuffer, + &ReusePictureBuffer, &Flush, - &ReturnUncompressedDataBuffer + &Abort, }; } // namespace PPB_VideoDecoder_Impl::PPB_VideoDecoder_Impl(PluginInstance* instance) - : Resource(instance) { + : Resource(instance), + callback_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), + abort_callback_(PP_BlockUntilComplete()), + flush_callback_(PP_BlockUntilComplete()), + bitstream_buffer_callback_(PP_BlockUntilComplete()) { } PPB_VideoDecoder_Impl::~PPB_VideoDecoder_Impl() { @@ -112,8 +145,23 @@ PPB_VideoDecoder_Impl* PPB_VideoDecoder_Impl::AsPPB_VideoDecoder_Impl() { return this; } -bool PPB_VideoDecoder_Impl::Init( - const PP_VideoDecoderConfig_Dev& decoder_config) { +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) { + if (!instance()) + return false; + if (!platform_video_decoder_.get()) + return false; + + // TODO(vmr): Implement. + NOTIMPLEMENTED(); + + return false; +} + +bool PPB_VideoDecoder_Impl::Init(PP_VideoDecoderConfig_Dev* decoder_config) { if (!instance()) return false; @@ -124,28 +172,161 @@ bool PPB_VideoDecoder_Impl::Init( } bool PPB_VideoDecoder_Impl::Decode( - PP_VideoCompressedDataBuffer_Dev& input_buffer) { + PP_VideoBitstreamBuffer_Dev* bitstream_buffer, + PP_CompletionCallback callback) { if (!platform_video_decoder_.get()) return false; - return platform_video_decoder_->Decode(input_buffer); + media::BitstreamBuffer* decode_buffer = NULL; + // TODO(vmr): Convert bitstream_buffer to BitstreamBuffer object. + NOTIMPLEMENTED(); + + // Store the callback to inform when bitstream buffer has been processed. + // TODO(vmr): handle simultaneous decodes + callbacks. + bitstream_buffer_callback_ = callback; + + return platform_video_decoder_->Decode( + decode_buffer, + callback_factory_.NewCallback( + &PPB_VideoDecoder_Impl::OnBitstreamBufferProcessed)); } -int32_t PPB_VideoDecoder_Impl::Flush(PP_CompletionCallback& callback) { +void PPB_VideoDecoder_Impl::AssignPictureBuffer( + uint32_t no_of_picture_buffers, + PP_PictureData_Dev* picture_buffers) { if (!platform_video_decoder_.get()) - return PP_ERROR_FAILED; + return; - return platform_video_decoder_->Flush(callback); + // TODO(vmr): Map PP_PictureData_Dev into PictureBuffer object. + NOTIMPLEMENTED(); + + media::VideoDecodeAccelerator::PictureBuffer* buffer = NULL; + platform_video_decoder_->ReusePictureBuffer(buffer); } -bool PPB_VideoDecoder_Impl::ReturnUncompressedDataBuffer( - PP_VideoUncompressedDataBuffer_Dev& buffer) { +void PPB_VideoDecoder_Impl::ReusePictureBuffer( + PP_PictureData_Dev* picture_buffer) { + 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); +} + +bool PPB_VideoDecoder_Impl::Flush(PP_CompletionCallback callback) { + if (!platform_video_decoder_.get()) + return false; + + // Store the callback to be called when Flush() is done. + // TODO(vmr): Check for current flush/abort operations. + flush_callback_ = callback; + + return platform_video_decoder_->Flush( + callback_factory_.NewCallback( + &PPB_VideoDecoder_Impl::OnFlushComplete)); +} + +bool PPB_VideoDecoder_Impl::Abort(PP_CompletionCallback callback) { if (!platform_video_decoder_.get()) return false; - return platform_video_decoder_->ReturnUncompressedDataBuffer(buffer); + // Store the callback to be called when Abort() is done. + // TODO(vmr): Check for current flush/abort operations. + abort_callback_ = callback; + + return platform_video_decoder_->Abort( + callback_factory_.NewCallback( + &PPB_VideoDecoder_Impl::OnAbortComplete)); +} + +void PPB_VideoDecoder_Impl::ProvidePictureBuffers( + uint32_t requested_num_of_buffers, + const std::vector<uint32_t>& buffer_properties) { + // TODO(vmr): Implement. + NOTIMPLEMENTED(); +} + +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); +} + +void PPB_VideoDecoder_Impl::DismissPictureBuffer( + media::VideoDecodeAccelerator::PictureBuffer* picture_buffer) { + // TODO(vmr): Implement. + NOTIMPLEMENTED(); +} + +void PPB_VideoDecoder_Impl::NotifyPictureReady() { + // No need to react here as we are already reacting to PictureReady. +} + +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); +} + +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); +} + +void PPB_VideoDecoder_Impl::OnAbortComplete() { + if (abort_callback_.func == NULL) + return; + + // Call the callback that was stored to be called when Abort is done. + PP_CompletionCallback callback = PP_BlockUntilComplete(); + std::swap(callback, abort_callback_); + PP_RunCompletionCallback(&callback, PP_OK); +} + +void PPB_VideoDecoder_Impl::OnBitstreamBufferProcessed() { + if (bitstream_buffer_callback_.func == NULL) + return; + + // Call the callback that was stored to be called when bitstream was sent for + // decoding. + PP_CompletionCallback callback = PP_BlockUntilComplete(); + std::swap(callback, bitstream_buffer_callback_); + PP_RunCompletionCallback(&callback, PP_OK); +} + +void PPB_VideoDecoder_Impl::OnFlushComplete() { + if (flush_callback_.func == NULL) + return; + + // Call the callback that was stored to be called when Flush is done. + PP_CompletionCallback callback = PP_BlockUntilComplete(); + std::swap(callback, flush_callback_); + PP_RunCompletionCallback(&callback, PP_OK); } } // namespace ppapi } // namespace webkit - diff --git a/webkit/plugins/ppapi/ppb_video_decoder_impl.h b/webkit/plugins/ppapi/ppb_video_decoder_impl.h index 492cb33..cb9750d 100644 --- a/webkit/plugins/ppapi/ppb_video_decoder_impl.h +++ b/webkit/plugins/ppapi/ppb_video_decoder_impl.h @@ -5,14 +5,18 @@ #ifndef WEBKIT_PLUGINS_PPAPI_PPB_VIDEO_DECODER_IMPL_H_ #define WEBKIT_PLUGINS_PPAPI_PPB_VIDEO_DECODER_IMPL_H_ +#include <vector> + #include "base/basictypes.h" +#include "base/memory/scoped_callback_factory.h" #include "base/memory/scoped_ptr.h" +#include "ppapi/c/pp_var.h" #include "webkit/plugins/ppapi/plugin_delegate.h" #include "webkit/plugins/ppapi/resource.h" +union PP_PictureData_Dev; struct PP_VideoDecoderConfig_Dev; -struct PP_VideoCompressedDataBuffer_Dev; -struct PP_VideoUncompressedDataBuffer_Dev; +struct PP_VideoBitstreamBuffer_Dev; struct PPB_VideoDecoder_Dev; namespace webkit { @@ -20,9 +24,10 @@ namespace ppapi { class PluginInstance; -class PPB_VideoDecoder_Impl : public Resource { +class PPB_VideoDecoder_Impl : public Resource, + public media::VideoDecodeAccelerator::Client { public: - PPB_VideoDecoder_Impl(PluginInstance* instance); + explicit PPB_VideoDecoder_Impl(PluginInstance* instance); virtual ~PPB_VideoDecoder_Impl(); // Returns a pointer to the interface implementing PPB_VideoDecoder that is @@ -33,16 +38,45 @@ class PPB_VideoDecoder_Impl : public Resource { virtual PPB_VideoDecoder_Impl* AsPPB_VideoDecoder_Impl(); // PPB_VideoDecoder implementation. - bool Init(const PP_VideoDecoderConfig_Dev& decoder_config); - bool Decode(PP_VideoCompressedDataBuffer_Dev& input_buffer); - int32_t Flush(PP_CompletionCallback& callback); - bool ReturnUncompressedDataBuffer(PP_VideoUncompressedDataBuffer_Dev& buffer); + bool GetConfigs(PP_VideoDecoderConfig_Dev* proto_config, + PP_VideoDecoderConfig_Dev* matching_configs, + int32_t matching_configs_size, + int32_t* num_of_matching_configs); + bool Init(PP_VideoDecoderConfig_Dev* dec_config); + bool Decode(PP_VideoBitstreamBuffer_Dev* bitstream_buffer, + PP_CompletionCallback callback); + void AssignPictureBuffer(uint32_t no_of_picture_buffers, + PP_PictureData_Dev* picture_buffers); + void ReusePictureBuffer(PP_PictureData_Dev* picture_buffer); + bool Flush(PP_CompletionCallback callback); + bool Abort(PP_CompletionCallback callback); + + // media::VideoDecodeAccelerator::Client implementation. + void ProvidePictureBuffers(uint32_t requested_num_of_buffers, + const std::vector<uint32_t>& buffer_properties); + void DismissPictureBuffer( + media::VideoDecodeAccelerator::PictureBuffer* picture_buffer); + void PictureReady(media::VideoDecodeAccelerator::Picture* picture); + void NotifyPictureReady(); + void NotifyEndOfStream(); + void NotifyError(media::VideoDecodeAccelerator::Error error); private: + void OnAbortComplete(); + void OnBitstreamBufferProcessed(); + void OnFlushComplete(); + // This is NULL before initialization, and if this PPB_VideoDecoder_Impl is // swapped with another. scoped_ptr<PluginDelegate::PlatformVideoDecoder> platform_video_decoder_; + // Factory to produce our callbacks. + base::ScopedCallbackFactory<PPB_VideoDecoder_Impl> callback_factory_; + + PP_CompletionCallback abort_callback_; + PP_CompletionCallback flush_callback_; + PP_CompletionCallback bitstream_buffer_callback_; + DISALLOW_COPY_AND_ASSIGN(PPB_VideoDecoder_Impl); }; |