Index: content/common/gpu/media/vt_video_decode_accelerator.h |
diff --git a/content/common/gpu/media/vt_video_decode_accelerator.h b/content/common/gpu/media/vt_video_decode_accelerator.h |
index 185d0fb1b77b039553a79feed89f3d5495f1163e..d2cb9e8e7aee9b85bb18967809bce765c707b7fb 100644 |
--- a/content/common/gpu/media/vt_video_decode_accelerator.h |
+++ b/content/common/gpu/media/vt_video_decode_accelerator.h |
@@ -64,16 +64,58 @@ class VTVideoDecodeAccelerator |
base::ScopedCFTypeRef<CVImageBufferRef> image_buffer; |
}; |
+ // Actions are the possible types of pending operations, which are queued |
+ // by Flush(), Reset(), and Destroy(). |
+ enum Action { |
+ ACTION_FLUSH, |
+ ACTION_RESET, |
+ ACTION_DESTROY |
+ }; |
+ |
+ // PendingActions contain the |bitstream_id| of a frame that, once decoded and |
+ // sent, a particular |action| should be completed at. |
+ struct PendingAction { |
+ PendingAction(Action action, int32_t bitstream_id); |
+ ~PendingAction(); |
+ |
+ Action action; |
+ int32_t bitstream_id; |
+ }; |
+ |
// Methods for interacting with VideoToolbox. Run on |decoder_thread_|. |
void ConfigureDecoder( |
const std::vector<const uint8_t*>& nalu_data_ptrs, |
const std::vector<size_t>& nalu_data_sizes); |
void DecodeTask(const media::BitstreamBuffer); |
+ void FlushTask(); |
// Methods for interacting with |client_|. Run on |gpu_task_runner_|. |
void OutputTask(DecodedFrame frame); |
void SizeChangedTask(gfx::Size coded_size); |
- void SendPictures(); |
+ |
+ // Send decoded frames up to and including |up_to_bitstream_id|, and return |
+ // the last sent |bitstream_id|. |
+ int32_t SendPictures(int32_t up_to_bitstream_id); |
+ |
+ // Since VideoToolbox has no reset feature (only flush), and the VDA API |
+ // allows Decode() and Flush() calls during a reset operation, it's possible |
+ // to have multiple pending actions at once. We handle the fully general case |
+ // of an arbitrary sequence of pending actions (in reality, there should |
+ // probably be at most one reset and one flush at a time). |
+ void QueueAction(Action action); |
+ |
+ // Process queued decoded frames, usually by sending them (unless there |
+ // is a pending ACTION_RESET or ACTION_DESTROY, in which case they are |
+ // dropped), completing queued actions along the way. |
+ void ProcessDecodedFrames(); |
+ |
+ // Complete a particular action, by eg. calling NotifyFlushDone(). |
+ // Warning: Deletes |this| if |action| is ACTION_DESTROY. |
+ void CompleteAction(Action action); |
+ |
+ // Complete all actions pending for a particular |bitstream_id|. |
+ // Warning: Do not call if there is a pending ACTION_DESTROY. |
+ void CompleteActions(int32_t bitstream_id); |
// |
// GPU thread state. |
@@ -81,6 +123,8 @@ class VTVideoDecodeAccelerator |
CGLContextObj cgl_context_; |
media::VideoDecodeAccelerator::Client* client_; |
gfx::Size texture_size_; |
+ std::queue<PendingAction> pending_actions_; |
+ std::queue<int32_t> pending_bitstream_ids_; |
// Texture IDs of pictures. |
// TODO(sandersd): A single map of structs holding picture data. |
@@ -105,7 +149,7 @@ class VTVideoDecodeAccelerator |
gfx::Size coded_size_; |
// |
- // Unprotected shared state (set up and torn down on GPU thread). |
+ // Shared state (set up and torn down on GPU thread). |
// |
scoped_refptr<base::SingleThreadTaskRunner> gpu_task_runner_; |