Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
M
mpd
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Иван Мажукин
mpd
Commits
d8b6aff2
Commit
d8b6aff2
authored
Nov 07, 2016
by
Max Kellermann
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
encoder: migrate from class Error to C++ exceptions
parent
b8aac3f8
Show whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
276 additions
and
454 deletions
+276
-454
EncoderInterface.hxx
src/encoder/EncoderInterface.hxx
+15
-19
FlacEncoderPlugin.cxx
src/encoder/plugins/FlacEncoderPlugin.cxx
+35
-73
LameEncoderPlugin.cxx
src/encoder/plugins/LameEncoderPlugin.cxx
+32
-61
NullEncoderPlugin.cxx
src/encoder/plugins/NullEncoderPlugin.cxx
+2
-3
OggEncoder.hxx
src/encoder/plugins/OggEncoder.hxx
+2
-8
OpusEncoderPlugin.cxx
src/encoder/plugins/OpusEncoderPlugin.cxx
+24
-43
ShineEncoderPlugin.cxx
src/encoder/plugins/ShineEncoderPlugin.cxx
+16
-29
TwolameEncoderPlugin.cxx
src/encoder/plugins/TwolameEncoderPlugin.cxx
+33
-57
VorbisEncoderPlugin.cxx
src/encoder/plugins/VorbisEncoderPlugin.cxx
+24
-46
WaveEncoderPlugin.cxx
src/encoder/plugins/WaveEncoderPlugin.cxx
+4
-6
RecorderOutputPlugin.cxx
src/output/plugins/RecorderOutputPlugin.cxx
+20
-38
ShoutOutputPlugin.cxx
src/output/plugins/ShoutOutputPlugin.cxx
+25
-11
HttpdInternal.hxx
src/output/plugins/httpd/HttpdInternal.hxx
+7
-2
HttpdOutputPlugin.cxx
src/output/plugins/httpd/HttpdOutputPlugin.cxx
+28
-25
run_encoder.cxx
test/run_encoder.cxx
+3
-17
test_vorbis_encoder.cxx
test/test_vorbis_encoder.cxx
+6
-16
No files found.
src/encoder/EncoderInterface.hxx
View file @
d8b6aff2
...
@@ -28,7 +28,6 @@
...
@@ -28,7 +28,6 @@
struct
AudioFormat
;
struct
AudioFormat
;
struct
Tag
;
struct
Tag
;
class
Error
;
class
Encoder
{
class
Encoder
{
const
bool
implements_tag
;
const
bool
implements_tag
;
...
@@ -51,20 +50,18 @@ public:
...
@@ -51,20 +50,18 @@ public:
* usable for more data, and only Read() and Close() can be
* usable for more data, and only Read() and Close() can be
* called.
* called.
*
*
*
@return true on success
*
Throws #std::runtime_error on error.
*/
*/
virtual
bool
End
(
gcc_unused
Error
&
error
)
{
virtual
void
End
()
{
return
true
;
}
}
/**
/**
* Flushes an encoder object, make everything which might
* Flushes an encoder object, make everything which might
* currently be buffered available by Read().
* currently be buffered available by Read().
*
*
*
@return true on success
*
Throws #std::runtime_error on error.
*/
*/
virtual
bool
Flush
(
gcc_unused
Error
&
error
)
{
virtual
void
Flush
()
{
return
true
;
}
}
/**
/**
...
@@ -72,10 +69,9 @@ public:
...
@@ -72,10 +69,9 @@ public:
* some encoders to flush the previous sub-stream, in
* some encoders to flush the previous sub-stream, in
* preparation to begin a new one.
* preparation to begin a new one.
*
*
*
@return true on success
*
Throws #std::runtime_error on error.
*/
*/
virtual
bool
PreTag
(
gcc_unused
Error
&
error
)
{
virtual
void
PreTag
()
{
return
true
;
}
}
/**
/**
...
@@ -84,23 +80,22 @@ public:
...
@@ -84,23 +80,22 @@ public:
* Instructions: call PreTag(); then obtain flushed data with
* Instructions: call PreTag(); then obtain flushed data with
* Read(); finally call Tag().
* Read(); finally call Tag().
*
*
* Throws #std::runtime_error on error.
*
* @param tag the tag object
* @param tag the tag object
* @return true on success
*/
*/
virtual
bool
SendTag
(
gcc_unused
const
Tag
&
tag
,
virtual
void
SendTag
(
gcc_unused
const
Tag
&
tag
)
{
gcc_unused
Error
&
error
)
{
return
true
;
}
}
/**
/**
* Writes raw PCM data to the encoder.
* Writes raw PCM data to the encoder.
*
*
* Throws #std::runtime_error on error.
*
* @param data the buffer containing PCM samples
* @param data the buffer containing PCM samples
* @param length the length of the buffer in bytes
* @param length the length of the buffer in bytes
* @return true on success
*/
*/
virtual
bool
Write
(
const
void
*
data
,
size_t
length
,
virtual
void
Write
(
const
void
*
data
,
size_t
length
)
=
0
;
Error
&
error
)
=
0
;
/**
/**
* Reads encoded data from the encoder.
* Reads encoded data from the encoder.
...
@@ -127,11 +122,12 @@ public:
...
@@ -127,11 +122,12 @@ public:
* first encoder_write() call, you should invoke
* first encoder_write() call, you should invoke
* encoder_read() to obtain the file header.
* encoder_read() to obtain the file header.
*
*
* Throws #std::runtime_error on error.
*
* @param audio_format the encoder's input audio format; the plugin
* @param audio_format the encoder's input audio format; the plugin
* may modify the struct to adapt it to its abilities
* may modify the struct to adapt it to its abilities
* @return true on success
*/
*/
virtual
Encoder
*
Open
(
AudioFormat
&
audio_format
,
Error
&
error
)
=
0
;
virtual
Encoder
*
Open
(
AudioFormat
&
audio_format
)
=
0
;
/**
/**
* Get mime type of encoded content.
* Get mime type of encoded content.
...
...
src/encoder/plugins/FlacEncoderPlugin.cxx
View file @
d8b6aff2
...
@@ -24,8 +24,7 @@
...
@@ -24,8 +24,7 @@
#include "pcm/PcmBuffer.hxx"
#include "pcm/PcmBuffer.hxx"
#include "config/ConfigError.hxx"
#include "config/ConfigError.hxx"
#include "util/DynamicFifoBuffer.hxx"
#include "util/DynamicFifoBuffer.hxx"
#include "util/Error.hxx"
#include "util/RuntimeError.hxx"
#include "util/Domain.hxx"
#include <FLAC/stream_encoder.h>
#include <FLAC/stream_encoder.h>
...
@@ -47,29 +46,22 @@ class FlacEncoder final : public Encoder {
...
@@ -47,29 +46,22 @@ class FlacEncoder final : public Encoder {
DynamicFifoBuffer
<
uint8_t
>
output_buffer
;
DynamicFifoBuffer
<
uint8_t
>
output_buffer
;
public
:
public
:
FlacEncoder
(
AudioFormat
_audio_format
,
FLAC__StreamEncoder
*
_fse
)
FlacEncoder
(
AudioFormat
_audio_format
,
FLAC__StreamEncoder
*
_fse
);
:
Encoder
(
false
),
audio_format
(
_audio_format
),
fse
(
_fse
),
output_buffer
(
8192
)
{}
~
FlacEncoder
()
override
{
~
FlacEncoder
()
override
{
FLAC__stream_encoder_delete
(
fse
);
FLAC__stream_encoder_delete
(
fse
);
}
}
bool
Init
(
Error
&
error
);
/* virtual methods from class Encoder */
/* virtual methods from class Encoder */
bool
End
(
Error
&
)
override
{
void
End
(
)
override
{
(
void
)
FLAC__stream_encoder_finish
(
fse
);
(
void
)
FLAC__stream_encoder_finish
(
fse
);
return
true
;
}
}
bool
Flush
(
Error
&
)
override
{
void
Flush
(
)
override
{
(
void
)
FLAC__stream_encoder_finish
(
fse
);
(
void
)
FLAC__stream_encoder_finish
(
fse
);
return
true
;
}
}
bool
Write
(
const
void
*
data
,
size_t
length
,
Error
&
)
override
;
void
Write
(
const
void
*
data
,
size_t
length
)
override
;
size_t
Read
(
void
*
dest
,
size_t
length
)
override
{
size_t
Read
(
void
*
dest
,
size_t
length
)
override
{
return
output_buffer
.
Read
((
uint8_t
*
)
dest
,
length
);
return
output_buffer
.
Read
((
uint8_t
*
)
dest
,
length
);
...
@@ -95,15 +87,13 @@ public:
...
@@ -95,15 +87,13 @@ public:
PreparedFlacEncoder
(
const
ConfigBlock
&
block
);
PreparedFlacEncoder
(
const
ConfigBlock
&
block
);
/* virtual methods from class PreparedEncoder */
/* virtual methods from class PreparedEncoder */
Encoder
*
Open
(
AudioFormat
&
audio_format
,
Error
&
)
override
;
Encoder
*
Open
(
AudioFormat
&
audio_format
)
override
;
const
char
*
GetMimeType
()
const
override
{
const
char
*
GetMimeType
()
const
override
{
return
"audio/flac"
;
return
"audio/flac"
;
}
}
};
};
static
constexpr
Domain
flac_encoder_domain
(
"vorbis_encoder"
);
PreparedFlacEncoder
::
PreparedFlacEncoder
(
const
ConfigBlock
&
block
)
PreparedFlacEncoder
::
PreparedFlacEncoder
(
const
ConfigBlock
&
block
)
:
compression
(
block
.
GetBlockValue
(
"compression"
,
5u
))
:
compression
(
block
.
GetBlockValue
(
"compression"
,
5u
))
{
{
...
@@ -115,45 +105,32 @@ flac_encoder_init(const ConfigBlock &block)
...
@@ -115,45 +105,32 @@ flac_encoder_init(const ConfigBlock &block)
return
new
PreparedFlacEncoder
(
block
);
return
new
PreparedFlacEncoder
(
block
);
}
}
static
bool
static
void
flac_encoder_setup
(
FLAC__StreamEncoder
*
fse
,
unsigned
compression
,
flac_encoder_setup
(
FLAC__StreamEncoder
*
fse
,
unsigned
compression
,
const
AudioFormat
&
audio_format
,
unsigned
bits_per_sample
,
const
AudioFormat
&
audio_format
,
unsigned
bits_per_sample
)
Error
&
error
)
{
{
if
(
!
FLAC__stream_encoder_set_compression_level
(
fse
,
compression
))
{
if
(
!
FLAC__stream_encoder_set_compression_level
(
fse
,
compression
))
error
.
Format
(
config_domain
,
throw
FormatRuntimeError
(
"error setting flac compression to %d"
,
"error setting flac compression to %d"
,
compression
);
compression
);
return
false
;
}
if
(
!
FLAC__stream_encoder_set_channels
(
fse
,
audio_format
.
channels
))
{
if
(
!
FLAC__stream_encoder_set_channels
(
fse
,
audio_format
.
channels
))
error
.
Format
(
config_domain
,
throw
FormatRuntimeError
(
"error setting flac channels num to %d"
,
"error setting flac channels num to %d"
,
audio_format
.
channels
);
audio_format
.
channels
);
return
false
;
}
if
(
!
FLAC__stream_encoder_set_bits_per_sample
(
fse
,
bits_per_sample
))
{
if
(
!
FLAC__stream_encoder_set_bits_per_sample
(
fse
,
bits_per_sample
))
error
.
Format
(
config_domain
,
throw
FormatRuntimeError
(
"error setting flac bit format to %d"
,
"error setting flac bit format to %d"
,
bits_per_sample
);
bits_per_sample
);
return
false
;
}
if
(
!
FLAC__stream_encoder_set_sample_rate
(
fse
,
if
(
!
FLAC__stream_encoder_set_sample_rate
(
fse
,
audio_format
.
sample_rate
))
{
audio_format
.
sample_rate
))
error
.
Format
(
config_domain
,
throw
FormatRuntimeError
(
"error setting flac sample rate to %d"
,
"error setting flac sample rate to %d"
,
audio_format
.
sample_rate
);
audio_format
.
sample_rate
);
return
false
;
}
return
true
;
}
}
bool
FlacEncoder
::
FlacEncoder
(
AudioFormat
_audio_format
,
FLAC__StreamEncoder
*
_fse
)
FlacEncoder
::
Init
(
Error
&
error
)
:
Encoder
(
false
),
audio_format
(
_audio_format
),
fse
(
_fse
),
output_buffer
(
8192
)
{
{
/* this immediately outputs data through callback */
/* this immediately outputs data through callback */
...
@@ -163,18 +140,13 @@ FlacEncoder::Init(Error &error)
...
@@ -163,18 +140,13 @@ FlacEncoder::Init(Error &error)
nullptr
,
nullptr
,
nullptr
,
nullptr
,
nullptr
,
nullptr
,
this
);
this
);
if
(
init_status
!=
FLAC__STREAM_ENCODER_INIT_STATUS_OK
)
{
if
(
init_status
!=
FLAC__STREAM_ENCODER_INIT_STATUS_OK
)
error
.
Format
(
flac_encoder_domain
,
throw
FormatRuntimeError
(
"failed to initialize encoder: %s
\n
"
,
"failed to initialize encoder: %s
\n
"
,
FLAC__StreamEncoderInitStatusString
[
init_status
]);
FLAC__StreamEncoderInitStatusString
[
init_status
]);
return
false
;
}
return
true
;
}
}
Encoder
*
Encoder
*
PreparedFlacEncoder
::
Open
(
AudioFormat
&
audio_format
,
Error
&
error
)
PreparedFlacEncoder
::
Open
(
AudioFormat
&
audio_format
)
{
{
unsigned
bits_per_sample
;
unsigned
bits_per_sample
;
...
@@ -199,24 +171,18 @@ PreparedFlacEncoder::Open(AudioFormat &audio_format, Error &error)
...
@@ -199,24 +171,18 @@ PreparedFlacEncoder::Open(AudioFormat &audio_format, Error &error)
/* allocate the encoder */
/* allocate the encoder */
auto
fse
=
FLAC__stream_encoder_new
();
auto
fse
=
FLAC__stream_encoder_new
();
if
(
fse
==
nullptr
)
{
if
(
fse
==
nullptr
)
error
.
Set
(
flac_encoder_domain
,
"FLAC__stream_encoder_new() failed"
);
throw
std
::
runtime_error
(
"FLAC__stream_encoder_new() failed"
);
return
nullptr
;
}
if
(
!
flac_encoder_setup
(
fse
,
compression
,
try
{
audio_format
,
bits_per_sample
,
error
))
{
flac_encoder_setup
(
fse
,
compression
,
audio_format
,
bits_per_sample
);
}
catch
(...)
{
FLAC__stream_encoder_delete
(
fse
);
FLAC__stream_encoder_delete
(
fse
);
return
nullptr
;
throw
;
}
}
auto
*
e
=
new
FlacEncoder
(
audio_format
,
fse
);
return
new
FlacEncoder
(
audio_format
,
fse
);
if
(
!
e
->
Init
(
error
))
{
delete
e
;
return
nullptr
;
}
return
e
;
}
}
static
inline
void
static
inline
void
...
@@ -237,8 +203,8 @@ pcm16_to_flac(int32_t *out, const int16_t *in, unsigned num_samples)
...
@@ -237,8 +203,8 @@ pcm16_to_flac(int32_t *out, const int16_t *in, unsigned num_samples)
}
}
}
}
bool
void
FlacEncoder
::
Write
(
const
void
*
data
,
size_t
length
,
Error
&
error
)
FlacEncoder
::
Write
(
const
void
*
data
,
size_t
length
)
{
{
void
*
exbuffer
;
void
*
exbuffer
;
const
void
*
buffer
=
nullptr
;
const
void
*
buffer
=
nullptr
;
...
@@ -278,12 +244,8 @@ FlacEncoder::Write(const void *data, size_t length, Error &error)
...
@@ -278,12 +244,8 @@ FlacEncoder::Write(const void *data, size_t length, Error &error)
if
(
!
FLAC__stream_encoder_process_interleaved
(
fse
,
if
(
!
FLAC__stream_encoder_process_interleaved
(
fse
,
(
const
FLAC__int32
*
)
buffer
,
(
const
FLAC__int32
*
)
buffer
,
num_frames
))
{
num_frames
))
error
.
Set
(
flac_encoder_domain
,
"flac encoder process failed"
);
throw
std
::
runtime_error
(
"flac encoder process failed"
);
return
false
;
}
return
true
;
}
}
const
EncoderPlugin
flac_encoder_plugin
=
{
const
EncoderPlugin
flac_encoder_plugin
=
{
...
...
src/encoder/plugins/LameEncoderPlugin.cxx
View file @
d8b6aff2
...
@@ -25,11 +25,11 @@
...
@@ -25,11 +25,11 @@
#include "util/NumberParser.hxx"
#include "util/NumberParser.hxx"
#include "util/ReusableArray.hxx"
#include "util/ReusableArray.hxx"
#include "util/RuntimeError.hxx"
#include "util/RuntimeError.hxx"
#include "util/Error.hxx"
#include "util/Domain.hxx"
#include <lame/lame.h>
#include <lame/lame.h>
#include <stdexcept>
#include <assert.h>
#include <assert.h>
#include <string.h>
#include <string.h>
...
@@ -50,7 +50,7 @@ public:
...
@@ -50,7 +50,7 @@ public:
~
LameEncoder
()
override
;
~
LameEncoder
()
override
;
/* virtual methods from class Encoder */
/* virtual methods from class Encoder */
bool
Write
(
const
void
*
data
,
size_t
length
,
Error
&
)
override
;
void
Write
(
const
void
*
data
,
size_t
length
)
override
;
size_t
Read
(
void
*
dest
,
size_t
length
)
override
;
size_t
Read
(
void
*
dest
,
size_t
length
)
override
;
};
};
...
@@ -62,15 +62,13 @@ public:
...
@@ -62,15 +62,13 @@ public:
PreparedLameEncoder
(
const
ConfigBlock
&
block
);
PreparedLameEncoder
(
const
ConfigBlock
&
block
);
/* virtual methods from class PreparedEncoder */
/* virtual methods from class PreparedEncoder */
Encoder
*
Open
(
AudioFormat
&
audio_format
,
Error
&
)
override
;
Encoder
*
Open
(
AudioFormat
&
audio_format
)
override
;
const
char
*
GetMimeType
()
const
override
{
const
char
*
GetMimeType
()
const
override
{
return
"audio/mpeg"
;
return
"audio/mpeg"
;
}
}
};
};
static
constexpr
Domain
lame_encoder_domain
(
"lame_encoder"
);
PreparedLameEncoder
::
PreparedLameEncoder
(
const
ConfigBlock
&
block
)
PreparedLameEncoder
::
PreparedLameEncoder
(
const
ConfigBlock
&
block
)
{
{
const
char
*
value
;
const
char
*
value
;
...
@@ -110,76 +108,53 @@ lame_encoder_init(const ConfigBlock &block)
...
@@ -110,76 +108,53 @@ lame_encoder_init(const ConfigBlock &block)
return
new
PreparedLameEncoder
(
block
);
return
new
PreparedLameEncoder
(
block
);
}
}
static
bool
static
void
lame_encoder_setup
(
lame_global_flags
*
gfp
,
float
quality
,
int
bitrate
,
lame_encoder_setup
(
lame_global_flags
*
gfp
,
float
quality
,
int
bitrate
,
const
AudioFormat
&
audio_format
,
Error
&
error
)
const
AudioFormat
&
audio_format
)
{
{
if
(
quality
>=
-
1.0
)
{
if
(
quality
>=
-
1.0
)
{
/* a quality was configured (VBR) */
/* a quality was configured (VBR) */
if
(
0
!=
lame_set_VBR
(
gfp
,
vbr_rh
))
{
if
(
0
!=
lame_set_VBR
(
gfp
,
vbr_rh
))
error
.
Set
(
lame_encoder_domain
,
throw
std
::
runtime_error
(
"error setting lame VBR mode"
);
"error setting lame VBR mode"
);
return
false
;
if
(
0
!=
lame_set_VBR_q
(
gfp
,
quality
))
}
throw
std
::
runtime_error
(
"error setting lame VBR quality"
);
if
(
0
!=
lame_set_VBR_q
(
gfp
,
quality
))
{
error
.
Set
(
lame_encoder_domain
,
"error setting lame VBR quality"
);
return
false
;
}
}
else
{
}
else
{
/* a bit rate was configured */
/* a bit rate was configured */
if
(
0
!=
lame_set_brate
(
gfp
,
bitrate
))
{
if
(
0
!=
lame_set_brate
(
gfp
,
bitrate
))
error
.
Set
(
lame_encoder_domain
,
throw
std
::
runtime_error
(
"error setting lame bitrate"
);
"error setting lame bitrate"
);
return
false
;
}
}
}
if
(
0
!=
lame_set_num_channels
(
gfp
,
audio_format
.
channels
))
{
if
(
0
!=
lame_set_num_channels
(
gfp
,
audio_format
.
channels
))
error
.
Set
(
lame_encoder_domain
,
throw
std
::
runtime_error
(
"error setting lame num channels"
);
"error setting lame num channels"
);
return
false
;
}
if
(
0
!=
lame_set_in_samplerate
(
gfp
,
audio_format
.
sample_rate
))
{
if
(
0
!=
lame_set_in_samplerate
(
gfp
,
audio_format
.
sample_rate
))
error
.
Set
(
lame_encoder_domain
,
throw
std
::
runtime_error
(
"error setting lame sample rate"
);
"error setting lame sample rate"
);
return
false
;
}
if
(
0
!=
lame_set_out_samplerate
(
gfp
,
audio_format
.
sample_rate
))
{
error
.
Set
(
lame_encoder_domain
,
"error setting lame out sample rate"
);
return
false
;
}
if
(
0
>
lame_init_params
(
gfp
))
{
if
(
0
!=
lame_set_out_samplerate
(
gfp
,
audio_format
.
sample_rate
))
error
.
Set
(
lame_encoder_domain
,
throw
std
::
runtime_error
(
"error setting lame out sample rate"
);
"error initializing lame params"
);
return
false
;
}
return
true
;
if
(
0
>
lame_init_params
(
gfp
))
throw
std
::
runtime_error
(
"error initializing lame params"
);
}
}
Encoder
*
Encoder
*
PreparedLameEncoder
::
Open
(
AudioFormat
&
audio_format
,
Error
&
error
)
PreparedLameEncoder
::
Open
(
AudioFormat
&
audio_format
)
{
{
audio_format
.
format
=
SampleFormat
::
S16
;
audio_format
.
format
=
SampleFormat
::
S16
;
audio_format
.
channels
=
2
;
audio_format
.
channels
=
2
;
auto
gfp
=
lame_init
();
auto
gfp
=
lame_init
();
if
(
gfp
==
nullptr
)
{
if
(
gfp
==
nullptr
)
error
.
Set
(
lame_encoder_domain
,
"lame_init() failed"
);
throw
std
::
runtime_error
(
"lame_init() failed"
);
return
nullptr
;
}
if
(
!
lame_encoder_setup
(
gfp
,
quality
,
bitrate
,
try
{
audio_format
,
error
))
{
lame_encoder_setup
(
gfp
,
quality
,
bitrate
,
audio_format
);
}
catch
(...)
{
lame_close
(
gfp
);
lame_close
(
gfp
);
return
nullptr
;
throw
;
}
}
return
new
LameEncoder
(
audio_format
,
gfp
);
return
new
LameEncoder
(
audio_format
,
gfp
);
...
@@ -190,9 +165,8 @@ LameEncoder::~LameEncoder()
...
@@ -190,9 +165,8 @@ LameEncoder::~LameEncoder()
lame_close
(
gfp
);
lame_close
(
gfp
);
}
}
bool
void
LameEncoder
::
Write
(
const
void
*
data
,
size_t
length
,
LameEncoder
::
Write
(
const
void
*
data
,
size_t
length
)
gcc_unused
Error
&
error
)
{
{
const
int16_t
*
src
=
(
const
int16_t
*
)
data
;
const
int16_t
*
src
=
(
const
int16_t
*
)
data
;
...
@@ -212,14 +186,11 @@ LameEncoder::Write(const void *data, size_t length,
...
@@ -212,14 +186,11 @@ LameEncoder::Write(const void *data, size_t length,
num_frames
,
num_frames
,
dest
,
output_buffer_size
);
dest
,
output_buffer_size
);
if
(
bytes_out
<
0
)
{
if
(
bytes_out
<
0
)
error
.
Set
(
lame_encoder_domain
,
"lame encoder failed"
);
throw
std
::
runtime_error
(
"lame encoder failed"
);
return
false
;
}
output_begin
=
dest
;
output_begin
=
dest
;
output_end
=
dest
+
bytes_out
;
output_end
=
dest
+
bytes_out
;
return
true
;
}
}
size_t
size_t
...
...
src/encoder/plugins/NullEncoderPlugin.cxx
View file @
d8b6aff2
...
@@ -32,9 +32,8 @@ public:
...
@@ -32,9 +32,8 @@ public:
buffer
(
8192
)
{}
buffer
(
8192
)
{}
/* virtual methods from class Encoder */
/* virtual methods from class Encoder */
bool
Write
(
const
void
*
data
,
size_t
length
,
Error
&
)
override
{
void
Write
(
const
void
*
data
,
size_t
length
)
override
{
buffer
.
Append
((
const
uint8_t
*
)
data
,
length
);
buffer
.
Append
((
const
uint8_t
*
)
data
,
length
);
return
true
;
}
}
size_t
Read
(
void
*
dest
,
size_t
length
)
override
{
size_t
Read
(
void
*
dest
,
size_t
length
)
override
{
...
@@ -45,7 +44,7 @@ public:
...
@@ -45,7 +44,7 @@ public:
class
PreparedNullEncoder
final
:
public
PreparedEncoder
{
class
PreparedNullEncoder
final
:
public
PreparedEncoder
{
public
:
public
:
/* virtual methods from class PreparedEncoder */
/* virtual methods from class PreparedEncoder */
Encoder
*
Open
(
AudioFormat
&
,
Error
&
)
override
{
Encoder
*
Open
(
AudioFormat
&
)
override
{
return
new
NullEncoder
();
return
new
NullEncoder
();
}
}
};
};
...
...
src/encoder/plugins/OggEncoder.hxx
View file @
d8b6aff2
...
@@ -47,9 +47,8 @@ public:
...
@@ -47,9 +47,8 @@ public:
}
}
/* virtual methods from class Encoder */
/* virtual methods from class Encoder */
bool
Flush
(
Error
&
)
override
{
void
Flush
()
final
{
Flush
();
flush
=
true
;
return
true
;
}
}
size_t
Read
(
void
*
dest
,
size_t
length
)
override
{
size_t
Read
(
void
*
dest
,
size_t
length
)
override
{
...
@@ -67,11 +66,6 @@ public:
...
@@ -67,11 +66,6 @@ public:
return
ReadPage
(
page
,
dest
,
length
);
return
ReadPage
(
page
,
dest
,
length
);
}
}
protected
:
void
Flush
()
{
flush
=
true
;
}
};
};
#endif
#endif
src/encoder/plugins/OpusEncoderPlugin.cxx
View file @
d8b6aff2
...
@@ -23,8 +23,6 @@
...
@@ -23,8 +23,6 @@
#include "AudioFormat.hxx"
#include "AudioFormat.hxx"
#include "config/ConfigError.hxx"
#include "config/ConfigError.hxx"
#include "util/Alloc.hxx"
#include "util/Alloc.hxx"
#include "util/Error.hxx"
#include "util/Domain.hxx"
#include "system/ByteOrder.hxx"
#include "system/ByteOrder.hxx"
#include <opus.h>
#include <opus.h>
...
@@ -61,14 +59,14 @@ public:
...
@@ -61,14 +59,14 @@ public:
~
OpusEncoder
()
override
;
~
OpusEncoder
()
override
;
/* virtual methods from class Encoder */
/* virtual methods from class Encoder */
bool
End
(
Error
&
)
override
;
void
End
(
)
override
;
bool
Write
(
const
void
*
data
,
size_t
length
,
Error
&
)
override
;
void
Write
(
const
void
*
data
,
size_t
length
)
override
;
size_t
Read
(
void
*
dest
,
size_t
length
)
override
;
size_t
Read
(
void
*
dest
,
size_t
length
)
override
;
private
:
private
:
bool
DoEncode
(
bool
eos
,
Error
&
error
);
void
DoEncode
(
bool
eos
);
bool
WriteSilence
(
unsigned
fill_frames
,
Error
&
error
);
void
WriteSilence
(
unsigned
fill_frames
);
void
GenerateHead
();
void
GenerateHead
();
void
GenerateTags
();
void
GenerateTags
();
...
@@ -83,15 +81,13 @@ public:
...
@@ -83,15 +81,13 @@ public:
PreparedOpusEncoder
(
const
ConfigBlock
&
block
);
PreparedOpusEncoder
(
const
ConfigBlock
&
block
);
/* virtual methods from class PreparedEncoder */
/* virtual methods from class PreparedEncoder */
Encoder
*
Open
(
AudioFormat
&
audio_format
,
Error
&
)
override
;
Encoder
*
Open
(
AudioFormat
&
audio_format
)
override
;
const
char
*
GetMimeType
()
const
override
{
const
char
*
GetMimeType
()
const
override
{
return
"audio/ogg"
;
return
"audio/ogg"
;
}
}
};
};
static
constexpr
Domain
opus_encoder_domain
(
"opus_encoder"
);
PreparedOpusEncoder
::
PreparedOpusEncoder
(
const
ConfigBlock
&
block
)
PreparedOpusEncoder
::
PreparedOpusEncoder
(
const
ConfigBlock
&
block
)
{
{
const
char
*
value
=
block
.
GetBlockValue
(
"bitrate"
,
"auto"
);
const
char
*
value
=
block
.
GetBlockValue
(
"bitrate"
,
"auto"
);
...
@@ -141,7 +137,7 @@ OpusEncoder::OpusEncoder(AudioFormat &_audio_format, ::OpusEncoder *_enc)
...
@@ -141,7 +137,7 @@ OpusEncoder::OpusEncoder(AudioFormat &_audio_format, ::OpusEncoder *_enc)
}
}
Encoder
*
Encoder
*
PreparedOpusEncoder
::
Open
(
AudioFormat
&
audio_format
,
Error
&
error
)
PreparedOpusEncoder
::
Open
(
AudioFormat
&
audio_format
)
{
{
/* libopus supports only 48 kHz */
/* libopus supports only 48 kHz */
audio_format
.
sample_rate
=
48000
;
audio_format
.
sample_rate
=
48000
;
...
@@ -168,11 +164,8 @@ PreparedOpusEncoder::Open(AudioFormat &audio_format, Error &error)
...
@@ -168,11 +164,8 @@ PreparedOpusEncoder::Open(AudioFormat &audio_format, Error &error)
audio_format
.
channels
,
audio_format
.
channels
,
OPUS_APPLICATION_AUDIO
,
OPUS_APPLICATION_AUDIO
,
&
error_code
);
&
error_code
);
if
(
enc
==
nullptr
)
{
if
(
enc
==
nullptr
)
error
.
Set
(
opus_encoder_domain
,
error_code
,
throw
std
::
runtime_error
(
opus_strerror
(
error_code
));
opus_strerror
(
error_code
));
return
nullptr
;
}
opus_encoder_ctl
(
enc
,
OPUS_SET_BITRATE
(
bitrate
));
opus_encoder_ctl
(
enc
,
OPUS_SET_BITRATE
(
bitrate
));
opus_encoder_ctl
(
enc
,
OPUS_SET_COMPLEXITY
(
complexity
));
opus_encoder_ctl
(
enc
,
OPUS_SET_COMPLEXITY
(
complexity
));
...
@@ -187,8 +180,8 @@ OpusEncoder::~OpusEncoder()
...
@@ -187,8 +180,8 @@ OpusEncoder::~OpusEncoder()
opus_encoder_destroy
(
enc
);
opus_encoder_destroy
(
enc
);
}
}
bool
void
OpusEncoder
::
DoEncode
(
bool
eos
,
Error
&
error
)
OpusEncoder
::
DoEncode
(
bool
eos
)
{
{
assert
(
buffer_position
==
buffer_size
);
assert
(
buffer_position
==
buffer_size
);
...
@@ -204,10 +197,8 @@ OpusEncoder::DoEncode(bool eos, Error &error)
...
@@ -204,10 +197,8 @@ OpusEncoder::DoEncode(bool eos, Error &error)
buffer_frames
,
buffer_frames
,
buffer2
,
buffer2
,
sizeof
(
buffer2
));
sizeof
(
buffer2
));
if
(
result
<
0
)
{
if
(
result
<
0
)
error
.
Set
(
opus_encoder_domain
,
"Opus encoder error"
);
throw
std
::
runtime_error
(
"Opus encoder error"
);
return
false
;
}
granulepos
+=
buffer_frames
;
granulepos
+=
buffer_frames
;
...
@@ -221,12 +212,10 @@ OpusEncoder::DoEncode(bool eos, Error &error)
...
@@ -221,12 +212,10 @@ OpusEncoder::DoEncode(bool eos, Error &error)
stream
.
PacketIn
(
packet
);
stream
.
PacketIn
(
packet
);
buffer_position
=
0
;
buffer_position
=
0
;
return
true
;
}
}
bool
void
OpusEncoder
::
End
(
Error
&
error
)
OpusEncoder
::
End
()
{
{
Flush
();
Flush
();
...
@@ -234,11 +223,11 @@ OpusEncoder::End(Error &error)
...
@@ -234,11 +223,11 @@ OpusEncoder::End(Error &error)
buffer_size
-
buffer_position
);
buffer_size
-
buffer_position
);
buffer_position
=
buffer_size
;
buffer_position
=
buffer_size
;
return
DoEncode
(
true
,
error
);
DoEncode
(
true
);
}
}
bool
void
OpusEncoder
::
WriteSilence
(
unsigned
fill_frames
,
Error
&
error
)
OpusEncoder
::
WriteSilence
(
unsigned
fill_frames
)
{
{
size_t
fill_bytes
=
fill_frames
*
frame_size
;
size_t
fill_bytes
=
fill_frames
*
frame_size
;
...
@@ -251,16 +240,13 @@ OpusEncoder::WriteSilence(unsigned fill_frames, Error &error)
...
@@ -251,16 +240,13 @@ OpusEncoder::WriteSilence(unsigned fill_frames, Error &error)
buffer_position
+=
nbytes
;
buffer_position
+=
nbytes
;
fill_bytes
-=
nbytes
;
fill_bytes
-=
nbytes
;
if
(
buffer_position
==
buffer_size
&&
if
(
buffer_position
==
buffer_size
)
!
DoEncode
(
false
,
error
))
DoEncode
(
false
);
return
false
;
}
}
return
true
;
}
}
bool
void
OpusEncoder
::
Write
(
const
void
*
_data
,
size_t
length
,
Error
&
error
)
OpusEncoder
::
Write
(
const
void
*
_data
,
size_t
length
)
{
{
const
uint8_t
*
data
=
(
const
uint8_t
*
)
_data
;
const
uint8_t
*
data
=
(
const
uint8_t
*
)
_data
;
...
@@ -270,9 +256,7 @@ OpusEncoder::Write(const void *_data, size_t length, Error &error)
...
@@ -270,9 +256,7 @@ OpusEncoder::Write(const void *_data, size_t length, Error &error)
assert
(
buffer_position
==
0
);
assert
(
buffer_position
==
0
);
if
(
!
WriteSilence
(
lookahead
,
error
))
WriteSilence
(
lookahead
);
return
false
;
lookahead
=
0
;
lookahead
=
0
;
}
}
...
@@ -286,12 +270,9 @@ OpusEncoder::Write(const void *_data, size_t length, Error &error)
...
@@ -286,12 +270,9 @@ OpusEncoder::Write(const void *_data, size_t length, Error &error)
length
-=
nbytes
;
length
-=
nbytes
;
buffer_position
+=
nbytes
;
buffer_position
+=
nbytes
;
if
(
buffer_position
==
buffer_size
&&
if
(
buffer_position
==
buffer_size
)
!
DoEncode
(
false
,
error
))
DoEncode
(
false
);
return
false
;
}
}
return
true
;
}
}
void
void
...
...
src/encoder/plugins/ShineEncoderPlugin.cxx
View file @
d8b6aff2
...
@@ -23,7 +23,7 @@
...
@@ -23,7 +23,7 @@
#include "AudioFormat.hxx"
#include "AudioFormat.hxx"
#include "config/ConfigError.hxx"
#include "config/ConfigError.hxx"
#include "util/DynamicFifoBuffer.hxx"
#include "util/DynamicFifoBuffer.hxx"
#include "util/Error.hxx"
#include "util/
Runtime
Error.hxx"
extern
"C"
extern
"C"
{
{
...
@@ -71,13 +71,13 @@ public:
...
@@ -71,13 +71,13 @@ public:
bool
WriteChunk
(
bool
flush
);
bool
WriteChunk
(
bool
flush
);
/* virtual methods from class Encoder */
/* virtual methods from class Encoder */
bool
End
(
Error
&
error
)
override
{
void
End
(
)
override
{
return
Flush
(
error
);
return
Flush
();
}
}
bool
Flush
(
Error
&
)
override
;
void
Flush
(
)
override
;
bool
Write
(
const
void
*
data
,
size_t
length
,
Error
&
)
override
;
void
Write
(
const
void
*
data
,
size_t
length
)
override
;
size_t
Read
(
void
*
dest
,
size_t
length
)
override
{
size_t
Read
(
void
*
dest
,
size_t
length
)
override
{
return
output_buffer
.
Read
((
uint8_t
*
)
dest
,
length
);
return
output_buffer
.
Read
((
uint8_t
*
)
dest
,
length
);
...
@@ -91,7 +91,7 @@ public:
...
@@ -91,7 +91,7 @@ public:
PreparedShineEncoder
(
const
ConfigBlock
&
block
);
PreparedShineEncoder
(
const
ConfigBlock
&
block
);
/* virtual methods from class PreparedEncoder */
/* virtual methods from class PreparedEncoder */
Encoder
*
Open
(
AudioFormat
&
audio_format
,
Error
&
)
override
;
Encoder
*
Open
(
AudioFormat
&
audio_format
)
override
;
const
char
*
GetMimeType
()
const
override
{
const
char
*
GetMimeType
()
const
override
{
return
"audio/mpeg"
;
return
"audio/mpeg"
;
...
@@ -111,8 +111,7 @@ shine_encoder_init(const ConfigBlock &block)
...
@@ -111,8 +111,7 @@ shine_encoder_init(const ConfigBlock &block)
}
}
static
shine_t
static
shine_t
SetupShine
(
shine_config_t
config
,
AudioFormat
&
audio_format
,
SetupShine
(
shine_config_t
config
,
AudioFormat
&
audio_format
)
Error
&
error
)
{
{
audio_format
.
format
=
SampleFormat
::
S16
;
audio_format
.
format
=
SampleFormat
::
S16
;
audio_format
.
channels
=
CHANNELS
;
audio_format
.
channels
=
CHANNELS
;
...
@@ -122,32 +121,24 @@ SetupShine(shine_config_t config, AudioFormat &audio_format,
...
@@ -122,32 +121,24 @@ SetupShine(shine_config_t config, AudioFormat &audio_format,
config
.
wave
.
channels
=
config
.
wave
.
channels
=
audio_format
.
channels
==
2
?
PCM_STEREO
:
PCM_MONO
;
audio_format
.
channels
==
2
?
PCM_STEREO
:
PCM_MONO
;
if
(
shine_check_config
(
config
.
wave
.
samplerate
,
config
.
mpeg
.
bitr
)
<
0
)
{
if
(
shine_check_config
(
config
.
wave
.
samplerate
,
config
.
mpeg
.
bitr
)
<
0
)
error
.
Format
(
config_domain
,
throw
FormatRuntimeError
(
"error configuring shine. "
"error configuring shine. "
"samplerate %d and bitrate %d configuration"
"samplerate %d and bitrate %d configuration"
" not supported."
,
" not supported."
,
config
.
wave
.
samplerate
,
config
.
wave
.
samplerate
,
config
.
mpeg
.
bitr
);
config
.
mpeg
.
bitr
);
return
nullptr
;
}
auto
shine
=
shine_initialise
(
&
config
);
auto
shine
=
shine_initialise
(
&
config
);
if
(
!
shine
)
if
(
!
shine
)
error
.
Format
(
config_domain
,
throw
std
::
runtime_error
(
"error initializing shine"
);
"error initializing shine."
);
return
shine
;
return
shine
;
}
}
Encoder
*
Encoder
*
PreparedShineEncoder
::
Open
(
AudioFormat
&
audio_format
,
Error
&
error
)
PreparedShineEncoder
::
Open
(
AudioFormat
&
audio_format
)
{
{
auto
shine
=
SetupShine
(
config
,
audio_format
,
error
);
auto
shine
=
SetupShine
(
config
,
audio_format
);
if
(
!
shine
)
return
nullptr
;
return
new
ShineEncoder
(
audio_format
,
shine
);
return
new
ShineEncoder
(
audio_format
,
shine
);
}
}
...
@@ -175,8 +166,8 @@ ShineEncoder::WriteChunk(bool flush)
...
@@ -175,8 +166,8 @@ ShineEncoder::WriteChunk(bool flush)
return
true
;
return
true
;
}
}
bool
void
ShineEncoder
::
Write
(
const
void
*
_data
,
size_t
length
,
gcc_unused
Error
&
error
)
ShineEncoder
::
Write
(
const
void
*
_data
,
size_t
length
)
{
{
const
int16_t
*
data
=
(
const
int16_t
*
)
_data
;
const
int16_t
*
data
=
(
const
int16_t
*
)
_data
;
length
/=
sizeof
(
*
data
)
*
audio_format
.
channels
;
length
/=
sizeof
(
*
data
)
*
audio_format
.
channels
;
...
@@ -198,12 +189,10 @@ ShineEncoder::Write(const void *_data, size_t length, gcc_unused Error &error)
...
@@ -198,12 +189,10 @@ ShineEncoder::Write(const void *_data, size_t length, gcc_unused Error &error)
/* write if chunk is filled */
/* write if chunk is filled */
WriteChunk
(
false
);
WriteChunk
(
false
);
}
}
return
true
;
}
}
bool
void
ShineEncoder
::
Flush
(
gcc_unused
Error
&
error
)
ShineEncoder
::
Flush
()
{
{
/* flush buffers and flush shine */
/* flush buffers and flush shine */
WriteChunk
(
true
);
WriteChunk
(
true
);
...
@@ -213,8 +202,6 @@ ShineEncoder::Flush(gcc_unused Error &error)
...
@@ -213,8 +202,6 @@ ShineEncoder::Flush(gcc_unused Error &error)
if
(
written
>
0
)
if
(
written
>
0
)
output_buffer
.
Append
(
data
,
written
);
output_buffer
.
Append
(
data
,
written
);
return
true
;
}
}
const
EncoderPlugin
shine_encoder_plugin
=
{
const
EncoderPlugin
shine_encoder_plugin
=
{
...
...
src/encoder/plugins/TwolameEncoderPlugin.cxx
View file @
d8b6aff2
...
@@ -24,12 +24,13 @@
...
@@ -24,12 +24,13 @@
#include "config/ConfigError.hxx"
#include "config/ConfigError.hxx"
#include "util/NumberParser.hxx"
#include "util/NumberParser.hxx"
#include "util/RuntimeError.hxx"
#include "util/RuntimeError.hxx"
#include "util/Error.hxx"
#include "util/Domain.hxx"
#include "util/Domain.hxx"
#include "Log.hxx"
#include "Log.hxx"
#include <twolame.h>
#include <twolame.h>
#include <stdexcept>
#include <assert.h>
#include <assert.h>
#include <string.h>
#include <string.h>
...
@@ -59,17 +60,15 @@ public:
...
@@ -59,17 +60,15 @@ public:
/* virtual methods from class Encoder */
/* virtual methods from class Encoder */
bool
End
(
Error
&
)
override
{
void
End
(
)
override
{
flush
=
true
;
flush
=
true
;
return
true
;
}
}
bool
Flush
(
Error
&
)
override
{
void
Flush
(
)
override
{
flush
=
true
;
flush
=
true
;
return
true
;
}
}
bool
Write
(
const
void
*
data
,
size_t
length
,
Error
&
)
override
;
void
Write
(
const
void
*
data
,
size_t
length
)
override
;
size_t
Read
(
void
*
dest
,
size_t
length
)
override
;
size_t
Read
(
void
*
dest
,
size_t
length
)
override
;
};
};
...
@@ -81,7 +80,7 @@ public:
...
@@ -81,7 +80,7 @@ public:
PreparedTwolameEncoder
(
const
ConfigBlock
&
block
);
PreparedTwolameEncoder
(
const
ConfigBlock
&
block
);
/* virtual methods from class PreparedEncoder */
/* virtual methods from class PreparedEncoder */
Encoder
*
Open
(
AudioFormat
&
audio_format
,
Error
&
)
override
;
Encoder
*
Open
(
AudioFormat
&
audio_format
)
override
;
const
char
*
GetMimeType
()
const
override
{
const
char
*
GetMimeType
()
const
override
{
return
"audio/mpeg"
;
return
"audio/mpeg"
;
...
@@ -132,71 +131,52 @@ twolame_encoder_init(const ConfigBlock &block)
...
@@ -132,71 +131,52 @@ twolame_encoder_init(const ConfigBlock &block)
return
new
PreparedTwolameEncoder
(
block
);
return
new
PreparedTwolameEncoder
(
block
);
}
}
static
bool
static
void
twolame_encoder_setup
(
twolame_options
*
options
,
float
quality
,
int
bitrate
,
twolame_encoder_setup
(
twolame_options
*
options
,
float
quality
,
int
bitrate
,
const
AudioFormat
&
audio_format
,
Error
&
error
)
const
AudioFormat
&
audio_format
)
{
{
if
(
quality
>=
-
1.0
)
{
if
(
quality
>=
-
1.0
)
{
/* a quality was configured (VBR) */
/* a quality was configured (VBR) */
if
(
0
!=
twolame_set_VBR
(
options
,
true
))
{
if
(
0
!=
twolame_set_VBR
(
options
,
true
))
error
.
Set
(
twolame_encoder_domain
,
throw
std
::
runtime_error
(
"error setting twolame VBR mode"
);
"error setting twolame VBR mode"
);
return
false
;
if
(
0
!=
twolame_set_VBR_q
(
options
,
quality
))
}
throw
std
::
runtime_error
(
"error setting twolame VBR quality"
);
if
(
0
!=
twolame_set_VBR_q
(
options
,
quality
))
{
error
.
Set
(
twolame_encoder_domain
,
"error setting twolame VBR quality"
);
return
false
;
}
}
else
{
}
else
{
/* a bit rate was configured */
/* a bit rate was configured */
if
(
0
!=
twolame_set_brate
(
options
,
bitrate
))
{
if
(
0
!=
twolame_set_brate
(
options
,
bitrate
))
error
.
Set
(
twolame_encoder_domain
,
throw
std
::
runtime_error
(
"error setting twolame bitrate"
);
"error setting twolame bitrate"
);
return
false
;
}
}
}
if
(
0
!=
twolame_set_num_channels
(
options
,
audio_format
.
channels
))
{
if
(
0
!=
twolame_set_num_channels
(
options
,
audio_format
.
channels
))
error
.
Set
(
twolame_encoder_domain
,
throw
std
::
runtime_error
(
"error setting twolame num channels"
);
"error setting twolame num channels"
);
return
false
;
}
if
(
0
!=
twolame_set_in_samplerate
(
options
,
if
(
0
!=
twolame_set_in_samplerate
(
options
,
audio_format
.
sample_rate
))
{
audio_format
.
sample_rate
))
error
.
Set
(
twolame_encoder_domain
,
throw
std
::
runtime_error
(
"error setting twolame sample rate"
);
"error setting twolame sample rate"
);
return
false
;
}
if
(
0
>
twolame_init_params
(
options
))
{
error
.
Set
(
twolame_encoder_domain
,
"error initializing twolame params"
);
return
false
;
}
return
true
;
if
(
0
>
twolame_init_params
(
options
))
throw
std
::
runtime_error
(
"error initializing twolame params"
);
}
}
Encoder
*
Encoder
*
PreparedTwolameEncoder
::
Open
(
AudioFormat
&
audio_format
,
Error
&
error
)
PreparedTwolameEncoder
::
Open
(
AudioFormat
&
audio_format
)
{
{
audio_format
.
format
=
SampleFormat
::
S16
;
audio_format
.
format
=
SampleFormat
::
S16
;
audio_format
.
channels
=
2
;
audio_format
.
channels
=
2
;
auto
options
=
twolame_init
();
auto
options
=
twolame_init
();
if
(
options
==
nullptr
)
{
if
(
options
==
nullptr
)
error
.
Set
(
twolame_encoder_domain
,
"twolame_init() failed"
);
throw
std
::
runtime_error
(
"twolame_init() failed"
);
return
nullptr
;
}
if
(
!
twolame_encoder_setup
(
options
,
quality
,
bitrate
,
try
{
audio_format
,
error
))
{
twolame_encoder_setup
(
options
,
quality
,
bitrate
,
audio_format
);
}
catch
(...)
{
twolame_close
(
&
options
);
twolame_close
(
&
options
);
return
nullptr
;
throw
;
}
}
return
new
TwolameEncoder
(
audio_format
,
options
);
return
new
TwolameEncoder
(
audio_format
,
options
);
...
@@ -207,9 +187,8 @@ TwolameEncoder::~TwolameEncoder()
...
@@ -207,9 +187,8 @@ TwolameEncoder::~TwolameEncoder()
twolame_close
(
&
options
);
twolame_close
(
&
options
);
}
}
bool
void
TwolameEncoder
::
Write
(
const
void
*
data
,
size_t
length
,
TwolameEncoder
::
Write
(
const
void
*
data
,
size_t
length
)
gcc_unused
Error
&
error
)
{
{
const
int16_t
*
src
=
(
const
int16_t
*
)
data
;
const
int16_t
*
src
=
(
const
int16_t
*
)
data
;
...
@@ -221,14 +200,11 @@ TwolameEncoder::Write(const void *data, size_t length,
...
@@ -221,14 +200,11 @@ TwolameEncoder::Write(const void *data, size_t length,
src
,
num_frames
,
src
,
num_frames
,
output_buffer
,
output_buffer
,
sizeof
(
output_buffer
));
sizeof
(
output_buffer
));
if
(
bytes_out
<
0
)
{
if
(
bytes_out
<
0
)
error
.
Set
(
twolame_encoder_domain
,
"twolame encoder failed"
);
throw
std
::
runtime_error
(
"twolame encoder failed"
);
return
false
;
}
output_buffer_length
=
(
size_t
)
bytes_out
;
output_buffer_length
=
(
size_t
)
bytes_out
;
output_buffer_position
=
0
;
output_buffer_position
=
0
;
return
true
;
}
}
size_t
size_t
...
...
src/encoder/plugins/VorbisEncoderPlugin.cxx
View file @
d8b6aff2
...
@@ -26,8 +26,6 @@
...
@@ -26,8 +26,6 @@
#include "util/StringUtil.hxx"
#include "util/StringUtil.hxx"
#include "util/NumberParser.hxx"
#include "util/NumberParser.hxx"
#include "util/RuntimeError.hxx"
#include "util/RuntimeError.hxx"
#include "util/Error.hxx"
#include "util/Domain.hxx"
#include <vorbis/vorbisenc.h>
#include <vorbis/vorbisenc.h>
...
@@ -39,10 +37,7 @@ class VorbisEncoder final : public OggEncoder {
...
@@ -39,10 +37,7 @@ class VorbisEncoder final : public OggEncoder {
vorbis_info
vi
;
vorbis_info
vi
;
public
:
public
:
VorbisEncoder
()
VorbisEncoder
(
float
quality
,
int
bitrate
,
AudioFormat
&
_audio_format
);
:
OggEncoder
(
true
)
{
vorbis_info_init
(
&
vi
);
}
virtual
~
VorbisEncoder
()
{
virtual
~
VorbisEncoder
()
{
vorbis_block_clear
(
&
vb
);
vorbis_block_clear
(
&
vb
);
...
@@ -50,18 +45,15 @@ public:
...
@@ -50,18 +45,15 @@ public:
vorbis_info_clear
(
&
vi
);
vorbis_info_clear
(
&
vi
);
}
}
bool
Open
(
float
quality
,
int
bitrate
,
AudioFormat
&
audio_format
,
Error
&
error
);
/* virtual methods from class Encoder */
/* virtual methods from class Encoder */
bool
End
(
Error
&
error
)
override
{
void
End
(
)
override
{
return
PreTag
(
error
);
PreTag
(
);
}
}
bool
PreTag
(
Error
&
error
)
override
;
void
PreTag
(
)
override
;
bool
SendTag
(
const
Tag
&
tag
,
Error
&
error
)
override
;
void
SendTag
(
const
Tag
&
tag
)
override
;
bool
Write
(
const
void
*
data
,
size_t
length
,
Error
&
)
override
;
void
Write
(
const
void
*
data
,
size_t
length
)
override
;
private
:
private
:
void
HeaderOut
(
vorbis_comment
&
vc
);
void
HeaderOut
(
vorbis_comment
&
vc
);
...
@@ -77,15 +69,13 @@ public:
...
@@ -77,15 +69,13 @@ public:
PreparedVorbisEncoder
(
const
ConfigBlock
&
block
);
PreparedVorbisEncoder
(
const
ConfigBlock
&
block
);
/* virtual methods from class PreparedEncoder */
/* virtual methods from class PreparedEncoder */
Encoder
*
Open
(
AudioFormat
&
audio_format
,
Error
&
)
override
;
Encoder
*
Open
(
AudioFormat
&
audio_format
)
override
;
const
char
*
GetMimeType
()
const
override
{
const
char
*
GetMimeType
()
const
override
{
return
"audio/ogg"
;
return
"audio/ogg"
;
}
}
};
};
static
constexpr
Domain
vorbis_encoder_domain
(
"vorbis_encoder"
);
PreparedVorbisEncoder
::
PreparedVorbisEncoder
(
const
ConfigBlock
&
block
)
PreparedVorbisEncoder
::
PreparedVorbisEncoder
(
const
ConfigBlock
&
block
)
{
{
const
char
*
value
=
block
.
GetBlockValue
(
"quality"
);
const
char
*
value
=
block
.
GetBlockValue
(
"quality"
);
...
@@ -124,10 +114,12 @@ vorbis_encoder_init(const ConfigBlock &block)
...
@@ -124,10 +114,12 @@ vorbis_encoder_init(const ConfigBlock &block)
return
new
PreparedVorbisEncoder
(
block
);
return
new
PreparedVorbisEncoder
(
block
);
}
}
bool
VorbisEncoder
::
VorbisEncoder
(
float
quality
,
int
bitrate
,
VorbisEncoder
::
Open
(
float
quality
,
int
bitrate
,
AudioFormat
&
_audio_format
,
AudioFormat
&
_audio_format
)
Error
&
error
)
:
OggEncoder
(
true
)
{
{
vorbis_info_init
(
&
vi
);
_audio_format
.
format
=
SampleFormat
::
FLOAT
;
_audio_format
.
format
=
SampleFormat
::
FLOAT
;
audio_format
=
_audio_format
;
audio_format
=
_audio_format
;
...
@@ -138,9 +130,8 @@ VorbisEncoder::Open(float quality, int bitrate, AudioFormat &_audio_format,
...
@@ -138,9 +130,8 @@ VorbisEncoder::Open(float quality, int bitrate, AudioFormat &_audio_format,
audio_format
.
channels
,
audio_format
.
channels
,
audio_format
.
sample_rate
,
audio_format
.
sample_rate
,
quality
*
0.1
))
{
quality
*
0.1
))
{
error
.
Set
(
vorbis_encoder_domain
,
vorbis_info_clear
(
&
vi
);
"error initializing vorbis vbr"
);
throw
std
::
runtime_error
(
"error initializing vorbis vbr"
);
return
false
;
}
}
}
else
{
}
else
{
/* a bit rate was configured */
/* a bit rate was configured */
...
@@ -149,9 +140,8 @@ VorbisEncoder::Open(float quality, int bitrate, AudioFormat &_audio_format,
...
@@ -149,9 +140,8 @@ VorbisEncoder::Open(float quality, int bitrate, AudioFormat &_audio_format,
audio_format
.
channels
,
audio_format
.
channels
,
audio_format
.
sample_rate
,
-
1.0
,
audio_format
.
sample_rate
,
-
1.0
,
bitrate
*
1000
,
-
1.0
))
{
bitrate
*
1000
,
-
1.0
))
{
error
.
Set
(
vorbis_encoder_domain
,
vorbis_info_clear
(
&
vi
);
"error initializing vorbis encoder"
);
throw
std
::
runtime_error
(
"error initializing vorbis encoder"
);
return
false
;
}
}
}
}
...
@@ -159,8 +149,6 @@ VorbisEncoder::Open(float quality, int bitrate, AudioFormat &_audio_format,
...
@@ -159,8 +149,6 @@ VorbisEncoder::Open(float quality, int bitrate, AudioFormat &_audio_format,
vorbis_block_init
(
&
vd
,
&
vb
);
vorbis_block_init
(
&
vd
,
&
vb
);
SendHeader
();
SendHeader
();
return
true
;
}
}
void
void
...
@@ -184,15 +172,9 @@ VorbisEncoder::SendHeader()
...
@@ -184,15 +172,9 @@ VorbisEncoder::SendHeader()
}
}
Encoder
*
Encoder
*
PreparedVorbisEncoder
::
Open
(
AudioFormat
&
audio_format
,
Error
&
error
)
PreparedVorbisEncoder
::
Open
(
AudioFormat
&
audio_format
)
{
{
auto
*
e
=
new
VorbisEncoder
();
return
new
VorbisEncoder
(
quality
,
bitrate
,
audio_format
);
if
(
!
e
->
Open
(
quality
,
bitrate
,
audio_format
,
error
))
{
delete
e
;
return
nullptr
;
}
return
e
;
}
}
void
void
...
@@ -208,8 +190,8 @@ VorbisEncoder::BlockOut()
...
@@ -208,8 +190,8 @@ VorbisEncoder::BlockOut()
}
}
}
}
bool
void
VorbisEncoder
::
PreTag
(
gcc_unused
Error
&
error
)
VorbisEncoder
::
PreTag
()
{
{
vorbis_analysis_wrote
(
&
vd
,
0
);
vorbis_analysis_wrote
(
&
vd
,
0
);
BlockOut
();
BlockOut
();
...
@@ -222,7 +204,6 @@ VorbisEncoder::PreTag(gcc_unused Error &error)
...
@@ -222,7 +204,6 @@ VorbisEncoder::PreTag(gcc_unused Error &error)
vorbis_block_init
(
&
vd
,
&
vb
);
vorbis_block_init
(
&
vd
,
&
vb
);
Flush
();
Flush
();
return
true
;
}
}
static
void
static
void
...
@@ -235,8 +216,8 @@ copy_tag_to_vorbis_comment(VorbisComment &vc, const Tag &tag)
...
@@ -235,8 +216,8 @@ copy_tag_to_vorbis_comment(VorbisComment &vc, const Tag &tag)
}
}
}
}
bool
void
VorbisEncoder
::
SendTag
(
const
Tag
&
tag
,
gcc_unused
Error
&
error
)
VorbisEncoder
::
SendTag
(
const
Tag
&
tag
)
{
{
/* write the vorbis_comment object */
/* write the vorbis_comment object */
...
@@ -250,8 +231,6 @@ VorbisEncoder::SendTag(const Tag &tag, gcc_unused Error &error)
...
@@ -250,8 +231,6 @@ VorbisEncoder::SendTag(const Tag &tag, gcc_unused Error &error)
/* send that vorbis_comment to the ogg_stream_state */
/* send that vorbis_comment to the ogg_stream_state */
HeaderOut
(
comment
);
HeaderOut
(
comment
);
return
true
;
}
}
static
void
static
void
...
@@ -263,8 +242,8 @@ interleaved_to_vorbis_buffer(float **dest, const float *src,
...
@@ -263,8 +242,8 @@ interleaved_to_vorbis_buffer(float **dest, const float *src,
dest
[
j
][
i
]
=
*
src
++
;
dest
[
j
][
i
]
=
*
src
++
;
}
}
bool
void
VorbisEncoder
::
Write
(
const
void
*
data
,
size_t
length
,
gcc_unused
Error
&
error
)
VorbisEncoder
::
Write
(
const
void
*
data
,
size_t
length
)
{
{
unsigned
num_frames
=
length
/
audio_format
.
GetFrameSize
();
unsigned
num_frames
=
length
/
audio_format
.
GetFrameSize
();
...
@@ -277,7 +256,6 @@ VorbisEncoder::Write(const void *data, size_t length, gcc_unused Error &error)
...
@@ -277,7 +256,6 @@ VorbisEncoder::Write(const void *data, size_t length, gcc_unused Error &error)
vorbis_analysis_wrote
(
&
vd
,
num_frames
);
vorbis_analysis_wrote
(
&
vd
,
num_frames
);
BlockOut
();
BlockOut
();
return
true
;
}
}
const
EncoderPlugin
vorbis_encoder_plugin
=
{
const
EncoderPlugin
vorbis_encoder_plugin
=
{
...
...
src/encoder/plugins/WaveEncoderPlugin.cxx
View file @
d8b6aff2
...
@@ -37,7 +37,7 @@ public:
...
@@ -37,7 +37,7 @@ public:
WaveEncoder
(
AudioFormat
&
audio_format
);
WaveEncoder
(
AudioFormat
&
audio_format
);
/* virtual methods from class Encoder */
/* virtual methods from class Encoder */
bool
Write
(
const
void
*
data
,
size_t
length
,
Error
&
)
override
;
void
Write
(
const
void
*
data
,
size_t
length
)
override
;
size_t
Read
(
void
*
dest
,
size_t
length
)
override
{
size_t
Read
(
void
*
dest
,
size_t
length
)
override
{
return
buffer
.
Read
((
uint8_t
*
)
dest
,
length
);
return
buffer
.
Read
((
uint8_t
*
)
dest
,
length
);
...
@@ -46,7 +46,7 @@ public:
...
@@ -46,7 +46,7 @@ public:
class
PreparedWaveEncoder
final
:
public
PreparedEncoder
{
class
PreparedWaveEncoder
final
:
public
PreparedEncoder
{
/* virtual methods from class PreparedEncoder */
/* virtual methods from class PreparedEncoder */
Encoder
*
Open
(
AudioFormat
&
audio_format
,
Error
&
)
override
{
Encoder
*
Open
(
AudioFormat
&
audio_format
)
override
{
return
new
WaveEncoder
(
audio_format
);
return
new
WaveEncoder
(
audio_format
);
}
}
...
@@ -186,9 +186,8 @@ pcm24_to_wave(uint8_t *dst8, const uint32_t *src32, size_t length)
...
@@ -186,9 +186,8 @@ pcm24_to_wave(uint8_t *dst8, const uint32_t *src32, size_t length)
return
(
dst8
-
dst_old
);
return
(
dst8
-
dst_old
);
}
}
bool
void
WaveEncoder
::
Write
(
const
void
*
src
,
size_t
length
,
WaveEncoder
::
Write
(
const
void
*
src
,
size_t
length
)
gcc_unused
Error
&
error
)
{
{
uint8_t
*
dst
=
buffer
.
Write
(
length
);
uint8_t
*
dst
=
buffer
.
Write
(
length
);
...
@@ -223,7 +222,6 @@ WaveEncoder::Write(const void *src, size_t length,
...
@@ -223,7 +222,6 @@ WaveEncoder::Write(const void *src, size_t length,
}
}
buffer
.
Append
(
length
);
buffer
.
Append
(
length
);
return
true
;
}
}
const
EncoderPlugin
wave_encoder_plugin
=
{
const
EncoderPlugin
wave_encoder_plugin
=
{
...
...
src/output/plugins/RecorderOutputPlugin.cxx
View file @
d8b6aff2
...
@@ -110,8 +110,10 @@ private:
...
@@ -110,8 +110,10 @@ private:
/**
/**
* Finish the encoder and commit the file.
* Finish the encoder and commit the file.
*
* Throws #std::runtime_error on error.
*/
*/
bool
Commit
(
Error
&
error
);
void
Commit
(
);
void
FinishFormat
();
void
FinishFormat
();
bool
ReopenFormat
(
AllocatedPath
&&
new_path
,
Error
&
error
);
bool
ReopenFormat
(
AllocatedPath
&&
new_path
,
Error
&
error
);
...
@@ -209,10 +211,11 @@ RecorderOutput::Open(AudioFormat &audio_format, Error &error)
...
@@ -209,10 +211,11 @@ RecorderOutput::Open(AudioFormat &audio_format, Error &error)
/* open the encoder */
/* open the encoder */
encoder
=
prepared_encoder
->
Open
(
audio_format
,
error
);
try
{
if
(
encoder
==
nullptr
)
{
encoder
=
prepared_encoder
->
Open
(
audio_format
);
}
catch
(
const
std
::
runtime_error
&
)
{
delete
file
;
delete
file
;
return
false
;
throw
;
}
}
if
(
!
HasDynamicPath
())
{
if
(
!
HasDynamicPath
())
{
...
@@ -235,39 +238,33 @@ RecorderOutput::Open(AudioFormat &audio_format, Error &error)
...
@@ -235,39 +238,33 @@ RecorderOutput::Open(AudioFormat &audio_format, Error &error)
return
true
;
return
true
;
}
}
inline
bool
inline
void
RecorderOutput
::
Commit
(
Error
&
error
)
RecorderOutput
::
Commit
()
{
{
assert
(
!
path
.
IsNull
());
assert
(
!
path
.
IsNull
());
/* flush the encoder and write the rest to the file */
/* flush the encoder and write the rest to the file */
bool
success
=
encoder
->
End
(
error
);
if
(
success
)
{
try
{
try
{
encoder
->
End
();
EncoderToFile
();
EncoderToFile
();
}
catch
(...)
{
}
catch
(...)
{
delete
encoder
;
delete
encoder
;
throw
;
throw
;
}
}
}
/* now really close everything */
/* now really close everything */
delete
encoder
;
delete
encoder
;
if
(
success
)
{
try
{
try
{
file
->
Commit
();
file
->
Commit
();
}
catch
(...)
{
}
catch
(...)
{
delete
file
;
delete
file
;
throw
;
throw
;
}
}
}
delete
file
;
delete
file
;
return
success
;
}
}
inline
void
inline
void
...
@@ -282,9 +279,7 @@ RecorderOutput::Close()
...
@@ -282,9 +279,7 @@ RecorderOutput::Close()
}
}
try
{
try
{
Error
error
;
Commit
();
if
(
!
Commit
(
error
))
LogError
(
error
);
}
catch
(
const
std
::
exception
&
e
)
{
}
catch
(
const
std
::
exception
&
e
)
{
LogError
(
e
);
LogError
(
e
);
}
}
...
@@ -304,9 +299,7 @@ RecorderOutput::FinishFormat()
...
@@ -304,9 +299,7 @@ RecorderOutput::FinishFormat()
return
;
return
;
try
{
try
{
Error
error
;
Commit
();
if
(
!
Commit
(
error
))
LogError
(
error
);
}
catch
(
const
std
::
exception
&
e
)
{
}
catch
(
const
std
::
exception
&
e
)
{
LogError
(
e
);
LogError
(
e
);
}
}
...
@@ -331,10 +324,12 @@ RecorderOutput::ReopenFormat(AllocatedPath &&new_path, Error &error)
...
@@ -331,10 +324,12 @@ RecorderOutput::ReopenFormat(AllocatedPath &&new_path, Error &error)
}
}
AudioFormat
new_audio_format
=
effective_audio_format
;
AudioFormat
new_audio_format
=
effective_audio_format
;
encoder
=
prepared_encoder
->
Open
(
new_audio_format
,
error
);
if
(
encoder
==
nullptr
)
{
try
{
encoder
=
prepared_encoder
->
Open
(
new_audio_format
);
}
catch
(...)
{
delete
new_file
;
delete
new_file
;
return
false
;
throw
;
}
}
/* reopening the encoder must always result in the same
/* reopening the encoder must always result in the same
...
@@ -395,21 +390,9 @@ RecorderOutput::SendTag(const Tag &tag)
...
@@ -395,21 +390,9 @@ RecorderOutput::SendTag(const Tag &tag)
}
}
}
}
Error
error
;
encoder
->
PreTag
();
if
(
!
encoder
->
PreTag
(
error
))
{
LogError
(
error
);
return
;
}
try
{
EncoderToFile
();
EncoderToFile
();
}
catch
(
const
std
::
exception
&
e
)
{
encoder
->
SendTag
(
tag
);
LogError
(
e
);
return
;
}
if
(
!
encoder
->
SendTag
(
tag
,
error
))
LogError
(
error
);
}
}
inline
size_t
inline
size_t
...
@@ -423,8 +406,7 @@ RecorderOutput::Play(const void *chunk, size_t size, Error &error)
...
@@ -423,8 +406,7 @@ RecorderOutput::Play(const void *chunk, size_t size, Error &error)
return
size
;
return
size
;
}
}
if
(
!
encoder
->
Write
(
chunk
,
size
,
error
))
encoder
->
Write
(
chunk
,
size
);
return
0
;
try
{
try
{
EncoderToFile
();
EncoderToFile
();
...
...
src/output/plugins/ShoutOutputPlugin.cxx
View file @
d8b6aff2
...
@@ -32,6 +32,8 @@
...
@@ -32,6 +32,8 @@
#include <shout/shout.h>
#include <shout/shout.h>
#include <stdexcept>
#include <assert.h>
#include <assert.h>
#include <stdlib.h>
#include <stdlib.h>
#include <string.h>
#include <string.h>
...
@@ -366,8 +368,12 @@ void
...
@@ -366,8 +368,12 @@ void
ShoutOutput
::
Close
()
ShoutOutput
::
Close
()
{
{
if
(
encoder
!=
nullptr
)
{
if
(
encoder
!=
nullptr
)
{
if
(
encoder
->
End
(
IgnoreError
()))
try
{
encoder
->
End
();
write_page
(
this
,
IgnoreError
());
write_page
(
this
,
IgnoreError
());
}
catch
(
const
std
::
runtime_error
&
)
{
/* ignore */
}
delete
encoder
;
delete
encoder
;
}
}
...
@@ -410,17 +416,23 @@ ShoutOutput::Open(AudioFormat &audio_format, Error &error)
...
@@ -410,17 +416,23 @@ ShoutOutput::Open(AudioFormat &audio_format, Error &error)
if
(
!
shout_connect
(
this
,
error
))
if
(
!
shout_connect
(
this
,
error
))
return
false
;
return
false
;
encoder
=
prepared_encoder
->
Open
(
audio_format
,
error
);
try
{
if
(
encoder
==
nullptr
)
{
encoder
=
prepared_encoder
->
Open
(
audio_format
);
shout_close
(
shout_conn
);
return
false
;
}
try
{
if
(
!
write_page
(
this
,
error
))
{
if
(
!
write_page
(
this
,
error
))
{
delete
encoder
;
delete
encoder
;
shout_close
(
shout_conn
);
shout_close
(
shout_conn
);
return
false
;
return
false
;
}
}
}
catch
(
const
std
::
runtime_error
&
)
{
delete
encoder
;
throw
;
}
}
catch
(
const
std
::
runtime_error
&
)
{
shout_close
(
shout_conn
);
throw
;
}
return
true
;
return
true
;
}
}
...
@@ -438,8 +450,8 @@ ShoutOutput::Delay() const
...
@@ -438,8 +450,8 @@ ShoutOutput::Delay() const
size_t
size_t
ShoutOutput
::
Play
(
const
void
*
chunk
,
size_t
size
,
Error
&
error
)
ShoutOutput
::
Play
(
const
void
*
chunk
,
size_t
size
,
Error
&
error
)
{
{
return
encoder
->
Write
(
chunk
,
size
,
error
)
&&
encoder
->
Write
(
chunk
,
size
);
write_page
(
this
,
error
)
return
write_page
(
this
,
error
)
?
size
?
size
:
0
;
:
0
;
}
}
...
@@ -484,13 +496,15 @@ ShoutOutput::SendTag(const Tag &tag)
...
@@ -484,13 +496,15 @@ ShoutOutput::SendTag(const Tag &tag)
if
(
encoder
->
ImplementsTag
())
{
if
(
encoder
->
ImplementsTag
())
{
/* encoder plugin supports stream tags */
/* encoder plugin supports stream tags */
encoder
->
PreTag
();
Error
error
;
Error
error
;
if
(
!
encoder
->
PreTag
(
error
)
||
if
(
!
write_page
(
this
,
error
))
{
!
write_page
(
this
,
error
)
||
!
encoder
->
SendTag
(
tag
,
error
))
{
LogError
(
error
);
LogError
(
error
);
return
;
return
;
}
}
encoder
->
SendTag
(
tag
);
}
else
{
}
else
{
/* no stream tag support: fall back to icy-metadata */
/* no stream tag support: fall back to icy-metadata */
char
song
[
1024
];
char
song
[
1024
];
...
...
src/output/plugins/httpd/HttpdInternal.hxx
View file @
d8b6aff2
...
@@ -171,8 +171,10 @@ public:
...
@@ -171,8 +171,10 @@ public:
/**
/**
* Caller must lock the mutex.
* Caller must lock the mutex.
*
* Throws #std::runtime_error on error.
*/
*/
bool
OpenEncoder
(
AudioFormat
&
audio_format
,
Error
&
error
);
void
OpenEncoder
(
AudioFormat
&
audio_format
);
/**
/**
* Caller must lock the mutex.
* Caller must lock the mutex.
...
@@ -237,7 +239,10 @@ public:
...
@@ -237,7 +239,10 @@ public:
*/
*/
void
BroadcastFromEncoder
();
void
BroadcastFromEncoder
();
bool
EncodeAndPlay
(
const
void
*
chunk
,
size_t
size
,
Error
&
error
);
/**
* Throws #std::runtime_error on error.
*/
void
EncodeAndPlay
(
const
void
*
chunk
,
size_t
size
);
void
SendTag
(
const
Tag
&
tag
);
void
SendTag
(
const
Tag
&
tag
);
...
...
src/output/plugins/httpd/HttpdOutputPlugin.cxx
View file @
d8b6aff2
...
@@ -221,7 +221,12 @@ HttpdOutput::ReadPage()
...
@@ -221,7 +221,12 @@ HttpdOutput::ReadPage()
/* we have fed a lot of input into the encoder, but it
/* we have fed a lot of input into the encoder, but it
didn't give anything back yet - flush now to avoid
didn't give anything back yet - flush now to avoid
buffer underruns */
buffer underruns */
encoder
->
Flush
(
IgnoreError
());
try
{
encoder
->
Flush
();
}
catch
(
const
std
::
runtime_error
&
)
{
/* ignore */
}
unflushed_input
=
0
;
unflushed_input
=
0
;
}
}
...
@@ -260,12 +265,10 @@ httpd_output_disable(AudioOutput *ao)
...
@@ -260,12 +265,10 @@ httpd_output_disable(AudioOutput *ao)
httpd
->
Unbind
();
httpd
->
Unbind
();
}
}
inline
bool
inline
void
HttpdOutput
::
OpenEncoder
(
AudioFormat
&
audio_format
,
Error
&
error
)
HttpdOutput
::
OpenEncoder
(
AudioFormat
&
audio_format
)
{
{
encoder
=
prepared_encoder
->
Open
(
audio_format
,
error
);
encoder
=
prepared_encoder
->
Open
(
audio_format
);
if
(
encoder
==
nullptr
)
return
false
;
/* we have to remember the encoder header, i.e. the first
/* we have to remember the encoder header, i.e. the first
bytes of encoder output after opening it, because it has to
bytes of encoder output after opening it, because it has to
...
@@ -273,20 +276,15 @@ HttpdOutput::OpenEncoder(AudioFormat &audio_format, Error &error)
...
@@ -273,20 +276,15 @@ HttpdOutput::OpenEncoder(AudioFormat &audio_format, Error &error)
header
=
ReadPage
();
header
=
ReadPage
();
unflushed_input
=
0
;
unflushed_input
=
0
;
return
true
;
}
}
inline
bool
inline
bool
HttpdOutput
::
Open
(
AudioFormat
&
audio_format
,
Error
&
error
)
HttpdOutput
::
Open
(
AudioFormat
&
audio_format
,
Error
&
)
{
{
assert
(
!
open
);
assert
(
!
open
);
assert
(
clients
.
empty
());
assert
(
clients
.
empty
());
/* open the encoder */
OpenEncoder
(
audio_format
);
if
(
!
OpenEncoder
(
audio_format
,
error
))
return
false
;
/* initialize other attributes */
/* initialize other attributes */
...
@@ -410,25 +408,21 @@ HttpdOutput::BroadcastFromEncoder()
...
@@ -410,25 +408,21 @@ HttpdOutput::BroadcastFromEncoder()
DeferredMonitor
::
Schedule
();
DeferredMonitor
::
Schedule
();
}
}
inline
bool
inline
void
HttpdOutput
::
EncodeAndPlay
(
const
void
*
chunk
,
size_t
size
,
Error
&
error
)
HttpdOutput
::
EncodeAndPlay
(
const
void
*
chunk
,
size_t
size
)
{
{
if
(
!
encoder
->
Write
(
chunk
,
size
,
error
))
encoder
->
Write
(
chunk
,
size
);
return
false
;
unflushed_input
+=
size
;
unflushed_input
+=
size
;
BroadcastFromEncoder
();
BroadcastFromEncoder
();
return
true
;
}
}
inline
size_t
inline
size_t
HttpdOutput
::
Play
(
const
void
*
chunk
,
size_t
size
,
Error
&
error
)
HttpdOutput
::
Play
(
const
void
*
chunk
,
size_t
size
,
Error
&
)
{
{
if
(
LockHasClients
())
{
if
(
LockHasClients
())
if
(
!
EncodeAndPlay
(
chunk
,
size
,
error
))
EncodeAndPlay
(
chunk
,
size
);
return
0
;
}
if
(
!
timer
->
IsStarted
())
if
(
!
timer
->
IsStarted
())
timer
->
Start
();
timer
->
Start
();
...
@@ -468,13 +462,22 @@ HttpdOutput::SendTag(const Tag &tag)
...
@@ -468,13 +462,22 @@ HttpdOutput::SendTag(const Tag &tag)
/* flush the current stream, and end it */
/* flush the current stream, and end it */
encoder
->
PreTag
(
IgnoreError
());
try
{
encoder
->
PreTag
();
}
catch
(
const
std
::
runtime_error
&
)
{
/* ignore */
}
BroadcastFromEncoder
();
BroadcastFromEncoder
();
/* send the tag to the encoder - which starts a new
/* send the tag to the encoder - which starts a new
stream now */
stream now */
encoder
->
SendTag
(
tag
,
IgnoreError
());
try
{
encoder
->
SendTag
(
tag
);
}
catch
(
const
std
::
runtime_error
&
)
{
/* ignore */
}
/* the first page generated by the encoder will now be
/* the first page generated by the encoder will now be
used as the new "header" page, which is sent to all
used as the new "header" page, which is sent to all
...
...
test/run_encoder.cxx
View file @
d8b6aff2
...
@@ -26,7 +26,6 @@
...
@@ -26,7 +26,6 @@
#include "AudioParser.hxx"
#include "AudioParser.hxx"
#include "config/Block.hxx"
#include "config/Block.hxx"
#include "fs/io/StdioOutputStream.hxx"
#include "fs/io/StdioOutputStream.hxx"
#include "util/Error.hxx"
#include "Log.hxx"
#include "Log.hxx"
#include <memory>
#include <memory>
...
@@ -66,7 +65,6 @@ int main(int argc, char **argv)
...
@@ -66,7 +65,6 @@ int main(int argc, char **argv)
block
.
AddBlockParam
(
"quality"
,
"5.0"
,
-
1
);
block
.
AddBlockParam
(
"quality"
,
"5.0"
,
-
1
);
try
{
try
{
Error
error
;
std
::
unique_ptr
<
PreparedEncoder
>
p_encoder
(
encoder_init
(
*
plugin
,
block
));
std
::
unique_ptr
<
PreparedEncoder
>
p_encoder
(
encoder_init
(
*
plugin
,
block
));
/* open the encoder */
/* open the encoder */
...
@@ -75,11 +73,7 @@ int main(int argc, char **argv)
...
@@ -75,11 +73,7 @@ int main(int argc, char **argv)
if
(
argc
>
2
)
if
(
argc
>
2
)
audio_format
=
ParseAudioFormat
(
argv
[
2
],
false
);
audio_format
=
ParseAudioFormat
(
argv
[
2
],
false
);
std
::
unique_ptr
<
Encoder
>
encoder
(
p_encoder
->
Open
(
audio_format
,
error
));
std
::
unique_ptr
<
Encoder
>
encoder
(
p_encoder
->
Open
(
audio_format
));
if
(
encoder
==
nullptr
)
{
LogError
(
error
,
"Failed to open encoder"
);
return
EXIT_FAILURE
;
}
StdioOutputStream
os
(
stdout
);
StdioOutputStream
os
(
stdout
);
...
@@ -89,19 +83,11 @@ int main(int argc, char **argv)
...
@@ -89,19 +83,11 @@ int main(int argc, char **argv)
ssize_t
nbytes
;
ssize_t
nbytes
;
while
((
nbytes
=
read
(
0
,
buffer
,
sizeof
(
buffer
)))
>
0
)
{
while
((
nbytes
=
read
(
0
,
buffer
,
sizeof
(
buffer
)))
>
0
)
{
if
(
!
encoder
->
Write
(
buffer
,
nbytes
,
error
))
{
encoder
->
Write
(
buffer
,
nbytes
);
LogError
(
error
,
"encoder_write() failed"
);
return
EXIT_FAILURE
;
}
EncoderToOutputStream
(
os
,
*
encoder
);
EncoderToOutputStream
(
os
,
*
encoder
);
}
}
if
(
!
encoder
->
End
(
error
))
{
encoder
->
End
();
LogError
(
error
,
"encoder_flush() failed"
);
return
EXIT_FAILURE
;
}
EncoderToOutputStream
(
os
,
*
encoder
);
EncoderToOutputStream
(
os
,
*
encoder
);
return
EXIT_SUCCESS
;
return
EXIT_SUCCESS
;
...
...
test/test_vorbis_encoder.cxx
View file @
d8b6aff2
...
@@ -27,7 +27,6 @@
...
@@ -27,7 +27,6 @@
#include "fs/io/StdioOutputStream.hxx"
#include "fs/io/StdioOutputStream.hxx"
#include "tag/Tag.hxx"
#include "tag/Tag.hxx"
#include "tag/TagBuilder.hxx"
#include "tag/TagBuilder.hxx"
#include "util/Error.hxx"
#include "Log.hxx"
#include "Log.hxx"
#include <memory>
#include <memory>
...
@@ -40,8 +39,6 @@ static uint8_t zero[256];
...
@@ -40,8 +39,6 @@ static uint8_t zero[256];
int
int
main
(
gcc_unused
int
argc
,
gcc_unused
char
**
argv
)
main
(
gcc_unused
int
argc
,
gcc_unused
char
**
argv
)
try
{
try
{
gcc_unused
bool
success
;
/* create the encoder */
/* create the encoder */
const
auto
plugin
=
encoder_plugin_get
(
"vorbis"
);
const
auto
plugin
=
encoder_plugin_get
(
"vorbis"
);
...
@@ -56,8 +53,7 @@ try {
...
@@ -56,8 +53,7 @@ try {
/* open the encoder */
/* open the encoder */
AudioFormat
audio_format
(
44100
,
SampleFormat
::
S16
,
2
);
AudioFormat
audio_format
(
44100
,
SampleFormat
::
S16
,
2
);
std
::
unique_ptr
<
Encoder
>
encoder
(
p_encoder
->
Open
(
audio_format
,
std
::
unique_ptr
<
Encoder
>
encoder
(
p_encoder
->
Open
(
audio_format
));
IgnoreError
()));
assert
(
encoder
!=
nullptr
);
assert
(
encoder
!=
nullptr
);
StdioOutputStream
os
(
stdout
);
StdioOutputStream
os
(
stdout
);
...
@@ -66,15 +62,13 @@ try {
...
@@ -66,15 +62,13 @@ try {
/* write a block of data */
/* write a block of data */
success
=
encoder
->
Write
(
zero
,
sizeof
(
zero
),
IgnoreError
());
encoder
->
Write
(
zero
,
sizeof
(
zero
));
assert
(
success
);
EncoderToOutputStream
(
os
,
*
encoder
);
EncoderToOutputStream
(
os
,
*
encoder
);
/* write a tag */
/* write a tag */
success
=
encoder
->
PreTag
(
IgnoreError
());
encoder
->
PreTag
();
assert
(
success
);
EncoderToOutputStream
(
os
,
*
encoder
);
EncoderToOutputStream
(
os
,
*
encoder
);
...
@@ -87,21 +81,17 @@ try {
...
@@ -87,21 +81,17 @@ try {
tag_builder
.
Commit
(
tag
);
tag_builder
.
Commit
(
tag
);
}
}
success
=
encoder
->
SendTag
(
tag
,
IgnoreError
());
encoder
->
SendTag
(
tag
);
assert
(
success
);
EncoderToOutputStream
(
os
,
*
encoder
);
EncoderToOutputStream
(
os
,
*
encoder
);
/* write another block of data */
/* write another block of data */
success
=
encoder
->
Write
(
zero
,
sizeof
(
zero
),
IgnoreError
());
encoder
->
Write
(
zero
,
sizeof
(
zero
));
assert
(
success
);
/* finish */
/* finish */
success
=
encoder
->
End
(
IgnoreError
());
encoder
->
End
();
assert
(
success
);
EncoderToOutputStream
(
os
,
*
encoder
);
EncoderToOutputStream
(
os
,
*
encoder
);
return
EXIT_SUCCESS
;
return
EXIT_SUCCESS
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment