FFMPEG库压缩视频

#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 秒.


转帖:http://bbs.csdn.net/topics/50296853

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值