代码改变世界

xbmc-12.0稳定版代码初探 (1) —— 对ffmpeg的动态库调用

2013-01-31 13:31  Scott Guthrie Liu  阅读(377)  评论(0编辑  收藏  举报

根据http://en.wikipedia.org/wiki/Xbox_Media_Center#Architecture

Some of XBMC's ownlibraries as well as many third-party libraries that XBMC depends on are written in the C programming-language but are mostly used with a C++ wrapper or loaded via XBMC's own DLL loader.[9][30]


FFmpeg主目录下主要有libavcodec、libavformat和libavutil等子目录。其中libavcodec用于存放各个encode/decode模块,libavformat用于存放muxer/demuxer模块,libavutil用于存放内存操作等辅助性模块。

以下针对xbmc-12.0稳定版代码XBMC 12.0 - Frodo 正式发布XBMC 12.0 - Frodo

对应头文件lib目录下 DllAvCodec.h DllAvFormat.h DllAvFilter.h

DVDDemuxFFmpeg.cpp -> bool CDVDDemuxFFmpeg::Open(CDVDInputStream* pInput) -> 

line286:      result = m_dllAvFormat.avformat_open_input(&m_pFormatContext, strFile2.c_str(), iformat, NULL);

DllAvFormat.h line186:  DEFINE_FUNC_ALIGNED4(int, __cdecl, avformat_open_input, AVFormatContext **, const char *, AVInputFormat *, AVDictionary **)

可以看到

#define DEFINE_FUNC_ALIGNED4(result, linkage, name, t1, t2, t3, t4) \
DEFINE_FUNC_PART1(result, linkage, name, (t1 p1, t2 p2, t3 p3, t4 p4)) \
DEFINE_FUNC_PART2(ALS(p1)+ALS(p2)+ALS(p3)+ALS(p4)) \
DEFINE_FUNC_PART3(name,(p1, p2, p3, p4))

可以看到DynamicDll.h

#define ALS(a) ((sizeof(a)+3)&~3)
#define DEFINE_FUNC_PART1(result, linkage, name, args) \
private: \
typedef result (linkage * name##_type)##args; \
union { \
name##_type m_##name; \
void* m_##name##_ptr; \
}; \
public: \
virtual result name##args

#define DEFINE_FUNC_PART2(size) \
{ \
int o,s = size; \
__asm { \
__asm mov [o], esp \
__asm sub esp, [s] \
__asm and esp, ~15 \
__asm add esp, [s] \
}

#define DEFINE_FUNC_PART3(name,args) \
m_##name##args; \
__asm { \
__asm mov esp,[o] \
} \
}

使用[转]用宏展开代码 测试展开

View Code
//  DEFINE_FUNC_ALIGNED4(int, __cdecl, avformat_open_input, AVFormatContext **, const char *, AVInputFormat *, AVDictionary **)

#define DEFINE_FUNC_ALIGNED4(result, linkage, name, t1, t2, t3, t4) \
    DEFINE_FUNC_PART1(result, linkage, name, (t1 p1, t2 p2, t3 p3, t4 p4)) \
    DEFINE_FUNC_PART2(ALS(p1)+ALS(p2)+ALS(p3)+ALS(p4)) \
    DEFINE_FUNC_PART3(name,(p1, p2, p3, p4))

#define ALS(a) ((sizeof(a)+3)&~3)
#define DEFINE_FUNC_PART1(result, linkage, name, args) \
  private:                                             \
    typedef result (linkage * name##_type)##args;      \
    union { \
      name##_type m_##name;                            \
      void*       m_##name##_ptr;                      \
    }; \
  public:                                              \
    virtual result name##args

#define DEFINE_FUNC_PART2(size) \
  {                             \
    int o,s = size;             \
    __asm {                     \
      __asm mov [o], esp        \
      __asm sub esp, [s]        \
      __asm and esp, ~15        \
      __asm add esp, [s]        \
    }

#define DEFINE_FUNC_PART3(name,args) \
    m_##name##args;                  \
    __asm {                          \
      __asm mov esp,[o]              \
    }                                \
  }

//调试宏的宏 begin
#define PRINT_MACRO_( x,...) #x #__VA_ARGS__
#define PRINT_MACRO( x ) PRINT_MACRO_( x )
//调试宏的宏 end

int main(int argc, char* argv[])
{
    std::cout<<PRINT_MACRO(DEFINE_FUNC_ALIGNED4(int, __cdecl, avformat_open_input, AVFormatContext **, const char *, AVInputFormat *, AVDictionary **))<<std::endl;
    return 0;
}

结果

View Code
private: typedef int (__cdecl * avformat_open_input_type)(AVFormatContext ** p1, const char * p2, AVInputFormat * p3, AVDictionary ** p4); 
union 
{ 
    avformat_open_input_type m_avformat_open_input; 
    void* m_avformat_open_input_ptr; 
}; 
public: virtual int avformat_open_input(AVFormatContext ** p1, const char * p2, AVInputFormat * p3, AVDictionary ** p4) 
{ 
    int o,s = ((sizeof(p1)+3)&~3)+((sizeof(p2)+3)&~3)+((sizeof(p3)+3)&~3)+((sizeof(p4)+3)&~3); 
    __asm 
    { 
        __asm mov [o], esp 
        __asm sub esp, [s] 
        __asm and esp, ~15 
        __asm add esp, [s] 
    } 
    m_avformat_open_input(p1, p2,p3, p4); 
    __asm 
    { 
        __asm mov esp,[o]
    } 
}