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