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