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