zoukankan      html  css  js  c++  java
  • (转)FFMPEG的一些使用技巧

    1、查看FFMPEG的日志信息

    在vc中使用ffmpeg静态库做二次开发的时候,如果不是控制台应用程序,又需要查看ffmpeg的日志信息,可使用

    1. av_log_set_callback  

    函数注册一个回调函数,如
     
    1. void ff_log_callback(void*avcl, int level, const char*fmt, va_list vl)  
    2. {  
    3.     char log[1024];  
    4.     vsnprintf(log,sizeof(log),fmt,vl);  
    5.     OutputDebugStringA(log);  
    6. }  
    这样就能在vc的调试输出窗口中看见所有的ffmpeg日志了。

    2 使用多个线程同时播放多个视频源的时候,在调用avcodec_open/close的时候,可能导致失败,这个可以查阅ffmpeg的源码分析其中的原因,失败的主要原因是在调用此2函数时,ffmpeg为了确保该2函数为原子操作,在avcodec_open/close两函数的开头和结尾处使用了一个变量entangled_thread_counter来记录当前函数是否已经有其他线程进入,如果有其他线程正在此2函数内运行,则会调用失败

    解决此问题可使用函数

    1. av_lockmgr_register  
    注册一个运行时锁,当一个线程进入此2函数内时,ffmpeg会调用回调函数锁定该段代码,不让其他函数进入。下面是一个回调函数:
     
    1. int ff_lockmgr_callback(void **mutex, enum AVLockOp op)  
    2. {  
    3.     switch(op)  
    4.     {  
    5.     case AV_LOCK_CREATE:///< Create a mutex  
    6.         {  
    7.             CRITICAL_SECTION * cs = (CRITICAL_SECTION*)av_malloc(sizeof(CRITICAL_SECTION));  
    8.             if(!cs)  
    9.             {  
    10.                 return -1;  
    11.             }  
    12.             memset(cs,0,sizeof(CRITICAL_SECTION));  
    13.             InitializeCriticalSection(cs);  
    14.             *(CRITICAL_SECTION**)mutex = cs;  
    15.         }  
    16.         break;  
    17.     case AV_LOCK_OBTAIN:///< Lock the mutex  
    18.         {  
    19.             if(mutex && *(CRITICAL_SECTION**)mutex)  
    20.             {  
    21.                 ::EnterCriticalSection(*(CRITICAL_SECTION**)mutex);  
    22.             }  
    23.         }  
    24.         break;  
    25.     case AV_LOCK_RELEASE:///< Unlock the mutex  
    26.         {  
    27.             if(mutex && *(CRITICAL_SECTION**)mutex)  
    28.             {  
    29.                 ::LeaveCriticalSection(*(CRITICAL_SECTION**)mutex);  
    30.             }  
    31.         }  
    32.         break;  
    33.     case AV_LOCK_DESTROY:///< Free mutex resources  
    34.         {  
    35.             if(mutex && *(CRITICAL_SECTION**)mutex)  
    36.             {  
    37.                 ::DeleteCriticalSection(*(CRITICAL_SECTION**)mutex);  
    38.                 av_free(*(CRITICAL_SECTION**)mutex);  
    39.                 *(CRITICAL_SECTION**)mutex = NULL;  
    40.             }  
    41.         }  
    42.         break;  
    43.     default:  
    44.         break;  
    45.     }  
    46.     return 0;  
    47. }  
    3 ffmpeg内存泄漏检测

    ffmpeg做二次开发的时候,最头疼的问题之一就是内存泄漏了,其实可以重写libavutil/mem.h和libavutil/mem.c两个文件中的以下几个函数:

    av_malloc
    av_realloc
    av_free
    av_mallocz
    av_strdup
    av_freep
    通过重写上述函数(重写后,原上述函数需要注释掉),我们可以记录从堆上动态分配的内存块及其这些内存块的释放情况。

    一般情况下,vc可以检测到哪个内存块已经发生泄露,只是定位不到该内存块是在什么地方分配的。

    通过重写以上函数后,可以记录动态分配的内存块地址和释放掉的内存块地址,总的分配次数,总的释放次数等等。

    下面是一个范本,具体实现可仿照mem.c中对应的函数实现部分。

    1. void *av_malloc_memory_leak_detect(unsigned int size,const char * file,int line) av_malloc_attrib av_alloc_size(1);  
    2. void *av_realloc_memory_leak_detect(void *ptr, unsigned int NewSize,const char * file,int line) av_alloc_size(2);  
    3. void av_free_memory_leak_detect(void *ptr,const char * file,int line);  
    4. void av_freep_memory_leak_detect(void *arg,const char * file,int line);  
    5. void *av_mallocz_memory_leak_detect(unsigned int size,const char * file,int line) av_malloc_attrib av_alloc_size(1);  
    6. char *av_strdup_memory_leak_detect(const char *s,const char * file,int line);  
    7.   
    8. #define av_malloc(size) av_malloc_memory_leak_detect((size),__FILE__,__LINE__)  
    9. #define av_realloc(ptr,size) av_realloc_memory_leak_detect((ptr),(size),__FILE__,__LINE__)  
    10. #define av_free(ptr) av_free_memory_leak_detect((ptr),__FILE__,__LINE__)  
    11. #define av_mallocz(size) av_mallocz_memory_leak_detect((size),__FILE__,__LINE__)  
    12. #define av_strdup(s) av_strdup_memory_leak_detect((s),__FILE__,__LINE__)  
    13. #define av_freep(ptr) av_freep_memory_leak_detect((ptr),__

    转自:http://blog.csdn.net/sloan6/article/details/9500491

  • 相关阅读:
    基于visual c++之windows核心编程代码分析(52)使用WMI 获取进程启动参数
    基于visual c++之windows核心编程代码分析(56)使用winsock搜索蓝牙设备
    这个星期上网找工作,周六准备就去上海了.
    Delphi 中的 XMLDocument 类详解(21) 暂停
    数组与子界
    Delphi 中的 XMLDocument 类详解(17) 上一个节点、下一个节点、父节点
    Delphi 中的 XMLDocument 类详解(19) NodeValue 与 NodeName 的读写区别
    Delphi 中的 XMLDocument 类详解(18) 更好地显示 xml 的测试结果 FormatXMLData 及其他
    Delphi 中的 XMLDocument 类详解(16) 节点列表中的第一个与最后一个节点
    Delphi 中的 XMLDocument 类详解(14) 遍历 XML 文件
  • 原文地址:https://www.cnblogs.com/lihaiping/p/4632929.html
Copyright © 2011-2022 走看看