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