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