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 #include <system/audio.h>
28 #include <audio_utils/primitives.h>
29 #include <audio_utils/format.h>
30
31
32 namespace android {
33
convert(const sp<MediaCodecBuffer> & source,sp<MediaCodecBuffer> & target)34 status_t DataConverter::convert(const sp<MediaCodecBuffer> &source, sp<MediaCodecBuffer> &target) {
35 CHECK(source->base() != target->base());
36 size_t size = targetSize(source->size());
37 status_t err = OK;
38 if (size > target->capacity()) {
39 ALOGE("data size (%zu) is greater than buffer capacity (%zu)",
40 size, // this is the data received/to be converted
41 target->capacity()); // this is out buffer size
42 err = FAILED_TRANSACTION;
43 } else {
44 err = safeConvert(source, target);
45 }
46 target->setRange(0, err == OK ? size : 0);
47 return err;
48 }
49
safeConvert(const sp<MediaCodecBuffer> & source,sp<MediaCodecBuffer> & target)50 status_t DataConverter::safeConvert(
51 const sp<MediaCodecBuffer> &source, sp<MediaCodecBuffer> &target) {
52 memcpy(target->base(), source->data(), source->size());
53 return OK;
54 }
55
sourceSize(size_t targetSize)56 size_t DataConverter::sourceSize(size_t targetSize) {
57 return targetSize;
58 }
59
targetSize(size_t sourceSize)60 size_t DataConverter::targetSize(size_t sourceSize) {
61 return sourceSize;
62 }
63
~DataConverter()64 DataConverter::~DataConverter() { }
65
66
sourceSize(size_t targetSize)67 size_t SampleConverterBase::sourceSize(size_t targetSize) {
68 size_t numSamples = targetSize / mTargetSampleSize;
69 if (numSamples > SIZE_MAX / mSourceSampleSize) {
70 ALOGW("limiting source size due to overflow (%zu*%zu/%zu)",
71 targetSize, mSourceSampleSize, mTargetSampleSize);
72 return SIZE_MAX;
73 }
74 return numSamples * mSourceSampleSize;
75 }
76
targetSize(size_t sourceSize)77 size_t SampleConverterBase::targetSize(size_t sourceSize) {
78 // we round up on conversion
79 size_t numSamples = divUp(sourceSize, (size_t)mSourceSampleSize);
80 if (numSamples > SIZE_MAX / mTargetSampleSize) {
81 ALOGW("limiting target size due to overflow (%zu*%zu/%zu)",
82 sourceSize, mTargetSampleSize, mSourceSampleSize);
83 return SIZE_MAX;
84 }
85 return numSamples * mTargetSampleSize;
86 }
87
getAudioFormat(AudioEncoding e)88 static audio_format_t getAudioFormat(AudioEncoding e) {
89 audio_format_t format = AUDIO_FORMAT_INVALID;
90 switch (e) {
91 case kAudioEncodingPcm16bit:
92 format = AUDIO_FORMAT_PCM_16_BIT;
93 break;
94 case kAudioEncodingPcm8bit:
95 format = AUDIO_FORMAT_PCM_8_BIT;
96 break;
97 case kAudioEncodingPcmFloat:
98 format = AUDIO_FORMAT_PCM_FLOAT;
99 break;
100 case kAudioEncodingPcm24bitPacked:
101 format = AUDIO_FORMAT_PCM_24_BIT_PACKED;
102 break;
103 case kAudioEncodingPcm32bit:
104 format = AUDIO_FORMAT_PCM_32_BIT;
105 break;
106 default:
107 ALOGE("Invalid AudioEncoding %d", e);
108 }
109 return format;
110 }
111
getAudioSampleSize(AudioEncoding e)112 static size_t getAudioSampleSize(AudioEncoding e) {
113 switch (e) {
114 case kAudioEncodingPcm16bit:
115 case kAudioEncodingPcm8bit:
116 case kAudioEncodingPcmFloat:
117 case kAudioEncodingPcm24bitPacked:
118 case kAudioEncodingPcm32bit:
119 return audio_bytes_per_sample(getAudioFormat(e));
120 default: return 0;
121 }
122 }
123
124
125 // static
Create(AudioEncoding source,AudioEncoding target)126 AudioConverter* AudioConverter::Create(AudioEncoding source, AudioEncoding target) {
127 uint32_t sourceSampleSize = getAudioSampleSize(source);
128 uint32_t targetSampleSize = getAudioSampleSize(target);
129 if (sourceSampleSize && targetSampleSize && sourceSampleSize != targetSampleSize) {
130 return new AudioConverter(source, sourceSampleSize, target, targetSampleSize);
131 }
132 return NULL;
133 }
134
safeConvert(const sp<MediaCodecBuffer> & src,sp<MediaCodecBuffer> & tgt)135 status_t AudioConverter::safeConvert(const sp<MediaCodecBuffer> &src, sp<MediaCodecBuffer> &tgt) {
136 if (mTo == kAudioEncodingPcm8bit && mFrom == kAudioEncodingPcm16bit) {
137 memcpy_to_u8_from_i16((uint8_t*)tgt->base(), (const int16_t*)src->data(), src->size() / 2);
138 } else if (mTo == kAudioEncodingPcm8bit && mFrom == kAudioEncodingPcmFloat) {
139 memcpy_to_u8_from_float((uint8_t*)tgt->base(), (const float*)src->data(), src->size() / 4);
140 } else if (mTo == kAudioEncodingPcm16bit && mFrom == kAudioEncodingPcm8bit) {
141 memcpy_to_i16_from_u8((int16_t*)tgt->base(), (const uint8_t*)src->data(), src->size());
142 } else if (mTo == kAudioEncodingPcm16bit && mFrom == kAudioEncodingPcmFloat) {
143 memcpy_to_i16_from_float((int16_t*)tgt->base(), (const float*)src->data(), src->size() / 4);
144 } else if (mTo == kAudioEncodingPcmFloat && mFrom == kAudioEncodingPcm8bit) {
145 memcpy_to_float_from_u8((float*)tgt->base(), (const uint8_t*)src->data(), src->size());
146 } else if (mTo == kAudioEncodingPcmFloat && mFrom == kAudioEncodingPcm16bit) {
147 memcpy_to_float_from_i16((float*)tgt->base(), (const int16_t*)src->data(), src->size() / 2);
148 } else {
149 audio_format_t srcFormat = getAudioFormat(mFrom);
150 audio_format_t dstFormat = getAudioFormat(mTo);
151
152 if ((srcFormat == AUDIO_FORMAT_INVALID) || (dstFormat == AUDIO_FORMAT_INVALID))
153 return INVALID_OPERATION;
154
155 size_t frames = src->size() / audio_bytes_per_sample(srcFormat);
156 memcpy_by_audio_format((void*)tgt->base(), dstFormat, (void*)src->data(),
157 srcFormat, frames);
158 }
159 return OK;
160 }
161
162 } // namespace android
163