blob: 7df6669700351214a632d14933950a6750122ef0 [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
280/* Implementation of AudioSink interface */
281#undef LOG_TAG
282#define LOG_TAG "VeAudioSink"
283
284int VideoEditorPlayer::VeAudioOutput::mMinBufferCount = 4;
285bool VideoEditorPlayer::VeAudioOutput::mIsOnEmulator = false;
286
287VideoEditorPlayer::VeAudioOutput::VeAudioOutput()
288 : mCallback(NULL),
289 mCallbackCookie(NULL) {
290 mTrack = 0;
291 mStreamType = AudioSystem::MUSIC;
292 mLeftVolume = 1.0;
293 mRightVolume = 1.0;
294 mLatency = 0;
295 mMsecsPerFrame = 0;
296 mNumFramesWritten = 0;
297 setMinBufferCount();
298}
299
300VideoEditorPlayer::VeAudioOutput::~VeAudioOutput() {
301 close();
302}
303
304void VideoEditorPlayer::VeAudioOutput::setMinBufferCount() {
305
306 mIsOnEmulator = false;
Danny Fernandesd196f1c2011-02-11 18:47:03 -0800307 mMinBufferCount = 4;
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800308}
309
310bool VideoEditorPlayer::VeAudioOutput::isOnEmulator() {
311
312 setMinBufferCount();
313 return mIsOnEmulator;
314}
315
316int VideoEditorPlayer::VeAudioOutput::getMinBufferCount() {
317
318 setMinBufferCount();
319 return mMinBufferCount;
320}
321
322ssize_t VideoEditorPlayer::VeAudioOutput::bufferSize() const {
323
324 if (mTrack == 0) return NO_INIT;
325 return mTrack->frameCount() * frameSize();
326}
327
328ssize_t VideoEditorPlayer::VeAudioOutput::frameCount() const {
329
330 if (mTrack == 0) return NO_INIT;
331 return mTrack->frameCount();
332}
333
334ssize_t VideoEditorPlayer::VeAudioOutput::channelCount() const
335{
336 if (mTrack == 0) return NO_INIT;
337 return mTrack->channelCount();
338}
339
340ssize_t VideoEditorPlayer::VeAudioOutput::frameSize() const
341{
342 if (mTrack == 0) return NO_INIT;
343 return mTrack->frameSize();
344}
345
346uint32_t VideoEditorPlayer::VeAudioOutput::latency () const
347{
348 return mLatency;
349}
350
351float VideoEditorPlayer::VeAudioOutput::msecsPerFrame() const
352{
353 return mMsecsPerFrame;
354}
355
356status_t VideoEditorPlayer::VeAudioOutput::getPosition(uint32_t *position) {
357
358 if (mTrack == 0) return NO_INIT;
359 return mTrack->getPosition(position);
360}
361
362status_t VideoEditorPlayer::VeAudioOutput::open(
363 uint32_t sampleRate, int channelCount, int format, int bufferCount,
364 AudioCallback cb, void *cookie) {
365
366 mCallback = cb;
367 mCallbackCookie = cookie;
368
369 // Check argument "bufferCount" against the mininum buffer count
370 if (bufferCount < mMinBufferCount) {
Danny Fernandesd196f1c2011-02-11 18:47:03 -0800371 LOGV("bufferCount (%d) is too small and increased to %d",
372 bufferCount, mMinBufferCount);
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800373 bufferCount = mMinBufferCount;
374
375 }
376 LOGV("open(%u, %d, %d, %d)", sampleRate, channelCount, format, bufferCount);
377 if (mTrack) close();
378 int afSampleRate;
379 int afFrameCount;
380 int frameCount;
381
382 if (AudioSystem::getOutputFrameCount(&afFrameCount, mStreamType) !=
383 NO_ERROR) {
384 return NO_INIT;
385 }
386 if (AudioSystem::getOutputSamplingRate(&afSampleRate, mStreamType) !=
387 NO_ERROR) {
388 return NO_INIT;
389 }
390
391 frameCount = (sampleRate*afFrameCount*bufferCount)/afSampleRate;
392
393 AudioTrack *t;
394 if (mCallback != NULL) {
395 t = new AudioTrack(
396 mStreamType,
397 sampleRate,
398 format,
399 (channelCount == 2) ?
400 AudioSystem::CHANNEL_OUT_STEREO : AudioSystem::CHANNEL_OUT_MONO,
401 frameCount,
402 0 /* flags */,
403 CallbackWrapper,
404 this);
405 } else {
406 t = new AudioTrack(
407 mStreamType,
408 sampleRate,
409 format,
410 (channelCount == 2) ?
411 AudioSystem::CHANNEL_OUT_STEREO : AudioSystem::CHANNEL_OUT_MONO,
412 frameCount);
413 }
414
415 if ((t == 0) || (t->initCheck() != NO_ERROR)) {
416 LOGE("Unable to create audio track");
417 delete t;
418 return NO_INIT;
419 }
420
421 LOGV("setVolume");
422 t->setVolume(mLeftVolume, mRightVolume);
423 mMsecsPerFrame = 1.e3 / (float) sampleRate;
424 mLatency = t->latency();
425 mTrack = t;
426 return NO_ERROR;
427}
428
429void VideoEditorPlayer::VeAudioOutput::start() {
430
431 LOGV("start");
432 if (mTrack) {
433 mTrack->setVolume(mLeftVolume, mRightVolume);
434 mTrack->start();
435 mTrack->getPosition(&mNumFramesWritten);
436 }
437}
438
439void VideoEditorPlayer::VeAudioOutput::snoopWrite(
440 const void* buffer, size_t size) {
441 // Visualization buffers not supported
442 return;
443
444}
445
446ssize_t VideoEditorPlayer::VeAudioOutput::write(
447 const void* buffer, size_t size) {
448
449 LOG_FATAL_IF(mCallback != NULL, "Don't call write if supplying a callback.");
450
451 //LOGV("write(%p, %u)", buffer, size);
452 if (mTrack) {
453 snoopWrite(buffer, size);
454 ssize_t ret = mTrack->write(buffer, size);
455 mNumFramesWritten += ret / 4; // assume 16 bit stereo
456 return ret;
457 }
458 return NO_INIT;
459}
460
461void VideoEditorPlayer::VeAudioOutput::stop() {
462
463 LOGV("stop");
464 if (mTrack) mTrack->stop();
465}
466
467void VideoEditorPlayer::VeAudioOutput::flush() {
468
469 LOGV("flush");
470 if (mTrack) mTrack->flush();
471}
472
473void VideoEditorPlayer::VeAudioOutput::pause() {
474
475 LOGV("VeAudioOutput::pause");
476 if (mTrack) mTrack->pause();
477}
478
479void VideoEditorPlayer::VeAudioOutput::close() {
480
481 LOGV("close");
482 delete mTrack;
483 mTrack = 0;
484}
485
486void VideoEditorPlayer::VeAudioOutput::setVolume(float left, float right) {
487
488 LOGV("setVolume(%f, %f)", left, right);
489 mLeftVolume = left;
490 mRightVolume = right;
491 if (mTrack) {
492 mTrack->setVolume(left, right);
493 }
494}
495
496// static
497void VideoEditorPlayer::VeAudioOutput::CallbackWrapper(
498 int event, void *cookie, void *info) {
499 //LOGV("VeAudioOutput::callbackwrapper");
500 if (event != AudioTrack::EVENT_MORE_DATA) {
501 return;
502 }
503
504 VeAudioOutput *me = (VeAudioOutput *)cookie;
505 AudioTrack::Buffer *buffer = (AudioTrack::Buffer *)info;
506
507 size_t actualSize = (*me->mCallback)(
508 me, buffer->raw, buffer->size, me->mCallbackCookie);
509
510 buffer->size = actualSize;
511
512 if (actualSize > 0) {
513 me->snoopWrite(buffer->raw, actualSize);
514 }
515}
516
517status_t VideoEditorPlayer::VeAudioOutput::dump(int fd, const Vector<String16>& args) const
518{
519 const size_t SIZE = 256;
520 char buffer[SIZE];
521 String8 result;
522
523 result.append(" VeAudioOutput\n");
524 snprintf(buffer, SIZE-1, " stream type(%d), left - right volume(%f, %f)\n",
525 mStreamType, mLeftVolume, mRightVolume);
526 result.append(buffer);
527 snprintf(buffer, SIZE-1, " msec per frame(%f), latency (%d)\n",
528 mMsecsPerFrame, mLatency);
529 result.append(buffer);
530 ::write(fd, result.string(), result.size());
531 if (mTrack != 0) {
532 mTrack->dump(fd, args);
533 }
534 return NO_ERROR;
535}
536
537int VideoEditorPlayer::VeAudioOutput::getSessionId() {
538
539 return mSessionId;
540}
541
542} // namespace android