Merge pull request #4011 from fritsch/vdpau-settings
[vuplus_xbmc] / lib / DllAvCodec.h
1 #pragma once
2 /*
3  *      Copyright (C) 2005-2013 Team XBMC
4  *      http://xbmc.org
5  *
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)
9  *  any later version.
10  *
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.
15  *
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/>.
19  *
20  */
21
22 #if (defined HAVE_CONFIG_H) && (!defined WIN32)
23   #include "config.h"
24 #endif
25 #include "DynamicDll.h"
26 #include "DllAvUtil.h"
27 #include "utils/log.h"
28
29 extern "C" {
30 #ifndef HAVE_MMX
31 #define HAVE_MMX
32 #endif
33 #ifndef __STDC_CONSTANT_MACROS
34 #define __STDC_CONSTANT_MACROS
35 #endif
36 #ifndef __STDC_LIMIT_MACROS
37 #define __STDC_LIMIT_MACROS
38 #endif
39
40 #ifndef __GNUC__
41 #pragma warning(disable:4244)
42 #endif
43
44 #if (defined USE_EXTERNAL_FFMPEG)
45   #include <libavcodec/avcodec.h>
46 #else
47   #include "libavcodec/avcodec.h"
48 #endif
49 }
50
51 #include "threads/SingleLock.h"
52
53 class DllAvCodecInterface
54 {
55 public:
56   virtual ~DllAvCodecInterface() {}
57   virtual void avcodec_register_all(void)=0;
58   virtual void avcodec_flush_buffers(AVCodecContext *avctx)=0;
59   virtual int avcodec_open2_dont_call(AVCodecContext *avctx, AVCodec *codec, AVDictionary **options)=0;
60   virtual AVCodec *avcodec_find_decoder(enum AVCodecID id)=0;
61   virtual AVCodec *avcodec_find_encoder(enum AVCodecID id)=0;
62   virtual int avcodec_close_dont_call(AVCodecContext *avctx)=0;
63   virtual AVFrame *avcodec_alloc_frame(void)=0;
64   virtual int avpicture_fill(AVPicture *picture, uint8_t *ptr, PixelFormat pix_fmt, int width, int height)=0;
65   virtual int avcodec_decode_video2(AVCodecContext *avctx, AVFrame *picture, int *got_picture_ptr, AVPacket *avpkt)=0;
66   virtual int avcodec_decode_audio4(AVCodecContext *avctx, AVFrame *frame, int *got_frame_ptr, AVPacket *avpkt)=0;
67   virtual int avcodec_decode_subtitle2(AVCodecContext *avctx, AVSubtitle *sub, int *got_sub_ptr, AVPacket *avpkt)=0;
68   virtual int avcodec_encode_audio2(AVCodecContext *avctx, AVPacket *avpkt, const AVFrame *frame, int *got_packet_ptr)=0;
69   virtual int avpicture_get_size(PixelFormat pix_fmt, int width, int height)=0;
70   virtual AVCodecContext *avcodec_alloc_context3(AVCodec *codec)=0;
71   virtual void avcodec_string(char *buf, int buf_size, AVCodecContext *enc, int encode)=0;
72   virtual void avcodec_get_context_defaults3(AVCodecContext *s, AVCodec *codec)=0;
73   virtual AVCodecParserContext *av_parser_init(int codec_id)=0;
74   virtual int av_parser_parse2(AVCodecParserContext *s,AVCodecContext *avctx, uint8_t **poutbuf, int *poutbuf_size,
75                     const uint8_t *buf, int buf_size,
76                     int64_t pts, int64_t dts, int64_t pos)=0;
77   virtual void av_parser_close(AVCodecParserContext *s)=0;
78   virtual AVBitStreamFilterContext *av_bitstream_filter_init(const char *name)=0;
79   virtual int av_bitstream_filter_filter(AVBitStreamFilterContext *bsfc,
80     AVCodecContext *avctx, const char *args,
81     uint8_t **poutbuf, int *poutbuf_size,
82     const uint8_t *buf, int buf_size, int keyframe) =0;
83   virtual void av_bitstream_filter_close(AVBitStreamFilterContext *bsfc) =0;
84   virtual void avpicture_free(AVPicture *picture)=0;
85   virtual void av_free_packet(AVPacket *pkt)=0;
86   virtual int avpicture_alloc(AVPicture *picture, PixelFormat pix_fmt, int width, int height)=0;
87   virtual enum PixelFormat avcodec_default_get_format(struct AVCodecContext *s, const enum PixelFormat *fmt)=0;
88   virtual AVCodec *av_codec_next(AVCodec *c)=0;
89   virtual int av_dup_packet(AVPacket *pkt)=0;
90   virtual void av_init_packet(AVPacket *pkt)=0;
91   virtual int avcodec_fill_audio_frame(AVFrame *frame, int nb_channels, enum AVSampleFormat sample_fmt, const uint8_t *buf, int buf_size, int align) = 0;
92   virtual void avcodec_free_frame(AVFrame **frame)=0;
93   virtual int av_codec_is_decoder(const AVCodec *codec)=0;
94   virtual AVDictionary* av_frame_get_metadata(const AVFrame* frame)=0;
95 };
96
97 #if (defined USE_EXTERNAL_FFMPEG) || (defined TARGET_DARWIN) || (defined USE_STATIC_FFMPEG)
98
99 // Use direct layer
100 class DllAvCodec : public DllDynamic, DllAvCodecInterface
101 {
102 public:
103   static CCriticalSection m_critSection;
104
105   virtual ~DllAvCodec() {}
106   virtual void avcodec_register_all()
107   {
108     CSingleLock lock(DllAvCodec::m_critSection);
109     ::avcodec_register_all();
110   }
111   virtual void avcodec_flush_buffers(AVCodecContext *avctx) { ::avcodec_flush_buffers(avctx); }
112   virtual int avcodec_open2(AVCodecContext *avctx, AVCodec *codec, AVDictionary **options)
113   {
114     CSingleLock lock(DllAvCodec::m_critSection);
115     return ::avcodec_open2(avctx, codec, options);
116   }
117   virtual int avcodec_open2_dont_call(AVCodecContext *avctx, AVCodec *codec, AVDictionary **options) { *(volatile int *)0x0 = 0; return 0; }
118   virtual int avcodec_close_dont_call(AVCodecContext *avctx) { *(volatile int *)0x0 = 0; return 0; }
119   virtual AVCodec *avcodec_find_decoder(enum AVCodecID id) { return ::avcodec_find_decoder(id); }
120   virtual AVCodec *avcodec_find_encoder(enum AVCodecID id) { return ::avcodec_find_encoder(id); }
121   virtual int avcodec_close(AVCodecContext *avctx)
122   {
123     CSingleLock lock(DllAvCodec::m_critSection);
124     return ::avcodec_close(avctx);
125   }
126   virtual AVFrame *avcodec_alloc_frame() { return ::avcodec_alloc_frame(); }
127   virtual int avpicture_fill(AVPicture *picture, uint8_t *ptr, PixelFormat pix_fmt, int width, int height) { return ::avpicture_fill(picture, ptr, pix_fmt, width, height); }
128   virtual int avcodec_decode_video2(AVCodecContext *avctx, AVFrame *picture, int *got_picture_ptr, AVPacket *avpkt) { return ::avcodec_decode_video2(avctx, picture, got_picture_ptr, avpkt); }
129   virtual int avcodec_decode_audio4(AVCodecContext *avctx, AVFrame *frame, int *got_frame_ptr, AVPacket *avpkt) { return ::avcodec_decode_audio4(avctx, frame, got_frame_ptr, avpkt); }
130   virtual int avcodec_decode_subtitle2(AVCodecContext *avctx, AVSubtitle *sub, int *got_sub_ptr, AVPacket *avpkt) { return ::avcodec_decode_subtitle2(avctx, sub, got_sub_ptr, avpkt); }
131   virtual int avcodec_encode_audio2(AVCodecContext *avctx, AVPacket *avpkt, const AVFrame *frame, int *got_packet_ptr) { return ::avcodec_encode_audio2(avctx, avpkt, frame, got_packet_ptr); }
132   virtual int avpicture_get_size(PixelFormat pix_fmt, int width, int height) { return ::avpicture_get_size(pix_fmt, width, height); }
133   virtual AVCodecContext *avcodec_alloc_context3(AVCodec *codec) { return ::avcodec_alloc_context3(codec); }
134   virtual void avcodec_string(char *buf, int buf_size, AVCodecContext *enc, int encode) { ::avcodec_string(buf, buf_size, enc, encode); }
135   virtual void avcodec_get_context_defaults3(AVCodecContext *s, AVCodec *codec) { ::avcodec_get_context_defaults3(s, codec); }
136
137   virtual AVCodecParserContext *av_parser_init(int codec_id) { return ::av_parser_init(codec_id); }
138   virtual int av_parser_parse2(AVCodecParserContext *s,AVCodecContext *avctx, uint8_t **poutbuf, int *poutbuf_size,
139                     const uint8_t *buf, int buf_size,
140                     int64_t pts, int64_t dts, int64_t pos)
141   {
142     return ::av_parser_parse2(s, avctx, poutbuf, poutbuf_size, buf, buf_size, pts, dts, pos);
143   }
144   virtual void av_parser_close(AVCodecParserContext *s) { ::av_parser_close(s); }
145
146   virtual AVBitStreamFilterContext *av_bitstream_filter_init(const char *name) { return ::av_bitstream_filter_init(name); }
147   virtual int av_bitstream_filter_filter(AVBitStreamFilterContext *bsfc,
148     AVCodecContext *avctx, const char *args,
149     uint8_t **poutbuf, int *poutbuf_size,
150     const uint8_t *buf, int buf_size, int keyframe) { return ::av_bitstream_filter_filter(bsfc, avctx, args, poutbuf, poutbuf_size, buf, buf_size, keyframe); }
151   virtual void av_bitstream_filter_close(AVBitStreamFilterContext *bsfc) { ::av_bitstream_filter_close(bsfc); }
152
153   virtual void avpicture_free(AVPicture *picture) { ::avpicture_free(picture); }
154   virtual void av_free_packet(AVPacket *pkt) { ::av_free_packet(pkt); }
155   virtual int avpicture_alloc(AVPicture *picture, PixelFormat pix_fmt, int width, int height) { return ::avpicture_alloc(picture, pix_fmt, width, height); }
156   virtual enum PixelFormat avcodec_default_get_format(struct AVCodecContext *s, const enum PixelFormat *fmt) { return ::avcodec_default_get_format(s, fmt); }
157   virtual AVCodec *av_codec_next(AVCodec *c) { return ::av_codec_next(c); }
158
159   virtual int av_dup_packet(AVPacket *pkt) { return ::av_dup_packet(pkt); }
160   virtual void av_init_packet(AVPacket *pkt) { return ::av_init_packet(pkt); }
161   virtual int avcodec_fill_audio_frame(AVFrame *frame, int nb_channels, enum AVSampleFormat sample_fmt, const uint8_t *buf, int buf_size, int align) { return ::avcodec_fill_audio_frame(frame, nb_channels, sample_fmt, buf, buf_size, align); }
162   virtual void avcodec_free_frame(AVFrame **frame) { return ::avcodec_free_frame(frame); };
163   virtual int av_codec_is_decoder(const AVCodec *codec) { return ::av_codec_is_decoder(codec); }
164   virtual AVDictionary* av_frame_get_metadata(const AVFrame* frame) { return ::av_frame_get_metadata(frame); }
165
166   // DLL faking.
167   virtual bool ResolveExports() { return true; }
168   virtual bool Load() {
169 #if !defined(TARGET_DARWIN) && !defined(USE_STATIC_FFMPEG)
170     CLog::Log(LOGDEBUG, "DllAvCodec: Using libavcodec system library");
171 #endif
172     return true;
173   }
174   virtual void Unload() {}
175 };
176 #else
177 class DllAvCodec : public DllDynamic, DllAvCodecInterface
178 {
179   DECLARE_DLL_WRAPPER(DllAvCodec, DLL_PATH_LIBAVCODEC)
180   DEFINE_FUNC_ALIGNED1(void, __cdecl, avcodec_flush_buffers, AVCodecContext*)
181   DEFINE_FUNC_ALIGNED3(int, __cdecl, avcodec_open2_dont_call, AVCodecContext*, AVCodec *, AVDictionary **)
182   DEFINE_FUNC_ALIGNED4(int, __cdecl, avcodec_decode_video2, AVCodecContext*, AVFrame*, int*, AVPacket*)
183   DEFINE_FUNC_ALIGNED4(int, __cdecl, avcodec_decode_audio4, AVCodecContext*, AVFrame*, int*, AVPacket*)
184   DEFINE_FUNC_ALIGNED4(int, __cdecl, avcodec_decode_subtitle2, AVCodecContext*, AVSubtitle*, int*, AVPacket*)
185   DEFINE_FUNC_ALIGNED4(int, __cdecl, avcodec_encode_audio2, AVCodecContext*, AVPacket*, const AVFrame*, int*)
186   DEFINE_FUNC_ALIGNED1(AVCodecContext*, __cdecl, avcodec_alloc_context3, AVCodec *)
187   DEFINE_FUNC_ALIGNED1(AVCodecParserContext*, __cdecl, av_parser_init, int)
188   DEFINE_FUNC_ALIGNED9(int, __cdecl, av_parser_parse2, AVCodecParserContext*,AVCodecContext*, uint8_t**, int*, const uint8_t*, int, int64_t, int64_t, int64_t)
189   DEFINE_METHOD1(int, av_dup_packet, (AVPacket *p1))
190   DEFINE_METHOD1(void, av_init_packet, (AVPacket *p1))
191
192   LOAD_SYMBOLS();
193
194   DEFINE_METHOD0(void, avcodec_register_all_dont_call)
195   DEFINE_METHOD1(AVCodec*, avcodec_find_decoder, (enum AVCodecID p1))
196   DEFINE_METHOD1(AVCodec*, avcodec_find_encoder, (enum AVCodecID p1))
197   DEFINE_METHOD1(int, avcodec_close_dont_call, (AVCodecContext *p1))
198   DEFINE_METHOD0(AVFrame*, avcodec_alloc_frame)
199   DEFINE_METHOD5(int, avpicture_fill, (AVPicture *p1, uint8_t *p2, PixelFormat p3, int p4, int p5))
200   DEFINE_METHOD3(int, avpicture_get_size, (PixelFormat p1, int p2, int p3))
201   DEFINE_METHOD4(void, avcodec_string, (char *p1, int p2, AVCodecContext *p3, int p4))
202   DEFINE_METHOD2(void, avcodec_get_context_defaults3, (AVCodecContext *p1, AVCodec *p2))
203   DEFINE_METHOD1(void, av_parser_close, (AVCodecParserContext *p1))
204   DEFINE_METHOD1(void, avpicture_free, (AVPicture *p1))
205   DEFINE_METHOD1(AVBitStreamFilterContext*, av_bitstream_filter_init, (const char *p1))
206   DEFINE_METHOD8(int, av_bitstream_filter_filter, (AVBitStreamFilterContext* p1, AVCodecContext* p2, const char* p3, uint8_t** p4, int* p5, const uint8_t* p6, int p7, int p8))
207   DEFINE_METHOD1(void, av_bitstream_filter_close, (AVBitStreamFilterContext *p1))
208   DEFINE_METHOD1(void, av_free_packet, (AVPacket *p1))
209   DEFINE_METHOD4(int, avpicture_alloc, (AVPicture *p1, PixelFormat p2, int p3, int p4))
210   DEFINE_METHOD2(enum PixelFormat, avcodec_default_get_format, (struct AVCodecContext *p1, const enum PixelFormat *p2))
211   DEFINE_METHOD6(int, avcodec_fill_audio_frame, (AVFrame* p1, int p2, enum AVSampleFormat p3, const uint8_t* p4, int p5, int p6))
212   DEFINE_METHOD1(void, avcodec_free_frame, (AVFrame **p1))
213   DEFINE_METHOD1(AVCodec*, av_codec_next, (AVCodec *p1))
214   DEFINE_METHOD1(int, av_codec_is_decoder, (const AVCodec *p1))
215   DEFINE_METHOD1(AVDictionary*, av_frame_get_metadata, (const AVFrame* p1))
216
217   BEGIN_METHOD_RESOLVE()
218     RESOLVE_METHOD(avcodec_flush_buffers)
219     RESOLVE_METHOD_RENAME(avcodec_open2,avcodec_open2_dont_call)
220     RESOLVE_METHOD_RENAME(avcodec_close,avcodec_close_dont_call)
221     RESOLVE_METHOD(avcodec_find_decoder)
222     RESOLVE_METHOD(avcodec_find_encoder)
223     RESOLVE_METHOD(avcodec_alloc_frame)
224     RESOLVE_METHOD_RENAME(avcodec_register_all, avcodec_register_all_dont_call)
225     RESOLVE_METHOD(avpicture_fill)
226     RESOLVE_METHOD(avcodec_decode_video2)
227     RESOLVE_METHOD(avcodec_decode_audio4)
228     RESOLVE_METHOD(avcodec_decode_subtitle2)
229     RESOLVE_METHOD(avcodec_encode_audio2)
230     RESOLVE_METHOD(avpicture_get_size)
231     RESOLVE_METHOD(avcodec_alloc_context3)
232     RESOLVE_METHOD(avcodec_string)
233     RESOLVE_METHOD(avcodec_get_context_defaults3)
234     RESOLVE_METHOD(av_parser_init)
235     RESOLVE_METHOD(av_parser_parse2)
236     RESOLVE_METHOD(av_parser_close)
237     RESOLVE_METHOD(av_bitstream_filter_init)
238     RESOLVE_METHOD(av_bitstream_filter_filter)
239     RESOLVE_METHOD(av_bitstream_filter_close)
240     RESOLVE_METHOD(avpicture_free)
241     RESOLVE_METHOD(avpicture_alloc)
242     RESOLVE_METHOD(av_free_packet)
243     RESOLVE_METHOD(avcodec_default_get_format)
244     RESOLVE_METHOD(av_codec_next)
245     RESOLVE_METHOD(av_dup_packet)
246     RESOLVE_METHOD(av_init_packet)
247     RESOLVE_METHOD(avcodec_fill_audio_frame)
248     RESOLVE_METHOD(avcodec_free_frame)
249     RESOLVE_METHOD(av_codec_is_decoder)
250     RESOLVE_METHOD(av_frame_get_metadata)
251   END_METHOD_RESOLVE()
252
253   /* dependencies of libavcodec */
254   DllAvUtil m_dllAvUtil;
255
256 public:
257     static CCriticalSection m_critSection;
258     int avcodec_open2(AVCodecContext *avctx, AVCodec *codec, AVDictionary **options)
259     {
260       CSingleLock lock(DllAvCodec::m_critSection);
261       return avcodec_open2_dont_call(avctx,codec, options);
262     }
263     int avcodec_close(AVCodecContext *avctx)
264     {
265       CSingleLock lock(DllAvCodec::m_critSection);
266       return avcodec_close_dont_call(avctx);
267     }
268     void avcodec_register_all()
269     {
270       CSingleLock lock(DllAvCodec::m_critSection);
271       avcodec_register_all_dont_call();
272     }
273     virtual bool Load()
274     {
275       if (!m_dllAvUtil.Load())
276         return false;
277       return DllDynamic::Load();
278     }
279 };
280
281 #endif