ffmpeg3.X解码器

首先致敬雷神!代码参考了雷神代码,在ffmpeg3.X的基础上进行修改。

int videoDecode()
{
    AVFormatContext *pFormatCtx = NULL;
    AVCodec *pCodec             = NULL;
    AVCodecContext *pCodecCtx   = NULL;
    AVFrame *pFrame             = NULL;
    AVFrame *pFrameYUV          = NULL;
    AVPacket *pPacket           = NULL;

    //初始化
    av_register_all();
    avformat_network_init();
    
    //申请内存
    pFormatCtx = avformat_alloc_context();

    //输入文件路径
    const char *fileName = "Titanic.mkv";
    if (avformat_open_input(&pFormatCtx, fileName, NULL, NULL) != 0)//打开输入的文件,并读取头信息。
    {
        printf("could not open input stream.\n");
        return -1;
    }
    if (avformat_find_stream_info(pFormatCtx, NULL) < 0)
    {
        printf("could not find stream information.\n");
        return -1;
    }

    //输出文件
    FILE *outputfile = NULL;
    const char *outputfilename = "output.yuv";
    fopen_s(&outputfile, outputfilename, "wb");


    //find videoindex
    int videoindex = av_find_best_stream(pFormatCtx, AVMEDIA_TYPE_VIDEO, -1, -1, NULL, 0);//0.寻找文件中最佳的流
    if (videoindex < 0)
    {
        printf("could not find a video stream.\n");
        return -1;
    }

    //find the decoder
    pCodecCtx = avcodec_alloc_context3(NULL);
    if (pCodecCtx == NULL)
    {
        printf("could not allocate AVCodecContext.\n");
        return -1;
    }
    avcodec_parameters_to_context(pCodecCtx, pFormatCtx->streams[videoindex]->codecpar);//用编解码器填充编解码信息。
    pCodec = avcodec_find_decoder(pCodecCtx->codec_id);//查找解码器
    if (pCodec == NULL)
    {
        printf("codec not found.\n");
        return -1;
    }

    //open the decoder
    if (avcodec_open2(pCodecCtx, pCodec, NULL) < 0)//用编解码器初始化编解码环境
    {
        printf("could not open codec.\n");
        return -1;
    }

    //output information
    printf("---------------- File Information --------------\n");
    av_dump_format(pFormatCtx, videoindex, fileName, 0);//输出编解码信息。
    printf("------------------------------------------------\n");

    //pre decode
    pPacket = (AVPacket *)av_malloc(sizeof(AVPacket));
    av_init_packet(pPacket);

    pFrame = av_frame_alloc();
    pFrameYUV = av_frame_alloc();

    int video_dst_bufsize = av_image_alloc((uint8_t**)pFrameYUV->data, pFrameYUV->linesize, pCodecCtx->width, pCodecCtx->height, pCodecCtx->pix_fmt, 1);
    printf("decode video file %s to %s\n", fileName, outputfilename);

    //decode
    int frame_count = 0;

    while (av_read_frame(pFormatCtx, pPacket) == 0)//读取下一帧
    {
        if (pPacket->stream_index == videoindex)
        {
            if (avcodec_send_packet(pCodecCtx, pPacket) != 0) {
                printf("input AVPacket to decoder failed!\n");
                return -1;
            }
            while (0 == avcodec_receive_frame(pCodecCtx, pFrame)) {
                av_image_copy((uint8_t **)pFrameYUV->data, pFrameYUV->linesize, (const uint8_t **)pFrame->data, pFrame->linesize, pCodecCtx->pix_fmt, pCodecCtx->width, pCodecCtx->height);
                fwrite(pFrameYUV->data[0], 1, video_dst_bufsize, outputfile);
                //printf("decoded frame index: %d\n", frame_count);
                frame_count++;
            }
        }
        av_packet_unref(pPacket);//清空pPacket
    }


    fclose(outputfile);
    av_frame_free(&pFrame);
    av_frame_free(&pFrameYUV);
    avcodec_close(pCodecCtx);
    avformat_close_input(&pFormatCtx);

    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值