| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include <dlfcn.h> | 5 #include <dlfcn.h> |
| 6 #include <errno.h> | 6 #include <errno.h> |
| 7 #include <fcntl.h> | 7 #include <fcntl.h> |
| 8 #include <libdrm/drm_fourcc.h> | 8 #include <libdrm/drm_fourcc.h> |
| 9 #include <linux/videodev2.h> | 9 #include <linux/videodev2.h> |
| 10 #include <poll.h> | 10 #include <poll.h> |
| (...skipping 270 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 281 video_profile_ <= media::H264PROFILE_MAX) { | 281 video_profile_ <= media::H264PROFILE_MAX) { |
| 282 decoder_h264_parser_.reset(new media::H264Parser()); | 282 decoder_h264_parser_.reset(new media::H264Parser()); |
| 283 } | 283 } |
| 284 | 284 |
| 285 if (!decoder_thread_.Start()) { | 285 if (!decoder_thread_.Start()) { |
| 286 DLOG(ERROR) << "Initialize(): decoder thread failed to start"; | 286 DLOG(ERROR) << "Initialize(): decoder thread failed to start"; |
| 287 NOTIFY_ERROR(PLATFORM_FAILURE); | 287 NOTIFY_ERROR(PLATFORM_FAILURE); |
| 288 return false; | 288 return false; |
| 289 } | 289 } |
| 290 | 290 |
| 291 if (!StartDevicePoll()) |
| 292 return false; |
| 293 |
| 291 SetDecoderState(kInitialized); | 294 SetDecoderState(kInitialized); |
| 292 | 295 |
| 293 child_message_loop_proxy_->PostTask(FROM_HERE, base::Bind( | 296 child_message_loop_proxy_->PostTask(FROM_HERE, base::Bind( |
| 294 &Client::NotifyInitializeDone, client_)); | 297 &Client::NotifyInitializeDone, client_)); |
| 295 return true; | 298 return true; |
| 296 } | 299 } |
| 297 | 300 |
| 298 void V4L2VideoDecodeAccelerator::Decode( | 301 void V4L2VideoDecodeAccelerator::Decode( |
| 299 const media::BitstreamBuffer& bitstream_buffer) { | 302 const media::BitstreamBuffer& bitstream_buffer) { |
| 300 DVLOG(1) << "Decode(): input_id=" << bitstream_buffer.id() | 303 DVLOG(1) << "Decode(): input_id=" << bitstream_buffer.id() |
| (...skipping 401 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 702 base::Unretained(this))); | 705 base::Unretained(this))); |
| 703 } | 706 } |
| 704 } | 707 } |
| 705 | 708 |
| 706 bool V4L2VideoDecodeAccelerator::DecodeBufferInitial( | 709 bool V4L2VideoDecodeAccelerator::DecodeBufferInitial( |
| 707 const void* data, size_t size, size_t* endpos) { | 710 const void* data, size_t size, size_t* endpos) { |
| 708 DVLOG(3) << "DecodeBufferInitial(): data=" << data << ", size=" << size; | 711 DVLOG(3) << "DecodeBufferInitial(): data=" << data << ", size=" << size; |
| 709 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); | 712 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); |
| 710 DCHECK_NE(decoder_state_, kUninitialized); | 713 DCHECK_NE(decoder_state_, kUninitialized); |
| 711 DCHECK_NE(decoder_state_, kDecoding); | 714 DCHECK_NE(decoder_state_, kDecoding); |
| 712 DCHECK(!device_poll_thread_.IsRunning()); | |
| 713 // Initial decode. We haven't been able to get output stream format info yet. | 715 // Initial decode. We haven't been able to get output stream format info yet. |
| 714 // Get it, and start decoding. | 716 // Get it, and start decoding. |
| 715 | 717 |
| 716 // Copy in and send to HW. | 718 // Copy in and send to HW. |
| 717 if (!AppendToInputFrame(data, size)) | 719 if (!AppendToInputFrame(data, size)) |
| 718 return false; | 720 return false; |
| 719 | 721 |
| 720 // If we only have a partial frame, don't flush and process yet. | 722 // If we only have a partial frame, don't flush and process yet. |
| 721 if (decoder_partial_frame_pending_) | 723 if (decoder_partial_frame_pending_) |
| 722 return true; | 724 return true; |
| (...skipping 25 matching lines...) Expand all Loading... |
| 748 | 750 |
| 749 // We expect to process the initial buffer once during stream init to | 751 // We expect to process the initial buffer once during stream init to |
| 750 // configure stream parameters, but will not consume the steam data on that | 752 // configure stream parameters, but will not consume the steam data on that |
| 751 // iteration. Subsequent iterations (including after reset) do not require | 753 // iteration. Subsequent iterations (including after reset) do not require |
| 752 // the stream init step. | 754 // the stream init step. |
| 753 *endpos = 0; | 755 *endpos = 0; |
| 754 } else { | 756 } else { |
| 755 *endpos = size; | 757 *endpos = size; |
| 756 } | 758 } |
| 757 | 759 |
| 758 // StartDevicePoll will raise the error if there is one. | |
| 759 if (!StartDevicePoll()) | |
| 760 return false; | |
| 761 | |
| 762 decoder_state_ = kDecoding; | 760 decoder_state_ = kDecoding; |
| 763 ScheduleDecodeBufferTaskIfNeeded(); | 761 ScheduleDecodeBufferTaskIfNeeded(); |
| 764 return true; | 762 return true; |
| 765 } | 763 } |
| 766 | 764 |
| 767 bool V4L2VideoDecodeAccelerator::DecodeBufferContinue( | 765 bool V4L2VideoDecodeAccelerator::DecodeBufferContinue( |
| 768 const void* data, size_t size) { | 766 const void* data, size_t size) { |
| 769 DVLOG(3) << "DecodeBufferContinue(): data=" << data << ", size=" << size; | 767 DVLOG(3) << "DecodeBufferContinue(): data=" << data << ", size=" << size; |
| 770 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); | 768 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); |
| 771 DCHECK_EQ(decoder_state_, kDecoding); | 769 DCHECK_EQ(decoder_state_, kDecoding); |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 878 // Enqueue once since there's new available input for it. | 876 // Enqueue once since there's new available input for it. |
| 879 Enqueue(); | 877 Enqueue(); |
| 880 | 878 |
| 881 return (decoder_state_ != kError); | 879 return (decoder_state_ != kError); |
| 882 } | 880 } |
| 883 | 881 |
| 884 void V4L2VideoDecodeAccelerator::ServiceDeviceTask(bool event_pending) { | 882 void V4L2VideoDecodeAccelerator::ServiceDeviceTask(bool event_pending) { |
| 885 DVLOG(3) << "ServiceDeviceTask()"; | 883 DVLOG(3) << "ServiceDeviceTask()"; |
| 886 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); | 884 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); |
| 887 DCHECK_NE(decoder_state_, kUninitialized); | 885 DCHECK_NE(decoder_state_, kUninitialized); |
| 888 DCHECK_NE(decoder_state_, kInitialized); | |
| 889 DCHECK_NE(decoder_state_, kAfterReset); | |
| 890 TRACE_EVENT0("Video Decoder", "V4L2VDA::ServiceDeviceTask"); | 886 TRACE_EVENT0("Video Decoder", "V4L2VDA::ServiceDeviceTask"); |
| 891 | 887 |
| 892 if (decoder_state_ == kResetting) { | 888 if (decoder_state_ == kResetting) { |
| 893 DVLOG(2) << "ServiceDeviceTask(): early out: kResetting state"; | 889 DVLOG(2) << "ServiceDeviceTask(): early out: kResetting state"; |
| 894 return; | 890 return; |
| 895 } else if (decoder_state_ == kError) { | 891 } else if (decoder_state_ == kError) { |
| 896 DVLOG(2) << "ServiceDeviceTask(): early out: kError state"; | 892 DVLOG(2) << "ServiceDeviceTask(): early out: kError state"; |
| 897 return; | 893 return; |
| 898 } else if (decoder_state_ == kChangingResolution) { | 894 } else if (decoder_state_ == kChangingResolution) { |
| 899 DVLOG(2) << "ServiceDeviceTask(): early out: kChangingResolution state"; | 895 DVLOG(2) << "ServiceDeviceTask(): early out: kChangingResolution state"; |
| (...skipping 446 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1346 void V4L2VideoDecodeAccelerator::ResetDoneTask() { | 1342 void V4L2VideoDecodeAccelerator::ResetDoneTask() { |
| 1347 DVLOG(3) << "ResetDoneTask()"; | 1343 DVLOG(3) << "ResetDoneTask()"; |
| 1348 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); | 1344 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); |
| 1349 TRACE_EVENT0("Video Decoder", "V4L2VDA::ResetDoneTask"); | 1345 TRACE_EVENT0("Video Decoder", "V4L2VDA::ResetDoneTask"); |
| 1350 | 1346 |
| 1351 if (decoder_state_ == kError) { | 1347 if (decoder_state_ == kError) { |
| 1352 DVLOG(2) << "ResetDoneTask(): early out: kError state"; | 1348 DVLOG(2) << "ResetDoneTask(): early out: kError state"; |
| 1353 return; | 1349 return; |
| 1354 } | 1350 } |
| 1355 | 1351 |
| 1352 if (!StartDevicePoll()) |
| 1353 return; |
| 1354 |
| 1356 // We might have received a resolution change event while we were waiting | 1355 // We might have received a resolution change event while we were waiting |
| 1357 // for the reset to finish. The codec will not post another event if the | 1356 // for the reset to finish. The codec will not post another event if the |
| 1358 // resolution after reset remains the same as the one to which were just | 1357 // resolution after reset remains the same as the one to which were just |
| 1359 // about to switch, so preserve the event across reset so we can address | 1358 // about to switch, so preserve the event across reset so we can address |
| 1360 // it after resuming. | 1359 // it after resuming. |
| 1361 | 1360 |
| 1362 // Reset format-specific bits. | 1361 // Reset format-specific bits. |
| 1363 if (video_profile_ >= media::H264PROFILE_MIN && | 1362 if (video_profile_ >= media::H264PROFILE_MIN && |
| 1364 video_profile_ <= media::H264PROFILE_MAX) { | 1363 video_profile_ <= media::H264PROFILE_MAX) { |
| 1365 decoder_h264_parser_.reset(new media::H264Parser()); | 1364 decoder_h264_parser_.reset(new media::H264Parser()); |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1400 while (!decoder_input_queue_.empty()) | 1399 while (!decoder_input_queue_.empty()) |
| 1401 decoder_input_queue_.pop(); | 1400 decoder_input_queue_.pop(); |
| 1402 decoder_flushing_ = false; | 1401 decoder_flushing_ = false; |
| 1403 | 1402 |
| 1404 // Set our state to kError. Just in case. | 1403 // Set our state to kError. Just in case. |
| 1405 decoder_state_ = kError; | 1404 decoder_state_ = kError; |
| 1406 } | 1405 } |
| 1407 | 1406 |
| 1408 bool V4L2VideoDecodeAccelerator::StartDevicePoll() { | 1407 bool V4L2VideoDecodeAccelerator::StartDevicePoll() { |
| 1409 DVLOG(3) << "StartDevicePoll()"; | 1408 DVLOG(3) << "StartDevicePoll()"; |
| 1410 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); | |
| 1411 DCHECK(!device_poll_thread_.IsRunning()); | 1409 DCHECK(!device_poll_thread_.IsRunning()); |
| 1410 if (decoder_thread_.IsRunning()) |
| 1411 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); |
| 1412 | 1412 |
| 1413 // Start up the device poll thread and schedule its first DevicePollTask(). | 1413 // Start up the device poll thread and schedule its first DevicePollTask(). |
| 1414 if (!device_poll_thread_.Start()) { | 1414 if (!device_poll_thread_.Start()) { |
| 1415 DLOG(ERROR) << "StartDevicePoll(): Device thread failed to start"; | 1415 DLOG(ERROR) << "StartDevicePoll(): Device thread failed to start"; |
| 1416 NOTIFY_ERROR(PLATFORM_FAILURE); | 1416 NOTIFY_ERROR(PLATFORM_FAILURE); |
| 1417 return false; | 1417 return false; |
| 1418 } | 1418 } |
| 1419 device_poll_thread_.message_loop()->PostTask(FROM_HERE, base::Bind( | 1419 device_poll_thread_.message_loop()->PostTask(FROM_HERE, base::Bind( |
| 1420 &V4L2VideoDecodeAccelerator::DevicePollTask, | 1420 &V4L2VideoDecodeAccelerator::DevicePollTask, |
| 1421 base::Unretained(this), | 1421 base::Unretained(this), |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1488 } | 1488 } |
| 1489 } | 1489 } |
| 1490 output_buffer_queued_count_ = 0; | 1490 output_buffer_queued_count_ = 0; |
| 1491 | 1491 |
| 1492 DVLOG(3) << "StopDevicePoll(): device poll stopped"; | 1492 DVLOG(3) << "StopDevicePoll(): device poll stopped"; |
| 1493 return true; | 1493 return true; |
| 1494 } | 1494 } |
| 1495 | 1495 |
| 1496 void V4L2VideoDecodeAccelerator::StartResolutionChangeIfNeeded() { | 1496 void V4L2VideoDecodeAccelerator::StartResolutionChangeIfNeeded() { |
| 1497 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); | 1497 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); |
| 1498 DCHECK_EQ(decoder_state_, kDecoding); | 1498 DCHECK_NE(decoder_state_, kUninitialized); |
| 1499 DCHECK_NE(decoder_state_, kResetting); |
| 1499 | 1500 |
| 1500 if (!resolution_change_pending_) | 1501 if (!resolution_change_pending_) |
| 1501 return; | 1502 return; |
| 1502 | 1503 |
| 1503 DVLOG(3) << "No more work, initiate resolution change"; | 1504 DVLOG(3) << "No more work, initiate resolution change"; |
| 1504 | 1505 |
| 1505 // Keep input queue. | 1506 // Keep input queue. |
| 1506 if (!StopDevicePoll(true)) | 1507 if (!StopDevicePoll(true)) |
| 1507 return; | 1508 return; |
| 1508 | 1509 |
| (...skipping 410 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1919 | 1920 |
| 1920 void V4L2VideoDecodeAccelerator::PictureCleared() { | 1921 void V4L2VideoDecodeAccelerator::PictureCleared() { |
| 1921 DVLOG(3) << "PictureCleared(). clearing count=" << picture_clearing_count_; | 1922 DVLOG(3) << "PictureCleared(). clearing count=" << picture_clearing_count_; |
| 1922 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); | 1923 DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current()); |
| 1923 DCHECK_GT(picture_clearing_count_, 0); | 1924 DCHECK_GT(picture_clearing_count_, 0); |
| 1924 picture_clearing_count_--; | 1925 picture_clearing_count_--; |
| 1925 SendPictureReady(); | 1926 SendPictureReady(); |
| 1926 } | 1927 } |
| 1927 | 1928 |
| 1928 } // namespace content | 1929 } // namespace content |
| OLD | NEW |