ffmpeg视频解码原理和实战-(1)对H264编码后的帧进行分割并存入AVPacket

源文件:

cpp 复制代码
#include <iostream>
#include <fstream>
using namespace std;
extern "C" { //指定函数是c语言函数,函数名不包含重载标注
//引用ffmpeg头文件
#include <libavcodec/avcodec.h>
}
//预处理指令导入库
#pragma comment(lib,"avcodec.lib")
#pragma comment(lib,"avutil.lib")
int main(int argc, char* argv[])
{
    //1 分割h264 存入AVPacket
      // ffmpeg -i v1080.mp4 -s 400x300 test.h264
    string filename = "test.h264";
    ifstream ifs(filename, ios::binary);
    if (!ifs)return -1;
    unsigned char inbuf[4096] = { 0 };
    AVCodecID codec_id = AV_CODEC_ID_H264;


    //1 找解码器
    auto codec = avcodec_find_decoder(codec_id);

    //2 创建上下文
    auto c = avcodec_alloc_context3(codec);

    //3 打开上下文
    avcodec_open2(c, NULL, NULL);


    //分割上下文
    auto parser = av_parser_init(codec_id);
    auto pkt = av_packet_alloc();
    while (!ifs.eof())
    {
        ifs.read((char*)inbuf, sizeof(inbuf));//将h264编码的流读入inbuf中
        int data_size = ifs.gcount();// 读取的字节数
        if (data_size <= 0)break;
        auto data = inbuf;
        while (data_size > 0) //一次有多帧数据
        {
           /* int av_parser_parse2(AVCodecParserContext * s, 
           AVCodecContext * avctx,
                uint8_t * *poutbuf, 
                int* poutbuf_size,
                const uint8_t * buf, 
                int buf_size,
                int64_t pts, 
                int64_t dts, 
                int64_t pos);
            s :指向 AVCodecParserContext 的指针,用于维护解析器的状态。
            avctx : 指向 AVCodecContext 的指针,包含解码器的上下文信息。
            poutbuf : 输出缓冲区的指针,解析出的完整帧将被存储在这里。
            poutbuf_size : 输出缓冲区的大小,以字节为单位。
            buf : 输入缓冲区的指针,包含需要解析的原始数据。
            buf_size : 输入缓冲区的大小,以字节为单位。
            pts : 输入数据包的演示时间戳(presentation timestamp)。
            dts : 输入数据包的解码时间戳(decoding timestamp)。
            pos : 输入数据包在文件中的位置。*/

            //通过0001 截断输出到AVPacket 返回帧大小
            int ret = av_parser_parse2(parser, c,
                &pkt->data, &pkt->size, //输出
                data, data_size,        //输入
                AV_NOPTS_VALUE, AV_NOPTS_VALUE, 0
            );//返回消耗的输入数据字节数ret。如果所有输入数据都被消耗,则返回值等于 buf_size。如果解析过程中出现错误,则返回负数。
            data += ret;
            data_size -= ret; //待处理的数据大小
            if (pkt->size)
            {
                cout << pkt->size << " " << flush;
            }
        }

    }
    av_packet_free(&pkt);

    getchar();
    return 0;
}
相关推荐
程序猿玖月柒1 小时前
嵌入式音视频开发——视频篇(三)
音视频
涛涛讲AI1 小时前
扣子平台音频功能:让声音也能“智能”起来
人工智能·音视频·工作流·智能体·ai智能体·ai应用
学习嵌入式的小羊~2 小时前
RV1126画面质量一:视频基础
音视频
霍格沃兹测试开发学社测试人社区2 小时前
人工智能在音频、视觉、多模态领域的应用
软件测试·人工智能·测试开发·自动化·音视频
单片机社区6 小时前
随笔十六、音频采集、UDP发送
嵌入式硬件·udp·音视频·泰山派
灵魂画师向阳9 小时前
Stable Diffusion 秋叶整合包v4.7 :解压即用,快速入门AI绘画
java·人工智能·ai作画·stable diffusion·音视频
程序猿玖月柒12 小时前
嵌入式音视频开发——视频篇(一)
笔记·音视频
yerennuo12 小时前
FFmpeg音视频采集
ffmpeg·音视频
我真不会起名字啊17 小时前
“深入浅出”系列之音视频开发:(4)FFmpeg库
ffmpeg·音视频
daqinzl17 小时前
VS环境下调用ffmpeg库
ffmpeg·visual studio