2011-06-01 00:26:14)

转载

view plaincopy to clipboardprint?
///  
intinit_decoder()   
{  
    intret;  
   xvid_gbl_init_t  xvid_gbl_init;  
   xvid_dec_create_txvid_dec_create;  
    
   memset(&xvid_gbl_init, 0,sizeof(xvid_gbl_init_t));  
   memset(&xvid_dec_create, 0,sizeof(xvid_dec_create_t));  
    
    XDIM = 0;   
    YDIM = 0;   
    FORMAT = 0;   
    CSP =XVID_CSP_BGR;  
    BPP =3;  
      
    dec_handle =NULL ;  
      
    mp4_buffer =NULL ;   
    out_buffer =NULL ;   
    mp4_ptr =NULL ;   
    
   xvid_gbl_init.version =XVID_VERSION;  
    
   xvid_gbl_init.cpu_flags = 0;  // use assemblyoptimized   
   xvid_gbl_init.debug = 0;    // set debug level 0, no debugoutput   
   xvid_global(NULL, 0, &xvid_gbl_init, NULL);//XVID初始化  
    
    
   xvid_dec_create.version =XVID_VERSION;  
    
   xvid_dec_create.width = 0;//解码后图像的宽度 如果事先已经知道那么这里就填写 否则设置0  
   xvid_dec_create.height = 0;//解码后图像的高度 如果事先已经知道那么这里就填写否则设置0  
    ret =xvid_decore(NULL, XVID_DEC_CREATE,&xvid_dec_create, NULL);//创建xvid解码实例  
    dec_handle =xvid_dec_create.handle;将创建的句柄 赋值 给dec_handle  
   return(ret);  
}  
//  
int decode_one_frame(unsigned char *istream, unsigned char*ostream,  
                                     int istream_size, xvid_dec_stats_t*xvid_dec_stats)  
{  
    intret;  
   xvid_dec_frame_txvid_dec_frame;  
    
   memset(&xvid_dec_frame, 0,sizeof(xvid_dec_frame_t));  
   memset(xvid_dec_stats, 0,sizeof(xvid_dec_stats_t));  
    
   xvid_dec_frame.version =XVID_VERSION;  
   xvid_dec_stats->version =XVID_VERSION;    
    
   xvid_dec_frame.general         = 0;  
    
   xvid_dec_frame.bitstream       = istream;//待解码的数据  
   xvid_dec_frame.length          = istream_size;//待解码数据的长度  
    
   xvid_dec_frame.output.plane[0]  =ostream;//解码完成后存放原始视频流的缓冲区  
   xvid_dec_frame.output.stride[0] =XDIM*BPP;//步长即一行像素所占的空间大小  
   xvid_dec_frame.output.csp = CSP;//输出时 采用的色场空间 这里 XVID_CSP_BGR即采用RGB  
    ret =xvid_decore(dec_handle, XVID_DEC_DECODE,&xvid_dec_frame, xvid_dec_stats);//ret 值解码前帧的长度  
   return(ret);  
}  
///调用方式  
do {  
            
           used_bytes = decode_one_frame(mp4_ptr, out_buffer, useful_bytes,&xvid_dec_stats);  
            
           if(xvid_dec_stats.type == XVID_TYPE_VOL)//如果输入一帧包含 VOL重新获得输出图像的宽度和高度  
           {  
                
               if(XDIM*YDIM <xvid_dec_stats.data.vol.width*xvid_dec_stats.data.vol.height)   
               {  
                    
                   XDIM =xvid_dec_stats.data.vol.width;  
                   YDIM =xvid_dec_stats.data.vol.height;  
                      
                    
                   if(out_buffer)free(out_buffer);  
                    
                   out_buffer = (unsigned char*)malloc(XDIM*YDIM*4);//动态调整输出流存储空间的大小  
                   if(out_buffer == NULL)  
                       goto free_all_memory;  
               }  
           }  
            
           if(used_bytes > 0){  
               mp4_ptr += used_bytes;  
               useful_bytes -=used_bytes;  
           }  
       } while (xvid_dec_stats.type <= 0&& useful_bytes >MIN_USEFUL_BYTES);  
          
        
       draw_image(out_buffer) ;  
///
int init_decoder()
{
 int ret;
 xvid_gbl_init_t  xvid_gbl_init;
 xvid_dec_create_t xvid_dec_create;
 
 memset(&xvid_gbl_init, 0,sizeof(xvid_gbl_init_t));
 memset(&xvid_dec_create, 0,sizeof(xvid_dec_create_t));
 
 XDIM = 0 ;
 YDIM = 0 ;
 FORMAT = 0 ;
 CSP = XVID_CSP_BGR;
 BPP = 3;
 
 dec_handle = NULL ;
 
 mp4_buffer = NULL ;
 out_buffer = NULL ;
 mp4_ptr = NULL ;
 
 xvid_gbl_init.version = XVID_VERSION;
 
 xvid_gbl_init.cpu_flags = 0;  //use assembly optimized
 xvid_gbl_init.debug = 0;    // set debug level 0, no debug output
 xvid_global(NULL, 0,&xvid_gbl_init, NULL);//XVID 初始化
 
 
 xvid_dec_create.version = XVID_VERSION;
 
 xvid_dec_create.width =0;//解码后图像的宽度  如果事先已经知道 那么这里就填写 否则设置0
 xvid_dec_create.height = 0;//解码后图像的高度如果事先已经知道那么这里就填写 否则设置0
 ret = xvid_decore(NULL, XVID_DEC_CREATE,&xvid_dec_create, NULL);//创建xvid 解码实例
 dec_handle = xvid_dec_create.handle;将创建的句柄赋值给 dec_handle
 return(ret);
}
//
int decode_one_frame(unsigned char *istream, unsigned char*ostream,
          int istream_size, xvid_dec_stats_t *xvid_dec_stats)
{
 int ret;
 xvid_dec_frame_t xvid_dec_frame;
 
 memset(&xvid_dec_frame, 0,sizeof(xvid_dec_frame_t));
 memset(xvid_dec_stats, 0,sizeof(xvid_dec_stats_t));
 
 xvid_dec_frame.version = XVID_VERSION;
 xvid_dec_stats->version =XVID_VERSION; 
 
 xvid_dec_frame.general         = 0;
 
 xvid_dec_frame.bitstream       = istream;//待解码的数据
 xvid_dec_frame.length          = istream_size;//待解码数据的长度
 
 xvid_dec_frame.output.plane[0] = ostream;//解码完成后 存放原始视频流的缓冲区
 xvid_dec_frame.output.stride[0] =XDIM*BPP;//步长即一行像素所占的空间大小
 xvid_dec_frame.output.csp = CSP;//输出时 采用的色场空间 这里XVID_CSP_BGR 即采用RGB
 ret = xvid_decore(dec_handle, XVID_DEC_DECODE,&xvid_dec_frame, xvid_dec_stats);//ret 值解码前帧的长度
 return(ret);
}
///调用方式
do {
   
   used_bytes =decode_one_frame(mp4_ptr, out_buffer, useful_bytes,&xvid_dec_stats);
   
   if(xvid_dec_stats.type== XVID_TYPE_VOL)//如果输入一帧包含 VOL 重新获得 输出图像的宽度和高度
   {
    
    if(XDIM*YDIM<xvid_dec_stats.data.vol.width*xvid_dec_stats.data.vol.height)
    {
     
     XDIM= xvid_dec_stats.data.vol.width;
     YDIM= xvid_dec_stats.data.vol.height;
     
     
     if(out_buffer)free(out_buffer);
     
     out_buffer= (unsigned char*)malloc(XDIM*YDIM*4);//动态调整 输出流 存储空间的大小
     if(out_buffer== NULL)
      gotofree_all_memory;
    }
   }
   
   if(used_bytes> 0) {
    mp4_ptr+= used_bytes;
    useful_bytes-= used_bytes;
   }
  } while (xvid_dec_stats.type<= 0 && useful_bytes> MIN_USEFUL_BYTES);
  
  
  draw_image(out_buffer);

2 Xvid编解码 实践

关于编码器输入格式设置:

其中 en->width图像采集时的宽度(以像素为单位)

switch( input->format )
  {
  case FORMAT_RAW_BGR24:
   xvid_enc_frame.input.csp =XVID_CSP_BGR;
   xvid_enc_frame.input.stride[0]= en->width * 3;
   break;
  case FORMAT_RAW_UYVY:
   xvid_enc_frame.input.csp =XVID_CSP_UYVY;
   xvid_enc_frame.input.stride[0]= en->width * 2;
   break;
  case FORMAT_RAW_YUY2:
   xvid_enc_frame.input.csp =XVID_CSP_YUY2;
   xvid_enc_frame.input.stride[0]= en->width * 2;
   break;
  }

解码器输出格式设置:

switch( output->format )
  {
  case FORMAT_RAW_BGR24:
  xvid_dec_frame.output.stride[0] = m_width*3;
   xvid_dec_frame.output.csp=XVID_CSP_BGR;

break;
   case FORMAT_RAW_YUY2:
   xvid_dec_frame.output.csp =XVID_CSP_YUY2;
  xvid_dec_frame.output.stride[0]= en->width *2;
   break;
  }

特别注意的是:

在xvid 中stride 步长与 视频格式有密切格式 一旦设置错误导致 编解码异常终止。

xvid使用小技巧:

(1)解决:使用xvid编解码rtp传输directshow播放远程视频时开始会出现绿屏但可以看到图像轮廓,在经过几秒后正常

很可能的一个原因是 关键帧丢失 方法:

减小关键帧的间隔

//最大I帧(关键帧)间隔,一般设置成帧数的10倍

xvid_enc_create.max_key_interval =1;//(int)-1;   //--default 10s

(2)(获得编码后 帧长度)

ret = xvid_encore(m_enc_handle, XVID_ENC_ENCODE,&xvid_enc_frame,&xvid_enc_stats);

m_enc_frame_length=xvid_enc_stats.length;//编码获得的帧长度

转载 调用xvid 实现解码相关推荐

  1. 调用D3D11硬解码和渲染VideoProcessor版本

    在https://blog.csdn.net/robothn/article/details/78781321一文中使用shader来显示FFMPEG硬解码后的YUV420P,本文调用D3D11的vi ...

  2. 2023-02-21:请用go语言调用ffmpeg,解码mp4文件,输出视频信息和总帧数。

    2023-02-21:请用go语言调用ffmpeg,解码mp4文件,输出视频信息和总帧数. 答案2023-02-21: 使用 github.com/moonfdd/ffmpeg-go 库,这个库比go ...

  3. 调用Xvid编码器流程(基于xvid1.1.0)

    xvid有两种编码方式:single pass和twopass   single pass模式编码简单,速度也快,但最终效果不如twopass.   twopass就是视频压制需要经过两次编码,分别为 ...

  4. 嵌入式Linux下LCD应用编程: 调用giflib库解码显示GIF动态图

    一.开发环境介绍 开发板:友善之臂Tiny4412 LCD型号: S702 .分辨率: 800*480 Linux内核版本: Linux 3.5 交叉编译器: arm-linux-gcc 4.5.1 ...

  5. 腾讯云 sdk调用 显示 图片解码失败 解决方案

    参考人脸识别接入常见问题汇总 - 腾讯云开发者社区-腾讯云的第六条 前情提要,接口需要image 的base64编码str,于是我的基本处理办法是 # 初始化用于对比的图片 filename1 = ' ...

  6. 基于Intel 集成显卡的 FFmpeg 调用 VAAPI 硬件解码零数据拷贝链接推理引擎工作流程的实现

    概述 在视频处理流程中,视频的解码通常在 CPU 中进行,若用户需要使用集成显卡进行深度学习推理,解码数据需要从 CPU的缓存中拷贝至集成显卡中进行推理.本文旨在通过集成显卡进行硬件解码,使用FFmp ...

  7. 【转载】vob格式转换成avi格式的影片和制作的方法

    vob格式转换成avi格式的影片和制作的方法: 打开DVD根目录,你可看到两个子目录:VIDEO_TS和AUDIO_TS.AUDIO_TS中并没有内容,DVD的所有内容都存放在VIDEO_TS目录之下 ...

  8. Python_编写UDP通信编解码类、文件的上传、远程执行命令、黏包

    1.UDP通信编解码类 (1) 类 1 # ------------------UDP通信解码编码类------------------------ 2 3 from socket import * ...

  9. 图像解码之一——使用libjpeg解码jpeg图片

    多媒体应用在现在电子产品中的地位越来越重要,尤其是在嵌入式设备中.本系列文章将会介绍利用libjpeg解码jpeg文件,libpng解码png文件,libgif解码gif文件.本文为第一篇,介绍使用l ...

最新文章

  1. binlog_group_commit_sync_delay 参数对并发的影响
  2. Mac OS X 10.10.3对SSD开启Trim功能
  3. pycharm 2020 版取消鼠标悬停显示说明文档的方法
  4. Java基础---数组练习(最大值、最小值的索引)
  5. MFC开发IM-第二十七篇、如何引入acl,解决Json解析问题
  6. 排序算法第四篇——冒泡排序
  7. Selenium +Python项目实践(注册流程)
  8. 按键精灵手机助手之实战篇(二)防封
  9. Processing 椭圆运动模拟
  10. 【LaTex】各种空格的实现(相对quad、qquad、\,、\:、\;、\!、endspace、thinspace、negthinspace绝对vspace和hspace膨胀hfill、vfill)
  11. 3分钟教会你Graylog收集Windows主机日志
  12. 程序员为什么要学习软件工程
  13. java 地铁费_Java练习题_Map集合,遍历车站编号及名称、计算地铁票价。
  14. 计算机考试行高怎么设置,Excel隔行调整行高的四种有效方法
  15. MATLAB实现利用三个不共线的点绘制圆(包括圆心和半径的求解)
  16. 苹果拟在爱尔兰建数据中心 当地居民抗议
  17. 2.1.4 超声波雷达
  18. FTP服务器vsftpd配置项-黑白名单(userlist_enable、userlist_deny)
  19. VUE|利用父子组件制作弹出框
  20. mysql数据库学习之sql调优思路

热门文章

  1. 使用 python 开发 Web Service
  2. the first day
  3. iOS 本地化应用程序汇总 国际化
  4. Angular rxjs operators 笔记
  5. GIT — 使用回顾
  6. XAML中格式化日期
  7. Javascript闭包——懂不懂由你,反正我是懂了
  8. 图解MapReduceMapReduce整体流程图
  9. pat1043. Is It a Binary Search Tree (25)
  10. Hibernate查询缓存