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