blob: 71411abc8fcd4728141969bff32fb0901519750f [file] [log] [blame]
Chih-Chung Chang99698662011-06-30 14:21:38 +08001/*
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 "VEAudioSource"
19#include <utils/Log.h>
20
21
22#include "VideoEditorSRC.h"
23#include <media/stagefright/MetaData.h>
24#include <media/stagefright/MediaDebug.h>
25#include <media/stagefright/MediaBuffer.h>
26#include <media/stagefright/MediaDefs.h>
27#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;
50 mReSampledBuffer = NULL;
51 mSeekMode = ReadOptions::SEEK_PREVIOUS_SYNC;
52
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;
75 mInterframeBuffer = new uint8_t[DEFAULT_SAMPLING_FREQ * 2 * 2]; //stereo=2 * bytespersample=2
76
77
78}
79
80VideoEditorSRC::~VideoEditorSRC(){
81 if (mStarted == true)
82 stop();
83
84 if(mOutputFormat != NULL) {
85 mOutputFormat.clear();
86 mOutputFormat = NULL;
87 }
88
89 if (mInterframeBuffer != NULL){
90 delete mInterframeBuffer;
91 mInterframeBuffer = NULL;
92 }
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
106status_t VideoEditorSRC::start (MetaData *params) {
107 Mutex::Autolock autoLock(mLock);
108
109 CHECK(!mStarted);
110 LOGV(" VideoEditorSRC:start() called");
111
Rajneesh Chowdury1c3c5432011-07-20 13:47:34 -0700112 // Set resampler if required
113 status_t err = checkAndSetResampler();
114 if (err != OK) {
115 LOGE("checkAndSetResampler() returned error %d", err);
116 return err;
Chih-Chung Chang99698662011-06-30 14:21:38 +0800117 }
Rajneesh Chowdury1c3c5432011-07-20 13:47:34 -0700118
Chih-Chung Chang99698662011-06-30 14:21:38 +0800119 mSeekTimeUs = -1;
120 mSeekMode = ReadOptions::SEEK_PREVIOUS_SYNC;
121 mStarted = true;
122 mSource->start();
123
124 return OK;
125}
126
127status_t VideoEditorSRC::stop() {
128
129 Mutex::Autolock autoLock(mLock);
130 LOGV("VideoEditorSRC::stop()");
131 mSource->stop();
132 if(mResampler != NULL) {
133 delete mResampler;
134 mResampler = NULL;
135 }
136 mStarted = false;
137 mInitialTimeStampUs = -1;
138 mAccuOutBufferSize = 0;
139 mLeftover = 0;
140 mLastReadSize = 0;
141 if (mReSampledBuffer != NULL) {
142 free(mReSampledBuffer);
143 mReSampledBuffer = NULL;
144 }
145
146 return OK;
147}
148
149sp<MetaData> VideoEditorSRC::getFormat() {
150 LOGV("AudioSRC getFormat");
151 //Mutex::Autolock autoLock(mLock);
152 return mOutputFormat;
153}
154
155status_t VideoEditorSRC::read (
156 MediaBuffer **buffer_out, const ReadOptions *options) {
157 Mutex::Autolock autoLock(mLock);
158 *buffer_out = NULL;
159 int32_t leftover = 0;
160
161 LOGV("VideoEditorSRC::read");
162
163 if (!mStarted) {
164 return ERROR_END_OF_STREAM;
165 }
166
167 if(mIsResamplingRequired == true) {
168
169 LOGV("mIsResamplingRequired = true");
170
171 // Store the seek parameters
172 int64_t seekTimeUs;
173 ReadOptions::SeekMode mode = ReadOptions::SEEK_PREVIOUS_SYNC;
174 if (options && options->getSeekTo(&seekTimeUs, &mode)) {
175 LOGV("read Seek %lld", seekTimeUs);
176 mInitialTimeStampUs = -1;
177 mSeekTimeUs = seekTimeUs;
178 mSeekMode = mode;
179 }
180
181 // We ask for 1024 frames in output
182 size_t outFrameCnt = 1024;
183 int32_t outBufferSize = (outFrameCnt) * 2 * sizeof(int16_t); //out is always 2 channels & 16 bits
184 int64_t outDurationUs = (outBufferSize * 1000000) /(mOutputSampleRate * 2 * sizeof(int16_t)); //2 channels out * 2 bytes per sample
185 LOGV("outBufferSize %d", outBufferSize);
186 LOGV("outFrameCnt %d", outFrameCnt);
187
188 int32_t *pTmpBuffer = (int32_t*)malloc(outFrameCnt * 2 * sizeof(int32_t)); //out is always 2 channels and resampler out is 32 bits
189 memset(pTmpBuffer, 0x00, outFrameCnt * 2 * sizeof(int32_t));
190 // Resample to target quality
191 mResampler->resample(pTmpBuffer, outFrameCnt, this);
192
193 // Free previous allocation
194 if (mReSampledBuffer != NULL) {
195 free(mReSampledBuffer);
196 mReSampledBuffer = NULL;
197 }
198 mReSampledBuffer = (int16_t*)malloc(outBufferSize);
199 memset(mReSampledBuffer, 0x00, outBufferSize);
200
201 // Convert back to 16 bits
202 AudioMixer::ditherAndClamp((int32_t*)mReSampledBuffer, pTmpBuffer, outFrameCnt);
203 LOGV("Resampled buffer size %d", outFrameCnt* 2 * sizeof(int16_t));
204
205 // Create new MediaBuffer
206 mCopyBuffer = new MediaBuffer((void*)mReSampledBuffer, outBufferSize);
207
208 // Compute and set the new timestamp
209 sp<MetaData> to = mCopyBuffer->meta_data();
210 int64_t totalOutDurationUs = (mAccuOutBufferSize * 1000000) /(mOutputSampleRate * 2 * 2); //2 channels out * 2 bytes per sample
211 int64_t timeUs = mInitialTimeStampUs + totalOutDurationUs;
212 to->setInt64(kKeyTime, timeUs);
213 LOGV("buffer duration %lld timestamp %lld init %lld", outDurationUs, timeUs, mInitialTimeStampUs);
214
215 // update the accumulate size
216 mAccuOutBufferSize += outBufferSize;
217
218 mCopyBuffer->set_range(0, outBufferSize);
219 *buffer_out = mCopyBuffer;
220
221 free(pTmpBuffer);
222
223 } else if(mIsChannelConvertionRequired == true) {
224 //TODO convert to stereo here.
225 } else {
226 //LOGI("Resampling not required");
227 MediaBuffer *aBuffer;
228 status_t err = mSource->read(&aBuffer, options);
229 LOGV("mSource->read returned %d", err);
230 if(err != OK) {
231 *buffer_out = NULL;
232 mStarted = false;
233 return err;
234 }
235 *buffer_out = aBuffer;
236 }
237
238 return OK;
239}
240
241status_t VideoEditorSRC::getNextBuffer(AudioBufferProvider::Buffer *pBuffer) {
242 LOGV("Requesting %d", pBuffer->frameCount);
243 uint32_t availableFrames;
244 bool lastBuffer = false;
245 MediaBuffer *aBuffer;
246
Chih-Chung Chang99698662011-06-30 14:21:38 +0800247 //update the internal buffer
248 // Store the leftover at the beginning of the local buffer
249 if (mLeftover > 0) {
250 LOGV("Moving mLeftover =%d from %d", mLeftover, mLastReadSize);
251 if (mLastReadSize > 0) {
252 memcpy(mInterframeBuffer, (uint8_t*) (mInterframeBuffer + mLastReadSize), mLeftover);
253 }
254 mInterframeBufferPosition = mLeftover;
255 }
256 else {
257 mInterframeBufferPosition = 0;
258 }
259
260 availableFrames = mInterframeBufferPosition / (mChannelCnt*2);
261
262 while ((availableFrames < pBuffer->frameCount)&&(mStarted)) {
263 // if we seek, reset the initial time stamp and accumulated time
264 ReadOptions options;
265 if (mSeekTimeUs >= 0) {
266 LOGV("%p cacheMore_l Seek requested = %lld", this, mSeekTimeUs);
267 ReadOptions::SeekMode mode = mSeekMode;
268 options.setSeekTo(mSeekTimeUs, mode);
269 mSeekTimeUs = -1;
270 }
271 /* The first call to read() will require to buffer twice as much data */
272 /* This will be needed by the resampler */
273 status_t err = mSource->read(&aBuffer, &options);
274 LOGV("mSource->read returned %d", err);
Rajneesh Chowdury1c3c5432011-07-20 13:47:34 -0700275 if (err == INFO_FORMAT_CHANGED) {
276 LOGV("getNextBuffer: source read returned INFO_FORMAT_CHANGED");
277 // Change resampler if required
278 status_t err1 = checkAndSetResampler();
279 if (err1 != OK) {
280 LOGE("checkAndSetResampler() returned error %d", err1);
281 return err1;
282 }
283 // Update availableFrames with new channel count
284 availableFrames = mInterframeBufferPosition / (mChannelCnt*2);
285 continue;
286 } else if (err != OK) {
Chih-Chung Chang99698662011-06-30 14:21:38 +0800287 if (mInterframeBufferPosition == 0) {
288 mStarted = false;
289 }
290 //Empty the internal buffer if there is no more data left in the source
291 else {
292 lastBuffer = true;
293 //clear the end of the buffer, just in case
294 memset(mInterframeBuffer+mInterframeBufferPosition, 0x00, DEFAULT_SAMPLING_FREQ * 2 * 2 - mInterframeBufferPosition);
295 mStarted = false;
296 }
297 }
298 else {
299 //copy the buffer
300 memcpy(((uint8_t*) mInterframeBuffer) + mInterframeBufferPosition,
301 ((uint8_t*) aBuffer->data()) + aBuffer->range_offset(),
302 aBuffer->range_length());
303 LOGV("Read from buffer %d", aBuffer->range_length());
304
305 mInterframeBufferPosition += aBuffer->range_length();
306 LOGV("Stored %d", mInterframeBufferPosition);
307
308 // Get the time stamp of the first buffer
309 if (mInitialTimeStampUs == -1) {
310 int64_t curTS;
311 sp<MetaData> from = aBuffer->meta_data();
312 from->findInt64(kKeyTime, &curTS);
313 LOGV("setting mInitialTimeStampUs to %lld", mInitialTimeStampUs);
314 mInitialTimeStampUs = curTS;
315 }
316
317 // release the buffer
318 aBuffer->release();
319 }
320 availableFrames = mInterframeBufferPosition / (mChannelCnt*2);
321 LOGV("availableFrames %d", availableFrames);
322 }
323
324 if (lastBuffer) {
325 pBuffer->frameCount = availableFrames;
326 }
327
328 //update the input buffer
329 pBuffer->raw = (void*)(mInterframeBuffer);
330
331 // Update how many bytes are left
332 // (actualReadSize is updated in getNextBuffer() called from resample())
333 int32_t actualReadSize = pBuffer->frameCount * mChannelCnt * 2;
334 mLeftover = mInterframeBufferPosition - actualReadSize;
335 LOGV("mLeftover %d", mLeftover);
336
337 mLastReadSize = actualReadSize;
338
339 LOGV("inFrameCount %d", pBuffer->frameCount);
340
341 return OK;
342}
343
344
345void VideoEditorSRC::releaseBuffer(AudioBufferProvider::Buffer *pBuffer) {
346 if(pBuffer->raw != NULL) {
347 pBuffer->raw = NULL;
348 }
349 pBuffer->frameCount = 0;
350}
351
Rajneesh Chowdury1c3c5432011-07-20 13:47:34 -0700352status_t VideoEditorSRC::checkAndSetResampler() {
353
354 LOGV("checkAndSetResampler");
355
356 sp<MetaData> format = mSource->getFormat();
357 const char *mime;
358 bool success = format->findCString(kKeyMIMEType, &mime);
359 CHECK(success);
360 CHECK(!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW));
361
362 success = format->findInt32(kKeySampleRate, &mSampleRate);
363 CHECK(success);
364
365 int32_t numChannels;
366 success = format->findInt32(kKeyChannelCount, &mChannelCnt);
367 CHECK(success);
368
369 // If Resampler exists, delete it first
370 if (mResampler != NULL) {
371 delete mResampler;
372 mResampler = NULL;
373 }
374
375 if (mSampleRate != mOutputSampleRate) {
376 LOGV("Resampling required (%d != %d)", mSampleRate, mOutputSampleRate);
377 mIsResamplingRequired = true;
378 LOGV("Create resampler %d %d %d", mBitDepth, mChannelCnt, mOutputSampleRate);
379
380 mResampler = AudioResampler::create(
381 mBitDepth, mChannelCnt, mOutputSampleRate, AudioResampler::DEFAULT);
382
383 if (mResampler == NULL) {
384 return NO_MEMORY;
385 }
386 LOGV("Set input rate %d", mSampleRate);
387 mResampler->setSampleRate(mSampleRate);
388 mResampler->setVolume(UNITY_GAIN, UNITY_GAIN);
389
390 } else {
391 LOGV("Resampling not required (%d = %d)", mSampleRate, mOutputSampleRate);
392 mIsResamplingRequired = false;
393 if (mChannelCnt != 2) {
394 // we always make sure to provide stereo
395 LOGV("Only Channel convertion required");
396 mIsChannelConvertionRequired = true;
397 }
398 }
399
400 return OK;
401
402}
403
Chih-Chung Chang99698662011-06-30 14:21:38 +0800404} //namespce android