VideoEditorPlayer.cpp revision 1c97d9ab52a288d24ea54499de435277cc1a3d68
1/*
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
52
53status_t VideoEditorPlayer::setAudioPlayer(VideoEditorAudioPlayer *audioPlayer) {
54    return mPlayer->setAudioPlayer(audioPlayer);
55}
56
57
58status_t VideoEditorPlayer::setDataSource(
59        const char *url, const KeyedVector<String8, String8> *headers) {
60    LOGI("setDataSource('%s')", url);
61
62    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
283status_t VideoEditorPlayer::getLastRenderedTimeMs(uint32_t *lastRenderedTimeMs) {
284    mPlayer->getLastRenderedTimeMs(lastRenderedTimeMs);
285    return NO_ERROR;
286}
287
288/* 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;
315    mMinBufferCount = 4;
316}
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) {
379        LOGV("bufferCount (%d) is too small and increased to %d",
380            bufferCount, mMinBufferCount);
381        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
551