视频编码流程 YUV数据编码为H264数据

news2024/11/15 5:27:06

文章目录

  • 1.视频编码流程
  • 2.实战demo
  • 3.相关编码知识点讲解
    • 1. 参数设置问题:
    • 2. 关于av_opt_set
    • 3. 关于码流设置

1.视频编码流程

在这里插入图片描述

2.实战demo

#ifndef MAINBACK_C
#define MAINBACK_C
#endif // MAINBACK_C
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <libavcodec/avcodec.h>
#include <libavutil/common.h>
#include <libavutil/frame.h>
#include <libavutil/opt.h>
#include <libavutil/imgutils.h>
#include <time.h>
int encode(AVCodecContext* codec_ctx,AVFrame* frame,AVPacket* pkt,FILE* out)
{
    int ret=0;
    ret = avcodec_send_frame(codec_ctx,frame);
    printf("send data\n");
    if(ret<0){
        printf("avcodec_send_frame failed\n");
        return ret;
    }

    while(1)
    {
        ret=avcodec_receive_packet(codec_ctx,pkt);
        if(ret==AVERROR(EAGAIN)||ret==AVERROR(AVERROR_EOF))
            break;
        if(ret<0)return ret;
        printf("write data\n");
        fwrite(pkt->data,1,pkt->size,out);

    }

}
//编码流程  先初始化编码器,读取原始文件,send,recvice,写入
int main(int argc,char* argv[])
{
    if(argv<3)
    {
        printf("argv<3\n");
        return -1;
    }
    char* yuv_path=argv[1];
    char* out_path=argv[2];
    FILE* yuv_file=fopen(yuv_path,"rb");
    FILE* out_file=fopen(out_path,"wb");
    AVCodec* codec=avcodec_find_encoder(AV_CODEC_ID_H264);
    AVCodecContext* codec_ctx=avcodec_alloc_context3(codec);

    codec_ctx->bit_rate=1024*512;
    codec_ctx->width=768;
    codec_ctx->height=320;
    codec_ctx->pix_fmt=AV_PIX_FMT_YUV420P;
    codec_ctx->max_b_frames=0;
    codec_ctx->gop_size=25;
    codec_ctx->framerate=(AVRational){25,1};
    codec_ctx->time_base=(AVRational){1,25};
    av_opt_set(codec_ctx->priv_data,"preset","veryslow",0);
    av_opt_set(codec_ctx->priv_data,"profile","main",0);
    av_opt_set(codec_ctx->priv_data,"tune","zerolatency",0);
    avcodec_open2(codec_ctx,codec,NULL);
    AVFrame* frame=av_frame_alloc();
    AVPacket* pkt=av_packet_alloc();
    frame->format=codec_ctx->pix_fmt;
    frame->width=codec_ctx->width;
    frame->height=codec_ctx->height;

    av_frame_get_buffer(frame,0);//分配frame的buff
    int frame_bytes=av_image_get_buffer_size(frame->format,frame->width,frame->height,1);
    uint8_t* yuv_buff=av_malloc(frame_bytes);
    memset(yuv_buff,0,frame_bytes);
    int pts=0;
    int ret=0;
    uint64_t begin=time(0);
    while(1)
    {
        int rsize=fread(yuv_buff,1,frame_bytes,yuv_file);
        ret = av_frame_make_writable(frame);
        if(ret != 0)
            printf("av_frame_make_writable failed, ret = %d\n", ret);

        int need_size=av_image_fill_arrays(frame->data,frame->linesize,yuv_buff,frame->format,frame->width,frame->height,1);
        if(rsize!=need_size)break;
        frame->pts=pts;
        pts+=1;

        encode(codec_ctx,frame,pkt,out_file);
    }
    encode(codec_ctx,NULL,pkt,out_file);
    printf("time:%lld",time(0)-begin);
    return 0;
}

3.相关编码知识点讲解

1. 参数设置问题:

视频编码时,设置编码器上下文参数有:码率,宽,高,格式,帧率等
frame设置:宽,高,格式
然后计算一帧的数据:宽 * 高 * 格式占用字节数
通常使用av_image_get_buffer_size来计算

2. 关于av_opt_set

av_opt_set就是用来设置参数的

  • preset
    preset参数是一个权衡编码速度和压缩率的参数,编码速度越慢,压缩率越高
    参数:
    ultrafast
    superfast
    veryfast
    faster
    fast
    medium – default preset 默认是medium
    slow
    slower
    veryslow
  • tune
    tune参数用于视觉的侧重点,也就是说压缩的时候重点压缩什么,保留什么…
    参数:
    film:电影类型,对视频的质量⾮常严格时使⽤该选项
    animation:动画⽚,压缩的视频是动画⽚时使⽤该选项
    grain:颗粒物很重,该选项适⽤于颗粒感很重的视频
    stillimage:静态图像,该选项主要⽤于静⽌画⾯⽐较多的视频
    psnr:提⾼psnr,该选项编码出来的视频psnr⽐较⾼
    ssim:提⾼ssim,该选项编码出来的视频ssim⽐较⾼
    fastdecode:快速解码,该选项有利于快速解码
    zerolatency:零延迟,该选项主要⽤于视频直播
  • profile
  1. baseline profile:基本画质。⽀持I/P 帧,只⽀持⽆交错(Progressive)和CAVLC;
  2. extended profile:进阶画质。⽀持I/P/B/SP/SI 帧,只⽀持⽆交错(Progressive)和CAVLC;
  3. main profile:主流画质。提供I/P/B 帧,⽀持⽆交错(Progressive)和交错(Interlaced),也⽀持CAVLC 和CABAC 的⽀持;
  4. high profile:⾼级画质。在main Profile 的基础上增加了8x8内部预测、⾃定义量化、 ⽆损视频编码和更多的YUV 格式;

3. 关于码流设置

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/731760.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

火车头采集器AI伪原创[php源码]

本文介绍php版本的火车头采集器AI伪原创&#xff0c;对于网站的原创内容&#xff0c;站长朋友们一定很头疼。作为一个草根站长&#xff0c;自己写原创文章太累了。当然&#xff0c;我并不是说你不能写。自己写原创文章是不现实的。时间是最大的问题。 也许有的站长朋友会问&…

自定义封装Mybatis的过程

手写持久层框架思路分析&#xff1a; 步骤1:加载数据库配置信息&#xff0c;包括数据库url&#xff0c;端口&#xff0c;数据库名字&#xff1b;加载所有sqlmapper文件。 步骤2: 创建javaBean&#xff0c;全局配置类&#xff0c;Configuration&#xff0c;映射配置类&#xff…

香橙派和树莓派基于官方外设开发

香橙派和树莓派基于官方外设开发 1.wiringPi外设SDK安装 方式一&#xff1a; git clone https://github.com/orangepi-xunlong/wiringOP //下载源码 cd wiringOP //进入文件夹 sudo ./build clean //清除编译信息 sudo ./build //编译方式二 通过windows浏览器打开https://…

全网最新网络安全学习路线

在各大平台搜的网安学习路线都太粗略了。。。。看不下去了&#xff01; 我把自己整理的系统学习路线&#xff0c;拿出来跟大家分享了&#xff01;点击查看详细路线图 建议的学习顺序&#xff1a; 一、网络安全学习普法&#xff08;心里有个数&#xff0c;要进去坐几年&#xf…

Java入门教程||Java 网络编程||Java 发送邮件

Java 网络编程 网络编程是指编写运行在多个设备&#xff08;计算机&#xff09;的程序&#xff0c;这些设备都通过网络连接起来。 java.net包中J2SE的API包含有类和接口&#xff0c;它们提供低层次的通信细节。你可以直接使用这些类和接口&#xff0c;来专注于解决问题&#…

基于simulink视频处理系统多核仿真(附源码)

一、前言 此示例演示如何使用 Simulink中的数据流执行域在多个内核上运行视频处理系统。 数据流执行域允许您在计算密集型系统的设计中使用多个内核。此示例演示数据流作为子系统的执行域如何提高模型的模拟性能。 二、视频中的对象计数 此示例演示如何使用基本形态运算符从…

Docker部署Doris超详细图文教程

Doris安装有非常多的方法&#xff0c;这里主要介绍Docker中使用dev容器用来学习和测试的方法&#xff0c;避免在其他教程中踩坑(生产环境不建议使用Docker安装) 这里介绍一个不踩坑的docker本地单机版&#xff0c;笔者安装环境为Windows下的Docker&#xff0c;若为Linux系统安装…

SwiftUI + Swift 设备振动

如何让设备振动呢 iPhone 6S 3D Touch&#xff0c;可以识别轻&#xff0c;中&#xff0c;重三种按压力度&#xff0c;配合恰到好处的振动有利于提升交互体验&#xff0c;但后面的新设备都不支持 3D Touch 了&#xff0c;改为了检测按压时间&#xff0c;按同一个图标&#xff0…

如何用canvans实现地图上的运动轨迹

1.先需要一个地图的图片 2.通过canvas绘制出运动轨迹 // 创建渐变function createGradient(context, p0, p1) {const gradient context.createLinearGradient(p0.x, p0.y, p1.x, p1.y);gradient.addColorStop(0, "rgba(255, 0, 255, 0)");gradient.addColorStop(1,…

颜色渐变的数据密集适用的堆叠图

一般情况会用柱状图去堆叠&#xff0c;但是如果数据量太大了&#xff0c;就可考虑这种方式堆叠。可以呈现时间和数量上不同层次数据的变化。 效果图&#xff1a; 比较详细的注释一下源码&#xff1a; import matplotlib as mpl import matplotlib.pyplot as plt import numpy …

第七章:L2JMobius学习 – 登录服务LoginServer讲解

在上一个章节中&#xff0c;我们学习了网络数据传输的封装network。那么&#xff0c;在本章的登录服务LoginServer的讲解中&#xff0c;我们就来使用一下这个封装好的功能。Network的封装需要我们继承很多的接口或类。我们首先查看一下登录服务LoginServer的文件结构&#xff0…

[Android 13]Binder系列--获取ServiceManager

获取ServiceManager hongxi.zhu 2023-7-1 以SurfaceFlinger为例&#xff0c;分析客户端进程如何获取ServiceManager代理服务对象 主要流程 SurfaceFlinger中获取SM服务 frameworks/native/services/surfaceflinger/main_surfaceflinger.cpp // publish surface flingersp<…

mysql单表查询,排序,分组查询,运算符

CREATE TABLE emp (empno int(4) NOT NULL, --员工编号ename varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,--员工名字job varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,--员工工作mgr int(4) NULL DEFAULT NU…

随机产生50个100以内的不重复的整数,设计位图排序算法进行排序。

1.问题 随机产生50个100以内的不重复的整数&#xff0c;设计位图排序算法进行排序。 2.设计思路 阶段1&#xff1a; 初始化一个空集合    for i[0,n)    bit[i]0 阶段2&#xff1a; 读入数据i&#xff0c;并设置bit[i]1    for each i in the input file    bit[i]1…

Tomcat 应用服务 WEB服务

简述&#xff1a; 中间件产品介绍 目前来说IBM的WebSphere&#xff0c;Oracle的Weblogic占据了市场上Java语言Web站点的部分份额&#xff0c;该两种软件由于无与伦比的性能及可靠性等优势被广泛应用于大型互联网公司的Web场景中&#xff0c;但是其高昂的价格也使得中小型互联…

DL-FWI:数据(第二次培训作业)

代码&#xff1a; import scipy.io import matplotlib import numpy as np import matplotlib.pylab as plt matplotlib.use(TkAgg) from mpl_toolkits.axes_grid1 import make_axes_locatable import cv2font21 {family: Times New Roman,weight: normal,size: 21,}font18 …

【通览一百个大模型】LaMDA(Google)

【通览一百个大模型】LaMDA&#xff08;Google&#xff09; 作者&#xff1a;王嘉宁&#xff0c;本文章内容为原创&#xff0c;仓库链接&#xff1a;https://github.com/wjn1996/LLMs-NLP-Algo 订阅专栏【大模型&NLP&算法】可获得博主多年积累的全部NLP、大模型和算法干…

图像金字塔、滑动条、鼠标事件响应

1、拉普拉斯图像金字塔 1.1 原理 1.2 实现 //拉普拉斯图像金字塔 void test1() {//高斯图像金字塔构建Mat img imread("F:/testMap/lena.png");vector<Mat> Guass;int level 3;Guass.push_back(img);for (int i 0; i < level; i){Mat guass;pyrDown(Gua…

蓝桥杯每日一练专栏导读2

之前一直更新的是C、C相关的题目&#xff0c;但作为一名前端工程师&#xff0c;还是对Js了解的更多一些&#xff0c;所以从此以后停止更新C/C相关内容&#xff0c;改为更新Js相关的练习题。 内容 更新的内容依旧是蓝桥杯大赛官网提供的习题。每一道题都会提供详细的解题思路&a…

方案编制要求--模版--可以借鉴

写方案的标题要求的编写&#xff0c;可以参照这个进行编写&#xff1b; 附录2&#xff1a;方案编制要求及模板 一、封面格式要求 封面内容应包括项目名称、需求单位&#xff08;盖章&#xff09;、建设单位&#xff08;盖章&#xff09;、设计单位&#xff08;盖章&#xff0…