| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125 |
- #include <stdlib.h>
- #include <string.h>
- #include "audio_stream.h"
- #include "audio_buffer.h"
- #include "audio_decoder.h"
- #include "audio_receiver_internal.h"
- extern const audio_stream_ops_t audio_stream_realtime_ops;
- extern const audio_stream_ops_t audio_stream_buffered_ops;
- static bool apply_aac_transient_mute(audio_receiver_state_t *state,
- int16_t *buffer, size_t samples,
- int channels) {
- if (!audio_decoder_is_aac(state->decoder)) {
- return false;
- }
- if ((state->blocks_read_in_sequence <= 2) &&
- (state->blocks_read_in_sequence != state->blocks_read)) {
- memset(buffer, 0, samples * channels * sizeof(int16_t));
- return true;
- }
- return false;
- }
- bool audio_stream_process_frame(audio_receiver_state_t *state,
- uint32_t timestamp, const uint8_t *audio_data,
- size_t audio_len) {
- if (!state || !state->decoder) {
- return false;
- }
- // Blanket gate: reject everything between seek_flush and the next anchor.
- if (state->discard_all_until_anchor) {
- return false;
- }
- // Post-seek RTP window gate: discard frames outside [discard_before_rtp,
- // discard_above_rtp]. The TCP socket buffer can hold many seconds of
- // pre-seek audio; both gates together handle both seek directions:
- // discard_before_rtp — forward seek: stale frames have lower RTP
- // discard_above_rtp — backward seek: stale frames have much higher RTP
- // Each self-disarms on the first frame that passes it.
- if (state->discard_before_rtp_valid) {
- if ((int32_t)(timestamp - state->discard_before_rtp) < 0) {
- return false; // below lower bound — forward-seek stale frame
- }
- state->discard_before_rtp_valid = false;
- }
- if (state->discard_above_rtp_valid) {
- if ((int32_t)(timestamp - state->discard_above_rtp) > 0) {
- return false; // above upper bound — backward-seek stale frame
- }
- state->discard_above_rtp_valid = false;
- }
- size_t capacity_samples = 0;
- int16_t *decode_buffer =
- audio_buffer_get_decode_buffer(&state->buffer, &capacity_samples);
- if (!decode_buffer || capacity_samples == 0) {
- return false;
- }
- audio_decode_info_t info = {0};
- int decoded_samples =
- audio_decoder_decode(state->decoder, audio_data, audio_len, decode_buffer,
- capacity_samples, &info);
- if (decoded_samples <= 0) {
- return false;
- }
- int channels =
- info.channels > 0 ? info.channels : state->stream->format.channels;
- if (channels <= 0) {
- channels = 2;
- }
- apply_aac_transient_mute(state, decode_buffer, (size_t)decoded_samples,
- channels);
- return audio_buffer_queue_decoded(&state->buffer, &state->stats, timestamp,
- decode_buffer, (size_t)decoded_samples,
- channels);
- }
- audio_stream_t *audio_stream_create_realtime(void) {
- audio_stream_t *stream = calloc(1, sizeof(*stream));
- if (!stream) {
- return NULL;
- }
- stream->ops = &audio_stream_realtime_ops;
- stream->type = AUDIO_STREAM_REALTIME;
- return stream;
- }
- audio_stream_t *audio_stream_create_buffered(void) {
- audio_stream_t *stream = calloc(1, sizeof(*stream));
- if (!stream) {
- return NULL;
- }
- stream->ops = &audio_stream_buffered_ops;
- stream->type = AUDIO_STREAM_BUFFERED;
- return stream;
- }
- void audio_stream_destroy(audio_stream_t *stream) {
- if (!stream) {
- return;
- }
- if (stream->ops && stream->ops->destroy) {
- stream->ops->destroy(stream);
- return;
- }
- free(stream);
- }
- bool audio_stream_uses_buffer(audio_stream_type_t type) {
- return type == AUDIO_STREAM_BUFFERED;
- }
|