您的位置:首页 > 其它

ffmpeg h264 编码。。。

2015-04-08 22:33 197 查看

// 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, ***Frame *m_pRGBFrame, ***Frame *m_pYUVFrame, uint8_t* rgb_buff, uint8_t* yuv_buff, int nWidth, int nHeight){

//安全检查

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

//将YUV buffer 填充YUV Frame

avpicture_fill((***Picture*)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();

***Frame *m_pRGBFrame = new ***Frame[1]; //RGB帧数据

***Frame *m_pYUVFrame = new ***Frame[1];; //YUV帧数据

***CodecContext *c = NULL;

***CodecContext *in_c = NULL;

***Codec *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

***Rational rate;

rate.num = 1;

rate.den = 25;

c->time_base = rate;//(***Rational){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);

***Packet avpkt;

//***Frame *pTFrame=new ***Frame

for (int i = 0; i<250; ++i)

{

//***Frame *m_pYUVFrame = new ***Frame[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((***Picture*)m_pRGBFrame, (uint8_t*)rgb_buff, PIX_FMT_RGB24, nWidth, nHeight);

//将YUV buffer 填充YUV Frame

avpicture_fill((***Picture*)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);

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: