FFmpeg解码H264为YUV420
来源:互联网 发布:淘宝网首页连衣裙 编辑:程序博客网 时间:2024/06/05 00:14
在这里我们主要用到三个函数实现解码过程,首先是H264解码初期化,其次是进行H264解码,最后 H264解码销毁,具体代码实现如下。
H264Decoder.h
#pragma onceextern "C"{#include <libavformat\avformat.h>#include <libavutil\pixfmt.h>#include <libavcodec\avcodec.h>}#define X264_DECODER_H longtypedef struct{ struct AVCodec *codec;// Codec struct AVCodecContext *c;// Codec ContextAVCodecParserContext *pCodecParserCtx; int frame_count; struct AVFrame *picture;// Frame AVPacket avpkt; int iWidth; int iHeight; int comsumedSize; int got_picture;} X264_Decoder_Handle;class H264Decoder{public:H264Decoder(void);~H264Decoder(void);public: // H264解码初期化 X264_DECODER_H X264Decoder_Init(); /* H264数据解码,解码后的数据为yuv420格式 dwHandle:初期化时返回的句柄 pDataIn:待解码数据 nInSize:待解码数据长度 pDataOut:解码后的数据,存储空间由调用者申请 nOutSize:存储空间大小 nWidth:解码后的图像宽度 nHeight:解码后的图像高度 */ int X264Decoder_Decode(X264_DECODER_H dwHandle, uint8_t *pDataIn, int nInSize, uint8_t *pDataOut, int *nOutSize, int *nWidth,int *nHeight);/* H264解码销毁 dwHandle:初期化时返回的句柄 */ void X264Decoder_UnInit(X264_DECODER_H dwHandle); protected: void pgm_save2(unsigned char *buf, int wrap, int xsize, int ysize, uint8_t *pDataOut) { int i; for(i = 0; i < ysize; i++) { memcpy(pDataOut+i*xsize, buf + /*(ysize-i)*/i * wrap, xsize); } }};
H264Decoder.cpp
#include "stdafx.h"#include "H264Decoder.h"H264Decoder::H264Decoder(void){}H264Decoder::~H264Decoder(void){}X264_DECODER_H H264Decoder::X264Decoder_Init(){ X264_Decoder_Handle *pHandle = (X264_Decoder_Handle *)malloc(sizeof(X264_Decoder_Handle)); if (pHandle == NULL) { return -1; } avcodec_register_all(); pHandle->codec = avcodec_find_decoder(AV_CODEC_ID_H264); if (!pHandle->codec) { return -2; } pHandle->c = avcodec_alloc_context3(pHandle->codec); if (!pHandle->c) { return -3; } pHandle->c->codec_type = AVMEDIA_TYPE_VIDEO; pHandle->c->pix_fmt =AV_PIX_FMT_YUV420P;pHandle->c->flags2|=AV_CODEC_FLAG2_CHUNKS;pHandle->pCodecParserCtx=av_parser_init(AV_CODEC_ID_H264); if (!pHandle->pCodecParserCtx){ printf("Could not allocate video parser context\n"); return -6; } if (avcodec_open2(pHandle->c, pHandle->codec, NULL) < 0) { return -4; } pHandle->picture =av_frame_alloc(); if (!pHandle->picture) { return -5; } pHandle->frame_count = 0; return (X264_DECODER_H)pHandle;}void H264Decoder::X264Decoder_UnInit(X264_DECODER_H dwHandle){ if (dwHandle <= 0) { return; } X264_Decoder_Handle *pHandle = (X264_Decoder_Handle *)dwHandle; avcodec_close(pHandle->c); av_free(pHandle->c);av_free(pHandle->picture->data[0]); av_free(pHandle->picture); free(pHandle);}int H264Decoder::X264Decoder_Decode(X264_DECODER_H dwHandle, uint8_t *pDataIn, int nInSize, uint8_t *pDataOut, int *nOutSize, int *nWidth, int *nHeight){ if (dwHandle <= 0) { return -1; }unsigned char buf[20*1024]={0}; X264_Decoder_Handle *pHandle = (X264_Decoder_Handle *)dwHandle;av_init_packet(&(pHandle->avpkt));pHandle->avpkt.size = nInSize;pHandle->avpkt.data = pDataIn; while (pHandle->avpkt.size > 0) { pHandle->comsumedSize = avcodec_decode_video2(pHandle->c, pHandle->picture, &pHandle->got_picture, &(pHandle->avpkt)); if (pHandle->comsumedSize < 0) { return -2; } if (pHandle->got_picture) { *nWidth = pHandle->c->width; *nHeight = pHandle->c->height;if(pHandle->c->width!=0 && pHandle->c->height!=0){*nOutSize=pHandle->c->width*pHandle->c->height*3/2;}else {*nOutSize=0;} pgm_save2(pHandle->picture->data[0], pHandle->picture->linesize[0], pHandle->c->width, pHandle->c->height,pDataOut); pgm_save2(pHandle->picture->data[1], pHandle->picture->linesize[1], pHandle->c->width/2, pHandle->c->height/2, pDataOut +pHandle->c->width * pHandle->c->height); pgm_save2(pHandle->picture->data[2], pHandle->picture->linesize[2], pHandle->c->width/2, pHandle->c->height/2, pDataOut +pHandle->c->width * pHandle->c->height*5/4); } if (pHandle->avpkt.data) { pHandle->avpkt.size -= pHandle->comsumedSize; pHandle->avpkt.data += pHandle->comsumedSize; } } return 0;}
0 0
- FFmpeg解码H264为YUV420
- ffmpeg简化方案---只支持h264解码,输出为yuv420
- Live555接收h264使用ffmpeg解码为YUV420
- Live555接收h264使用ffmpeg解码为YUV420 .
- Live555接收h264使用ffmpeg解码为YUV420 .
- Live555接收h264使用ffmpeg解码为YUV420 .
- Live555接收h264使用ffmpeg解码为YUV420
- ubuntu下ffmpeg编译安装 -只支持h264解码,输出为yuv420
- 利用ffmpeg解码h264裸流并存储成YUV420
- 嵌入式linux------ffmpeg移植 解码H264(am335x解码H264到yuv420并通过SDL显示)
- 嵌入式linux------ffmpeg移植 解码H264(am335x解码H264到yuv420并通过SDL显示)
- FFMPEG3.2SDK解码H264保存为YUV420文件
- 利用ffmpeg将H264解码为RGB
- 利用ffmpeg将H264解码为RGB
- ffmpeg编译,解码 H264
- FFMPEG解码H264拼帧简解
- FFMPEG解码H264拼帧简解
- ffmpeg 解码h264
- 实现单实例应用程序的三种方法
- JQuery树形菜单
- android开发/设计原则总结
- 程序员更有动力的10个技巧
- C# ActiveX的打包发布
- FFmpeg解码H264为YUV420
- android 开发之- 获取倒计时CountDownTimer 实现
- Node.js EventEmitter
- TableWidget使用说明和增删改操作的实现
- Unable to get package info for com.mofang.joker03; is package not installed?
- 5位数回文数字的判断(Palindromes)
- shell中忽略大小写的设置方法
- Spring4.0 构造函数配置bean
- MongoDB简介