summaryrefslogtreecommitdiffstats
path: root/services/audioflinger/test-resample.cpp
diff options
context:
space:
mode:
authorGlenn Kasten <gkasten@google.com>2013-12-17 13:54:29 -0800
committerGlenn Kasten <gkasten@google.com>2013-12-17 14:13:54 -0800
commite00eefe64e3bad166c672db96c9c35992766e819 (patch)
treee2645cbcb92fc6b4ccdb2075323309f6f22196fc /services/audioflinger/test-resample.cpp
parente175e5ec1636fc638465187f3d5c6166d92388ed (diff)
downloadframeworks_av-e00eefe64e3bad166c672db96c9c35992766e819.zip
frameworks_av-e00eefe64e3bad166c672db96c9c35992766e819.tar.gz
frameworks_av-e00eefe64e3bad166c672db96c9c35992766e819.tar.bz2
Fix several test-resample BufferProvider bugs
Previously getNextBuffer always returned the same data address over and over. Now it correctly returns the right portion of the input buffer. Previously getNextBuffer always returned the total number of frames in the input, which might be larger than the size requested by the caller, and/or larger than the number of remaining input frames. It also always returned successfully, even when there should be no frames available. This violates the contract for getNextBuffer. Now getNextBuffer will return the maximum of the number of frames requested, and the number of remaining frames available. If that maximum is zero, getNextBuffer will return an error instead. Previously releaseBuffer would silently allow releasing more frames than were actually gotten, which violates the contract for releaseBuffer. Now releaseBuffer checks for this and logs a message if it happens. Add 'v' (verbose) option to log buffer provider calls. Bug: 12194314 Change-Id: I9b915e954b3612a07ef271da8652486b8875e0fd
Diffstat (limited to 'services/audioflinger/test-resample.cpp')
-rw-r--r--services/audioflinger/test-resample.cpp71
1 files changed, 61 insertions, 10 deletions
diff --git a/services/audioflinger/test-resample.cpp b/services/audioflinger/test-resample.cpp
index 7a314cf..39018b2 100644
--- a/services/audioflinger/test-resample.cpp
+++ b/services/audioflinger/test-resample.cpp
@@ -29,6 +29,8 @@
using namespace android;
+bool gVerbose = false;
+
struct HeaderWav {
HeaderWav(size_t size, int nc, int sr, int bits) {
strncpy(RIFF, "RIFF", 4);
@@ -62,10 +64,11 @@ struct HeaderWav {
};
static int usage(const char* name) {
- fprintf(stderr,"Usage: %s [-p] [-h] [-s] [-q {dq|lq|mq|hq|vhq}] [-i input-sample-rate] "
+ fprintf(stderr,"Usage: %s [-p] [-h] [-v] [-s] [-q {dq|lq|mq|hq|vhq}] [-i input-sample-rate] "
"[-o output-sample-rate] [<input-file>] <output-file>\n", name);
fprintf(stderr," -p enable profiling\n");
fprintf(stderr," -h create wav file\n");
+ fprintf(stderr," -v verbose : log buffer provider calls\n");
fprintf(stderr," -s stereo\n");
fprintf(stderr," -q resampler quality\n");
fprintf(stderr," dq : default quality\n");
@@ -89,7 +92,7 @@ int main(int argc, char* argv[]) {
AudioResampler::src_quality quality = AudioResampler::DEFAULT_QUALITY;
int ch;
- while ((ch = getopt(argc, argv, "phsq:i:o:")) != -1) {
+ while ((ch = getopt(argc, argv, "phvsq:i:o:")) != -1) {
switch (ch) {
case 'p':
profiling = true;
@@ -97,6 +100,9 @@ int main(int argc, char* argv[]) {
case 'h':
writeHeader = true;
break;
+ case 'v':
+ gVerbose = true;
+ break;
case 's':
channels = 2;
break;
@@ -186,24 +192,59 @@ int main(int argc, char* argv[]) {
// ----------------------------------------------------------
class Provider: public AudioBufferProvider {
- int16_t* mAddr;
- size_t mNumFrames;
+ int16_t* const mAddr; // base address
+ const size_t mNumFrames; // total frames
+ const int mChannels;
+ size_t mNextFrame; // index of next frame to provide
+ size_t mUnrel; // number of frames not yet released
public:
- Provider(const void* addr, size_t size, int channels) {
- mAddr = (int16_t*) addr;
- mNumFrames = size / (channels*sizeof(int16_t));
+ Provider(const void* addr, size_t size, int channels)
+ : mAddr((int16_t*) addr),
+ mNumFrames(size / (channels*sizeof(int16_t))),
+ mChannels(channels),
+ mNextFrame(0), mUnrel(0) {
}
virtual status_t getNextBuffer(Buffer* buffer,
int64_t pts = kInvalidPTS) {
- buffer->frameCount = mNumFrames;
- buffer->i16 = mAddr;
- return NO_ERROR;
+ size_t requestedFrames = buffer->frameCount;
+ if (requestedFrames > mNumFrames - mNextFrame) {
+ buffer->frameCount = mNumFrames - mNextFrame;
+ }
+ if (gVerbose) {
+ printf("getNextBuffer() requested %u frames out of %u frames available,"
+ " and returned %u frames\n",
+ requestedFrames, mNumFrames - mNextFrame, buffer->frameCount);
+ }
+ mUnrel = buffer->frameCount;
+ if (buffer->frameCount > 0) {
+ buffer->i16 = &mAddr[mChannels * mNextFrame];
+ return NO_ERROR;
+ } else {
+ buffer->i16 = NULL;
+ return NOT_ENOUGH_DATA;
+ }
}
virtual void releaseBuffer(Buffer* buffer) {
+ if (buffer->frameCount > mUnrel) {
+ fprintf(stderr, "ERROR releaseBuffer() released %u frames but only %u available "
+ "to release\n", buffer->frameCount, mUnrel);
+ mNextFrame += mUnrel;
+ mUnrel = 0;
+ } else {
+ if (gVerbose) {
+ printf("releaseBuffer() released %u frames out of %u frames available "
+ "to release\n", buffer->frameCount, mUnrel);
+ }
+ mNextFrame += buffer->frameCount;
+ mUnrel -= buffer->frameCount;
+ }
}
} provider(input_vaddr, input_size, channels);
size_t input_frames = input_size / (channels * sizeof(int16_t));
+ if (gVerbose) {
+ printf("%u input frames\n", input_frames);
+ }
size_t output_size = 2 * 4 * ((int64_t) input_frames * output_freq) / input_freq;
output_size &= ~7; // always stereo, 32-bits
@@ -240,7 +281,17 @@ int main(int argc, char* argv[]) {
resampler->setVolume(0x1000, 0x1000);
memset(output_vaddr, 0, output_size);
+ if (gVerbose) {
+ printf("resample() %u output frames\n", out_frames);
+ }
resampler->resample((int*) output_vaddr, out_frames, &provider);
+ if (gVerbose) {
+ printf("resample() complete\n");
+ }
+ resampler->reset();
+ if (gVerbose) {
+ printf("reset() complete\n");
+ }
// down-mix (we just truncate and keep the left channel)
int32_t* out = (int32_t*) output_vaddr;