#include<iostream>
extern "C"
{
#include"libavutil\imgutils.h"
#include"libavutil\samplefmt.h"
#include"libavformat\avformat.h"
#include"libavutil\opt.h"
#include<libavformat/avformat.h>
#include<libswscale/swscale.h>
#include <libswresample/swresample.h>
}
char errorbuf[1024];
AVCodec *Encodec = NULL; //编解码器1
AVCodecContext *Enc = NULL; //编码的
void SaveH264(AVPacket * packet)
{
FILE *fpSave;
if ((fpSave = fopen("BB.h264", "wb")) == NULL) //h264保存的文件名
{
std::cout << "fopen SaveH264 NO";
return;
}
fwrite(packet->data, 1, packet->size, fpSave);//写数据到文件中
fclose(fpSave);
}
int main()
{
static int i = 0;
av_register_all();
avcodec_register_all();
//fps每秒25帧
int fps = 25;
Encodec = avcodec_find_encoder(AV_CODEC_ID_H264);
if (!Encodec)
{
printf("avcodec_find_encoder AV_CODEC_ID_H264 failed!\n");
exit(0);
}
Enc = avcodec_alloc_context3(Encodec);
if (!Enc)
{
printf("avcodec_alloc_context3 failed!\n");
exit(0);
}
//设置编码器上下文参数
Enc->width = 1920;
Enc->height = 1080;
Enc->bit_rate = 576000;
AVRational r = { 1, 25 };//每秒25帧
Enc->time_base = r;
Enc->gop_size = 50;//GOP组
Enc->max_b_frames = 1;
Enc->pix_fmt = AV_PIX_FMT_YUV420P;//视频格式
av_opt_set(Enc->priv_data, "preset", "ultrafast", 0);
av_opt_set(Enc->priv_data, "tune", "stillimage,fastdecode,zerolatency", 0);
av_opt_set(Enc->priv_data, "x264opts", "crf=26:vbv-maxrate=728:vbv-bufsize=364:keyint=25", 0);
//Enc->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
int ret = avcodec_open2(Enc, Encodec, NULL);
if (ret < 0)
{
printf("avcodec_open2 failed!\n");
exit(0);
}
printf("avcodec_open2 success!\n");
AVFrame *pict = av_frame_alloc();
FILE * fyuv = fopen("Out_fileTT.yuv", "rb");
int nfilelen = (1920 * 1080 * 3) / 2;
uint8_t * pbuf = new uint8_t[nfilelen];
fread(pbuf, 1, nfilelen, fyuv);
fclose(fyuv);
int size = 1920 * 1080;
pict->data[0] = pbuf;
pict->data[1] = pict->data[0] + size;
pict->data[2] = pict->data[1] + size / 4;
pict->linesize[0] = 1920;
pict->linesize[1] = 1920 / 2;
pict->linesize[2] = 1920 / 2;
pict->format = AV_PIX_FMT_YUV420P;
pict->width = 1920;
pict->height = 1080;
clock_t start_time = clock();
int p = 0;
int Top = 1;
while (Top != 0)
{
//6 encode frame
pict->pts = p;
p = p + 3600;
Top = avcodec_send_frame(Enc, pict);
if (Top != 0)
{
continue;
}
AVPacket Packetpkt;
av_init_packet(&Packetpkt);
Top = avcodec_receive_packet(Enc, &Packetpkt);
if (Top != 0)
{
av_strerror(Top, errorbuf, sizeof(errorbuf));
std::cout << "avcodec_receive_packet NO ->" << errorbuf << Top << std::endl;
std::cout << " Number :" << i << Top << std::endl;
i++;
continue;
}
SaveH264(&Packetpkt);
//********* Encodec Packetpkt start ***************
std::cout << " Packetpkt size : " << Packetpkt.size << " " << std::endl;
std::cout << " Packetpkt KB size : " << Packetpkt.size / 1024 << std::endl;
std::cout << " Packetpkt data : " << Packetpkt.data << std::endl ;
std::cout << " Packetpkt pts : " << Packetpkt.pts<< std::endl;
std::cout << " Packetpkt dts : " << Packetpkt.dts << std::endl;
//********* Encodec Packetpkt End ***************
clock_t end_time = clock();
std::cout << "Codec Time: " << static_cast<double>(end_time - start_time) / CLOCKS_PER_SEC * 1000 << "ms"<< std::endl;
std::cout << " ********************* " << std::endl;
av_packet_unref(&Packetpkt);
std::cout << " ImageEnde End "<< std::endl;
}
av_free(pict);
avcodec_close(Enc);
avcodec_free_context(&Enc);
return 0;
}
【FFMPEG应用篇】yuv图片编码为h264文件
于 2022-11-14 15:56:50 首次发布