转载 调用xvid 实现解码

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;//编码获得的帧长度

 


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/254366.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

创业感悟:技术兄弟为什么一直没有起来(1)

相信很多做技术的朋友&#xff0c;看到“人脉”两个字&#xff0c;就显得有些敏感&#xff0c;有人甚至产生一种“抵触”的心理。 因为在很多人的心中&#xff0c;会自动的把“人脉”和“关系”关联起来&#xff0c;会把“人脉”与“走后门”&#xff0c;甚至会和“酒桌文化”&…

京东入职一周感悟:4个匹配和4个观点

入职一周啦&#xff0c;随便写点。一、京东之缘1、我和京东之间的4点匹配Ⅰ技术2008年9月到2016年9月&#xff0c;一直坚持自学技术。京东&#xff0c;是一家商业化的互联网公司&#xff0c;有技术积淀&#xff0c;有发挥空间。作为技术人员&#xff0c;职业匹配。Ⅱ读书大学的…

01_SQlite数据库简介

转载于:https://www.cnblogs.com/ZHONGZHENHUA/p/7023014.html

开发人员MySQL调优-理论篇

2019独角兽企业重金招聘Python工程师标准>>> 修改字符集 查看字符集 show variables like character% show variables like %char% 上面的两个命令都可以&#xff0c;我一般使用的下面的&#xff0c;会出来如下几个字符集设定的选项&#xff1a; character_set_clie…

通过ProGet搭建一个内部的Nuget服务器

.NET Core项目完全使用Nuget 管理组件之间的依赖关系&#xff0c;Nuget已经成为.NET 生态系统中不可或缺的一个组件&#xff0c;从项目角度&#xff0c;将项目中各种组件的引用统统交给NuGet&#xff0c;添加组件/删除组件/以及更新组件即可一键完成&#xff0c;大大提升工作效…

unity官方教程-TANKS(一)

unity官方教程TANKS&#xff0c;难度系数中阶。跟着官方教程学习Unity&#xff0c;通过本教程你可以学会使用Unity开发游戏的基本流程。 一、环境 Unity 版本 > 5.2Asset Store 里面搜索 Tanks!Tutorial ,下载导入 二、项目设置 为了便于开发&#xff0c;很多时候我们选用的…

VS配置本地IIS以域名访问

1.IIS下配置自己的网站&#xff0c;添加主机名 2.修改hosts文件&#xff08;C://Windows/System32/drivers/etc&#xff09; 3.VS中配置项目Web服务器&#xff08;选择外部主机&#xff09; 转载于:https://www.cnblogs.com/zuimeideshi520/p/7028544.html

Spark RDD/Core 编程 API入门系列 之rdd实战(rdd基本操作实战及transformation和action流程图)(源码)(三)...

本博文的主要内容是&#xff1a; 1、rdd基本操作实战 2、transformation和action流程图 3、典型的transformation和action RDD有3种操作&#xff1a; 1、 Trandformation 对数据状态的转换&#xff0c;即所谓算子的转换 2、 Action 触发作业&#xff0c;即所谓得结果…

灯塔的出现给那些有想法,有能力而又缺乏资金的社区人士提供了一条途径

2019独角兽企业重金招聘Python工程师标准>>> 在上个月&#xff0c;BCH社区传出基于比特币现金的众筹平台Lighthouse&#xff08;灯塔&#xff09;正在复活的消息&#xff0c;并且有网友在论坛上贴出了部分网站图片。当消息被证实为真&#xff0c;官网和项目的审核细…

PID 算法理解

PID 算法 使用环境&#xff1a;受到外界的影响不能按照理想状态发展。如小车的速度不稳定的调节&#xff0c;尽快达到目标速度。 条件&#xff1a;闭环系统->有反馈 要求&#xff1a;快准狠 分类&#xff1a;位置式、增量式 增量式 输入&#xff1a;前次速度、前前次速度、前…

三种方式在CentOS 7搭建KVM虚拟化平台

KVM 全称是基于内核的虚拟机&#xff08;Kernel-based Virtual Machine&#xff09;&#xff0c;它是一个 Linux的一个内核模块&#xff0c;该内核模块使得 Linux变成了一个Hypervisor&#xff1a;它由 Quramnet开发&#xff0c;该公司于 2008年被 Red Hat 收购 KVM的整体结构&…

(五)EasyUI使用——datagrid数据表格

DataGrid以表格形式展示数据&#xff0c;并提供了丰富的选择、排序、分组和编辑数据的功能支持。DataGrid的设计用于缩短开发时间&#xff0c;并且使开发人员不需要具备特定的知识。它是轻量级的且功能丰富。单元格合并、多列标题、冻结列和页脚只是其中的一小部分功能。具体功…

拾取模型的原理及其在THREE.JS中的代码实现

1. Three.js中的拾取 1.1. 从模型转到屏幕上的过程说开 由于图形显示的基本单位是三角形&#xff0c;那就先从一个三角形从世界坐标转到屏幕坐标说起&#xff0c;例如三角形abc 乘以模型视图矩阵就进入了视点坐标系&#xff0c;其实就是相机所在的坐标系&#xff0c;如下图&am…

旧知识打造新技术--AJAX学习总结

AJAX是将旧知识在新思想的容器内进行碰撞产生的新技术&#xff1a;推翻传统网页的设计技术。改善用户体验的技术。 学习AJAX之初写过一篇《与Ajax的初次谋面》。当中都仅仅是一些自己浅显的理解&#xff0c;这次就总结一下它在历史长河中的重要地位。 【全】 AJAX全称为Asnychr…

redis(一)--认识redis

Redis官网对redis的定义是&#xff1a;“Redis is an open source, BSD licensed, advanced key-value cache and store”&#xff0c;可以看出&#xff0c;Redis是一种键值系统&#xff0c;可以用来缓存或存储数据。Redis是“Remote Dictionary Server”&#xff08;远程字典服…

SQLSEVER 中的那些键和约束

SQL Server中有五种约束类型&#xff0c;各自是 PRIMARY KEY约束、FOREIGN KEY约束、UNIQUE约束、DEFAULT约束、和CHECK约束。查看或者创建约束都要使用到 Microsoft SQL Server Managment Studio。1. PRIMARY KEY约束 在表中常有一列或多列的组合&#xff0c;其值能唯一标识表…

Confluence 6 手动备份站点

2019独角兽企业重金招聘Python工程师标准>>> Confluence 被配置自动备份数据&#xff0c;使用压缩的 XML 格式。同时你也可以通过 Confluence 的 管理员控制台&#xff08;Administration Console&#xff09;手动进行备份。 你需要具有 System Administrator 权限才…

第六篇:python基础之文件处理

第六篇&#xff1a;python基础之文件处理 阅读目录 一.文件处理流程二.基本操作2.1 文件操作基本流程初探2.2 文件编码2.3 文件打开模式2.4 文件内置函数flush2.5 文件内光标移动2.6 open函数详解2.7 上下文管理2.8 文件的修改一.文件处理流程 打开文件&#xff0c;得到文件句柄…

前端每日实战:56# 视频演示如何用纯 CSS 描述程序员的生活

效果预览 按下右侧的“点击预览”按钮可以在当前页面预览&#xff0c;点击链接可以全屏预览。 https://codepen.io/comehope/pen/YvYVvY 可交互视频 此视频是可以交互的&#xff0c;你可以随时暂停视频&#xff0c;编辑视频中的代码。 请用 chrome, safari, edge 打开观看。 ht…