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
28 namespace android {
29
convert(const sp<ABuffer> & source,sp<ABuffer> & target)30 status_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
safeConvert(const sp<ABuffer> & source,sp<ABuffer> & target)46 status_t DataConverter::safeConvert(const sp<ABuffer> &source, sp<ABuffer> &target) {
47 memcpy(target->base(), source->data(), source->size());
48 return OK;
49 }
50
sourceSize(size_t targetSize)51 size_t DataConverter::sourceSize(size_t targetSize) {
52 return targetSize;
53 }
54
targetSize(size_t sourceSize)55 size_t DataConverter::targetSize(size_t sourceSize) {
56 return sourceSize;
57 }
58
~DataConverter()59 DataConverter::~DataConverter() { }
60
61
sourceSize(size_t targetSize)62 size_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
targetSize(size_t sourceSize)72 size_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
getAudioSampleSize(AudioEncoding e)84 static 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
Create(AudioEncoding source,AudioEncoding target)95 AudioConverter* 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
safeConvert(const sp<ABuffer> & src,sp<ABuffer> & tgt)104 status_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