blob: 0990ad58065bbc48dbf0c11b8a6158d6a5d2d52e [file] [log] [blame]
Dharmaray Kundargi643290d2011-01-16 16:02:42 -08001/*
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 "VEAudioSource"
20#include <utils/Log.h>
21
22
23#include "VideoEditorSRC.h"
24#include <media/stagefright/MetaData.h>
25#include <media/stagefright/MediaDebug.h>
26#include "AudioMixer.h"
27
28
29namespace android {
30
31VideoEditorSRC::VideoEditorSRC(
32 const sp<MediaSource> &source) {
33
34 LOGV("VideoEditorSRC::Create");
35 mSource = source;
36 mResampler = NULL;
37 mBitDepth = 16;
38 mChannelCnt = 0;
39 mSampleRate = 0;
40 mOutputSampleRate = DEFAULT_SAMPLING_FREQ;
41 mStarted = false;
42 mIsResamplingRequired = false;
43 mIsChannelConvertionRequired = false;
44 mInitialTimeStampUs = -1;
45 mAccuOutBufferSize = 0;
46 mSeekTimeUs = -1;
47 mLeftover = 0;
48 mLastReadSize = 0;
Santosh Madhava9785cdf2011-02-08 23:26:18 -080049 mReSampledBuffer = NULL;
Dharmaray Kundargi643290d2011-01-16 16:02:42 -080050#ifndef FROYO
51 mSeekMode = ReadOptions::SEEK_PREVIOUS_SYNC;
52#endif
53
54 mOutputFormat = new MetaData;
55
56 // Input Source validation
57 sp<MetaData> format = mSource->getFormat();
58 const char *mime;
59 bool success = format->findCString(kKeyMIMEType, &mime);
60 CHECK(success);
61 CHECK(!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW));
62
63 //set the meta data of the output after convertion.
64 if(mOutputFormat != NULL) {
65 mOutputFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_RAW);
66 mOutputFormat->setInt32(kKeySampleRate, DEFAULT_SAMPLING_FREQ);
67
68 //by default we convert all data to stereo
69 mOutputFormat->setInt32(kKeyChannelCount, 2);
70 } else {
71 LOGE("Meta data was not allocated.");
72 }
73
74 // Allocate a 1 sec buffer (test only, to be refined)
75 mInterframeBufferPosition = 0;
76 pInterframeBuffer = new uint8_t[DEFAULT_SAMPLING_FREQ * 2 * 2]; //stereo=2 * bytespersample=2
77
78
79}
80
81VideoEditorSRC::~VideoEditorSRC(){
82 if (mStarted == true)
83 stop();
84
85 if(mOutputFormat != NULL) {
86 mOutputFormat.clear();
87 mOutputFormat = NULL;
88 }
89
90 if (pInterframeBuffer != NULL){
91 delete pInterframeBuffer;
92 pInterframeBuffer = NULL;
93 }
94}
95
96void VideoEditorSRC::setResampling(int32_t sampleRate) {
97 Mutex::Autolock autoLock(mLock);
98 LOGV("VideoEditorSRC::setResampling called with samplreRate = %d", sampleRate);
99 if(sampleRate != DEFAULT_SAMPLING_FREQ) { //default case
100 LOGV("VideoEditor Audio resampler, freq set is other than default");
101 CHECK(mOutputFormat->setInt32(kKeySampleRate, DEFAULT_SAMPLING_FREQ));
102 }
103 mOutputSampleRate = sampleRate;
104 return;
105}
106
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800107status_t VideoEditorSRC::start (MetaData *params) {
108 Mutex::Autolock autoLock(mLock);
109
110 CHECK(!mStarted);
111 LOGV(" VideoEditorSRC:start() called");
112
113 sp<MetaData> format = mSource->getFormat();
114 const char *mime;
115 bool success = format->findCString(kKeyMIMEType, &mime);
116 CHECK(success);
117 CHECK(!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW));
118
119 success = format->findInt32(kKeySampleRate, &mSampleRate);
120 CHECK(success);
121
122 int32_t numChannels;
123 success = format->findInt32(kKeyChannelCount, &mChannelCnt);
124 CHECK(success);
125
126 mInputFrameSize = mChannelCnt * 2; //2 is the byte depth
127 if(mSampleRate != mOutputSampleRate) {
128 LOGV("Resampling required (%d != %d)", mSampleRate, mOutputSampleRate);
129 mIsResamplingRequired = true;
130 LOGV("Create resampler %d %d %d", mBitDepth, mChannelCnt, mOutputSampleRate);
131
132 mResampler = AudioResampler::create(
133 mBitDepth, mChannelCnt, mOutputSampleRate, AudioResampler::DEFAULT);
134
135 if(mResampler == NULL) {
136 return NO_MEMORY;
137 }
138 LOGV("Set input rate %d", mSampleRate);
139 mResampler->setSampleRate(mSampleRate);
140 mResampler->setVolume(UNITY_GAIN, UNITY_GAIN);
141
142 } else {
143 if(mChannelCnt != 2) { //we always make sure to provide stereo
144 LOGV("Only Channel convertion required");
145 mIsChannelConvertionRequired = true;
146 }
147 }
148 mSeekTimeUs = -1;
149#ifndef FROYO
150 mSeekMode = ReadOptions::SEEK_PREVIOUS_SYNC;
151#endif
152 mStarted = true;
153 mSource->start();
154
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800155 return OK;
156}
157
158status_t VideoEditorSRC::stop() {
159
160 Mutex::Autolock autoLock(mLock);
161 LOGV("VideoEditorSRC::stop()");
162 mSource->stop();
163 if(mResampler != NULL) {
164 delete mResampler;
165 mResampler = NULL;
166 }
167 mStarted = false;
168 mInitialTimeStampUs = -1;
169 mAccuOutBufferSize = 0;
170 mLeftover = 0;
171 mLastReadSize = 0;
Santosh Madhava9785cdf2011-02-08 23:26:18 -0800172 if (mReSampledBuffer != NULL) {
173 free(mReSampledBuffer);
174 mReSampledBuffer = NULL;
175 }
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800176
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800177 return OK;
178}
179
180sp<MetaData> VideoEditorSRC::getFormat() {
181 LOGV("AudioSRC getFormat");
182 //Mutex::Autolock autoLock(mLock);
183 return mOutputFormat;
184}
185
186status_t VideoEditorSRC::read (
187 MediaBuffer **buffer_out, const ReadOptions *options) {
188 Mutex::Autolock autoLock(mLock);
189 *buffer_out = NULL;
190 int32_t leftover = 0;
191
192 LOGV("VideoEditorSRC::read");
193
194 if (!mStarted) {
195 return ERROR_END_OF_STREAM;
196 }
197
198 if(mIsResamplingRequired == true) {
199
200 LOGV("mIsResamplingRequired = true");
201
202 // Store the seek parameters
203 int64_t seekTimeUs;
204#ifndef FROYO
205 ReadOptions::SeekMode mode = ReadOptions::SEEK_PREVIOUS_SYNC;
206 if (options && options->getSeekTo(&seekTimeUs, &mode)) {
207#else
208 if (options && options->getSeekTo(&seekTimeUs)) {
209#endif
210 LOGV("read Seek %lld", seekTimeUs);
211 mInitialTimeStampUs = -1;
212 mSeekTimeUs = seekTimeUs;
213#ifndef FROYO
214 mSeekMode = mode;
215#else
216 mReadOptions = *options;
217#endif
218 }
219
220 // We ask for 1024 frames in output
221 size_t outFrameCnt = 1024;
222 int32_t outBufferSize = (outFrameCnt) * 2 * sizeof(int16_t); //out is always 2 channels & 16 bits
223 int64_t outDurationUs = (outBufferSize * 1000000) /(mOutputSampleRate * 2 * sizeof(int16_t)); //2 channels out * 2 bytes per sample
224 LOGV("outBufferSize %d", outBufferSize);
225 LOGV("outFrameCnt %d", outFrameCnt);
226
227 pTmpBuffer = (int32_t*)malloc(outFrameCnt * 2 * sizeof(int32_t)); //out is always 2 channels and resampler out is 32 bits
228 memset(pTmpBuffer, 0x00, outFrameCnt * 2 * sizeof(int32_t));
229 // Resample to target quality
230 mResampler->resample(pTmpBuffer, outFrameCnt, this);
Santosh Madhava9785cdf2011-02-08 23:26:18 -0800231
232 // Free previous allocation
233 if (mReSampledBuffer != NULL) {
234 free(mReSampledBuffer);
235 mReSampledBuffer = NULL;
236 }
237 mReSampledBuffer = (int16_t*)malloc(outBufferSize);
238 memset(mReSampledBuffer, 0x00, outBufferSize);
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800239
240 // Convert back to 16 bits
Santosh Madhava9785cdf2011-02-08 23:26:18 -0800241 AudioMixer::ditherAndClamp((int32_t*)mReSampledBuffer, pTmpBuffer, outFrameCnt);
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800242 LOGV("Resampled buffer size %d", outFrameCnt* 2 * sizeof(int16_t));
243
244 // Create new MediaBuffer
Santosh Madhava9785cdf2011-02-08 23:26:18 -0800245 mCopyBuffer = new MediaBuffer((void*)mReSampledBuffer, outBufferSize);
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800246
247 // Compute and set the new timestamp
248 sp<MetaData> to = mCopyBuffer->meta_data();
249 int64_t totalOutDurationUs = (mAccuOutBufferSize * 1000000) /(mOutputSampleRate * 2 * 2); //2 channels out * 2 bytes per sample
250 int64_t timeUs = mInitialTimeStampUs + totalOutDurationUs;
251 to->setInt64(kKeyTime, timeUs);
252 LOGV("buffer duration %lld timestamp %lld init %lld", outDurationUs, timeUs, mInitialTimeStampUs);
253
254 // update the accumulate size
255 mAccuOutBufferSize += outBufferSize;
256
257 mCopyBuffer->set_range(0, outBufferSize);
258 *buffer_out = mCopyBuffer;
259
260 free(pTmpBuffer);
261
262 } else if(mIsChannelConvertionRequired == true) {
263 //TODO convert to stereo here.
264 } else {
265 //LOGI("Resampling not required");
266 MediaBuffer *aBuffer;
267 status_t err = mSource->read(&aBuffer, options);
268 LOGV("mSource->read returned %d", err);
269 if(err != OK) {
270 *buffer_out = NULL;
271 mStarted = false;
272 return err;
273 }
274 *buffer_out = aBuffer;
275 }
276
277 return OK;
278}
279
280status_t VideoEditorSRC::getNextBuffer(AudioBufferProvider::Buffer *pBuffer) {
281 LOGV("Requesting %d", pBuffer->frameCount);
282 uint32_t availableFrames;
283 bool lastBuffer = false;
284 MediaBuffer *aBuffer;
285
286
287 //update the internal buffer
288 // Store the leftover at the beginning of the local buffer
289 if (mLeftover > 0) {
290 LOGV("Moving mLeftover =%d from %d", mLeftover, mLastReadSize);
291 if (mLastReadSize > 0) {
292 memcpy(pInterframeBuffer, (uint8_t*) (pInterframeBuffer + mLastReadSize), mLeftover);
293 }
294 mInterframeBufferPosition = mLeftover;
295 }
296 else {
297 mInterframeBufferPosition = 0;
298 }
299
300 availableFrames = mInterframeBufferPosition / (mChannelCnt*2);
301
302 while ((availableFrames < pBuffer->frameCount)&&(mStarted)) {
303 // if we seek, reset the initial time stamp and accumulated time
304#ifndef FROYO
305 ReadOptions options;
306 if (mSeekTimeUs >= 0) {
307 LOGV("%p cacheMore_l Seek requested = %lld", this, mSeekTimeUs);
308 ReadOptions::SeekMode mode = mSeekMode;
309 options.setSeekTo(mSeekTimeUs, mode);
310 mSeekTimeUs = -1;
311 }
312#else
313 ReadOptions options;
314 if (mSeekTimeUs >= 0) {
315 LOGV("%p cacheMore_l Seek requested = %lld", this, mSeekTimeUs);
316 options = mReadOptions;
317 mSeekTimeUs = -1;
318 }
319#endif
320 /* The first call to read() will require to buffer twice as much data */
321 /* This will be needed by the resampler */
322 status_t err = mSource->read(&aBuffer, &options);
323 LOGV("mSource->read returned %d", err);
324 if(err != OK) {
325 if (mInterframeBufferPosition == 0) {
326 mStarted = false;
327 }
328 //Empty the internal buffer if there is no more data left in the source
329 else {
330 lastBuffer = true;
331 mInputByteBuffer = pInterframeBuffer;
332 //clear the end of the buffer, just in case
333 memset(pInterframeBuffer+mInterframeBufferPosition, 0x00, DEFAULT_SAMPLING_FREQ * 2 * 2 - mInterframeBufferPosition);
334 mStarted = false;
335 }
336 }
337 else {
338 //copy the buffer
Kenny Rooteb5b2652011-02-08 11:13:19 -0800339 memcpy(((uint8_t*) pInterframeBuffer) + mInterframeBufferPosition,
340 ((uint8_t*) aBuffer->data()) + aBuffer->range_offset(),
341 aBuffer->range_length());
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800342 LOGV("Read from buffer %d", aBuffer->range_length());
343
344 mInterframeBufferPosition += aBuffer->range_length();
345 LOGV("Stored %d", mInterframeBufferPosition);
346
347 // Get the time stamp of the first buffer
348 if (mInitialTimeStampUs == -1) {
349 int64_t curTS;
350 sp<MetaData> from = aBuffer->meta_data();
351 from->findInt64(kKeyTime, &curTS);
352 LOGV("setting mInitialTimeStampUs to %lld", mInitialTimeStampUs);
353 mInitialTimeStampUs = curTS;
354 }
355
356 // release the buffer
357 aBuffer->release();
358 }
359 availableFrames = mInterframeBufferPosition / (mChannelCnt*2);
360 LOGV("availableFrames %d", availableFrames);
361 }
362
363 if (lastBuffer) {
364 pBuffer->frameCount = availableFrames;
365 }
366
367 //update the input buffer
368 pBuffer->raw = (void*)(pInterframeBuffer);
369
370 // Update how many bytes are left
371 // (actualReadSize is updated in getNextBuffer() called from resample())
372 int32_t actualReadSize = pBuffer->frameCount * mChannelCnt * 2;
373 mLeftover = mInterframeBufferPosition - actualReadSize;
374 LOGV("mLeftover %d", mLeftover);
375
376 mLastReadSize = actualReadSize;
377
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800378 LOGV("inFrameCount %d", pBuffer->frameCount);
379
380 return OK;
381}
382
383
384void VideoEditorSRC::releaseBuffer(AudioBufferProvider::Buffer *pBuffer) {
385 if(pBuffer->raw != NULL) {
386 pBuffer->raw = NULL;
387 }
388 pBuffer->frameCount = 0;
389}
390
391} //namespce android