[备份代码使用,未优化]
#include "MyEncodeYUV.h"
#include
#define __STDC_CONSTANT_MACROS
#include
#include
#include
int flush_encoder(AVFormatContext *fmt_ctx,unsigned 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) {
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("Flush Encoder: Succeed to encode 1 frame!\tsize:%5d\n",enc_pkt.size);
/* mux encoded frame */
ret = av_write_frame(fmt_ctx, &enc_pkt);
if (ret < 0)
break;
}
return ret;
}
int ecode_main(char * yuvFilePath,char *outFilePath,int videoWidth,int videoHeight,long num,int videoInfo[])
{
AVFormatContext* pFormatCtx;
AVOutputFormat* fmt;
AVStream* video_st;
AVCodecContext* pCodecCtx;
AVCodec* pCodec;
AVPacket pkt;
uint8_t* picture_buf;
AVFrame* pFrame;
int picture_size;
int y_size;
int framecnt=0;
FILE *in_file = fopen(yuvFilePath, "rb"); //Input raw YUV data
int in_w=videoWidth,in_h=videoHeight; //Input data's width and height
int framenum=num; //Frames to encode
//const char* out_file = "src01.h264"; //Output Filepath
//const char* out_file = "src01.ts";
//const char* out_file = "src01.hevc";
const char* out_file =outFilePath;
avcodec_register_all();
av_register_all();
//Method1.
pFormatCtx = avformat_alloc_context();
//Guess Format
fmt = av_guess_format(NULL, out_file, NULL);
if (NULL==fmt) {
// av_log(s, AV_LOG_ERROR, "Requested output format '%s' is not a suitable output format\n", format);
printf("========fmt===is null==\n");
return -1;
}else
{
printf("=======yes ==ok!");
}
pFormatCtx->oformat = fmt;
//Method 2.
//avformat_alloc_output_context2(&pFormatCtx, NULL, NULL, out_file);
//fmt = pFormatCtx->oformat;
printf("==========open output====");
//Open output URL
if (avio_open(&pFormatCtx->pb,out_file, AVIO_FLAG_READ_WRITE) < 0){
printf("Failed to open output file! \n");
return -1;
}
printf("==========open output=1===\n");
// int videoCodec[8];
// videoCodec[0]=pCodecCtx->pix_fmt;
// videoCodec[1]=pCodecCtx->time_base.num;
// videoCodec[2]=pCodecCtx->time_base.den;
// videoCodec[3]=pCodecCtx->bit_rate;
// videoCodec[4]=pCodecCtx->gop_size;
// videoCodec[5]=pCodecCtx->qmin;
// videoCodec[6]=pCodecCtx->qmax;
// videoCodec[7]=pCodecCtx->qcompress;
video_st = avformat_new_stream(pFormatCtx, 0);
video_st->time_base.num = 1;
video_st->time_base.den = 25;
// video_st->metadata;
if (video_st==NULL){
return -1;
}
//Param that must set
pCodecCtx = video_st->codec;
pCodecCtx->codec_id =AV_CODEC_ID_H264;
// 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 =videoInfo[3];
pCodecCtx->gop_size=videoInfo[4];
//H264
// ctx->me_range = 16;
// ctx->max_qdiff = 4;
// pCodecCtx->me_range = 16;
// pCodecCtx->max_qdiff = 4;
pCodecCtx->qmin =3;
pCodecCtx->qmax =30;
pCodecCtx->qcompress =1;
//Optional Param
// pCodecCtx->max_b_frames=codecCtx->max_b_frames;
printf("=222video info==video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d=====bit_rate:%d==gop_size:%d\n==compress:%f",
pCodecCtx->width, pCodecCtx->height, pCodecCtx->pix_fmt,
pCodecCtx->time_base.num, pCodecCtx->time_base.den,
pCodecCtx->sample_aspect_ratio.num, pCodecCtx->sample_aspect_ratio.den,pCodecCtx->bit_rate,pCodecCtx->gop_size, pCodecCtx->qcompress );
// Set Option
AVDictionary *param = 0;
//H.264
if(pCodecCtx->codec_id == AV_CODEC_ID_H264) {
av_dict_set(¶m, "preset", "slow", 0);
av_dict_set(¶m, "tune", "zerolatency", 0);
//av_dict_set(¶m, "profile", "main", 0);
}
//H.265
if(pCodecCtx->codec_id == AV_CODEC_ID_H265){
av_dict_set(¶m, "preset", "ultrafast", 0);
av_dict_set(¶m, "tune", "zero-latency", 0);
}
//Show some Information
av_dump_format(pFormatCtx, 0, out_file, 1);
printf("==========open output==2==\n");
pCodec = avcodec_find_encoder(pCodecCtx->codec_id);
printf("==========open output==3==\n");
if (!pCodec){
printf("Can not find encoder! \n");
return -1;
}
if (avcodec_open2(pCodecCtx, pCodec,¶m) < 0){
printf("Failed to open encoder! \n");
return -1;
}
//Failed to read raw data
printf("==========open output==4==\n");
pFrame = av_frame_alloc();
picture_size = avpicture_get_size(pCodecCtx->pix_fmt, pCodecCtx->width, pCodecCtx->height);
picture_buf = (uint8_t *)av_malloc(picture_size);
avpicture_fill((AVPicture *)pFrame, picture_buf, pCodecCtx->pix_fmt, pCodecCtx->width, pCodecCtx->height);
printf("==========open output==5==\n");
//Write File Header
// avformat_write_header(pFormatCtx,NULL);
printf("=======avformat_write_header===%d\n",avformat_write_header(pFormatCtx,NULL));
av_new_packet(&pkt,picture_size);
y_size = pCodecCtx->width * pCodecCtx->height;
printf("=======av_new_packet======width:%d,height:%d \n",pCodecCtx->width,pCodecCtx->height);
for (int i=0; i //Read raw YUV data printf("=======Read raw YUV data===%d\n",i); if(feof(in_file)){ break; } else if (fread(picture_buf, 1, y_size*3/2, in_file) <= 0){ printf("Failed to read raw data! \n"); return -1; } pFrame->data[0] = picture_buf; // Y pFrame->data[1] = picture_buf+ y_size; // U pFrame->data[2] = picture_buf+ y_size*5/4; // V //PTS pFrame->pts=i; int got_picture=0; //Encode int ret = avcodec_encode_video2(pCodecCtx, &pkt,pFrame, &got_picture); if(ret < 0){ printf("Failed to encode! \n"); return -1; } if (got_picture==1){ printf("Succeed to encode frame: %5d\tsize:%5d\n",framecnt,pkt.size); framecnt++; pkt.stream_index = video_st->index; ret = av_write_frame(pFormatCtx, &pkt); av_free_packet(&pkt); } } //Flush Encoder printf("=======flush_encoder===\n"); int ret = flush_encoder(pFormatCtx,0); if (ret < 0) { printf("Flushing encoder failed\n"); return -1; } //Write file trailer printf("=======av_write_trailer===\n"); av_write_trailer(pFormatCtx); printf("=======av_write_trailer==after=\n"); //Clean if (video_st){ avcodec_close(video_st->codec); av_free(pFrame); av_free(picture_buf); } avio_close(pFormatCtx->pb); avformat_free_context(pFormatCtx); fclose(in_file); printf("========encode yuv success!===\n"); return 0; }