How can I get rendered frames statistics (drawn/dropped) from StageFright Media Framework?

3.3k views Asked by At

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.

2

There are 2 answers

0
Justin Buser On

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 *);
0
Shash316 On

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.