从H264视频中获取宽、高、帧率、比特率等属性信息

news2024/11/16 20:30:16

背景

最近整理视频编解码的代码,早前在jetson上封装了jetson multimedia作为视频编解码的类,供其他同事和其他组使用,但该解码接口有一个问题,无法首先获取视频宽高信息,更无法直接获取视频的帧率、比特率等信息。

解决方法

  1. 使用ffmpeg库,命令行参数不适合代码集成
  2. 使用ffmpeg的API接口进行封装

源码实现

// ffmpeg_videoinfo.h

#ifndef FFMPEG_VIDEOINFO_H
#define FFMPEG_VIDEOINFO_H

#include <iostream>
#include <memory>

struct VideoAsset {
    float width; 
    float height;
    float fps;
    float bitrate; /** bit per second */
    float duration; /** seconds */
};

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

int GetVideoInfo(const char *in_file,  std::shared_ptr<VideoAsset> &info);

#ifdef __cplusplus
};
#endif

#endif  // FFMPEG_VIDEOINFO_H
// ffmpeg_videoinfo.cpp


#include "ffmpeg_videoinfo.h"

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

#include <libavformat/avformat.h>
#include <libavcodec/avcodec.h>
#include <libavutil/avutil.h>

int GetVideoInfo(const char *in_file,  std::shared_ptr<VideoAsset> &info){
  // 注册所有格式和编解码器
    av_register_all();

    // 创建一个格式上下文(Format Context)
    AVFormatContext* formatContext = nullptr;
    if (avformat_open_input(&formatContext, in_file, nullptr, nullptr) != 0) {
        fprintf(stderr, "Could not open input file '%s'", in_file);
        return -1;
    }

    // 获取流信息
    if (avformat_find_stream_info(formatContext, nullptr) < 0) {
        fprintf(stderr, "Could not find stream information '%s'", in_file);
        return -1;
    }

    // 查找视频流
    int videoStreamIndex = -1;
    for (unsigned i = 0; i < formatContext->nb_streams; i++) {
        if (formatContext->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
            videoStreamIndex = i;
            break;
        }
    }

    if (videoStreamIndex == -1) {
        fprintf(stderr, "Could not find video stream '%s'", in_file);
        return -1;
    }

    // 获取视频流的编码参数
    AVCodecParameters* codecParameters = formatContext->streams[videoStreamIndex]->codecpar;
    AVStream* videoStream = formatContext->streams[videoStreamIndex];
    info->fps = av_q2d(videoStream->avg_frame_rate);
    info->width = codecParameters->width;
    info->height = codecParameters->height;

    int64_t totalSize = 0;
    int64_t totalDuration = 0;
    AVPacket packet;
    while (av_read_frame(formatContext, &packet) >= 0) {
        if (packet.stream_index == 0) {
            totalSize += packet.size;
            totalDuration += packet.duration;
        }
        av_packet_unref(&packet);
    }

    AVRational timeBase = videoStream->time_base; /** 时间基 */
    info->duration = (float)totalDuration * av_q2d(timeBase);
    info->bitrate = (totalDuration > 0) ? (totalSize * 8.0 / info->duration) : 0.0;

    // 清理
    avformat_close_input(&formatContext);

    return 0;
}
#ifdef __cplusplus
};
#endif
// 测试脚本 test_single_videoinfo.cpp



#include "ffmpeg_videoinfo.h"

int main(int argc, char **argv) {
  if(argc<2){
    return 1;
  }
  const std::string &input_h264=argv[1];

  std::shared_ptr<VideoAsset> video_info_ptr = std::make_shared<VideoAsset>();
  // VideoAsset video_info;
  int status_code = GetVideoInfo(input_h264.c_str(), video_info_ptr);
  if (status_code < 0) {
    printf("GetVideoInfo failed\n");
    return -1;
  }
  printf("bitrate:%f, duration:%f, fps:%f, height:%f, width:%f\n",
         video_info_ptr->bitrate, video_info_ptr->duration, 
         video_info_ptr->fps, video_info_ptr->height, 
         video_info_ptr->width);
  return 1;
}
# CMakelist.txt核心

add_executable(test_video_info test_single_videoinfo.cpp ffmpeg_videoinfo.h ffmpeg_videoinfo.cpp)
target_compile_features(test_video_info PRIVATE cxx_std_14)
target_link_libraries(test_video_info avcodec avutil avformat)
# 测试

./test_video_info /data/videos/l4t.h264

# 输出信息示例
[h264 @ 0xaaaac14b16a0] Stream #0: not enough frames to estimate rate; consider increasing probesize
bitrate:30681866.000000, duration:164.490005, fps:20.000000, height:2160.000000, width:3840.000000

后记

本人对ffmpeg接口并不熟悉,以上根据文档及搜索结果进行的实现,不敢保证没有bug,如果各位遇到问题,可以留言交流

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

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

相关文章

MySql 日期周处理方式

MySql 日期周处理方式 最近在做数仓相关工作&#xff0c;最近遇到 几个问题&#xff0c; 1、计算指定日期是一年中的第几周&#xff0c;周一为周的第一天 2、计算周的开始时间&#xff0c;结束时间 3、计算周对应的年 比如 2023-01-01 WEEKOFYEAR(2023-01-01) 是2022年的52周&…

STM32 BootLoader 刷新项目 (十) Flash擦除-命令0x56

STM32 BootLoader 刷新项目 (十) Flash擦除-命令0x56 1. STM32F407 BootLoader 中的 Flash 擦除功能详解 在嵌入式系统中&#xff0c;BootLoader 的设计是非常关键的部分&#xff0c;它负责引导主程序的启动、升级以及安全管理。而在 STM32F407 等 MCU 上实现 BootLoader&…

【Homework】【5】Learning resources for DQ Robotics in MATLAB

Lesson 5 代码-TwoDofPlanarRobot.m 表示一个 2 自由度平面机器人。该类包含构造函数、计算正向运动学模型的函数、计算平移雅可比矩阵的函数&#xff0c;以及在二维空间中绘制机器人的函数。 classdef TwoDofPlanarRobot%TwoDofPlanarRobot - 表示一个 2 自由度平面机器人类…

Uniapp 引入 Android aar 包 和 Android 离线打包

需求&#xff1a; 原生安卓 apk 要求嵌入到 uniapp 中&#xff0c;并通过 uniapp 前端调起 app 的相关组件。 下面手把手教你&#xff0c;从 apk 到 aar&#xff0c;以及打包冲突到如何运行&#xff0c;期间我所遇到的问题都会 一 一 进行说明&#xff0c;相关版本以我文章内为…

你可以通过以下步骤找到并打开 **Visual Studio 开发者命令提示符**:

你可以通过以下步骤找到并打开 Visual Studio 开发者命令提示符&#xff1a; 1. 通过开始菜单查找 打开 开始菜单&#xff08;点击屏幕左下角的 Windows 图标&#xff09;。在搜索框中输入 Developer Command Prompt。你应该看到以下几种选项&#xff08;具体取决于你的 Visu…

北京大学c++程序设计听课笔记101

基本概念 程序运行期间&#xff0c;每个函数都会占用一段连续的内存空间。而函数名就是该函数所占内存区域的起始地址&#xff08;也称“入口地址”&#xff09;。我们可以将函数的入口地址赋给一个指针变量&#xff0c;使该指针变量指向该函数。然后通过指针变量就可以调用这个…

(时序论文阅读)TimeMixer: Decomposable Multiscale Mixing for Time Series Forecasting

来源论文iclr2024 论文地址&#xff1a;https://arxiv.org/abs/2405.14616 源码地址&#xff1a; https://github.com/kwuking/TimeMixer 背景 数据是有连续性&#xff0c;周期性&#xff0c;趋势性的。我们这篇文章主要围绕的是用MLP结构来预测数据的周期性具体为&#xff…

Springboot 使用EasyExcel导出含图片并设置样式的Excel文件

Springboot 使用EasyExcel导出含图片并设置样式的Excel文件 Excel导出系列目录&#xff1a;★★★★尤其注意&#xff1a;引入依赖创建导出模板类逻辑处理controllerservice 导出效果总结 Excel导出系列目录&#xff1a; 【Springboot 使用EasyExcel导出Excel文件】 【Springb…

【论文分享】基于街景图像识别和深度学习的针对不同移动能力老年人的街道步行可达性研究——以南京成贤街社区为例

全球老龄化趋势加剧, 许多城市中老年人数量不断增加&#xff0c;而现有街道和社区基础设施往往未能满足其步行安全和便利需求。本次我们给大家带来一篇SCI论文的全文翻译&#xff0c;该论文通过探讨不同步行能力的老年人对城市步行环境的需求&#xff0c;提供了关于如何改善城市…

LM2 : A Simple Society of Language Models Solves Complex Reasoning

文章目录 题目摘要简介相关工作方法论实验结果结论局限性 题目 LM2&#xff1a;简单的语言模型社会解决复杂推理问题 论文地址&#xff1a;https://aclanthology.org/2024.emnlp-main.920/ 项目地址&#xff1a; https://github.com/LCS2-IIITD/Language_Model_Multiplex 摘要…

【因果分析方法】MATLAB计算Liang-Kleeman信息流

【因果分析方法】MATLAB计算Liang-Kleeman信息流 1 Liang-Kleeman信息流2 MATLAB代码2.1 函数代码2.2 案例参考Liang-Kleeman 信息流(Liang-Kleeman Information Flow)是由 Liang 和 Kleeman 提出的基于信息论的因果分析方法。该方法用于量化变量之间的因果关系,通过计算信息…

[含文档+PPT+源码等]精品基于springboot实现的原生Andriod手机使用管理软件

软件开发环境及开发工具&#xff1a; 数据库管理工具&#xff1a;phpstudy/Navicat或者phpstudy/sqlyog 开发工具&#xff1a;Android Studio 后台管理系统涉及技术&#xff1a; 后台使用框架&#xff1a;Springboot 前端使用技术&#xff1a;Vue,HTML5,CSS3、JavaScript等…

(三十三)队列(queue)

文章目录 1. 队列&#xff08;queue&#xff09;1.1 定义1.2 函数1.3 习题1.3.1 例题&#xff08;周末舞会&#xff09; 2. 双向队列&#xff08;deque&#xff09;2.1 定义2.2 函数2.3 题目2.3.1 例题&#xff08;打BOSS&#xff09; 1. 队列&#xff08;queue&#xff09; 队…

常用数据类型

1.数值类型 分为整型和浮点型 double(3,1)&#xff1b;长度是3&#xff0c;小数点后是1&#xff0c;比如99.5&#xff0c;10.0&#xff0c;20.8 这里的float和double与java中的类似&#xff0c;都是IEEE 754标准的浮点数&#xff0c;精度会丢失&#xff0c;存在一定误差&#…

Vue3 -- 集成sass【项目集成5】

集成sass&#xff1a; 看过博主的 配置styleLint工具应该已经安装过 sass sass-loader 了&#xff0c;所以我们只需要加上我们的 lang"scss"即可。 <style scoped lang"scss"></style>给项目添加全局样式文件&#xff1a; 在src文件夹下创建…

【云原生系列--Longhorn的部署】

Longhorn部署手册 1.部署longhorn longhorn架构图&#xff1a; 1.1部署环境要求 kubernetes版本要大于v1.21 每个节点都必须装open-iscsi &#xff0c;Longhorn依赖于 iscsiadm主机为 Kubernetes 提供持久卷。 apt-get install -y open-iscsiRWX 支持要求每个节点都安装 N…

Springboot集成ElasticSearch实现minio文件内容全文检索

一、docker安装Elasticsearch &#xff08;1&#xff09;springboot和Elasticsearch的版本对应关系如下&#xff0c;请看版本对应&#xff1a; 注意安装对应版本&#xff0c;否则可能会出现一些未知的错误。 &#xff08;2&#xff09;拉取镜像 docker pull elasticsearch:7…

Diff 算法的误判

起源&#xff1a; 设想一下&#xff0c;假如你桌面上的文件都没有文件名&#xff0c;取而代之的是&#xff0c;你使用通过文件的位置顺序即index来区分它们———第一个文件&#xff0c;第二个文件&#xff0c;以此类推。也许这种方式可行&#xff0c;可是一旦你删除了其中的一…

D69【 python 接口自动化学习】- python 基础之数据库

day69 Python 执行 SQL 语句 学习日期&#xff1a;20241115 学习目标&#xff1a; MySQL 数据库&#xfe63;- Python连接redis 学习笔记&#xff1a; redis数据库的用途 使用Python访问redis数据库 使用Python对redis数据库进行读写操作 总结 1. redis是一款高性能的键…

飞书文档只读限制复制

飞书文档只读限制复制 场景描述解决方式插件安装测试 场景描述 当使用飞书时&#xff0c;可能会存在无对方文档编辑/管理权限&#xff0c;对方只给自己开放只读权限的时候&#xff0c;此时如果文档较重要&#xff0c;需要本地保存一份&#xff0c;但是又无法复制文档或直接屏蔽…