blob: 2ca7996819ae73bfe84f11da918d528725367c80 [file] [log] [blame]
Dharmaray Kundargi643290d2011-01-16 16:02:42 -08001/*
2 * Copyright (C) 2011 NXP Software
3 * Copyright (C) 2011 The Android Open Source Project
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18#define LOG_NDEBUG 1
19#define LOG_TAG "VideoEditorPlayer"
20#include <utils/Log.h>
21
22#include "VideoEditorPlayer.h"
23#include "PreviewPlayer.h"
24
25#include <media/Metadata.h>
26#include <media/stagefright/MediaExtractor.h>
Dima Zavin68598372011-04-05 16:13:49 -070027
28#include <hardware/audio.h>
Dharmaray Kundargi643290d2011-01-16 16:02:42 -080029
30namespace android {
31
32VideoEditorPlayer::VideoEditorPlayer()
33 : mPlayer(new PreviewPlayer) {
34
35 LOGV("VideoEditorPlayer");
36 mPlayer->setListener(this);
37}
38
39VideoEditorPlayer::~VideoEditorPlayer() {
40 LOGV("~VideoEditorPlayer");
41
42 reset();
43 mVeAudioSink.clear();
44
45 delete mPlayer;
46 mPlayer = NULL;
47}
48
49status_t VideoEditorPlayer::initCheck() {
50 LOGV("initCheck");
51 return OK;
52}
53
Rajneesh Chowdury1c97d9a2011-02-21 15:43:33 -080054
55status_t VideoEditorPlayer::setAudioPlayer(VideoEditorAudioPlayer *audioPlayer) {
56 return mPlayer->setAudioPlayer(audioPlayer);
57}
58
59
Dharmaray Kundargi643290d2011-01-16 16:02:42 -080060status_t VideoEditorPlayer::setDataSource(
61 const char *url, const KeyedVector<String8, String8> *headers) {
62 LOGI("setDataSource('%s')", url);
63
Dharmaray Kundargi643290d2011-01-16 16:02:42 -080064 return mPlayer->setDataSource(url, headers);
65}
66
67//We donot use this in preview, dummy implimentation as this is pure virtual
68status_t VideoEditorPlayer::setDataSource(int fd, int64_t offset,
69 int64_t length) {
70 LOGE("setDataSource(%d, %lld, %lld) Not supported", fd, offset, length);
71 return (!OK);
72}
73
Dharmaray Kundargi643290d2011-01-16 16:02:42 -080074status_t VideoEditorPlayer::setVideoSurface(const sp<Surface> &surface) {
75 LOGV("setVideoSurface");
76
77 mPlayer->setSurface(surface);
78 return OK;
79}
80
Glenn Kasten4aeec632011-02-14 11:56:16 -080081status_t VideoEditorPlayer::setVideoSurfaceTexture(const sp<ISurfaceTexture> &surfaceTexture) {
82 LOGV("setVideoSurfaceTexture");
83
84 mPlayer->setSurfaceTexture(surfaceTexture);
85 return OK;
86}
87
Dharmaray Kundargi643290d2011-01-16 16:02:42 -080088status_t VideoEditorPlayer::prepare() {
89 LOGV("prepare");
90 return mPlayer->prepare();
91}
92
93status_t VideoEditorPlayer::prepareAsync() {
94 return mPlayer->prepareAsync();
95}
96
97status_t VideoEditorPlayer::start() {
98 LOGV("start");
99 return mPlayer->play();
100}
101
102status_t VideoEditorPlayer::stop() {
103 LOGV("stop");
104 return pause();
105}
106
107status_t VideoEditorPlayer::pause() {
108 LOGV("pause");
109 return mPlayer->pause();
110}
111
112bool VideoEditorPlayer::isPlaying() {
113 LOGV("isPlaying");
114 return mPlayer->isPlaying();
115}
116
117status_t VideoEditorPlayer::seekTo(int msec) {
118 LOGV("seekTo");
119 status_t err = mPlayer->seekTo((int64_t)msec * 1000);
120 return err;
121}
122
123status_t VideoEditorPlayer::getCurrentPosition(int *msec) {
124 LOGV("getCurrentPosition");
125 int64_t positionUs;
126 status_t err = mPlayer->getPosition(&positionUs);
127
128 if (err != OK) {
129 return err;
130 }
131
132 *msec = (positionUs + 500) / 1000;
133 return OK;
134}
135
136status_t VideoEditorPlayer::getDuration(int *msec) {
137 LOGV("getDuration");
138
139 int64_t durationUs;
140 status_t err = mPlayer->getDuration(&durationUs);
141
142 if (err != OK) {
143 *msec = 0;
144 return OK;
145 }
146
147 *msec = (durationUs + 500) / 1000;
148 return OK;
149}
150
151status_t VideoEditorPlayer::reset() {
152 LOGV("reset");
153 mPlayer->reset();
154 return OK;
155}
156
157status_t VideoEditorPlayer::setLooping(int loop) {
158 LOGV("setLooping");
159 return mPlayer->setLooping(loop);
160}
161
162player_type VideoEditorPlayer::playerType() {
163 LOGV("playerType");
164 return STAGEFRIGHT_PLAYER;
165}
166
167status_t VideoEditorPlayer::suspend() {
168 LOGV("suspend");
169 return mPlayer->suspend();
170}
171
172status_t VideoEditorPlayer::resume() {
173 LOGV("resume");
174 return mPlayer->resume();
Raghavender Pallafa31daf2011-03-18 22:32:51 -0700175}
176
177void VideoEditorPlayer::acquireLock() {
178 LOGV("acquireLock");
179 mPlayer->acquireLock();
180}
181
182void VideoEditorPlayer::releaseLock() {
183 LOGV("releaseLock");
184 mPlayer->releaseLock();
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800185}
186
187status_t VideoEditorPlayer::invoke(const Parcel &request, Parcel *reply) {
188 return INVALID_OPERATION;
189}
190
191void VideoEditorPlayer::setAudioSink(const sp<AudioSink> &audioSink) {
192 MediaPlayerInterface::setAudioSink(audioSink);
193
194 mPlayer->setAudioSink(audioSink);
195}
196
197status_t VideoEditorPlayer::getMetadata(
198 const media::Metadata::Filter& ids, Parcel *records) {
199 using media::Metadata;
200
201 uint32_t flags = mPlayer->flags();
202
203 Metadata metadata(records);
204
205 metadata.appendBool(
206 Metadata::kPauseAvailable,
207 flags & MediaExtractor::CAN_PAUSE);
208
209 metadata.appendBool(
210 Metadata::kSeekBackwardAvailable,
211 flags & MediaExtractor::CAN_SEEK_BACKWARD);
212
213 metadata.appendBool(
214 Metadata::kSeekForwardAvailable,
215 flags & MediaExtractor::CAN_SEEK_FORWARD);
216
217 metadata.appendBool(
218 Metadata::kSeekAvailable,
219 flags & MediaExtractor::CAN_SEEK);
220
221 return OK;
222}
223
224status_t VideoEditorPlayer::loadEffectsSettings(
225 M4VSS3GPP_EffectSettings* pEffectSettings, int nEffects) {
226 LOGV("loadEffectsSettings");
227 return mPlayer->loadEffectsSettings(pEffectSettings, nEffects);
228}
229
230status_t VideoEditorPlayer::loadAudioMixSettings(
231 M4xVSS_AudioMixingSettings* pAudioMixSettings) {
232 LOGV("VideoEditorPlayer: loadAudioMixSettings");
233 return mPlayer->loadAudioMixSettings(pAudioMixSettings);
234}
235
236status_t VideoEditorPlayer::setAudioMixPCMFileHandle(
237 M4OSA_Context pAudioMixPCMFileHandle) {
238
239 LOGV("VideoEditorPlayer: loadAudioMixSettings");
240 return mPlayer->setAudioMixPCMFileHandle(pAudioMixPCMFileHandle);
241}
242
243status_t VideoEditorPlayer::setAudioMixStoryBoardParam(
244 M4OSA_UInt32 audioMixStoryBoardTS,
245 M4OSA_UInt32 currentMediaBeginCutTime,
246 M4OSA_UInt32 primaryTrackVolValue) {
247
248 LOGV("VideoEditorPlayer: loadAudioMixSettings");
249 return mPlayer->setAudioMixStoryBoardParam(audioMixStoryBoardTS,
250 currentMediaBeginCutTime, primaryTrackVolValue);
251}
252
253status_t VideoEditorPlayer::setPlaybackBeginTime(uint32_t msec) {
254 LOGV("setPlaybackBeginTime");
255 return mPlayer->setPlaybackBeginTime(msec);
256}
257
258status_t VideoEditorPlayer::setPlaybackEndTime(uint32_t msec) {
259 LOGV("setPlaybackEndTime");
260 return mPlayer->setPlaybackEndTime(msec);
261}
262
263status_t VideoEditorPlayer::setStoryboardStartTime(uint32_t msec) {
264 LOGV("setStoryboardStartTime");
265 return mPlayer->setStoryboardStartTime(msec);
266}
267
268status_t VideoEditorPlayer::setProgressCallbackInterval(uint32_t cbInterval) {
269 LOGV("setProgressCallbackInterval");
270 return mPlayer->setProgressCallbackInterval(cbInterval);
271}
272
273status_t VideoEditorPlayer::setMediaRenderingMode(
274 M4xVSS_MediaRendering mode,
275 M4VIDEOEDITING_VideoFrameSize outputVideoSize) {
276
277 LOGV("setMediaRenderingMode");
278 return mPlayer->setMediaRenderingMode(mode, outputVideoSize);
279}
280
281status_t VideoEditorPlayer::resetJniCallbackTimeStamp() {
282 LOGV("resetJniCallbackTimeStamp");
283 return mPlayer->resetJniCallbackTimeStamp();
284}
285
286status_t VideoEditorPlayer::setImageClipProperties(
287 uint32_t width, uint32_t height) {
288 return mPlayer->setImageClipProperties(width, height);
289}
290
291status_t VideoEditorPlayer::readFirstVideoFrame() {
292 return mPlayer->readFirstVideoFrame();
293}
294
Santosh Madhavab2d6e0f2011-02-16 22:24:42 -0800295status_t VideoEditorPlayer::getLastRenderedTimeMs(uint32_t *lastRenderedTimeMs) {
296 mPlayer->getLastRenderedTimeMs(lastRenderedTimeMs);
297 return NO_ERROR;
298}
299
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800300/* Implementation of AudioSink interface */
301#undef LOG_TAG
302#define LOG_TAG "VeAudioSink"
303
304int VideoEditorPlayer::VeAudioOutput::mMinBufferCount = 4;
305bool VideoEditorPlayer::VeAudioOutput::mIsOnEmulator = false;
306
307VideoEditorPlayer::VeAudioOutput::VeAudioOutput()
308 : mCallback(NULL),
309 mCallbackCookie(NULL) {
310 mTrack = 0;
Dima Zavin68598372011-04-05 16:13:49 -0700311 mStreamType = AUDIO_STREAM_MUSIC;
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800312 mLeftVolume = 1.0;
313 mRightVolume = 1.0;
314 mLatency = 0;
315 mMsecsPerFrame = 0;
316 mNumFramesWritten = 0;
317 setMinBufferCount();
318}
319
320VideoEditorPlayer::VeAudioOutput::~VeAudioOutput() {
321 close();
322}
323
324void VideoEditorPlayer::VeAudioOutput::setMinBufferCount() {
325
326 mIsOnEmulator = false;
Danny Fernandesd196f1c2011-02-11 18:47:03 -0800327 mMinBufferCount = 4;
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800328}
329
330bool VideoEditorPlayer::VeAudioOutput::isOnEmulator() {
331
332 setMinBufferCount();
333 return mIsOnEmulator;
334}
335
336int VideoEditorPlayer::VeAudioOutput::getMinBufferCount() {
337
338 setMinBufferCount();
339 return mMinBufferCount;
340}
341
342ssize_t VideoEditorPlayer::VeAudioOutput::bufferSize() const {
343
344 if (mTrack == 0) return NO_INIT;
345 return mTrack->frameCount() * frameSize();
346}
347
348ssize_t VideoEditorPlayer::VeAudioOutput::frameCount() const {
349
350 if (mTrack == 0) return NO_INIT;
351 return mTrack->frameCount();
352}
353
354ssize_t VideoEditorPlayer::VeAudioOutput::channelCount() const
355{
356 if (mTrack == 0) return NO_INIT;
357 return mTrack->channelCount();
358}
359
360ssize_t VideoEditorPlayer::VeAudioOutput::frameSize() const
361{
362 if (mTrack == 0) return NO_INIT;
363 return mTrack->frameSize();
364}
365
366uint32_t VideoEditorPlayer::VeAudioOutput::latency () const
367{
368 return mLatency;
369}
370
371float VideoEditorPlayer::VeAudioOutput::msecsPerFrame() const
372{
373 return mMsecsPerFrame;
374}
375
376status_t VideoEditorPlayer::VeAudioOutput::getPosition(uint32_t *position) {
377
378 if (mTrack == 0) return NO_INIT;
379 return mTrack->getPosition(position);
380}
381
382status_t VideoEditorPlayer::VeAudioOutput::open(
383 uint32_t sampleRate, int channelCount, int format, int bufferCount,
384 AudioCallback cb, void *cookie) {
385
386 mCallback = cb;
387 mCallbackCookie = cookie;
388
389 // Check argument "bufferCount" against the mininum buffer count
390 if (bufferCount < mMinBufferCount) {
Danny Fernandesd196f1c2011-02-11 18:47:03 -0800391 LOGV("bufferCount (%d) is too small and increased to %d",
392 bufferCount, mMinBufferCount);
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800393 bufferCount = mMinBufferCount;
394
395 }
396 LOGV("open(%u, %d, %d, %d)", sampleRate, channelCount, format, bufferCount);
397 if (mTrack) close();
398 int afSampleRate;
399 int afFrameCount;
400 int frameCount;
401
402 if (AudioSystem::getOutputFrameCount(&afFrameCount, mStreamType) !=
403 NO_ERROR) {
404 return NO_INIT;
405 }
406 if (AudioSystem::getOutputSamplingRate(&afSampleRate, mStreamType) !=
407 NO_ERROR) {
408 return NO_INIT;
409 }
410
411 frameCount = (sampleRate*afFrameCount*bufferCount)/afSampleRate;
412
413 AudioTrack *t;
414 if (mCallback != NULL) {
415 t = new AudioTrack(
416 mStreamType,
417 sampleRate,
418 format,
419 (channelCount == 2) ?
Dima Zavin68598372011-04-05 16:13:49 -0700420 AUDIO_CHANNEL_OUT_STEREO : AUDIO_CHANNEL_OUT_MONO,
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800421 frameCount,
422 0 /* flags */,
423 CallbackWrapper,
424 this);
425 } else {
426 t = new AudioTrack(
427 mStreamType,
428 sampleRate,
429 format,
430 (channelCount == 2) ?
Dima Zavin68598372011-04-05 16:13:49 -0700431 AUDIO_CHANNEL_OUT_STEREO : AUDIO_CHANNEL_OUT_MONO,
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800432 frameCount);
433 }
434
435 if ((t == 0) || (t->initCheck() != NO_ERROR)) {
436 LOGE("Unable to create audio track");
437 delete t;
438 return NO_INIT;
439 }
440
441 LOGV("setVolume");
442 t->setVolume(mLeftVolume, mRightVolume);
443 mMsecsPerFrame = 1.e3 / (float) sampleRate;
444 mLatency = t->latency();
445 mTrack = t;
446 return NO_ERROR;
447}
448
449void VideoEditorPlayer::VeAudioOutput::start() {
450
451 LOGV("start");
452 if (mTrack) {
453 mTrack->setVolume(mLeftVolume, mRightVolume);
454 mTrack->start();
455 mTrack->getPosition(&mNumFramesWritten);
456 }
457}
458
459void VideoEditorPlayer::VeAudioOutput::snoopWrite(
460 const void* buffer, size_t size) {
461 // Visualization buffers not supported
462 return;
463
464}
465
466ssize_t VideoEditorPlayer::VeAudioOutput::write(
467 const void* buffer, size_t size) {
468
469 LOG_FATAL_IF(mCallback != NULL, "Don't call write if supplying a callback.");
470
471 //LOGV("write(%p, %u)", buffer, size);
472 if (mTrack) {
473 snoopWrite(buffer, size);
474 ssize_t ret = mTrack->write(buffer, size);
475 mNumFramesWritten += ret / 4; // assume 16 bit stereo
476 return ret;
477 }
478 return NO_INIT;
479}
480
481void VideoEditorPlayer::VeAudioOutput::stop() {
482
483 LOGV("stop");
484 if (mTrack) mTrack->stop();
485}
486
487void VideoEditorPlayer::VeAudioOutput::flush() {
488
489 LOGV("flush");
490 if (mTrack) mTrack->flush();
491}
492
493void VideoEditorPlayer::VeAudioOutput::pause() {
494
495 LOGV("VeAudioOutput::pause");
496 if (mTrack) mTrack->pause();
497}
498
499void VideoEditorPlayer::VeAudioOutput::close() {
500
501 LOGV("close");
502 delete mTrack;
503 mTrack = 0;
504}
505
506void VideoEditorPlayer::VeAudioOutput::setVolume(float left, float right) {
507
508 LOGV("setVolume(%f, %f)", left, right);
509 mLeftVolume = left;
510 mRightVolume = right;
511 if (mTrack) {
512 mTrack->setVolume(left, right);
513 }
514}
515
516// static
517void VideoEditorPlayer::VeAudioOutput::CallbackWrapper(
518 int event, void *cookie, void *info) {
519 //LOGV("VeAudioOutput::callbackwrapper");
520 if (event != AudioTrack::EVENT_MORE_DATA) {
521 return;
522 }
523
524 VeAudioOutput *me = (VeAudioOutput *)cookie;
525 AudioTrack::Buffer *buffer = (AudioTrack::Buffer *)info;
526
527 size_t actualSize = (*me->mCallback)(
528 me, buffer->raw, buffer->size, me->mCallbackCookie);
529
530 buffer->size = actualSize;
531
532 if (actualSize > 0) {
533 me->snoopWrite(buffer->raw, actualSize);
534 }
535}
536
537status_t VideoEditorPlayer::VeAudioOutput::dump(int fd, const Vector<String16>& args) const
538{
539 const size_t SIZE = 256;
540 char buffer[SIZE];
541 String8 result;
542
543 result.append(" VeAudioOutput\n");
544 snprintf(buffer, SIZE-1, " stream type(%d), left - right volume(%f, %f)\n",
545 mStreamType, mLeftVolume, mRightVolume);
546 result.append(buffer);
547 snprintf(buffer, SIZE-1, " msec per frame(%f), latency (%d)\n",
548 mMsecsPerFrame, mLatency);
549 result.append(buffer);
550 ::write(fd, result.string(), result.size());
551 if (mTrack != 0) {
552 mTrack->dump(fd, args);
553 }
554 return NO_ERROR;
555}
556
557int VideoEditorPlayer::VeAudioOutput::getSessionId() {
558
559 return mSessionId;
560}
561
562} // namespace android