blob: f75200868a0dba20dee0bdefb2a0c653f60cd07f [file] [log] [blame]
Wei Jia071a8b72015-03-09 16:38:25 -07001/*
2 * Copyright 2015, The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17//#define LOG_NDEBUG 0
18#define LOG_TAG "MediaSync-JNI"
19#include <utils/Log.h>
20
21#include "android_media_MediaSync.h"
22
23#include "android_media_AudioTrack.h"
Wei Jia2d61e2b2015-05-08 15:23:28 -070024#include "android_media_PlaybackParams.h"
25#include "android_media_SyncParams.h"
Wei Jia071a8b72015-03-09 16:38:25 -070026#include "android_runtime/AndroidRuntime.h"
27#include "android_runtime/android_view_Surface.h"
28#include "jni.h"
Steven Moreland2279b252017-07-19 09:50:45 -070029#include <nativehelper/JNIHelp.h>
Wei Jia071a8b72015-03-09 16:38:25 -070030
31#include <gui/Surface.h>
32
Lajos Molnar05ebffe2015-04-29 20:41:19 -070033#include <media/AudioResamplerPublic.h>
Wei Jia071a8b72015-03-09 16:38:25 -070034#include <media/AudioTrack.h>
Wei Jia217ec0a2015-04-09 18:48:18 -070035#include <media/stagefright/MediaClock.h>
Wei Jia071a8b72015-03-09 16:38:25 -070036#include <media/stagefright/MediaSync.h>
37#include <media/stagefright/foundation/ADebug.h>
38#include <media/stagefright/foundation/AString.h>
39
40#include <nativehelper/ScopedLocalRef.h>
41
42namespace android {
43
44struct fields_t {
45 jfieldID context;
Wei Jia217ec0a2015-04-09 18:48:18 -070046 jfieldID mediaTimestampMediaTimeUsID;
47 jfieldID mediaTimestampNanoTimeID;
48 jfieldID mediaTimestampClockRateID;
Wei Jia071a8b72015-03-09 16:38:25 -070049};
50
51static fields_t gFields;
Wei Jia2d61e2b2015-05-08 15:23:28 -070052static PlaybackParams::fields_t gPlaybackParamsFields;
53static SyncParams::fields_t gSyncParamsFields;
Wei Jia071a8b72015-03-09 16:38:25 -070054
55////////////////////////////////////////////////////////////////////////////////
56
57JMediaSync::JMediaSync() {
58 mSync = MediaSync::create();
59}
60
61JMediaSync::~JMediaSync() {
62}
63
Wei Jiad80d6f62015-05-04 15:59:20 -070064status_t JMediaSync::setSurface(const sp<IGraphicBufferProducer> &bufferProducer) {
65 return mSync->setSurface(bufferProducer);
Wei Jia071a8b72015-03-09 16:38:25 -070066}
67
Wei Jiad80d6f62015-05-04 15:59:20 -070068status_t JMediaSync::setAudioTrack(const sp<AudioTrack> &audioTrack) {
69 return mSync->setAudioTrack(audioTrack);
Wei Jia071a8b72015-03-09 16:38:25 -070070}
71
72status_t JMediaSync::createInputSurface(
73 sp<IGraphicBufferProducer>* bufferProducer) {
74 return mSync->createInputSurface(bufferProducer);
75}
76
Wei Jia217ec0a2015-04-09 18:48:18 -070077sp<const MediaClock> JMediaSync::getMediaClock() {
78 return mSync->getMediaClock();
79}
80
Wei Jia2d61e2b2015-05-08 15:23:28 -070081status_t JMediaSync::setPlaybackParams(const AudioPlaybackRate& rate) {
Lajos Molnar05ebffe2015-04-29 20:41:19 -070082 return mSync->setPlaybackSettings(rate);
83}
84
Wei Jia2d61e2b2015-05-08 15:23:28 -070085void JMediaSync::getPlaybackParams(AudioPlaybackRate* rate /* nonnull */) {
Lajos Molnar05ebffe2015-04-29 20:41:19 -070086 mSync->getPlaybackSettings(rate);
87}
88
Wei Jia2d61e2b2015-05-08 15:23:28 -070089status_t JMediaSync::setSyncParams(const AVSyncSettings& syncParams) {
90 return mSync->setSyncSettings(syncParams);
Lajos Molnar05ebffe2015-04-29 20:41:19 -070091}
92
Wei Jia2d61e2b2015-05-08 15:23:28 -070093void JMediaSync::getSyncParams(AVSyncSettings* syncParams /* nonnull */) {
94 mSync->getSyncSettings(syncParams);
Lajos Molnar05ebffe2015-04-29 20:41:19 -070095}
96
97status_t JMediaSync::setVideoFrameRateHint(float rate) {
98 return mSync->setVideoFrameRateHint(rate);
99}
100
101float JMediaSync::getVideoFrameRate() {
102 return mSync->getVideoFrameRate();
103}
104
Lajos Molnard08debcf2015-07-01 16:35:49 -0700105void JMediaSync::flush() {
106 mSync->flush();
107}
108
Wei Jia071a8b72015-03-09 16:38:25 -0700109status_t JMediaSync::updateQueuedAudioData(
110 int sizeInBytes, int64_t presentationTimeUs) {
111 return mSync->updateQueuedAudioData(sizeInBytes, presentationTimeUs);
112}
113
Wei Jia25b802d2015-04-23 14:10:30 -0700114status_t JMediaSync::getPlayTimeForPendingAudioFrames(int64_t *outTimeUs) {
115 return mSync->getPlayTimeForPendingAudioFrames(outTimeUs);
116}
117
Wei Jia071a8b72015-03-09 16:38:25 -0700118} // namespace android
119
120////////////////////////////////////////////////////////////////////////////////
121
122using namespace android;
123
124static sp<JMediaSync> setMediaSync(JNIEnv *env, jobject thiz, const sp<JMediaSync> &sync) {
125 sp<JMediaSync> old = (JMediaSync *)env->GetLongField(thiz, gFields.context);
126 if (sync != NULL) {
127 sync->incStrong(thiz);
128 }
129 if (old != NULL) {
130 old->decStrong(thiz);
131 }
132
133 env->SetLongField(thiz, gFields.context, (jlong)sync.get());
134
135 return old;
136}
137
138static sp<JMediaSync> getMediaSync(JNIEnv *env, jobject thiz) {
139 return (JMediaSync *)env->GetLongField(thiz, gFields.context);
140}
141
142static void android_media_MediaSync_release(JNIEnv *env, jobject thiz) {
143 setMediaSync(env, thiz, NULL);
144}
145
146static void throwExceptionAsNecessary(
147 JNIEnv *env, status_t err, const char *msg = NULL) {
148 switch (err) {
Wei Jia0feab712015-04-15 13:24:35 -0700149 case NO_ERROR:
Wei Jia071a8b72015-03-09 16:38:25 -0700150 break;
151
152 case BAD_VALUE:
153 jniThrowException(env, "java/lang/IllegalArgumentException", msg);
154 break;
155
Wei Jia0feab712015-04-15 13:24:35 -0700156 case NO_INIT:
157 case INVALID_OPERATION:
Wei Jia071a8b72015-03-09 16:38:25 -0700158 default:
Wei Jia0feab712015-04-15 13:24:35 -0700159 if (err > 0) {
160 break;
161 }
Wei Jia838a4ed2016-05-16 17:40:02 -0700162 AString msgWithErrorCode(msg == NULL ? "" : msg);
Wei Jia0feab712015-04-15 13:24:35 -0700163 msgWithErrorCode.append(" error:");
164 msgWithErrorCode.append(err);
165 jniThrowException(env, "java/lang/IllegalStateException", msgWithErrorCode.c_str());
Wei Jia071a8b72015-03-09 16:38:25 -0700166 break;
167 }
168}
169
Wei Jiad80d6f62015-05-04 15:59:20 -0700170static void android_media_MediaSync_native_setSurface(
Wei Jia071a8b72015-03-09 16:38:25 -0700171 JNIEnv *env, jobject thiz, jobject jsurface) {
Wei Jiad80d6f62015-05-04 15:59:20 -0700172 ALOGV("android_media_MediaSync_setSurface");
Wei Jia071a8b72015-03-09 16:38:25 -0700173
174 sp<JMediaSync> sync = getMediaSync(env, thiz);
175 if (sync == NULL) {
176 throwExceptionAsNecessary(env, INVALID_OPERATION);
177 return;
178 }
179
180 sp<IGraphicBufferProducer> bufferProducer;
181 if (jsurface != NULL) {
182 sp<Surface> surface(android_view_Surface_getSurface(env, jsurface));
183 if (surface != NULL) {
184 bufferProducer = surface->getIGraphicBufferProducer();
185 } else {
186 throwExceptionAsNecessary(env, BAD_VALUE, "The surface has been released");
187 return;
188 }
189 }
190
Wei Jiad80d6f62015-05-04 15:59:20 -0700191 status_t err = sync->setSurface(bufferProducer);
Wei Jia071a8b72015-03-09 16:38:25 -0700192
193 if (err == INVALID_OPERATION) {
194 throwExceptionAsNecessary(
195 env, INVALID_OPERATION, "Surface has already been configured");
196 } if (err != NO_ERROR) {
197 AString msg("Failed to connect to surface with error ");
198 msg.append(err);
199 throwExceptionAsNecessary(env, BAD_VALUE, msg.c_str());
200 }
201}
202
Wei Jiad80d6f62015-05-04 15:59:20 -0700203static void android_media_MediaSync_native_setAudioTrack(
Lajos Molnar05ebffe2015-04-29 20:41:19 -0700204 JNIEnv *env, jobject thiz, jobject jaudioTrack) {
Wei Jiad80d6f62015-05-04 15:59:20 -0700205 ALOGV("android_media_MediaSync_setAudioTrack");
Wei Jia071a8b72015-03-09 16:38:25 -0700206
207 sp<JMediaSync> sync = getMediaSync(env, thiz);
208 if (sync == NULL) {
209 throwExceptionAsNecessary(env, INVALID_OPERATION);
210 return;
211 }
212
213 sp<AudioTrack> audioTrack;
214 if (jaudioTrack != NULL) {
215 audioTrack = android_media_AudioTrack_getAudioTrack(env, jaudioTrack);
216 if (audioTrack == NULL) {
217 throwExceptionAsNecessary(env, BAD_VALUE, "The audio track has been released");
218 return;
219 }
220 }
221
Wei Jiad80d6f62015-05-04 15:59:20 -0700222 status_t err = sync->setAudioTrack(audioTrack);
Wei Jia071a8b72015-03-09 16:38:25 -0700223
224 if (err == INVALID_OPERATION) {
225 throwExceptionAsNecessary(
226 env, INVALID_OPERATION, "Audio track has already been configured");
227 } if (err != NO_ERROR) {
228 AString msg("Failed to configure audio track with error ");
229 msg.append(err);
230 throwExceptionAsNecessary(env, BAD_VALUE, msg.c_str());
231 }
232}
233
234static jobject android_media_MediaSync_createInputSurface(
235 JNIEnv* env, jobject thiz) {
236 ALOGV("android_media_MediaSync_createInputSurface");
237
238 sp<JMediaSync> sync = getMediaSync(env, thiz);
239 if (sync == NULL) {
240 throwExceptionAsNecessary(env, INVALID_OPERATION);
241 return NULL;
242 }
243
244 // Tell the MediaSync that we want to use a Surface as input.
245 sp<IGraphicBufferProducer> bufferProducer;
246 status_t err = sync->createInputSurface(&bufferProducer);
247 if (err != NO_ERROR) {
248 throwExceptionAsNecessary(env, INVALID_OPERATION);
249 return NULL;
250 }
251
252 // Wrap the IGBP in a Java-language Surface.
253 return android_view_Surface_createFromIGraphicBufferProducer(env,
254 bufferProducer);
255}
256
257static void android_media_MediaSync_native_updateQueuedAudioData(
258 JNIEnv *env, jobject thiz, jint sizeInBytes, jlong presentationTimeUs) {
259 sp<JMediaSync> sync = getMediaSync(env, thiz);
260 if (sync == NULL) {
261 throwExceptionAsNecessary(env, INVALID_OPERATION);
262 return;
263 }
264
265 status_t err = sync->updateQueuedAudioData(sizeInBytes, presentationTimeUs);
266 if (err != NO_ERROR) {
267 throwExceptionAsNecessary(env, err);
268 return;
269 }
270}
271
Wei Jia217ec0a2015-04-09 18:48:18 -0700272static jboolean android_media_MediaSync_native_getTimestamp(
273 JNIEnv *env, jobject thiz, jobject timestamp) {
274 sp<JMediaSync> sync = getMediaSync(env, thiz);
275 if (sync == NULL) {
276 throwExceptionAsNecessary(env, INVALID_OPERATION);
277 return JNI_FALSE;
278 }
279
280 sp<const MediaClock> mediaClock = sync->getMediaClock();
281 if (mediaClock == NULL) {
282 return JNI_FALSE;
283 }
284
285 int64_t nowUs = ALooper::GetNowUs();
286 int64_t mediaUs = 0;
287 if (mediaClock->getMediaTime(nowUs, &mediaUs) != OK) {
288 return JNI_FALSE;
289 }
290
291 env->SetLongField(timestamp, gFields.mediaTimestampMediaTimeUsID,
292 (jlong)mediaUs);
293 env->SetLongField(timestamp, gFields.mediaTimestampNanoTimeID,
294 (jlong)(nowUs * 1000));
295 env->SetFloatField(timestamp, gFields.mediaTimestampClockRateID,
296 (jfloat)mediaClock->getPlaybackRate());
297 return JNI_TRUE;
298}
299
Wei Jia25b802d2015-04-23 14:10:30 -0700300static jlong android_media_MediaSync_native_getPlayTimeForPendingAudioFrames(
301 JNIEnv *env, jobject thiz) {
302 sp<JMediaSync> sync = getMediaSync(env, thiz);
303 if (sync == NULL) {
304 throwExceptionAsNecessary(env, INVALID_OPERATION);
305 }
306
307 int64_t playTimeUs = 0;
308 status_t err = sync->getPlayTimeForPendingAudioFrames(&playTimeUs);
309 if (err != NO_ERROR) {
310 throwExceptionAsNecessary(env, err);
311 }
312 return (jlong)playTimeUs;
313}
314
Wei Jia2d61e2b2015-05-08 15:23:28 -0700315static jfloat android_media_MediaSync_setPlaybackParams(
316 JNIEnv *env, jobject thiz, jobject params) {
Lajos Molnarc98f58e2015-04-22 19:28:53 -0700317 sp<JMediaSync> sync = getMediaSync(env, thiz);
318 if (sync == NULL) {
319 throwExceptionAsNecessary(env, INVALID_OPERATION);
Lajos Molnar05ebffe2015-04-29 20:41:19 -0700320 return (jfloat)0.f;
321 }
322
Wei Jia2d61e2b2015-05-08 15:23:28 -0700323 PlaybackParams pbs;
324 pbs.fillFromJobject(env, gPlaybackParamsFields, params);
325 ALOGV("setPlaybackParams: %d:%f %d:%f %d:%u %d:%u",
Lajos Molnar05ebffe2015-04-29 20:41:19 -0700326 pbs.speedSet, pbs.audioRate.mSpeed,
327 pbs.pitchSet, pbs.audioRate.mPitch,
328 pbs.audioFallbackModeSet, pbs.audioRate.mFallbackMode,
329 pbs.audioStretchModeSet, pbs.audioRate.mStretchMode);
330
331 AudioPlaybackRate rate;
Wei Jia2d61e2b2015-05-08 15:23:28 -0700332 sync->getPlaybackParams(&rate);
Lajos Molnar05ebffe2015-04-29 20:41:19 -0700333 bool updatedRate = false;
334 if (pbs.speedSet) {
335 rate.mSpeed = pbs.audioRate.mSpeed;
336 updatedRate = true;
337 }
338 if (pbs.pitchSet) {
339 rate.mPitch = pbs.audioRate.mPitch;
340 updatedRate = true;
341 }
342 if (pbs.audioFallbackModeSet) {
343 rate.mFallbackMode = pbs.audioRate.mFallbackMode;
344 updatedRate = true;
345 }
346 if (pbs.audioStretchModeSet) {
347 rate.mStretchMode = pbs.audioRate.mStretchMode;
348 updatedRate = true;
349 }
350 if (updatedRate) {
Wei Jia2d61e2b2015-05-08 15:23:28 -0700351 status_t err = sync->setPlaybackParams(rate);
Lajos Molnar05ebffe2015-04-29 20:41:19 -0700352 if (err != OK) {
353 throwExceptionAsNecessary(env, err);
354 return (jfloat)0.f;
355 }
356 }
357
358 sp<const MediaClock> mediaClock = sync->getMediaClock();
359 if (mediaClock == NULL) {
360 return (jfloat)0.f;
361 }
362
363 return (jfloat)mediaClock->getPlaybackRate();
364}
365
Wei Jia2d61e2b2015-05-08 15:23:28 -0700366static jobject android_media_MediaSync_getPlaybackParams(
Lajos Molnar05ebffe2015-04-29 20:41:19 -0700367 JNIEnv *env, jobject thiz) {
368 sp<JMediaSync> sync = getMediaSync(env, thiz);
369 if (sync == NULL) {
370 throwExceptionAsNecessary(env, INVALID_OPERATION);
371 return NULL;
372 }
373
Wei Jia2d61e2b2015-05-08 15:23:28 -0700374 PlaybackParams pbs;
Lajos Molnar05ebffe2015-04-29 20:41:19 -0700375 AudioPlaybackRate &audioRate = pbs.audioRate;
Wei Jia2d61e2b2015-05-08 15:23:28 -0700376 sync->getPlaybackParams(&audioRate);
377 ALOGV("getPlaybackParams: %f %f %d %d",
Lajos Molnar05ebffe2015-04-29 20:41:19 -0700378 audioRate.mSpeed, audioRate.mPitch, audioRate.mFallbackMode, audioRate.mStretchMode);
379
380 pbs.speedSet = true;
381 pbs.pitchSet = true;
382 pbs.audioFallbackModeSet = true;
383 pbs.audioStretchModeSet = true;
384
Wei Jia2d61e2b2015-05-08 15:23:28 -0700385 return pbs.asJobject(env, gPlaybackParamsFields);
Lajos Molnar05ebffe2015-04-29 20:41:19 -0700386}
387
Wei Jia2d61e2b2015-05-08 15:23:28 -0700388static jfloat android_media_MediaSync_setSyncParams(
389 JNIEnv *env, jobject thiz, jobject params) {
Lajos Molnar05ebffe2015-04-29 20:41:19 -0700390 sp<JMediaSync> sync = getMediaSync(env, thiz);
391 if (sync == NULL) {
392 throwExceptionAsNecessary(env, INVALID_OPERATION);
393 return (jfloat)0.f;
Lajos Molnarc98f58e2015-04-22 19:28:53 -0700394 }
395
Wei Jia2d61e2b2015-05-08 15:23:28 -0700396 SyncParams scs;
397 scs.fillFromJobject(env, gSyncParamsFields, params);
398 ALOGV("setSyncParams: %d:%d %d:%d %d:%f %d:%f",
Lajos Molnar05ebffe2015-04-29 20:41:19 -0700399 scs.syncSourceSet, scs.sync.mSource,
400 scs.audioAdjustModeSet, scs.sync.mAudioAdjustMode,
401 scs.toleranceSet, scs.sync.mTolerance,
Lajos Molnarc98f58e2015-04-22 19:28:53 -0700402 scs.frameRateSet, scs.frameRate);
403
Lajos Molnar05ebffe2015-04-29 20:41:19 -0700404 AVSyncSettings avsync;
Wei Jia2d61e2b2015-05-08 15:23:28 -0700405 sync->getSyncParams(&avsync);
Lajos Molnar05ebffe2015-04-29 20:41:19 -0700406 bool updatedSync = false;
407 status_t err = OK;
408 if (scs.syncSourceSet) {
409 avsync.mSource = scs.sync.mSource;
410 updatedSync = true;
411 }
412 if (scs.audioAdjustModeSet) {
413 avsync.mAudioAdjustMode = scs.sync.mAudioAdjustMode;
414 updatedSync = true;
415 }
416 if (scs.toleranceSet) {
417 avsync.mTolerance = scs.sync.mTolerance;
418 updatedSync = true;
419 }
420 if (updatedSync) {
Wei Jia2d61e2b2015-05-08 15:23:28 -0700421 err = sync->setSyncParams(avsync);
Lajos Molnar05ebffe2015-04-29 20:41:19 -0700422 }
423
424 if (scs.frameRateSet && err == OK) {
425 err = sync->setVideoFrameRateHint(scs.frameRate);
426 }
427 if (err != OK) {
428 throwExceptionAsNecessary(env, err);
429 return (jfloat)0.f;
430 }
431
432 sp<const MediaClock> mediaClock = sync->getMediaClock();
433 if (mediaClock == NULL) {
434 return (jfloat)0.f;
435 }
436
437 return (jfloat)mediaClock->getPlaybackRate();
Lajos Molnarc98f58e2015-04-22 19:28:53 -0700438}
439
Wei Jia2d61e2b2015-05-08 15:23:28 -0700440static jobject android_media_MediaSync_getSyncParams(JNIEnv *env, jobject thiz) {
Lajos Molnarc98f58e2015-04-22 19:28:53 -0700441 sp<JMediaSync> sync = getMediaSync(env, thiz);
442 if (sync == NULL) {
443 throwExceptionAsNecessary(env, INVALID_OPERATION);
444 return NULL;
445 }
446
Wei Jia2d61e2b2015-05-08 15:23:28 -0700447 SyncParams scs;
448 sync->getSyncParams(&scs.sync);
Lajos Molnar05ebffe2015-04-29 20:41:19 -0700449 scs.frameRate = sync->getVideoFrameRate();
Lajos Molnarc98f58e2015-04-22 19:28:53 -0700450
Wei Jia2d61e2b2015-05-08 15:23:28 -0700451 ALOGV("getSyncParams: %d %d %f %f",
Lajos Molnar05ebffe2015-04-29 20:41:19 -0700452 scs.sync.mSource, scs.sync.mAudioAdjustMode, scs.sync.mTolerance, scs.frameRate);
453
Wei Jia2d61e2b2015-05-08 15:23:28 -0700454 // sanity check params
Lajos Molnar05ebffe2015-04-29 20:41:19 -0700455 if (scs.sync.mSource >= AVSYNC_SOURCE_MAX
456 || scs.sync.mAudioAdjustMode >= AVSYNC_AUDIO_ADJUST_MODE_MAX
457 || scs.sync.mTolerance < 0.f
458 || scs.sync.mTolerance >= AVSYNC_TOLERANCE_MAX) {
459 throwExceptionAsNecessary(env, INVALID_OPERATION);
460 return NULL;
461 }
Lajos Molnarc98f58e2015-04-22 19:28:53 -0700462
463 scs.syncSourceSet = true;
464 scs.audioAdjustModeSet = true;
465 scs.toleranceSet = true;
Lajos Molnar05ebffe2015-04-29 20:41:19 -0700466 scs.frameRateSet = scs.frameRate >= 0.f;
Lajos Molnarc98f58e2015-04-22 19:28:53 -0700467
Wei Jia2d61e2b2015-05-08 15:23:28 -0700468 return scs.asJobject(env, gSyncParamsFields);
Lajos Molnarc98f58e2015-04-22 19:28:53 -0700469}
470
Lajos Molnard08debcf2015-07-01 16:35:49 -0700471static void android_media_MediaSync_native_flush(JNIEnv *env, jobject thiz) {
472 sp<JMediaSync> sync = getMediaSync(env, thiz);
473 if (sync == NULL) {
474 throwExceptionAsNecessary(env, INVALID_OPERATION);
475 return;
476 }
477
478 sync->flush();
479}
480
Wei Jia071a8b72015-03-09 16:38:25 -0700481static void android_media_MediaSync_native_init(JNIEnv *env) {
482 ScopedLocalRef<jclass> clazz(env, env->FindClass("android/media/MediaSync"));
483 CHECK(clazz.get() != NULL);
484
485 gFields.context = env->GetFieldID(clazz.get(), "mNativeContext", "J");
486 CHECK(gFields.context != NULL);
Wei Jia217ec0a2015-04-09 18:48:18 -0700487
488 clazz.reset(env->FindClass("android/media/MediaTimestamp"));
489 CHECK(clazz.get() != NULL);
490
491 gFields.mediaTimestampMediaTimeUsID =
492 env->GetFieldID(clazz.get(), "mediaTimeUs", "J");
493 CHECK(gFields.mediaTimestampMediaTimeUsID != NULL);
494
495 gFields.mediaTimestampNanoTimeID =
496 env->GetFieldID(clazz.get(), "nanoTime", "J");
497 CHECK(gFields.mediaTimestampNanoTimeID != NULL);
498
499 gFields.mediaTimestampClockRateID =
Wei Jiadfb0e622015-04-10 16:47:12 -0700500 env->GetFieldID(clazz.get(), "clockRate", "F");
Wei Jia217ec0a2015-04-09 18:48:18 -0700501 CHECK(gFields.mediaTimestampClockRateID != NULL);
Lajos Molnarc98f58e2015-04-22 19:28:53 -0700502
Wei Jia2d61e2b2015-05-08 15:23:28 -0700503 gSyncParamsFields.init(env);
504 gPlaybackParamsFields.init(env);
Wei Jia071a8b72015-03-09 16:38:25 -0700505}
506
507static void android_media_MediaSync_native_setup(JNIEnv *env, jobject thiz) {
508 sp<JMediaSync> sync = new JMediaSync();
509
510 setMediaSync(env, thiz, sync);
511}
512
Wei Jia071a8b72015-03-09 16:38:25 -0700513static void android_media_MediaSync_native_finalize(JNIEnv *env, jobject thiz) {
514 android_media_MediaSync_release(env, thiz);
515}
516
517static JNINativeMethod gMethods[] = {
Wei Jiad80d6f62015-05-04 15:59:20 -0700518 { "native_setSurface",
Wei Jia071a8b72015-03-09 16:38:25 -0700519 "(Landroid/view/Surface;)V",
Wei Jiad80d6f62015-05-04 15:59:20 -0700520 (void *)android_media_MediaSync_native_setSurface },
Wei Jia071a8b72015-03-09 16:38:25 -0700521
Wei Jiad80d6f62015-05-04 15:59:20 -0700522 { "native_setAudioTrack",
523 "(Landroid/media/AudioTrack;)V",
524 (void *)android_media_MediaSync_native_setAudioTrack },
Wei Jia071a8b72015-03-09 16:38:25 -0700525
526 { "createInputSurface", "()Landroid/view/Surface;",
527 (void *)android_media_MediaSync_createInputSurface },
528
529 { "native_updateQueuedAudioData",
530 "(IJ)V",
531 (void *)android_media_MediaSync_native_updateQueuedAudioData },
532
Wei Jia217ec0a2015-04-09 18:48:18 -0700533 { "native_getTimestamp",
534 "(Landroid/media/MediaTimestamp;)Z",
535 (void *)android_media_MediaSync_native_getTimestamp },
536
Wei Jia25b802d2015-04-23 14:10:30 -0700537 { "native_getPlayTimeForPendingAudioFrames",
538 "()J",
539 (void *)android_media_MediaSync_native_getPlayTimeForPendingAudioFrames },
540
Lajos Molnard08debcf2015-07-01 16:35:49 -0700541 { "native_flush", "()V", (void *)android_media_MediaSync_native_flush },
542
Wei Jia071a8b72015-03-09 16:38:25 -0700543 { "native_init", "()V", (void *)android_media_MediaSync_native_init },
544
545 { "native_setup", "()V", (void *)android_media_MediaSync_native_setup },
546
547 { "native_release", "()V", (void *)android_media_MediaSync_release },
548
Wei Jia2d61e2b2015-05-08 15:23:28 -0700549 { "native_setPlaybackParams", "(Landroid/media/PlaybackParams;)F",
550 (void *)android_media_MediaSync_setPlaybackParams },
Wei Jia071a8b72015-03-09 16:38:25 -0700551
Wei Jia2d61e2b2015-05-08 15:23:28 -0700552 { "getPlaybackParams", "()Landroid/media/PlaybackParams;",
553 (void *)android_media_MediaSync_getPlaybackParams },
Lajos Molnarc98f58e2015-04-22 19:28:53 -0700554
Wei Jia2d61e2b2015-05-08 15:23:28 -0700555 { "native_setSyncParams", "(Landroid/media/SyncParams;)F",
556 (void *)android_media_MediaSync_setSyncParams },
Lajos Molnar05ebffe2015-04-29 20:41:19 -0700557
Wei Jia2d61e2b2015-05-08 15:23:28 -0700558 { "getSyncParams", "()Landroid/media/SyncParams;",
559 (void *)android_media_MediaSync_getSyncParams },
Lajos Molnarc98f58e2015-04-22 19:28:53 -0700560
Wei Jia071a8b72015-03-09 16:38:25 -0700561 { "native_finalize", "()V", (void *)android_media_MediaSync_native_finalize },
562};
563
564int register_android_media_MediaSync(JNIEnv *env) {
565 return AndroidRuntime::registerNativeMethods(
566 env, "android/media/MediaSync", gMethods, NELEM(gMethods));
567}