| OLD | NEW |
| (Empty) |
| 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 // This file contains an implementation of VideoDecodeAccelerator | |
| 6 // that utilizes hardware video decoders, which expose Video4Linux 2 API | |
| 7 // (http://linuxtv.org/downloads/v4l-dvb-apis/). | |
| 8 | |
| 9 #ifndef CONTENT_COMMON_GPU_MEDIA_V4L2_VIDEO_DECODE_ACCELERATOR_H_ | |
| 10 #define CONTENT_COMMON_GPU_MEDIA_V4L2_VIDEO_DECODE_ACCELERATOR_H_ | |
| 11 | |
| 12 #include <stddef.h> | |
| 13 #include <stdint.h> | |
| 14 | |
| 15 #include <memory> | |
| 16 #include <queue> | |
| 17 #include <vector> | |
| 18 | |
| 19 #include "base/callback_forward.h" | |
| 20 #include "base/macros.h" | |
| 21 #include "base/memory/linked_ptr.h" | |
| 22 #include "base/memory/ref_counted.h" | |
| 23 #include "base/synchronization/waitable_event.h" | |
| 24 #include "base/threading/thread.h" | |
| 25 #include "content/common/content_export.h" | |
| 26 #include "content/common/gpu/media/gpu_video_decode_accelerator_helpers.h" | |
| 27 #include "content/common/gpu/media/v4l2_device.h" | |
| 28 #include "content/common/gpu/media/v4l2_image_processor.h" | |
| 29 #include "media/base/limits.h" | |
| 30 #include "media/base/video_decoder_config.h" | |
| 31 #include "media/video/picture.h" | |
| 32 #include "media/video/video_decode_accelerator.h" | |
| 33 #include "ui/gfx/geometry/size.h" | |
| 34 #include "ui/gl/gl_bindings.h" | |
| 35 | |
| 36 namespace media { | |
| 37 class H264Parser; | |
| 38 } // namespace media | |
| 39 | |
| 40 namespace content { | |
| 41 // This class handles video accelerators directly through a V4L2 device exported | |
| 42 // by the hardware blocks. | |
| 43 // | |
| 44 // The threading model of this class is driven by the fact that it needs to | |
| 45 // interface two fundamentally different event queues -- the one Chromium | |
| 46 // provides through MessageLoop, and the one driven by the V4L2 devices which | |
| 47 // is waited on with epoll(). There are three threads involved in this class: | |
| 48 // | |
| 49 // * The child thread, which is the main GPU process thread which calls the | |
| 50 // media::VideoDecodeAccelerator entry points. Calls from this thread | |
| 51 // generally do not block (with the exception of Initialize() and Destroy()). | |
| 52 // They post tasks to the decoder_thread_, which actually services the task | |
| 53 // and calls back when complete through the | |
| 54 // media::VideoDecodeAccelerator::Client interface. | |
| 55 // * The decoder_thread_, owned by this class. It services API tasks, through | |
| 56 // the *Task() routines, as well as V4L2 device events, through | |
| 57 // ServiceDeviceTask(). Almost all state modification is done on this thread | |
| 58 // (this doesn't include buffer (re)allocation sequence, see below). | |
| 59 // * The device_poll_thread_, owned by this class. All it does is epoll() on | |
| 60 // the V4L2 in DevicePollTask() and schedule a ServiceDeviceTask() on the | |
| 61 // decoder_thread_ when something interesting happens. | |
| 62 // TODO(sheu): replace this thread with an TYPE_IO decoder_thread_. | |
| 63 // | |
| 64 // Note that this class has (almost) no locks, apart from the pictures_assigned_ | |
| 65 // WaitableEvent. Everything (apart from buffer (re)allocation) is serviced on | |
| 66 // the decoder_thread_, so there are no synchronization issues. | |
| 67 // ... well, there are, but it's a matter of getting messages posted in the | |
| 68 // right order, not fiddling with locks. | |
| 69 // Buffer creation is a two-step process that is serviced partially on the | |
| 70 // Child thread, because we need to wait for the client to provide textures | |
| 71 // for the buffers we allocate. We cannot keep the decoder thread running while | |
| 72 // the client allocates Pictures for us, because we need to REQBUFS first to get | |
| 73 // the required number of output buffers from the device and that cannot be done | |
| 74 // unless we free the previous set of buffers, leaving the decoding in a | |
| 75 // inoperable state for the duration of the wait for Pictures. So to prevent | |
| 76 // subtle races (esp. if we get Reset() in the meantime), we block the decoder | |
| 77 // thread while we wait for AssignPictureBuffers from the client. | |
| 78 // | |
| 79 // V4L2VideoDecodeAccelerator may use image processor to convert the output. | |
| 80 // There are three cases: | |
| 81 // Flush: V4L2VDA should wait until image processor returns all processed | |
| 82 // frames. | |
| 83 // Reset: V4L2VDA doesn't need to wait for image processor. When image processor | |
| 84 // returns an old frame, drop it. | |
| 85 // Resolution change: V4L2VDA destroy image processor when destroying output | |
| 86 // buffrers. We cannot drop any frame during resolution change. So V4L2VDA | |
| 87 // should destroy output buffers after image processor returns all the frames. | |
| 88 class CONTENT_EXPORT V4L2VideoDecodeAccelerator | |
| 89 : public media::VideoDecodeAccelerator { | |
| 90 public: | |
| 91 V4L2VideoDecodeAccelerator( | |
| 92 EGLDisplay egl_display, | |
| 93 const GetGLContextCallback& get_gl_context_cb, | |
| 94 const MakeGLContextCurrentCallback& make_context_current_cb, | |
| 95 const scoped_refptr<V4L2Device>& device); | |
| 96 ~V4L2VideoDecodeAccelerator() override; | |
| 97 | |
| 98 // media::VideoDecodeAccelerator implementation. | |
| 99 // Note: Initialize() and Destroy() are synchronous. | |
| 100 bool Initialize(const Config& config, Client* client) override; | |
| 101 void Decode(const media::BitstreamBuffer& bitstream_buffer) override; | |
| 102 void AssignPictureBuffers( | |
| 103 const std::vector<media::PictureBuffer>& buffers) override; | |
| 104 void ReusePictureBuffer(int32_t picture_buffer_id) override; | |
| 105 void Flush() override; | |
| 106 void Reset() override; | |
| 107 void Destroy() override; | |
| 108 bool TryToSetupDecodeOnSeparateThread( | |
| 109 const base::WeakPtr<Client>& decode_client, | |
| 110 const scoped_refptr<base::SingleThreadTaskRunner>& decode_task_runner) | |
| 111 override; | |
| 112 media::VideoPixelFormat GetOutputFormat() const override; | |
| 113 | |
| 114 static media::VideoDecodeAccelerator::SupportedProfiles | |
| 115 GetSupportedProfiles(); | |
| 116 | |
| 117 private: | |
| 118 // These are rather subjectively tuned. | |
| 119 enum { | |
| 120 kInputBufferCount = 8, | |
| 121 // TODO(posciak): determine input buffer size based on level limits. | |
| 122 // See http://crbug.com/255116. | |
| 123 // Input bitstream buffer size for up to 1080p streams. | |
| 124 kInputBufferMaxSizeFor1080p = 1024 * 1024, | |
| 125 // Input bitstream buffer size for up to 4k streams. | |
| 126 kInputBufferMaxSizeFor4k = 4 * kInputBufferMaxSizeFor1080p, | |
| 127 // Number of output buffers to use for each VDA stage above what's required | |
| 128 // by the decoder (e.g. DPB size, in H264). We need | |
| 129 // media::limits::kMaxVideoFrames to fill up the GpuVideoDecode pipeline, | |
| 130 // and +1 for a frame in transit. | |
| 131 kDpbOutputBufferExtraCount = media::limits::kMaxVideoFrames + 1, | |
| 132 }; | |
| 133 | |
| 134 // Internal state of the decoder. | |
| 135 enum State { | |
| 136 kUninitialized, // Initialize() not yet called. | |
| 137 kInitialized, // Initialize() returned true; ready to start decoding. | |
| 138 kDecoding, // DecodeBufferInitial() successful; decoding frames. | |
| 139 kResetting, // Presently resetting. | |
| 140 kAfterReset, // After Reset(), ready to start decoding again. | |
| 141 kChangingResolution, // Performing resolution change, all remaining | |
| 142 // pre-change frames decoded and processed. | |
| 143 kError, // Error in kDecoding state. | |
| 144 }; | |
| 145 | |
| 146 enum OutputRecordState { | |
| 147 kFree, // Ready to be queued to the device. | |
| 148 kAtDevice, // Held by device. | |
| 149 kAtProcessor, // Held by image processor. | |
| 150 kAtClient, // Held by client of V4L2VideoDecodeAccelerator. | |
| 151 }; | |
| 152 | |
| 153 enum BufferId { | |
| 154 kFlushBufferId = -2 // Buffer id for flush buffer, queued by FlushTask(). | |
| 155 }; | |
| 156 | |
| 157 // Auto-destruction reference for BitstreamBuffer, for message-passing from | |
| 158 // Decode() to DecodeTask(). | |
| 159 struct BitstreamBufferRef; | |
| 160 | |
| 161 // Auto-destruction reference for EGLSync (for message-passing). | |
| 162 struct EGLSyncKHRRef; | |
| 163 | |
| 164 // Record for decoded pictures that can be sent to PictureReady. | |
| 165 struct PictureRecord; | |
| 166 | |
| 167 // Record for input buffers. | |
| 168 struct InputRecord { | |
| 169 InputRecord(); | |
| 170 ~InputRecord(); | |
| 171 bool at_device; // held by device. | |
| 172 void* address; // mmap() address. | |
| 173 size_t length; // mmap() length. | |
| 174 off_t bytes_used; // bytes filled in the mmap() segment. | |
| 175 int32_t input_id; // triggering input_id as given to Decode(). | |
| 176 }; | |
| 177 | |
| 178 // Record for output buffers. | |
| 179 struct OutputRecord { | |
| 180 OutputRecord(); | |
| 181 OutputRecord(OutputRecord&&) = default; | |
| 182 ~OutputRecord(); | |
| 183 OutputRecordState state; | |
| 184 EGLImageKHR egl_image; // EGLImageKHR for the output buffer. | |
| 185 EGLSyncKHR egl_sync; // sync the compositor's use of the EGLImage. | |
| 186 int32_t picture_id; // picture buffer id as returned to PictureReady(). | |
| 187 bool cleared; // Whether the texture is cleared and safe to render | |
| 188 // from. See TextureManager for details. | |
| 189 // Exported fds for image processor to import. | |
| 190 std::vector<base::ScopedFD> fds; | |
| 191 }; | |
| 192 | |
| 193 // | |
| 194 // Decoding tasks, to be run on decode_thread_. | |
| 195 // | |
| 196 | |
| 197 // Enqueue a BitstreamBuffer to decode. This will enqueue a buffer to the | |
| 198 // decoder_input_queue_, then queue a DecodeBufferTask() to actually decode | |
| 199 // the buffer. | |
| 200 void DecodeTask(const media::BitstreamBuffer& bitstream_buffer); | |
| 201 | |
| 202 // Decode from the buffers queued in decoder_input_queue_. Calls | |
| 203 // DecodeBufferInitial() or DecodeBufferContinue() as appropriate. | |
| 204 void DecodeBufferTask(); | |
| 205 // Advance to the next fragment that begins a frame. | |
| 206 bool AdvanceFrameFragment(const uint8_t* data, size_t size, size_t* endpos); | |
| 207 // Schedule another DecodeBufferTask() if we're behind. | |
| 208 void ScheduleDecodeBufferTaskIfNeeded(); | |
| 209 | |
| 210 // Return true if we should continue to schedule DecodeBufferTask()s after | |
| 211 // completion. Store the amount of input actually consumed in |endpos|. | |
| 212 bool DecodeBufferInitial(const void* data, size_t size, size_t* endpos); | |
| 213 bool DecodeBufferContinue(const void* data, size_t size); | |
| 214 | |
| 215 // Accumulate data for the next frame to decode. May return false in | |
| 216 // non-error conditions; for example when pipeline is full and should be | |
| 217 // retried later. | |
| 218 bool AppendToInputFrame(const void* data, size_t size); | |
| 219 // Flush data for one decoded frame. | |
| 220 bool FlushInputFrame(); | |
| 221 | |
| 222 // Service I/O on the V4L2 devices. This task should only be scheduled from | |
| 223 // DevicePollTask(). If |event_pending| is true, one or more events | |
| 224 // on file descriptor are pending. | |
| 225 void ServiceDeviceTask(bool event_pending); | |
| 226 // Handle the various device queues. | |
| 227 void Enqueue(); | |
| 228 void Dequeue(); | |
| 229 | |
| 230 // Return true if there is a resolution change event pending. | |
| 231 bool DequeueResolutionChangeEvent(); | |
| 232 | |
| 233 // Enqueue a buffer on the corresponding queue. | |
| 234 bool EnqueueInputRecord(); | |
| 235 bool EnqueueOutputRecord(); | |
| 236 | |
| 237 // Process a ReusePictureBuffer() API call. The API call create an EGLSync | |
| 238 // object on the main (GPU process) thread; we will record this object so we | |
| 239 // can wait on it before reusing the buffer. | |
| 240 void ReusePictureBufferTask(int32_t picture_buffer_id, | |
| 241 std::unique_ptr<EGLSyncKHRRef> egl_sync_ref); | |
| 242 | |
| 243 // Flush() task. Child thread should not submit any more buffers until it | |
| 244 // receives the NotifyFlushDone callback. This task will schedule an empty | |
| 245 // BitstreamBufferRef (with input_id == kFlushBufferId) to perform the flush. | |
| 246 void FlushTask(); | |
| 247 // Notify the client of a flush completion, if required. This should be | |
| 248 // called any time a relevant queue could potentially be emptied: see | |
| 249 // function definition. | |
| 250 void NotifyFlushDoneIfNeeded(); | |
| 251 | |
| 252 // Reset() task. This task will schedule a ResetDoneTask() that will send | |
| 253 // the NotifyResetDone callback, then set the decoder state to kResetting so | |
| 254 // that all intervening tasks will drain. | |
| 255 void ResetTask(); | |
| 256 // ResetDoneTask() will set the decoder state back to kAfterReset, so | |
| 257 // subsequent decoding can continue. | |
| 258 void ResetDoneTask(); | |
| 259 | |
| 260 // Device destruction task. | |
| 261 void DestroyTask(); | |
| 262 | |
| 263 // Start |device_poll_thread_|. | |
| 264 bool StartDevicePoll(); | |
| 265 | |
| 266 // Stop |device_poll_thread_|. | |
| 267 bool StopDevicePoll(); | |
| 268 | |
| 269 bool StopInputStream(); | |
| 270 bool StopOutputStream(); | |
| 271 | |
| 272 void StartResolutionChange(); | |
| 273 void FinishResolutionChange(); | |
| 274 | |
| 275 // Try to get output format and visible size, detected after parsing the | |
| 276 // beginning of the stream. Sets |again| to true if more parsing is needed. | |
| 277 // |visible_size| could be nullptr and ignored. | |
| 278 bool GetFormatInfo(struct v4l2_format* format, | |
| 279 gfx::Size* visible_size, | |
| 280 bool* again); | |
| 281 // Create output buffers for the given |format| and |visible_size|. | |
| 282 bool CreateBuffersForFormat(const struct v4l2_format& format, | |
| 283 const gfx::Size& visible_size); | |
| 284 | |
| 285 // Try to get |visible_size|. Return visible size, or, if querying it is not | |
| 286 // supported or produces invalid size, return |coded_size| instead. | |
| 287 gfx::Size GetVisibleSize(const gfx::Size& coded_size); | |
| 288 | |
| 289 // | |
| 290 // Device tasks, to be run on device_poll_thread_. | |
| 291 // | |
| 292 | |
| 293 // The device task. | |
| 294 void DevicePollTask(bool poll_device); | |
| 295 | |
| 296 // | |
| 297 // Safe from any thread. | |
| 298 // | |
| 299 | |
| 300 // Error notification (using PostTask() to child thread, if necessary). | |
| 301 void NotifyError(Error error); | |
| 302 | |
| 303 // Set the decoder_state_ to kError and notify the client (if necessary). | |
| 304 void SetErrorState(Error error); | |
| 305 | |
| 306 // | |
| 307 // Other utility functions. Called on decoder_thread_, unless | |
| 308 // decoder_thread_ is not yet started, in which case the child thread can call | |
| 309 // these (e.g. in Initialize() or Destroy()). | |
| 310 // | |
| 311 | |
| 312 // Create the buffers we need. | |
| 313 bool CreateInputBuffers(); | |
| 314 bool CreateOutputBuffers(); | |
| 315 | |
| 316 // Set input and output formats before starting decode. | |
| 317 bool SetupFormats(); | |
| 318 // Return a usable input format of image processor. Return 0 if not found. | |
| 319 uint32_t FindImageProcessorInputFormat(); | |
| 320 // Return a usable output format of image processor. Return 0 if not found. | |
| 321 uint32_t FindImageProcessorOutputFormat(); | |
| 322 | |
| 323 // | |
| 324 // Methods run on child thread. | |
| 325 // | |
| 326 | |
| 327 // Destroy buffers. | |
| 328 void DestroyInputBuffers(); | |
| 329 // In contrast to DestroyInputBuffers, which is called only from destructor, | |
| 330 // we call DestroyOutputBuffers also during playback, on resolution change. | |
| 331 // Even if anything fails along the way, we still want to go on and clean | |
| 332 // up as much as possible, so return false if this happens, so that the | |
| 333 // caller can error out on resolution change. | |
| 334 bool DestroyOutputBuffers(); | |
| 335 void ResolutionChangeDestroyBuffers(); | |
| 336 | |
| 337 // Send decoded pictures to PictureReady. | |
| 338 void SendPictureReady(); | |
| 339 | |
| 340 // Callback that indicates a picture has been cleared. | |
| 341 void PictureCleared(); | |
| 342 | |
| 343 // Image processor returns a processed frame. Its id is |bitstream_buffer_id| | |
| 344 // and stored in |output_buffer_index| buffer of image processor. | |
| 345 void FrameProcessed(int32_t bitstream_buffer_id, int output_buffer_index); | |
| 346 | |
| 347 // Image processor notifies an error. | |
| 348 void ImageProcessorError(); | |
| 349 | |
| 350 // Our original calling task runner for the child thread. | |
| 351 scoped_refptr<base::SingleThreadTaskRunner> child_task_runner_; | |
| 352 | |
| 353 // Task runner Decode() and PictureReady() run on. | |
| 354 scoped_refptr<base::SingleThreadTaskRunner> decode_task_runner_; | |
| 355 | |
| 356 // WeakPtr<> pointing to |this| for use in posting tasks from the decoder or | |
| 357 // device worker threads back to the child thread. Because the worker threads | |
| 358 // are members of this class, any task running on those threads is guaranteed | |
| 359 // that this object is still alive. As a result, tasks posted from the child | |
| 360 // thread to the decoder or device thread should use base::Unretained(this), | |
| 361 // and tasks posted the other way should use |weak_this_|. | |
| 362 base::WeakPtr<V4L2VideoDecodeAccelerator> weak_this_; | |
| 363 | |
| 364 // To expose client callbacks from VideoDecodeAccelerator. | |
| 365 // NOTE: all calls to these objects *MUST* be executed on | |
| 366 // child_task_runner_. | |
| 367 std::unique_ptr<base::WeakPtrFactory<Client>> client_ptr_factory_; | |
| 368 base::WeakPtr<Client> client_; | |
| 369 // Callbacks to |decode_client_| must be executed on |decode_task_runner_|. | |
| 370 base::WeakPtr<Client> decode_client_; | |
| 371 | |
| 372 // | |
| 373 // Decoder state, owned and operated by decoder_thread_. | |
| 374 // Before decoder_thread_ has started, the decoder state is managed by | |
| 375 // the child (main) thread. After decoder_thread_ has started, the decoder | |
| 376 // thread should be the only one managing these. | |
| 377 // | |
| 378 | |
| 379 // This thread services tasks posted from the VDA API entry points by the | |
| 380 // child thread and device service callbacks posted from the device thread. | |
| 381 base::Thread decoder_thread_; | |
| 382 // Decoder state machine state. | |
| 383 State decoder_state_; | |
| 384 // BitstreamBuffer we're presently reading. | |
| 385 std::unique_ptr<BitstreamBufferRef> decoder_current_bitstream_buffer_; | |
| 386 // The V4L2Device this class is operating upon. | |
| 387 scoped_refptr<V4L2Device> device_; | |
| 388 // FlushTask() and ResetTask() should not affect buffers that have been | |
| 389 // queued afterwards. For flushing or resetting the pipeline then, we will | |
| 390 // delay these buffers until after the flush or reset completes. | |
| 391 int decoder_delay_bitstream_buffer_id_; | |
| 392 // Input buffer we're presently filling. | |
| 393 int decoder_current_input_buffer_; | |
| 394 // We track the number of buffer decode tasks we have scheduled, since each | |
| 395 // task execution should complete one buffer. If we fall behind (due to | |
| 396 // resource backpressure, etc.), we'll have to schedule more to catch up. | |
| 397 int decoder_decode_buffer_tasks_scheduled_; | |
| 398 // Picture buffers held by the client. | |
| 399 int decoder_frames_at_client_; | |
| 400 // Are we flushing? | |
| 401 bool decoder_flushing_; | |
| 402 // Got a reset request while we were performing resolution change. | |
| 403 bool resolution_change_reset_pending_; | |
| 404 // Input queue for decoder_thread_: BitstreamBuffers in. | |
| 405 std::queue<linked_ptr<BitstreamBufferRef> > decoder_input_queue_; | |
| 406 // For H264 decode, hardware requires that we send it frame-sized chunks. | |
| 407 // We'll need to parse the stream. | |
| 408 std::unique_ptr<media::H264Parser> decoder_h264_parser_; | |
| 409 // Set if the decoder has a pending incomplete frame in an input buffer. | |
| 410 bool decoder_partial_frame_pending_; | |
| 411 | |
| 412 // | |
| 413 // Hardware state and associated queues. Since decoder_thread_ services | |
| 414 // the hardware, decoder_thread_ owns these too. | |
| 415 // output_buffer_map_, free_output_buffers_ and output_planes_count_ are an | |
| 416 // exception during the buffer (re)allocation sequence, when the | |
| 417 // decoder_thread_ is blocked briefly while the Child thread manipulates | |
| 418 // them. | |
| 419 // | |
| 420 | |
| 421 // Completed decode buffers. | |
| 422 std::queue<int> input_ready_queue_; | |
| 423 | |
| 424 // Input buffer state. | |
| 425 bool input_streamon_; | |
| 426 // Input buffers enqueued to device. | |
| 427 int input_buffer_queued_count_; | |
| 428 // Input buffers ready to use, as a LIFO since we don't care about ordering. | |
| 429 std::vector<int> free_input_buffers_; | |
| 430 // Mapping of int index to input buffer record. | |
| 431 std::vector<InputRecord> input_buffer_map_; | |
| 432 | |
| 433 // Output buffer state. | |
| 434 bool output_streamon_; | |
| 435 // Output buffers enqueued to device. | |
| 436 int output_buffer_queued_count_; | |
| 437 // Output buffers ready to use, as a FIFO since we want oldest-first to hide | |
| 438 // synchronization latency with GL. | |
| 439 std::queue<int> free_output_buffers_; | |
| 440 // Mapping of int index to output buffer record. | |
| 441 std::vector<OutputRecord> output_buffer_map_; | |
| 442 // Required size of DPB for decoding. | |
| 443 int output_dpb_size_; | |
| 444 | |
| 445 // Number of planes (i.e. separate memory buffers) for output. | |
| 446 size_t output_planes_count_; | |
| 447 | |
| 448 // Pictures that are ready but not sent to PictureReady yet. | |
| 449 std::queue<PictureRecord> pending_picture_ready_; | |
| 450 | |
| 451 // The number of pictures that are sent to PictureReady and will be cleared. | |
| 452 int picture_clearing_count_; | |
| 453 | |
| 454 // Used by the decoder thread to wait for AssignPictureBuffers to arrive | |
| 455 // to avoid races with potential Reset requests. | |
| 456 base::WaitableEvent pictures_assigned_; | |
| 457 | |
| 458 // Output picture coded size. | |
| 459 gfx::Size coded_size_; | |
| 460 | |
| 461 // Output picture visible size. | |
| 462 gfx::Size visible_size_; | |
| 463 | |
| 464 // | |
| 465 // The device polling thread handles notifications of V4L2 device changes. | |
| 466 // | |
| 467 | |
| 468 // The thread. | |
| 469 base::Thread device_poll_thread_; | |
| 470 | |
| 471 // | |
| 472 // Other state, held by the child (main) thread. | |
| 473 // | |
| 474 | |
| 475 // EGL state | |
| 476 EGLDisplay egl_display_; | |
| 477 | |
| 478 // Callback to get current GLContext. | |
| 479 GetGLContextCallback get_gl_context_cb_; | |
| 480 // Callback to set the correct gl context. | |
| 481 MakeGLContextCurrentCallback make_context_current_cb_; | |
| 482 | |
| 483 // The codec we'll be decoding for. | |
| 484 media::VideoCodecProfile video_profile_; | |
| 485 // Chosen output format. | |
| 486 uint32_t output_format_fourcc_; | |
| 487 | |
| 488 // Image processor device, if one is in use. | |
| 489 scoped_refptr<V4L2Device> image_processor_device_; | |
| 490 // Image processor. Created and destroyed on child thread. | |
| 491 std::unique_ptr<V4L2ImageProcessor> image_processor_; | |
| 492 | |
| 493 // The V4L2Device EGLImage is created from. | |
| 494 scoped_refptr<V4L2Device> egl_image_device_; | |
| 495 // The format of EGLImage. | |
| 496 uint32_t egl_image_format_fourcc_; | |
| 497 // The logical dimensions of EGLImage buffer in pixels. | |
| 498 gfx::Size egl_image_size_; | |
| 499 // Number of planes for EGLImage. | |
| 500 size_t egl_image_planes_count_; | |
| 501 | |
| 502 // IDs of bitstream buffers sent to image processor to process. After a | |
| 503 // buffer is processed, it will sent to render if the id is in this | |
| 504 // queue. If the id is not in this queue, the buffer will be dropped. | |
| 505 std::queue<int> image_processor_bitstream_buffer_ids_; | |
| 506 | |
| 507 // Input format V4L2 fourccs this class supports. | |
| 508 static const uint32_t supported_input_fourccs_[]; | |
| 509 | |
| 510 // The WeakPtrFactory for |weak_this_|. | |
| 511 base::WeakPtrFactory<V4L2VideoDecodeAccelerator> weak_this_factory_; | |
| 512 | |
| 513 DISALLOW_COPY_AND_ASSIGN(V4L2VideoDecodeAccelerator); | |
| 514 }; | |
| 515 | |
| 516 } // namespace content | |
| 517 | |
| 518 #endif // CONTENT_COMMON_GPU_MEDIA_V4L2_VIDEO_DECODE_ACCELERATOR_H_ | |
| OLD | NEW |