| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 "content/common/gpu/media/omx_video_decode_accelerator.h" | 5 #include "content/common/gpu/media/omx_video_decode_accelerator.h" |
| 6 | 6 |
| 7 #include "base/debug/trace_event.h" |
| 7 #include "base/stl_util.h" | 8 #include "base/stl_util.h" |
| 8 #include "base/string_util.h" | 9 #include "base/string_util.h" |
| 9 #include "content/common/gpu/gpu_channel.h" | 10 #include "content/common/gpu/gpu_channel.h" |
| 10 #include "content/common/gpu/media/gles2_texture_to_egl_image_translator.h" | 11 #include "content/common/gpu/media/gles2_texture_to_egl_image_translator.h" |
| 11 #include "media/base/bitstream_buffer.h" | 12 #include "media/base/bitstream_buffer.h" |
| 12 #include "media/video/picture.h" | 13 #include "media/video/picture.h" |
| 13 | 14 |
| 14 // Helper typedef for input buffers. This is used as the pAppPrivate field of | 15 // Helper typedef for input buffers. This is used as the pAppPrivate field of |
| 15 // OMX_BUFFERHEADERTYPEs of input buffers, to point to the data associated with | 16 // OMX_BUFFERHEADERTYPEs of input buffers, to point to the data associated with |
| 16 // them. | 17 // them. |
| (...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 270 buffer->nTimeStamp = -1; | 271 buffer->nTimeStamp = -1; |
| 271 buffer->nOutputPortIndex = output_port_; | 272 buffer->nOutputPortIndex = output_port_; |
| 272 CHECK(fake_output_buffers_.insert(buffer).second); | 273 CHECK(fake_output_buffers_.insert(buffer).second); |
| 273 } | 274 } |
| 274 | 275 |
| 275 return true; | 276 return true; |
| 276 } | 277 } |
| 277 | 278 |
| 278 void OmxVideoDecodeAccelerator::Decode( | 279 void OmxVideoDecodeAccelerator::Decode( |
| 279 const media::BitstreamBuffer& bitstream_buffer) { | 280 const media::BitstreamBuffer& bitstream_buffer) { |
| 281 TRACE_EVENT1("Video Decoder", "OVDA::Decode", |
| 282 "Buffer id", bitstream_buffer.id()); |
| 280 DCHECK_EQ(message_loop_, MessageLoop::current()); | 283 DCHECK_EQ(message_loop_, MessageLoop::current()); |
| 281 DCHECK(!free_input_buffers_.empty()); | 284 DCHECK(!free_input_buffers_.empty()); |
| 282 | 285 |
| 283 if (current_state_change_ == RESETTING || | 286 if (current_state_change_ == RESETTING || |
| 284 !queued_bitstream_buffers_.empty()) { | 287 !queued_bitstream_buffers_.empty()) { |
| 285 queued_bitstream_buffers_.push_back(bitstream_buffer); | 288 queued_bitstream_buffers_.push_back(bitstream_buffer); |
| 286 return; | 289 return; |
| 287 } | 290 } |
| 288 | 291 |
| 289 RETURN_ON_FAILURE(current_state_change_ == NO_TRANSITION && | 292 RETURN_ON_FAILURE(current_state_change_ == NO_TRANSITION && |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 346 DCHECK_EQ(pictures_.size(), kNumPictureBuffers); | 349 DCHECK_EQ(pictures_.size(), kNumPictureBuffers); |
| 347 | 350 |
| 348 // These do their own RETURN_ON_FAILURE dances. | 351 // These do their own RETURN_ON_FAILURE dances. |
| 349 if (!AllocateOutputBuffers()) | 352 if (!AllocateOutputBuffers()) |
| 350 return; | 353 return; |
| 351 if (!SendCommandToPort(OMX_CommandPortEnable, output_port_)) | 354 if (!SendCommandToPort(OMX_CommandPortEnable, output_port_)) |
| 352 return; | 355 return; |
| 353 } | 356 } |
| 354 | 357 |
| 355 void OmxVideoDecodeAccelerator::ReusePictureBuffer(int32 picture_buffer_id) { | 358 void OmxVideoDecodeAccelerator::ReusePictureBuffer(int32 picture_buffer_id) { |
| 359 TRACE_EVENT1("Video Decoder", "OVDA::ReusePictureBuffer", |
| 360 "Picture id", picture_buffer_id); |
| 356 DCHECK_EQ(message_loop_, MessageLoop::current()); | 361 DCHECK_EQ(message_loop_, MessageLoop::current()); |
| 357 RETURN_ON_FAILURE(CanFillBuffer(), "Can't fill buffer", ILLEGAL_STATE,); | 362 RETURN_ON_FAILURE(CanFillBuffer(), "Can't fill buffer", ILLEGAL_STATE,); |
| 358 | 363 |
| 359 OutputPictureById::iterator it = pictures_.find(picture_buffer_id); | 364 OutputPictureById::iterator it = pictures_.find(picture_buffer_id); |
| 360 RETURN_ON_FAILURE(it != pictures_.end(), | 365 RETURN_ON_FAILURE(it != pictures_.end(), |
| 361 "Missing picture buffer id: " << picture_buffer_id, | 366 "Missing picture buffer id: " << picture_buffer_id, |
| 362 INVALID_ARGUMENT,); | 367 INVALID_ARGUMENT,); |
| 363 OutputPicture& output_picture = it->second; | 368 OutputPicture& output_picture = it->second; |
| 364 | 369 |
| 365 ++output_buffers_at_component_; | 370 ++output_buffers_at_component_; |
| (...skipping 363 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 729 omx_buffer->nOutputPortIndex = output_port_; | 734 omx_buffer->nOutputPortIndex = output_port_; |
| 730 ++output_buffers_at_component_; | 735 ++output_buffers_at_component_; |
| 731 OMX_ERRORTYPE result = OMX_FillThisBuffer(component_handle_, omx_buffer); | 736 OMX_ERRORTYPE result = OMX_FillThisBuffer(component_handle_, omx_buffer); |
| 732 RETURN_ON_OMX_FAILURE(result, "OMX_FillThisBuffer() failed", | 737 RETURN_ON_OMX_FAILURE(result, "OMX_FillThisBuffer() failed", |
| 733 PLATFORM_FAILURE,); | 738 PLATFORM_FAILURE,); |
| 734 } | 739 } |
| 735 } | 740 } |
| 736 | 741 |
| 737 void OmxVideoDecodeAccelerator::FillBufferDoneTask( | 742 void OmxVideoDecodeAccelerator::FillBufferDoneTask( |
| 738 OMX_BUFFERHEADERTYPE* buffer) { | 743 OMX_BUFFERHEADERTYPE* buffer) { |
| 744 media::Picture* picture = |
| 745 reinterpret_cast<media::Picture*>(buffer->pAppPrivate); |
| 746 int picture_buffer_id = picture ? picture->picture_buffer_id() : -1; |
| 747 TRACE_EVENT2("Video Decoder", "OVDA::FillBufferDoneTask", |
| 748 "Buffer id", buffer->nTimeStamp, |
| 749 "Picture id", picture_buffer_id); |
| 739 DCHECK_EQ(message_loop_, MessageLoop::current()); | 750 DCHECK_EQ(message_loop_, MessageLoop::current()); |
| 740 DCHECK_GT(output_buffers_at_component_, 0); | 751 DCHECK_GT(output_buffers_at_component_, 0); |
| 741 --output_buffers_at_component_; | 752 --output_buffers_at_component_; |
| 742 | 753 |
| 743 if (fake_output_buffers_.size() && fake_output_buffers_.count(buffer)) { | 754 if (fake_output_buffers_.size() && fake_output_buffers_.count(buffer)) { |
| 744 CHECK_EQ(fake_output_buffers_.erase(buffer), 1U); | 755 CHECK_EQ(fake_output_buffers_.erase(buffer), 1U); |
| 745 OMX_ERRORTYPE result = | 756 OMX_ERRORTYPE result = |
| 746 OMX_FreeBuffer(component_handle_, output_port_, buffer); | 757 OMX_FreeBuffer(component_handle_, output_port_, buffer); |
| 747 RETURN_ON_OMX_FAILURE(result, "OMX_FreeBuffer failed", PLATFORM_FAILURE,); | 758 RETURN_ON_OMX_FAILURE(result, "OMX_FreeBuffer failed", PLATFORM_FAILURE,); |
| 748 return; | 759 return; |
| 749 } | 760 } |
| 750 CHECK(!fake_output_buffers_.size()); | 761 CHECK(!fake_output_buffers_.size()); |
| 751 | 762 |
| 752 if (current_state_change_ == FLUSHING && | 763 if (current_state_change_ == FLUSHING && |
| 753 buffer->nFlags & OMX_BUFFERFLAG_EOS) { | 764 buffer->nFlags & OMX_BUFFERFLAG_EOS) { |
| 754 DCHECK(!saw_eos_during_flush_); | 765 DCHECK(!saw_eos_during_flush_); |
| 755 saw_eos_during_flush_ = true; | 766 saw_eos_during_flush_ = true; |
| 756 } | 767 } |
| 757 | 768 |
| 758 DCHECK(buffer->pAppPrivate); | |
| 759 media::Picture* picture = | |
| 760 reinterpret_cast<media::Picture*>(buffer->pAppPrivate); | |
| 761 int picture_buffer_id = picture->picture_buffer_id(); | |
| 762 | |
| 763 // During the transition from Executing to Idle, and during port-flushing, all | 769 // During the transition from Executing to Idle, and during port-flushing, all |
| 764 // pictures are sent back through here. Avoid giving them to the client. | 770 // pictures are sent back through here. Avoid giving them to the client. |
| 765 // Also avoid sending the (fake) EOS buffer to the client. | 771 // Also avoid sending the (fake) EOS buffer to the client. |
| 766 if ((current_state_change_ != NO_TRANSITION && | 772 if ((current_state_change_ != NO_TRANSITION && |
| 767 current_state_change_ != FLUSHING) || | 773 current_state_change_ != FLUSHING) || |
| 768 saw_eos_during_flush_) { | 774 saw_eos_during_flush_) { |
| 769 if (current_state_change_ == RESETTING) | 775 if (current_state_change_ == RESETTING) |
| 770 queued_picture_buffer_ids_.push_back(picture_buffer_id); | 776 queued_picture_buffer_ids_.push_back(picture_buffer_id); |
| 771 return; | 777 return; |
| 772 } | 778 } |
| 773 | 779 |
| 780 DCHECK(picture); |
| 774 // See Decode() for an explanation of this abuse of nTimeStamp. | 781 // See Decode() for an explanation of this abuse of nTimeStamp. |
| 775 picture->set_bitstream_buffer_id(buffer->nTimeStamp); | 782 picture->set_bitstream_buffer_id(buffer->nTimeStamp); |
| 776 if (client_) | 783 if (client_) |
| 777 client_->PictureReady(*picture); | 784 client_->PictureReady(*picture); |
| 778 } | 785 } |
| 779 | 786 |
| 780 void OmxVideoDecodeAccelerator::EmptyBufferDoneTask( | 787 void OmxVideoDecodeAccelerator::EmptyBufferDoneTask( |
| 781 OMX_BUFFERHEADERTYPE* buffer) { | 788 OMX_BUFFERHEADERTYPE* buffer) { |
| 789 TRACE_EVENT1("Video Decoder", "OVDA::EmptyBufferDoneTask", |
| 790 "Buffer id", buffer->nTimeStamp); |
| 782 DCHECK_EQ(message_loop_, MessageLoop::current()); | 791 DCHECK_EQ(message_loop_, MessageLoop::current()); |
| 783 DCHECK_GT(input_buffers_at_component_, 0); | 792 DCHECK_GT(input_buffers_at_component_, 0); |
| 784 free_input_buffers_.push(buffer); | 793 free_input_buffers_.push(buffer); |
| 785 input_buffers_at_component_--; | 794 input_buffers_at_component_--; |
| 786 if (buffer->nFlags & OMX_BUFFERFLAG_EOS) | 795 if (buffer->nFlags & OMX_BUFFERFLAG_EOS) |
| 787 return; | 796 return; |
| 788 | 797 |
| 789 // Retrieve the corresponding BitstreamBuffer's id and notify the client of | 798 // Retrieve the corresponding BitstreamBuffer's id and notify the client of |
| 790 // its completion. | 799 // its completion. |
| 791 SharedMemoryAndId* input_buffer_details = | 800 SharedMemoryAndId* input_buffer_details = |
| (...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 962 decoder, &OmxVideoDecodeAccelerator::EventHandlerCompleteTask, | 971 decoder, &OmxVideoDecodeAccelerator::EventHandlerCompleteTask, |
| 963 event, data1, data2)); | 972 event, data1, data2)); |
| 964 return OMX_ErrorNone; | 973 return OMX_ErrorNone; |
| 965 } | 974 } |
| 966 | 975 |
| 967 // static | 976 // static |
| 968 OMX_ERRORTYPE OmxVideoDecodeAccelerator::EmptyBufferCallback( | 977 OMX_ERRORTYPE OmxVideoDecodeAccelerator::EmptyBufferCallback( |
| 969 OMX_HANDLETYPE component, | 978 OMX_HANDLETYPE component, |
| 970 OMX_PTR priv_data, | 979 OMX_PTR priv_data, |
| 971 OMX_BUFFERHEADERTYPE* buffer) { | 980 OMX_BUFFERHEADERTYPE* buffer) { |
| 981 TRACE_EVENT1("Video Decoder", "OVDA::EmptyBufferCallback", |
| 982 "Buffer id", buffer->nTimeStamp); |
| 972 // Called on the OMX thread. | 983 // Called on the OMX thread. |
| 973 OmxVideoDecodeAccelerator* decoder = | 984 OmxVideoDecodeAccelerator* decoder = |
| 974 static_cast<OmxVideoDecodeAccelerator*>(priv_data); | 985 static_cast<OmxVideoDecodeAccelerator*>(priv_data); |
| 975 DCHECK_EQ(component, decoder->component_handle_); | 986 DCHECK_EQ(component, decoder->component_handle_); |
| 976 decoder->message_loop_->PostTask( | 987 decoder->message_loop_->PostTask( |
| 977 FROM_HERE, | 988 FROM_HERE, |
| 978 NewRunnableMethod(decoder, | 989 NewRunnableMethod(decoder, |
| 979 &OmxVideoDecodeAccelerator::EmptyBufferDoneTask, | 990 &OmxVideoDecodeAccelerator::EmptyBufferDoneTask, |
| 980 buffer)); | 991 buffer)); |
| 981 return OMX_ErrorNone; | 992 return OMX_ErrorNone; |
| 982 } | 993 } |
| 983 | 994 |
| 984 // static | 995 // static |
| 985 OMX_ERRORTYPE OmxVideoDecodeAccelerator::FillBufferCallback( | 996 OMX_ERRORTYPE OmxVideoDecodeAccelerator::FillBufferCallback( |
| 986 OMX_HANDLETYPE component, | 997 OMX_HANDLETYPE component, |
| 987 OMX_PTR priv_data, | 998 OMX_PTR priv_data, |
| 988 OMX_BUFFERHEADERTYPE* buffer) { | 999 OMX_BUFFERHEADERTYPE* buffer) { |
| 1000 media::Picture* picture = |
| 1001 reinterpret_cast<media::Picture*>(buffer->pAppPrivate); |
| 1002 int picture_buffer_id = picture ? picture->picture_buffer_id() : -1; |
| 1003 TRACE_EVENT2("Video Decoder", "OVDA::FillBufferCallback", |
| 1004 "Buffer id", buffer->nTimeStamp, |
| 1005 "Picture id", picture_buffer_id); |
| 989 // Called on the OMX thread. | 1006 // Called on the OMX thread. |
| 990 OmxVideoDecodeAccelerator* decoder = | 1007 OmxVideoDecodeAccelerator* decoder = |
| 991 static_cast<OmxVideoDecodeAccelerator*>(priv_data); | 1008 static_cast<OmxVideoDecodeAccelerator*>(priv_data); |
| 992 DCHECK_EQ(component, decoder->component_handle_); | 1009 DCHECK_EQ(component, decoder->component_handle_); |
| 993 decoder->message_loop_->PostTask( | 1010 decoder->message_loop_->PostTask( |
| 994 FROM_HERE, | 1011 FROM_HERE, |
| 995 NewRunnableMethod(decoder, | 1012 NewRunnableMethod(decoder, |
| 996 &OmxVideoDecodeAccelerator::FillBufferDoneTask, | 1013 &OmxVideoDecodeAccelerator::FillBufferDoneTask, |
| 997 buffer)); | 1014 buffer)); |
| 998 return OMX_ErrorNone; | 1015 return OMX_ErrorNone; |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1011 | 1028 |
| 1012 bool OmxVideoDecodeAccelerator::SendCommandToPort( | 1029 bool OmxVideoDecodeAccelerator::SendCommandToPort( |
| 1013 OMX_COMMANDTYPE cmd, int port_index) { | 1030 OMX_COMMANDTYPE cmd, int port_index) { |
| 1014 DCHECK_EQ(message_loop_, MessageLoop::current()); | 1031 DCHECK_EQ(message_loop_, MessageLoop::current()); |
| 1015 OMX_ERRORTYPE result = OMX_SendCommand(component_handle_, | 1032 OMX_ERRORTYPE result = OMX_SendCommand(component_handle_, |
| 1016 cmd, port_index, 0); | 1033 cmd, port_index, 0); |
| 1017 RETURN_ON_OMX_FAILURE(result, "SendCommand() failed" << cmd, | 1034 RETURN_ON_OMX_FAILURE(result, "SendCommand() failed" << cmd, |
| 1018 PLATFORM_FAILURE, false); | 1035 PLATFORM_FAILURE, false); |
| 1019 return true; | 1036 return true; |
| 1020 } | 1037 } |
| OLD | NEW |