//功能:将一张BMP位图作为数据源,利用FFMpeg编码出一个MPG的视频文件
#include <math.h>
extern "C"
{
#include "libavutil/imgutils.h"
#include "libavutil/opt.h"
#include "libavcodec/avcodec.h"
#include "libavutil/mathematics.h"
#include "libavutil/samplefmt.h"
#include "libswscale/swscale.h"
}
#define INBUF_SIZE 4096
#define AUDIO_INBUF_SIZE 20480
#define AUDIO_REFILL_THRESH 4096
/*
* Video encoding example
*/
static void video_encode_example(const char *filename, int codec_id)
{
AVCodec *codec;
AVCodecContext *c= NULL;
int i = 0;
int out_size = 0;
int outbuf_size = 0;
int inbuf_size = 0;
FILE *f, *InputFileHead;
AVFrame *picture;
uint8_t *outbuf, *inbuf;
int had_output=0;
int index = 0;
printf("Video encoding\n");
/* find the mpeg1 video encoder */
codec = avcodec_find_encoder((CodecID)codec_id);
if (!codec) {
fprintf(stderr, "codec not found\n");
exit(1);
}
c = avcodec_alloc_context3(codec);
picture= avcodec_alloc_frame(); //这里分配了帧
/* put sample parameters */
c->bit_rate = 400000*2;
/* resolution must be a multiple of two */
c->width = 640;//1920;//352;
c->height = 480;//1080;//288;
/* frames per second */
c->time_base.num =1; //= (AVRational){1,25};
c->time_base.den = 24;
c->gop_size = 10; /* emit one intra frame every ten frames */
c->max_b_frames=1;
c->pix_fmt = PIX_FMT_YUV420P;
//下面的参数影响着编码出视频的质量,没有这两个参数视频会有些模糊的马赛克,加入这两个参数值就没有了
//Q值最小值
c->qmin=1;
//Q值最大值.
c->qmax=5;
if(codec_id == CODEC_ID_H264)
av_opt_set(c->priv_data, "preset", "slow", 0);
/* open it */
if (avcodec_open2(c, codec, NULL) < 0) {
fprintf(stderr, "could not open codec\n");
exit(1);
}
f = fopen(filename, "wb");
if (!f) {
fprintf(stderr, "could not open %s\n", filename);
exit(1);
}
//编码一张位图图像
InputFileHead = fopen("C:\\a.bmp","r"); //注意:这里的位图文件路径设置成你的文件,同时注意位图文件的宽高也作同样的修改
/* alloc image and output buffer */
outbuf_size = 100000 + 12 * c->width * c->height;
outbuf = (uint8_t *)malloc(outbuf_size);
//分配内存大小
inbuf_size = c->width * c->height * 3;
inbuf = (uint8_t *)malloc(inbuf_size);
/* the image can be allocated by any means and av_image_alloc() is
* just the most convenient way if av_malloc() is to be used */
av_image_alloc(picture->data, picture->linesize,
c->width, c->height, c->pix_fmt, 1);
//----------------------------------------------------------------------------------------------
//这里用来加载一张图片来进行编码
fseek(InputFileHead, 54, SEEK_SET);
fread(inbuf, 1, inbuf_size, InputFileHead);
struct SwsContext *sws;
//下面的位图转完是倒立的
uint8_t *rgb_src[3]= {inbuf, NULL, NULL};
int rgb_stride[3]={3*c->width, 0, 0};
sws= sws_getContext(c->width, c->height, PIX_FMT_RGB24, c->width, c->height, PIX_FMT_YUV420P, 2, NULL, NULL, NULL);
sws_scale(sws, rgb_src, rgb_stride, 0, c->height, picture->data, picture->linesize);
//----------------------------------------------------------------------------------------------
/* encode 1 second of video */
while(i<350/*feof(InputFile)*/)
{
fflush(stdout);
/* encode the image */
out_size = avcodec_encode_video(c, outbuf, outbuf_size, picture);
had_output |= out_size;
printf("encoding frame %3d (size=%5d)\n", i++, out_size);
fwrite(outbuf, 1, out_size, f);
}
/* get the delayed frames */
for(; out_size || !had_output; i++) {
fflush(stdout);
out_size = avcodec_encode_video(c, outbuf, outbuf_size, NULL);
had_output |= out_size;
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);
av_free(c);
//av_free(picture->data[0]);
av_free(picture);
printf("\n");
}
int main(int argc, char **argv)
{
/* register all the codecs */
avcodec_register_all();
video_encode_example("D:\\tmp.mpg", CODEC_ID_MPEG1VIDEO);
return 0;
}
要源码的留下邮箱