android_media_MediaSync.cpp revision 05ebffe6bf6cdacc6de4b3bbf480c31869a81661
1071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia/*
2071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia * Copyright 2015, The Android Open Source Project
3071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia *
4071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia * Licensed under the Apache License, Version 2.0 (the "License");
5071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia * you may not use this file except in compliance with the License.
6071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia * You may obtain a copy of the License at
7071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia *
8071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia *     http://www.apache.org/licenses/LICENSE-2.0
9071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia *
10071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia * Unless required by applicable law or agreed to in writing, software
11071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia * distributed under the License is distributed on an "AS IS" BASIS,
12071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia * See the License for the specific language governing permissions and
14071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia * limitations under the License.
15071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia */
16071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia
17071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia//#define LOG_NDEBUG 0
18071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia#define LOG_TAG "MediaSync-JNI"
19071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia#include <utils/Log.h>
20071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia
21071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia#include "android_media_MediaSync.h"
22071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia
23071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia#include "android_media_AudioTrack.h"
2405ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar#include "android_media_PlaybackSettings.h"
25c98f58efd147c574faa4a4f9956b5ab95e3027a5Lajos Molnar#include "android_media_SyncSettings.h"
26071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia#include "android_runtime/AndroidRuntime.h"
27071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia#include "android_runtime/android_view_Surface.h"
28071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia#include "jni.h"
29071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia#include "JNIHelp.h"
30071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia
31071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia#include <gui/Surface.h>
32071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia
3305ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar#include <media/AudioResamplerPublic.h>
34071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia#include <media/AudioTrack.h>
35217ec0adfc35302a6cc6b04bc78bf8fd82ffc8a5Wei Jia#include <media/stagefright/MediaClock.h>
36071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia#include <media/stagefright/MediaSync.h>
37071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia#include <media/stagefright/foundation/ADebug.h>
38071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia#include <media/stagefright/foundation/AString.h>
39071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia
40071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia#include <nativehelper/ScopedLocalRef.h>
41071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia
42071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jianamespace android {
43071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia
44071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jiastruct fields_t {
45071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia    jfieldID context;
46217ec0adfc35302a6cc6b04bc78bf8fd82ffc8a5Wei Jia    jfieldID mediaTimestampMediaTimeUsID;
47217ec0adfc35302a6cc6b04bc78bf8fd82ffc8a5Wei Jia    jfieldID mediaTimestampNanoTimeID;
48217ec0adfc35302a6cc6b04bc78bf8fd82ffc8a5Wei Jia    jfieldID mediaTimestampClockRateID;
49071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia};
50071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia
51071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jiastatic fields_t gFields;
5205ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnarstatic PlaybackSettings::fields_t gPlaybackSettingsFields;
53c98f58efd147c574faa4a4f9956b5ab95e3027a5Lajos Molnarstatic SyncSettings::fields_t gSyncSettingsFields;
54071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia
55071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia////////////////////////////////////////////////////////////////////////////////
56071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia
57071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei JiaJMediaSync::JMediaSync() {
58071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia    mSync = MediaSync::create();
59071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia}
60071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia
61071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei JiaJMediaSync::~JMediaSync() {
62071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia}
63071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia
64071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jiastatus_t JMediaSync::configureSurface(const sp<IGraphicBufferProducer> &bufferProducer) {
65071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia    return mSync->configureSurface(bufferProducer);
66071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia}
67071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia
6805ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnarstatus_t JMediaSync::configureAudioTrack(const sp<AudioTrack> &audioTrack) {
6905ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar    return mSync->configureAudioTrack(audioTrack);
70071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia}
71071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia
72071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jiastatus_t JMediaSync::createInputSurface(
73071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia        sp<IGraphicBufferProducer>* bufferProducer) {
74071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia    return mSync->createInputSurface(bufferProducer);
75071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia}
76071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia
77217ec0adfc35302a6cc6b04bc78bf8fd82ffc8a5Wei Jiasp<const MediaClock> JMediaSync::getMediaClock() {
78217ec0adfc35302a6cc6b04bc78bf8fd82ffc8a5Wei Jia    return mSync->getMediaClock();
79217ec0adfc35302a6cc6b04bc78bf8fd82ffc8a5Wei Jia}
80217ec0adfc35302a6cc6b04bc78bf8fd82ffc8a5Wei Jia
8105ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnarstatus_t JMediaSync::setPlaybackSettings(const AudioPlaybackRate& rate) {
8205ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar    return mSync->setPlaybackSettings(rate);
8305ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar}
8405ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar
8505ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnarvoid JMediaSync::getPlaybackSettings(AudioPlaybackRate* rate /* nonnull */) {
8605ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar    mSync->getPlaybackSettings(rate);
8705ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar}
8805ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar
8905ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnarstatus_t JMediaSync::setSyncSettings(const AVSyncSettings& syncSettings) {
9005ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar    return mSync->setSyncSettings(syncSettings);
9105ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar}
9205ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar
9305ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnarvoid JMediaSync::getSyncSettings(AVSyncSettings* syncSettings /* nonnull */) {
9405ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar    mSync->getSyncSettings(syncSettings);
9505ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar}
9605ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar
9705ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnarstatus_t JMediaSync::setVideoFrameRateHint(float rate) {
9805ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar    return mSync->setVideoFrameRateHint(rate);
9905ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar}
10005ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar
10105ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnarfloat JMediaSync::getVideoFrameRate() {
10205ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar    return mSync->getVideoFrameRate();
10305ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar}
10405ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar
105071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jiastatus_t JMediaSync::updateQueuedAudioData(
106071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia        int sizeInBytes, int64_t presentationTimeUs) {
107071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia    return mSync->updateQueuedAudioData(sizeInBytes, presentationTimeUs);
108071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia}
109071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia
11025b802d47249702b9e5d175b3e7144934b67553dWei Jiastatus_t JMediaSync::getPlayTimeForPendingAudioFrames(int64_t *outTimeUs) {
11125b802d47249702b9e5d175b3e7144934b67553dWei Jia    return mSync->getPlayTimeForPendingAudioFrames(outTimeUs);
11225b802d47249702b9e5d175b3e7144934b67553dWei Jia}
11325b802d47249702b9e5d175b3e7144934b67553dWei Jia
114071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia}  // namespace android
115071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia
116071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia////////////////////////////////////////////////////////////////////////////////
117071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia
118071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jiausing namespace android;
119071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia
120071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jiastatic sp<JMediaSync> setMediaSync(JNIEnv *env, jobject thiz, const sp<JMediaSync> &sync) {
121071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia    sp<JMediaSync> old = (JMediaSync *)env->GetLongField(thiz, gFields.context);
122071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia    if (sync != NULL) {
123071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia        sync->incStrong(thiz);
124071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia    }
125071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia    if (old != NULL) {
126071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia        old->decStrong(thiz);
127071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia    }
128071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia
129071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia    env->SetLongField(thiz, gFields.context, (jlong)sync.get());
130071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia
131071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia    return old;
132071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia}
133071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia
134071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jiastatic sp<JMediaSync> getMediaSync(JNIEnv *env, jobject thiz) {
135071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia    return (JMediaSync *)env->GetLongField(thiz, gFields.context);
136071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia}
137071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia
138071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jiastatic void android_media_MediaSync_release(JNIEnv *env, jobject thiz) {
139071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia    setMediaSync(env, thiz, NULL);
140071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia}
141071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia
142071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jiastatic void throwExceptionAsNecessary(
143071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia        JNIEnv *env, status_t err, const char *msg = NULL) {
144071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia    switch (err) {
1450feab71799d2290595d42dec401903cb7d983c40Wei Jia        case NO_ERROR:
146071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia            break;
147071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia
148071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia        case BAD_VALUE:
149071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia            jniThrowException(env, "java/lang/IllegalArgumentException", msg);
150071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia            break;
151071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia
1520feab71799d2290595d42dec401903cb7d983c40Wei Jia        case NO_INIT:
1530feab71799d2290595d42dec401903cb7d983c40Wei Jia        case INVALID_OPERATION:
154071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia        default:
1550feab71799d2290595d42dec401903cb7d983c40Wei Jia            if (err > 0) {
1560feab71799d2290595d42dec401903cb7d983c40Wei Jia                break;
1570feab71799d2290595d42dec401903cb7d983c40Wei Jia            }
1580feab71799d2290595d42dec401903cb7d983c40Wei Jia            AString msgWithErrorCode(msg);
1590feab71799d2290595d42dec401903cb7d983c40Wei Jia            msgWithErrorCode.append(" error:");
1600feab71799d2290595d42dec401903cb7d983c40Wei Jia            msgWithErrorCode.append(err);
1610feab71799d2290595d42dec401903cb7d983c40Wei Jia            jniThrowException(env, "java/lang/IllegalStateException", msgWithErrorCode.c_str());
162071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia            break;
163071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia    }
164071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia}
165071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia
166071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jiastatic void android_media_MediaSync_native_configureSurface(
167071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia        JNIEnv *env, jobject thiz, jobject jsurface) {
168071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia    ALOGV("android_media_MediaSync_configureSurface");
169071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia
170071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia    sp<JMediaSync> sync = getMediaSync(env, thiz);
171071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia    if (sync == NULL) {
172071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia        throwExceptionAsNecessary(env, INVALID_OPERATION);
173071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia        return;
174071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia    }
175071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia
176071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia    sp<IGraphicBufferProducer> bufferProducer;
177071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia    if (jsurface != NULL) {
178071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia        sp<Surface> surface(android_view_Surface_getSurface(env, jsurface));
179071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia        if (surface != NULL) {
180071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia            bufferProducer = surface->getIGraphicBufferProducer();
181071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia        } else {
182071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia            throwExceptionAsNecessary(env, BAD_VALUE, "The surface has been released");
183071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia            return;
184071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia        }
185071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia    }
186071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia
187071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia    status_t err = sync->configureSurface(bufferProducer);
188071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia
189071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia    if (err == INVALID_OPERATION) {
190071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia        throwExceptionAsNecessary(
191071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia                env, INVALID_OPERATION, "Surface has already been configured");
192071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia    } if (err != NO_ERROR) {
193071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia        AString msg("Failed to connect to surface with error ");
194071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia        msg.append(err);
195071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia        throwExceptionAsNecessary(env, BAD_VALUE, msg.c_str());
196071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia    }
197071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia}
198071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia
199071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jiastatic void android_media_MediaSync_native_configureAudioTrack(
20005ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar        JNIEnv *env, jobject thiz, jobject jaudioTrack) {
201071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia    ALOGV("android_media_MediaSync_configureAudioTrack");
202071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia
203071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia    sp<JMediaSync> sync = getMediaSync(env, thiz);
204071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia    if (sync == NULL) {
205071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia        throwExceptionAsNecessary(env, INVALID_OPERATION);
206071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia        return;
207071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia    }
208071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia
209071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia    sp<AudioTrack> audioTrack;
210071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia    if (jaudioTrack != NULL) {
211071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia        audioTrack = android_media_AudioTrack_getAudioTrack(env, jaudioTrack);
212071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia        if (audioTrack == NULL) {
213071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia            throwExceptionAsNecessary(env, BAD_VALUE, "The audio track has been released");
214071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia            return;
215071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia        }
216071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia    }
217071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia
21805ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar    status_t err = sync->configureAudioTrack(audioTrack);
219071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia
220071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia    if (err == INVALID_OPERATION) {
221071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia        throwExceptionAsNecessary(
222071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia                env, INVALID_OPERATION, "Audio track has already been configured");
223071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia    } if (err != NO_ERROR) {
224071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia        AString msg("Failed to configure audio track with error ");
225071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia        msg.append(err);
226071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia        throwExceptionAsNecessary(env, BAD_VALUE, msg.c_str());
227071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia    }
228071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia}
229071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia
230071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jiastatic jobject android_media_MediaSync_createInputSurface(
231071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia        JNIEnv* env, jobject thiz) {
232071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia    ALOGV("android_media_MediaSync_createInputSurface");
233071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia
234071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia    sp<JMediaSync> sync = getMediaSync(env, thiz);
235071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia    if (sync == NULL) {
236071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia        throwExceptionAsNecessary(env, INVALID_OPERATION);
237071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia        return NULL;
238071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia    }
239071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia
240071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia    // Tell the MediaSync that we want to use a Surface as input.
241071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia    sp<IGraphicBufferProducer> bufferProducer;
242071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia    status_t err = sync->createInputSurface(&bufferProducer);
243071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia    if (err != NO_ERROR) {
244071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia        throwExceptionAsNecessary(env, INVALID_OPERATION);
245071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia        return NULL;
246071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia    }
247071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia
248071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia    // Wrap the IGBP in a Java-language Surface.
249071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia    return android_view_Surface_createFromIGraphicBufferProducer(env,
250071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia            bufferProducer);
251071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia}
252071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia
253071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jiastatic void android_media_MediaSync_native_updateQueuedAudioData(
254071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia        JNIEnv *env, jobject thiz, jint sizeInBytes, jlong presentationTimeUs) {
255071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia    sp<JMediaSync> sync = getMediaSync(env, thiz);
256071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia    if (sync == NULL) {
257071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia        throwExceptionAsNecessary(env, INVALID_OPERATION);
258071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia        return;
259071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia    }
260071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia
261071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia    status_t err = sync->updateQueuedAudioData(sizeInBytes, presentationTimeUs);
262071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia    if (err != NO_ERROR) {
263071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia        throwExceptionAsNecessary(env, err);
264071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia        return;
265071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia    }
266071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia}
267071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia
268217ec0adfc35302a6cc6b04bc78bf8fd82ffc8a5Wei Jiastatic jboolean android_media_MediaSync_native_getTimestamp(
269217ec0adfc35302a6cc6b04bc78bf8fd82ffc8a5Wei Jia        JNIEnv *env, jobject thiz, jobject timestamp) {
270217ec0adfc35302a6cc6b04bc78bf8fd82ffc8a5Wei Jia    sp<JMediaSync> sync = getMediaSync(env, thiz);
271217ec0adfc35302a6cc6b04bc78bf8fd82ffc8a5Wei Jia    if (sync == NULL) {
272217ec0adfc35302a6cc6b04bc78bf8fd82ffc8a5Wei Jia        throwExceptionAsNecessary(env, INVALID_OPERATION);
273217ec0adfc35302a6cc6b04bc78bf8fd82ffc8a5Wei Jia        return JNI_FALSE;
274217ec0adfc35302a6cc6b04bc78bf8fd82ffc8a5Wei Jia    }
275217ec0adfc35302a6cc6b04bc78bf8fd82ffc8a5Wei Jia
276217ec0adfc35302a6cc6b04bc78bf8fd82ffc8a5Wei Jia    sp<const MediaClock> mediaClock = sync->getMediaClock();
277217ec0adfc35302a6cc6b04bc78bf8fd82ffc8a5Wei Jia    if (mediaClock == NULL) {
278217ec0adfc35302a6cc6b04bc78bf8fd82ffc8a5Wei Jia        return JNI_FALSE;
279217ec0adfc35302a6cc6b04bc78bf8fd82ffc8a5Wei Jia    }
280217ec0adfc35302a6cc6b04bc78bf8fd82ffc8a5Wei Jia
281217ec0adfc35302a6cc6b04bc78bf8fd82ffc8a5Wei Jia    int64_t nowUs = ALooper::GetNowUs();
282217ec0adfc35302a6cc6b04bc78bf8fd82ffc8a5Wei Jia    int64_t mediaUs = 0;
283217ec0adfc35302a6cc6b04bc78bf8fd82ffc8a5Wei Jia    if (mediaClock->getMediaTime(nowUs, &mediaUs) != OK) {
284217ec0adfc35302a6cc6b04bc78bf8fd82ffc8a5Wei Jia        return JNI_FALSE;
285217ec0adfc35302a6cc6b04bc78bf8fd82ffc8a5Wei Jia    }
286217ec0adfc35302a6cc6b04bc78bf8fd82ffc8a5Wei Jia
287217ec0adfc35302a6cc6b04bc78bf8fd82ffc8a5Wei Jia    env->SetLongField(timestamp, gFields.mediaTimestampMediaTimeUsID,
288217ec0adfc35302a6cc6b04bc78bf8fd82ffc8a5Wei Jia            (jlong)mediaUs);
289217ec0adfc35302a6cc6b04bc78bf8fd82ffc8a5Wei Jia    env->SetLongField(timestamp, gFields.mediaTimestampNanoTimeID,
290217ec0adfc35302a6cc6b04bc78bf8fd82ffc8a5Wei Jia            (jlong)(nowUs * 1000));
291217ec0adfc35302a6cc6b04bc78bf8fd82ffc8a5Wei Jia    env->SetFloatField(timestamp, gFields.mediaTimestampClockRateID,
292217ec0adfc35302a6cc6b04bc78bf8fd82ffc8a5Wei Jia            (jfloat)mediaClock->getPlaybackRate());
293217ec0adfc35302a6cc6b04bc78bf8fd82ffc8a5Wei Jia    return JNI_TRUE;
294217ec0adfc35302a6cc6b04bc78bf8fd82ffc8a5Wei Jia}
295217ec0adfc35302a6cc6b04bc78bf8fd82ffc8a5Wei Jia
29625b802d47249702b9e5d175b3e7144934b67553dWei Jiastatic jlong android_media_MediaSync_native_getPlayTimeForPendingAudioFrames(
29725b802d47249702b9e5d175b3e7144934b67553dWei Jia        JNIEnv *env, jobject thiz) {
29825b802d47249702b9e5d175b3e7144934b67553dWei Jia    sp<JMediaSync> sync = getMediaSync(env, thiz);
29925b802d47249702b9e5d175b3e7144934b67553dWei Jia    if (sync == NULL) {
30025b802d47249702b9e5d175b3e7144934b67553dWei Jia        throwExceptionAsNecessary(env, INVALID_OPERATION);
30125b802d47249702b9e5d175b3e7144934b67553dWei Jia    }
30225b802d47249702b9e5d175b3e7144934b67553dWei Jia
30325b802d47249702b9e5d175b3e7144934b67553dWei Jia    int64_t playTimeUs = 0;
30425b802d47249702b9e5d175b3e7144934b67553dWei Jia    status_t err = sync->getPlayTimeForPendingAudioFrames(&playTimeUs);
30525b802d47249702b9e5d175b3e7144934b67553dWei Jia    if (err != NO_ERROR) {
30625b802d47249702b9e5d175b3e7144934b67553dWei Jia        throwExceptionAsNecessary(env, err);
30725b802d47249702b9e5d175b3e7144934b67553dWei Jia    }
30825b802d47249702b9e5d175b3e7144934b67553dWei Jia    return (jlong)playTimeUs;
30925b802d47249702b9e5d175b3e7144934b67553dWei Jia}
31025b802d47249702b9e5d175b3e7144934b67553dWei Jia
31105ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnarstatic jfloat android_media_MediaSync_setPlaybackSettings(
31205ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar        JNIEnv *env, jobject thiz, jobject settings) {
313c98f58efd147c574faa4a4f9956b5ab95e3027a5Lajos Molnar    sp<JMediaSync> sync = getMediaSync(env, thiz);
314c98f58efd147c574faa4a4f9956b5ab95e3027a5Lajos Molnar    if (sync == NULL) {
315c98f58efd147c574faa4a4f9956b5ab95e3027a5Lajos Molnar        throwExceptionAsNecessary(env, INVALID_OPERATION);
31605ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar        return (jfloat)0.f;
31705ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar    }
31805ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar
31905ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar    PlaybackSettings pbs;
32005ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar    pbs.fillFromJobject(env, gPlaybackSettingsFields, settings);
32105ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar    ALOGV("setPlaybackSettings: %d:%f %d:%f %d:%u %d:%u",
32205ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar            pbs.speedSet, pbs.audioRate.mSpeed,
32305ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar            pbs.pitchSet, pbs.audioRate.mPitch,
32405ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar            pbs.audioFallbackModeSet, pbs.audioRate.mFallbackMode,
32505ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar            pbs.audioStretchModeSet, pbs.audioRate.mStretchMode);
32605ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar
32705ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar    AudioPlaybackRate rate;
32805ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar    sync->getPlaybackSettings(&rate);
32905ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar    bool updatedRate = false;
33005ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar    if (pbs.speedSet) {
33105ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar        rate.mSpeed = pbs.audioRate.mSpeed;
33205ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar        updatedRate = true;
33305ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar    }
33405ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar    if (pbs.pitchSet) {
33505ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar        rate.mPitch = pbs.audioRate.mPitch;
33605ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar        updatedRate = true;
33705ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar    }
33805ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar    if (pbs.audioFallbackModeSet) {
33905ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar        rate.mFallbackMode = pbs.audioRate.mFallbackMode;
34005ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar        updatedRate = true;
34105ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar    }
34205ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar    if (pbs.audioStretchModeSet) {
34305ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar        rate.mStretchMode = pbs.audioRate.mStretchMode;
34405ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar        updatedRate = true;
34505ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar    }
34605ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar    if (updatedRate) {
34705ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar        status_t err = sync->setPlaybackSettings(rate);
34805ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar        if (err != OK) {
34905ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar            throwExceptionAsNecessary(env, err);
35005ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar            return (jfloat)0.f;
35105ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar        }
35205ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar    }
35305ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar
35405ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar    sp<const MediaClock> mediaClock = sync->getMediaClock();
35505ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar    if (mediaClock == NULL) {
35605ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar        return (jfloat)0.f;
35705ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar    }
35805ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar
35905ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar    return (jfloat)mediaClock->getPlaybackRate();
36005ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar}
36105ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar
36205ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnarstatic jobject android_media_MediaSync_getPlaybackSettings(
36305ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar        JNIEnv *env, jobject thiz) {
36405ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar    sp<JMediaSync> sync = getMediaSync(env, thiz);
36505ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar    if (sync == NULL) {
36605ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar        throwExceptionAsNecessary(env, INVALID_OPERATION);
36705ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar        return NULL;
36805ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar    }
36905ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar
37005ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar    PlaybackSettings pbs;
37105ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar    AudioPlaybackRate &audioRate = pbs.audioRate;
37205ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar    sync->getPlaybackSettings(&audioRate);
37305ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar    ALOGV("getPlaybackSettings: %f %f %d %d",
37405ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar            audioRate.mSpeed, audioRate.mPitch, audioRate.mFallbackMode, audioRate.mStretchMode);
37505ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar
37605ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar    pbs.speedSet = true;
37705ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar    pbs.pitchSet = true;
37805ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar    pbs.audioFallbackModeSet = true;
37905ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar    pbs.audioStretchModeSet = true;
38005ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar
38105ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar    return pbs.asJobject(env, gPlaybackSettingsFields);
38205ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar}
38305ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar
38405ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnarstatic jfloat android_media_MediaSync_setSyncSettings(
38505ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar        JNIEnv *env, jobject thiz, jobject settings) {
38605ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar    sp<JMediaSync> sync = getMediaSync(env, thiz);
38705ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar    if (sync == NULL) {
38805ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar        throwExceptionAsNecessary(env, INVALID_OPERATION);
38905ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar        return (jfloat)0.f;
390c98f58efd147c574faa4a4f9956b5ab95e3027a5Lajos Molnar    }
391c98f58efd147c574faa4a4f9956b5ab95e3027a5Lajos Molnar
392c98f58efd147c574faa4a4f9956b5ab95e3027a5Lajos Molnar    SyncSettings scs;
393c98f58efd147c574faa4a4f9956b5ab95e3027a5Lajos Molnar    scs.fillFromJobject(env, gSyncSettingsFields, settings);
394c98f58efd147c574faa4a4f9956b5ab95e3027a5Lajos Molnar    ALOGV("setSyncSettings: %d:%d %d:%d %d:%f %d:%f",
39505ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar            scs.syncSourceSet, scs.sync.mSource,
39605ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar            scs.audioAdjustModeSet, scs.sync.mAudioAdjustMode,
39705ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar            scs.toleranceSet, scs.sync.mTolerance,
398c98f58efd147c574faa4a4f9956b5ab95e3027a5Lajos Molnar            scs.frameRateSet, scs.frameRate);
399c98f58efd147c574faa4a4f9956b5ab95e3027a5Lajos Molnar
40005ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar    AVSyncSettings avsync;
40105ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar    sync->getSyncSettings(&avsync);
40205ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar    bool updatedSync = false;
40305ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar    status_t err = OK;
40405ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar    if (scs.syncSourceSet) {
40505ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar        avsync.mSource = scs.sync.mSource;
40605ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar        updatedSync = true;
40705ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar    }
40805ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar    if (scs.audioAdjustModeSet) {
40905ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar        avsync.mAudioAdjustMode = scs.sync.mAudioAdjustMode;
41005ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar        updatedSync = true;
41105ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar    }
41205ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar    if (scs.toleranceSet) {
41305ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar        avsync.mTolerance = scs.sync.mTolerance;
41405ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar        updatedSync = true;
41505ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar    }
41605ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar    if (updatedSync) {
41705ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar        err = sync->setSyncSettings(avsync);
41805ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar    }
41905ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar
42005ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar    if (scs.frameRateSet && err == OK) {
42105ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar        err = sync->setVideoFrameRateHint(scs.frameRate);
42205ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar    }
42305ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar    if (err != OK) {
42405ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar        throwExceptionAsNecessary(env, err);
42505ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar        return (jfloat)0.f;
42605ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar    }
42705ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar
42805ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar    sp<const MediaClock> mediaClock = sync->getMediaClock();
42905ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar    if (mediaClock == NULL) {
43005ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar        return (jfloat)0.f;
43105ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar    }
43205ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar
43305ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar    return (jfloat)mediaClock->getPlaybackRate();
434c98f58efd147c574faa4a4f9956b5ab95e3027a5Lajos Molnar}
435c98f58efd147c574faa4a4f9956b5ab95e3027a5Lajos Molnar
43605ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnarstatic jobject android_media_MediaSync_getSyncSettings(JNIEnv *env, jobject thiz) {
437c98f58efd147c574faa4a4f9956b5ab95e3027a5Lajos Molnar    sp<JMediaSync> sync = getMediaSync(env, thiz);
438c98f58efd147c574faa4a4f9956b5ab95e3027a5Lajos Molnar    if (sync == NULL) {
439c98f58efd147c574faa4a4f9956b5ab95e3027a5Lajos Molnar        throwExceptionAsNecessary(env, INVALID_OPERATION);
440c98f58efd147c574faa4a4f9956b5ab95e3027a5Lajos Molnar        return NULL;
441c98f58efd147c574faa4a4f9956b5ab95e3027a5Lajos Molnar    }
442c98f58efd147c574faa4a4f9956b5ab95e3027a5Lajos Molnar
443c98f58efd147c574faa4a4f9956b5ab95e3027a5Lajos Molnar    SyncSettings scs;
44405ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar    sync->getSyncSettings(&scs.sync);
44505ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar    scs.frameRate = sync->getVideoFrameRate();
44605ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar
447c98f58efd147c574faa4a4f9956b5ab95e3027a5Lajos Molnar    ALOGV("getSyncSettings: %d %d %f %f",
44805ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar            scs.sync.mSource, scs.sync.mAudioAdjustMode, scs.sync.mTolerance, scs.frameRate);
44905ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar
45005ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar    // sanity check settings
45105ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar    if (scs.sync.mSource >= AVSYNC_SOURCE_MAX
45205ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar            || scs.sync.mAudioAdjustMode >= AVSYNC_AUDIO_ADJUST_MODE_MAX
45305ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar            || scs.sync.mTolerance < 0.f
45405ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar            || scs.sync.mTolerance >= AVSYNC_TOLERANCE_MAX) {
45505ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar        throwExceptionAsNecessary(env, INVALID_OPERATION);
45605ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar        return NULL;
45705ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar    }
458c98f58efd147c574faa4a4f9956b5ab95e3027a5Lajos Molnar
459c98f58efd147c574faa4a4f9956b5ab95e3027a5Lajos Molnar    scs.syncSourceSet = true;
460c98f58efd147c574faa4a4f9956b5ab95e3027a5Lajos Molnar    scs.audioAdjustModeSet = true;
461c98f58efd147c574faa4a4f9956b5ab95e3027a5Lajos Molnar    scs.toleranceSet = true;
46205ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar    scs.frameRateSet = scs.frameRate >= 0.f;
463c98f58efd147c574faa4a4f9956b5ab95e3027a5Lajos Molnar
464c98f58efd147c574faa4a4f9956b5ab95e3027a5Lajos Molnar    return scs.asJobject(env, gSyncSettingsFields);
465c98f58efd147c574faa4a4f9956b5ab95e3027a5Lajos Molnar}
466c98f58efd147c574faa4a4f9956b5ab95e3027a5Lajos Molnar
467071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jiastatic void android_media_MediaSync_native_init(JNIEnv *env) {
468071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia    ScopedLocalRef<jclass> clazz(env, env->FindClass("android/media/MediaSync"));
469071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia    CHECK(clazz.get() != NULL);
470071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia
471071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia    gFields.context = env->GetFieldID(clazz.get(), "mNativeContext", "J");
472071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia    CHECK(gFields.context != NULL);
473217ec0adfc35302a6cc6b04bc78bf8fd82ffc8a5Wei Jia
474217ec0adfc35302a6cc6b04bc78bf8fd82ffc8a5Wei Jia    clazz.reset(env->FindClass("android/media/MediaTimestamp"));
475217ec0adfc35302a6cc6b04bc78bf8fd82ffc8a5Wei Jia    CHECK(clazz.get() != NULL);
476217ec0adfc35302a6cc6b04bc78bf8fd82ffc8a5Wei Jia
477217ec0adfc35302a6cc6b04bc78bf8fd82ffc8a5Wei Jia    gFields.mediaTimestampMediaTimeUsID =
478217ec0adfc35302a6cc6b04bc78bf8fd82ffc8a5Wei Jia        env->GetFieldID(clazz.get(), "mediaTimeUs", "J");
479217ec0adfc35302a6cc6b04bc78bf8fd82ffc8a5Wei Jia    CHECK(gFields.mediaTimestampMediaTimeUsID != NULL);
480217ec0adfc35302a6cc6b04bc78bf8fd82ffc8a5Wei Jia
481217ec0adfc35302a6cc6b04bc78bf8fd82ffc8a5Wei Jia    gFields.mediaTimestampNanoTimeID =
482217ec0adfc35302a6cc6b04bc78bf8fd82ffc8a5Wei Jia        env->GetFieldID(clazz.get(), "nanoTime", "J");
483217ec0adfc35302a6cc6b04bc78bf8fd82ffc8a5Wei Jia    CHECK(gFields.mediaTimestampNanoTimeID != NULL);
484217ec0adfc35302a6cc6b04bc78bf8fd82ffc8a5Wei Jia
485217ec0adfc35302a6cc6b04bc78bf8fd82ffc8a5Wei Jia    gFields.mediaTimestampClockRateID =
486dfb0e6236b573f1dea1e5182a38aa22a7dc10dc1Wei Jia        env->GetFieldID(clazz.get(), "clockRate", "F");
487217ec0adfc35302a6cc6b04bc78bf8fd82ffc8a5Wei Jia    CHECK(gFields.mediaTimestampClockRateID != NULL);
488c98f58efd147c574faa4a4f9956b5ab95e3027a5Lajos Molnar
489c98f58efd147c574faa4a4f9956b5ab95e3027a5Lajos Molnar    gSyncSettingsFields.init(env);
49005ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar    gPlaybackSettingsFields.init(env);
491071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia}
492071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia
493071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jiastatic void android_media_MediaSync_native_setup(JNIEnv *env, jobject thiz) {
494071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia    sp<JMediaSync> sync = new JMediaSync();
495071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia
496071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia    setMediaSync(env, thiz, sync);
497071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia}
498071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia
499071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jiastatic void android_media_MediaSync_native_finalize(JNIEnv *env, jobject thiz) {
500071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia    android_media_MediaSync_release(env, thiz);
501071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia}
502071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia
503071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jiastatic JNINativeMethod gMethods[] = {
504071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia    { "native_configureSurface",
505071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia      "(Landroid/view/Surface;)V",
506071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia      (void *)android_media_MediaSync_native_configureSurface },
507071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia
508071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia    { "native_configureAudioTrack",
509071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia      "(Landroid/media/AudioTrack;I)V",
510071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia      (void *)android_media_MediaSync_native_configureAudioTrack },
511071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia
512071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia    { "createInputSurface", "()Landroid/view/Surface;",
513071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia      (void *)android_media_MediaSync_createInputSurface },
514071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia
515071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia    { "native_updateQueuedAudioData",
516071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia      "(IJ)V",
517071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia      (void *)android_media_MediaSync_native_updateQueuedAudioData },
518071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia
519217ec0adfc35302a6cc6b04bc78bf8fd82ffc8a5Wei Jia    { "native_getTimestamp",
520217ec0adfc35302a6cc6b04bc78bf8fd82ffc8a5Wei Jia      "(Landroid/media/MediaTimestamp;)Z",
521217ec0adfc35302a6cc6b04bc78bf8fd82ffc8a5Wei Jia      (void *)android_media_MediaSync_native_getTimestamp },
522217ec0adfc35302a6cc6b04bc78bf8fd82ffc8a5Wei Jia
52325b802d47249702b9e5d175b3e7144934b67553dWei Jia    { "native_getPlayTimeForPendingAudioFrames",
52425b802d47249702b9e5d175b3e7144934b67553dWei Jia      "()J",
52525b802d47249702b9e5d175b3e7144934b67553dWei Jia      (void *)android_media_MediaSync_native_getPlayTimeForPendingAudioFrames },
52625b802d47249702b9e5d175b3e7144934b67553dWei Jia
527071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia    { "native_init", "()V", (void *)android_media_MediaSync_native_init },
528071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia
529071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia    { "native_setup", "()V", (void *)android_media_MediaSync_native_setup },
530071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia
531071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia    { "native_release", "()V", (void *)android_media_MediaSync_release },
532071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia
53305ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar    { "native_setPlaybackSettings", "(Landroid/media/PlaybackSettings;)F",
53405ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar      (void *)android_media_MediaSync_setPlaybackSettings },
53505ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar
53605ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar    { "getPlaybackSettings", "()Landroid/media/PlaybackSettings;",
53705ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar      (void *)android_media_MediaSync_getPlaybackSettings },
538071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia
53905ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar    { "native_setSyncSettings", "(Landroid/media/SyncSettings;)F",
54005ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar      (void *)android_media_MediaSync_setSyncSettings },
541c98f58efd147c574faa4a4f9956b5ab95e3027a5Lajos Molnar
54205ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar    { "getSyncSettings", "()Landroid/media/SyncSettings;",
54305ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar      (void *)android_media_MediaSync_getSyncSettings },
544c98f58efd147c574faa4a4f9956b5ab95e3027a5Lajos Molnar
545071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia    { "native_finalize", "()V", (void *)android_media_MediaSync_native_finalize },
546071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia};
547071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia
548071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jiaint register_android_media_MediaSync(JNIEnv *env) {
549071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia    return AndroidRuntime::registerNativeMethods(
550071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia                   env, "android/media/MediaSync", gMethods, NELEM(gMethods));
551071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia}
552