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

news/2024/4/28 10:46:55/文章来源:https://blog.csdn.net/m0_60565784/article/details/131614914

文章目录

  • 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的buffint 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.luyixian.cn/news_show_328278.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Go内存分配那些事,就这么简单!

这篇文章主要介绍Go内存分配和Go内存管理&#xff0c;会轻微涉及内存申请和释放&#xff0c;以及Go垃圾回收。 从非常宏观的角度看&#xff0c;Go的内存管理就是下图这个样子&#xff0c;我们今天主要关注其中标红的部分。 本文基于go1.11.2&#xff0c;不同版本Go的内存管理可…

Linux驱动开发:Linux内核启动流程详解

前言&#xff1a;Linux 内核同样作为 Linux 驱动开发的 “三巨头” 之一&#xff0c;Linux 内核的启动流程要比 uboot 复杂的多&#xff0c;涉及到的内容也更多。但秉持着 “知其然知其所以然” 的学习态度&#xff0c;作者将给读者朋友大致的过一遍 Linux 内核的启动流程。(考…

Java csv文件上传下载中的相关转换

目录 一. 需求二. List<Entity>转List<List<String>>2.1 实体类2.2 转换 三. 上传csv文件转List<Map>3.1 csv文件3.2 前台3.3 实体类3.4 转换3.5 效果 一. 需求 &#x1f914;项目中遇到了两个需求 1.查询数据库&#xff0c;得到List<Entity>这…

初阶C语言———操作符详解(2)

hello&#xff0c;我们又见面了&#xff0c;今天我们把操作符这一章节完结&#xff0c;那让我们一起来学习吧 逻辑操作符 &&逻辑与 ||逻辑或 这里我们要区分按位与和按位或还有逻辑与和逻辑或的区分。 1&2----->0 1&&2---->1 1|2----->3 1||2---…

嵌入式_Keil (MDK - ARM) 的调试步骤

目录 1. 编译 调试 2. 复位 全速运行 3. 单步调试 4. 逐步调试 5. 跳出调试 6. 运行到光标处 7. 跳转到暂停行 8. 调试窗口 首先为什么需要在 MDK 中进行程序的调试呢&#xff1f; 在 MDK 中进行程序调试的主要目的是识别和解决程序中的问题和错误。 比如说找到程序中…

【CANopen】周立功轻松入门CANopen笔记

前言 想学习些新东西了&#xff0c;原本想直接学学Ethercat&#xff0c;但是简单看了看对象字典啥的概念一头雾水的&#xff0c;决定先从CANopen开始&#xff0c;Ethercat看着头疼。Etehrcat和CANopen有挺多类似的地方。感谢ZLG的这个入门笔记&#xff0c;我似乎是看懂了些&am…

一、枚举类型——新特性(模式匹配-支配性)

switch 中 case 语句的顺序很重要。如果基类先出现&#xff0c;就会支配任何出现在后面的 case&#xff1a; Dominance.java JDK 17 sealed interface Base { }record Derived() implements Base { }public class Dominance {static String test(Base base) {return switch (ba…

视频行为识别(一)——综述

Deep Neural Networks in Video Human Action Recognition: A Review 本次分享的文章是2023年收录在计算机视觉领域的顶刊“CVPR”&#xff08;级别&#xff1a;视觉类TOP&#xff09;期刊上。该期刊详细信息可关注公众号 AI八倍镜 点击菜单项查询。 论文地址&#xff1a;http…

代码随想录二刷day46 | 动态规划之139.单词拆分

day46 139.单词拆分1.确定dp数组以及下标的含义2.确定递推公式3.dp数组如何初始化4.确定遍历顺序5.举例推导dp[i] 139.单词拆分 题目链接 解题思路&#xff1a;单词就是物品&#xff0c;字符串s就是背包&#xff0c;单词能否组成字符串s&#xff0c;就是问物品能不能把背包装满…

第三章 SSD存储介质:闪存 3.4

3.4 闪存数据完整性 可采用以下数据完整性的技术确保用户数据不丢失&#xff1a; &#xff08;1&#xff09;ECC纠错&#xff1b; &#xff08;2&#xff09;RAID数据恢复&#xff1b; &#xff08;3&#xff09;重读&#xff08;Read Retry&#xff09;&#xff1b; &#xff…

vue 进阶---动态组件 插槽 自定义指令

目录 动态组件 如何实现动态组件渲染 使用 keep-alive 保持状态 keep-alive 对应的生命周期函数 keep-alive 的 include 属性和exclude属性 插槽 插槽的基础用法 具名插槽 作用域插槽 自定义指令 自定义指令的分类 私有自定义指令 全局自定义指令 了解 eslint 插件…

免费开源 | 基于SpringBoot的博客系统

介绍 基于springboot后端架构&#xff0c;websocket实现私信&#xff0c;前端采用thymeleafbootstraplayuiRedis 注册使用邮箱验证注册&#xff0c;且验证码存在redis中&#xff0c;所以需要有redis环境 软件架构 springbootwebsocketthymeleafbootstraplayuiRedismysql 8.…

Vue 数据双向绑定

双向数据绑定 : 通过前面学习知道 Vue 是数据驱动的&#xff0c;数据驱动有一个精髓之处是数据双向绑定&#xff0c; 即当数据发生变化的时候&#xff0c;视图也就发生变化&#xff0c;当视图发生变化的时候&#xff0c;数据也会跟着同步变化。&#xff08;就是mvvm数据发生变化…

C#,中国福利彩票《刮刮乐》的数学算法(01)——幸运123

彩票名称&#xff1a;幸运123面值&#xff1a;20元/张最高奖&#xff1a;100万&#xff08;人民币&#xff09;全套款式&#xff1a;2款玩法介绍&#xff1a; 一份好运&#xff0c;二倍快乐&#xff0c;三重惊喜。福彩刮刮乐新游戏“幸运123”&#xff0c;红色的票面上点缀着礼…

spring 详解二 IOC(Bean xml配置及DI)

配置列表 Xml配置 功能描述 <bean id"" class""></bean> Bean的id&#xff0c;配置id会转为Bean名称和不配就是全限定类名 <bean name"" ></bean> Bean的别名配置&#xff0c;存储在Factory的aliasMap中通过别名也…

Qt自定义控件之动画文本

文章目录 前言一、动画文本的效果二、具体实现定义动画对象设置动画时长的实现设置text函数实现绘制代码设置字体函数 三、高级部分操作代码总结 前言 在 Qt 中&#xff0c;自定义控件可以让我们实现丰富的用户界面效果和交互体验。其中&#xff0c;动画文本是一种常见的效果&…

使用 tail -f 实时观测服务器日志输出

在开发阶段, 有 console 端的输出, 总是可以方便实时地看到应用的日志. 可一旦应用部署到服务器上之后呢, 日志被输出到文件中, 在某些情景下需要不停地查看日志文件的输出以定位某些问题, 此时是否还能像开发那样实时查看日志呢? 答案是可以的! 这个命令就是 tail -f . tail…

Git使用详细教程

1. cmd面板的常用命令 clear&#xff1a;清屏cd 文件夹名称----进入文件夹cd … 进入上一级目录(两个点)dir 查看当前目录下的文件和文件夹(全拼:directory)Is 查看当前目录下的文件和文件夹touch 文件名----创建文件echo 内容 > 创建文件名----创建文件并写入内容rm 文件名…

Redis知识补充(1)

1)Redis本身就是在内存中进行存储数据的&#xff0c;那么为什么不直接定义一个变量来针对数据直接进行存储呢&#xff1f;因为Redis主要是应用于分布式系统&#xff0c;才能发挥它的最大威力&#xff0c;如果只是一个单机程序&#xff0c;通过变量存储数据的方式&#xff0c;是…

Kotlin~Composite组合模式

概念 能够帮助实现树状结构的模式。 主要特点 递归组合树状结构统一处理所有对象 角色介绍 Component: 组合接口Leaf: 叶子节点&#xff0c;无子节点Composite&#xff1a;枝节点&#xff0c;用来存储子部件 UML 代码实现 interface Organ {fun personCount():Int } cla…