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