资源描述
1. 注册所有容器格式和CODEC:av_register_all()
2. 打开文件:av_open_input_file()
3. 从文件中提取流信息:av_find_stream_info()
4. 穷举所有的流,查找其中种类为CODEC_TYPE_VIDEO
5. 查找对应的解码器:avcodec_find_decoder()
6. 打开编解码器:avcodec_open()
7. 为解码帧分配内存:avcodec_alloc_frame()
8. 不停地从码流中提取出帧数据:av_read_frame()
9. 判断帧的类型,对于视频帧调用:avcodec_decode_video()
10. 解码完后,释放解码器:avcodec_close()
11. 关闭输入文件:av_close_input_file()
//X264结束
//********************************************//
//********************************************//
//********************************************//
//ffmpeg开始
AVFormatContext * oc = NULL;
AVOutputFormat * fmt;
AVStream * video_st = NULL;
double video_pts = 0;
uint8_t * video_outbuf = NULL;
uint8_t * picture_buf = NULL;
AVFrame * picture = NULL;
AVCodecContext * c = NULL;
AVCodec * codec = NULL;
AVPacket pkt;
int size = 0;
const char * testfilename = "test2.h264";
void InitFFmpeg()
{
av_register_all();////1. 注册所有容器格式和CODEC:av_register_all()
avcodec_register_all();////
oc = avformat_alloc_context();
fmt = av_guess_format(NULL, testfilename, NULL);
TRACE("fmt = %d\n", fmt);
oc->oformat = fmt;
memcpy(oc->filename, testfilename, sizeof(oc->filename));
video_st = NULL;
video_st = avformat_new_stream(oc, 0);
c = video_st->codec;
c->codec_id = fmt->video_codec;
c->codec_type = AVMEDIA_TYPE_VIDEO; 4. 穷举所有的流,查找其中种类为
c->bit_rate = SPEED_RATE * 1024;
c->width = 1920;
c->height = 1080;
c->time_base.num = 1;
c->time_base.den = 25;
c->gop_size = 25;
c->qmin = 10;
c->qmax = 51;
c->pix_fmt = PIX_FMT_YUV420P;
c->max_b_frames = 01;
//av_set_parameters(oc, NULL);
av_opt_set(c->priv_data, "preset", "superfast", 0);
av_opt_set(c->priv_data, "tune", "zerolatency", 0);
av_dump_format(oc, 0, filename, 1);
codec = avcodec_find_encoder(c->codec_id);///// 5. 查找对应的解码器
avcodec_open2(c, codec , NULL); 6. 打开编解码器:avcodec_open()
picture = avcodec_alloc_frame();7. 为解码帧分配内存
size = avpicture_get_size(c->pix_fmt, 1920, 1080);
picture_buf = (uint8_t*)av_malloc(DEFAULT_BUFSIZE);
if (!(oc->oformat->flags & AVFMT_RAWPICTURE))
{
video_outbuf = (uint8_t*)av_malloc(DEFAULT_SIZE);
}
avpicture_fill((AVPicture*)picture, picture_buf, c->pix_fmt, c->width, c->height);
#if WRITEDATATOFILE
if (Videofile == NULL)
{
Videofile = fopen("test.264", "wb+");
}
#endif
}
void FFmpegEncode(uint8_t * buf, unsigned int bufsize, unsigned int width, unsigned int height)
{
decodeStart = clock();
memcpy(picture_buf, buf, bufsize);
picture->data[0] = picture_buf; // Y
picture->data[2] = picture_buf + DEFAULT_SIZE; // V
picture->data[1] = picture_buf + DEFAULT_SIZE * 5 / 4; // U
av_init_packet(&pkt);
if (oc->oformat->flags & AVFMT_RAWPICTURE)
{
pkt.data = (uint8_t*)picture;
pkt.size = sizeof(AVPicture);
}
else
{
int out_size = avcodec_encode_video(c, video_outbuf, DEFAULT_SIZE, picture); /////9判断帧的类型,对于视频帧调用
int got_size = 0;
//int out_size = avcodec_encode_video2(c, &pkt, picture, &got_size);
TRACE("%d\n", out_size);
if (out_size > 0)
{
pkt.data = video_outbuf;
pkt.size = out_size;
//ret = av_write_frame(oc, &pkt);
#if WRITEDATATOFILE
fwrite(pkt.data, 1, pkt.size, Videofile);
#endif
}
}
decodeEnd = clock();
TRACE("decode use time is %d ms\n", decodeEnd - decodeStart);
#if STREAMSENDTOVLC
void RptPack(byte *buf, int size);
if (pkt.data != NULL)
RptPack(pkt.data, pkt.size);
#endif
}
void DeInitFFmpeg()
{
if (video_st)
{
avcodec_close(video_st->codec); ////10. 解码完后,释放解码器 av_free(picture);
av_free(video_outbuf);
}
av_write_trailer(oc);
for (int i = 0; i < oc->nb_streams; i++)
{
av_freep(&oc->streams[i]->codec);
av_freep(&oc->streams[i]);
}
if (!(fmt->flags & AVFMT_NOFILE))
{
//url_fclose(oc->pb);
}
av_free(oc); 11. 关闭输入文件:av_close_input_file()
}
//ffmpeg结束
//********************************************//
//********************************************//
//********************************************//
X264bianmaguocheng
展开阅读全文