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