1/* 2 * Copyright (c) 2013 - 2014, The Linux Foundation. All rights reserved. 3 * Not a Contribution. 4 * 5 * Copyright (C) 2013 The Android Open Source Project 6 * 7 * Licensed under the Apache License, Version 2.0 (the "License"); 8 * you may not use this file except in compliance with the License. 9 * You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, software 14 * distributed under the License is distributed on an "AS IS" BASIS, 15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 * See the License for the specific language governing permissions and 17 * limitations under the License. 18 */ 19 20#define LOG_TAG "audio_hw_compress" 21/*#define LOG_NDEBUG 0*/ 22#define LOG_NDDEBUG 0 23 24#include <errno.h> 25#include <cutils/properties.h> 26#include <stdlib.h> 27#include <dlfcn.h> 28#include <cutils/str_parms.h> 29#include <cutils/log.h> 30 31#include "audio_hw.h" 32#include "platform.h" 33#include "platform_api.h" 34 35#include "sound/compress_params.h" 36#include "sound/compress_offload.h" 37 38#ifdef COMPRESS_CAPTURE_ENABLED 39 40#define COMPRESS_IN_CONFIG_CHANNELS 1 41#define COMPRESS_IN_CONFIG_PERIOD_SIZE 2048 42#define COMPRESS_IN_CONFIG_PERIOD_COUNT 16 43 44 45struct compress_in_module { 46 uint8_t *in_buf; 47}; 48 49static struct compress_in_module c_in_mod = { 50 .in_buf = NULL, 51}; 52 53 54void audio_extn_compr_cap_init(struct stream_in *in) 55{ 56 in->usecase = USECASE_AUDIO_RECORD_COMPRESS; 57 in->config.channels = COMPRESS_IN_CONFIG_CHANNELS; 58 in->config.period_size = COMPRESS_IN_CONFIG_PERIOD_SIZE; 59 in->config.period_count= COMPRESS_IN_CONFIG_PERIOD_COUNT; 60 in->config.format = AUDIO_FORMAT_AMR_WB; 61 c_in_mod.in_buf = (uint8_t*)calloc(1, in->config.period_size*2); 62} 63 64void audio_extn_compr_cap_deinit() 65{ 66 if (c_in_mod.in_buf) { 67 free(c_in_mod.in_buf); 68 c_in_mod.in_buf = NULL; 69 } 70} 71 72bool audio_extn_compr_cap_enabled() 73{ 74 char prop_value[PROPERTY_VALUE_MAX] = {0}; 75 bool tunnel_encode = false; 76 77 property_get("tunnel.audio.encode",prop_value,"0"); 78 if (!strncmp("true", prop_value, sizeof("true"))) 79 return true; 80 else 81 return false; 82} 83 84bool audio_extn_compr_cap_format_supported(audio_format_t format) 85{ 86 if (format == AUDIO_FORMAT_AMR_WB) 87 return true; 88 else 89 return false; 90} 91 92 93bool audio_extn_compr_cap_usecase_supported(audio_usecase_t usecase) 94{ 95 if ((usecase == USECASE_AUDIO_RECORD_COMPRESS) || 96 (usecase == USECASE_INCALL_REC_UPLINK_COMPRESS) || 97 (usecase == USECASE_INCALL_REC_DOWNLINK_COMPRESS) || 98 (usecase == USECASE_INCALL_REC_UPLINK_AND_DOWNLINK_COMPRESS)) 99 return true; 100 else 101 return false; 102} 103 104 105size_t audio_extn_compr_cap_get_buffer_size(audio_format_t format) 106{ 107 if (format == AUDIO_FORMAT_AMR_WB) 108 /*One AMR WB frame is 61 bytes. Return that to the caller. 109 The buffer size is not altered, that is still period size.*/ 110 return AMR_WB_FRAMESIZE; 111 else 112 return 0; 113} 114 115size_t audio_extn_compr_cap_read(struct stream_in * in, 116 void *buffer, size_t bytes) 117{ 118 int ret; 119 struct snd_compr_audio_info *header; 120 uint32_t c_in_header; 121 uint32_t c_in_buf_size; 122 123 c_in_buf_size = in->config.period_size*2; 124 125 if (in->pcm) { 126 ret = pcm_read(in->pcm, c_in_mod.in_buf, c_in_buf_size); 127 if (ret < 0) { 128 ALOGE("pcm_read() returned failure: %d", ret); 129 return ret; 130 } else { 131 header = (struct snd_compr_audio_info *) c_in_mod.in_buf; 132 c_in_header = sizeof(*header) + header->reserved[0]; 133 if (header->frame_size > 0) { 134 if (c_in_header + header->frame_size > c_in_buf_size) { 135 ALOGW("AMR WB read buffer overflow."); 136 header->frame_size = 137 bytes - sizeof(*header) - header->reserved[0]; 138 } 139 ALOGV("c_in_buf: %p, data offset: %p, header size: %zu," 140 "reserved[0]: %u frame_size: %d", c_in_mod.in_buf, 141 c_in_mod.in_buf + c_in_header, 142 sizeof(*header), header->reserved[0], 143 header->frame_size); 144 memcpy(buffer, c_in_mod.in_buf + c_in_header, header->frame_size); 145 } else { 146 ALOGE("pcm_read() with zero frame size"); 147 ret = -EINVAL; 148 } 149 } 150 } 151 152 return 0; 153} 154 155#endif /* COMPRESS_CAPTURE_ENABLED end */ 156