123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204 |
- #include"mkv_flac_decoder.h"
- #include "main.h"
- static FLAC__StreamDecoderReadStatus Packet_Read(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], size_t *bytes, void *client_data)
- {
- packet_client_data_t packet = (packet_client_data_t)client_data;
- size_t to_copy = *bytes;
- if (to_copy > packet->buffer_length) {
- to_copy = packet->buffer_length;
- }
- memcpy(buffer, packet->buffer, to_copy);
- *bytes = to_copy;
- packet->buffer += to_copy;
- packet->buffer_length -= to_copy;
- return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
- }
- static FLAC__StreamDecoderSeekStatus Packet_Seek(const FLAC__StreamDecoder *decoder, FLAC__uint64 absolute_byte_offset, void *client_data)
- {
- return FLAC__STREAM_DECODER_SEEK_STATUS_UNSUPPORTED;
- }
- static FLAC__StreamDecoderTellStatus Packet_Tell(const FLAC__StreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data)
- {
- return FLAC__STREAM_DECODER_TELL_STATUS_UNSUPPORTED;
- }
- static FLAC__StreamDecoderLengthStatus Packet_Length(const FLAC__StreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data)
- {
- return FLAC__STREAM_DECODER_LENGTH_STATUS_UNSUPPORTED;
- }
- static FLAC__bool Packet_EOF(const FLAC__StreamDecoder *decoder, void *client_data)
- {
- return 0;
- }
- static void OnError(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data)
- {
- //client_data=client_data; // dummy line so i can set a breakpoint
- }
- static void OnMetadata(const FLAC__StreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data)
- {
- packet_client_data_t packet = (packet_client_data_t)client_data;
- switch(metadata->type)
- {
- case FLAC__METADATA_TYPE_STREAMINFO:
- {
- packet->frame_size = metadata->data.stream_info.max_blocksize;
- packet->bps=metadata->data.stream_info.bits_per_sample;
- packet->bytes_per_sample = (packet->bps + 7) / 8;
- packet->channels=metadata->data.stream_info.channels;
- packet->sample_rate=metadata->data.stream_info.sample_rate;
- packet->samples=metadata->data.stream_info.total_samples;
- }
- break;
- }
- }
- static FLAC__StreamDecoderWriteStatus OnAudio(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 *const buffer[], void *client_data)
- {
- packet_client_data_t packet = (packet_client_data_t)client_data;
- size_t byteLength = packet->bytes_per_sample * packet->channels * frame->header.blocksize;
- if (byteLength > packet->outputBufferBytes[0]) {
- FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
- }
- InterleaveAndTruncate(buffer, packet->outputBuffer, packet->bytes_per_sample * 8, packet->channels, frame->header.blocksize);
- packet->outputBufferBytes[0] = byteLength;
- return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
- }
- MKVFLACDecoder *MKVFLACDecoder::Create(const nsmkv::TrackEntryData *track_entry_data, const nsmkv::AudioData *audio_data, unsigned int preferred_bits, unsigned int max_channels)
- {
- FLAC__StreamDecoder *decoder = FLAC__stream_decoder_new();
- if (!decoder) {
- return 0;
- }
- packet_client_data_t packet = new packet_client_data_s;
- packet->buffer = 0;
- packet->buffer_length = 0;
- if(FLAC__stream_decoder_init_stream(
- decoder,
- Packet_Read,
- Packet_Seek,
- Packet_Tell,
- Packet_Length,
- Packet_EOF,
- OnAudio,
- OnMetadata,
- OnError,
- packet
- ) != FLAC__STREAM_DECODER_INIT_STATUS_OK)
- {
- delete packet;
- FLAC__stream_decoder_delete(decoder);
- return 0;
- }
- packet->buffer = (const uint8_t *)track_entry_data->codec_private;
- packet->buffer_length = track_entry_data->codec_private_len;
- if (!FLAC__stream_decoder_process_until_end_of_metadata(decoder)) {
- delete packet;
- FLAC__stream_decoder_delete(decoder);
- return 0;
- }
- MKVFLACDecoder *mkv_decoder = new MKVFLACDecoder(decoder, packet, preferred_bits);
- if (!mkv_decoder) {
- delete packet;
- FLAC__stream_decoder_delete(decoder);
- return 0;
- }
- return mkv_decoder;
- }
- MKVFLACDecoder::MKVFLACDecoder(FLAC__StreamDecoder *decoder, packet_client_data_t packet, unsigned int bps)
- : decoder(decoder), packet(packet), bps(bps)
- {
- }
- MKVFLACDecoder::~MKVFLACDecoder()
- {
- delete packet;
- FLAC__stream_decoder_delete(decoder);
- }
- int MKVFLACDecoder::OutputFrameSize(size_t *frame_size)
- {
- *frame_size = packet->frame_size * packet->bytes_per_sample * packet->channels;
- return MKV_SUCCESS;
- }
- int MKVFLACDecoder::GetOutputProperties(unsigned int *sampleRate, unsigned int *channels, unsigned int *bitsPerSample, bool *isFloat)
- {
- *sampleRate = packet->sample_rate;
- *channels = packet->channels;
- *bitsPerSample = packet->bps;
- *isFloat = false;
- return MKV_SUCCESS;
- }
- int MKVFLACDecoder::DecodeBlock(void *inputBuffer, size_t inputBufferBytes, void *outputBuffer, size_t *outputBufferBytes)
- {
- packet->buffer = (const uint8_t *)inputBuffer;
- packet->buffer_length = inputBufferBytes;
- packet->outputBuffer = outputBuffer;
- packet->outputBufferBytes = outputBufferBytes;
- if (FLAC__stream_decoder_process_single(decoder) == 0) {
- return MKV_FAILURE;
- }
- return MKV_SUCCESS;
- }
- void MKVFLACDecoder::Flush()
- {
- FLAC__stream_decoder_flush(decoder);
- }
- void MKVFLACDecoder::Close()
- {
- delete this;
- }
- #define CBCLASS MKVFLACDecoder
- START_DISPATCH;
- CB(OUTPUT_FRAME_SIZE, OutputFrameSize)
- CB(GET_OUTPUT_PROPERTIES, GetOutputProperties)
- CB(DECODE_BLOCK, DecodeBlock)
- VCB(FLUSH, Flush)
- VCB(CLOSE, Close)
- END_DISPATCH;
- #undef CBCLASS
- int MKVDecoder::CreateAudioDecoder(const char *codec_id, const nsmkv::TrackEntryData *track_entry_data, const nsmkv::AudioData *audio_data, unsigned int preferred_bits, unsigned int max_channels,bool floating_point, ifc_mkvaudiodecoder **decoder)
- {
- if (!strcmp(codec_id, "A_FLAC"))
- {
- MKVFLACDecoder *flac_decoder = MKVFLACDecoder::Create(track_entry_data, audio_data, preferred_bits, max_channels);
- if (flac_decoder)
- {
- *decoder = flac_decoder;
- return CREATEDECODER_SUCCESS;
- }
- return CREATEDECODER_FAILURE;
- }
- return CREATEDECODER_NOT_MINE;
- }
- #define CBCLASS MKVDecoder
- START_DISPATCH;
- CB(CREATE_AUDIO_DECODER, CreateAudioDecoder)
- END_DISPATCH;
- #undef CBCLASS
|