From 85bde8013facb070b59e42fa1436270bc56df8be Mon Sep 17 00:00:00 2001 From: Denis Shulyaka Date: Thu, 30 Sep 2021 21:50:43 +0300 Subject: [PATCH 1/3] first test --- pareceive.c | 134 +++++++++++++++------------------------------------- 1 file changed, 38 insertions(+), 96 deletions(-) diff --git a/pareceive.c b/pareceive.c index 5e04be3..be133e6 100644 --- a/pareceive.c +++ b/pareceive.c @@ -471,7 +471,7 @@ void open_output_stream(void) out_sample_spec.rate = avcodeccontext->sample_rate; out_sample_spec.channels = avcodeccontext->channels; map_channel_layout(&out_channel_map, avcodeccontext->channel_layout); - tlength = avformatcontext->pb->buffer_size / 4 * out_bytes_per_sample * 2; + tlength = avformatcontext->pb->buffer_size / 4 * out_bytes_per_sample * 2; //block length?????????? } else { @@ -525,6 +525,23 @@ void open_output_stream(void) return; } +void set_instream_fragsize(uint32_t fragsize) +{ + if(instream) + { + pa_buffer_attr buffer_attr; + memcpy(&buffer_attr, pa_stream_get_buffer_attr(instream), sizeof(pa_buffer_attr)); + buffer_attr.fragsize = fragsize; + pa_operation_unref(pa_stream_set_buffer_attr(instream, &buffer_attr, stream_set_buffer_attr_callback, NULL)); + } + else + { + stdin_fragsize = fragsize == (uint32_t) -1 ? MAX_STDIN_READ : fragsize; + if(stdin_fragsize > MAX_STDIN_READ) + stdin_fragsize = MAX_STDIN_READ; + } +} + static int readFunction(void* opaque, uint8_t* buf, int buf_size) { size_t l = buf_size; @@ -553,6 +570,8 @@ static int readFunction(void* opaque, uint8_t* buf, int buf_size) inbuffer_index = 0; } + set_instream_fragsize(buf_size); + return l; } @@ -567,27 +586,9 @@ void print_averror(const char *str, int err) fprintf(stderr, "%s: %s\n", str, errbuf_ptr); } -void set_instream_fragsize(uint32_t fragsize) -{ - if(instream) - { - pa_buffer_attr buffer_attr; - memcpy(&buffer_attr, pa_stream_get_buffer_attr(instream), sizeof(pa_buffer_attr)); - buffer_attr.fragsize = fragsize; - pa_operation_unref(pa_stream_set_buffer_attr(instream, &buffer_attr, stream_set_buffer_attr_callback, NULL)); - } - else - { - stdin_fragsize = fragsize == (uint32_t) -1 ? MAX_STDIN_READ : fragsize; - if(stdin_fragsize > MAX_STDIN_READ) - stdin_fragsize = MAX_STDIN_READ; - } -} - void set_state(enum state newstate) { enum state oldstate = state; - AVIOContext *aviocontext; if(oldstate == newstate) return; @@ -617,9 +618,8 @@ void set_state(enum state newstate) case IEC61937: if(avformatcontext) { - aviocontext = avformatcontext->pb; - av_free(aviocontext->buffer); - av_free(aviocontext); + av_free(avformatcontext->pb->buffer); + av_free(avformatcontext->pb); avformat_close_input(&avformatcontext); avcodec_free_context(&avcodeccontext); swr_free(&swrcontext); @@ -658,61 +658,7 @@ void set_state(enum state newstate) } } -#define SPDIF_MAX_OFFSET 16384*10 - -// returns 0 if data is too small for examination, 1 if validation fails and a block size (aka offset) if validation is successful -size_t iec61937_validate(const uint8_t* data, size_t length) -{ - static const uint32_t magic = 0x4E1FF872; - size_t firstmagic, secondmagic; - - for(firstmagic = 0; firstmagic < length-sizeof(uint32_t)+1; firstmagic++) - if(*(uint32_t*)(data+firstmagic) == magic) - break; - - if(firstmagic == length-sizeof(uint32_t)+1) - { - if(length < SPDIF_MAX_OFFSET) - return 0; - else - return 1; - } - - for(secondmagic = firstmagic + ((*(uint16_t*)(data+firstmagic+6))>>3) + 8; secondmagic < length-sizeof(uint32_t)+1; secondmagic++) - if(*(uint32_t*)(data+secondmagic) == magic) - break; - - if(secondmagic == length-sizeof(uint32_t)+1) - { - if(length < SPDIF_MAX_OFFSET * 2) - return 0; - else - return 1; - } - - secondmagic -= firstmagic; - - if(secondmagic > SPDIF_MAX_OFFSET) - return 1; - - if(length < secondmagic * 2) - return 0; - - return secondmagic; -} - -//returns 1 if magic found, 0 if not -int iec61937_suspect(const uint8_t* data, size_t length) -{ - static const uint32_t magic = 0x4E1FF872; - size_t firstmagic; - - for(firstmagic = 0; firstmagic < length-sizeof(uint32_t)+1; firstmagic++) - if(*(uint32_t*)(data+firstmagic) == magic) - break; - - return (firstmagic == length-sizeof(uint32_t)+1) ? 0 : 1; -} +#define SPDIF_MAX_OFFSET 24576 /* Process new data */ static void decode_data(const void *data, size_t length, void *userdata) @@ -720,6 +666,8 @@ static void decode_data(const void *data, size_t length, void *userdata) int i=0; static AVPacket pkt; static size_t prevextralength = 0; + static AVProbeData iec61937_probedata = {0}; + static int (*spdif_probe)(const AVProbeData *) = NULL; assert(data); assert(length > 0); @@ -764,37 +712,29 @@ static void decode_data(const void *data, size_t length, void *userdata) if(!avformatcontext) { - size_t block_size = iec61937_validate(inbuffer + inbuffer_index, inbuffer_length); - if (block_size == 0) + if(inbuffer_length < SPDIF_MAX_OFFSET) { #ifdef DEBUG_LATENCY fprintf(stderr, "Buffer is too small, waiting for more data\n"); #endif return; } - else if(block_size == 1) + + if(!spdif_probe) + spdif_probe = av_find_input_format("spdif")->read_probe; + iec61937_probedata.buf = inbuffer + inbuffer_index; + iec61937_probedata.buf_size = inbuffer_length; + if(!spdif_probe(&iec61937_probedata)) { fprintf(stderr, "IEC61937 validation failed\n"); set_state(PCM); return; } -#ifdef DEBUG_LATENCY - fprintf(stderr, "block_size=%zu\n", block_size); -#endif - - if(inbuffer_length < block_size * 3) - { -#ifdef DEBUG_LATENCY - fprintf(stderr, "Buffer is too small, waiting for more data\n"); -#endif - return; - } - prevextralength = inbuffer_length; avformatcontext = avformat_alloc_context(); - avformatcontext->pb = avio_alloc_context(av_malloc(block_size), block_size, 0, NULL, readFunction, NULL, NULL); + avformatcontext->pb = avio_alloc_context(av_malloc(SPDIF_MAX_OFFSET), SPDIF_MAX_OFFSET, 0, NULL, readFunction, NULL, NULL); if( (i = avformat_open_input(&avformatcontext, input_device_name, av_find_input_format("spdif"), NULL)) < 0) { print_averror("avformat_open_input", i); @@ -855,8 +795,6 @@ static void decode_data(const void *data, size_t length, void *userdata) pkt.data = NULL; pkt.size = 0; - set_instream_fragsize(block_size * 2); - open_output_stream(); char buf[256]; @@ -960,7 +898,11 @@ static void decode_data(const void *data, size_t length, void *userdata) if(state==PCM) { - if(iec61937_suspect(data, length)) + if(!spdif_probe) + spdif_probe = av_find_input_format("spdif")->read_probe; + iec61937_probedata.buf = (unsigned char *)data; + iec61937_probedata.buf_size = length; + if(spdif_probe(&iec61937_probedata)) { printf("Suspected IEC61937\n"); set_state(IEC61937); From 4df5ec62a5f8fa727512ad7468a7d29ac999a7b7 Mon Sep 17 00:00:00 2001 From: Denis Shulyaka Date: Wed, 6 Oct 2021 01:55:14 +0300 Subject: [PATCH 2/3] removed redundant return --- pareceive.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/pareceive.c b/pareceive.c index 661b049..01e4287 100644 --- a/pareceive.c +++ b/pareceive.c @@ -590,8 +590,6 @@ void open_output_stream(void) fprintf(stderr, "pa_stream_connect_playback() failed: %s\n", pa_strerror(pa_context_errno(context))); quit(1); } - - return; } void set_instream_fragsize(uint32_t fragsize) From c7dcffd9c0245fe834978f9419903f13a9dffa62 Mon Sep 17 00:00:00 2001 From: Denis Shulyaka Date: Wed, 6 Oct 2021 12:17:49 +0300 Subject: [PATCH 3/3] fix warning --- pareceive.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pareceive.c b/pareceive.c index 01e4287..9e98f55 100644 --- a/pareceive.c +++ b/pareceive.c @@ -790,7 +790,7 @@ static void decode_data(const void *data, size_t length, void *userdata) if(!spdif_probe) spdif_probe = av_find_input_format("spdif")->read_probe; - iec61937_probedata.buf = inbuffer + inbuffer_index; + iec61937_probedata.buf = (uint8_t*) inbuffer + inbuffer_index; iec61937_probedata.buf_size = inbuffer_length; if(!spdif_probe(&iec61937_probedata)) {