如何从 StageFright 媒体框架获取渲染帧统计信息(绘制/丢弃)?

发布于 2024-10-18 05:06:32 字数 119 浏览 6 评论 0原文

我是 Android 世界的新手,我必须在 Android 上编写一个流视频质量检查应用程序。我必须使用本机 StageFright 媒体框架来播放视频。据我所知,有一个渲染统计的本机 API,但我需要建议如何获取它。谢谢。

I'm very newbie in Android world and I have to write an streaming video quality checker application on Android. I have to use the native StageFright media framework to play videos. As far as I understand there is an native API of render statistics, but I need advice how I can get it. Thank you.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

久伴你 2024-10-25 05:06:32

有一个 ADB 命令可以打印播放帧率。

过程

  1. 在主机上的Windows(或Linux)上打开控制台。确保已安装所需的驱动程序,以便与设备(Android 手机或开发板)进行 USB 连接

  2. 运行以下命令
    <代码>$> adb Kill-server
    <代码>$> adb shell setprop debug.video.showfps 1

  3. 运行视频播放。如果视频正在使用 Android 媒体播放器堆栈运行,那么您将看到报告所达到的帧速率的打印。

There is an ADB command to print playback framerate.

Procedure

  1. Open console on windows (or linux) on the host. Make sure that required drivers have been installed for USB connectivity with the device (android phone or board)

  2. Run the following commands
    $> adb kill-server
    $> adb shell setprop debug.video.showfps 1

  3. Run the video playback. If the video is being run using Android Media player stack, then you will see prints reporting frame rate achieved.

花开浅夏 2024-10-25 05:06:32

也欢迎您使用它,在渲染的每个帧的开头和结尾调用它。它是 NDK 中的一些示例代码的稍微修改的版本:

stats.c:

#include <sys/time.h>
#include <string.h>
#include <android/log.h>
#include <stdio.h>
#include "stats.h"

#define  LOG_TAG    "[STATS]"
#define  LOGI(...)  __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)
#define  LOGW(...)  __android_log_print(ANDROID_LOG_WARN,LOG_TAG,__VA_ARGS__)
#define  LOGE(...)  __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__)
#define  STATS_DUMP(...) __android_

double now_ms()
{
    struct timeval tv;
    gettimeofday(&tv, NULL);
    return tv.tv_sec*1000. + tv.tv_usec/1000.;
}

void stats_init(Stats* s)
{
    s->lastTime = now_ms();
    s->firstTime = 0.;
    s->firstFrame = 0;
    s->numFrames = 0;
    s->dump = malloc(128);
    memset(s->dump,0,128);
}

void stats_startFrame(Stats* s)
{
    s->frameTime = now_ms();
}

void stats_endFrame(Stats* s)
{
    double now = now_ms();
    double renderTime = now - s->frameTime;
    double frameTime  = now - s->lastTime;
    int nn;
    if (now - s->firstTime >= MAX_PERIOD_MS) {
        if (s->numFrames > 0) {
                double renderTime = now - s->frameTime;
                double frameTime  = now - s->lastTime;
                int nn;
                double minRender, maxRender, avgRender;
                double minFrame, maxFrame, avgFrame;
                int count;
                nn = s->firstFrame;
                minRender = maxRender = avgRender = s->frames[nn].renderTime;
                minFrame  = maxFrame  = avgFrame  = s->frames[nn].frameTime;
                for (count = s->numFrames; count > 0; count-- ) {
                    nn += 1;
                    if (nn >= MAX_FRAME_STATS)
                        nn -= MAX_FRAME_STATS;
                    double render = s->frames[nn].renderTime;
                    if (render < minRender) minRender = render;
                    if (render > maxRender) maxRender = render;
                    double frame = s->frames[nn].frameTime;
                    if (frame < minFrame) minFrame = frame;
                    if (frame > maxFrame) maxFrame = frame;
                    avgRender += render;
                    avgFrame  += frame;
                }
                avgRender /= s->numFrames;
                avgFrame  /= s->numFrames;
                sprintf(s->dump,"Frames per second - [AVG:%.1f] [MIN:%.1f] [MAX:%.1f]Rendering time ms - [AVG:%.1f] [MIN:%.1f] [MAX:%.1f]", 1000./avgFrame, 1000./maxFrame, 1000./minFrame, avgRender, minRender, maxRender);
                //LOGI("Frames per second - [AVG:%.1f] [MIN:%.1f] [MAX:%.1f]Rendering time ms - [AVG:%.1f] [MIN:%.1f] [MAX:%.1f]", 1000./avgFrame, 1000./maxFrame, 1000./minFrame, avgRender, minRender, maxRender);
        }
        s->numFrames  = 0;
        s->firstFrame = 0;
        s->firstTime  = now;
    }
    nn = s->firstFrame + s->numFrames;
    if (nn >= MAX_FRAME_STATS)
        nn -= MAX_FRAME_STATS;

    s->frames[nn].renderTime = renderTime;
    s->frames[nn].frameTime  = frameTime;

    if (s->numFrames < MAX_FRAME_STATS) {
        s->numFrames += 1;
    } else {
        s->firstFrame += 1;
        if (s->firstFrame >= MAX_FRAME_STATS)
            s->firstFrame -= MAX_FRAME_STATS;
    }

    s->lastTime = now;
}

stats.h:

#include <jni.h>
#define  MAX_FRAME_STATS  120
#define  MAX_PERIOD_MS    5000

typedef struct{
    double  renderTime;
    double  frameTime;
} FrameStats;

typedef struct{
    double  firstTime;
    double  lastTime;
    double  frameTime;
    int         firstFrame;
    int         numFrames;
    FrameStats  frames[ MAX_FRAME_STATS ];
    char* dump;
} Stats;

extern double now_ms();

extern void stats_init(Stats *);

extern int stats_dump(Stats *);

extern void stats_startFrame(Stats *);

extern void stats_endFrame(Stats *);

You're welcome to use this as well, call it at the beginning and end of each frame rendered. It's a slightly altered version of some sample code from the NDK:

stats.c:

#include <sys/time.h>
#include <string.h>
#include <android/log.h>
#include <stdio.h>
#include "stats.h"

#define  LOG_TAG    "[STATS]"
#define  LOGI(...)  __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)
#define  LOGW(...)  __android_log_print(ANDROID_LOG_WARN,LOG_TAG,__VA_ARGS__)
#define  LOGE(...)  __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__)
#define  STATS_DUMP(...) __android_

double now_ms()
{
    struct timeval tv;
    gettimeofday(&tv, NULL);
    return tv.tv_sec*1000. + tv.tv_usec/1000.;
}

void stats_init(Stats* s)
{
    s->lastTime = now_ms();
    s->firstTime = 0.;
    s->firstFrame = 0;
    s->numFrames = 0;
    s->dump = malloc(128);
    memset(s->dump,0,128);
}

void stats_startFrame(Stats* s)
{
    s->frameTime = now_ms();
}

void stats_endFrame(Stats* s)
{
    double now = now_ms();
    double renderTime = now - s->frameTime;
    double frameTime  = now - s->lastTime;
    int nn;
    if (now - s->firstTime >= MAX_PERIOD_MS) {
        if (s->numFrames > 0) {
                double renderTime = now - s->frameTime;
                double frameTime  = now - s->lastTime;
                int nn;
                double minRender, maxRender, avgRender;
                double minFrame, maxFrame, avgFrame;
                int count;
                nn = s->firstFrame;
                minRender = maxRender = avgRender = s->frames[nn].renderTime;
                minFrame  = maxFrame  = avgFrame  = s->frames[nn].frameTime;
                for (count = s->numFrames; count > 0; count-- ) {
                    nn += 1;
                    if (nn >= MAX_FRAME_STATS)
                        nn -= MAX_FRAME_STATS;
                    double render = s->frames[nn].renderTime;
                    if (render < minRender) minRender = render;
                    if (render > maxRender) maxRender = render;
                    double frame = s->frames[nn].frameTime;
                    if (frame < minFrame) minFrame = frame;
                    if (frame > maxFrame) maxFrame = frame;
                    avgRender += render;
                    avgFrame  += frame;
                }
                avgRender /= s->numFrames;
                avgFrame  /= s->numFrames;
                sprintf(s->dump,"Frames per second - [AVG:%.1f] [MIN:%.1f] [MAX:%.1f]Rendering time ms - [AVG:%.1f] [MIN:%.1f] [MAX:%.1f]", 1000./avgFrame, 1000./maxFrame, 1000./minFrame, avgRender, minRender, maxRender);
                //LOGI("Frames per second - [AVG:%.1f] [MIN:%.1f] [MAX:%.1f]Rendering time ms - [AVG:%.1f] [MIN:%.1f] [MAX:%.1f]", 1000./avgFrame, 1000./maxFrame, 1000./minFrame, avgRender, minRender, maxRender);
        }
        s->numFrames  = 0;
        s->firstFrame = 0;
        s->firstTime  = now;
    }
    nn = s->firstFrame + s->numFrames;
    if (nn >= MAX_FRAME_STATS)
        nn -= MAX_FRAME_STATS;

    s->frames[nn].renderTime = renderTime;
    s->frames[nn].frameTime  = frameTime;

    if (s->numFrames < MAX_FRAME_STATS) {
        s->numFrames += 1;
    } else {
        s->firstFrame += 1;
        if (s->firstFrame >= MAX_FRAME_STATS)
            s->firstFrame -= MAX_FRAME_STATS;
    }

    s->lastTime = now;
}

stats.h:

#include <jni.h>
#define  MAX_FRAME_STATS  120
#define  MAX_PERIOD_MS    5000

typedef struct{
    double  renderTime;
    double  frameTime;
} FrameStats;

typedef struct{
    double  firstTime;
    double  lastTime;
    double  frameTime;
    int         firstFrame;
    int         numFrames;
    FrameStats  frames[ MAX_FRAME_STATS ];
    char* dump;
} Stats;

extern double now_ms();

extern void stats_init(Stats *);

extern int stats_dump(Stats *);

extern void stats_startFrame(Stats *);

extern void stats_endFrame(Stats *);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文