3 * Copyright (C) 2005-2013 Team XBMC
6 * This Program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2, or (at your option)
11 * This Program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with XBMC; see the file COPYING. If not, see
18 * <http://www.gnu.org/licenses/>.
22 #if (defined HAVE_CONFIG_H) && (!defined WIN32)
25 #include "DynamicDll.h"
26 #include "DllAvCodec.h"
32 #ifndef __STDC_CONSTANT_MACROS
33 #define __STDC_CONSTANT_MACROS
36 #pragma warning(disable:4244)
38 #if (defined USE_EXTERNAL_FFMPEG)
39 #include <libavformat/avformat.h>
40 /* xbmc_read_frame_flush() is defined for us in lib/xbmc-dll-symbols/DllAvFormat.c */
41 void xbmc_read_frame_flush(AVFormatContext *s);
43 #include "libavformat/avformat.h"
44 #if defined(TARGET_DARWIN)
45 void ff_read_frame_flush(AVFormatContext *s); // internal replacement
46 #define xbmc_read_frame_flush ff_read_frame_flush
51 /* Flag introduced without a version bump */
53 #define AVSEEK_FORCE 0x20000
56 #if LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT(55,12,100)
57 #define AVFORMAT_HAS_STREAM_GET_R_FRAME_RATE
60 typedef int64_t offset_t;
62 class DllAvFormatInterface
65 virtual ~DllAvFormatInterface() {}
66 virtual void av_register_all_dont_call(void)=0;
67 virtual void avformat_network_init_dont_call(void)=0;
68 virtual void avformat_network_deinit_dont_call(void)=0;
69 virtual AVInputFormat *av_find_input_format(const char *short_name)=0;
70 virtual void avformat_close_input(AVFormatContext **s)=0;
71 virtual int av_read_frame(AVFormatContext *s, AVPacket *pkt)=0;
72 virtual void av_read_frame_flush(AVFormatContext *s)=0;
73 virtual int av_read_play(AVFormatContext *s)=0;
74 virtual int av_read_pause(AVFormatContext *s)=0;
75 virtual int av_seek_frame(AVFormatContext *s, int stream_index, int64_t timestamp, int flags)=0;
76 #if (!defined USE_EXTERNAL_FFMPEG) && (!defined TARGET_DARWIN)
77 virtual int avformat_find_stream_info_dont_call(AVFormatContext *ic, AVDictionary **options)=0;
79 virtual int avformat_open_input(AVFormatContext **ps, const char *filename, AVInputFormat *fmt, AVDictionary **options)=0;
80 virtual AVIOContext *avio_alloc_context(unsigned char *buffer, int buffer_size, int write_flag, void *opaque,
81 int (*read_packet)(void *opaque, uint8_t *buf, int buf_size),
82 int (*write_packet)(void *opaque, uint8_t *buf, int buf_size),
83 offset_t (*seek)(void *opaque, offset_t offset, int whence))=0;
84 virtual AVInputFormat *av_probe_input_format(AVProbeData *pd, int is_opened)=0;
85 virtual AVInputFormat *av_probe_input_format2(AVProbeData *pd, int is_opened, int *score_max)=0;
86 virtual int av_probe_input_buffer(AVIOContext *pb, AVInputFormat **fmt, const char *filename, void *logctx, unsigned int offset, unsigned int max_probe_size)=0;
87 virtual void av_dump_format(AVFormatContext *ic, int index, const char *url, int is_output)=0;
88 virtual int avio_open(AVIOContext **s, const char *filename, int flags)=0;
89 virtual int avio_close(AVIOContext *s)=0;
90 virtual int avio_open_dyn_buf(AVIOContext **s)=0;
91 virtual int avio_close_dyn_buf(AVIOContext *s, uint8_t **pbuffer)=0;
92 virtual offset_t avio_seek(AVIOContext *s, offset_t offset, int whence)=0;
93 virtual int avio_read(AVIOContext *s, unsigned char *buf, int size)=0;
94 virtual void avio_w8(AVIOContext *s, int b)=0;
95 virtual void avio_write(AVIOContext *s, const unsigned char *buf, int size)=0;
96 virtual void avio_wb24(AVIOContext *s, unsigned int val)=0;
97 virtual void avio_wb32(AVIOContext *s, unsigned int val)=0;
98 virtual void avio_wb16(AVIOContext *s, unsigned int val)=0;
99 virtual AVFormatContext *avformat_alloc_context(void)=0;
100 virtual int avformat_alloc_output_context2(AVFormatContext **ctx, AVOutputFormat *oformat, const char *format_name, const char *filename) = 0;
101 virtual AVStream *avformat_new_stream(AVFormatContext *s, AVCodec *c)=0;
102 virtual AVOutputFormat *av_guess_format(const char *short_name, const char *filename, const char *mime_type)=0;
103 virtual int avformat_write_header (AVFormatContext *s, AVDictionary **options)=0;
104 virtual int av_write_trailer(AVFormatContext *s)=0;
105 virtual int av_write_frame (AVFormatContext *s, AVPacket *pkt)=0;
106 #if defined(AVFORMAT_HAS_STREAM_GET_R_FRAME_RATE)
107 virtual AVRational av_stream_get_r_frame_rate(const AVStream *s)=0;
111 #if (defined USE_EXTERNAL_FFMPEG) || (defined TARGET_DARWIN)
113 // Use direct mapping
114 class DllAvFormat : public DllDynamic, DllAvFormatInterface
117 virtual ~DllAvFormat() {}
118 virtual void av_register_all()
120 CSingleLock lock(DllAvCodec::m_critSection);
121 return ::av_register_all();
123 virtual void av_register_all_dont_call() { *(volatile int* )0x0 = 0; }
124 virtual void avformat_network_init_dont_call() { *(volatile int* )0x0 = 0; }
125 virtual void avformat_network_deinit_dont_call() { *(volatile int* )0x0 = 0; }
126 virtual AVInputFormat *av_find_input_format(const char *short_name) { return ::av_find_input_format(short_name); }
127 virtual void avformat_close_input(AVFormatContext **s) { ::avformat_close_input(s); }
128 virtual int av_read_frame(AVFormatContext *s, AVPacket *pkt) { return ::av_read_frame(s, pkt); }
129 virtual void av_read_frame_flush(AVFormatContext *s) { ::xbmc_read_frame_flush(s); }
130 virtual int av_read_play(AVFormatContext *s) { return ::av_read_play(s); }
131 virtual int av_read_pause(AVFormatContext *s) { return ::av_read_pause(s); }
132 virtual int av_seek_frame(AVFormatContext *s, int stream_index, int64_t timestamp, int flags) { return ::av_seek_frame(s, stream_index, timestamp, flags); }
133 virtual int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options)
135 CSingleLock lock(DllAvCodec::m_critSection);
136 return ::avformat_find_stream_info(ic, options);
138 virtual int avformat_open_input(AVFormatContext **ps, const char *filename, AVInputFormat *fmt, AVDictionary **options)
139 { return ::avformat_open_input(ps, filename, fmt, options); }
140 virtual AVIOContext *avio_alloc_context(unsigned char *buffer, int buffer_size, int write_flag, void *opaque,
141 int (*read_packet)(void *opaque, uint8_t *buf, int buf_size),
142 int (*write_packet)(void *opaque, uint8_t *buf, int buf_size),
143 offset_t (*seek)(void *opaque, offset_t offset, int whence)) { return ::avio_alloc_context(buffer, buffer_size, write_flag, opaque, read_packet, write_packet, seek); }
144 virtual AVInputFormat *av_probe_input_format(AVProbeData *pd, int is_opened) {return ::av_probe_input_format(pd, is_opened); }
145 virtual AVInputFormat *av_probe_input_format2(AVProbeData *pd, int is_opened, int *score_max) {*score_max = 100; return ::av_probe_input_format(pd, is_opened); } // Use av_probe_input_format, this is not exported by ffmpeg's headers
146 virtual int av_probe_input_buffer(AVIOContext *pb, AVInputFormat **fmt, const char *filename, void *logctx, unsigned int offset, unsigned int max_probe_size) { return ::av_probe_input_buffer(pb, fmt, filename, logctx, offset, max_probe_size); }
147 virtual void av_dump_format(AVFormatContext *ic, int index, const char *url, int is_output) { ::av_dump_format(ic, index, url, is_output); }
148 virtual int avio_open(AVIOContext **s, const char *filename, int flags) { return ::avio_open(s, filename, flags); }
149 virtual int avio_close(AVIOContext *s) { return ::avio_close(s); }
150 virtual int avio_open_dyn_buf(AVIOContext **s) { return ::avio_open_dyn_buf(s); }
151 virtual int avio_close_dyn_buf(AVIOContext *s, uint8_t **pbuffer) { return ::avio_close_dyn_buf(s, pbuffer); }
152 virtual offset_t avio_seek(AVIOContext *s, offset_t offset, int whence) { return ::avio_seek(s, offset, whence); }
153 virtual int avio_read(AVIOContext *s, unsigned char *buf, int size) { return ::avio_read(s, buf, size); }
154 virtual void avio_w8(AVIOContext *s, int b) { ::avio_w8(s, b); }
155 virtual void avio_write(AVIOContext *s, const unsigned char *buf, int size) { ::avio_write(s, buf, size); }
156 virtual void avio_wb24(AVIOContext *s, unsigned int val) { ::avio_wb24(s, val); }
157 virtual void avio_wb32(AVIOContext *s, unsigned int val) { ::avio_wb32(s, val); }
158 virtual void avio_wb16(AVIOContext *s, unsigned int val) { ::avio_wb16(s, val); }
159 virtual AVFormatContext *avformat_alloc_context() { return ::avformat_alloc_context(); }
160 virtual int avformat_alloc_output_context2(AVFormatContext **ctx, AVOutputFormat *oformat, const char *format_name, const char *filename){ return ::avformat_alloc_output_context2(ctx,oformat,format_name,filename); }
161 virtual AVStream *avformat_new_stream(AVFormatContext *s, AVCodec *c) { return ::avformat_new_stream(s, c); }
162 virtual AVOutputFormat *av_guess_format(const char *short_name, const char *filename, const char *mime_type) { return ::av_guess_format(short_name, filename, mime_type); }
163 virtual int avformat_write_header (AVFormatContext *s, AVDictionary **options) { return ::avformat_write_header (s, options); }
164 virtual int av_write_trailer(AVFormatContext *s) { return ::av_write_trailer(s); }
165 virtual int av_write_frame (AVFormatContext *s, AVPacket *pkt) { return ::av_write_frame(s, pkt); }
166 #if defined(AVFORMAT_HAS_STREAM_GET_R_FRAME_RATE)
167 virtual AVRational av_stream_get_r_frame_rate(const AVStream *s) { return ::av_stream_get_r_frame_rate(s); }
171 virtual bool ResolveExports() { return true; }
172 virtual bool Load() {
173 #if !defined(TARGET_DARWIN)
174 CLog::Log(LOGDEBUG, "DllAvFormat: Using libavformat system library");
176 CSingleLock lock(DllAvCodec::m_critSection);
177 if (++m_avformat_refcnt == 1)
178 ::avformat_network_init();
181 virtual void Unload() {
182 CSingleLock lock(DllAvCodec::m_critSection);
183 if (--m_avformat_refcnt == 0)
184 ::avformat_network_deinit();
188 static int m_avformat_refcnt;
193 class DllAvFormat : public DllDynamic, DllAvFormatInterface
195 DECLARE_DLL_WRAPPER(DllAvFormat, DLL_PATH_LIBAVFORMAT)
199 DEFINE_METHOD0(void, av_register_all_dont_call)
200 DEFINE_METHOD0(void, avformat_network_init_dont_call)
201 DEFINE_METHOD0(void, avformat_network_deinit_dont_call)
202 DEFINE_METHOD1(AVInputFormat*, av_find_input_format, (const char *p1))
203 DEFINE_METHOD1(void, avformat_close_input, (AVFormatContext **p1))
204 DEFINE_METHOD1(int, av_read_play, (AVFormatContext *p1))
205 DEFINE_METHOD1(int, av_read_pause, (AVFormatContext *p1))
206 DEFINE_METHOD1(void, av_read_frame_flush, (AVFormatContext *p1))
207 DEFINE_FUNC_ALIGNED2(int, __cdecl, av_read_frame, AVFormatContext *, AVPacket *)
208 DEFINE_FUNC_ALIGNED4(int, __cdecl, av_seek_frame, AVFormatContext*, int, int64_t, int)
209 DEFINE_FUNC_ALIGNED2(int, __cdecl, avformat_find_stream_info_dont_call, AVFormatContext*, AVDictionary **)
210 DEFINE_FUNC_ALIGNED4(int, __cdecl, avformat_open_input, AVFormatContext **, const char *, AVInputFormat *, AVDictionary **)
211 DEFINE_FUNC_ALIGNED2(AVInputFormat*, __cdecl, av_probe_input_format, AVProbeData*, int)
212 DEFINE_FUNC_ALIGNED3(AVInputFormat*, __cdecl, av_probe_input_format2, AVProbeData*, int, int*)
213 DEFINE_FUNC_ALIGNED6(int, __cdecl, av_probe_input_buffer, AVIOContext *, AVInputFormat **, const char *, void *, unsigned int, unsigned int)
214 DEFINE_FUNC_ALIGNED3(int, __cdecl, avio_read, AVIOContext*, unsigned char *, int)
215 DEFINE_FUNC_ALIGNED2(void, __cdecl, avio_w8, AVIOContext*, int)
216 DEFINE_FUNC_ALIGNED3(void, __cdecl, avio_write, AVIOContext*, const unsigned char *, int)
217 DEFINE_FUNC_ALIGNED2(void, __cdecl, avio_wb24, AVIOContext*, unsigned int)
218 DEFINE_FUNC_ALIGNED2(void, __cdecl, avio_wb32, AVIOContext*, unsigned int)
219 DEFINE_FUNC_ALIGNED2(void, __cdecl, avio_wb16, AVIOContext*, unsigned int)
220 DEFINE_METHOD7(AVIOContext *, avio_alloc_context, (unsigned char *p1, int p2, int p3, void *p4,
221 int (*p5)(void *opaque, uint8_t *buf, int buf_size),
222 int (*p6)(void *opaque, uint8_t *buf, int buf_size),
223 offset_t (*p7)(void *opaque, offset_t offset, int whence)))
224 DEFINE_METHOD4(void, av_dump_format, (AVFormatContext *p1, int p2, const char *p3, int p4))
225 DEFINE_METHOD3(int, avio_open, (AVIOContext **p1, const char *p2, int p3))
226 DEFINE_METHOD1(int, avio_close, (AVIOContext *p1))
227 DEFINE_METHOD1(int, avio_open_dyn_buf, (AVIOContext **p1))
228 DEFINE_METHOD2(int, avio_close_dyn_buf, (AVIOContext *p1, uint8_t **p2))
229 DEFINE_METHOD3(offset_t, avio_seek, (AVIOContext *p1, offset_t p2, int p3))
230 DEFINE_METHOD0(AVFormatContext *, avformat_alloc_context)
231 DEFINE_METHOD4(int, avformat_alloc_output_context2, (AVFormatContext **p1, AVOutputFormat *p2, const char *p3, const char *p4))
232 DEFINE_METHOD2(AVStream *, avformat_new_stream, (AVFormatContext *p1, AVCodec *p2))
233 DEFINE_METHOD3(AVOutputFormat *, av_guess_format, (const char *p1, const char *p2, const char *p3))
234 DEFINE_METHOD2(int, avformat_write_header , (AVFormatContext *p1, AVDictionary **p2))
235 DEFINE_METHOD1(int, av_write_trailer, (AVFormatContext *p1))
236 DEFINE_METHOD2(int, av_write_frame , (AVFormatContext *p1, AVPacket *p2))
237 #if defined(AVFORMAT_HAS_STREAM_GET_R_FRAME_RATE)
238 DEFINE_METHOD1(AVRational, av_stream_get_r_frame_rate, (const AVStream *p1))
240 BEGIN_METHOD_RESOLVE()
241 RESOLVE_METHOD_RENAME(av_register_all, av_register_all_dont_call)
242 RESOLVE_METHOD_RENAME(avformat_network_init, avformat_network_init_dont_call)
243 RESOLVE_METHOD_RENAME(avformat_network_deinit, avformat_network_deinit_dont_call)
244 RESOLVE_METHOD(av_find_input_format)
245 RESOLVE_METHOD(avformat_close_input)
246 RESOLVE_METHOD(av_read_frame)
247 RESOLVE_METHOD(av_read_play)
248 RESOLVE_METHOD(av_read_pause)
249 RESOLVE_METHOD(av_read_frame_flush)
250 RESOLVE_METHOD(av_seek_frame)
251 RESOLVE_METHOD_RENAME(avformat_find_stream_info, avformat_find_stream_info_dont_call)
252 RESOLVE_METHOD(avformat_open_input)
253 RESOLVE_METHOD(avio_alloc_context)
254 RESOLVE_METHOD(av_probe_input_format)
255 RESOLVE_METHOD(av_probe_input_format2)
256 RESOLVE_METHOD(av_probe_input_buffer)
257 RESOLVE_METHOD(av_dump_format)
258 RESOLVE_METHOD(avio_open)
259 RESOLVE_METHOD(avio_close)
260 RESOLVE_METHOD(avio_open_dyn_buf)
261 RESOLVE_METHOD(avio_close_dyn_buf)
262 RESOLVE_METHOD(avio_seek)
263 RESOLVE_METHOD(avio_read)
264 RESOLVE_METHOD(avio_w8)
265 RESOLVE_METHOD(avio_write)
266 RESOLVE_METHOD(avio_wb24)
267 RESOLVE_METHOD(avio_wb32)
268 RESOLVE_METHOD(avio_wb16)
269 RESOLVE_METHOD(avformat_alloc_context)
270 RESOLVE_METHOD(avformat_alloc_output_context2)
271 RESOLVE_METHOD(avformat_new_stream)
272 RESOLVE_METHOD(av_guess_format)
273 RESOLVE_METHOD(avformat_write_header)
274 RESOLVE_METHOD(av_write_trailer)
275 RESOLVE_METHOD(av_write_frame)
276 #if defined(AVFORMAT_HAS_STREAM_GET_R_FRAME_RATE)
277 RESOLVE_METHOD(av_stream_get_r_frame_rate)
281 /* dependencies of libavformat */
282 DllAvCodec m_dllAvCodec;
283 // DllAvUtil loaded implicitely by m_dllAvCodec
286 void av_register_all()
288 CSingleLock lock(DllAvCodec::m_critSection);
289 av_register_all_dont_call();
291 int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options)
293 CSingleLock lock(DllAvCodec::m_critSection);
294 return avformat_find_stream_info_dont_call(ic, options);
299 if (!m_dllAvCodec.Load())
301 bool loaded = DllDynamic::Load();
303 CSingleLock lock(DllAvCodec::m_critSection);
304 if (++m_avformat_refcnt == 1 && loaded)
305 avformat_network_init_dont_call();
309 virtual void Unload()
311 CSingleLock lock(DllAvCodec::m_critSection);
312 if (--m_avformat_refcnt == 0 && DllDynamic::IsLoaded())
313 avformat_network_deinit_dont_call();
315 DllDynamic::Unload();
319 static int m_avformat_refcnt;