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