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

背景

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

解决方法

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

源码实现

cpp 复制代码
// 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
cpp 复制代码
// 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
cpp 复制代码
// 测试脚本 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;
}
bash 复制代码
# 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)
bash 复制代码
# 测试

./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,如果各位遇到问题,可以留言交流

相关推荐
不大姐姐AI智能体4 天前
最新Coze(扣子)智能体工作流:用Coze实现「图片生成-视频制作」全自动化,3分钟批量产出爆款内容
运维·人工智能·经验分享·自动化·aigc·视频
melonbo10 天前
正向矩阵(DCT)变换后还是一个矩阵,怎么减少存储空间
音视频·h.264
软件测试-阿涛11 天前
2025年大语言模型与多模态生成工具全景指南(V2.0)
大数据·图像处理·人工智能·语言模型·视频
看兵马俑的程序员19 天前
H.264视频的RTP有效载荷格式(翻译自:RFC6184 第5节 RTP有效载荷格式)
网络·音视频·h.264
Casia_Dominic19 天前
【nerf处理视频数据】Instant-NGP项目NeRF模型训练数据集准备指南
linux·人工智能·ubuntu·视频·nerf
lm down23 天前
ComfyUI中运行Wan 2.1工作流,电影级视频,兼容Mac, Windows
人工智能·macos·ai作画·视频
IIIIIII_II1 个月前
【视频格式转换】.264格式转为mp4格式
python·视频·格式转换
geffen16881 个月前
无缝矩阵与普通矩阵的对比分析
es6·h.265·qt6.3
153578738981 个月前
MS1826+MS9332 4K@30Hz HD4×2视频分割器
视频·半导体
DogDaoDao1 个月前
HEVC/H.265 码流分析工具 HEVCESBrowser 使用教程
ffmpeg·音视频·h.265·hevc·码流分析工具·elecard·hevcsbrowser