| /* |
| * Copyright (C) 2010 Amlogic Corporation. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| |
| |
| //#define LOG_NDEBUG 0 |
| #define LOG_TAG "SPDIFEncoderAD" |
| #include <stdint.h> |
| #include <cutils/log.h> |
| #include <system/audio.h> |
| #include <tinyalsa/asoundlib.h> |
| #include <cutils/properties.h> |
| #include "SPDIFEncoder.h" |
| #include "SPDIFEncoderAD.h" |
| #include "aml_android_utils.h" |
| #include "aml_dump_debug.h" |
| |
| extern "C" |
| { |
| //#include "audio_hw_utils.h" |
| } |
| |
| |
| namespace android |
| { |
| class SPDIFEncoderAD : public SPDIFEncoder |
| { |
| public: |
| SPDIFEncoderAD(audio_format_t format, const void *output, size_t max_output_size) |
| : SPDIFEncoder(format) |
| , mTotalBytes(0) |
| //, eac3_frame(0) |
| //, mformat(format) |
| , outBuf(output) |
| , outBufSize(max_output_size) |
| , outBufCurrentPos(0) |
| { |
| ALOGI("%s() format %#x outBuf %p outBufSize %zu\n", __FUNCTION__, format, outBuf, outBufSize); |
| }; |
| virtual ssize_t writeOutput(const void* buffer, size_t bytes) |
| { |
| // int ret = -1; |
| ALOGV("write size %zu , outBufCurrentPos %zu\n", bytes, outBufCurrentPos); |
| |
| // ret = pcm_write(buffer, bytes); |
| char *iec61937_buffer = (char *)outBuf + outBufCurrentPos; |
| size_t actual_write_size = |
| ((outBufSize - outBufCurrentPos) > bytes) ? (bytes) : (outBufSize - outBufCurrentPos); |
| if (outBuf && (actual_write_size > 0)) |
| memcpy((void *)iec61937_buffer, (const void*)buffer, actual_write_size); |
| else |
| return -1; |
| if (actual_write_size > 0) { |
| outBufCurrentPos += actual_write_size; |
| mTotalBytes += actual_write_size; |
| ALOGV("%s() actual_write_size %zu outBufCurrentPos %zu\n", __FUNCTION__, actual_write_size, outBufCurrentPos); |
| if (get_debug_value(AML_DUMP_AUDIOHAL_SPDIF)) { |
| aml_dump_audio_bitstreams("enc_output.spdif", iec61937_buffer, actual_write_size); |
| } |
| return actual_write_size; |
| } |
| else |
| return -1; |
| } |
| /* |
| *@brief get current iec61937 data size |
| */ |
| virtual size_t getCurrentIEC61937DataSize(void) { |
| return outBufCurrentPos; |
| } |
| /* |
| *@brief flush output iec61937 data current position to zero! |
| */ |
| virtual void flushOutputCurrentPosition() { |
| outBufCurrentPos = 0; |
| } |
| /* |
| *@brief get total tytes that through the spdif encoder |
| */ |
| virtual uint64_t total_bytes() |
| { |
| return mTotalBytes; |
| } |
| protected: |
| |
| private: |
| uint64_t mTotalBytes; |
| // uint64_t eac3_frame; |
| // audio_format_t mformat; |
| const void *outBuf; |
| size_t outBufSize; |
| size_t outBufCurrentPos; |
| |
| }; |
| |
| extern "C" int spdif_encoder_ad_init(void **pphandle, audio_format_t format, const void *output, int max_output_size) |
| { |
| SPDIFEncoderAD *spdif_encoder_ad = NULL; |
| |
| spdif_encoder_ad = new SPDIFEncoderAD(format, output, max_output_size); |
| if (spdif_encoder_ad == NULL) { |
| ALOGE("init SPDIFEncoderAD failed \n"); |
| return -1; |
| } |
| *pphandle = (void *)spdif_encoder_ad; |
| ALOGI("init SPDIFEncoderAD done\n"); |
| return 0; |
| } |
| extern "C" int spdif_encoder_ad_deinit(void *phandle) |
| { |
| SPDIFEncoderAD *spdif_encoder_ad = (SPDIFEncoderAD *) phandle; |
| if (spdif_encoder_ad) { |
| delete spdif_encoder_ad; |
| } |
| |
| return 0; |
| } |
| |
| |
| extern "C" int spdif_encoder_ad_write(void *phandle, const void *buffer, size_t numBytes) |
| { |
| SPDIFEncoderAD *spdif_encoder_ad = (SPDIFEncoderAD *) phandle; |
| if (phandle == NULL) { |
| return -1; |
| } |
| |
| if (get_debug_value(AML_DUMP_AUDIOHAL_SPDIF)) { |
| aml_dump_audio_bitstreams("enc_input.spdif", buffer, numBytes); |
| } |
| return spdif_encoder_ad->write(buffer, numBytes); |
| } |
| extern "C" uint64_t spdif_encoder_ad_get_total(void *phandle) |
| { |
| SPDIFEncoderAD *spdif_encoder_ad = (SPDIFEncoderAD *) phandle; |
| if (phandle == NULL) { |
| return -1; |
| } |
| |
| return spdif_encoder_ad->total_bytes(); |
| } |
| /* |
| *@brief get current iec61937 data size |
| */ |
| extern "C" size_t spdif_encoder_ad_get_current_position(void *phandle) |
| { |
| SPDIFEncoderAD *spdif_encoder_ad = (SPDIFEncoderAD *) phandle; |
| if (phandle == NULL) { |
| return -1; |
| } |
| |
| return spdif_encoder_ad->getCurrentIEC61937DataSize(); |
| } |
| /* |
| *@brief flush output iec61937 data current position to zero! |
| */ |
| extern "C" void spdif_encoder_ad_flush_output_current_position(void *phandle) |
| { |
| SPDIFEncoderAD *spdif_encoder_ad = (SPDIFEncoderAD *) phandle; |
| if (phandle == NULL) { |
| return; |
| } |
| |
| return spdif_encoder_ad->flushOutputCurrentPosition(); |
| } |
| |
| extern "C" void spdif_encoder_ad_reset(void *phandle) |
| { |
| SPDIFEncoderAD *spdif_encoder_ad = (SPDIFEncoderAD *) phandle; |
| if (phandle == NULL) { |
| return; |
| } |
| |
| return spdif_encoder_ad->reset(); |
| } |
| |
| } |