blob: 912aab061e489bddb65e4fc390b9459d1f401259 [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
Dima Zavin272eb552011-05-11 14:15:37 -070028#include <system/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
Gloria Wangacb62af2011-04-25 17:29:16 -0700162status_t VideoEditorPlayer::setParameter(int key, const Parcel &request) {
163 LOGV("setParameter");
164 return mPlayer->setParameter(key, request);
165}
166
167status_t VideoEditorPlayer::getParameter(int key, Parcel *reply) {
168 LOGV("getParameter");
169 return mPlayer->getParameter(key, reply);
170}
171
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800172player_type VideoEditorPlayer::playerType() {
173 LOGV("playerType");
174 return STAGEFRIGHT_PLAYER;
175}
176
177status_t VideoEditorPlayer::suspend() {
178 LOGV("suspend");
179 return mPlayer->suspend();
180}
181
182status_t VideoEditorPlayer::resume() {
183 LOGV("resume");
184 return mPlayer->resume();
Raghavender Pallafa31daf2011-03-18 22:32:51 -0700185}
186
187void VideoEditorPlayer::acquireLock() {
188 LOGV("acquireLock");
189 mPlayer->acquireLock();
190}
191
192void VideoEditorPlayer::releaseLock() {
193 LOGV("releaseLock");
194 mPlayer->releaseLock();
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800195}
196
197status_t VideoEditorPlayer::invoke(const Parcel &request, Parcel *reply) {
198 return INVALID_OPERATION;
199}
200
201void VideoEditorPlayer::setAudioSink(const sp<AudioSink> &audioSink) {
202 MediaPlayerInterface::setAudioSink(audioSink);
203
204 mPlayer->setAudioSink(audioSink);
205}
206
207status_t VideoEditorPlayer::getMetadata(
208 const media::Metadata::Filter& ids, Parcel *records) {
209 using media::Metadata;
210
211 uint32_t flags = mPlayer->flags();
212
213 Metadata metadata(records);
214
215 metadata.appendBool(
216 Metadata::kPauseAvailable,
217 flags & MediaExtractor::CAN_PAUSE);
218
219 metadata.appendBool(
220 Metadata::kSeekBackwardAvailable,
221 flags & MediaExtractor::CAN_SEEK_BACKWARD);
222
223 metadata.appendBool(
224 Metadata::kSeekForwardAvailable,
225 flags & MediaExtractor::CAN_SEEK_FORWARD);
226
227 metadata.appendBool(
228 Metadata::kSeekAvailable,
229 flags & MediaExtractor::CAN_SEEK);
230
231 return OK;
232}
233
234status_t VideoEditorPlayer::loadEffectsSettings(
235 M4VSS3GPP_EffectSettings* pEffectSettings, int nEffects) {
236 LOGV("loadEffectsSettings");
237 return mPlayer->loadEffectsSettings(pEffectSettings, nEffects);
238}
239
240status_t VideoEditorPlayer::loadAudioMixSettings(
241 M4xVSS_AudioMixingSettings* pAudioMixSettings) {
242 LOGV("VideoEditorPlayer: loadAudioMixSettings");
243 return mPlayer->loadAudioMixSettings(pAudioMixSettings);
244}
245
246status_t VideoEditorPlayer::setAudioMixPCMFileHandle(
247 M4OSA_Context pAudioMixPCMFileHandle) {
248
249 LOGV("VideoEditorPlayer: loadAudioMixSettings");
250 return mPlayer->setAudioMixPCMFileHandle(pAudioMixPCMFileHandle);
251}
252
253status_t VideoEditorPlayer::setAudioMixStoryBoardParam(
254 M4OSA_UInt32 audioMixStoryBoardTS,
255 M4OSA_UInt32 currentMediaBeginCutTime,
256 M4OSA_UInt32 primaryTrackVolValue) {
257
258 LOGV("VideoEditorPlayer: loadAudioMixSettings");
259 return mPlayer->setAudioMixStoryBoardParam(audioMixStoryBoardTS,
260 currentMediaBeginCutTime, primaryTrackVolValue);
261}
262
263status_t VideoEditorPlayer::setPlaybackBeginTime(uint32_t msec) {
264 LOGV("setPlaybackBeginTime");
265 return mPlayer->setPlaybackBeginTime(msec);
266}
267
268status_t VideoEditorPlayer::setPlaybackEndTime(uint32_t msec) {
269 LOGV("setPlaybackEndTime");
270 return mPlayer->setPlaybackEndTime(msec);
271}
272
273status_t VideoEditorPlayer::setStoryboardStartTime(uint32_t msec) {
274 LOGV("setStoryboardStartTime");
275 return mPlayer->setStoryboardStartTime(msec);
276}
277
278status_t VideoEditorPlayer::setProgressCallbackInterval(uint32_t cbInterval) {
279 LOGV("setProgressCallbackInterval");
280 return mPlayer->setProgressCallbackInterval(cbInterval);
281}
282
283status_t VideoEditorPlayer::setMediaRenderingMode(
284 M4xVSS_MediaRendering mode,
285 M4VIDEOEDITING_VideoFrameSize outputVideoSize) {
286
287 LOGV("setMediaRenderingMode");
288 return mPlayer->setMediaRenderingMode(mode, outputVideoSize);
289}
290
291status_t VideoEditorPlayer::resetJniCallbackTimeStamp() {
292 LOGV("resetJniCallbackTimeStamp");
293 return mPlayer->resetJniCallbackTimeStamp();
294}
295
296status_t VideoEditorPlayer::setImageClipProperties(
297 uint32_t width, uint32_t height) {
298 return mPlayer->setImageClipProperties(width, height);
299}
300
301status_t VideoEditorPlayer::readFirstVideoFrame() {
302 return mPlayer->readFirstVideoFrame();
303}
304
Santosh Madhavab2d6e0f2011-02-16 22:24:42 -0800305status_t VideoEditorPlayer::getLastRenderedTimeMs(uint32_t *lastRenderedTimeMs) {
306 mPlayer->getLastRenderedTimeMs(lastRenderedTimeMs);
307 return NO_ERROR;
308}
309
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800310/* Implementation of AudioSink interface */
311#undef LOG_TAG
312#define LOG_TAG "VeAudioSink"
313
314int VideoEditorPlayer::VeAudioOutput::mMinBufferCount = 4;
315bool VideoEditorPlayer::VeAudioOutput::mIsOnEmulator = false;
316
317VideoEditorPlayer::VeAudioOutput::VeAudioOutput()
318 : mCallback(NULL),
319 mCallbackCookie(NULL) {
320 mTrack = 0;
Dima Zavin68598372011-04-05 16:13:49 -0700321 mStreamType = AUDIO_STREAM_MUSIC;
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800322 mLeftVolume = 1.0;
323 mRightVolume = 1.0;
324 mLatency = 0;
325 mMsecsPerFrame = 0;
326 mNumFramesWritten = 0;
327 setMinBufferCount();
328}
329
330VideoEditorPlayer::VeAudioOutput::~VeAudioOutput() {
331 close();
332}
333
334void VideoEditorPlayer::VeAudioOutput::setMinBufferCount() {
335
336 mIsOnEmulator = false;
Danny Fernandesd196f1c2011-02-11 18:47:03 -0800337 mMinBufferCount = 4;
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800338}
339
340bool VideoEditorPlayer::VeAudioOutput::isOnEmulator() {
341
342 setMinBufferCount();
343 return mIsOnEmulator;
344}
345
346int VideoEditorPlayer::VeAudioOutput::getMinBufferCount() {
347
348 setMinBufferCount();
349 return mMinBufferCount;
350}
351
352ssize_t VideoEditorPlayer::VeAudioOutput::bufferSize() const {
353
354 if (mTrack == 0) return NO_INIT;
355 return mTrack->frameCount() * frameSize();
356}
357
358ssize_t VideoEditorPlayer::VeAudioOutput::frameCount() const {
359
360 if (mTrack == 0) return NO_INIT;
361 return mTrack->frameCount();
362}
363
364ssize_t VideoEditorPlayer::VeAudioOutput::channelCount() const
365{
366 if (mTrack == 0) return NO_INIT;
367 return mTrack->channelCount();
368}
369
370ssize_t VideoEditorPlayer::VeAudioOutput::frameSize() const
371{
372 if (mTrack == 0) return NO_INIT;
373 return mTrack->frameSize();
374}
375
376uint32_t VideoEditorPlayer::VeAudioOutput::latency () const
377{
378 return mLatency;
379}
380
381float VideoEditorPlayer::VeAudioOutput::msecsPerFrame() const
382{
383 return mMsecsPerFrame;
384}
385
386status_t VideoEditorPlayer::VeAudioOutput::getPosition(uint32_t *position) {
387
388 if (mTrack == 0) return NO_INIT;
389 return mTrack->getPosition(position);
390}
391
392status_t VideoEditorPlayer::VeAudioOutput::open(
393 uint32_t sampleRate, int channelCount, int format, int bufferCount,
394 AudioCallback cb, void *cookie) {
395
396 mCallback = cb;
397 mCallbackCookie = cookie;
398
399 // Check argument "bufferCount" against the mininum buffer count
400 if (bufferCount < mMinBufferCount) {
Danny Fernandesd196f1c2011-02-11 18:47:03 -0800401 LOGV("bufferCount (%d) is too small and increased to %d",
402 bufferCount, mMinBufferCount);
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800403 bufferCount = mMinBufferCount;
404
405 }
406 LOGV("open(%u, %d, %d, %d)", sampleRate, channelCount, format, bufferCount);
407 if (mTrack) close();
408 int afSampleRate;
409 int afFrameCount;
410 int frameCount;
411
412 if (AudioSystem::getOutputFrameCount(&afFrameCount, mStreamType) !=
413 NO_ERROR) {
414 return NO_INIT;
415 }
416 if (AudioSystem::getOutputSamplingRate(&afSampleRate, mStreamType) !=
417 NO_ERROR) {
418 return NO_INIT;
419 }
420
421 frameCount = (sampleRate*afFrameCount*bufferCount)/afSampleRate;
422
423 AudioTrack *t;
424 if (mCallback != NULL) {
425 t = new AudioTrack(
426 mStreamType,
427 sampleRate,
428 format,
429 (channelCount == 2) ?
Dima Zavin68598372011-04-05 16:13:49 -0700430 AUDIO_CHANNEL_OUT_STEREO : AUDIO_CHANNEL_OUT_MONO,
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800431 frameCount,
432 0 /* flags */,
433 CallbackWrapper,
434 this);
435 } else {
436 t = new AudioTrack(
437 mStreamType,
438 sampleRate,
439 format,
440 (channelCount == 2) ?
Dima Zavin68598372011-04-05 16:13:49 -0700441 AUDIO_CHANNEL_OUT_STEREO : AUDIO_CHANNEL_OUT_MONO,
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800442 frameCount);
443 }
444
445 if ((t == 0) || (t->initCheck() != NO_ERROR)) {
446 LOGE("Unable to create audio track");
447 delete t;
448 return NO_INIT;
449 }
450
451 LOGV("setVolume");
452 t->setVolume(mLeftVolume, mRightVolume);
453 mMsecsPerFrame = 1.e3 / (float) sampleRate;
454 mLatency = t->latency();
455 mTrack = t;
456 return NO_ERROR;
457}
458
459void VideoEditorPlayer::VeAudioOutput::start() {
460
461 LOGV("start");
462 if (mTrack) {
463 mTrack->setVolume(mLeftVolume, mRightVolume);
464 mTrack->start();
465 mTrack->getPosition(&mNumFramesWritten);
466 }
467}
468
469void VideoEditorPlayer::VeAudioOutput::snoopWrite(
470 const void* buffer, size_t size) {
471 // Visualization buffers not supported
472 return;
473
474}
475
476ssize_t VideoEditorPlayer::VeAudioOutput::write(
477 const void* buffer, size_t size) {
478
479 LOG_FATAL_IF(mCallback != NULL, "Don't call write if supplying a callback.");
480
481 //LOGV("write(%p, %u)", buffer, size);
482 if (mTrack) {
483 snoopWrite(buffer, size);
484 ssize_t ret = mTrack->write(buffer, size);
485 mNumFramesWritten += ret / 4; // assume 16 bit stereo
486 return ret;
487 }
488 return NO_INIT;
489}
490
491void VideoEditorPlayer::VeAudioOutput::stop() {
492
493 LOGV("stop");
494 if (mTrack) mTrack->stop();
495}
496
497void VideoEditorPlayer::VeAudioOutput::flush() {
498
499 LOGV("flush");
500 if (mTrack) mTrack->flush();
501}
502
503void VideoEditorPlayer::VeAudioOutput::pause() {
504
505 LOGV("VeAudioOutput::pause");
506 if (mTrack) mTrack->pause();
507}
508
509void VideoEditorPlayer::VeAudioOutput::close() {
510
511 LOGV("close");
512 delete mTrack;
513 mTrack = 0;
514}
515
516void VideoEditorPlayer::VeAudioOutput::setVolume(float left, float right) {
517
518 LOGV("setVolume(%f, %f)", left, right);
519 mLeftVolume = left;
520 mRightVolume = right;
521 if (mTrack) {
522 mTrack->setVolume(left, right);
523 }
524}
525
526// static
527void VideoEditorPlayer::VeAudioOutput::CallbackWrapper(
Glenn Kasten72e95e72011-06-01 15:20:41 -0700528 int event, void *cookie, void *info) {
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800529 //LOGV("VeAudioOutput::callbackwrapper");
530 if (event != AudioTrack::EVENT_MORE_DATA) {
531 return;
532 }
533
534 VeAudioOutput *me = (VeAudioOutput *)cookie;
535 AudioTrack::Buffer *buffer = (AudioTrack::Buffer *)info;
536
537 size_t actualSize = (*me->mCallback)(
538 me, buffer->raw, buffer->size, me->mCallbackCookie);
539
540 buffer->size = actualSize;
541
542 if (actualSize > 0) {
543 me->snoopWrite(buffer->raw, actualSize);
544 }
545}
546
547status_t VideoEditorPlayer::VeAudioOutput::dump(int fd, const Vector<String16>& args) const
548{
549 const size_t SIZE = 256;
550 char buffer[SIZE];
551 String8 result;
552
553 result.append(" VeAudioOutput\n");
554 snprintf(buffer, SIZE-1, " stream type(%d), left - right volume(%f, %f)\n",
555 mStreamType, mLeftVolume, mRightVolume);
556 result.append(buffer);
557 snprintf(buffer, SIZE-1, " msec per frame(%f), latency (%d)\n",
558 mMsecsPerFrame, mLatency);
559 result.append(buffer);
560 ::write(fd, result.string(), result.size());
561 if (mTrack != 0) {
562 mTrack->dump(fd, args);
563 }
564 return NO_ERROR;
565}
566
567int VideoEditorPlayer::VeAudioOutput::getSessionId() {
568
569 return mSessionId;
570}
571
572} // namespace android