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
convert(const sp<MediaCodecBuffer> & source,sp<MediaCodecBuffer> & target)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
safeConvert(const sp<MediaCodecBuffer> & source,sp<MediaCodecBuffer> & target)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
sourceSize(size_t targetSize)52 size_t DataConverter::sourceSize(size_t targetSize) {
53 return targetSize;
54 }
55
targetSize(size_t sourceSize)56 size_t DataConverter::targetSize(size_t sourceSize) {
57 return sourceSize;
58 }
59
~DataConverter()60 DataConverter::~DataConverter() { }
61
62
sourceSize(size_t targetSize)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
targetSize(size_t sourceSize)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
getAudioSampleSize(AudioEncoding e)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
Create(AudioEncoding source,AudioEncoding target)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
safeConvert(const sp<MediaCodecBuffer> & src,sp<MediaCodecBuffer> & tgt)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