转载 调用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,一经查实,立即删除!

相关文章

C# 数值和字符串之间的相互转换

文章目录方法用例ToString&#xff08;&#xff09;方法Parse&#xff08;&#xff09;方法博主写作不容易&#xff0c;孩子需要您鼓励 万水千山总是情 , 先点个赞行不行 方法 ToString&#xff08;&#xff09;方法&#xff1a;数值类型的 ToString&#xff08;&#xff…

LeetCode Reverse Words in a String III

原题链接在这里&#xff1a;https://leetcode.com/problems/reverse-words-in-a-string-iii/#/description 题目&#xff1a; Given a string, you need to reverse the order of characters in each word within a sentence while still preserving whitespace and initial wo…

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

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

kali开启ssh

修改 vi /etc/ssh/sshd_config 1.将 permitrootlogin 前面的注释去掉,并且后面改为yes 如果没有则添加permitrootlogin yes 2.将#PasswordAuthentication no的注释去掉&#xff0c;并且将NO修改为YES //kali中默认是yes 3.按Esc , 同时按shift和冒号键 ,输入wq &#xff0c;回…

C# 引用类型与值类型转换-装箱和拆箱

文章目录简介用例装箱拆箱博主写作不容易&#xff0c;孩子需要您鼓励 万水千山总是情 , 先点个赞行不行 简介 拆箱就是把 “引用” 类型转化为 “值” 类型&#xff1b; 装箱就是把 “值” 类型转化为 “引用” 类型&#xff1b; 装箱与拆箱是数据类型转换的一种特殊应用…

XVID基本参数解析

XVID&#xff0c;X264等是MPEG4、H264标准的开源编码器&#xff0c;其中X264只有编码部分&#xff0c;解码部分需要FFMPEG完成&#xff1b;XVID有编解码部分&#xff0c;其中解码亦可以利用FFMPEG中的MPEG4完成解码。视频压缩算法的计算复杂度&#xff0c;都是比较高的。其中具…

自己整理的openresty安装步骤

这几天一直在研究对webapi的限流和名单的问题&#xff0c;于是看了开涛博客的方案&#xff0c;于是就用到了openresty&#xff0c;一个把Nginx和lua集成的东西。 下面就是整理的安装方案&#xff08;简单使用基本可以这么安装&#xff09; 下载openresty&#xff08;centos上下…

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

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

C#赋值运算符及解析

文章目录博主写作不容易&#xff0c;孩子需要您鼓励 万水千山总是情 , 先点个赞行不行 赋值运算符对运算符右边的操作式求值&#xff0c;并用该值设置运算符左边的变量操作式。赋值运算符主要有简单赋值及复合赋值运算符&#xff1b;可以放在赋值运算符左边的对象类型是变量…

mysql 案例 ~ pt修复工具的使用

简介:今天咱们来聊聊PT修复工具pt-table-sync 注意事项&#xff1a; 1 表要有主键或者唯一键 2 针对每一个chunk加的是for update锁 3 修复过程中不能容忍从库延迟 如果从库延迟太多&#xff0c;pt-table-sync会长期持有对chunk的for update锁&#xff0c;然后等待从库的…

mpeg2,mpeg4,h264编码标准的异同

1、宏块匹配像素精度&#xff1a; MPEG2中&#xff0c;运动估计的精度是1/2的像素&#xff0c;通过线性插值实现&#xff08;可能有简单修正&#xff09;&#xff1b; H264和MPEG4 都可以支持1/4像素的精度 2、参考帧的数量&#xff1a;MPEG2&#xff0c;MPEG4的P帧只能有一帧…

四十岁学编程(一)

有时想想&#xff0c;人生还真的是曲折&#xff0c;人到中年了&#xff0c;我才开始学编程。 这一学&#xff0c;就是三年多&#xff0c;我居然坚持了下来。 更没想到的是&#xff0c;三年后的我居然有勇气投简历求职前端&#xff0c;虽然面试前战战兢兢。 很多时候&#xff0c…

01_SQlite数据库简介

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

GNU Make 使用手册(中译版)

翻译&#xff1a;于凤昌译者注&#xff1a;本人在阅读Linux源代码过程中发现如果要全面了解Linux的结构、理解Linux的编程总体设计及思想必须首先全部读通Linux源代码中各级的Makefile文件。目前&#xff0c;在网上虽然有一些著作&#xff0c;但都不能全面的解释Linux源代码中各…

基础10 多进程、协程(multiprocessing、greenlet、gevent、gevent.monkey、select、selector)...

1.多进程实现方式&#xff08;类似于多线程&#xff09; 1 import multiprocessing2 import time,threading3 4 def thread_run():#定义一个线程函数5 print("我是子线程%s" %threading.get_ident()) #threading.get_ident()函数获取当前线程的id6 def run(name…

C#比较运算符及解析

文章目录博主写作不容易&#xff0c;孩子需要您鼓励 万水千山总是情 , 先点个赞行不行 比较运算符得出的结果是逻辑型&#xff08;bool&#xff09;&#xff0c;即 True 或 False 。 比较运算符又称关系运算符&#xff0c;我们可以把它理解为一种判断&#xff0c;判断的结果…

开发人员MySQL调优-理论篇

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

Java基础之反射机制

Java反射机制 反射机制是什么 反射机制是在运行状态中&#xff0c;对于任意一个类&#xff0c;都能够知道这个类的所有属性和方法&#xff1b;对于任意一个对象&#xff0c;都能够调用它的任意一个方法和属性&#xff1b;这种动态获取的信息以及动态调用对象的方法的功能称为ja…

C#逻辑运算符及解析

文章目录博主写作不容易&#xff0c;孩子需要您鼓励 万水千山总是情 , 先点个赞行不行 逻辑运算符用于连接一个或多个条件&#xff0c;判断这些条件是否成立。 &#xff23;&#xff03;的逻辑运算符可以分为两类&#xff1a; “&#xff06;” “&#xff5c;” “&…

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

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