VideoEditorPlayer.cpp revision 4aeec63e25e1d1f55d55245d1c0ffd554f2a2f49
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
72// needed?
73status_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
87status_t VideoEditorPlayer::setVideoSurfaceTexture(const sp<ISurfaceTexture> &surfaceTexture) {
88    LOGV("setVideoSurfaceTexture");
89
90    mPlayer->setSurfaceTexture(surfaceTexture);
91    return OK;
92}
93
94status_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
291status_t VideoEditorPlayer::getLastRenderedTimeMs(uint32_t *lastRenderedTimeMs) {
292    mPlayer->getLastRenderedTimeMs(lastRenderedTimeMs);
293    return NO_ERROR;
294}
295
296/* 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;
323    mMinBufferCount = 4;
324}
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) {
387        LOGV("bufferCount (%d) is too small and increased to %d",
388            bufferCount, mMinBufferCount);
389        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
559