9.用FFmpeg测试H.264文件的解码时间

news2024/12/24 2:33:41

1. Essence of Method

要测试对H.264文件的解码时间,可以使用FFmpeg进行操作。FFmpeg是一个开源的多媒体处理工具,可以用来处理视频和音频文件,包括解码H.264文件。以下是使用FFmpeg的命令行来测试解码时间的方法:

ffmpeg -i input.h264 -f null -

这个命令会将输入的input.h264文件解码到空输出,通过查看FFmpeg的输出信息,可以得到解码的耗时信息。

在FFmpeg中,-i选项用于指定输入文件,后面跟着输入文件的路径。例如,-i input.h264表示将input.h264作为输入文件。

-f选项用于指定输出格式。在上面的示例中,-f null表示将输出格式设置为null,这意味着不生成任何输出文件,仅仅执行解码操作。

2. Can the FFmpeg be Used Normally?

要检查是否安装了FFmpeg,并查看其版本号,可以在命令行中运行以下命令:

ffmpeg -version

如果安装了FFmpeg,将会显示版本信息。如果未安装,系统可能会显示命令未找到或类似的消息。要安装FFmpeg,请参考官方文档。

PS C:\Users\Administrator> ffmpeg  -version
ffmpeg version 2022-09-22-git-af919cf780-essentials_build-www.gyan.dev Copyright (c) 2000-2022 the FFmpeg developers
built with gcc 12.1.0 (Rev2, Built by MSYS2 project)
configuration: --enable-gpl --enable-version3 --enable-static --disable-w32threads --disable-autodetect --enable-fontconfig --enable-iconv --enable-gnutls --enable-libxml2 --enable-gmp --enable-bzlib --enable-lzma --enable-zlib --enable-libsrt --enable-libssh --enable-libzmq --enable-avisynth --enable-sdl2 --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxvid --enable-libaom --enable-libopenjpeg --enable-libvpx --enable-mediafoundation --enable-libass --enable-libfreetype --enable-libfribidi --enable-libvidstab --enable-libvmaf --enable-libzimg --enable-amf --enable-cuda-llvm --enable-cuvid --enable-ffnvcodec --enable-nvdec --enable-nvenc --enable-d3d11va --enable-dxva2 --enable-libmfx --enable-libgme --enable-libopenmpt --enable-libopencore-amrwb --enable-libmp3lame --enable-libtheora --enable-libvo-amrwbenc --enable-libgsm --enable-libopencore-amrnb --enable-libopus --enable-libspeex --enable-libvorbis --enable-librubberband
libavutil      57. 36.102 / 57. 36.102
libavcodec     59. 44.100 / 59. 44.100
libavformat    59. 32.100 / 59. 32.100
libavdevice    59.  8.101 / 59.  8.101
libavfilter     8. 49.100 /  8. 49.100
libswscale      6.  8.112 /  6.  8.112
libswresample   4.  9.100 /  4.  9.100
libpostproc    56.  7.100 / 56.  7.100

3. How?

在FFmpeg输出信息中,可以看到解码过程的耗时信息。怎么看解码耗时多久?
可以找到类似以下格式的行,其中包含了解码过程的耗时信息:

frame=  250 fps=0.0 q=0.0 size=N/A time=00:00:10.00 bitrate=N/A speed=19.6x

在这个例子中,time=00:00:10.00表示解码了10秒钟的视频。可以根据这个信息计算解码的平均速度。

在这个例子中,各个字段的含义如下:

  • frame: 已解码的帧数。
  • fps: 每秒钟解码的帧数,即帧率。
  • q: 压缩质量指标,一般不关注。
  • size: 输出文件大小。
  • time: 已解码的时间。
  • bitrate: 比特率,表示每秒传输的数据量。
  • speed: 解码速度,表示相对于实时播放速度的倍数。

4. Basic Examples

1)有一组H.264文件若干个,测试解码完这些文件耗时。
import subprocess
import time

# H.264文件列表
file_list = ['file1.h264', 'file2.h264', 'file3.h264']

# 开始计时
start_time = time.time()

# 解码每个文件
for file in file_list:
    subprocess.run(['ffmpeg', '-i', file, '-f', 'null', '-'])

# 计算总耗时
end_time = time.time()
total_time = end_time - start_time
print(f"解码耗时: {total_time} 秒")

这个脚本会逐个解码文件,并计算整个过程的总耗时。

2) 在Android手机设备上怎么测试H.264的解码时间

在Android手机设备上测试H.264的解码时间可以使用Android的MediaCodec API。这个API可以用来解码视频,并提供了一些回调函数来监测解码进度。

import android.media.MediaCodec;
import android.media.MediaExtractor;
import android.media.MediaFormat;
import android.os.Bundle;
import android.os.Environment;
import android.support.v7.app.AppCompatActivity;

import java.io.IOException;
import java.nio.ByteBuffer;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        new Thread(new Runnable() {
            @Override
            public void run() {
                long startTime = System.currentTimeMillis();

                MediaExtractor extractor = new MediaExtractor();
                try {
                    extractor.setDataSource(Environment.getExternalStorageDirectory().getPath() + "/test.h264");
                } catch (IOException e) {
                    e.printStackTrace();
                }

                MediaFormat format = extractor.getTrackFormat(0);
                String mime = format.getString(MediaFormat.KEY_MIME);

                MediaCodec codec = MediaCodec.createDecoderByType(mime);
                codec.configure(format, null, null, 0);
                codec.start();

                ByteBuffer[] inputBuffers = codec.getInputBuffers();
                ByteBuffer[] outputBuffers = codec.getOutputBuffers();
                MediaCodec.BufferInfo info = new MediaCodec.BufferInfo();
                boolean isEOS = false;
                long time = 0;

                while (!isEOS) {
                    int inputBufferIndex = codec.dequeueInputBuffer(10000);
                    if (inputBufferIndex >= 0) {
                        ByteBuffer inputBuffer = inputBuffers[inputBufferIndex];
                        int sampleSize = extractor.readSampleData(inputBuffer, 0);
                        if (sampleSize < 0) {
                            codec.queueInputBuffer(inputBufferIndex, 0, 0, 0, MediaCodec.BUFFER_FLAG_END_OF_STREAM);
                            isEOS = true;
                        } else {
                            time = extractor.getSampleTime();
                            codec.queueInputBuffer(inputBufferIndex, 0, sampleSize, time, 0);
                            extractor.advance();
                        }
                    }

                    int outputBufferIndex = codec.dequeueOutputBuffer(info, 10000);
                    if (outputBufferIndex >= 0) {
                        ByteBuffer outputBuffer = outputBuffers[outputBufferIndex];
                        codec.releaseOutputBuffer(outputBufferIndex, true);
                    }
                }

                codec.stop();
                codec.release();

                long endTime = System.currentTimeMillis();
                long elapsedTime = endTime - startTime;
                System.out.println("解码耗时:" + elapsedTime + "毫秒");
            }
        }).start();
    }
}

NOTE : 需要替换setDataSource()方法中的文件路径为你要测试的H.264文件路径。

5. Practical Examples

在这里插入图片描述

有一个文件目录里都是H.264的文件。文件名字是“(0,0)tile0crf15.264”,“(0,0)tile0crf17.264”,“(0,0)tile0crf19.264”,“(0,0)tile0crf21.264”,和 (0,0)tile0crf23.264等等共10000个文件。 写一个脚本,自动读取这个目录的文件,会根据文件名中的CRF值将文件分类,并使用FFmpeg解码每个文件,然后计算每个CRF值的平均解码时间。比如测试解码文件为xxxcrf17.264的平均时间是多少,测试解码文件为xxxcrf19.264的平均时间是多少,测试解码文件为xxxcrf21.264的平均时间是多少。

import os
import subprocess

# H.264文件所在目录
directory = 'files/'

# 不同crf值的文件名列表
crf_files = {
    15: [],
    17: [],
    19: [],
    21: [],
    23: []
}

# 根据文件名分类
for filename in os.listdir(directory):
    if filename.endswith(".264"):
        crf = int(filename.split('crf')[1].split('.')[0])
        crf_files[crf].append(filename)

# 解码每个文件并计算平均时间
for crf, files in crf_files.items():
    total_time = 0
    for file in files:
        command = ['ffmpeg', '-i', os.path.join(directory, file), '-f', 'null', '-']
        process = subprocess.Popen(command, stderr=subprocess.PIPE)
        for line in iter(process.stderr.readline, b''):
            line = line.decode('utf-8')
            if 'time=' in line:
                time_str = line.split('time=')[1].split()[0]
                time = float(time_str.replace(':', ''))
                total_time += time
                print(f"解码文件 {file} 的进度: {time_str}")

        process.communicate()
        process.wait()

    avg_time = total_time / len(files) if len(files) > 0 else 0
    print(f"测试解码文件为xxxcrf{crf}.264的平均时间是 {avg_time} 秒")


解码文件 (0,0)tile0crf15.264 的进度: 00:00:00.04
测试解码文件为xxxcrf15.264的平均时间是 0.04 秒
解码文件 (0,0)tile0crf17.264 的进度: 00:00:00.04
测试解码文件为xxxcrf17.264的平均时间是 0.04 秒
解码文件 (0,0)tile0crf19.264 的进度: 00:00:00.04
测试解码文件为xxxcrf19.264的平均时间是 0.04 秒
解码文件 (0,0)tile0crf21.264 的进度: 00:00:00.04
测试解码文件为xxxcrf21.264的平均时间是 0.04 秒
解码文件 (0,0)tile0crf23.264 的进度: 00:00:00.04
测试解码文件为xxxcrf23.264的平均时间是 0.04 秒
解码文件 (0,0)tile0crf27.264 的进度: 00:00:00.04
测试解码文件为xxxcrf27.264的平均时间是 0.04 秒
解码文件 (0,0)tile0crf32.264 的进度: 00:00:00.04
测试解码文件为xxxcrf32.264的平均时间是 0.04 秒
解码文件 (0,0)tile0crf37.264 的进度: 00:00:00.04
测试解码文件为xxxcrf37.264的平均时间是 0.04 秒
解码文件 (0,0)tile0crf41.264 的进度: 00:00:00.04
测试解码文件为xxxcrf41.264的平均时间是 0.04 秒
解码文件 (0,0)tile0crf45.264 的进度: 00:00:00.04
测试解码文件为xxxcrf45.264的平均时间是 0.04

对于质量相同但内容不同的H.264文件,解码时间可能会有一些差别,但差别通常不会很大。质量相同的文件表示它们在编码时使用的压缩参数相似,因此解码时的工作量也应该相似。然而,由于视频内容的不同可能会导致一些微小的差异,例如帧类型的分布、运动复杂度等,这些差异可能会导致解码时间略有不同。
总的来说,对于质量相同但内容不同的H.264文件,解码时间的差别通常不会很大,但可能会有一些轻微的变化。

对于内容相同但质量不同的H.264文件,解码时间可能会有一些特性,具体取决于编码时所使用的压缩参数和视频内容的复杂性。一般来说,质量较高的H.264文件(即低压缩率、较高码率)可能会导致解码时间稍长,因为解码器需要更多的计算来恢复更精细的图像质量。
另一方面,质量较低的H.264文件(即高压缩率、较低码率)可能会解码得更快,因为解码器需要处理的数据量更少。

但在某些情况下,质量较低的文件可能会因为压缩算法的特性而导致解码时间略有增加,例如出现了更多的预测误差或者需要更多的解码步骤来恢复图像细节。

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

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

相关文章

四连杆机构运动学仿真 | 【Matlab源码+理论公式文本】

【程序简介】&#x1f4bb;&#x1f50d; 本程序通过matlab实现了四连杆机构的运动学仿真编程&#xff0c;动态展现了四连杆机构的运动动画&#xff0c;同时给出了角位移、角速度和角加速度的时程曲线&#xff0c;除了程序本身&#xff0c;还提供了机构运动学公式推导文档&…

更安全的C gets()和str* 以及fgets和strcspn的用法

#include <stdio.h>int main() {char *str;gets(str);puts(str);return(0); }可以说全是错误 首先char *str没有指向一个分配好的地址&#xff0c;就直接读入&#xff0c;危险 ps: 怎么理解char *str "Hello World" 是将一个存储在一个只读的数据段中字符串常…

字符函数以及字符串函数

1.strlen的使用和模拟实现 • 字符串以 \0 作为结束标志&#xff0c;strlen函数返回的是在字符串中 \0 前⾯出现的字符个数&#xff08;不包 含 \0 )。 • 参数指向的字符串必须要以 \0 结束。 • 注意函数的返回值为size_t&#xff0c;是⽆符号的&#xff08; 易错 &#xff…

【C++】了解一下编码

个人主页 &#xff1a; zxctscl 如有转载请先通知 文章目录 1. 前言2. ASCII编码3. unicode4. GBK5. 类型转换 1. 前言 看到string里面还有Template instantiations&#xff1a; string其实是basic_string<char>&#xff0c;它还是一个模板。 再看看wstring&#xff1…

音频的录制及播放

在终端安装好pip install pyaudio&#xff0c;在pycharm中敲入录音的代码&#xff0c;然后点击运行可以在10s内进行录音&#xff0c;录音后的音频会保存在与录音代码同一路径项目中&#xff0c;然后再新建项目敲入播放的代码&#xff0c;点击运行&#xff0c;会把录入的录音进行…

更改el-tabs默认样式,实现tab标签居中显示,标签对应内容使用另一个div显示

首先看效果图 如图所示&#xff0c;标签在浏览器窗口居中&#xff0c;但是下面的内容依然是默认从左到右&#xff0c;不会受到tab样式的影响 <template><div><div style"display: flex; justify-content: center; align-items: center;"><el-…

文献阅读及笔记

每个阶段&#xff0c;该看什么文献 当我们刚开始接触课题时&#xff0c;对这个研究方向一无所知&#xff0c;可以选择硕博学位论文、领域大牛的文献综述当我们已经对课题有了解&#xff0c;处于深化认识的阶段&#xff0c;可以选择行业最新的论文&#xff0c;领域大牛的文献综…

探讨大世界游戏的制作流程及技术——大场景制作技术概况篇

接上文&#xff0c;我们接下来了解一下大世界场景制作技术有哪些&#xff0c;本篇旨在给大家过一遍目前业界的做法&#xff0c;能让大家有一个宏观的知识蓝图。实际上&#xff0c;针对不同的游戏类型和美术风格&#xff0c;制作技术在细节上有着非常大的不同&#xff0c;业界目…

开环端到端自动驾驶: 到底行不行

开环端到端自动驾驶&#xff1a; 到底行不行 附赠全面专业的自动驾驶学习资料&#xff1a;直达链接 TLDR: 别在nuScenes上做开环端到端自动驾驶刷点了。 论文&#xff1a; https://arxiv.org/pdf/2312.03031.pdf github: https://github.com/NVlabs/BEV-Planner 前言 Uni…

set与zset数据类型

set类型基础 redis集合(set)类型和list列表类型类似&#xff0c;都可以用来存储多个字符串元素的 集合。但是和list不同的是set集合当中不允许重复的元素。而且set集合当中元素是没有顺序的&#xff0c;不存在元素下标。 redis的set类型是使用哈希表构造的&#xff0c;因此复…

宠物疾病 与 光线疗法

人类与动物以及大自然是相辅相成的。人离开动物将无法生存&#xff0c;对于动物我们尽力去保护&#xff0c;与大自然和谐稳定生存发展。 生息在地球上的所有动物、在自然太阳光奇妙的作用下、生长发育。太阳光的能量使它们不断进化、繁衍种族。现在、生物能够生存、全仰仗于太…

什么是类加载器

类加载器&#xff08;Class Loader&#xff09;是 Java 虚拟机&#xff08;JVM&#xff09;的重要组成部分&#xff0c;负责将字节码文件加载到内存中并转换为可执行的类。 类加载总共分为以下四种&#xff1a; 启动类加载器&#xff08;Bootstrap Class Loader&#xff09;&…

(二)移植FreeRTOS到STM32中

一、概念 &#xff08;1&#xff09;任务&#xff08;线程&#xff09;&#xff1a;根据功能的不同&#xff0c;将一个系统分割成一个个独立且无法返回的函数&#xff0c;这个函数就被称为任务 &#xff08;2&#xff09;任务栈&#xff1a;静态创建的任务保存在栈中 &#xf…

layui2.9.7-入门初学

下载&#xff1a;https://layui.dev/ 下载后解压&#xff1a; 在hbuider中新建一个项目 将如上解压好的文件打开&#xff0c;复制如下到项目中 写案例&#xff0c;基础学习通之前的bootstrap 那样&#xff0c;挨个相中哪个就测试哪个&#xff0c;在这里不再重复罗列&#x…

刷题日记——三种方法秒杀《最大子串和》(厦大机试)

题目 分析——暴力 两个for循环&#xff0c;计算每一种子序&#xff08;连续&#xff09;和的值&#xff0c;找到最大时的自序起点和终点&#xff0c;输出即可 代码 #include <cstdio> #include <map> #include <string> #include <cmath> #include…

2024-03-14 Android app runOnUiThread 函数,它的作用是让一个Runnable对象在主线程(UI线程)上运行。

一、看到别人app有这么一个runOnUiThread 函数用法。 二、在Android中&#xff0c;runOnUiThread 是一个非常重要的方法&#xff0c;它的作用是让一个Runnable对象在主线程&#xff08;UI线程&#xff09;上运行。在Android中&#xff0c;主线程是负责更新UI的线程&#xff0c;…

StarRocks面试题及答案整理,最新面试题

StarRocks 的 MV&#xff08;物化视图&#xff09;机制是如何工作的&#xff1f; StarRocks 的物化视图&#xff08;MV&#xff09;机制通过预先计算和存储数据的聚合结果或者转换结果来提高查询性能。其工作原理如下&#xff1a; 1、数据预处理&#xff1a; 在创建物化视图时…

JOSEF约瑟 TQ-100同期继电器 额定直流电压220V 交流电压100V±10V

TQ-100型同期继电器 TQ-100同期继电器 ​ l 应用 本继电器用于双端供电线路的自动重合闸和备用电源自投装置中&#xff0c;以检查线路电压与母线电压的 相位差和幅值差。 2 主要性能 2 1采用进口集成电路和元器件构成&#xff0c;具有原理先进、性能稳定、可靠性高、动作值精…

电脑那个部件坏了或者是哪个软件需要修复来看价钱

电脑维修价格表是多少&#xff1f; 价格取决于计算机的哪个部分损坏或哪个软件需要修复。 由于电脑中的部件非常多&#xff0c;而且会以各种奇怪的方式出现问题&#xff0c;下面我们就来看看具体的充电方法。 电脑维修价格表&#xff1a; 1. 重新安装系统。 安装XP系统通常需…

双指针、bfs与图论

1238. 日志统计 - AcWing题库 import java.util.*;class PII implements Comparable<PII>{int x, y;public PII(int x, int y){this.x x;this.y y;}public int compareTo(PII o){return Integer.compare(x, o.x);} }public class Main{static int N 100010, D, K;st…