VideoEditorSRC.cpp revision 2db767137112a619751b70b9947aaa064030a210
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 0
18#define LOG_TAG "VideoEditorSRC"
19
20#include "VideoEditorSRC.h"
21#include <media/stagefright/MetaData.h>
22#include <media/stagefright/MediaDebug.h>
23#include <media/stagefright/MediaBuffer.h>
24#include <media/stagefright/MediaDefs.h>
25#include "AudioMixer.h"
26#include <utils/Log.h>
27
28namespace android {
29
30VideoEditorSRC::VideoEditorSRC(const sp<MediaSource> &source) {
31    LOGV("VideoEditorSRC::VideoEditorSRC %p(%p)", this, source.get());
32    mSource = source;
33    mResampler = NULL;
34    mChannelCnt = 0;
35    mSampleRate = 0;
36    mOutputSampleRate = DEFAULT_SAMPLING_FREQ;
37    mStarted = false;
38    mInitialTimeStampUs = -1;
39    mAccuOutBufferSize  = 0;
40    mSeekTimeUs = -1;
41    mBuffer = NULL;
42    mLeftover = 0;
43    mFormatChanged = false;
44    mStopPending = false;
45    mSeekMode = ReadOptions::SEEK_PREVIOUS_SYNC;
46
47    // Input Source validation
48    sp<MetaData> format = mSource->getFormat();
49    const char *mime;
50    CHECK(format->findCString(kKeyMIMEType, &mime));
51    CHECK(!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW));
52
53    // Set the metadata of the output after resampling.
54    mOutputFormat = new MetaData;
55    mOutputFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_RAW);
56    mOutputFormat->setInt32(kKeySampleRate, DEFAULT_SAMPLING_FREQ);
57    mOutputFormat->setInt32(kKeyChannelCount, 2);
58}
59
60VideoEditorSRC::~VideoEditorSRC() {
61    LOGV("VideoEditorSRC::~VideoEditorSRC %p(%p)", this, mSource.get());
62    stop();
63}
64
65status_t VideoEditorSRC::start(MetaData *params) {
66    CHECK(!mStarted);
67    LOGV("VideoEditorSRC:start %p(%p)", this, mSource.get());
68
69    // Set resampler if required
70    checkAndSetResampler();
71
72    mSeekTimeUs = -1;
73    mSeekMode = ReadOptions::SEEK_PREVIOUS_SYNC;
74    mStarted = true;
75    mSource->start();
76
77    return OK;
78}
79
80status_t VideoEditorSRC::stop() {
81    LOGV("VideoEditorSRC::stop %p(%p)", this, mSource.get());
82    if (!mStarted) return OK;
83    if (mBuffer) {
84        mBuffer->release();
85        mBuffer = NULL;
86    }
87    mSource->stop();
88    if(mResampler != NULL) {
89        delete mResampler;
90        mResampler = NULL;
91    }
92    mStarted = false;
93    mInitialTimeStampUs = -1;
94    mAccuOutBufferSize = 0;
95    mLeftover = 0;
96
97    return OK;
98}
99
100sp<MetaData> VideoEditorSRC::getFormat() {
101    LOGV("VideoEditorSRC::getFormat");
102    return mOutputFormat;
103}
104
105status_t VideoEditorSRC::read(
106        MediaBuffer **buffer_out, const ReadOptions *options) {
107    LOGV("VideoEditorSRC::read %p(%p)", this, mSource.get());
108    *buffer_out = NULL;
109
110    if (!mStarted) {
111        return ERROR_END_OF_STREAM;
112    }
113
114    if (mResampler) {
115        // Store the seek parameters
116        int64_t seekTimeUs;
117        ReadOptions::SeekMode mode = ReadOptions::SEEK_PREVIOUS_SYNC;
118        if (options && options->getSeekTo(&seekTimeUs, &mode)) {
119            LOGV("read Seek %lld", seekTimeUs);
120            mSeekTimeUs = seekTimeUs;
121            mSeekMode = mode;
122        }
123
124        // We ask for 1024 frames in output
125        const size_t outFrameCnt = 1024;
126        // resampler output is always 2 channels and 32 bits
127        int32_t *pTmpBuffer = (int32_t *)calloc(1, outFrameCnt * 2 * sizeof(int32_t));
128        // Resample to target quality
129        mResampler->resample(pTmpBuffer, outFrameCnt, this);
130
131        if (mStopPending) {
132            stop();
133            mStopPending = false;
134        }
135
136        // Change resampler and retry if format change happened
137        if (mFormatChanged) {
138            mFormatChanged = false;
139            checkAndSetResampler();
140            free(pTmpBuffer);
141            return read(buffer_out, NULL);
142        }
143
144        // Create a new MediaBuffer
145        int32_t outBufferSize = outFrameCnt * 2 * sizeof(int16_t);
146        MediaBuffer* outBuffer = new MediaBuffer(outBufferSize);
147
148        // Convert back to 2 channels and 16 bits
149        AudioMixer::ditherAndClamp(
150                (int32_t *)((uint8_t*)outBuffer->data() + outBuffer->range_offset()),
151                pTmpBuffer, outFrameCnt);
152        free(pTmpBuffer);
153
154        // Compute and set the new timestamp
155        sp<MetaData> to = outBuffer->meta_data();
156        int64_t totalOutDurationUs = (mAccuOutBufferSize * 1000000) / (mOutputSampleRate * 2 * 2);
157        int64_t timeUs = mInitialTimeStampUs + totalOutDurationUs;
158        to->setInt64(kKeyTime, timeUs);
159
160        // update the accumulate size
161        mAccuOutBufferSize += outBufferSize;
162        *buffer_out = outBuffer;
163    } else {
164        // Resampling not required. Read and pass-through.
165        MediaBuffer *aBuffer;
166        status_t err = mSource->read(&aBuffer, options);
167        if (err != OK) {
168            LOGV("read returns err = %d", err);
169        }
170
171        if (err == INFO_FORMAT_CHANGED) {
172            checkAndSetResampler();
173            return read(buffer_out, NULL);
174        }
175
176        // EOS or some other error
177        if(err != OK) {
178            stop();
179            *buffer_out = NULL;
180            return err;
181        }
182        *buffer_out = aBuffer;
183    }
184
185    return OK;
186}
187
188status_t VideoEditorSRC::getNextBuffer(AudioBufferProvider::Buffer *pBuffer) {
189    LOGV("Requesting %d, chan = %d", pBuffer->frameCount, mChannelCnt);
190    uint32_t done = 0;
191    uint32_t want = pBuffer->frameCount * mChannelCnt * 2;
192    pBuffer->raw = malloc(want);
193
194    while (mStarted && want > 0) {
195        // If we don't have any data left, read a new buffer.
196        if (!mBuffer) {
197            // if we seek, reset the initial time stamp and accumulated time
198            ReadOptions options;
199            if (mSeekTimeUs >= 0) {
200                LOGV("%p cacheMore_l Seek requested = %lld", this, mSeekTimeUs);
201                ReadOptions::SeekMode mode = mSeekMode;
202                options.setSeekTo(mSeekTimeUs, mode);
203                mSeekTimeUs = -1;
204                mInitialTimeStampUs = -1;
205                mAccuOutBufferSize = 0;
206            }
207
208            status_t err = mSource->read(&mBuffer, &options);
209
210            if (err != OK) {
211                free(pBuffer->raw);
212                pBuffer->raw = NULL;
213                pBuffer->frameCount = 0;
214            }
215
216            if (err == INFO_FORMAT_CHANGED) {
217                LOGV("getNextBuffer: source read returned INFO_FORMAT_CHANGED");
218                // At this point we cannot switch to a new AudioResampler because
219                // we are in a callback called by the AudioResampler itself. So
220                // just remember the fact that the format has changed, and let
221                // read() handles this.
222                mFormatChanged = true;
223                return err;
224            }
225
226            // EOS or some other error
227            if (err != OK) {
228                LOGV("EOS or some err: %d", err);
229                // We cannot call stop() here because stop() will release the
230                // AudioResampler, and we are in a callback of the AudioResampler.
231                // So just remember the fact and let read() call stop().
232                mStopPending = true;
233                return err;
234            }
235
236            CHECK(mBuffer);
237            mLeftover = mBuffer->range_length();
238            if (mInitialTimeStampUs == -1) {
239                int64_t curTS;
240                sp<MetaData> from = mBuffer->meta_data();
241                from->findInt64(kKeyTime, &curTS);
242                LOGV("setting mInitialTimeStampUs to %lld", mInitialTimeStampUs);
243                mInitialTimeStampUs = curTS;
244            }
245        }
246
247        // Now copy data to the destination
248        uint32_t todo = mLeftover;
249        if (todo > want) {
250            todo = want;
251        }
252
253        uint8_t* end = (uint8_t*)mBuffer->data() + mBuffer->range_offset()
254                + mBuffer->range_length();
255        memcpy((uint8_t*)pBuffer->raw + done, end - mLeftover, todo);
256        done += todo;
257        want -= todo;
258        mLeftover -= todo;
259
260        // Release MediaBuffer as soon as possible.
261        if (mLeftover == 0) {
262            mBuffer->release();
263            mBuffer = NULL;
264        }
265    }
266
267    pBuffer->frameCount = done / (mChannelCnt * 2);
268    LOGV("getNextBuffer done %d", pBuffer->frameCount);
269    return OK;
270}
271
272
273void VideoEditorSRC::releaseBuffer(AudioBufferProvider::Buffer *pBuffer) {
274    free(pBuffer->raw);
275    pBuffer->raw = NULL;
276    pBuffer->frameCount = 0;
277}
278
279void VideoEditorSRC::checkAndSetResampler() {
280    LOGV("checkAndSetResampler");
281
282    sp<MetaData> format = mSource->getFormat();
283    const char *mime;
284    CHECK(format->findCString(kKeyMIMEType, &mime));
285    CHECK(!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW));
286
287    CHECK(format->findInt32(kKeySampleRate, &mSampleRate));
288    CHECK(format->findInt32(kKeyChannelCount, &mChannelCnt));
289
290    // If a resampler exists, delete it first
291    if (mResampler != NULL) {
292        delete mResampler;
293        mResampler = NULL;
294    }
295
296    // Clear previous buffer
297    if (mBuffer) {
298        mBuffer->release();
299        mBuffer = NULL;
300    }
301
302    if (mSampleRate != mOutputSampleRate || mChannelCnt != 2) {
303        LOGV("Resampling required (in rate %d, out rate %d, in channel %d)",
304            mSampleRate, mOutputSampleRate, mChannelCnt);
305
306        mResampler = AudioResampler::create(
307                        16 /* bit depth */,
308                        mChannelCnt,
309                        mOutputSampleRate,
310                        AudioResampler::DEFAULT);
311        CHECK(mResampler);
312        mResampler->setSampleRate(mSampleRate);
313        mResampler->setVolume(UNITY_GAIN, UNITY_GAIN);
314    } else {
315        LOGV("Resampling not required (%d = %d)", mSampleRate, mOutputSampleRate);
316    }
317}
318
319} //namespce android
320