| 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_;
 | 
|  
 | 
| 
 |