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" 242d61e2b97c92ac2de80ebb3782b728ae5cdf5306Wei Jia#include "android_media_PlaybackParams.h" 252d61e2b97c92ac2de80ebb3782b728ae5cdf5306Wei Jia#include "android_media_SyncParams.h" 26071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia#include "android_runtime/AndroidRuntime.h" 27071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia#include "android_runtime/android_view_Surface.h" 28071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia#include "jni.h" 292279b2534272282a5b5152723235da397e49195cSteven Moreland#include <nativehelper/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; 522d61e2b97c92ac2de80ebb3782b728ae5cdf5306Wei Jiastatic PlaybackParams::fields_t gPlaybackParamsFields; 532d61e2b97c92ac2de80ebb3782b728ae5cdf5306Wei Jiastatic SyncParams::fields_t gSyncParamsFields; 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 64d80d6f6b056e23a8d017fe8f3900f6a88e27aa1bWei Jiastatus_t JMediaSync::setSurface(const sp<IGraphicBufferProducer> &bufferProducer) { 65d80d6f6b056e23a8d017fe8f3900f6a88e27aa1bWei Jia return mSync->setSurface(bufferProducer); 66071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia} 67071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia 68d80d6f6b056e23a8d017fe8f3900f6a88e27aa1bWei Jiastatus_t JMediaSync::setAudioTrack(const sp<AudioTrack> &audioTrack) { 69d80d6f6b056e23a8d017fe8f3900f6a88e27aa1bWei Jia return mSync->setAudioTrack(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 812d61e2b97c92ac2de80ebb3782b728ae5cdf5306Wei Jiastatus_t JMediaSync::setPlaybackParams(const AudioPlaybackRate& rate) { 8205ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar return mSync->setPlaybackSettings(rate); 8305ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar} 8405ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar 852d61e2b97c92ac2de80ebb3782b728ae5cdf5306Wei Jiavoid JMediaSync::getPlaybackParams(AudioPlaybackRate* rate /* nonnull */) { 8605ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar mSync->getPlaybackSettings(rate); 8705ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar} 8805ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar 892d61e2b97c92ac2de80ebb3782b728ae5cdf5306Wei Jiastatus_t JMediaSync::setSyncParams(const AVSyncSettings& syncParams) { 902d61e2b97c92ac2de80ebb3782b728ae5cdf5306Wei Jia return mSync->setSyncSettings(syncParams); 9105ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar} 9205ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar 932d61e2b97c92ac2de80ebb3782b728ae5cdf5306Wei Jiavoid JMediaSync::getSyncParams(AVSyncSettings* syncParams /* nonnull */) { 942d61e2b97c92ac2de80ebb3782b728ae5cdf5306Wei Jia mSync->getSyncSettings(syncParams); 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 105d08debcf42d820fa8ef9916077a7bfc0a36f2db5Lajos Molnarvoid JMediaSync::flush() { 106d08debcf42d820fa8ef9916077a7bfc0a36f2db5Lajos Molnar mSync->flush(); 107d08debcf42d820fa8ef9916077a7bfc0a36f2db5Lajos Molnar} 108d08debcf42d820fa8ef9916077a7bfc0a36f2db5Lajos Molnar 109071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jiastatus_t JMediaSync::updateQueuedAudioData( 110071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia int sizeInBytes, int64_t presentationTimeUs) { 111071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia return mSync->updateQueuedAudioData(sizeInBytes, presentationTimeUs); 112071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia} 113071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia 11425b802d47249702b9e5d175b3e7144934b67553dWei Jiastatus_t JMediaSync::getPlayTimeForPendingAudioFrames(int64_t *outTimeUs) { 11525b802d47249702b9e5d175b3e7144934b67553dWei Jia return mSync->getPlayTimeForPendingAudioFrames(outTimeUs); 11625b802d47249702b9e5d175b3e7144934b67553dWei Jia} 11725b802d47249702b9e5d175b3e7144934b67553dWei Jia 118071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia} // namespace android 119071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia 120071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia//////////////////////////////////////////////////////////////////////////////// 121071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia 122071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jiausing namespace android; 123071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia 124071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jiastatic sp<JMediaSync> setMediaSync(JNIEnv *env, jobject thiz, const sp<JMediaSync> &sync) { 125071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia sp<JMediaSync> old = (JMediaSync *)env->GetLongField(thiz, gFields.context); 126071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia if (sync != NULL) { 127071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia sync->incStrong(thiz); 128071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia } 129071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia if (old != NULL) { 130071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia old->decStrong(thiz); 131071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia } 132071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia 133071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia env->SetLongField(thiz, gFields.context, (jlong)sync.get()); 134071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia 135071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia return old; 136071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia} 137071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia 138071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jiastatic sp<JMediaSync> getMediaSync(JNIEnv *env, jobject thiz) { 139071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia return (JMediaSync *)env->GetLongField(thiz, gFields.context); 140071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia} 141071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia 142071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jiastatic void android_media_MediaSync_release(JNIEnv *env, jobject thiz) { 143071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia setMediaSync(env, thiz, NULL); 144071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia} 145071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia 146071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jiastatic void throwExceptionAsNecessary( 147071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia JNIEnv *env, status_t err, const char *msg = NULL) { 148071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia switch (err) { 1490feab71799d2290595d42dec401903cb7d983c40Wei Jia case NO_ERROR: 150071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia break; 151071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia 152071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia case BAD_VALUE: 153071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia jniThrowException(env, "java/lang/IllegalArgumentException", msg); 154071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia break; 155071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia 1560feab71799d2290595d42dec401903cb7d983c40Wei Jia case NO_INIT: 1570feab71799d2290595d42dec401903cb7d983c40Wei Jia case INVALID_OPERATION: 158071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia default: 1590feab71799d2290595d42dec401903cb7d983c40Wei Jia if (err > 0) { 1600feab71799d2290595d42dec401903cb7d983c40Wei Jia break; 1610feab71799d2290595d42dec401903cb7d983c40Wei Jia } 162838a4ed101ef46ecd707087bee68ed19f87c6cc8Wei Jia AString msgWithErrorCode(msg == NULL ? "" : msg); 1630feab71799d2290595d42dec401903cb7d983c40Wei Jia msgWithErrorCode.append(" error:"); 1640feab71799d2290595d42dec401903cb7d983c40Wei Jia msgWithErrorCode.append(err); 1650feab71799d2290595d42dec401903cb7d983c40Wei Jia jniThrowException(env, "java/lang/IllegalStateException", msgWithErrorCode.c_str()); 166071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia break; 167071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia } 168071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia} 169071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia 170d80d6f6b056e23a8d017fe8f3900f6a88e27aa1bWei Jiastatic void android_media_MediaSync_native_setSurface( 171071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia JNIEnv *env, jobject thiz, jobject jsurface) { 172d80d6f6b056e23a8d017fe8f3900f6a88e27aa1bWei Jia ALOGV("android_media_MediaSync_setSurface"); 173071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia 174071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia sp<JMediaSync> sync = getMediaSync(env, thiz); 175071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia if (sync == NULL) { 176071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia throwExceptionAsNecessary(env, INVALID_OPERATION); 177071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia return; 178071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia } 179071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia 180071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia sp<IGraphicBufferProducer> bufferProducer; 181071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia if (jsurface != NULL) { 182071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia sp<Surface> surface(android_view_Surface_getSurface(env, jsurface)); 183071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia if (surface != NULL) { 184071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia bufferProducer = surface->getIGraphicBufferProducer(); 185071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia } else { 186071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia throwExceptionAsNecessary(env, BAD_VALUE, "The surface has been released"); 187071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia return; 188071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia } 189071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia } 190071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia 191d80d6f6b056e23a8d017fe8f3900f6a88e27aa1bWei Jia status_t err = sync->setSurface(bufferProducer); 192071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia 193071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia if (err == INVALID_OPERATION) { 194071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia throwExceptionAsNecessary( 195071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia env, INVALID_OPERATION, "Surface has already been configured"); 196071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia } if (err != NO_ERROR) { 197071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia AString msg("Failed to connect to surface with error "); 198071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia msg.append(err); 199071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia throwExceptionAsNecessary(env, BAD_VALUE, msg.c_str()); 200071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia } 201071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia} 202071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia 203d80d6f6b056e23a8d017fe8f3900f6a88e27aa1bWei Jiastatic void android_media_MediaSync_native_setAudioTrack( 20405ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar JNIEnv *env, jobject thiz, jobject jaudioTrack) { 205d80d6f6b056e23a8d017fe8f3900f6a88e27aa1bWei Jia ALOGV("android_media_MediaSync_setAudioTrack"); 206071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia 207071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia sp<JMediaSync> sync = getMediaSync(env, thiz); 208071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia if (sync == NULL) { 209071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia throwExceptionAsNecessary(env, INVALID_OPERATION); 210071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia return; 211071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia } 212071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia 213071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia sp<AudioTrack> audioTrack; 214071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia if (jaudioTrack != NULL) { 215071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia audioTrack = android_media_AudioTrack_getAudioTrack(env, jaudioTrack); 216071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia if (audioTrack == NULL) { 217071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia throwExceptionAsNecessary(env, BAD_VALUE, "The audio track has been released"); 218071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia return; 219071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia } 220071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia } 221071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia 222d80d6f6b056e23a8d017fe8f3900f6a88e27aa1bWei Jia status_t err = sync->setAudioTrack(audioTrack); 223071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia 224071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia if (err == INVALID_OPERATION) { 225071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia throwExceptionAsNecessary( 226071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia env, INVALID_OPERATION, "Audio track has already been configured"); 227071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia } if (err != NO_ERROR) { 228071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia AString msg("Failed to configure audio track with error "); 229071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia msg.append(err); 230071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia throwExceptionAsNecessary(env, BAD_VALUE, msg.c_str()); 231071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia } 232071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia} 233071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia 234071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jiastatic jobject android_media_MediaSync_createInputSurface( 235071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia JNIEnv* env, jobject thiz) { 236071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia ALOGV("android_media_MediaSync_createInputSurface"); 237071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia 238071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia sp<JMediaSync> sync = getMediaSync(env, thiz); 239071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia if (sync == NULL) { 240071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia throwExceptionAsNecessary(env, INVALID_OPERATION); 241071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia return NULL; 242071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia } 243071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia 244071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia // Tell the MediaSync that we want to use a Surface as input. 245071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia sp<IGraphicBufferProducer> bufferProducer; 246071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia status_t err = sync->createInputSurface(&bufferProducer); 247071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia if (err != NO_ERROR) { 248071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia throwExceptionAsNecessary(env, INVALID_OPERATION); 249071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia return NULL; 250071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia } 251071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia 252071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia // Wrap the IGBP in a Java-language Surface. 253071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia return android_view_Surface_createFromIGraphicBufferProducer(env, 254071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia bufferProducer); 255071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia} 256071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia 257071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jiastatic void android_media_MediaSync_native_updateQueuedAudioData( 258071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia JNIEnv *env, jobject thiz, jint sizeInBytes, jlong presentationTimeUs) { 259071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia sp<JMediaSync> sync = getMediaSync(env, thiz); 260071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia if (sync == NULL) { 261071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia throwExceptionAsNecessary(env, INVALID_OPERATION); 262071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia return; 263071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia } 264071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia 265071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia status_t err = sync->updateQueuedAudioData(sizeInBytes, presentationTimeUs); 266071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia if (err != NO_ERROR) { 267071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia throwExceptionAsNecessary(env, err); 268071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia return; 269071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia } 270071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia} 271071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia 272217ec0adfc35302a6cc6b04bc78bf8fd82ffc8a5Wei Jiastatic jboolean android_media_MediaSync_native_getTimestamp( 273217ec0adfc35302a6cc6b04bc78bf8fd82ffc8a5Wei Jia JNIEnv *env, jobject thiz, jobject timestamp) { 274217ec0adfc35302a6cc6b04bc78bf8fd82ffc8a5Wei Jia sp<JMediaSync> sync = getMediaSync(env, thiz); 275217ec0adfc35302a6cc6b04bc78bf8fd82ffc8a5Wei Jia if (sync == NULL) { 276217ec0adfc35302a6cc6b04bc78bf8fd82ffc8a5Wei Jia throwExceptionAsNecessary(env, INVALID_OPERATION); 277217ec0adfc35302a6cc6b04bc78bf8fd82ffc8a5Wei Jia return JNI_FALSE; 278217ec0adfc35302a6cc6b04bc78bf8fd82ffc8a5Wei Jia } 279217ec0adfc35302a6cc6b04bc78bf8fd82ffc8a5Wei Jia 280217ec0adfc35302a6cc6b04bc78bf8fd82ffc8a5Wei Jia sp<const MediaClock> mediaClock = sync->getMediaClock(); 281217ec0adfc35302a6cc6b04bc78bf8fd82ffc8a5Wei Jia if (mediaClock == NULL) { 282217ec0adfc35302a6cc6b04bc78bf8fd82ffc8a5Wei Jia return JNI_FALSE; 283217ec0adfc35302a6cc6b04bc78bf8fd82ffc8a5Wei Jia } 284217ec0adfc35302a6cc6b04bc78bf8fd82ffc8a5Wei Jia 285217ec0adfc35302a6cc6b04bc78bf8fd82ffc8a5Wei Jia int64_t nowUs = ALooper::GetNowUs(); 286217ec0adfc35302a6cc6b04bc78bf8fd82ffc8a5Wei Jia int64_t mediaUs = 0; 287217ec0adfc35302a6cc6b04bc78bf8fd82ffc8a5Wei Jia if (mediaClock->getMediaTime(nowUs, &mediaUs) != OK) { 288217ec0adfc35302a6cc6b04bc78bf8fd82ffc8a5Wei Jia return JNI_FALSE; 289217ec0adfc35302a6cc6b04bc78bf8fd82ffc8a5Wei Jia } 290217ec0adfc35302a6cc6b04bc78bf8fd82ffc8a5Wei Jia 291217ec0adfc35302a6cc6b04bc78bf8fd82ffc8a5Wei Jia env->SetLongField(timestamp, gFields.mediaTimestampMediaTimeUsID, 292217ec0adfc35302a6cc6b04bc78bf8fd82ffc8a5Wei Jia (jlong)mediaUs); 293217ec0adfc35302a6cc6b04bc78bf8fd82ffc8a5Wei Jia env->SetLongField(timestamp, gFields.mediaTimestampNanoTimeID, 294217ec0adfc35302a6cc6b04bc78bf8fd82ffc8a5Wei Jia (jlong)(nowUs * 1000)); 295217ec0adfc35302a6cc6b04bc78bf8fd82ffc8a5Wei Jia env->SetFloatField(timestamp, gFields.mediaTimestampClockRateID, 296217ec0adfc35302a6cc6b04bc78bf8fd82ffc8a5Wei Jia (jfloat)mediaClock->getPlaybackRate()); 297217ec0adfc35302a6cc6b04bc78bf8fd82ffc8a5Wei Jia return JNI_TRUE; 298217ec0adfc35302a6cc6b04bc78bf8fd82ffc8a5Wei Jia} 299217ec0adfc35302a6cc6b04bc78bf8fd82ffc8a5Wei Jia 30025b802d47249702b9e5d175b3e7144934b67553dWei Jiastatic jlong android_media_MediaSync_native_getPlayTimeForPendingAudioFrames( 30125b802d47249702b9e5d175b3e7144934b67553dWei Jia JNIEnv *env, jobject thiz) { 30225b802d47249702b9e5d175b3e7144934b67553dWei Jia sp<JMediaSync> sync = getMediaSync(env, thiz); 30325b802d47249702b9e5d175b3e7144934b67553dWei Jia if (sync == NULL) { 30425b802d47249702b9e5d175b3e7144934b67553dWei Jia throwExceptionAsNecessary(env, INVALID_OPERATION); 30525b802d47249702b9e5d175b3e7144934b67553dWei Jia } 30625b802d47249702b9e5d175b3e7144934b67553dWei Jia 30725b802d47249702b9e5d175b3e7144934b67553dWei Jia int64_t playTimeUs = 0; 30825b802d47249702b9e5d175b3e7144934b67553dWei Jia status_t err = sync->getPlayTimeForPendingAudioFrames(&playTimeUs); 30925b802d47249702b9e5d175b3e7144934b67553dWei Jia if (err != NO_ERROR) { 31025b802d47249702b9e5d175b3e7144934b67553dWei Jia throwExceptionAsNecessary(env, err); 31125b802d47249702b9e5d175b3e7144934b67553dWei Jia } 31225b802d47249702b9e5d175b3e7144934b67553dWei Jia return (jlong)playTimeUs; 31325b802d47249702b9e5d175b3e7144934b67553dWei Jia} 31425b802d47249702b9e5d175b3e7144934b67553dWei Jia 3152d61e2b97c92ac2de80ebb3782b728ae5cdf5306Wei Jiastatic jfloat android_media_MediaSync_setPlaybackParams( 3162d61e2b97c92ac2de80ebb3782b728ae5cdf5306Wei Jia JNIEnv *env, jobject thiz, jobject params) { 317c98f58efd147c574faa4a4f9956b5ab95e3027a5Lajos Molnar sp<JMediaSync> sync = getMediaSync(env, thiz); 318c98f58efd147c574faa4a4f9956b5ab95e3027a5Lajos Molnar if (sync == NULL) { 319c98f58efd147c574faa4a4f9956b5ab95e3027a5Lajos Molnar throwExceptionAsNecessary(env, INVALID_OPERATION); 32005ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar return (jfloat)0.f; 32105ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar } 32205ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar 3232d61e2b97c92ac2de80ebb3782b728ae5cdf5306Wei Jia PlaybackParams pbs; 3242d61e2b97c92ac2de80ebb3782b728ae5cdf5306Wei Jia pbs.fillFromJobject(env, gPlaybackParamsFields, params); 3252d61e2b97c92ac2de80ebb3782b728ae5cdf5306Wei Jia ALOGV("setPlaybackParams: %d:%f %d:%f %d:%u %d:%u", 32605ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar pbs.speedSet, pbs.audioRate.mSpeed, 32705ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar pbs.pitchSet, pbs.audioRate.mPitch, 32805ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar pbs.audioFallbackModeSet, pbs.audioRate.mFallbackMode, 32905ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar pbs.audioStretchModeSet, pbs.audioRate.mStretchMode); 33005ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar 33105ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar AudioPlaybackRate rate; 3322d61e2b97c92ac2de80ebb3782b728ae5cdf5306Wei Jia sync->getPlaybackParams(&rate); 33305ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar bool updatedRate = false; 33405ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar if (pbs.speedSet) { 33505ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar rate.mSpeed = pbs.audioRate.mSpeed; 33605ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar updatedRate = true; 33705ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar } 33805ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar if (pbs.pitchSet) { 33905ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar rate.mPitch = pbs.audioRate.mPitch; 34005ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar updatedRate = true; 34105ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar } 34205ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar if (pbs.audioFallbackModeSet) { 34305ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar rate.mFallbackMode = pbs.audioRate.mFallbackMode; 34405ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar updatedRate = true; 34505ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar } 34605ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar if (pbs.audioStretchModeSet) { 34705ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar rate.mStretchMode = pbs.audioRate.mStretchMode; 34805ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar updatedRate = true; 34905ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar } 35005ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar if (updatedRate) { 3512d61e2b97c92ac2de80ebb3782b728ae5cdf5306Wei Jia status_t err = sync->setPlaybackParams(rate); 35205ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar if (err != OK) { 35305ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar throwExceptionAsNecessary(env, err); 35405ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar return (jfloat)0.f; 35505ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar } 35605ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar } 35705ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar 35805ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar sp<const MediaClock> mediaClock = sync->getMediaClock(); 35905ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar if (mediaClock == NULL) { 36005ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar return (jfloat)0.f; 36105ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar } 36205ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar 36305ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar return (jfloat)mediaClock->getPlaybackRate(); 36405ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar} 36505ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar 3662d61e2b97c92ac2de80ebb3782b728ae5cdf5306Wei Jiastatic jobject android_media_MediaSync_getPlaybackParams( 36705ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar JNIEnv *env, jobject thiz) { 36805ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar sp<JMediaSync> sync = getMediaSync(env, thiz); 36905ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar if (sync == NULL) { 37005ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar throwExceptionAsNecessary(env, INVALID_OPERATION); 37105ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar return NULL; 37205ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar } 37305ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar 3742d61e2b97c92ac2de80ebb3782b728ae5cdf5306Wei Jia PlaybackParams pbs; 37505ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar AudioPlaybackRate &audioRate = pbs.audioRate; 3762d61e2b97c92ac2de80ebb3782b728ae5cdf5306Wei Jia sync->getPlaybackParams(&audioRate); 3772d61e2b97c92ac2de80ebb3782b728ae5cdf5306Wei Jia ALOGV("getPlaybackParams: %f %f %d %d", 37805ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar audioRate.mSpeed, audioRate.mPitch, audioRate.mFallbackMode, audioRate.mStretchMode); 37905ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar 38005ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar pbs.speedSet = true; 38105ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar pbs.pitchSet = true; 38205ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar pbs.audioFallbackModeSet = true; 38305ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar pbs.audioStretchModeSet = true; 38405ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar 3852d61e2b97c92ac2de80ebb3782b728ae5cdf5306Wei Jia return pbs.asJobject(env, gPlaybackParamsFields); 38605ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar} 38705ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar 3882d61e2b97c92ac2de80ebb3782b728ae5cdf5306Wei Jiastatic jfloat android_media_MediaSync_setSyncParams( 3892d61e2b97c92ac2de80ebb3782b728ae5cdf5306Wei Jia JNIEnv *env, jobject thiz, jobject params) { 39005ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar sp<JMediaSync> sync = getMediaSync(env, thiz); 39105ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar if (sync == NULL) { 39205ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar throwExceptionAsNecessary(env, INVALID_OPERATION); 39305ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar return (jfloat)0.f; 394c98f58efd147c574faa4a4f9956b5ab95e3027a5Lajos Molnar } 395c98f58efd147c574faa4a4f9956b5ab95e3027a5Lajos Molnar 3962d61e2b97c92ac2de80ebb3782b728ae5cdf5306Wei Jia SyncParams scs; 3972d61e2b97c92ac2de80ebb3782b728ae5cdf5306Wei Jia scs.fillFromJobject(env, gSyncParamsFields, params); 3982d61e2b97c92ac2de80ebb3782b728ae5cdf5306Wei Jia ALOGV("setSyncParams: %d:%d %d:%d %d:%f %d:%f", 39905ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar scs.syncSourceSet, scs.sync.mSource, 40005ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar scs.audioAdjustModeSet, scs.sync.mAudioAdjustMode, 40105ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar scs.toleranceSet, scs.sync.mTolerance, 402c98f58efd147c574faa4a4f9956b5ab95e3027a5Lajos Molnar scs.frameRateSet, scs.frameRate); 403c98f58efd147c574faa4a4f9956b5ab95e3027a5Lajos Molnar 40405ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar AVSyncSettings avsync; 4052d61e2b97c92ac2de80ebb3782b728ae5cdf5306Wei Jia sync->getSyncParams(&avsync); 40605ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar bool updatedSync = false; 40705ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar status_t err = OK; 40805ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar if (scs.syncSourceSet) { 40905ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar avsync.mSource = scs.sync.mSource; 41005ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar updatedSync = true; 41105ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar } 41205ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar if (scs.audioAdjustModeSet) { 41305ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar avsync.mAudioAdjustMode = scs.sync.mAudioAdjustMode; 41405ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar updatedSync = true; 41505ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar } 41605ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar if (scs.toleranceSet) { 41705ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar avsync.mTolerance = scs.sync.mTolerance; 41805ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar updatedSync = true; 41905ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar } 42005ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar if (updatedSync) { 4212d61e2b97c92ac2de80ebb3782b728ae5cdf5306Wei Jia err = sync->setSyncParams(avsync); 42205ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar } 42305ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar 42405ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar if (scs.frameRateSet && err == OK) { 42505ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar err = sync->setVideoFrameRateHint(scs.frameRate); 42605ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar } 42705ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar if (err != OK) { 42805ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar throwExceptionAsNecessary(env, err); 42905ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar return (jfloat)0.f; 43005ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar } 43105ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar 43205ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar sp<const MediaClock> mediaClock = sync->getMediaClock(); 43305ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar if (mediaClock == NULL) { 43405ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar return (jfloat)0.f; 43505ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar } 43605ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar 43705ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar return (jfloat)mediaClock->getPlaybackRate(); 438c98f58efd147c574faa4a4f9956b5ab95e3027a5Lajos Molnar} 439c98f58efd147c574faa4a4f9956b5ab95e3027a5Lajos Molnar 4402d61e2b97c92ac2de80ebb3782b728ae5cdf5306Wei Jiastatic jobject android_media_MediaSync_getSyncParams(JNIEnv *env, jobject thiz) { 441c98f58efd147c574faa4a4f9956b5ab95e3027a5Lajos Molnar sp<JMediaSync> sync = getMediaSync(env, thiz); 442c98f58efd147c574faa4a4f9956b5ab95e3027a5Lajos Molnar if (sync == NULL) { 443c98f58efd147c574faa4a4f9956b5ab95e3027a5Lajos Molnar throwExceptionAsNecessary(env, INVALID_OPERATION); 444c98f58efd147c574faa4a4f9956b5ab95e3027a5Lajos Molnar return NULL; 445c98f58efd147c574faa4a4f9956b5ab95e3027a5Lajos Molnar } 446c98f58efd147c574faa4a4f9956b5ab95e3027a5Lajos Molnar 4472d61e2b97c92ac2de80ebb3782b728ae5cdf5306Wei Jia SyncParams scs; 4482d61e2b97c92ac2de80ebb3782b728ae5cdf5306Wei Jia sync->getSyncParams(&scs.sync); 44905ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar scs.frameRate = sync->getVideoFrameRate(); 45005ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar 4512d61e2b97c92ac2de80ebb3782b728ae5cdf5306Wei Jia ALOGV("getSyncParams: %d %d %f %f", 45205ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar scs.sync.mSource, scs.sync.mAudioAdjustMode, scs.sync.mTolerance, scs.frameRate); 45305ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar 4542d61e2b97c92ac2de80ebb3782b728ae5cdf5306Wei Jia // sanity check params 45505ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar if (scs.sync.mSource >= AVSYNC_SOURCE_MAX 45605ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar || scs.sync.mAudioAdjustMode >= AVSYNC_AUDIO_ADJUST_MODE_MAX 45705ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar || scs.sync.mTolerance < 0.f 45805ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar || scs.sync.mTolerance >= AVSYNC_TOLERANCE_MAX) { 45905ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar throwExceptionAsNecessary(env, INVALID_OPERATION); 46005ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar return NULL; 46105ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar } 462c98f58efd147c574faa4a4f9956b5ab95e3027a5Lajos Molnar 463c98f58efd147c574faa4a4f9956b5ab95e3027a5Lajos Molnar scs.syncSourceSet = true; 464c98f58efd147c574faa4a4f9956b5ab95e3027a5Lajos Molnar scs.audioAdjustModeSet = true; 465c98f58efd147c574faa4a4f9956b5ab95e3027a5Lajos Molnar scs.toleranceSet = true; 46605ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar scs.frameRateSet = scs.frameRate >= 0.f; 467c98f58efd147c574faa4a4f9956b5ab95e3027a5Lajos Molnar 4682d61e2b97c92ac2de80ebb3782b728ae5cdf5306Wei Jia return scs.asJobject(env, gSyncParamsFields); 469c98f58efd147c574faa4a4f9956b5ab95e3027a5Lajos Molnar} 470c98f58efd147c574faa4a4f9956b5ab95e3027a5Lajos Molnar 471d08debcf42d820fa8ef9916077a7bfc0a36f2db5Lajos Molnarstatic void android_media_MediaSync_native_flush(JNIEnv *env, jobject thiz) { 472d08debcf42d820fa8ef9916077a7bfc0a36f2db5Lajos Molnar sp<JMediaSync> sync = getMediaSync(env, thiz); 473d08debcf42d820fa8ef9916077a7bfc0a36f2db5Lajos Molnar if (sync == NULL) { 474d08debcf42d820fa8ef9916077a7bfc0a36f2db5Lajos Molnar throwExceptionAsNecessary(env, INVALID_OPERATION); 475d08debcf42d820fa8ef9916077a7bfc0a36f2db5Lajos Molnar return; 476d08debcf42d820fa8ef9916077a7bfc0a36f2db5Lajos Molnar } 477d08debcf42d820fa8ef9916077a7bfc0a36f2db5Lajos Molnar 478d08debcf42d820fa8ef9916077a7bfc0a36f2db5Lajos Molnar sync->flush(); 479d08debcf42d820fa8ef9916077a7bfc0a36f2db5Lajos Molnar} 480d08debcf42d820fa8ef9916077a7bfc0a36f2db5Lajos Molnar 481071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jiastatic void android_media_MediaSync_native_init(JNIEnv *env) { 482071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia ScopedLocalRef<jclass> clazz(env, env->FindClass("android/media/MediaSync")); 483071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia CHECK(clazz.get() != NULL); 484071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia 485071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia gFields.context = env->GetFieldID(clazz.get(), "mNativeContext", "J"); 486071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia CHECK(gFields.context != NULL); 487217ec0adfc35302a6cc6b04bc78bf8fd82ffc8a5Wei Jia 488217ec0adfc35302a6cc6b04bc78bf8fd82ffc8a5Wei Jia clazz.reset(env->FindClass("android/media/MediaTimestamp")); 489217ec0adfc35302a6cc6b04bc78bf8fd82ffc8a5Wei Jia CHECK(clazz.get() != NULL); 490217ec0adfc35302a6cc6b04bc78bf8fd82ffc8a5Wei Jia 491217ec0adfc35302a6cc6b04bc78bf8fd82ffc8a5Wei Jia gFields.mediaTimestampMediaTimeUsID = 492217ec0adfc35302a6cc6b04bc78bf8fd82ffc8a5Wei Jia env->GetFieldID(clazz.get(), "mediaTimeUs", "J"); 493217ec0adfc35302a6cc6b04bc78bf8fd82ffc8a5Wei Jia CHECK(gFields.mediaTimestampMediaTimeUsID != NULL); 494217ec0adfc35302a6cc6b04bc78bf8fd82ffc8a5Wei Jia 495217ec0adfc35302a6cc6b04bc78bf8fd82ffc8a5Wei Jia gFields.mediaTimestampNanoTimeID = 496217ec0adfc35302a6cc6b04bc78bf8fd82ffc8a5Wei Jia env->GetFieldID(clazz.get(), "nanoTime", "J"); 497217ec0adfc35302a6cc6b04bc78bf8fd82ffc8a5Wei Jia CHECK(gFields.mediaTimestampNanoTimeID != NULL); 498217ec0adfc35302a6cc6b04bc78bf8fd82ffc8a5Wei Jia 499217ec0adfc35302a6cc6b04bc78bf8fd82ffc8a5Wei Jia gFields.mediaTimestampClockRateID = 500dfb0e6236b573f1dea1e5182a38aa22a7dc10dc1Wei Jia env->GetFieldID(clazz.get(), "clockRate", "F"); 501217ec0adfc35302a6cc6b04bc78bf8fd82ffc8a5Wei Jia CHECK(gFields.mediaTimestampClockRateID != NULL); 502c98f58efd147c574faa4a4f9956b5ab95e3027a5Lajos Molnar 5032d61e2b97c92ac2de80ebb3782b728ae5cdf5306Wei Jia gSyncParamsFields.init(env); 5042d61e2b97c92ac2de80ebb3782b728ae5cdf5306Wei Jia gPlaybackParamsFields.init(env); 505071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia} 506071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia 507071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jiastatic void android_media_MediaSync_native_setup(JNIEnv *env, jobject thiz) { 508071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia sp<JMediaSync> sync = new JMediaSync(); 509071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia 510071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia setMediaSync(env, thiz, sync); 511071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia} 512071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia 513071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jiastatic void android_media_MediaSync_native_finalize(JNIEnv *env, jobject thiz) { 514071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia android_media_MediaSync_release(env, thiz); 515071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia} 516071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia 517071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jiastatic JNINativeMethod gMethods[] = { 518d80d6f6b056e23a8d017fe8f3900f6a88e27aa1bWei Jia { "native_setSurface", 519071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia "(Landroid/view/Surface;)V", 520d80d6f6b056e23a8d017fe8f3900f6a88e27aa1bWei Jia (void *)android_media_MediaSync_native_setSurface }, 521071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia 522d80d6f6b056e23a8d017fe8f3900f6a88e27aa1bWei Jia { "native_setAudioTrack", 523d80d6f6b056e23a8d017fe8f3900f6a88e27aa1bWei Jia "(Landroid/media/AudioTrack;)V", 524d80d6f6b056e23a8d017fe8f3900f6a88e27aa1bWei Jia (void *)android_media_MediaSync_native_setAudioTrack }, 525071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia 526071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia { "createInputSurface", "()Landroid/view/Surface;", 527071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia (void *)android_media_MediaSync_createInputSurface }, 528071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia 529071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia { "native_updateQueuedAudioData", 530071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia "(IJ)V", 531071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia (void *)android_media_MediaSync_native_updateQueuedAudioData }, 532071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia 533217ec0adfc35302a6cc6b04bc78bf8fd82ffc8a5Wei Jia { "native_getTimestamp", 534217ec0adfc35302a6cc6b04bc78bf8fd82ffc8a5Wei Jia "(Landroid/media/MediaTimestamp;)Z", 535217ec0adfc35302a6cc6b04bc78bf8fd82ffc8a5Wei Jia (void *)android_media_MediaSync_native_getTimestamp }, 536217ec0adfc35302a6cc6b04bc78bf8fd82ffc8a5Wei Jia 53725b802d47249702b9e5d175b3e7144934b67553dWei Jia { "native_getPlayTimeForPendingAudioFrames", 53825b802d47249702b9e5d175b3e7144934b67553dWei Jia "()J", 53925b802d47249702b9e5d175b3e7144934b67553dWei Jia (void *)android_media_MediaSync_native_getPlayTimeForPendingAudioFrames }, 54025b802d47249702b9e5d175b3e7144934b67553dWei Jia 541d08debcf42d820fa8ef9916077a7bfc0a36f2db5Lajos Molnar { "native_flush", "()V", (void *)android_media_MediaSync_native_flush }, 542d08debcf42d820fa8ef9916077a7bfc0a36f2db5Lajos Molnar 543071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia { "native_init", "()V", (void *)android_media_MediaSync_native_init }, 544071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia 545071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia { "native_setup", "()V", (void *)android_media_MediaSync_native_setup }, 546071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia 547071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia { "native_release", "()V", (void *)android_media_MediaSync_release }, 548071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia 5492d61e2b97c92ac2de80ebb3782b728ae5cdf5306Wei Jia { "native_setPlaybackParams", "(Landroid/media/PlaybackParams;)F", 5502d61e2b97c92ac2de80ebb3782b728ae5cdf5306Wei Jia (void *)android_media_MediaSync_setPlaybackParams }, 55105ebffe6bf6cdacc6de4b3bbf480c31869a81661Lajos Molnar 5522d61e2b97c92ac2de80ebb3782b728ae5cdf5306Wei Jia { "getPlaybackParams", "()Landroid/media/PlaybackParams;", 5532d61e2b97c92ac2de80ebb3782b728ae5cdf5306Wei Jia (void *)android_media_MediaSync_getPlaybackParams }, 554071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia 5552d61e2b97c92ac2de80ebb3782b728ae5cdf5306Wei Jia { "native_setSyncParams", "(Landroid/media/SyncParams;)F", 5562d61e2b97c92ac2de80ebb3782b728ae5cdf5306Wei Jia (void *)android_media_MediaSync_setSyncParams }, 557c98f58efd147c574faa4a4f9956b5ab95e3027a5Lajos Molnar 5582d61e2b97c92ac2de80ebb3782b728ae5cdf5306Wei Jia { "getSyncParams", "()Landroid/media/SyncParams;", 5592d61e2b97c92ac2de80ebb3782b728ae5cdf5306Wei Jia (void *)android_media_MediaSync_getSyncParams }, 560c98f58efd147c574faa4a4f9956b5ab95e3027a5Lajos Molnar 561071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia { "native_finalize", "()V", (void *)android_media_MediaSync_native_finalize }, 562071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia}; 563071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia 564071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jiaint register_android_media_MediaSync(JNIEnv *env) { 565071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia return AndroidRuntime::registerNativeMethods( 566071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia env, "android/media/MediaSync", gMethods, NELEM(gMethods)); 567071a8b71d1212e218a3ebf7dbb8908a4acf5cf6dWei Jia} 568