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 小时前
chrome插件-给音视频添加倍速播放控制功能
音视频·chrome devtools
sweetone14 小时前
SONY老式磁带随身听wm-fx193 之摩机过程(提升重低音音效,改耳放)
经验分享·音视频
m0_7471245315 小时前
多媒体框架 FFmpeg 和 GStreamer
ffmpeg·gstreamer
数据法师15 小时前
视频文件重复检测工具:基于哈希与视频指纹的三级筛选机制
算法·音视频·哈希算法
AI创界者15 小时前
告别云端限制!Sulphur 2 本地文生视频/图生视频整合包,本地部署,解压即用,保姆级部署与工作流实战
人工智能·python·aigc·音视频
南山有乔木78917 小时前
NCM格式在线转换MP3怎么操作?解决ncm打不开和无法导入问题
音视频
小鹿研究点东西20 小时前
AI直播系统怎么搭?
人工智能·ffmpeg·自动化·音视频·语音识别
byte轻骑兵20 小时前
【AVRCP】规范精讲[29]:多播放器切换全流程,蓝牙音频控制如何精准选歌台
智能手机·音视频·avrcp·音视频控制·车机蓝牙
南山有乔木78921 小时前
喜马拉雅XM转MP3怎么操作?xm转换成MP3后播放更方便
音视频
Nightwish51 天前
Oracle 数据库巡检检查清单
数据库·oracle·ffmpeg