资源简介

FFMPEG工程浩大,可以参考的书籍又不是很多,因此很多刚学习FFMPEG的人常常感觉到无从下手。因此特地分离出了一个简单的视频编码器供学习之用。 该视频编码器实现了YUV420P像素数据编码为H.264码流 尽管该视频编码器的代码十分简单,但是几乎包含了使用FFMPEG编码一个视频所有必备的API。十分适合FFmpeg的初学者。 工程基于VC2010。 使用了2014.5.6版本的FFmpeg类库。 注:这是修正版,增加了flush_encoder()函数

资源截图

代码片段和文件信息

/* 
 *最简单的基于FFmpeg的视频编码器
 *Simplest FFmpeg Video Encoder
 *
 *雷霄骅 Lei Xiaohua
 *leixiaohua1020@126.com
 *中国传媒大学/数字电视技术
 *Communication University of China / Digital TV Technology
 *http://blog.csdn.net/leixiaohua1020
 *
 *本程序实现了YUV像素数据编码为视频码流(H264,MPEG2,VP8等等)。
 *是最简单的FFmpeg视频编码方面的教程。
 *通过学习本例子可以了解FFmpeg的编码流程。
 *This software encode YUV420P data to H.264 bitstream.
 *It‘s the simplest video encoding software based on FFmpeg. 
 *Suitable for beginner of FFmpeg 
 */

#include “stdafx.h“

extern “C“
{
#include “libavcodec\avcodec.h“
#include “libavformat\avformat.h“
#include “libswscale\swscale.h“
};


int flush_encoder(AVFormatContext *fmt_ctxunsigned int stream_index)
{
int ret;
int got_frame;
AVPacket enc_pkt;
if (!(fmt_ctx->streams[stream_index]->codec->codec->capabilities &
CODEC_CAP_DELAY))
return 0;
while (1) {
printf(“Flushing stream #%u encoder\n“ stream_index);
//ret = encode_write_frame(NULL stream_index &got_frame);
enc_pkt.data = NULL;
enc_pkt.size = 0;
av_init_packet(&enc_pkt);
ret = avcodec_encode_video2 (fmt_ctx->streams[stream_index]->codec &enc_pkt
NULL &got_frame);
av_frame_free(NULL);
if (ret < 0)
break;
if (!got_frame)
{ret=0;break;}
printf(“编码成功1帧!\n“);
/* mux encoded frame */
ret = av_write_frame(fmt_ctx &enc_pkt);
if (ret < 0)
break;
}
return ret;
}

int _tmain(int argc _TCHAR* argv[])
{
AVFormatContext* pFormatCtx;
AVOutputFormat* fmt;
AVStream* video_st;
AVCodecContext* pCodecCtx;
AVCodec* pCodec;

uint8_t* picture_buf;
AVframe* picture;
int size;

FILE *in_file = fopen(“src01_480x272.yuv“ “rb“); //视频YUV源文件 
int in_w=480in_h=272;//宽高
int framenum=50;
const char* out_file = “src01.h264“; //输出文件路径

av_register_all();
//方法1.组合使用几个函数
pFormatCtx = avformat_alloc_context();
//猜格式
fmt = av_guess_format(NULL out_file NULL);
pFormatCtx->oformat = fmt;

//方法2.更加自动化一些
//avformat_alloc_output_context2(&pFormatCtx NULL NULL out_file);
//fmt = pFormatCtx->oformat;


//注意输出路径
if (avio_open(&pFormatCtx->pbout_file AVIO_FLAG_READ_WRITE) < 0)
{
printf(“输出文件打开失败“);
return -1;
}

video_st = av_new_stream(pFormatCtx 0);
if (video_st==NULL)
{
return -1;
}
pCodecCtx = video_st->codec;
pCodecCtx->codec_id = fmt->video_codec;
pCodecCtx->codec_type = AVMEDIA_TYPE_VIDEO;
pCodecCtx->pix_fmt = PIX_FMT_YUV420P;
pCodecCtx->width = in_w;  
pCodecCtx->height = in_h;
pCodecCtx->time_base.num = 1;  
pCodecCtx->time_base.den = 25;  
pCodecCtx->bit_rate = 400000;  
pCodecCtx->gop_size=250;
//H264
//pCodecCtx->me_range = 16;
//pCodecCtx->max_qdiff = 4;
pCodecCtx->qmin = 10;
pCodecCtx->qmax = 51;
//pCodecCtx->qcompress = 0.6;
//输出格式信息
av_dump_format(pFormatCtx 0 out_file 1);

pCodec = avcodec_find_encoder(pCodecCtx->codec_id);
if (!pCodec)
{
printf(“没有找到合适的编码器!\n“);
return -1;
}
if (avcodec_open2(pCodecCt

评论

共有 条评论