MayaFlux 0.2.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches
AudioStreamContext.hpp
Go to the documentation of this file.
1#pragma once
2
4
5extern "C" {
6struct AVCodecContext;
7struct SwrContext;
8}
9
10namespace MayaFlux::IO {
11
12/**
13 * @class AudioStreamContext
14 * @brief RAII owner of one audio stream's codec and resampler state.
15 *
16 * Encapsulates all audio-stream-specific FFmpeg objects:
17 * - AVCodecContext for the selected audio stream
18 * - SwrContext for sample-format conversion and optional resampling
19 * - Cached audio parameters: sample_rate, channel count, total_frames
20 *
21 * Does NOT own AVFormatContext — that belongs to FFmpegDemuxContext.
22 * Packet reading is always delegated to the demuxer's format_context;
23 * this context only decodes and converts packets it receives.
24 *
25 * Destruction order (enforced in destructor):
26 * swr_context → codec_context
27 * The associated FFmpegDemuxContext must outlive this object.
28 */
29class MAYAFLUX_API AudioStreamContext {
30public:
31 AudioStreamContext() = default;
33
38
39 // =========================================================================
40 // Lifecycle
41 // =========================================================================
42
43 /**
44 * @brief Open the audio stream from an already-probed demux context.
45 *
46 * Finds the best audio stream, allocates and opens the codec context,
47 * caches audio parameters, and initialises the SwrContext for conversion
48 * to AV_SAMPLE_FMT_DBL (or AV_SAMPLE_FMT_DBLP if planar output requested).
49 *
50 * @param demux Open demux context (must outlive this object).
51 * @param planar_output If true, configure swr for planar double output.
52 * @param target_rate Resample target in Hz; 0 = keep source rate.
53 * @return True on success.
54 */
55 bool open(const FFmpegDemuxContext& demux,
56 bool planar_output = false,
57 uint32_t target_rate = 0);
58
59 /**
60 * @brief Release codec and resampler resources.
61 * Safe to call multiple times.
62 */
63 void close();
64
65 /**
66 * @brief True if the codec and resampler are ready for decoding.
67 */
68 [[nodiscard]] bool is_valid() const
69 {
70 return codec_context && swr_context && stream_index >= 0;
71 }
72
73 // =========================================================================
74 // Codec flush
75 // =========================================================================
76
77 /**
78 * @brief Flush codec internal buffers (call after a seek).
79 */
80 void flush_codec();
81
82 /**
83 * @brief Drain any samples buffered inside the resampler.
84 *
85 * swr_init() and seek+flush sequences can leave delay-compensation
86 * samples inside SwrContext. Calling this discards them so that the
87 * next decode_frames() call starts from a clean resampler state.
88 * Must be called after open() and after every seek+flush pair.
89 */
90 void drain_resampler_init();
91
92 // =========================================================================
93 // Stream-level metadata extraction
94 // =========================================================================
95
96 /**
97 * @brief Populate stream-specific fields into an existing FileMetadata.
98 * Appends codec name, channel layout, bit_rate, sample_rate, etc.
99 * @param demux The demux context that owns the format_context.
100 * @param out Metadata struct to append into.
101 */
102 void extract_stream_metadata(const FFmpegDemuxContext& demux, FileMetadata& out) const;
103
104 /**
105 * @brief Extract cue/marker regions from stream metadata tags.
106 * @param demux The demux context.
107 * @return Vector of FileRegion with type="cue" or "marker".
108 */
109 [[nodiscard]] std::vector<FileRegion> extract_cue_regions(const FFmpegDemuxContext& demux) const;
110
111 // =========================================================================
112 // Error
113 // =========================================================================
114
115 [[nodiscard]] const std::string& last_error() const { return m_last_error; }
116
117 // =========================================================================
118 // Owned handles — accessible to SoundFileReader for decode loops
119 // =========================================================================
120
121 AVCodecContext* codec_context = nullptr; ///< Owned; freed in destructor.
122 SwrContext* swr_context = nullptr; ///< Owned; freed in destructor.
123
124 int stream_index = -1;
125 uint64_t total_frames = 0;
126 uint32_t sample_rate = 0;
127 uint32_t channels = 0;
128
129private:
130 std::string m_last_error;
131
132 bool setup_resampler(bool planar_output, uint32_t target_rate);
133};
134
135} // namespace MayaFlux::IO
bool is_valid() const
True if the codec and resampler are ready for decoding.
AudioStreamContext & operator=(AudioStreamContext &&)=delete
const std::string & last_error() const
AudioStreamContext(const AudioStreamContext &)=delete
AudioStreamContext & operator=(const AudioStreamContext &)=delete
AudioStreamContext(AudioStreamContext &&)=delete
RAII owner of one audio stream's codec and resampler state.
RAII owner of a single AVFormatContext and associated demux state.
Generic metadata structure for any file type.