1/* 2 * Copyright (C) 2016 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 "DataConverter" 19 20#include "include/DataConverter.h" 21 22#include <audio_utils/primitives.h> 23 24#include <media/stagefright/foundation/ABuffer.h> 25#include <media/stagefright/foundation/ADebug.h> 26#include <media/stagefright/foundation/AUtils.h> 27 28namespace android { 29 30status_t DataConverter::convert(const sp<ABuffer> &source, sp<ABuffer> &target) { 31 CHECK(source->base() != target->base()); 32 size_t size = targetSize(source->size()); 33 status_t err = OK; 34 if (size > target->capacity()) { 35 ALOGE("data size (%zu) is greater than buffer capacity (%zu)", 36 size, // this is the data received/to be converted 37 target->capacity()); // this is out buffer size 38 err = FAILED_TRANSACTION; 39 } else { 40 err = safeConvert(source, target); 41 } 42 target->setRange(0, err == OK ? size : 0); 43 return err; 44} 45 46status_t DataConverter::safeConvert(const sp<ABuffer> &source, sp<ABuffer> &target) { 47 memcpy(target->base(), source->data(), source->size()); 48 return OK; 49} 50 51size_t DataConverter::sourceSize(size_t targetSize) { 52 return targetSize; 53} 54 55size_t DataConverter::targetSize(size_t sourceSize) { 56 return sourceSize; 57} 58 59DataConverter::~DataConverter() { } 60 61 62size_t SampleConverterBase::sourceSize(size_t targetSize) { 63 size_t numSamples = targetSize / mTargetSampleSize; 64 if (numSamples > SIZE_MAX / mSourceSampleSize) { 65 ALOGW("limiting source size due to overflow (%zu*%zu/%zu)", 66 targetSize, mSourceSampleSize, mTargetSampleSize); 67 return SIZE_MAX; 68 } 69 return numSamples * mSourceSampleSize; 70} 71 72size_t SampleConverterBase::targetSize(size_t sourceSize) { 73 // we round up on conversion 74 size_t numSamples = divUp(sourceSize, (size_t)mSourceSampleSize); 75 if (numSamples > SIZE_MAX / mTargetSampleSize) { 76 ALOGW("limiting target size due to overflow (%zu*%zu/%zu)", 77 sourceSize, mTargetSampleSize, mSourceSampleSize); 78 return SIZE_MAX; 79 } 80 return numSamples * mTargetSampleSize; 81} 82 83 84static size_t getAudioSampleSize(AudioEncoding e) { 85 switch (e) { 86 case kAudioEncodingPcm16bit: return 2; 87 case kAudioEncodingPcm8bit: return 1; 88 case kAudioEncodingPcmFloat: return 4; 89 default: return 0; 90 } 91} 92 93 94// static 95AudioConverter* AudioConverter::Create(AudioEncoding source, AudioEncoding target) { 96 uint32_t sourceSampleSize = getAudioSampleSize(source); 97 uint32_t targetSampleSize = getAudioSampleSize(target); 98 if (sourceSampleSize && targetSampleSize && sourceSampleSize != targetSampleSize) { 99 return new AudioConverter(source, sourceSampleSize, target, targetSampleSize); 100 } 101 return NULL; 102} 103 104status_t AudioConverter::safeConvert(const sp<ABuffer> &src, sp<ABuffer> &tgt) { 105 if (mTo == kAudioEncodingPcm8bit && mFrom == kAudioEncodingPcm16bit) { 106 memcpy_to_u8_from_i16((uint8_t*)tgt->base(), (const int16_t*)src->data(), src->size() / 2); 107 } else if (mTo == kAudioEncodingPcm8bit && mFrom == kAudioEncodingPcmFloat) { 108 memcpy_to_u8_from_float((uint8_t*)tgt->base(), (const float*)src->data(), src->size() / 4); 109 } else if (mTo == kAudioEncodingPcm16bit && mFrom == kAudioEncodingPcm8bit) { 110 memcpy_to_i16_from_u8((int16_t*)tgt->base(), (const uint8_t*)src->data(), src->size()); 111 } else if (mTo == kAudioEncodingPcm16bit && mFrom == kAudioEncodingPcmFloat) { 112 memcpy_to_i16_from_float((int16_t*)tgt->base(), (const float*)src->data(), src->size() / 4); 113 } else if (mTo == kAudioEncodingPcmFloat && mFrom == kAudioEncodingPcm8bit) { 114 memcpy_to_float_from_u8((float*)tgt->base(), (const uint8_t*)src->data(), src->size()); 115 } else if (mTo == kAudioEncodingPcmFloat && mFrom == kAudioEncodingPcm16bit) { 116 memcpy_to_float_from_i16((float*)tgt->base(), (const int16_t*)src->data(), src->size() / 2); 117 } else { 118 return INVALID_OPERATION; 119 } 120 return OK; 121} 122 123} // namespace android 124