Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b0bd62f9 authored by Ray Essick's avatar Ray Essick
Browse files

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'
parent 49f38bb4
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -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;
+1 −0
Original line number Diff line number Diff line
@@ -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;
+1 −0
Original line number Diff line number Diff line
@@ -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;
+88 −0
Original line number Diff line number Diff line
@@ -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(); }
}
+34 −0
Original line number Diff line number Diff line
@@ -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