• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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