Metrics for android.media.MediaRecorder

Implementation of getMetrics() API and underlying metrics gathering
for android.media.MediaRecorder.

Bug: 35150984
Test: hacked CTS, observing of 'dumpsys media.metrics'
This commit is contained in:
Ray Essick
2017-02-12 19:22:48 -08:00
parent 49f38bb487
commit b0bd62f96c
5 changed files with 125 additions and 0 deletions

View File

@@ -22448,6 +22448,7 @@ package android.media {
ctor public MediaRecorder();
method public static final int getAudioSourceMax();
method public int getMaxAmplitude() throws java.lang.IllegalStateException;
method public android.os.Bundle getMetrics();
method public android.view.Surface getSurface();
method public void pause() throws java.lang.IllegalStateException;
method public void prepare() throws java.io.IOException, java.lang.IllegalStateException;

View File

@@ -24068,6 +24068,7 @@ package android.media {
ctor public MediaRecorder();
method public static final int getAudioSourceMax();
method public int getMaxAmplitude() throws java.lang.IllegalStateException;
method public android.os.Bundle getMetrics();
method public android.view.Surface getSurface();
method public void pause() throws java.lang.IllegalStateException;
method public void prepare() throws java.io.IOException, java.lang.IllegalStateException;

View File

@@ -22540,6 +22540,7 @@ package android.media {
ctor public MediaRecorder();
method public static final int getAudioSourceMax();
method public int getMaxAmplitude() throws java.lang.IllegalStateException;
method public android.os.Bundle getMetrics();
method public android.view.Surface getSurface();
method public void pause() throws java.lang.IllegalStateException;
method public void prepare() throws java.io.IOException, java.lang.IllegalStateException;

View File

@@ -20,6 +20,7 @@ import android.annotation.NonNull;
import android.annotation.SystemApi;
import android.app.ActivityThread;
import android.hardware.Camera;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
@@ -1257,6 +1258,93 @@ public class MediaRecorder
private native void setParameter(String nameValuePair);
/**
* Returns Metrics data about the current media container.
*
* @return the set of keys and values available for the media being
* handled by this instance of MediaExtractor. The keys, data types,
* and meaning are described in the following table.
*
* <table style="width: 0%">
* <thead>
* <tr>
* <th>Key</th>
* <th>Type</th>
* <th>Description</th>
* </tr>
* </thead>
* <tbody>
* <tr>
* <td>{@code "ht"}</td>
* <td>Integer</td>
* <td>Height of the recorded video (pixels)</td>
* </tr><tr>
* <td>{@code "wid"}</td>
* <td>Integer</td>
* <td>Width of the recorded video (pixels)</td>
* </tr><tr>
* <td>{@code "frame-rate"}</td>
* <td>Integer</td>
* <td>Framerate of captured Video (frames per second)</td>
* </tr><tr>
* <td>{@code "video-bitrate"}</td>
* <td>Integer</td>
* <td>Bit rate of encoded video (bits per second)</td>
* </tr><tr>
* <td>{@code "video-iframe-interval"}</td>
* <td>Integer</td>
* <td>Interval between encoded IFrames (seconds)</td>
* </tr><tr>
* <td>{@code "video-timescale"}</td>
* <td>Integer</td>
* <td></td>
* </tr><tr>
* <td>{@code "video-encoder-profile"}</td>
* <td>Integer</td>
* <td>Video Encoder Profile, as defined in OpenMAX IL</td>
* </tr><tr>
* <td>{@code "video-encoder-level"}</td>
* <td>Integer</td>
* <td>Video Encoder Level, as defined in OpenMAX IL</td>
* </tr><tr>
* <td>{@code "audio-bitrate"}</td>
* <td>Integer</td>
* <td>Bitrate of encoded audio (bits per second)</td>
* </tr><tr>
* <td>{@code "audio-samplerate"}</td>
* <td>Integer</td>
* <td></td>
* </tr><tr>
* <td>{@code "audio-channels"}</td>
* <td>Integer</td>
* <td>Number of Audio Channels Captured</td>
* </tr><tr>
* <td>{@code "audio-timescale"}</td>
* <td>Integer</td>
* <td></td>
* </tr><tr>
* <td>{@code "movie-timescale"}</td>
* <td>Integer</td>
* <td></td>
* </tr><tr>
* <td>{@code "movie-timescale"}</td>
* <td>Integer</td>
* <td></td>
* </tr><tr>
* <td>{@code "capture-fps"}</td>
* <td>Integer</td>
* <td></td>
* </tr><tr>
* <td>{@code "rotation"}</td>
* <td>Integer</td>
* <td>Orientation of the Video (degrees)</td>
* </tr>
* </tbody>
* </table>
*/
public native Bundle getMetrics();
@Override
protected void finalize() { native_finalize(); }
}

View File

@@ -28,6 +28,7 @@
#include <gui/Surface.h>
#include <camera/Camera.h>
#include <media/mediarecorder.h>
#include <media/MediaAnalyticsItem.h>
#include <media/stagefright/PersistentSurface.h>
#include <utils/threads.h>
@@ -35,6 +36,7 @@
#include "jni.h"
#include "JNIHelp.h"
#include "android_media_MediaMetricsJNI.h"
#include "android_runtime/AndroidRuntime.h"
#include <system/audio.h>
@@ -625,6 +627,36 @@ void android_media_MediaRecorder_setInputSurface(
"java/lang/IllegalArgumentException", "native_setInputSurface failed.");
}
static jobject
android_media_MediaRecorder_getMetrics(JNIEnv *env, jobject thiz)
{
ALOGV("android_media_MediaRecorder_getMetrics");
sp<MediaRecorder> mr = getMediaRecorder(env, thiz);
if (mr == NULL) {
jniThrowException(env, "java/lang/IllegalStateException", NULL);
return NULL;
}
// get what we have for the metrics from the codec
Parcel reply;
status_t err = mr->getMetrics(&reply);
if (err != OK) {
ALOGE("getMetrics failed");
return (jobject) NULL;
}
// build and return the Bundle
MediaAnalyticsItem *item = new MediaAnalyticsItem;
item->readFromParcel(reply);
jobject mybundle = MediaMetricsJNI::writeMetricsToBundle(env, item, NULL);
// housekeeping
delete item;
item = NULL;
return mybundle;
}
// ----------------------------------------------------------------------------
static const JNINativeMethod gMethods[] = {
@@ -655,6 +687,8 @@ static const JNINativeMethod gMethods[] = {
(void *)android_media_MediaRecorder_native_setup},
{"native_finalize", "()V", (void *)android_media_MediaRecorder_native_finalize},
{"native_setInputSurface", "(Landroid/view/Surface;)V", (void *)android_media_MediaRecorder_setInputSurface },
{"getMetrics", "()Landroid/os/Bundle;", (void *)android_media_MediaRecorder_getMetrics},
};
// This function only registers the native methods, and is called from