audio_stream.c 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. #include <stdlib.h>
  2. #include <string.h>
  3. #include "audio_stream.h"
  4. #include "audio_buffer.h"
  5. #include "audio_decoder.h"
  6. #include "audio_receiver_internal.h"
  7. extern const audio_stream_ops_t audio_stream_realtime_ops;
  8. extern const audio_stream_ops_t audio_stream_buffered_ops;
  9. static bool apply_aac_transient_mute(audio_receiver_state_t *state,
  10. int16_t *buffer, size_t samples,
  11. int channels) {
  12. if (!audio_decoder_is_aac(state->decoder)) {
  13. return false;
  14. }
  15. if ((state->blocks_read_in_sequence <= 2) &&
  16. (state->blocks_read_in_sequence != state->blocks_read)) {
  17. memset(buffer, 0, samples * channels * sizeof(int16_t));
  18. return true;
  19. }
  20. return false;
  21. }
  22. bool audio_stream_process_frame(audio_receiver_state_t *state,
  23. uint32_t timestamp, const uint8_t *audio_data,
  24. size_t audio_len) {
  25. if (!state || !state->decoder) {
  26. return false;
  27. }
  28. // Blanket gate: reject everything between seek_flush and the next anchor.
  29. if (state->discard_all_until_anchor) {
  30. return false;
  31. }
  32. // Post-seek RTP window gate: discard frames outside [discard_before_rtp,
  33. // discard_above_rtp]. The TCP socket buffer can hold many seconds of
  34. // pre-seek audio; both gates together handle both seek directions:
  35. // discard_before_rtp — forward seek: stale frames have lower RTP
  36. // discard_above_rtp — backward seek: stale frames have much higher RTP
  37. // Each self-disarms on the first frame that passes it.
  38. if (state->discard_before_rtp_valid) {
  39. if ((int32_t)(timestamp - state->discard_before_rtp) < 0) {
  40. return false; // below lower bound — forward-seek stale frame
  41. }
  42. state->discard_before_rtp_valid = false;
  43. }
  44. if (state->discard_above_rtp_valid) {
  45. if ((int32_t)(timestamp - state->discard_above_rtp) > 0) {
  46. return false; // above upper bound — backward-seek stale frame
  47. }
  48. state->discard_above_rtp_valid = false;
  49. }
  50. size_t capacity_samples = 0;
  51. int16_t *decode_buffer =
  52. audio_buffer_get_decode_buffer(&state->buffer, &capacity_samples);
  53. if (!decode_buffer || capacity_samples == 0) {
  54. return false;
  55. }
  56. audio_decode_info_t info = {0};
  57. int decoded_samples =
  58. audio_decoder_decode(state->decoder, audio_data, audio_len, decode_buffer,
  59. capacity_samples, &info);
  60. if (decoded_samples <= 0) {
  61. return false;
  62. }
  63. int channels =
  64. info.channels > 0 ? info.channels : state->stream->format.channels;
  65. if (channels <= 0) {
  66. channels = 2;
  67. }
  68. apply_aac_transient_mute(state, decode_buffer, (size_t)decoded_samples,
  69. channels);
  70. return audio_buffer_queue_decoded(&state->buffer, &state->stats, timestamp,
  71. decode_buffer, (size_t)decoded_samples,
  72. channels);
  73. }
  74. audio_stream_t *audio_stream_create_realtime(void) {
  75. audio_stream_t *stream = calloc(1, sizeof(*stream));
  76. if (!stream) {
  77. return NULL;
  78. }
  79. stream->ops = &audio_stream_realtime_ops;
  80. stream->type = AUDIO_STREAM_REALTIME;
  81. return stream;
  82. }
  83. audio_stream_t *audio_stream_create_buffered(void) {
  84. audio_stream_t *stream = calloc(1, sizeof(*stream));
  85. if (!stream) {
  86. return NULL;
  87. }
  88. stream->ops = &audio_stream_buffered_ops;
  89. stream->type = AUDIO_STREAM_BUFFERED;
  90. return stream;
  91. }
  92. void audio_stream_destroy(audio_stream_t *stream) {
  93. if (!stream) {
  94. return;
  95. }
  96. if (stream->ops && stream->ops->destroy) {
  97. stream->ops->destroy(stream);
  98. return;
  99. }
  100. free(stream);
  101. }
  102. bool audio_stream_uses_buffer(audio_stream_type_t type) {
  103. return type == AUDIO_STREAM_BUFFERED;
  104. }