VideoEditorPlayer.cpp revision 8dcbd11c186e26b67de813adaec66dd578415cd7
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
63    return mPlayer->setDataSource(url, headers);
64}
65
66//We donot use this in preview, dummy implimentation as this is pure virtual
67status_t VideoEditorPlayer::setDataSource(int fd, int64_t offset,
68    int64_t length) {
69    ALOGE("setDataSource(%d, %lld, %lld) Not supported", fd, offset, length);
70    return (!OK);
71}
72
73status_t VideoEditorPlayer::setVideoSurface(const sp<Surface> &surface) {
74    ALOGV("setVideoSurface");
75
76    mPlayer->setSurface(surface);
77    return OK;
78}
79
80status_t VideoEditorPlayer::setVideoSurfaceTexture(const sp<ISurfaceTexture> &surfaceTexture) {
81    ALOGV("setVideoSurfaceTexture");
82
83    mPlayer->setSurfaceTexture(surfaceTexture);
84    return OK;
85}
86
87status_t VideoEditorPlayer::prepare() {
88    ALOGV("prepare");
89    return mPlayer->prepare();
90}
91
92status_t VideoEditorPlayer::prepareAsync() {
93    return mPlayer->prepareAsync();
94}
95
96status_t VideoEditorPlayer::start() {
97    ALOGV("start");
98    return mPlayer->play();
99}
100
101status_t VideoEditorPlayer::stop() {
102    ALOGV("stop");
103    return pause();
104}
105
106status_t VideoEditorPlayer::pause() {
107    ALOGV("pause");
108    return mPlayer->pause();
109}
110
111bool VideoEditorPlayer::isPlaying() {
112    ALOGV("isPlaying");
113    return mPlayer->isPlaying();
114}
115
116status_t VideoEditorPlayer::seekTo(int msec) {
117    ALOGV("seekTo");
118    status_t err = mPlayer->seekTo((int64_t)msec * 1000);
119    return err;
120}
121
122status_t VideoEditorPlayer::getCurrentPosition(int *msec) {
123    ALOGV("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
135status_t VideoEditorPlayer::getDuration(int *msec) {
136    ALOGV("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
150status_t VideoEditorPlayer::reset() {
151    ALOGV("reset");
152    mPlayer->reset();
153    return OK;
154}
155
156status_t VideoEditorPlayer::setLooping(int loop) {
157    ALOGV("setLooping");
158    return mPlayer->setLooping(loop);
159}
160
161status_t VideoEditorPlayer::setParameter(int key, const Parcel &request) {
162    ALOGV("setParameter");
163    return mPlayer->setParameter(key, request);
164}
165
166status_t VideoEditorPlayer::getParameter(int key, Parcel *reply) {
167    ALOGV("getParameter");
168    return mPlayer->getParameter(key, reply);
169}
170
171player_type VideoEditorPlayer::playerType() {
172    ALOGV("playerType");
173    return STAGEFRIGHT_PLAYER;
174}
175
176void VideoEditorPlayer::acquireLock() {
177    ALOGV("acquireLock");
178    mPlayer->acquireLock();
179}
180
181void VideoEditorPlayer::releaseLock() {
182    ALOGV("releaseLock");
183    mPlayer->releaseLock();
184}
185
186status_t VideoEditorPlayer::invoke(const Parcel &request, Parcel *reply) {
187    return INVALID_OPERATION;
188}
189
190void VideoEditorPlayer::setAudioSink(const sp<AudioSink> &audioSink) {
191    MediaPlayerInterface::setAudioSink(audioSink);
192
193    mPlayer->setAudioSink(audioSink);
194}
195
196status_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
223status_t VideoEditorPlayer::loadEffectsSettings(
224    M4VSS3GPP_EffectSettings* pEffectSettings, int nEffects) {
225    ALOGV("loadEffectsSettings");
226    return mPlayer->loadEffectsSettings(pEffectSettings, nEffects);
227}
228
229status_t VideoEditorPlayer::loadAudioMixSettings(
230    M4xVSS_AudioMixingSettings* pAudioMixSettings) {
231    ALOGV("VideoEditorPlayer: loadAudioMixSettings");
232    return mPlayer->loadAudioMixSettings(pAudioMixSettings);
233}
234
235status_t VideoEditorPlayer::setAudioMixPCMFileHandle(
236    M4OSA_Context pAudioMixPCMFileHandle) {
237
238    ALOGV("VideoEditorPlayer: loadAudioMixSettings");
239    return mPlayer->setAudioMixPCMFileHandle(pAudioMixPCMFileHandle);
240}
241
242status_t VideoEditorPlayer::setAudioMixStoryBoardParam(
243    M4OSA_UInt32 audioMixStoryBoardTS,
244    M4OSA_UInt32 currentMediaBeginCutTime,
245    M4OSA_UInt32 primaryTrackVolValue) {
246
247    ALOGV("VideoEditorPlayer: loadAudioMixSettings");
248    return mPlayer->setAudioMixStoryBoardParam(audioMixStoryBoardTS,
249     currentMediaBeginCutTime, primaryTrackVolValue);
250}
251
252status_t VideoEditorPlayer::setPlaybackBeginTime(uint32_t msec) {
253    ALOGV("setPlaybackBeginTime");
254    return mPlayer->setPlaybackBeginTime(msec);
255}
256
257status_t VideoEditorPlayer::setPlaybackEndTime(uint32_t msec) {
258    ALOGV("setPlaybackEndTime");
259    return mPlayer->setPlaybackEndTime(msec);
260}
261
262status_t VideoEditorPlayer::setStoryboardStartTime(uint32_t msec) {
263    ALOGV("setStoryboardStartTime");
264    return mPlayer->setStoryboardStartTime(msec);
265}
266
267status_t VideoEditorPlayer::setProgressCallbackInterval(uint32_t cbInterval) {
268    ALOGV("setProgressCallbackInterval");
269    return mPlayer->setProgressCallbackInterval(cbInterval);
270}
271
272status_t VideoEditorPlayer::setMediaRenderingMode(
273    M4xVSS_MediaRendering mode,
274    M4VIDEOEDITING_VideoFrameSize outputVideoSize) {
275
276    ALOGV("setMediaRenderingMode");
277    return mPlayer->setMediaRenderingMode(mode, outputVideoSize);
278}
279
280status_t VideoEditorPlayer::resetJniCallbackTimeStamp() {
281    ALOGV("resetJniCallbackTimeStamp");
282    return mPlayer->resetJniCallbackTimeStamp();
283}
284
285status_t VideoEditorPlayer::setImageClipProperties(
286    uint32_t width, uint32_t height) {
287    return mPlayer->setImageClipProperties(width, height);
288}
289
290status_t VideoEditorPlayer::readFirstVideoFrame() {
291    return mPlayer->readFirstVideoFrame();
292}
293
294status_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
303int VideoEditorPlayer::VeAudioOutput::mMinBufferCount = 4;
304bool VideoEditorPlayer::VeAudioOutput::mIsOnEmulator = false;
305
306VideoEditorPlayer::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
319VideoEditorPlayer::VeAudioOutput::~VeAudioOutput() {
320    close();
321}
322
323void VideoEditorPlayer::VeAudioOutput::setMinBufferCount() {
324
325    mIsOnEmulator = false;
326    mMinBufferCount = 4;
327}
328
329bool VideoEditorPlayer::VeAudioOutput::isOnEmulator() {
330
331    setMinBufferCount();
332    return mIsOnEmulator;
333}
334
335int VideoEditorPlayer::VeAudioOutput::getMinBufferCount() {
336
337    setMinBufferCount();
338    return mMinBufferCount;
339}
340
341ssize_t VideoEditorPlayer::VeAudioOutput::bufferSize() const {
342
343    if (mTrack == 0) return NO_INIT;
344    return mTrack->frameCount() * frameSize();
345}
346
347ssize_t VideoEditorPlayer::VeAudioOutput::frameCount() const {
348
349    if (mTrack == 0) return NO_INIT;
350    return mTrack->frameCount();
351}
352
353ssize_t VideoEditorPlayer::VeAudioOutput::channelCount() const
354{
355    if (mTrack == 0) return NO_INIT;
356    return mTrack->channelCount();
357}
358
359ssize_t VideoEditorPlayer::VeAudioOutput::frameSize() const
360{
361    if (mTrack == 0) return NO_INIT;
362    return mTrack->frameSize();
363}
364
365uint32_t VideoEditorPlayer::VeAudioOutput::latency () const
366{
367    return mLatency;
368}
369
370float VideoEditorPlayer::VeAudioOutput::msecsPerFrame() const
371{
372    return mMsecsPerFrame;
373}
374
375status_t VideoEditorPlayer::VeAudioOutput::getPosition(uint32_t *position) {
376
377    if (mTrack == 0) return NO_INIT;
378    return mTrack->getPosition(position);
379}
380
381status_t VideoEditorPlayer::VeAudioOutput::open(
382        uint32_t sampleRate, int channelCount, audio_format_t 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        ALOGV("bufferCount (%d) is too small and increased to %d",
391            bufferCount, mMinBufferCount);
392        bufferCount = mMinBufferCount;
393
394    }
395    ALOGV("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        ALOGE("Unable to create audio track");
436        delete t;
437        return NO_INIT;
438    }
439
440    ALOGV("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
448void VideoEditorPlayer::VeAudioOutput::start() {
449
450    ALOGV("start");
451    if (mTrack) {
452        mTrack->setVolume(mLeftVolume, mRightVolume);
453        mTrack->start();
454        mTrack->getPosition(&mNumFramesWritten);
455    }
456}
457
458void VideoEditorPlayer::VeAudioOutput::snoopWrite(
459    const void* buffer, size_t size) {
460    // Visualization buffers not supported
461    return;
462
463}
464
465ssize_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    //ALOGV("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
480void VideoEditorPlayer::VeAudioOutput::stop() {
481
482    ALOGV("stop");
483    if (mTrack) mTrack->stop();
484}
485
486void VideoEditorPlayer::VeAudioOutput::flush() {
487
488    ALOGV("flush");
489    if (mTrack) mTrack->flush();
490}
491
492void VideoEditorPlayer::VeAudioOutput::pause() {
493
494    ALOGV("VeAudioOutput::pause");
495    if (mTrack) mTrack->pause();
496}
497
498void VideoEditorPlayer::VeAudioOutput::close() {
499
500    ALOGV("close");
501    delete mTrack;
502    mTrack = 0;
503}
504
505void VideoEditorPlayer::VeAudioOutput::setVolume(float left, float right) {
506
507    ALOGV("setVolume(%f, %f)", left, right);
508    mLeftVolume = left;
509    mRightVolume = right;
510    if (mTrack) {
511        mTrack->setVolume(left, right);
512    }
513}
514
515// static
516void VideoEditorPlayer::VeAudioOutput::CallbackWrapper(
517        int event, void *cookie, void *info) {
518    //ALOGV("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
536status_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
556int VideoEditorPlayer::VeAudioOutput::getSessionId() {
557
558    return mSessionId;
559}
560
561}  // namespace android
562