您的位置:首页 > 其它

FFMPEG3.2SDK解码H264保存为YUV420文件

2012-05-20 12:44 441 查看
直接上代码.

#pragma comment(lib, "avcodec.lib")

#pragma comment(lib, "avformat.lib")

#pragma comment(lib, "avutil.lib")

#include <windows.h>

#include <windef.h>

#include <stdio.h>

#include <assert.h>

#include <string.h>

#include <math.h>

#include "libavcodec/avcodec.h"

#include "libavformat/avformat.h"

#include "libavutil/avutil.h"

#include "libswscale/swscale.h"

#define INBUF_SIZE 4096

bool H264_Init();

void H264_Release();

void ReadH264();

void pgm_save(unsigned char *buf,int wrap, int xsize,int ysize,char *filename);

static AVCodecContext * g_pCodecCtx = NULL;

static AVFrame * g_pavfFrame = NULL;

static AVFormatContext * pFormatCtx = NULL;

static AVCodec * pCodec = NULL;

uint8_t inbuf[INBUF_SIZE + FF_INPUT_BUFFER_PADDING_SIZE], *inbuf_ptr;

//main

int main(int arg,char* argv[]){

//SDK初始化

H264_Init();

//解码

ReadH264();

return 0;

}

//ffmpge init .全局解码上下文应该可以通过FORMAT自动侦测的吧.这里写死了

bool H264_Init(){

if(g_pCodecCtx){

return true;

}

avcodec_init();

av_register_all();

pCodec = avcodec_find_decoder(CODEC_ID_H264);

if(NULL!=pCodec){

//printf("%s","ok");

g_pCodecCtx=avcodec_alloc_context();

g_pCodecCtx->time_base.num=1;

g_pCodecCtx->time_base.den=25;

g_pCodecCtx->bit_rate=0;

g_pCodecCtx->frame_number=1;

g_pCodecCtx->codec_type=CODEC_TYPE_VIDEO;

g_pCodecCtx->width=1080;

g_pCodecCtx->height=720;

if(avcodec_open(g_pCodecCtx,pCodec)>=0){

g_pavfFrame=avcodec_alloc_frame();

}

}

return g_pavfFrame==NULL?true:false;

}

void H264_Release(){

if(g_pavfFrame){

av_free(g_pavfFrame);

g_pavfFrame=NULL;

}

if(g_pCodecCtx){

avcodec_close(g_pCodecCtx);

av_free(g_pCodecCtx);

g_pCodecCtx=NULL;

}

};

//本来参考网上的资料,这个封装的方法实在不知道怎么用,就注释不用了.

/*

bool H264_Decode(const PBYTE pSrcData,const DWORD dwDataLen,PBYTE pDeData,int * pnWidth,int * pnHeight){

bool nGot=false;

avcodec_decode_video(g_pCodecCtx,g_pavfFrame,(int*)&nGot,(const unsigned char *)pSrcData,dwDataLen);

if(nGot){

*pnWidth=g_pCodecCtx->width;

*pnHeight=g_pCodecCtx->height;

assert(g_pCodecCtx->pix_fmt==PIX_FMT_YUV420P);

for(int i=0,nDataLen=0;i<3;i++){

int nShift=(i==0)?0:1;

PBYTE pYUVData = (PBYTE)g_pavfFrame->data[i];

for(int j=0;j<(g_pCodecCtx->height>>nShift);j++){

memcpy(&pDeData[nDataLen],pYUVData,(g_pCodecCtx->width>>nShift));

pYUVData+=g_pavfFrame->linesize[i];

nDataLen+=(g_pCodecCtx->width>>nShift);

}

}

}

return nGot;

}

*/

void ReadH264(){

AVPacket packet;

uint8_t *buffer;

AVFrame *pFrame;

pFrame=avcodec_alloc_frame();

int frameFinished;

int numBytes;

if(av_open_input_file(&pFormatCtx, "H264.264", NULL, 0, NULL)!=0){

printf("%s","error");

}

if(av_find_stream_info(pFormatCtx)<0) {

printf("%s","null stream"); // Couldn't find stream information</SPAN>

}

int videoStream=-1;

for(int i=0; i<(int)pFormatCtx->nb_streams; i++)

if(pFormatCtx->streams[i]->codec->codec_type==CODEC_TYPE_VIDEO) {

videoStream=i;

break;

}

if(videoStream==-1) {

printf("%s","null video stream"); // Didn't find a video stream

}else{

printf("%s","Have a video stream");

}

numBytes=avpicture_get_size(PIX_FMT_YUV420P, g_pCodecCtx->width,g_pCodecCtx->height);

buffer=(uint8_t *)av_malloc(numBytes*sizeof(uint8_t));

//avpicture_fill((AVPicture *)g_pavfFrame, buffer, PIX_FMT_YUV420P, g_pCodecCtx->width, g_pCodecCtx->height);

av_init_packet(&packet);

FILE * fp = fopen("test.yuv","wb+");

while(av_read_frame(pFormatCtx, &packet)>=0){

if(packet.stream_index==videoStream){

avcodec_decode_video(g_pCodecCtx,pFrame,&frameFinished,packet.data,packet.size);

if(frameFinished){

fflush(stdout);

/* the picture is allocated by the decoder. no need to free it */

pgm_save(pFrame->data[0], pFrame->linesize[0], g_pCodecCtx->width, g_pCodecCtx->height, "test.yuv");//Y

pgm_save(pFrame->data[1], pFrame->linesize[1], g_pCodecCtx->width/2, g_pCodecCtx->height/2, "test.yuv"); //U

pgm_save(pFrame->data[2], pFrame->linesize[2], g_pCodecCtx->width/2, g_pCodecCtx->height/2, "test.yuv");

}

}

}

//avcodec_decode_video

// Get a pointer to the codec context for the video stream

//g_pCodecCtx=pFormatCtx->streams[videoStream]->codec;

//pCodec=avcodec_find_decoder(g_pCodecCtx->codec_id);

}

//保存文件方法

void pgm_save(unsigned char *buf,int wrap, int xsize,int ysize,char *filename)

{

FILE *f;

int i;

f=fopen(filename,"ab+");

for(i=0;i<ysize;i++)

{

fwrite(buf + i * wrap, 1, xsize, f );

}

fclose(f);

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