OLD | NEW |
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 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 "media/base/media.h" | 5 #include "media/base/media.h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 | 8 |
9 #include <dlfcn.h> | 9 #include <dlfcn.h> |
10 | 10 |
11 #include "base/file_path.h" | 11 #include "base/file_path.h" |
12 #include "base/logging.h" | 12 #include "base/logging.h" |
13 #include "base/path_service.h" | 13 #include "base/path_service.h" |
14 #include "media/filters/ffmpeg_common.h" | 14 #include "media/filters/ffmpeg_common.h" |
15 | 15 |
16 // We create stub references to dynamically loaded functions in ffmpeg | 16 // We create stub references to dynamically loaded functions in FFmpeg |
17 // for ease of linking. | 17 // for ease of linking. |
18 // | 18 // |
19 // TODO(ajwong): We need to find a more maintainable way to have this work. | 19 // TODO(ajwong): We need to find a more maintainable way to have this work. |
20 // Also, this code should really be in the ffmpeg wrapper, and not here | 20 // Also, this code should really be in the FFmpeg wrapper, and not here |
21 // in the media level. The concept of "weak symbols" looks like it might | 21 // in the media level. The concept of "weak symbols" looks like it might |
22 // be promising, but I don't quite understand it yet. | 22 // be promising, but I don't quite understand it yet. |
| 23 // |
| 24 // TODO(scherkus): I am *this close* to writing the world's coolest macro to |
| 25 // make modifying this file easier. |
23 extern "C" { | 26 extern "C" { |
24 | 27 |
25 int (*av_get_bits_per_sample_format_ptr)(enum SampleFormat sample_fmt); | 28 // libavcodec functions. |
| 29 void (*av_free_packet_ptr)(AVPacket* pkt) = NULL; |
| 30 void av_free_packet(AVPacket* pkt) { |
| 31 av_free_packet_ptr(pkt); |
| 32 } |
| 33 |
| 34 int (*av_get_bits_per_sample_format_ptr)(enum SampleFormat sample_fmt) = NULL; |
26 int av_get_bits_per_sample_format(enum SampleFormat sample_fmt) { | 35 int av_get_bits_per_sample_format(enum SampleFormat sample_fmt) { |
27 return av_get_bits_per_sample_format_ptr(sample_fmt); | 36 return av_get_bits_per_sample_format_ptr(sample_fmt); |
28 } | 37 } |
29 | 38 |
30 int (*av_new_packet_ptr)(AVPacket* pkt, int size); | 39 void (*av_init_packet_ptr)(AVPacket* pkt) = NULL; |
| 40 void av_init_packet(AVPacket* pkt) { |
| 41 av_init_packet_ptr(pkt); |
| 42 } |
| 43 |
| 44 int (*av_new_packet_ptr)(AVPacket* pkt, int size) = NULL; |
31 int av_new_packet(AVPacket* pkt, int size) { | 45 int av_new_packet(AVPacket* pkt, int size) { |
32 return av_new_packet_ptr(pkt, size); | 46 return av_new_packet_ptr(pkt, size); |
33 } | 47 } |
34 | 48 |
35 void (*avcodec_init_ptr)(void) = NULL; | 49 AVFrame* (*avcodec_alloc_frame_ptr)(void) = NULL; |
36 void avcodec_init(void) { | 50 AVFrame* avcodec_alloc_frame(void) { |
37 avcodec_init_ptr(); | 51 return avcodec_alloc_frame_ptr(); |
| 52 } |
| 53 |
| 54 int (*avcodec_decode_audio3_ptr)(AVCodecContext* avctx, int16_t* samples, |
| 55 int* frame_size_ptr, AVPacket* avpkt) = NULL; |
| 56 int avcodec_decode_audio3(AVCodecContext* avctx, int16_t* samples, |
| 57 int* frame_size_ptr, AVPacket* avpkt) { |
| 58 return avcodec_decode_audio3_ptr(avctx, samples, frame_size_ptr, avpkt); |
| 59 } |
| 60 |
| 61 int (*avcodec_decode_video2_ptr)(AVCodecContext* avctx, AVFrame* picture, |
| 62 int* got_picture_ptr, AVPacket* avpkt) = NULL; |
| 63 int avcodec_decode_video2(AVCodecContext* avctx, AVFrame* picture, |
| 64 int* got_picture_ptr, AVPacket* avpkt) { |
| 65 return avcodec_decode_video2_ptr(avctx, picture, got_picture_ptr, avpkt); |
38 } | 66 } |
39 | 67 |
40 AVCodec* (*avcodec_find_decoder_ptr)(enum CodecID id) = NULL; | 68 AVCodec* (*avcodec_find_decoder_ptr)(enum CodecID id) = NULL; |
41 AVCodec* avcodec_find_decoder(enum CodecID id) { | 69 AVCodec* avcodec_find_decoder(enum CodecID id) { |
42 return avcodec_find_decoder_ptr(id); | 70 return avcodec_find_decoder_ptr(id); |
43 } | 71 } |
44 | 72 |
45 int (*avcodec_thread_init_ptr)(AVCodecContext* s, int thread_count) = NULL; | 73 void (*avcodec_init_ptr)(void) = NULL; |
46 int avcodec_thread_init(AVCodecContext* s, int thread_count) { | 74 void avcodec_init(void) { |
47 return avcodec_thread_init_ptr(s, thread_count); | 75 avcodec_init_ptr(); |
48 } | 76 } |
49 | 77 |
50 int (*avcodec_open_ptr)(AVCodecContext* avctx, AVCodec* codec) = NULL; | 78 int (*avcodec_open_ptr)(AVCodecContext* avctx, AVCodec* codec) = NULL; |
51 int avcodec_open(AVCodecContext* avctx, AVCodec* codec) { | 79 int avcodec_open(AVCodecContext* avctx, AVCodec* codec) { |
52 return avcodec_open_ptr(avctx, codec); | 80 return avcodec_open_ptr(avctx, codec); |
53 } | 81 } |
54 | 82 |
55 AVFrame* (*avcodec_alloc_frame_ptr)(void) = NULL; | 83 int (*avcodec_thread_init_ptr)(AVCodecContext* s, int thread_count) = NULL; |
56 AVFrame* avcodec_alloc_frame(void) { | 84 int avcodec_thread_init(AVCodecContext* s, int thread_count) { |
57 return avcodec_alloc_frame_ptr(); | 85 return avcodec_thread_init_ptr(s, thread_count); |
58 } | |
59 | |
60 int (*avcodec_decode_audio2_ptr)(AVCodecContext* avctx, int16_t* samples, | |
61 int* frame_size_ptr, const uint8_t* buf, | |
62 int buf_size) = NULL; | |
63 int avcodec_decode_audio2(AVCodecContext* avctx, int16_t* samples, | |
64 int* frame_size_ptr, | |
65 const uint8_t* buf, int buf_size) { | |
66 | |
67 return avcodec_decode_audio2_ptr(avctx, samples, frame_size_ptr, buf, | |
68 buf_size); | |
69 } | 86 } |
70 | 87 |
71 | 88 |
72 int (*avcodec_decode_video_ptr)(AVCodecContext* avctx, AVFrame* picture, | 89 // libavformat functions. |
73 int* got_picture_ptr, const uint8_t* buf, | 90 int (*av_find_stream_info_ptr)(AVFormatContext* ic) = NULL; |
74 int buf_size) = NULL; | 91 int av_find_stream_info(AVFormatContext* ic) { |
75 int avcodec_decode_video(AVCodecContext* avctx, AVFrame* picture, | 92 return av_find_stream_info_ptr(ic); |
76 int* got_picture_ptr, const uint8_t* buf, | |
77 int buf_size) { | |
78 return avcodec_decode_video_ptr(avctx, picture, got_picture_ptr, buf, | |
79 buf_size); | |
80 } | |
81 | |
82 | |
83 void (*av_register_all_ptr)(void); | |
84 void av_register_all(void) { | |
85 av_register_all_ptr(); | |
86 } | 93 } |
87 | 94 |
88 int (*av_open_input_file_ptr)(AVFormatContext** ic_ptr, const char* filename, | 95 int (*av_open_input_file_ptr)(AVFormatContext** ic_ptr, const char* filename, |
89 AVInputFormat* fmt, int buf_size, | 96 AVInputFormat* fmt, int buf_size, |
90 AVFormatParameters* ap) = NULL; | 97 AVFormatParameters* ap) = NULL; |
91 int av_open_input_file(AVFormatContext** ic_ptr, const char* filename, | 98 int av_open_input_file(AVFormatContext** ic_ptr, const char* filename, |
92 AVInputFormat* fmt, int buf_size, | 99 AVInputFormat* fmt, int buf_size, |
93 AVFormatParameters* ap) { | 100 AVFormatParameters* ap) { |
94 return av_open_input_file_ptr(ic_ptr, filename, fmt, buf_size, ap); | 101 return av_open_input_file_ptr(ic_ptr, filename, fmt, buf_size, ap); |
95 } | 102 } |
96 | 103 |
97 int (*av_find_stream_info_ptr)(AVFormatContext* ic) = NULL; | |
98 int av_find_stream_info(AVFormatContext* ic) { | |
99 return av_find_stream_info_ptr(ic); | |
100 } | |
101 | |
102 int (*av_read_frame_ptr)(AVFormatContext* s, AVPacket* pkt) = NULL; | 104 int (*av_read_frame_ptr)(AVFormatContext* s, AVPacket* pkt) = NULL; |
103 int av_read_frame(AVFormatContext* s, AVPacket* pkt) { | 105 int av_read_frame(AVFormatContext* s, AVPacket* pkt) { |
104 return av_read_frame_ptr(s, pkt); | 106 return av_read_frame_ptr(s, pkt); |
105 } | 107 } |
106 | 108 |
107 int (*av_seek_frame_ptr)(AVFormatContext* s, int stream_index, | 109 void (*av_register_all_ptr)(void) = NULL; |
108 int64_t timestamp, int flags) = NULL; | 110 void av_register_all(void) { |
109 int av_seek_frame(AVFormatContext* s, int stream_index, | 111 av_register_all_ptr(); |
110 int64_t timestamp, int flags) { | |
111 return av_seek_frame_ptr(s, stream_index, timestamp, flags); | |
112 } | 112 } |
113 | 113 |
114 int (*av_register_protocol_ptr)(URLProtocol* protocol) = NULL; | 114 int (*av_register_protocol_ptr)(URLProtocol* protocol) = NULL; |
115 int av_register_protocol(URLProtocol* protocol) { | 115 int av_register_protocol(URLProtocol* protocol) { |
116 return av_register_protocol_ptr(protocol); | 116 return av_register_protocol_ptr(protocol); |
117 } | 117 } |
118 | 118 |
| 119 int (*av_seek_frame_ptr)(AVFormatContext* s, int stream_index, |
| 120 int64_t timestamp, int flags) = NULL; |
| 121 int av_seek_frame(AVFormatContext* s, int stream_index, |
| 122 int64_t timestamp, int flags) { |
| 123 return av_seek_frame_ptr(s, stream_index, timestamp, flags); |
| 124 } |
| 125 |
| 126 |
| 127 // libavutil functions. |
| 128 void (*av_free_ptr)(void* ptr) = NULL; |
| 129 void av_free(void* ptr) { |
| 130 return av_free_ptr(ptr); |
| 131 } |
119 | 132 |
120 void* (*av_malloc_ptr)(unsigned int size) = NULL; | 133 void* (*av_malloc_ptr)(unsigned int size) = NULL; |
121 void* av_malloc(unsigned int size) { | 134 void* av_malloc(unsigned int size) { |
122 return av_malloc_ptr(size); | 135 return av_malloc_ptr(size); |
123 } | 136 } |
124 | 137 |
125 void (*av_free_ptr)(void* ptr) = NULL; | |
126 void av_free(void* ptr) { | |
127 return av_free_ptr(ptr); | |
128 } | |
129 | |
130 int64_t (*av_rescale_q_ptr)(int64_t a, AVRational bq, AVRational cq) = NULL; | 138 int64_t (*av_rescale_q_ptr)(int64_t a, AVRational bq, AVRational cq) = NULL; |
131 int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq) { | 139 int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq) { |
132 return av_rescale_q_ptr(a, bq, cq); | 140 return av_rescale_q_ptr(a, bq, cq); |
133 } | 141 } |
134 | 142 |
135 } // extern "C" | 143 } // extern "C" |
136 | 144 |
137 | 145 |
138 namespace media { | 146 namespace media { |
139 | 147 |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
189 for (size_t i = 0; i < arraysize(libs) && libs[i] != NULL; ++i) { | 197 for (size_t i = 0; i < arraysize(libs) && libs[i] != NULL; ++i) { |
190 dlclose(libs[i]); | 198 dlclose(libs[i]); |
191 libs[i] = NULL; // Just to be safe. | 199 libs[i] = NULL; // Just to be safe. |
192 } | 200 } |
193 return false; | 201 return false; |
194 } | 202 } |
195 | 203 |
196 // TODO(ajwong): Extract this to somewhere saner, and hopefully | 204 // TODO(ajwong): Extract this to somewhere saner, and hopefully |
197 // autogenerate the bindings from the .def files. Having all this | 205 // autogenerate the bindings from the .def files. Having all this |
198 // code here is incredibly ugly. | 206 // code here is incredibly ugly. |
| 207 |
| 208 // libavcodec functions. |
| 209 av_free_packet_ptr = |
| 210 reinterpret_cast<void (*)(AVPacket*)>( |
| 211 dlsym(libs[FILE_LIBAVCODEC], "av_free_packet")); |
199 av_get_bits_per_sample_format_ptr = | 212 av_get_bits_per_sample_format_ptr = |
200 reinterpret_cast<int (*)(enum SampleFormat)>( | 213 reinterpret_cast<int (*)(enum SampleFormat)>( |
201 dlsym(libs[FILE_LIBAVCODEC], "av_get_bits_per_sample_format")); | 214 dlsym(libs[FILE_LIBAVCODEC], "av_get_bits_per_sample_format")); |
| 215 av_init_packet_ptr = |
| 216 reinterpret_cast<void (*)(AVPacket*)>( |
| 217 dlsym(libs[FILE_LIBAVCODEC], "av_init_packet")); |
202 av_new_packet_ptr = | 218 av_new_packet_ptr = |
203 reinterpret_cast<int (*)(AVPacket*, int)>( | 219 reinterpret_cast<int (*)(AVPacket*, int)>( |
204 dlsym(libs[FILE_LIBAVCODEC], "av_new_packet")); | 220 dlsym(libs[FILE_LIBAVCODEC], "av_new_packet")); |
205 avcodec_init_ptr = | 221 avcodec_alloc_frame_ptr = |
206 reinterpret_cast<void(*)(void)>( | 222 reinterpret_cast<AVFrame* (*)(void)>( |
207 dlsym(libs[FILE_LIBAVCODEC], "avcodec_init")); | 223 dlsym(libs[FILE_LIBAVCODEC], "avcodec_alloc_frame")); |
| 224 avcodec_decode_audio3_ptr = |
| 225 reinterpret_cast<int (*)(AVCodecContext*, int16_t*, int*, AVPacket*)>( |
| 226 dlsym(libs[FILE_LIBAVCODEC], "avcodec_decode_audio3")); |
| 227 avcodec_decode_video2_ptr = |
| 228 reinterpret_cast<int (*)(AVCodecContext*, AVFrame*, int*, AVPacket*)>( |
| 229 dlsym(libs[FILE_LIBAVCODEC], "avcodec_decode_video2")); |
208 avcodec_find_decoder_ptr = | 230 avcodec_find_decoder_ptr = |
209 reinterpret_cast<AVCodec* (*)(enum CodecID)>( | 231 reinterpret_cast<AVCodec* (*)(enum CodecID)>( |
210 dlsym(libs[FILE_LIBAVCODEC], "avcodec_find_decoder")); | 232 dlsym(libs[FILE_LIBAVCODEC], "avcodec_find_decoder")); |
| 233 avcodec_init_ptr = |
| 234 reinterpret_cast<void (*)(void)>( |
| 235 dlsym(libs[FILE_LIBAVCODEC], "avcodec_init")); |
| 236 avcodec_open_ptr = |
| 237 reinterpret_cast<int (*)(AVCodecContext*, AVCodec*)>( |
| 238 dlsym(libs[FILE_LIBAVCODEC], "avcodec_open")); |
211 avcodec_thread_init_ptr = | 239 avcodec_thread_init_ptr = |
212 reinterpret_cast<int (*)(AVCodecContext*, int)>( | 240 reinterpret_cast<int (*)(AVCodecContext*, int)>( |
213 dlsym(libs[FILE_LIBAVCODEC], "avcodec_thread_init")); | 241 dlsym(libs[FILE_LIBAVCODEC], "avcodec_thread_init")); |
214 avcodec_open_ptr = | |
215 reinterpret_cast<int (*)(AVCodecContext*, AVCodec*)>( | |
216 dlsym(libs[FILE_LIBAVCODEC], "avcodec_open")); | |
217 avcodec_alloc_frame_ptr = | |
218 reinterpret_cast<AVFrame* (*)(void)>( | |
219 dlsym(libs[FILE_LIBAVCODEC], "avcodec_alloc_frame")); | |
220 avcodec_decode_audio2_ptr = | |
221 reinterpret_cast<int (*)(AVCodecContext*, int16_t*, int*, | |
222 const uint8_t*, int)>( | |
223 dlsym(libs[FILE_LIBAVCODEC], "avcodec_decode_audio2")); | |
224 avcodec_decode_video_ptr = | |
225 reinterpret_cast<int (*)(AVCodecContext*, AVFrame*, int*, | |
226 const uint8_t*, int)>( | |
227 dlsym(libs[FILE_LIBAVCODEC], "avcodec_decode_video")); | |
228 | 242 |
229 av_register_all_ptr = | 243 // libavformat functions. |
230 reinterpret_cast<void(*)(void)>( | 244 av_find_stream_info_ptr = |
231 dlsym(libs[FILE_LIBAVFORMAT], "av_register_all")); | 245 reinterpret_cast<int (*)(AVFormatContext*)>( |
| 246 dlsym(libs[FILE_LIBAVFORMAT], "av_find_stream_info")); |
232 av_open_input_file_ptr = | 247 av_open_input_file_ptr = |
233 reinterpret_cast<int (*)(AVFormatContext**, const char*, | 248 reinterpret_cast<int (*)(AVFormatContext**, const char*, |
234 AVInputFormat*, int, | 249 AVInputFormat*, int, |
235 AVFormatParameters*)>( | 250 AVFormatParameters*)>( |
236 dlsym(libs[FILE_LIBAVFORMAT], "av_open_input_file")); | 251 dlsym(libs[FILE_LIBAVFORMAT], "av_open_input_file")); |
237 av_find_stream_info_ptr = | |
238 reinterpret_cast<int (*)(AVFormatContext*)>( | |
239 dlsym(libs[FILE_LIBAVFORMAT], "av_find_stream_info")); | |
240 av_read_frame_ptr = | 252 av_read_frame_ptr = |
241 reinterpret_cast<int (*)(AVFormatContext*, AVPacket*)>( | 253 reinterpret_cast<int (*)(AVFormatContext*, AVPacket*)>( |
242 dlsym(libs[FILE_LIBAVFORMAT], "av_read_frame")); | 254 dlsym(libs[FILE_LIBAVFORMAT], "av_read_frame")); |
| 255 av_register_all_ptr = |
| 256 reinterpret_cast<void (*)(void)>( |
| 257 dlsym(libs[FILE_LIBAVFORMAT], "av_register_all")); |
| 258 av_register_protocol_ptr = |
| 259 reinterpret_cast<int (*)(URLProtocol*)>( |
| 260 dlsym(libs[FILE_LIBAVFORMAT], "av_register_protocol")); |
243 av_seek_frame_ptr = | 261 av_seek_frame_ptr = |
244 reinterpret_cast<int (*)(AVFormatContext*, int, int64_t, int)>( | 262 reinterpret_cast<int (*)(AVFormatContext*, int, int64_t, int)>( |
245 dlsym(libs[FILE_LIBAVFORMAT], "av_seek_frame")); | 263 dlsym(libs[FILE_LIBAVFORMAT], "av_seek_frame")); |
246 av_register_protocol_ptr = | |
247 reinterpret_cast<int (*)(URLProtocol*)>( | |
248 dlsym(libs[FILE_LIBAVFORMAT], "av_register_protocol")); | |
249 | 264 |
| 265 // libavutil functions. |
| 266 av_free_ptr = |
| 267 reinterpret_cast<void (*)(void*)>( |
| 268 dlsym(libs[FILE_LIBAVUTIL], "av_free")); |
250 av_malloc_ptr = | 269 av_malloc_ptr = |
251 reinterpret_cast<void* (*)(unsigned int)>( | 270 reinterpret_cast<void* (*)(unsigned int)>( |
252 dlsym(libs[FILE_LIBAVUTIL], "av_malloc")); | 271 dlsym(libs[FILE_LIBAVUTIL], "av_malloc")); |
253 av_free_ptr = | |
254 reinterpret_cast<void (*)(void*)>( | |
255 dlsym(libs[FILE_LIBAVUTIL], "av_free")); | |
256 av_rescale_q_ptr = | 272 av_rescale_q_ptr = |
257 reinterpret_cast<int64_t (*)(int64_t, AVRational, AVRational)>( | 273 reinterpret_cast<int64_t (*)(int64_t, AVRational, AVRational)>( |
258 dlsym(libs[FILE_LIBAVUTIL], "av_rescale_q")); | 274 dlsym(libs[FILE_LIBAVUTIL], "av_rescale_q")); |
259 | 275 |
260 // Check that all the symbols were loaded correctly before returning true. | 276 // Check that all the symbols were loaded correctly before returning true. |
261 if (av_get_bits_per_sample_format_ptr && | 277 if (av_free_packet_ptr && |
| 278 av_get_bits_per_sample_format_ptr && |
| 279 av_init_packet_ptr && |
262 av_new_packet_ptr && | 280 av_new_packet_ptr && |
| 281 avcodec_alloc_frame_ptr && |
| 282 avcodec_decode_audio3_ptr && |
| 283 avcodec_decode_video2_ptr && |
| 284 avcodec_find_decoder_ptr && |
263 avcodec_init_ptr && | 285 avcodec_init_ptr && |
264 avcodec_find_decoder_ptr && | 286 avcodec_open_ptr && |
265 avcodec_thread_init_ptr && | 287 avcodec_thread_init_ptr && |
266 avcodec_open_ptr && | |
267 avcodec_alloc_frame_ptr && | |
268 avcodec_decode_audio2_ptr && | |
269 avcodec_decode_video_ptr && | |
270 | 288 |
| 289 av_find_stream_info_ptr && |
| 290 av_open_input_file_ptr && |
| 291 av_read_frame_ptr && |
271 av_register_all_ptr && | 292 av_register_all_ptr && |
272 av_open_input_file_ptr && | 293 av_register_protocol_ptr && |
273 av_find_stream_info_ptr && | |
274 av_read_frame_ptr && | |
275 av_seek_frame_ptr && | 294 av_seek_frame_ptr && |
276 av_register_protocol_ptr && | |
277 | 295 |
| 296 av_free_ptr && |
278 av_malloc_ptr && | 297 av_malloc_ptr && |
279 av_free_ptr && | |
280 av_rescale_q_ptr) { | 298 av_rescale_q_ptr) { |
281 return true; | 299 return true; |
282 } | 300 } |
283 | 301 |
284 return false; | 302 return false; |
285 } | 303 } |
286 | 304 |
287 } // namespace media | 305 } // namespace media |
OLD | NEW |