OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/bind.h" | 7 #include "base/bind.h" |
8 #include "base/debug/trace_event.h" | 8 #include "base/debug/trace_event.h" |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "base/stl_util.h" | 10 #include "base/stl_util.h" |
11 #include "base/string_util.h" | 11 #include "base/string_util.h" |
12 #include "content/common/gpu/gpu_channel.h" | 12 #include "content/common/gpu/gpu_channel.h" |
13 #include "content/common/gpu/media/gles2_texture_to_egl_image_translator.h" | 13 #include "content/common/gpu/media/gles2_texture_to_egl_image_translator.h" |
14 #include "media/base/bitstream_buffer.h" | 14 #include "media/base/bitstream_buffer.h" |
15 #include "media/video/picture.h" | 15 #include "media/video/picture.h" |
16 | 16 |
17 // Helper typedef for input buffers. This is used as the pAppPrivate field of | 17 // Helper typedef for input buffers. This is used as the pAppPrivate field of |
18 // OMX_BUFFERHEADERTYPEs of input buffers, to point to the data associated with | 18 // OMX_BUFFERHEADERTYPEs of input buffers, to point to the data associated with |
19 // them. | 19 // them. |
20 typedef std::pair<scoped_ptr<base::SharedMemory>, int32> SharedMemoryAndId; | 20 typedef std::pair<scoped_ptr<base::SharedMemory>, int32> SharedMemoryAndId; |
21 | 21 |
22 enum { kNumPictureBuffers = 4 }; | 22 enum { kNumPictureBuffers = 4 }; |
23 | 23 |
24 void* omx_handle = NULL; | 24 // Open the libOmxCore here for now. |
| 25 void* omx_handle = dlopen("libOmxCore.so", RTLD_NOW); |
25 | 26 |
26 typedef OMX_ERRORTYPE (*OMXInit)(); | 27 typedef OMX_ERRORTYPE (*OMXInit)(); |
27 typedef OMX_ERRORTYPE (*OMXGetHandle)( | 28 typedef OMX_ERRORTYPE (*OMXGetHandle)( |
28 OMX_HANDLETYPE*, OMX_STRING, OMX_PTR, OMX_CALLBACKTYPE*); | 29 OMX_HANDLETYPE*, OMX_STRING, OMX_PTR, OMX_CALLBACKTYPE*); |
29 typedef OMX_ERRORTYPE (*OMXGetComponentsOfRole)(OMX_STRING, OMX_U32*, OMX_U8**); | 30 typedef OMX_ERRORTYPE (*OMXGetComponentsOfRole)(OMX_STRING, OMX_U32*, OMX_U8**); |
30 typedef OMX_ERRORTYPE (*OMXFreeHandle)(OMX_HANDLETYPE); | 31 typedef OMX_ERRORTYPE (*OMXFreeHandle)(OMX_HANDLETYPE); |
31 typedef OMX_ERRORTYPE (*OMXDeinit)(); | 32 typedef OMX_ERRORTYPE (*OMXDeinit)(); |
32 | 33 |
33 OMXInit omx_init = NULL; | 34 OMXInit omx_init = reinterpret_cast<OMXInit>(dlsym(omx_handle, "OMX_Init")); |
34 OMXGetHandle omx_gethandle = NULL; | 35 OMXGetHandle omx_gethandle = |
35 OMXGetComponentsOfRole omx_get_components_of_role = NULL; | 36 reinterpret_cast<OMXGetHandle>(dlsym(omx_handle, "OMX_GetHandle")); |
36 OMXFreeHandle omx_free_handle = NULL; | 37 OMXGetComponentsOfRole omx_get_components_of_role = |
37 OMXDeinit omx_deinit = NULL; | 38 reinterpret_cast<OMXGetComponentsOfRole>( |
| 39 dlsym(omx_handle, "OMX_GetComponentsOfRole")); |
| 40 OMXFreeHandle omx_free_handle = |
| 41 reinterpret_cast<OMXFreeHandle>(dlsym(omx_handle, "OMX_FreeHandle")); |
| 42 OMXDeinit omx_deinit = |
| 43 reinterpret_cast<OMXDeinit>(dlsym(omx_handle, "OMX_Deinit")); |
| 44 |
| 45 static bool AreOMXFunctionPointersInitialized() { |
| 46 return (omx_init && omx_gethandle && omx_get_components_of_role && |
| 47 omx_free_handle && omx_deinit); |
| 48 } |
38 | 49 |
39 // Maps h264-related Profile enum values to OMX_VIDEO_AVCPROFILETYPE values. | 50 // Maps h264-related Profile enum values to OMX_VIDEO_AVCPROFILETYPE values. |
40 static OMX_U32 MapH264ProfileToOMXAVCProfile(uint32 profile) { | 51 static OMX_U32 MapH264ProfileToOMXAVCProfile(uint32 profile) { |
41 switch (profile) { | 52 switch (profile) { |
42 case media::H264PROFILE_BASELINE: | 53 case media::H264PROFILE_BASELINE: |
43 return OMX_VIDEO_AVCProfileBaseline; | 54 return OMX_VIDEO_AVCProfileBaseline; |
44 case media::H264PROFILE_MAIN: | 55 case media::H264PROFILE_MAIN: |
45 return OMX_VIDEO_AVCProfileMain; | 56 return OMX_VIDEO_AVCProfileMain; |
46 case media::H264PROFILE_EXTENDED: | 57 case media::H264PROFILE_EXTENDED: |
47 return OMX_VIDEO_AVCProfileExtended; | 58 return OMX_VIDEO_AVCProfileExtended; |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
79 } \ | 90 } \ |
80 } while (0) | 91 } while (0) |
81 | 92 |
82 // OMX-specific version of RETURN_ON_FAILURE which compares with OMX_ErrorNone. | 93 // OMX-specific version of RETURN_ON_FAILURE which compares with OMX_ErrorNone. |
83 #define RETURN_ON_OMX_FAILURE(omx_result, log, error, ret_val) \ | 94 #define RETURN_ON_OMX_FAILURE(omx_result, log, error, ret_val) \ |
84 RETURN_ON_FAILURE( \ | 95 RETURN_ON_FAILURE( \ |
85 ((omx_result) == OMX_ErrorNone), \ | 96 ((omx_result) == OMX_ErrorNone), \ |
86 log << ", OMX result: 0x" << std::hex << omx_result, \ | 97 log << ", OMX result: 0x" << std::hex << omx_result, \ |
87 error, ret_val) | 98 error, ret_val) |
88 | 99 |
89 // static | |
90 bool OmxVideoDecodeAccelerator::pre_sandbox_init_done_ = false; | |
91 | |
92 OmxVideoDecodeAccelerator::OmxVideoDecodeAccelerator( | 100 OmxVideoDecodeAccelerator::OmxVideoDecodeAccelerator( |
93 EGLDisplay egl_display, EGLContext egl_context, | 101 EGLDisplay egl_display, EGLContext egl_context, |
94 media::VideoDecodeAccelerator::Client* client) | 102 media::VideoDecodeAccelerator::Client* client) |
95 : message_loop_(MessageLoop::current()), | 103 : message_loop_(MessageLoop::current()), |
96 component_handle_(NULL), | 104 component_handle_(NULL), |
97 weak_this_(base::AsWeakPtr(this)), | 105 weak_this_(base::AsWeakPtr(this)), |
98 init_begun_(false), | 106 init_begun_(false), |
99 client_state_(OMX_StateMax), | 107 client_state_(OMX_StateMax), |
100 current_state_change_(NO_TRANSITION), | 108 current_state_change_(NO_TRANSITION), |
101 input_buffer_count_(0), | 109 input_buffer_count_(0), |
102 input_buffer_size_(0), | 110 input_buffer_size_(0), |
103 input_port_(0), | 111 input_port_(0), |
104 input_buffers_at_component_(0), | 112 input_buffers_at_component_(0), |
105 output_port_(0), | 113 output_port_(0), |
106 output_buffers_at_component_(0), | 114 output_buffers_at_component_(0), |
107 egl_display_(egl_display), | 115 egl_display_(egl_display), |
108 egl_context_(egl_context), | 116 egl_context_(egl_context), |
109 client_(client), | 117 client_(client), |
110 codec_(UNKNOWN), | 118 codec_(UNKNOWN), |
111 h264_profile_(OMX_VIDEO_AVCProfileMax), | 119 h264_profile_(OMX_VIDEO_AVCProfileMax), |
112 component_name_is_nvidia_h264ext_(false) { | 120 component_name_is_nvidia_h264ext_(false) { |
113 static bool omx_functions_initialized = PostSandboxInitialization(); | 121 RETURN_ON_FAILURE(AreOMXFunctionPointersInitialized(), |
114 RETURN_ON_FAILURE(omx_functions_initialized, | |
115 "Failed to load openmax library", PLATFORM_FAILURE,); | 122 "Failed to load openmax library", PLATFORM_FAILURE,); |
116 RETURN_ON_OMX_FAILURE(omx_init(), "Failed to init OpenMAX core", | 123 RETURN_ON_OMX_FAILURE(omx_init(), "Failed to init OpenMAX core", |
117 PLATFORM_FAILURE,); | 124 PLATFORM_FAILURE,); |
118 } | 125 } |
119 | 126 |
120 OmxVideoDecodeAccelerator::~OmxVideoDecodeAccelerator() { | 127 OmxVideoDecodeAccelerator::~OmxVideoDecodeAccelerator() { |
121 DCHECK_EQ(message_loop_, MessageLoop::current()); | 128 DCHECK_EQ(message_loop_, MessageLoop::current()); |
122 DCHECK(free_input_buffers_.empty()); | 129 DCHECK(free_input_buffers_.empty()); |
123 DCHECK_EQ(0, input_buffers_at_component_); | 130 DCHECK_EQ(0, input_buffers_at_component_); |
124 DCHECK_EQ(0, output_buffers_at_component_); | 131 DCHECK_EQ(0, output_buffers_at_component_); |
(...skipping 855 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
980 PLATFORM_FAILURE,); | 987 PLATFORM_FAILURE,); |
981 } | 988 } |
982 return; | 989 return; |
983 default: | 990 default: |
984 RETURN_ON_FAILURE(false, "Unexpected unhandled event: " << event, | 991 RETURN_ON_FAILURE(false, "Unexpected unhandled event: " << event, |
985 PLATFORM_FAILURE,); | 992 PLATFORM_FAILURE,); |
986 } | 993 } |
987 } | 994 } |
988 | 995 |
989 // static | 996 // static |
990 void OmxVideoDecodeAccelerator::PreSandboxInitialization() { | |
991 DCHECK(!pre_sandbox_init_done_); | |
992 omx_handle = dlopen("libOmxCore.so", RTLD_NOW); | |
993 pre_sandbox_init_done_ = omx_handle != NULL; | |
994 } | |
995 | |
996 // static | |
997 bool OmxVideoDecodeAccelerator::PostSandboxInitialization() { | |
998 if (!pre_sandbox_init_done_) | |
999 return false; | |
1000 | |
1001 omx_init = reinterpret_cast<OMXInit>(dlsym(omx_handle, "OMX_Init")); | |
1002 omx_gethandle = | |
1003 reinterpret_cast<OMXGetHandle>(dlsym(omx_handle, "OMX_GetHandle")); | |
1004 omx_get_components_of_role = | |
1005 reinterpret_cast<OMXGetComponentsOfRole>( | |
1006 dlsym(omx_handle, "OMX_GetComponentsOfRole")); | |
1007 omx_free_handle = | |
1008 reinterpret_cast<OMXFreeHandle>(dlsym(omx_handle, "OMX_FreeHandle")); | |
1009 omx_deinit = | |
1010 reinterpret_cast<OMXDeinit>(dlsym(omx_handle, "OMX_Deinit")); | |
1011 return (omx_init && omx_gethandle && omx_get_components_of_role && | |
1012 omx_free_handle && omx_deinit); | |
1013 } | |
1014 | |
1015 // static | |
1016 OMX_ERRORTYPE OmxVideoDecodeAccelerator::EventHandler(OMX_HANDLETYPE component, | 997 OMX_ERRORTYPE OmxVideoDecodeAccelerator::EventHandler(OMX_HANDLETYPE component, |
1017 OMX_PTR priv_data, | 998 OMX_PTR priv_data, |
1018 OMX_EVENTTYPE event, | 999 OMX_EVENTTYPE event, |
1019 OMX_U32 data1, | 1000 OMX_U32 data1, |
1020 OMX_U32 data2, | 1001 OMX_U32 data2, |
1021 OMX_PTR event_data) { | 1002 OMX_PTR event_data) { |
1022 // Called on the OMX thread. | 1003 // Called on the OMX thread. |
1023 OmxVideoDecodeAccelerator* decoder = | 1004 OmxVideoDecodeAccelerator* decoder = |
1024 static_cast<OmxVideoDecodeAccelerator*>(priv_data); | 1005 static_cast<OmxVideoDecodeAccelerator*>(priv_data); |
1025 DCHECK_EQ(component, decoder->component_handle_); | 1006 DCHECK_EQ(component, decoder->component_handle_); |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1077 | 1058 |
1078 bool OmxVideoDecodeAccelerator::SendCommandToPort( | 1059 bool OmxVideoDecodeAccelerator::SendCommandToPort( |
1079 OMX_COMMANDTYPE cmd, int port_index) { | 1060 OMX_COMMANDTYPE cmd, int port_index) { |
1080 DCHECK_EQ(message_loop_, MessageLoop::current()); | 1061 DCHECK_EQ(message_loop_, MessageLoop::current()); |
1081 OMX_ERRORTYPE result = OMX_SendCommand(component_handle_, | 1062 OMX_ERRORTYPE result = OMX_SendCommand(component_handle_, |
1082 cmd, port_index, 0); | 1063 cmd, port_index, 0); |
1083 RETURN_ON_OMX_FAILURE(result, "SendCommand() failed" << cmd, | 1064 RETURN_ON_OMX_FAILURE(result, "SendCommand() failed" << cmd, |
1084 PLATFORM_FAILURE, false); | 1065 PLATFORM_FAILURE, false); |
1085 return true; | 1066 return true; |
1086 } | 1067 } |
OLD | NEW |