当前位置: 首页 > news >正文

C++-FFmpeg-(5)-1-ffmpeg原理-ffmpeg编码接口-AVFrame-AVPacket-最简单demo

1.视频编码原理
2.FFMpeg编码接口和AVPacket结构体详解

   2.1ffmpeg编码接口 -编码器+上下文
   2.2AVPacket结构体
   2.3AVFrame结构体

3.视频播放最简单demo
   3.1FFMpeg编码器获取和上下文打开
   3.2视频帧创建和测试


 1.视频编码原理


   1.1 流程:像素格式转换->编码->封装
   1.2为什么要编码:像素格式数据过大
         采集高速数据,内存:128G内存
         硬盘来不及存储:SSD :1s,3G ;PCIE接口 1s,500MB
   1.3原始帧AVFrame->压缩帧AVPacket
        AVFrame数据大:1s 1G的数据,性能性问题,不能复制。
        AVPacket数据小:1080p:1s 1MB  结构清晰
   1.4帧内压缩、帧间压缩
       图片压缩:bmp->jpg 压缩 找相似点,大小变化不大
       视频压缩:视频:保存差异
       帧内压缩:只跟关键帧相关
   1.5有损压缩、无损压缩
       有损压缩:类似数据丢掉 解压后无法与原文件相同。
       无损压缩:zip,rar,7z

2.FFMpeg编码接口和AVPacket结构体详解
  

2.1ffmpeg编码接口 -编码器+上下文


 
         

 2.2AVPacket结构体

 2.3AVFrame结构体

 

3.视频播放最简单demo
   

int main113()
{
  //  auto codec; 编码器
  //  auto c;     上下文
  //  auto frame; 对象+缓冲 编码前
  //  auto pkt;   对象+缓冲 编码后

    // 编码器+上下文
    //1.查找+分配空间
    auto codec = avcodec_find_encoder(AV_CODEC_ID_H264);  //对象返回的是指针
    if (!codec) { return -1; }
    auto c = avcodec_alloc_context3(codec);
    //2.上下文 参数设置 视频宽、高、帧时间、元数据像素格式、编码线程数
    c->width = 400;
    c->height = 300;
    c->time_base = { 1,25 };
    c->pix_fmt = AV_PIX_FMT_YUV420P;
    c->thread_count = 16;
    //3.编码器 参数设置 b帧为0,
    c->max_b_frames = 0;
    int opt_re = av_opt_set(c->priv_data,"preset","ultrafast",0);//最快速度
    opt_re = av_opt_set(c->priv_data,"tune","zerolatency",0);    //零延时
    //4.打开上下文 返回值==0 OK
    int re = avcodec_open2(c, codec, NULL);                      // 返回值 “打开”!=0表示正确 
    if (re != 0) { return -1; }
    //5.AVFrame -赋值-编码(压缩数据AVPAckage)-写入文件
    //5.1AVFrame   创建对象+缓冲(),
    //5.11AVFrame设置参数 宽、高、像素格式
    auto frame=av_frame_alloc();
    frame->width = 400;
    frame->height = 300;
    frame->format = c->pix_fmt;
    int re = av_frame_get_buffer(frame,0);                     // 返回值  创建“缓冲区”!=0表示错误
    if (re != 0) { return -1; }
    //5.12 AVPacket 创建对象
    auto pkt = av_packet_alloc();
    //5.13
    string filename;
    filename = "400_300_25_preset.h265";
    ofstream ofs;
    ofs.open(filename, ios::binary);                          //返回值  ofs ofs.open  !表示错误
    if (!ofs)
    {
        cerr << "open " << filename<<" failed!" << endl;
        return -1;
    }
    //ofs.write((char*)pkt->data, pkt->size);
    //ofs.close();
    /*编码
    re=avcodec_send_frame(c,frame);
    while (re >= 0)
    {
        re=avcodec_receive_packet(c,pkt);
        if (re < 0) { break; }
        ofs.write((char*)pkt->data, pkt->size);
        av_packet_unref(pkt);
    }*/
    for (int i = 0; i < 250; i++)
    {
        for (int y = 0; y < frame->height;y++)//Y
        {
            for (int x = 0; x < frame->width; x++)
            {
                frame->data[0][y * frame->linesize[0] + x] = x + y + i * 3;
            }

        }
        for (int y = 0; y < frame->height / 2; y++)//UV
        {
            for (int x = 0; x < frame->width / 2; x++)
            {
                frame->data[1][y*frame->linesize[1]+x]= 128+x + y + i * 3;
                frame->data[2][y*frame->linesize[2]+x]=64+ x + y + i * 3;
            }
        }
        frame->pts = i;
        re=avcodec_send_frame(c, frame);                     //返回值    !=0 表示错误
        if (re != 0){ break;}
        while (re >= 0)
        {
            re=avcodec_receive_packet(c, pkt);               //返回值
            if (re < 0) { break; }
            av_packet_unref(pkt);
        }
    }

    ofs.close();
    //5.释放对象 AVFrame AVPAckage 编码器上下文
    av_packet_free(&pkt);
    av_frame_free(&frame);
    avcodec_free_context(&c);
    return 0;

}



 

相关文章:

  • 有一个变量 在有些线程没有加锁 有些线程加锁了,那我在这些加锁的线程中能起到对应的作用吗
  • openEuler24.03 LTS下安装Spark
  • 使用 Google ML Kit 实现图片文字识别(提取美国驾照信息)
  • 爬虫抓包工具和PyExeJs模块
  • 领域大模型
  • flink iceberg写数据到hdfs,hive同步读取
  • 【C++游戏引擎开发】数学计算库GLM(线性代数)、CGAL(几何计算)的安装与使用指南
  • 【AI学习】AI Agent(人工智能体)
  • 蓝桥杯 C/C++ 组历届真题合集速刷(一)
  • GeoGPT:重新定义地理信息智能的下一代AI助手
  • 用PointNet++训练自己的数据集(语义分割模型semseg)
  • WEB安全--XSS--DOM破坏
  • 优选算法第八讲:链表
  • HOW - 如何测试 React 代码
  • unity urp 分层调酒思路解析
  • Nacos 服务发现的流程是怎样的?客户端如何获取最新的服务实例列表?
  • 鸿蒙开发_ARKTS快速入门_语法说明_渲染控制---纯血鸿蒙HarmonyOS5.0工作笔记012
  • 【JavaScript】十六、事件捕获和事件冒泡
  • TIM定时器
  • 跟着尚硅谷学vue-day3
  • 上海杨浦:优秀“博主”购房最高可获200万补贴
  • 眉山“笑气”迷局:草莓熊瓶背后的隐秘与危机
  • “救护车”转运病人半路加价,从宝鸡到西安往返都要多收钱
  • 从“重规模”向“重回报”转变,公募基金迎系统性改革
  • 又一日军“慰安妇”制度受害者去世,大陆在世幸存者仅7人
  • 当年的你,现在在哪里?——新民晚报杯40周年寻人启事