1efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang/*
2efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang * Copyright (C) 2011 The Android Open Source Project
3efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang *
4efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang * Licensed under the Apache License, Version 2.0 (the "License");
5efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang * you may not use this file except in compliance with the License.
6efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang * You may obtain a copy of the License at
7efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang *
8efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang *      http://www.apache.org/licenses/LICENSE-2.0
9efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang *
10efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang * Unless required by applicable law or agreed to in writing, software
11efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang * distributed under the License is distributed on an "AS IS" BASIS,
12efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang * See the License for the specific language governing permissions and
14efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang * limitations under the License.
15efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang */
16efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang
17e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang//#define LOG_NDEBUG 0
18e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang#define LOG_TAG "VideoEditorSRC"
19efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang
20efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang#include "VideoEditorSRC.h"
21efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang#include <media/stagefright/MetaData.h>
22efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang#include <media/stagefright/MediaDebug.h>
23efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang#include <media/stagefright/MediaBuffer.h>
24efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang#include <media/stagefright/MediaDefs.h>
25efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang#include "AudioMixer.h"
26e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang#include <utils/Log.h>
27efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang
28efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Changnamespace android {
29efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang
30e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung ChangVideoEditorSRC::VideoEditorSRC(const sp<MediaSource> &source) {
31e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang    LOGV("VideoEditorSRC::VideoEditorSRC %p(%p)", this, source.get());
32efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang    mSource = source;
33efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang    mResampler = NULL;
34efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang    mChannelCnt = 0;
35efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang    mSampleRate = 0;
36efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang    mOutputSampleRate = DEFAULT_SAMPLING_FREQ;
37efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang    mStarted = false;
38efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang    mInitialTimeStampUs = -1;
39efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang    mAccuOutBufferSize  = 0;
40efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang    mSeekTimeUs = -1;
41e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang    mBuffer = NULL;
42efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang    mLeftover = 0;
43e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang    mFormatChanged = false;
440d2c710a293d68fb729eff148d40002f5deacf17Chih-Chung Chang    mStopPending = false;
45e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang    mSeekMode = ReadOptions::SEEK_PREVIOUS_SYNC;
46efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang
47efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang    // Input Source validation
48efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang    sp<MetaData> format = mSource->getFormat();
49efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang    const char *mime;
50e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang    CHECK(format->findCString(kKeyMIMEType, &mime));
51efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang    CHECK(!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW));
52efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang
53e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang    // Set the metadata of the output after resampling.
54e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang    mOutputFormat = new MetaData;
55e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang    mOutputFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_RAW);
56e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang    mOutputFormat->setInt32(kKeySampleRate, DEFAULT_SAMPLING_FREQ);
57e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang    mOutputFormat->setInt32(kKeyChannelCount, 2);
58efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang}
59efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang
60e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung ChangVideoEditorSRC::~VideoEditorSRC() {
61e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang    LOGV("VideoEditorSRC::~VideoEditorSRC %p(%p)", this, mSource.get());
62e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang    stop();
63efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang}
64efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang
65e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Changstatus_t VideoEditorSRC::start(MetaData *params) {
66efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang    CHECK(!mStarted);
67e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang    LOGV("VideoEditorSRC:start %p(%p)", this, mSource.get());
68efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang
6984161acd0c02718b47f82ced3123e9d9eac7b9b9Rajneesh Chowdury    // Set resampler if required
70e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang    checkAndSetResampler();
7184161acd0c02718b47f82ced3123e9d9eac7b9b9Rajneesh Chowdury
72efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang    mSeekTimeUs = -1;
73e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang    mSeekMode = ReadOptions::SEEK_PREVIOUS_SYNC;
74efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang    mStarted = true;
75efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang    mSource->start();
76efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang
77efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang    return OK;
78efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang}
79efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang
80efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Changstatus_t VideoEditorSRC::stop() {
81e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang    LOGV("VideoEditorSRC::stop %p(%p)", this, mSource.get());
82e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang    if (!mStarted) return OK;
83e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang    if (mBuffer) {
84e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang        mBuffer->release();
85e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang        mBuffer = NULL;
86e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang    }
87efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang    mSource->stop();
88efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang    if(mResampler != NULL) {
89efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang        delete mResampler;
90efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang        mResampler = NULL;
91efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang    }
92efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang    mStarted = false;
93efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang    mInitialTimeStampUs = -1;
94e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang    mAccuOutBufferSize = 0;
95efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang    mLeftover = 0;
96efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang
97efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang    return OK;
98efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang}
99efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang
100efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Changsp<MetaData> VideoEditorSRC::getFormat() {
101e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang    LOGV("VideoEditorSRC::getFormat");
102efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang    return mOutputFormat;
103efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang}
104efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang
105e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Changstatus_t VideoEditorSRC::read(
106efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang        MediaBuffer **buffer_out, const ReadOptions *options) {
107e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang    LOGV("VideoEditorSRC::read %p(%p)", this, mSource.get());
108efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang    *buffer_out = NULL;
109efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang
110efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang    if (!mStarted) {
111efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang        return ERROR_END_OF_STREAM;
112efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang    }
113efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang
114e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang    if (mResampler) {
115efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang        // Store the seek parameters
116efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang        int64_t seekTimeUs;
117efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang        ReadOptions::SeekMode mode = ReadOptions::SEEK_PREVIOUS_SYNC;
118efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang        if (options && options->getSeekTo(&seekTimeUs, &mode)) {
119efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang            LOGV("read Seek %lld", seekTimeUs);
120efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang            mSeekTimeUs = seekTimeUs;
121efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang            mSeekMode = mode;
122efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang        }
123efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang
124efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang        // We ask for 1024 frames in output
125e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang        const size_t outFrameCnt = 1024;
126e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang        // resampler output is always 2 channels and 32 bits
127e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang        int32_t *pTmpBuffer = (int32_t *)calloc(1, outFrameCnt * 2 * sizeof(int32_t));
128efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang        // Resample to target quality
129efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang        mResampler->resample(pTmpBuffer, outFrameCnt, this);
130efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang
1310d2c710a293d68fb729eff148d40002f5deacf17Chih-Chung Chang        if (mStopPending) {
1320d2c710a293d68fb729eff148d40002f5deacf17Chih-Chung Chang            stop();
1330d2c710a293d68fb729eff148d40002f5deacf17Chih-Chung Chang            mStopPending = false;
1340d2c710a293d68fb729eff148d40002f5deacf17Chih-Chung Chang        }
1350d2c710a293d68fb729eff148d40002f5deacf17Chih-Chung Chang
136e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang        // Change resampler and retry if format change happened
137e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang        if (mFormatChanged) {
138e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang            mFormatChanged = false;
139e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang            checkAndSetResampler();
140e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang            free(pTmpBuffer);
141e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang            return read(buffer_out, NULL);
142efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang        }
143efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang
144e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang        // Create a new MediaBuffer
145e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang        int32_t outBufferSize = outFrameCnt * 2 * sizeof(int16_t);
146e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang        MediaBuffer* outBuffer = new MediaBuffer(outBufferSize);
147efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang
148e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang        // Convert back to 2 channels and 16 bits
149e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang        AudioMixer::ditherAndClamp(
150e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang                (int32_t *)((uint8_t*)outBuffer->data() + outBuffer->range_offset()),
151e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang                pTmpBuffer, outFrameCnt);
152e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang        free(pTmpBuffer);
153efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang
154efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang        // Compute and set the new timestamp
155e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang        sp<MetaData> to = outBuffer->meta_data();
156e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang        int64_t totalOutDurationUs = (mAccuOutBufferSize * 1000000) / (mOutputSampleRate * 2 * 2);
157efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang        int64_t timeUs = mInitialTimeStampUs + totalOutDurationUs;
158efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang        to->setInt64(kKeyTime, timeUs);
159efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang
160efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang        // update the accumulate size
161efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang        mAccuOutBufferSize += outBufferSize;
162e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang        *buffer_out = outBuffer;
163efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang    } else {
164e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang        // Resampling not required. Read and pass-through.
165efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang        MediaBuffer *aBuffer;
166efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang        status_t err = mSource->read(&aBuffer, options);
167e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang        if (err != OK) {
168e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang            LOGV("read returns err = %d", err);
169e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang        }
170e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang
171e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang        if (err == INFO_FORMAT_CHANGED) {
172e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang            checkAndSetResampler();
173e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang            return read(buffer_out, NULL);
174e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang        }
175e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang
176e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang        // EOS or some other error
177efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang        if(err != OK) {
178e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang            stop();
179efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang            *buffer_out = NULL;
180efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang            return err;
181efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang        }
182efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang        *buffer_out = aBuffer;
183efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang    }
184efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang
185efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang    return OK;
186efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang}
187efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang
188efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Changstatus_t VideoEditorSRC::getNextBuffer(AudioBufferProvider::Buffer *pBuffer) {
189e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang    LOGV("Requesting %d, chan = %d", pBuffer->frameCount, mChannelCnt);
190e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang    uint32_t done = 0;
191e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang    uint32_t want = pBuffer->frameCount * mChannelCnt * 2;
192e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang    pBuffer->raw = malloc(want);
193e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang
194e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang    while (mStarted && want > 0) {
195e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang        // If we don't have any data left, read a new buffer.
196e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang        if (!mBuffer) {
197e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang            // if we seek, reset the initial time stamp and accumulated time
198e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang            ReadOptions options;
199e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang            if (mSeekTimeUs >= 0) {
200e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang                LOGV("%p cacheMore_l Seek requested = %lld", this, mSeekTimeUs);
201e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang                ReadOptions::SeekMode mode = mSeekMode;
202e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang                options.setSeekTo(mSeekTimeUs, mode);
203e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang                mSeekTimeUs = -1;
204e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang                mInitialTimeStampUs = -1;
205e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang                mAccuOutBufferSize = 0;
206e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang            }
207efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang
208e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang            status_t err = mSource->read(&mBuffer, &options);
209efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang
210e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang            if (err != OK) {
211e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang                free(pBuffer->raw);
212e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang                pBuffer->raw = NULL;
213e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang                pBuffer->frameCount = 0;
21484161acd0c02718b47f82ced3123e9d9eac7b9b9Rajneesh Chowdury            }
215e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang
216e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang            if (err == INFO_FORMAT_CHANGED) {
217e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang                LOGV("getNextBuffer: source read returned INFO_FORMAT_CHANGED");
218e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang                // At this point we cannot switch to a new AudioResampler because
219e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang                // we are in a callback called by the AudioResampler itself. So
220e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang                // just remember the fact that the format has changed, and let
221e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang                // read() handles this.
222e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang                mFormatChanged = true;
223e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang                return err;
224efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang            }
225efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang
226e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang            // EOS or some other error
227e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang            if (err != OK) {
228e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang                LOGV("EOS or some err: %d", err);
2290d2c710a293d68fb729eff148d40002f5deacf17Chih-Chung Chang                // We cannot call stop() here because stop() will release the
2300d2c710a293d68fb729eff148d40002f5deacf17Chih-Chung Chang                // AudioResampler, and we are in a callback of the AudioResampler.
2310d2c710a293d68fb729eff148d40002f5deacf17Chih-Chung Chang                // So just remember the fact and let read() call stop().
2320d2c710a293d68fb729eff148d40002f5deacf17Chih-Chung Chang                mStopPending = true;
233e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang                return err;
234e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang            }
235efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang
236e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang            CHECK(mBuffer);
237e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang            mLeftover = mBuffer->range_length();
238efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang            if (mInitialTimeStampUs == -1) {
239efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang                int64_t curTS;
240e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang                sp<MetaData> from = mBuffer->meta_data();
241efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang                from->findInt64(kKeyTime, &curTS);
242efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang                LOGV("setting mInitialTimeStampUs to %lld", mInitialTimeStampUs);
243efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang                mInitialTimeStampUs = curTS;
244efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang            }
245e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang        }
246efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang
247e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang        // Now copy data to the destination
248e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang        uint32_t todo = mLeftover;
249e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang        if (todo > want) {
250e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang            todo = want;
251efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang        }
252efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang
253e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang        uint8_t* end = (uint8_t*)mBuffer->data() + mBuffer->range_offset()
254e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang                + mBuffer->range_length();
255e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang        memcpy((uint8_t*)pBuffer->raw + done, end - mLeftover, todo);
256e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang        done += todo;
257e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang        want -= todo;
258e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang        mLeftover -= todo;
259e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang
260e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang        // Release MediaBuffer as soon as possible.
261e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang        if (mLeftover == 0) {
262e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang            mBuffer->release();
263e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang            mBuffer = NULL;
264e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang        }
265efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang    }
266efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang
267e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang    pBuffer->frameCount = done / (mChannelCnt * 2);
268e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang    LOGV("getNextBuffer done %d", pBuffer->frameCount);
269efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang    return OK;
270efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang}
271efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang
272efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang
273efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Changvoid VideoEditorSRC::releaseBuffer(AudioBufferProvider::Buffer *pBuffer) {
274e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang    free(pBuffer->raw);
275e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang    pBuffer->raw = NULL;
276efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang    pBuffer->frameCount = 0;
277efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang}
278efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang
279e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Changvoid VideoEditorSRC::checkAndSetResampler() {
28084161acd0c02718b47f82ced3123e9d9eac7b9b9Rajneesh Chowdury    LOGV("checkAndSetResampler");
28184161acd0c02718b47f82ced3123e9d9eac7b9b9Rajneesh Chowdury
28284161acd0c02718b47f82ced3123e9d9eac7b9b9Rajneesh Chowdury    sp<MetaData> format = mSource->getFormat();
28384161acd0c02718b47f82ced3123e9d9eac7b9b9Rajneesh Chowdury    const char *mime;
284e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang    CHECK(format->findCString(kKeyMIMEType, &mime));
28584161acd0c02718b47f82ced3123e9d9eac7b9b9Rajneesh Chowdury    CHECK(!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW));
28684161acd0c02718b47f82ced3123e9d9eac7b9b9Rajneesh Chowdury
287e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang    CHECK(format->findInt32(kKeySampleRate, &mSampleRate));
288e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang    CHECK(format->findInt32(kKeyChannelCount, &mChannelCnt));
28984161acd0c02718b47f82ced3123e9d9eac7b9b9Rajneesh Chowdury
290e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang    // If a resampler exists, delete it first
29184161acd0c02718b47f82ced3123e9d9eac7b9b9Rajneesh Chowdury    if (mResampler != NULL) {
29284161acd0c02718b47f82ced3123e9d9eac7b9b9Rajneesh Chowdury        delete mResampler;
29384161acd0c02718b47f82ced3123e9d9eac7b9b9Rajneesh Chowdury        mResampler = NULL;
29484161acd0c02718b47f82ced3123e9d9eac7b9b9Rajneesh Chowdury    }
29584161acd0c02718b47f82ced3123e9d9eac7b9b9Rajneesh Chowdury
296e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang    // Clear previous buffer
297e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang    if (mBuffer) {
298e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang        mBuffer->release();
299e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang        mBuffer = NULL;
300e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang    }
30184161acd0c02718b47f82ced3123e9d9eac7b9b9Rajneesh Chowdury
302e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang    if (mSampleRate != mOutputSampleRate || mChannelCnt != 2) {
303e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang        LOGV("Resampling required (in rate %d, out rate %d, in channel %d)",
304e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang            mSampleRate, mOutputSampleRate, mChannelCnt);
30584161acd0c02718b47f82ced3123e9d9eac7b9b9Rajneesh Chowdury
306e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang        mResampler = AudioResampler::create(
307e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang                        16 /* bit depth */,
308e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang                        mChannelCnt,
309e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang                        mOutputSampleRate,
310e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang                        AudioResampler::DEFAULT);
311e79d2faf19cf0eaedf895888e2934262c7ecace7Chih-Chung Chang        CHECK(mResampler);
31284161acd0c02718b47f82ced3123e9d9eac7b9b9Rajneesh Chowdury        mResampler->setSampleRate(mSampleRate);
31384161acd0c02718b47f82ced3123e9d9eac7b9b9Rajneesh Chowdury        mResampler->setVolume(UNITY_GAIN, UNITY_GAIN);
31484161acd0c02718b47f82ced3123e9d9eac7b9b9Rajneesh Chowdury    } else {
31584161acd0c02718b47f82ced3123e9d9eac7b9b9Rajneesh Chowdury        LOGV("Resampling not required (%d = %d)", mSampleRate, mOutputSampleRate);
31684161acd0c02718b47f82ced3123e9d9eac7b9b9Rajneesh Chowdury    }
31784161acd0c02718b47f82ced3123e9d9eac7b9b9Rajneesh Chowdury}
31884161acd0c02718b47f82ced3123e9d9eac7b9b9Rajneesh Chowdury
319efa27232d6812a6c71682cc3d0041a39c2bd52efChih-Chung Chang} //namespce android
320