视频h.264 解码出YUV分量代码实现

P2P 点对点传输
流媒体传输 Stream server

PTSP RTMP

编码现在都是硬件直接编码手机端 pc端不是
手机端有专门的解码 手机端没开放给我们,第三方的库去解码 decode
随随便便解码每秒六七十兆是可以的

解码流程:

#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libswcale/swcale.h>
typedef struct H264FrameDef
{
    unsigned int length;
    unsigned int dataBuffer;
}H264Frame;
typedef struct H264YUVDef
{
    unsigned int width;
    unsigned int height;
    H264Frame  luma;
    H264Frame  chromaB;
    H264Frame  chromaR;
}H264YUV_Frame;




    {
        AVCodec * pCodec;
        AVCodecContext* pCodecCtx;
        AVFrame*  pVideoFrame;
        AVPacket  pAVPackage;


        //初始化
            pCodec =NULL;
            pCodecCtx=NULL;
            av_register_all();
            avcodec_register_all();
            pCodec=avcodec_find_decoder(CODEC_ID_H264)
            if(!pCodec)
            {
                printf("Codec not find\n"); 
            }
            pCodecCtx=avcodec_alloc_context3(pCodec);
            if(!pCodecCtx)
            {
                printf("allocate codec context error\n");
            }
            avcodec_open2(pCodecCtx,pCodec,NULL);
            pVideoFrame=avcodec_alloc_frame();
    }
//销毁函数
    if(!pCodecCtx){
        avcodec_close(pCodecCtx);
        pCodecCtx=NULL;
    }
    if(!pVideoFrame){
    avcodec_free_frame(&pVideoFrame);
    pVideoFrame=NULL;
    }
//
int decodecH264Frame((unsigned char *)inputBuffer int alength)
{
    int gotPictPtr=0;
    int result=0;
    av_init_packet(&pAVPackage);
    pAVPackage.data=(unsigned char *)inputBuffer;
    pAVPackage.size=alength;
    result=avcodec_decode_video2(pCodecCtx,pVideoFrame,&gotPictPtr,&pAVPackage);
    //YUV   420 Y U V
    if(gotPictPtr)
    {
        unsigned int lumaLength=(pCodecCtx->height)*(MIN(pVideoFrame->linesize[0],pCodecCtx->width));
        unsigned int chroBLength=((pCodecCtx->height/2)*(MIN(pVideoFrame->linesize[1],(pCodecCtx->width)/2));
        unsigned int chroBLength=((pCodecCtx->height/2)*(MIN(pVideoFrame->linesize[2],(pCodecCtx->width)/2));
        H264YUV_Frame  yuvFrame;
        memset(&yuvFrame,0,sizeof(H264YUV_Frame));
        yuvFrame.luma.length=lumaLength;
        yuvFrame.chromaB.length=chroBLength;
        yuvFrame.chromaR.length=chroRlength;
        yuvFrame.luma.dataBuffer=(unsigned char *)malloc(lumaLength);
        yuvFrame.chromaB.dataBuffer=(unsigned char *)malloc(chromaBLength);
        yuvFrame.chromaR.dataBuffer=(unsigned char *)malloc(chromaRLength);
        copyDecodedFrame(pVideoFrame->data[0],yuvFrame.luma.dataBuffer,pVideoFrame->linesize[0],pCodecCtx->width,pCodecCtx->height);
        copyDecodedFrame(pVideoFrame->data[1],yuvFrame.chromaB.dataBuffer,pVideoFrame->linesize[1],
        pCodecCtx->width/2,pCodecCtx->height/2);
        copyDecodedFrame(pVideoFrame->data[2],yuvFrame.chromaR.dataBuffer,pVideoFrame->linesize[2],
        pCodecCtx->width/2,pVideoCtx->height/2);
    yuvFrame.width=pCodecCtx->width;
    yuvFrame.height=pCodecCtx->height;


    free(yuvFrame.luma.dataBuffer);
    free(yuvFrame.chromaB.dataBuffer);
    free(yuvFrame.chromaR.dataBuffer);

    av_free_packet(&pAVpackage) ;

    }


}
viod copyDecodedFrame(unsigned char *src,unsigned *dist,int linesize,int width,int height)
{
    width=MIN(linesize,width);
    for(int i=0;i<height;++i){
    memcpy(dist,src,width);
    dist+=width;
    src+=linesize;
    }
}
这里写码片
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值