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;
}
相关推荐
小叮当⇔13 小时前
M4A 转 MP3 桌面转换器(PyQt5 + FFmpeg)
开发语言·qt·ffmpeg
jiejiejiejie_14 小时前
Flutter for OpenHarmony 视频播放与本地身份验证萌系实战总结
flutter·华为·音视频·harmonyos
y小花14 小时前
安卓音频子系统之AudioFlinger
音视频
拾-光14 小时前
LTX-Video 2.3 实战:用图片生成视频,消费级显卡也能跑的开源 I2V 模型(GPT Image 2)
java·人工智能·python·深度学习·算法·机器学习·音视频
巴德鸟14 小时前
DaVinci 常用技巧 关键帧 自动字幕 追踪 音频 冻结帧 快捷键 多轨道字幕 扩充边缘
android·编辑器·音视频·视频·davinci·davin
上善若水202015 小时前
【定制开发】ENC设备视频矩阵功能介绍
线性代数·矩阵·音视频
legendary_16316 小时前
Type-C手机快充与音频/数据传输的完美融合:多功能转接器解析
c语言·智能手机·音视频
The Straight18 小时前
【视频文件音画不同步】字幕和视频画面不同步问题
音视频
我是发哥哈1 天前
主流AI视频生成方案商用化能力横向评测
大数据·人工智能·学习·机器学习·chatgpt·音视频
reasonsummer1 天前
【教学类-160-10】20260418 AI视频培训-练习011“豆包AI视频《毛毛虫找妈妈》+豆包图片风格:水墨画”
音视频·豆包图片