头文件

#pragma once#ifndef _VIDEO_DECODING_HEADER_
#define _VIDEO_DECODING_HEADER_#define INBUF_SIZE 4096
#define AUDIO_INBUF_SIZE 20480
#define AUDIO_REFILL_THRESH 4096extern "C"
{
#include "libavutil/opt.h"
#include "libavcodec/avcodec.h"
#include "libavutil/channel_layout.h"
#include "libavutil/common.h"
#include "libavutil/imgutils.h"
#include "libavutil/mathematics.h"
#include "libavutil/samplefmt.h"
}/*************************************************
Struct:         CodecCtx
Description:    FFMpeg编解码器上下文
*************************************************/
typedef struct
{AVCodec            *pCodec;                //编解码器实例指针AVCodecContext    *pCodecContext;         //编解码器上下文,指定了编解码的参数AVCodecParserContext *pCodecParserCtx;    //编解码解析器,从码流中截取完整的一个NAL Unit数据AVFrame            *frame;                 //封装图像对象指针AVPacket      pkt;                    //封装码流对象实例
} CodecCtx;#endif

cpp文件

/*************
解码主要步骤:
1.解析输入参数,获取待解码的码流数据
2.初始化相应的FFMpeg结构
3.循环读取并解析输入码流数据--由2进制码流解析为FFMpeg可以处理的包数据
4.解码解析出的包为像素数据
5.写出像素数据
6.收尾工作
*************/#include<stdio.h>
#include<stdint.h>
#include"VideoDecodingHeader.h"#define INBUF_SIZE 4096   //接受区域大小FILE* pFin = NULL;
FILE* pFout = NULL;AVCodec* pCodec = NULL;
AVCodecContext* pCodecContext = NULL;
AVCodecParserContext* pCodecParserCtx = NULL;   //码流解码供解码器使用的包AVFrame* frame = NULL;
AVPacket pkt;static int open_input_output_file(char **argv)
{const char* inputFileName = argv[1];const char* outputFileName = argv[2];//fopen_s 以二进制只读的方式打开inputFileName,返回FILE指针fopen_s(&pFin, inputFileName, "rb+");if (!pFin){printf("Error: open input file failed.\n");return -1;}fopen_s(&pFout, outputFileName, "wb+");if (!pFout){printf("Error: open input file failed.\n");return -1;}return 0;
}
//打开解码器且初始化
static int open_decoder()
{//注册组件avcodec_register_all();//初始化最后输出的pktav_init_packet(&pkt);//查找解码器pCodec = avcodec_find_decoder(AV_CODEC_ID_H264);if (!pCodec){return -1;}pCodecContext = avcodec_alloc_context3(pCodec);if (!pCodecContext){return -1;}if (pCodec->capabilities & AV_CODEC_CAP_TRUNCATED){pCodecContext->flags |= AV_CODEC_CAP_TRUNCATED;}//初始化解析器pCodecParserCtx = av_parser_init(AV_CODEC_ID_H264);if (!pCodecParserCtx){printf("Error:alloc parser failed.\n");return -1;}//打开解码器if (avcodec_open2(pCodecContext, pCodec, NULL) < 0){printf("Error:open condec failed.\n");return -1;}//开辟frame空间frame = av_frame_alloc();if (!frame){printf("Error:alloc frame failed.\n");return -1;}return 0;}
//写出YUV数据
static void write_out_yuv_frame(AVFrame *frame)
{uint8_t **pBuf = frame->data;//保存地址int*    pStride = frame->linesize;//保存位宽for (int color_idx = 0; color_idx < 3; color_idx++){int       nWidth = color_idx == 0 ? frame->width : frame->width / 2;int      nHeight = color_idx == 0 ? frame->height : frame->height / 2;for (int idx = 0; idx < nHeight; idx++){fwrite(pBuf[color_idx], 1, nWidth, pFout);pBuf[color_idx] += pStride[color_idx];}fflush(pFout);}
}
//收尾工作
static void Close()
{fclose(pFin);fclose(pFout);avcodec_close(pCodecContext);av_free(pCodecContext);av_frame_free(&frame);}int main(int argc, char **argv)
{//从输入文件读取码流数据保存到的缓存位置uint8_t inbuf[INBUF_SIZE + AV_INPUT_BUFFER_PADDING_SIZE];if (open_input_output_file(argv) < 0){return -1;}else{printf("Open input/ouput file succeed\n");}if (open_decoder() < 0){return -1;}else{printf("Open decoder file succeed\n");}//解码循环int uDataSize = 0, len = 0;int got_frame = 0;uint8_t* pDataPtr = NULL;while (true){uDataSize = fread_s(inbuf, INBUF_SIZE, 1, INBUF_SIZE, pFin);if (uDataSize == 0){break;}pDataPtr = inbuf;while (uDataSize>0){len = av_parser_parse2(pCodecParserCtx, pCodecContext,&pkt.data, &pkt.size,pDataPtr, uDataSize, AV_NOPTS_VALUE, AV_NOPTS_VALUE, AV_NOPTS_VALUE);pDataPtr += len;uDataSize -= len;//pkt.size==0没有解析完if (pkt.size == 0){continue;}//!=0成功解析出一个packet的码流printf("Parse 1 packet.\n");int ret = avcodec_decode_video2(pCodecContext, frame, &got_frame, &pkt);if (ret < 0){printf("Error: decode failed.\n");return -1;}if (got_frame){printf("Decoded 1 frame OK! Width x Height: (%d x %d)\n", frame->width, frame->height);write_out_yuv_frame(frame);}else{break;}}}pkt.data = NULL;pkt.size = 0;while (true){int ret = avcodec_decode_video2(pCodecContext, frame, &got_frame, &pkt);if (ret < 0){printf("Error: decode failed.\n");return -1;}if (got_frame){printf("Flush Decoded 1 frame OK! Width x Height: (%d x %d)\n", frame->width, frame->height);write_out_yuv_frame(frame);}}Close();return 0;
}

【开源项目】使用FFMPEG解析H264编码为YUV格式相关推荐

  1. [高光谱] 开源项目Hyperspectral-Classification Pytorch解析之main

    开源项目Hyperspectral-Classification Pytorch解析之main.py 编码方式: # -*- coding: utf-8 -*- 项目简介: ""& ...

  2. java eventbus 原理_本文为 Android 开源项目实现原理解析 EventBus 部分,从源码分析 EventBus 的实现原理...

    之前太忙导致 Android 开源项目实现原理解析 一度搁浅,目前一期进行中,我也完成了 EventBus 分析的初稿,大家可以稍微看看后面会继续润色下. PS:本文直接复制 Markdown,格式有 ...

  3. [高光谱] GitHub开源项目Hyperspectral-Classification的解析

    GitHub链接:Hyperspectral-Classification Pytorch. 画重点!!! 完整版看这里嗷:GitHub开源项目Hyperspectral-Classification ...

  4. FFMPEG实现PCM编码(采用封装格式实现)

    技术在于交流.沟通,转载请注明出处并保持作品的完整性. 原文:https://blog.csdn.net/hiwubihe/article/details/81260882 [音频编解码系列文章] 音 ...

  5. Hisi3516交叉编译ffmpeg支持h264编码

    前言 Hi3516是海思半导体针对高清IPCamera产品应用开发的一款专业高端SOC芯片,具有1080P@30fps H264多码流编码性能.而ffmpeg是众多播放器的底层解.编码库,x264是一 ...

  6. ffmpeg的H264编码 视频逐渐模糊

    万能的互联网,又一次在临危之时解决了我的问题 最近在看ffmpeg里的H264编码,然后试着去做了一下.但是目前发现一个问题,就是编码写入的.264文件,用播放器(VLC,暴风都试过)播放后,发现编码 ...

  7. ffmpeg设置h264编码IDR间隔

    在ffmpeg中,编码h264时,想强制刷出一个I帧,比较容易,但是想强制刷出IDR帧,却没有明确的说明. 而在x264的头文件中,可以看到一个参数说明: int i_keyint_max; /* F ...

  8. ffmpeg进行h264编码

    首先需要穿件编码的上下文以及指定编码器代码如下 //视频编码上下文 - (AVCodecContext *)get_avcodecContext_fv{AVCodecContext *c_ctx = ...

  9. 使用FFMpeg进行H264编码

    使用FFMpeg可以很方便的对音视频进行编码,并且写文件. 下面的代码是将5幅1280*720大小的图片进行编码,并且写到文件中. 代码有些乱,但希望能抛砖引玉,对学习这方面的朋友有帮助. [cpp] ...

最新文章

  1. php将多个页面写在一个页面,php – 将多个标签添加到WooCommerce单个产品页面
  2. 100. Same Tree同样的树
  3. 跨服务器上传文件方式
  4. leetcood学习笔记-58-最后一个单词的长度
  5. visio生成数据表图
  6. mysql数据库面试总结
  7. Zabbix Server设置主机监控
  8. 删除的文件如何恢复?一个技巧就解决
  9. 爱情九十三课,指尖情话
  10. 4.2 各种各样的卷积层
  11. 肯德基champs各个字母代表什么_百度知道
  12. 一名 IT 工程师的九年工作总结!
  13. SQL SERVER插件之SQLPrompt 激活使用
  14. 苹果电脑u盘装win7系统教程
  15. 根据收入计算个人所得税
  16. Android 这些技术 —— 你都了解过吗
  17. 用python实现图片换脸
  18. android 百度全景,“android-panosdk | 百度地图API SDK
  19. 1000W纯正弦波逆变器方案资料EG8010源代码KA3525原理图图纸PCB
  20. 【Python】easygui小甲鱼

热门文章

  1. Java中的策略设计模式
  2. servlet异步_如何使用异步Servlet来提高性能
  3. 如何更改Spring Boot应用程序的默认端口
  4. php cdi_异步CDI事件
  5. JDeps入门–分析项目的依赖关系
  6. Spring批处理CSV处理
  7. 近似线性依靠matlab_不要仅仅依靠单元测试
  8. java中的五种排序方法_用Java排序的五种有用方法
  9. 拼图项目:一个不完整的难题
  10. 什么比日期和时区更难? SQL / JDBC中的日期和时区!