1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
|
/*
* Copyright 2003-2021 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef MPD_ENCODER_INTERFACE_HXX
#define MPD_ENCODER_INTERFACE_HXX
#include "EncoderPlugin.hxx"
#include "util/Compiler.h"
#include <cassert>
#include <cstddef>
struct AudioFormat;
struct Tag;
class Encoder {
const bool implements_tag;
public:
explicit Encoder(bool _implements_tag) noexcept
:implements_tag(_implements_tag) {}
virtual ~Encoder() noexcept {}
bool ImplementsTag() const noexcept {
return implements_tag;
}
/**
* Ends the stream: flushes the encoder object, generate an
* end-of-stream marker (if applicable), make everything which
* might currently be buffered available by encoder_read().
*
* After this function has been called, the encoder may not be
* usable for more data, and only Read() and Close() can be
* called.
*
* Throws on error.
*/
virtual void End() {
}
/**
* Flushes an encoder object, make everything which might
* currently be buffered available by Read().
*
* Throws on error.
*/
virtual void Flush() {
}
/**
* Prepare for sending a tag to the encoder. This is used by
* some encoders to flush the previous sub-stream, in
* preparation to begin a new one.
*
* Throws on error.
*/
virtual void PreTag() {
}
/**
* Sends a tag to the encoder.
*
* Instructions: call PreTag(); then obtain flushed data with
* Read(); finally call Tag().
*
* Throws on error.
*
* @param tag the tag object
*/
virtual void SendTag([[maybe_unused]] const Tag &tag) {
}
/**
* Writes raw PCM data to the encoder.
*
* Throws on error.
*
* @param data the buffer containing PCM samples
* @param length the length of the buffer in bytes
*/
virtual void Write(const void *data, size_t length) = 0;
/**
* Reads encoded data from the encoder.
*
* Call this repeatedly until no more data is returned.
*
* @param dest the destination buffer to copy to
* @param length the maximum length of the destination buffer
* @return the number of bytes written to #dest
*/
virtual size_t Read(void *dest, size_t length) = 0;
};
class PreparedEncoder {
public:
virtual ~PreparedEncoder() noexcept {}
/**
* Opens the object. You must call this prior to using it.
* Before you free it, you must call Close(). You may open
* and close (reuse) one encoder any number of times.
*
* After this function returns successfully and before the
* first encoder_write() call, you should invoke
* encoder_read() to obtain the file header.
*
* Throws on error.
*
* @param audio_format the encoder's input audio format; the plugin
* may modify the struct to adapt it to its abilities
*/
virtual Encoder *Open(AudioFormat &audio_format) = 0;
/**
* Get mime type of encoded content.
*
* @return an constant string, nullptr on failure
*/
virtual const char *GetMimeType() const noexcept {
return nullptr;
}
};
#endif
|