ffmpeg rgb转yuv 生成H264文件

BITMAPFILEHEADER * test = NULL;
FILE * file[5];
char * szTxt[5];
int nWidth = 0;
int nHeight = 0;
int nDataLen = 0;
int nLen;
char csFileName[20];
int fileI;
for (fileI = 1; fileI <= 5; fileI++)
{
sprintf(csFileName, "f:\\picture\\%d.bmp", fileI);
file[fileI - 1] = fopen(csFileName, "rb");
fseek(file[fileI - 1], 0, SEEK_END);
nLen = ftell(file[fileI - 1]);//nlen文件长度
fseek(file[fileI - 1], 0, SEEK_SET);
szTxt[fileI - 1] = (char *)malloc(nLen);
nLen = fread(szTxt[fileI - 1], 1, nLen, file[fileI - 1]);
fclose(file[fileI - 1]);
BITMAPFILEHEADER bmpFHeader;
BITMAPINFOHEADER bmpIHeader;
test = &bmpFHeader;
memcpy(&bmpFHeader, szTxt[fileI - 1], sizeof(BITMAPFILEHEADER));
unsigned long t_offbits = bmpFHeader.bfOffBits;
int nHeadLen = t_offbits - sizeof(BITMAPFILEHEADER);
memcpy(&bmpIHeader, szTxt[fileI - 1] + sizeof(BITMAPFILEHEADER), nHeadLen); //nHeadLen
char error[100];
sprintf(error, "%d: %d", bmpIHeader.biWidth, bmpIHeader.biHeight);//16
// AfxMessageBox(error);
nWidth = bmpIHeader.biWidth;
nHeight = bmpIHeader.biHeight;
szTxt[fileI - 1] += t_offbits;//颜色数据
nDataLen = nLen - t_offbits;
}
// printf("file ok\n");
AfxMessageBox("file ok\n");
av_register_all();
avcodec_register_all();
AVFrame * m_pRGBFrame = new AVFrame[1];//RGB帧数据
AVFrame * m_pYUVFrame = new AVFrame[1];;//YUV帧数据
AVCodecContext *c = NULL;
AVCodecContext *in_c = NULL;
AVCodec * pCodecH264;//编码器
uint8_t * yuv_buff;//
//查找h264编码器
pCodecH264 = avcodec_find_encoder(AV_CODEC_ID_H264);
c = avcodec_alloc_context3(pCodecH264);
c->bit_rate = 3000000;// put sample parameters
c->width = nWidth;//
c->height = nHeight;//
// frames per second     
AVRational rate;
rate.num = 1;
rate.den = 25;
c->time_base = rate;//(AVRational){1,25};
c->gop_size = 10; // emit one intra frame every ten frames
c->max_b_frames = 1;
c->thread_count = 1;
c->pix_fmt = AV_PIX_FMT_YUV420P;//PIX_FMT_RGB24;
av_opt_set(c->priv_data, /*"preset"*/"libvpx-1080p.ffpreset", /*"slow"*/NULL, 0);
//打开编码器
if (avcodec_open2(c, pCodecH264, NULL) < 0)
// printf("不能打开编码库");
{
AfxMessageBox("不能打开编码库");
}
int size = c->width * c->height;
yuv_buff = (uint8_t *)malloc((size * 3) / 2); //size for YUV 420
//将rgb图像数据填充rgb帧
uint8_t * rgb_buff = new uint8_t[nDataLen];
//图象编码
int outbuf_size = 100000;
uint8_t * outbuf = (uint8_t*)malloc(outbuf_size);
int u_size = 0;
FILE * f = NULL;
const char * filename = "myData.h264";
f = fopen(filename, "wb");
if (!f)
{
// printf("could not open %s\n", filename);
char error[100];
sprintf(error, "could not open %s\n", filename);
AfxMessageBox(error);
exit(1);
}
//初始化SwsContext
SwsContext * scxt = sws_getContext(c->width, c->height, AV_PIX_FMT_BGR24,
c->width, c->height, AV_PIX_FMT_YUV420P, SWS_POINT, NULL, NULL, NULL);
AVPacket avpkt;
//AVFrame *pTFrame=new AVFrame
for (int i = 0; i < 250; ++i)
{
//AVFrame *m_pYUVFrame = new AVFrame[1];
int index = (i / 25) % 5;
memcpy(rgb_buff, szTxt[index], nDataLen);
// memcpy(rgb_buff, m_irc->m_buf, nDataLen);
avpicture_fill((AVPicture*)m_pRGBFrame, (uint8_t*)rgb_buff, AV_PIX_FMT_RGB24, nWidth, nHeight);
//将YUV buffer 填充YUV Frame
avpicture_fill((AVPicture*)m_pYUVFrame, (uint8_t*)yuv_buff, AV_PIX_FMT_YUV420P, nWidth, nHeight);
// 翻转RGB图像
m_pRGBFrame->data[0] += m_pRGBFrame->linesize[0] * (nHeight - 1);
m_pRGBFrame->linesize[0] *= -1;
m_pRGBFrame->data[1] += m_pRGBFrame->linesize[1] * (nHeight / 2 - 1);
m_pRGBFrame->linesize[1] *= -1;
m_pRGBFrame->data[2] += m_pRGBFrame->linesize[2] * (nHeight / 2 - 1);
m_pRGBFrame->linesize[2] *= -1;
//将RGB转化为YUV
sws_scale(scxt, m_pRGBFrame->data, m_pRGBFrame->linesize, 0, c->height, m_pYUVFrame->data, m_pYUVFrame->linesize);
int got_packet_ptr = 0;
av_init_packet(&avpkt);
avpkt.data = outbuf;
avpkt.size = outbuf_size;
u_size = avcodec_encode_video2(c, &avpkt, m_pYUVFrame, &got_packet_ptr);
if (u_size == 0)
{
fwrite(avpkt.data, 1, avpkt.size, f);
}
}
fclose(f);
//delete []m_pRGBFrame;
//delete []m_pYUVFrame;
//delete []rgb_buff;
free(outbuf);
avcodec_close(c);

av_free(c);


从网上找的代码,改了N久终于可以用了,没找到原地址……

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值