码迷,mamicode.com
首页 > 其他好文 > 详细

转:ffmpeg压缩视频示例

时间:2015-05-10 11:14:36      阅读:158      评论:0      收藏:0      [点我收藏+]

标签:

#ifndef   RECORD_H 
#define   RECORD_H

#include   "avcodec.h " 
#include   "avformat.h "

#include   <stdio.h>

class   QRecord 

public: 
static   int   Open(const   char   *,int,int,int); 
static   int   AddFrame(unsigned   char*,unsigned   char*,unsigned   char*); 
static   int   Close();

        static   AVCodecContext   *c; 
        static   int   out_size,   outbuf_size; 
        static   FILE   *f; 
        static   AVFrame   *picture; 
        static   uint8_t   *outbuf; 
};

#endif


================================

 

#include   "Record.h "

#include   <stdlib.h>

AVCodecContext   *QRecord::c=NULL; 
int   QRecord::out_size,   QRecord::outbuf_size; 
FILE   *QRecord::f; 
AVFrame   *QRecord::picture; 
uint8_t   *QRecord::outbuf;

int   QRecord::Open(const   char   *filename,int   width,int   height,int   frame_rate) 

AVCodec   *codec;

av_register_all();

        codec   =   avcodec_find_encoder(CODEC_ID_MPEG1VIDEO); 
        if   (!codec)   { 
fprintf(stderr,   "codec   not   found\n "); 
                return   -1; 
        }

        c=   avcodec_alloc_context(); 
        picture=   avcodec_alloc_frame(); 
        
        /*   put   sample   parameters   */ 
        c-> bit_rate   =   400000; 
        /*   resolution   must   be   a   multiple   of   two   */ 
        c-> width   =   width;     
        c-> height   =   height; 
        /*   frames   per   second   */ 
        c-> frame_rate   =   frame_rate;     
        c-> frame_rate_base=   1; 
        c-> gop_size   =   10;   /*   emit   one   intra   frame   every   ten   frames   */ 
        c-> max_b_frames=1;

        /*   open   it   */ 
        if   (avcodec_open(c,   codec)   <   0)   { 
                fprintf(stderr,   "could   not   open   codec\n "); 
                return   -1; 
        } 
        
        /*   the   codec   gives   us   the   frame   size,   in   samples   */

        f   =   fopen(filename,   "w "); 
        if   (!f)   { 
                fprintf(stderr,   "could   not   open   %s\n ",   filename); 
                return   -1; 
        } 
        
        /*   alloc   image   and   output   buffer   */ 
        outbuf_size   =   1000000;//? 
        outbuf   =(uint8_t*)   malloc(outbuf_size); 
        //size   =   c-> width   *   c-> height; 
        //picture_buf   =(uint8_t*)   malloc((size   *   3)   /   2);   /*   size   for   YUV   420   */

        picture-> linesize[0]   =   c-> width; 
        picture-> linesize[1]   =   c-> width   /   2; 
        picture-> linesize[2]   =   c-> width   /   2;

return   0; 
}

int   QRecord::AddFrame(unsigned   char   *y,unsigned   char   *u,unsigned   char   *v) 

        picture-> data[0]   =   y; 
        picture-> data[1]   =   u; 
        picture-> data[2]   =   v;

out_size   =   avcodec_encode_video(c,   outbuf,   outbuf_size,   picture); 
//printf( "encoding   frame   %3d   (size=%5d)\n ",   i,   out_size); 
fwrite(outbuf,   1,   out_size,   f);

return   0; 
}

int   QRecord::Close() 

while(out_size)   { 
out_size   =   avcodec_encode_video(c,   outbuf,   outbuf_size,   NULL); 
//printf( "write   frame   %3d   (size=%5d)\n ",   i,   out_size); 
fwrite(outbuf,   1,   out_size,   f); 
}

/*   add   sequence   end   code   to   have   a   real   mpeg   file   */ 
outbuf[0]   =   0x00; 
outbuf[1]   =   0x00; 
outbuf[2]   =   0x01; 
outbuf[3]   =   0xb7; 
fwrite(outbuf,   1,   4,   f); 
fclose(f); 
free(outbuf);

avcodec_close(c); 
free(c); 
free(picture); 
//printf( "\n ");

return   0; 
}


============================================


使用ffmpeg的库编码mpeg的技术总结报告 
Sun   Gang,   2003-11-21

一   .   概述 
Ffmpeg是一个优秀的基于LGPL协议的视频/音频转换器.目前已经有很多多媒体应用软件使用它来作为编码器,如Xine,Mplayer,Xbox   Media   Player等.它也能用于从视频/音频源来抓取数据保存为视频音频文件.Ffmpeg还能从各种采样率来开始转换,能够通过高品质的多相滤波技术来实现放大缩小,频域相域的变换等. 
这里,我们使用Ffmpeg来实现mpeg的编码过程. 
二   .   摄像头的视频捕捉调用相关说明(即使用Video4Linux   API获取图象的调用说明) 
#include   <videodev.h> 
struct   video_window   vid_win; 
struct   video_capability   vid_caps; 
struct   video_picture   vid_pic; 
struct   video_mbuf   mbuf;

1.   打开设备 
int   dev   =   open( "/dev/video0 ",O_RDWR);

2.   获取相关参数 
ioctl   (dev,   VIDIOCGCAP,   &vid_caps); 
ioctl   (dev,   VIDIOCGWIN,   &vid_win); 
ioctl   (dev,   VIDIOCGPICT,   &vid_pic);

//Check   to   see   if   we   can   use   mmap 
if(0   ==   ioctl(dev,VIDIOCGMBUF,&mbuf))...;

//Check   to   see   if   this   camera   uses   MJPEG 
if(vid_caps.type   &   VID_TYPE_MJPEG_ENCODER)...;

3.   设置相关参数 
ioctl(dev,   VIDIOCSPICT,   &vid_pic); 
ioctl(dev,   VIDIOCSWIN,     &vid_win);

4.   获取图象数据 
read   (dev,   picbuff,   size); 
//至此,图象数据存放在picbuff中 
三   .   QRecord编码接口说明(编码为MPEG1   System   format,   其中视频采用mpeg1video,   音频采用MP2) 
定义如下 
class   QRecord 

public: 
//encode   mpeg1   file   with   ffmpeg   library 
static   int   audio_input_frame_size; 
static   AVOutputFormat   *fmt; 
static   AVFormatContext   *oc; 
static   AVStream   *audio_st,*video_st; 
static   int   Open(const   char*   filename,int   width,int   height,int   frame_rate,bool   audio_on=false); 
static   int   AddVideoFrame(uint8_t*   y,uint8_t*   u,uint8_t*   v); 
static   int   AddAudioFrame(int16_t*   inbuf); 
static   int   Close();

//for   decompress   Jpeg 
static   int   DecompressJpeg(const   char*   input,unsigned   char*   rgbbuffer); 
//for   rgb2yuv   convert 
static   int   count   ; 
static   float   RGBYUV02990[256],   RGBYUV05870[256],   RGBYUV01140[256]; 
static   float   RGBYUV01684[256],   RGBYUV03316[256]; 
static   float   RGBYUV04187[256],   RGBYUV00813[256]; 
static   void   InitRGB2YUVLookupTable(); 
static   int   RGB2YUV   (int   x_dim,   int   y_dim,   void   *bmp,   void   *y_out,   void   *u_out,   void   *v_out,   int   flip);

static   int   add_scanline_to_rgbbuffer(unsigned   char*   linebuffer,int   length,unsigned   char*   rgbbuffer); 
}; 
几个重要接口函数说明, 
QRecord::Open()   打开要存储文件,并初始化各项参数 
QRecord::AddVideoFrame()增加一帧视频数据,格式为YUV420P, 
QRecord::AddAudioFrame()增加一帧音频数据,格式为44.1KHz,16bits,2channels   PCM   data 
QRecord::Close()关闭文件,释放内存等.

四   .   编码速度测试报告 
测试数据为25张320X240,RGB24的图片文件,编码1000帧的各自需要时间如下: 
VIA   Cyrix   1G,   96M   ram为   39-42秒 
Intel   PIII-M   800M,   128M   ram   为6秒 
Intel   PIII   550M,128M   ram为10   秒.

转:ffmpeg压缩视频示例

标签:

原文地址:http://www.cnblogs.com/skyofbitbit/p/4491839.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!