#include "fillplugins.h" #include "audiodecoder.h" #include "utils.h" #include "plugin.h" #include "ac3-iec958.h" #include "avm_output.h" #include #include AVM_BEGIN_NAMESPACE; PLUGIN_TEMP(ac3pass); class AC3_PassDecoder : public IAudioDecoder { public: // Note: AudioQueue has this value hardcoded and it is used // as block size when ac3 passthrough stream is played! static const uint_t AC3_BLOCK_SIZE = 6144; AC3_PassDecoder(const CodecInfo& info, const WAVEFORMATEX* wf) :IAudioDecoder(info, wf) { } int Convert(const void* in_data, uint_t in_size, void* out_data, uint_t out_size, uint_t* size_read, uint_t* size_written) { if (!in_data || !out_data) return -1; int skipped; struct ac3info ai; int data_type = 1; int i = ac3_iec958_parse_syncinfo((unsigned char*)in_data, in_size, &ai, &skipped); if (i < 0) { AVM_WRITE("AC3_PassThrough", "AC3 stream not valid.\n"); return -1; } if (ai.samplerate != 48000) { AVM_WRITE("AC3_PassThrough", "Only 48000 Hz streams supported.\n"); return -1; } // we are reading just one frame - easier to synchronize // speed is not ours biggest problem :) ... // so I don't care we call write more offten then play-ac3 ac3_iec958_build_burst(ai.framesize, data_type, 1, (unsigned char*)in_data + skipped, (unsigned char*)out_data); if (size_read) *size_read = skipped + ai.framesize; if (size_written) *size_written = AC3_BLOCK_SIZE; return 0; } int GetOutputFormat(WAVEFORMATEX* destfmt) const { if (!destfmt) return -1; *destfmt = *m_pFormat; destfmt->wBitsPerSample = 16; destfmt->wFormatTag = 0x2000; destfmt->nAvgBytesPerSec = 192000; // after conversion destfmt->nBlockAlign = AC3_BLOCK_SIZE; destfmt->nSamplesPerSec = destfmt->nAvgBytesPerSec / destfmt->nChannels / (destfmt->wBitsPerSample / 8); destfmt->cbSize = 0; /* destfmt->nBlockAlign = destfmt->nChannels * destfmt->wBitsPerSample / 8; destfmt->nAvgBytesPerSec = destfmt->nSamplesPerSec * destfmt->nBlockAlign; */ return 0; } }; // PLUGIN loading part static IAudioDecoder* ac3pass_CreateAudioDecoder(const CodecInfo& info, const WAVEFORMATEX* format) { if (info.fourcc == 0x2000) //AC3 return new AC3_PassDecoder(info, format); ac3pass_error_set("format unsupported"); return 0; } AVM_END_NAMESPACE; extern "C" const avm::codec_plugin_t avm_codec_plugin_ac3pass = { PLUGIN_API_VERSION, 0, // err 0,0, 0, 0, 0, 0, // attrs avm::ac3pass_FillPlugins, avm::ac3pass_CreateAudioDecoder, 0, 0, 0, };