ffmpeg h264 编码。。。

来源:互联网 发布:启用MIUI优化 编辑:程序博客网 时间:2024/05/01 01:20
// Test.cpp : Defines the entry point for the console application.
//


#include "stdafx.h"
#include "stdio.h"
#include <cv.h>
#include <highgui.h>
using namespace std;


#define __STDC_CONSTANT_MACROS


#ifdef __cplusplus  
extern "C"
{
#include "libavutil/avutil.h"  
#include "libavcodec/avcodec.h"  
#include "libavformat/avformat.h"  
#include "libavdevice/avdevice.h"  
#include "libswscale/swscale.h"  
}
#endif 


#pragma comment(lib,"avutil.lib")  
#pragma comment(lib,"avcodec.lib")  
#pragma comment(lib,"avformat.lib")  
#pragma comment(lib,"swscale.lib")  



bool RGB24YUV420(SwsContext * scxt, AVFrame *m_pRGBFrame, AVFrame *m_pYUVFrame, uint8_t* rgb_buff, uint8_t* yuv_buff, int nWidth, int nHeight){


//安全检查


avpicture_fill((AVPicture*)m_pRGBFrame, (uint8_t*)rgb_buff, PIX_FMT_RGB24, nWidth, nHeight);


//将YUV buffer 填充YUV Frame  
avpicture_fill((AVPicture*)m_pYUVFrame, (uint8_t*)yuv_buff, 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, nHeight, m_pYUVFrame->data, m_pYUVFrame->linesize);
return true;


}
typedef unsigned short UINT;
typedef unsigned long DWORD;
typedef int LONG;
typedef unsigned short WORD;


#pragma pack (2) /*指定按2字节对齐*/ 
typedef struct tagBITMAPFILEHEADER {
WORD  bfType;
DWORD bfSize;
WORD  bfReserved1;
WORD  bfReserved2;
DWORD bfOffBits;
} BITMAPFILEHEADER, *PBITMAPFILEHEADER;
#pragma pack ()   /*取消指定对齐,恢复缺省对齐*/  
typedef struct tagBITMAPINFOHEADER {
DWORD biSize;
LONG  biWidth;
LONG  biHeight;
WORD  biPlanes;
WORD  biBitCount;
DWORD biCompression;
DWORD biSizeImage;
LONG  biXPelsPerMeter;
LONG  biYPelsPerMeter;
DWORD biClrUsed;
DWORD biClrImportant;
} BITMAPINFOHEADER, *PBITMAPINFOHEADER;


int main(int argc, char **argv)
{


FILE *file[5];
uint8_t *szTxt[5];


int nWidth = 0;
int nHeight = 0;


int nDataLen = 0;


int nLen;
printf("%d,%d", sizeof(BITMAPFILEHEADER), sizeof(BITMAPINFOHEADER));
string csFileName;
for (int fileI = 1; fileI <= 5; fileI++)
{
char filename[100];
sprintf(filename,"e:%d.bmp", fileI);
file[fileI - 1] = fopen(filename,"r+");
fseek(file[fileI - 1], 0, SEEK_END);
nLen = ftell(file[fileI - 1]);
fseek(file[fileI - 1], 0, SEEK_SET);


szTxt[fileI - 1] = new uint8_t[nLen];
fread(szTxt[fileI - 1], 1, nLen, file[fileI - 1]);
fclose(file[fileI - 1]);


//BMP bmi;//BITMAPINFO bmi;
//int nHeadLen = sizeof(BMP);
BITMAPFILEHEADER bmpFHeader;
BITMAPINFOHEADER bmpIHeader;
memcpy(&bmpFHeader, szTxt[fileI - 1], sizeof(BITMAPFILEHEADER));


int nHeadLen = bmpFHeader.bfOffBits - sizeof(BITMAPFILEHEADER);
memcpy(&bmpIHeader, szTxt[fileI - 1] + sizeof(BITMAPFILEHEADER), nHeadLen);


nWidth = bmpIHeader.biWidth;// 464;// bmi.bmpInfo.bmiHeader.biWidth;// ;
nHeight = bmpIHeader.biHeight;//362;// bmi.bmpInfo.bmiHeader.biHeight;// ;


szTxt[fileI - 1] += bmpFHeader.bfOffBits;
nDataLen = nLen - bmpFHeader.bfOffBits;
}


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(CODEC_ID_H264);
if (!pCodecH264)
{
fprintf(stderr, "h264 codec not found\n");
exit(1);
}


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 = 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("不能打开编码库");


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;
char * filename = "e:\\myData.h264";
f = fopen(filename, "wb");
if (!f)
{
printf("could not open %s\n", filename);
exit(1);
}


//初始化SwsContext
SwsContext * scxt = sws_getContext(c->width, c->height, PIX_FMT_BGR24, c->width, c->height, 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);
RGB24YUV420(scxt, m_pRGBFrame, m_pYUVFrame, rgb_buff, yuv_buff, nWidth, nHeight);
/*
avpicture_fill((AVPicture*)m_pRGBFrame, (uint8_t*)rgb_buff, PIX_FMT_RGB24, nWidth, nHeight);


//将YUV buffer 填充YUV Frame
avpicture_fill((AVPicture*)m_pYUVFrame, (uint8_t*)yuv_buff, 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);


}


0 0
原创粉丝点击