blob: c304ca2bffe96b41e50a42bfda4761b753e1e9b7 [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>
James Donge6815bf2011-05-02 18:23:42 -070026#include <media/stagefright/MediaBuffer.h>
27#include <media/stagefright/MediaDefs.h>
Dharmaray Kundargi643290d2011-01-16 16:02:42 -080028#include "AudioMixer.h"
29
30
31namespace android {
32
33VideoEditorSRC::VideoEditorSRC(
34 const sp<MediaSource> &source) {
35
36 LOGV("VideoEditorSRC::Create");
37 mSource = source;
38 mResampler = NULL;
39 mBitDepth = 16;
40 mChannelCnt = 0;
41 mSampleRate = 0;
42 mOutputSampleRate = DEFAULT_SAMPLING_FREQ;
43 mStarted = false;
44 mIsResamplingRequired = false;
45 mIsChannelConvertionRequired = false;
46 mInitialTimeStampUs = -1;
47 mAccuOutBufferSize = 0;
48 mSeekTimeUs = -1;
49 mLeftover = 0;
50 mLastReadSize = 0;
Santosh Madhava9785cdf2011-02-08 23:26:18 -080051 mReSampledBuffer = NULL;
Dharmaray Kundargi643290d2011-01-16 16:02:42 -080052 mSeekMode = ReadOptions::SEEK_PREVIOUS_SYNC;
Dharmaray Kundargi643290d2011-01-16 16:02:42 -080053
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;
James Donge6815bf2011-05-02 18:23:42 -070076 mInterframeBuffer = new uint8_t[DEFAULT_SAMPLING_FREQ * 2 * 2]; //stereo=2 * bytespersample=2
Dharmaray Kundargi643290d2011-01-16 16:02:42 -080077
78
79}
80
81VideoEditorSRC::~VideoEditorSRC(){
82 if (mStarted == true)
83 stop();
84
85 if(mOutputFormat != NULL) {
86 mOutputFormat.clear();
87 mOutputFormat = NULL;
88 }
89
James Donge6815bf2011-05-02 18:23:42 -070090 if (mInterframeBuffer != NULL){
91 delete mInterframeBuffer;
92 mInterframeBuffer = NULL;
Dharmaray Kundargi643290d2011-01-16 16:02:42 -080093 }
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
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800126 if(mSampleRate != mOutputSampleRate) {
127 LOGV("Resampling required (%d != %d)", mSampleRate, mOutputSampleRate);
128 mIsResamplingRequired = true;
129 LOGV("Create resampler %d %d %d", mBitDepth, mChannelCnt, mOutputSampleRate);
130
131 mResampler = AudioResampler::create(
132 mBitDepth, mChannelCnt, mOutputSampleRate, AudioResampler::DEFAULT);
133
134 if(mResampler == NULL) {
135 return NO_MEMORY;
136 }
137 LOGV("Set input rate %d", mSampleRate);
138 mResampler->setSampleRate(mSampleRate);
139 mResampler->setVolume(UNITY_GAIN, UNITY_GAIN);
140
141 } else {
142 if(mChannelCnt != 2) { //we always make sure to provide stereo
143 LOGV("Only Channel convertion required");
144 mIsChannelConvertionRequired = true;
145 }
146 }
147 mSeekTimeUs = -1;
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800148 mSeekMode = ReadOptions::SEEK_PREVIOUS_SYNC;
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800149 mStarted = true;
150 mSource->start();
151
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800152 return OK;
153}
154
155status_t VideoEditorSRC::stop() {
156
157 Mutex::Autolock autoLock(mLock);
158 LOGV("VideoEditorSRC::stop()");
159 mSource->stop();
160 if(mResampler != NULL) {
161 delete mResampler;
162 mResampler = NULL;
163 }
164 mStarted = false;
165 mInitialTimeStampUs = -1;
166 mAccuOutBufferSize = 0;
167 mLeftover = 0;
168 mLastReadSize = 0;
Santosh Madhava9785cdf2011-02-08 23:26:18 -0800169 if (mReSampledBuffer != NULL) {
170 free(mReSampledBuffer);
171 mReSampledBuffer = NULL;
172 }
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800173
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800174 return OK;
175}
176
177sp<MetaData> VideoEditorSRC::getFormat() {
178 LOGV("AudioSRC getFormat");
179 //Mutex::Autolock autoLock(mLock);
180 return mOutputFormat;
181}
182
183status_t VideoEditorSRC::read (
184 MediaBuffer **buffer_out, const ReadOptions *options) {
185 Mutex::Autolock autoLock(mLock);
186 *buffer_out = NULL;
187 int32_t leftover = 0;
188
189 LOGV("VideoEditorSRC::read");
190
191 if (!mStarted) {
192 return ERROR_END_OF_STREAM;
193 }
194
195 if(mIsResamplingRequired == true) {
196
197 LOGV("mIsResamplingRequired = true");
198
199 // Store the seek parameters
200 int64_t seekTimeUs;
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800201 ReadOptions::SeekMode mode = ReadOptions::SEEK_PREVIOUS_SYNC;
202 if (options && options->getSeekTo(&seekTimeUs, &mode)) {
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800203 LOGV("read Seek %lld", seekTimeUs);
204 mInitialTimeStampUs = -1;
205 mSeekTimeUs = seekTimeUs;
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800206 mSeekMode = mode;
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800207 }
208
209 // We ask for 1024 frames in output
210 size_t outFrameCnt = 1024;
211 int32_t outBufferSize = (outFrameCnt) * 2 * sizeof(int16_t); //out is always 2 channels & 16 bits
212 int64_t outDurationUs = (outBufferSize * 1000000) /(mOutputSampleRate * 2 * sizeof(int16_t)); //2 channels out * 2 bytes per sample
213 LOGV("outBufferSize %d", outBufferSize);
214 LOGV("outFrameCnt %d", outFrameCnt);
215
James Donge6815bf2011-05-02 18:23:42 -0700216 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 -0800217 memset(pTmpBuffer, 0x00, outFrameCnt * 2 * sizeof(int32_t));
218 // Resample to target quality
219 mResampler->resample(pTmpBuffer, outFrameCnt, this);
Santosh Madhava9785cdf2011-02-08 23:26:18 -0800220
221 // Free previous allocation
222 if (mReSampledBuffer != NULL) {
223 free(mReSampledBuffer);
224 mReSampledBuffer = NULL;
225 }
226 mReSampledBuffer = (int16_t*)malloc(outBufferSize);
227 memset(mReSampledBuffer, 0x00, outBufferSize);
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800228
229 // Convert back to 16 bits
Santosh Madhava9785cdf2011-02-08 23:26:18 -0800230 AudioMixer::ditherAndClamp((int32_t*)mReSampledBuffer, pTmpBuffer, outFrameCnt);
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800231 LOGV("Resampled buffer size %d", outFrameCnt* 2 * sizeof(int16_t));
232
233 // Create new MediaBuffer
Santosh Madhava9785cdf2011-02-08 23:26:18 -0800234 mCopyBuffer = new MediaBuffer((void*)mReSampledBuffer, outBufferSize);
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800235
236 // Compute and set the new timestamp
237 sp<MetaData> to = mCopyBuffer->meta_data();
238 int64_t totalOutDurationUs = (mAccuOutBufferSize * 1000000) /(mOutputSampleRate * 2 * 2); //2 channels out * 2 bytes per sample
239 int64_t timeUs = mInitialTimeStampUs + totalOutDurationUs;
240 to->setInt64(kKeyTime, timeUs);
241 LOGV("buffer duration %lld timestamp %lld init %lld", outDurationUs, timeUs, mInitialTimeStampUs);
242
243 // update the accumulate size
244 mAccuOutBufferSize += outBufferSize;
245
246 mCopyBuffer->set_range(0, outBufferSize);
247 *buffer_out = mCopyBuffer;
248
249 free(pTmpBuffer);
250
251 } else if(mIsChannelConvertionRequired == true) {
252 //TODO convert to stereo here.
253 } else {
254 //LOGI("Resampling not required");
255 MediaBuffer *aBuffer;
256 status_t err = mSource->read(&aBuffer, options);
257 LOGV("mSource->read returned %d", err);
258 if(err != OK) {
259 *buffer_out = NULL;
260 mStarted = false;
261 return err;
262 }
263 *buffer_out = aBuffer;
264 }
265
266 return OK;
267}
268
269status_t VideoEditorSRC::getNextBuffer(AudioBufferProvider::Buffer *pBuffer) {
270 LOGV("Requesting %d", pBuffer->frameCount);
271 uint32_t availableFrames;
272 bool lastBuffer = false;
273 MediaBuffer *aBuffer;
274
275
276 //update the internal buffer
277 // Store the leftover at the beginning of the local buffer
278 if (mLeftover > 0) {
279 LOGV("Moving mLeftover =%d from %d", mLeftover, mLastReadSize);
280 if (mLastReadSize > 0) {
James Donge6815bf2011-05-02 18:23:42 -0700281 memcpy(mInterframeBuffer, (uint8_t*) (mInterframeBuffer + mLastReadSize), mLeftover);
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800282 }
283 mInterframeBufferPosition = mLeftover;
284 }
285 else {
286 mInterframeBufferPosition = 0;
287 }
288
289 availableFrames = mInterframeBufferPosition / (mChannelCnt*2);
290
291 while ((availableFrames < pBuffer->frameCount)&&(mStarted)) {
292 // if we seek, reset the initial time stamp and accumulated time
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800293 ReadOptions options;
294 if (mSeekTimeUs >= 0) {
295 LOGV("%p cacheMore_l Seek requested = %lld", this, mSeekTimeUs);
296 ReadOptions::SeekMode mode = mSeekMode;
297 options.setSeekTo(mSeekTimeUs, mode);
298 mSeekTimeUs = -1;
299 }
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800300 /* The first call to read() will require to buffer twice as much data */
301 /* This will be needed by the resampler */
302 status_t err = mSource->read(&aBuffer, &options);
303 LOGV("mSource->read returned %d", err);
304 if(err != OK) {
305 if (mInterframeBufferPosition == 0) {
306 mStarted = false;
307 }
308 //Empty the internal buffer if there is no more data left in the source
309 else {
310 lastBuffer = true;
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800311 //clear the end of the buffer, just in case
James Donge6815bf2011-05-02 18:23:42 -0700312 memset(mInterframeBuffer+mInterframeBufferPosition, 0x00, DEFAULT_SAMPLING_FREQ * 2 * 2 - mInterframeBufferPosition);
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800313 mStarted = false;
314 }
315 }
316 else {
317 //copy the buffer
James Donge6815bf2011-05-02 18:23:42 -0700318 memcpy(((uint8_t*) mInterframeBuffer) + mInterframeBufferPosition,
Kenny Rooteb5b2652011-02-08 11:13:19 -0800319 ((uint8_t*) aBuffer->data()) + aBuffer->range_offset(),
320 aBuffer->range_length());
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800321 LOGV("Read from buffer %d", aBuffer->range_length());
322
323 mInterframeBufferPosition += aBuffer->range_length();
324 LOGV("Stored %d", mInterframeBufferPosition);
325
326 // Get the time stamp of the first buffer
327 if (mInitialTimeStampUs == -1) {
328 int64_t curTS;
329 sp<MetaData> from = aBuffer->meta_data();
330 from->findInt64(kKeyTime, &curTS);
331 LOGV("setting mInitialTimeStampUs to %lld", mInitialTimeStampUs);
332 mInitialTimeStampUs = curTS;
333 }
334
335 // release the buffer
336 aBuffer->release();
337 }
338 availableFrames = mInterframeBufferPosition / (mChannelCnt*2);
339 LOGV("availableFrames %d", availableFrames);
340 }
341
342 if (lastBuffer) {
343 pBuffer->frameCount = availableFrames;
344 }
345
346 //update the input buffer
James Donge6815bf2011-05-02 18:23:42 -0700347 pBuffer->raw = (void*)(mInterframeBuffer);
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800348
349 // Update how many bytes are left
350 // (actualReadSize is updated in getNextBuffer() called from resample())
351 int32_t actualReadSize = pBuffer->frameCount * mChannelCnt * 2;
352 mLeftover = mInterframeBufferPosition - actualReadSize;
353 LOGV("mLeftover %d", mLeftover);
354
355 mLastReadSize = actualReadSize;
356
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800357 LOGV("inFrameCount %d", pBuffer->frameCount);
358
359 return OK;
360}
361
362
363void VideoEditorSRC::releaseBuffer(AudioBufferProvider::Buffer *pBuffer) {
364 if(pBuffer->raw != NULL) {
365 pBuffer->raw = NULL;
366 }
367 pBuffer->frameCount = 0;
368}
369
370} //namespce android