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

Commit 2f711fec authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "JAudioTrack: Create StreamEventCallback in MediaPlayer2Impl"

parents 02a72280 8e5ef909
Loading
Loading
Loading
Loading
+66 −15
Original line number Diff line number Diff line
@@ -17,7 +17,6 @@
package android.media;

import android.annotation.CallbackExecutor;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.ActivityThread;
@@ -26,7 +25,6 @@ import android.content.ContentResolver;
import android.content.Context;
import android.content.res.AssetFileDescriptor;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
@@ -48,17 +46,8 @@ import android.view.Surface;
import android.view.SurfaceHolder;
import android.widget.VideoView;
import android.graphics.SurfaceTexture;
import android.media.AudioManager;
import android.media.MediaDrm;
import android.media.MediaFormat;
import android.media.MediaPlayer2;
import android.media.MediaTimeProvider;
import android.media.PlaybackParams;
import android.media.SubtitleController;
import android.media.SubtitleController.Anchor;
import android.media.SubtitleData;
import android.media.SubtitleTrack.RenderingWidget;
import android.media.SyncParams;

import com.android.internal.annotations.GuardedBy;
import com.android.internal.util.Preconditions;
@@ -74,16 +63,12 @@ import java.io.FileDescriptor;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.AutoCloseable;
import java.lang.Runnable;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.ref.WeakReference;
import java.net.CookieHandler;
import java.net.CookieManager;
import java.net.HttpCookie;
import java.net.HttpURLConnection;
import java.net.InetSocketAddress;
import java.net.URL;
import java.nio.ByteOrder;
import java.util.ArrayList;
@@ -2190,6 +2175,13 @@ public final class MediaPlayer2Impl extends MediaPlayer2 {
    private native final void native_setup(Object mediaplayer2_this);
    private native final void native_finalize();

    private static native final void native_stream_event_onTearDown(
            long nativeCallbackPtr, long userDataPtr);
    private static native final void native_stream_event_onStreamPresentationEnd(
            long nativeCallbackPtr, long userDataPtr);
    private static native final void native_stream_event_onStreamDataRequest(
            long jAudioTrackPtr, long nativeCallbackPtr, long userDataPtr);

    /**
     * Class for MediaPlayer2 to return each audio/video/subtitle track's metadata.
     *
@@ -4228,6 +4220,65 @@ public final class MediaPlayer2Impl extends MediaPlayer2 {

    }

    // Called from the native side
    @SuppressWarnings("unused")
    private static boolean setAudioOutputDeviceById(AudioTrack track, int deviceId) {
        if (track == null) {
            return false;
        }

        if (deviceId == 0) {
            // Use default routing.
            track.setPreferredDevice(null);
            return true;
        }

        // TODO: Unhide AudioManager.getDevicesStatic.
        AudioDeviceInfo[] outputDevices =
                AudioManager.getDevicesStatic(AudioManager.GET_DEVICES_OUTPUTS);

        boolean success = false;
        for (AudioDeviceInfo device : outputDevices) {
            if (device.getId() == deviceId) {
                track.setPreferredDevice(device);
                success = true;
                break;
            }
        }
        return success;
    }

    // Instantiated from the native side
    @SuppressWarnings("unused")
    private static class StreamEventCallback extends AudioTrack.StreamEventCallback {
        public long mJAudioTrackPtr;
        public long mNativeCallbackPtr;
        public long mUserDataPtr;

        public StreamEventCallback(long jAudioTrackPtr, long nativeCallbackPtr, long userDataPtr) {
            super();
            mJAudioTrackPtr = jAudioTrackPtr;
            mNativeCallbackPtr = nativeCallbackPtr;
            mUserDataPtr = userDataPtr;
        }

        @Override
        public void onTearDown(AudioTrack track) {
            native_stream_event_onTearDown(mNativeCallbackPtr, mUserDataPtr);
        }

        @Override
        public void onStreamPresentationEnd(AudioTrack track) {
            native_stream_event_onStreamPresentationEnd(mNativeCallbackPtr, mUserDataPtr);
        }

        @Override
        public void onStreamDataRequest(AudioTrack track) {
            native_stream_event_onStreamDataRequest(
                    mJAudioTrackPtr, mNativeCallbackPtr, mUserDataPtr);
        }
    }

    private class ProvisioningThread extends Thread {
        public static final int TIMEOUT_MS = 60000;

+65 −0
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@
#include <media/NdkWrapper.h>
#include <media/stagefright/Utils.h>
#include <media/stagefright/foundation/ByteUtils.h>  // for FOURCC definition
#include <mediaplayer2/JAudioTrack.h>
#include <mediaplayer2/mediaplayer2.h>
#include <stdio.h>
#include <assert.h>
@@ -1387,6 +1388,65 @@ static void android_media_MediaPlayer2_enableDeviceCallback(
// AudioRouting end
// ----------------------------------------------------------------------------

/////////////////////////////////////////////////////////////////////////////////////
// AudioTrack.StreamEventCallback begin
static void android_media_MediaPlayer2_native_on_tear_down(JNIEnv *env __unused,
        jobject thiz __unused, jlong callbackPtr, jlong userDataPtr)
{
    JAudioTrack::callback_t callback = (JAudioTrack::callback_t) callbackPtr;
    if (callback != NULL) {
        callback(JAudioTrack::EVENT_NEW_IAUDIOTRACK, (void *) userDataPtr, NULL);
    }
}

static void android_media_MediaPlayer2_native_on_stream_presentation_end(JNIEnv *env __unused,
        jobject thiz __unused, jlong callbackPtr, jlong userDataPtr)
{
    JAudioTrack::callback_t callback = (JAudioTrack::callback_t) callbackPtr;
    if (callback != NULL) {
        callback(JAudioTrack::EVENT_STREAM_END, (void *) userDataPtr, NULL);
    }
}

static void android_media_MediaPlayer2_native_on_stream_data_request(JNIEnv *env __unused,
        jobject thiz __unused, jlong jAudioTrackPtr, jlong callbackPtr, jlong userDataPtr)
{
    JAudioTrack::callback_t callback = (JAudioTrack::callback_t) callbackPtr;
    JAudioTrack* track = (JAudioTrack *) jAudioTrackPtr;
    if (callback != NULL && track != NULL) {
        JAudioTrack::Buffer* buffer = new JAudioTrack::Buffer();

        size_t bufferSizeInFrames = track->frameCount();
        audio_format_t format = track->format();

        size_t bufferSizeInBytes;
        if (audio_has_proportional_frames(format)) {
            bufferSizeInBytes =
                    bufferSizeInFrames * audio_bytes_per_sample(format) * track->channelCount();
        } else {
            // See Javadoc of AudioTrack::getBufferSizeInFrames().
            bufferSizeInBytes = bufferSizeInFrames;
        }

        uint8_t* byteBuffer = new uint8_t[bufferSizeInBytes];
        buffer->mSize = bufferSizeInBytes;
        buffer->mData = (void *) byteBuffer;

        callback(JAudioTrack::EVENT_MORE_DATA, (void *) userDataPtr, buffer);

        if (buffer->mSize > 0 && buffer->mData == byteBuffer) {
            track->write(buffer->mData, buffer->mSize, true /* Blocking */);
        }

        delete[] byteBuffer;
        delete buffer;
    }
}


// AudioTrack.StreamEventCallback end
// ----------------------------------------------------------------------------

static const JNINativeMethod gMethods[] = {
    {
        "nativeSetDataSource",
@@ -1443,6 +1503,11 @@ static const JNINativeMethod gMethods[] = {
    {"native_setOutputDevice", "(I)Z",                          (void *)android_media_MediaPlayer2_setOutputDevice},
    {"native_getRoutedDeviceId", "()I",                         (void *)android_media_MediaPlayer2_getRoutedDeviceId},
    {"native_enableDeviceCallback", "(Z)V",                     (void *)android_media_MediaPlayer2_enableDeviceCallback},

    // StreamEventCallback for JAudioTrack
    {"native_stream_event_onTearDown",                "(JJ)V",  (void *)android_media_MediaPlayer2_native_on_tear_down},
    {"native_stream_event_onStreamPresentationEnd",   "(JJ)V",  (void *)android_media_MediaPlayer2_native_on_stream_presentation_end},
    {"native_stream_event_onStreamDataRequest",       "(JJJ)V", (void *)android_media_MediaPlayer2_native_on_stream_data_request},
};

// This function only registers the native methods