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