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