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;
}
相关推荐
小兔子酱#2 小时前
音频 SDP 文件格式
音视频
DogDaoDao5 小时前
HEVC/H.265 码流分析工具 HEVCESBrowser 使用教程
ffmpeg·音视频·h.265·hevc·码流分析工具·elecard·hevcsbrowser
风无雨7 小时前
GO启动一个视频下载接口 前端可以边下边放
前端·golang·音视频
Antonio9158 小时前
【音视频】HTTP协议介绍
音视频
开开心心_Every21 小时前
便捷的电脑自动关机辅助工具
开发语言·人工智能·pdf·c#·电脑·音视频·sublime text
Antonio9151 天前
【音视频】TS协议介绍
音视频
来自宇宙的曹先生1 天前
【视频观看系统】- 技术与架构选型
架构·音视频
mulannanlu1 天前
视频音频转换器V!P版(安卓)安装就解锁V!P!永久免费使用!
音视频·软件·软件下载
一只特立独行的程序猿1 天前
手机、平板音频软件开发调测常用命令
音视频
来自宇宙的曹先生2 天前
视频网站弹幕系统简易实现
spring boot·音视频