1 // Copyright 2014 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef CONTENT_COMMON_GPU_MEDIA_VT_VIDEO_DECODE_ACCELERATOR_H_ 6 #define CONTENT_COMMON_GPU_MEDIA_VT_VIDEO_DECODE_ACCELERATOR_H_ 7 8 #include <stdint.h> 9 10 #include <map> 11 #include <queue> 12 13 #include "base/mac/scoped_cftyperef.h" 14 #include "base/memory/ref_counted.h" 15 #include "base/memory/weak_ptr.h" 16 #include "base/message_loop/message_loop.h" 17 #include "base/threading/thread.h" 18 #include "content/common/gpu/media/vt.h" 19 #include "media/filters/h264_parser.h" 20 #include "media/video/video_decode_accelerator.h" 21 #include "ui/gfx/geometry/size.h" 22 #include "ui/gl/gl_context_cgl.h" 23 24 namespace base { 25 class SingleThreadTaskRunner; 26 } // namespace base 27 28 namespace content { 29 30 // VideoToolbox.framework implementation of the VideoDecodeAccelerator 31 // interface for Mac OS X (currently limited to 10.9+). 32 class VTVideoDecodeAccelerator 33 : public media::VideoDecodeAccelerator, 34 public base::NonThreadSafe { 35 public: 36 explicit VTVideoDecodeAccelerator(CGLContextObj cgl_context); 37 virtual ~VTVideoDecodeAccelerator(); 38 39 // VideoDecodeAccelerator implementation. 40 virtual bool Initialize( 41 media::VideoCodecProfile profile, 42 Client* client) OVERRIDE; 43 virtual void Decode(const media::BitstreamBuffer& bitstream) OVERRIDE; 44 virtual void AssignPictureBuffers( 45 const std::vector<media::PictureBuffer>& pictures) OVERRIDE; 46 virtual void ReusePictureBuffer(int32_t picture_id) OVERRIDE; 47 virtual void Flush() OVERRIDE; 48 virtual void Reset() OVERRIDE; 49 virtual void Destroy() OVERRIDE; 50 virtual bool CanDecodeOnIOThread() OVERRIDE; 51 52 // Called by OutputThunk() when VideoToolbox finishes decoding a frame. 53 void Output( 54 int32_t bitstream_id, 55 OSStatus status, 56 CVImageBufferRef image_buffer); 57 58 private: 59 struct DecodedFrame { 60 DecodedFrame(int32_t bitstream_id, CVImageBufferRef image_buffer); 61 ~DecodedFrame(); 62 63 int32_t bitstream_id; 64 base::ScopedCFTypeRef<CVImageBufferRef> image_buffer; 65 }; 66 67 // Actions are the possible types of pending operations, which are queued 68 // by Flush(), Reset(), and Destroy(). 69 enum Action { 70 ACTION_FLUSH, 71 ACTION_RESET, 72 ACTION_DESTROY 73 }; 74 75 // PendingActions contain the |bitstream_id| of a frame that, once decoded and 76 // sent, a particular |action| should be completed at. 77 struct PendingAction { 78 PendingAction(Action action, int32_t bitstream_id); 79 ~PendingAction(); 80 81 Action action; 82 int32_t bitstream_id; 83 }; 84 85 // Methods for interacting with VideoToolbox. Run on |decoder_thread_|. 86 void ConfigureDecoder( 87 const std::vector<const uint8_t*>& nalu_data_ptrs, 88 const std::vector<size_t>& nalu_data_sizes); 89 void DecodeTask(const media::BitstreamBuffer); 90 void FlushTask(); 91 92 // Methods for interacting with |client_|. Run on |gpu_task_runner_|. 93 void OutputTask(DecodedFrame frame); 94 void SizeChangedTask(gfx::Size coded_size); 95 96 // Send decoded frames up to and including |up_to_bitstream_id|, and return 97 // the last sent |bitstream_id|. 98 int32_t SendPictures(int32_t up_to_bitstream_id); 99 100 // Since VideoToolbox has no reset feature (only flush), and the VDA API 101 // allows Decode() and Flush() calls during a reset operation, it's possible 102 // to have multiple pending actions at once. We handle the fully general case 103 // of an arbitrary sequence of pending actions (in reality, there should 104 // probably be at most one reset and one flush at a time). 105 void QueueAction(Action action); 106 107 // Process queued decoded frames, usually by sending them (unless there 108 // is a pending ACTION_RESET or ACTION_DESTROY, in which case they are 109 // dropped), completing queued actions along the way. 110 void ProcessDecodedFrames(); 111 112 // Complete a particular action, by eg. calling NotifyFlushDone(). 113 // Warning: Deletes |this| if |action| is ACTION_DESTROY. 114 void CompleteAction(Action action); 115 116 // Complete all actions pending for a particular |bitstream_id|. 117 // Warning: Do not call if there is a pending ACTION_DESTROY. 118 void CompleteActions(int32_t bitstream_id); 119 120 // 121 // GPU thread state. 122 // 123 CGLContextObj cgl_context_; 124 media::VideoDecodeAccelerator::Client* client_; 125 gfx::Size texture_size_; 126 std::queue<PendingAction> pending_actions_; 127 std::queue<int32_t> pending_bitstream_ids_; 128 129 // Texture IDs of pictures. 130 // TODO(sandersd): A single map of structs holding picture data. 131 std::map<int32_t, uint32_t> texture_ids_; 132 133 // Pictures ready to be rendered to. 134 std::queue<int32_t> available_picture_ids_; 135 136 // Decoded frames ready to render. 137 std::queue<DecodedFrame> decoded_frames_; 138 139 // Image buffers kept alive while they are bound to pictures. 140 std::map<int32_t, base::ScopedCFTypeRef<CVImageBufferRef>> picture_bindings_; 141 142 // 143 // Decoder thread state. 144 // 145 VTDecompressionOutputCallbackRecord callback_; 146 base::ScopedCFTypeRef<CMFormatDescriptionRef> format_; 147 base::ScopedCFTypeRef<VTDecompressionSessionRef> session_; 148 media::H264Parser parser_; 149 gfx::Size coded_size_; 150 151 // 152 // Shared state (set up and torn down on GPU thread). 153 // 154 scoped_refptr<base::SingleThreadTaskRunner> gpu_task_runner_; 155 156 // This WeakPtrFactory does not need to be last as its pointers are bound to 157 // the same thread it is destructed on (the GPU thread). 158 base::WeakPtrFactory<VTVideoDecodeAccelerator> weak_this_factory_; 159 160 // Declared last to ensure that all decoder thread tasks complete before any 161 // state is destructed. 162 base::Thread decoder_thread_; 163 164 DISALLOW_COPY_AND_ASSIGN(VTVideoDecodeAccelerator); 165 }; 166 167 } // namespace content 168 169 #endif // CONTENT_COMMON_GPU_MEDIA_VT_VIDEO_DECODE_ACCELERATOR_H_ 170