mirror of
https://gitlab.xiph.org/xiph/ezstream.git
synced 2025-01-03 14:56:35 -05:00
Modernize stream format options
Adds support for WebM/Matroska Replaces Vorbis and Theora with Ogg
This commit is contained in:
parent
4fe8ea4526
commit
b61b78e161
@ -343,13 +343,15 @@ Default:
|
||||
.Pq Mandatory.
|
||||
The stream format.
|
||||
.Pp
|
||||
.Bl -tag -width VORBIS -compact
|
||||
.It Ar Vorbis
|
||||
Ogg Vorbis audio format
|
||||
.Bl -tag -width Matroska -compact
|
||||
.It Ar Ogg
|
||||
Ogg media format
|
||||
.It Ar MP3
|
||||
MP3 audio format
|
||||
.It Ar Theora
|
||||
Ogg Theora video format
|
||||
.It Ar WebM
|
||||
WebM media format
|
||||
.It Ar Matroska
|
||||
Matroska media format
|
||||
.El
|
||||
.It Sy \&<encoder\ /\&>
|
||||
Use the encoder configuration with the provided symbolic name
|
||||
|
@ -21,7 +21,7 @@
|
||||
<streams>
|
||||
<stream>
|
||||
<mountpoint>/stream.ogg</mountpoint>
|
||||
<format>Vorbis</format>
|
||||
<format>Ogg</format>
|
||||
<encoder>OggEnc-Q1.5</encoder>
|
||||
</stream>
|
||||
</streams>
|
||||
@ -56,7 +56,7 @@
|
||||
<encoders>
|
||||
<encoder>
|
||||
<name>OggEnc-Q1.5</name>
|
||||
<format>Vorbis</format>
|
||||
<format>Ogg</format>
|
||||
<program>oggenc -r -B 16 -C 2 -R 44100 --raw-endianness 0 -q 1.5 -t @M@ -</program>
|
||||
</encoder>
|
||||
|
||||
|
@ -100,8 +100,8 @@
|
||||
-->
|
||||
<public>No</public>
|
||||
|
||||
<!-- Stream format: Vorbis, MP3, Theora -->
|
||||
<format>Vorbis</format>
|
||||
<!-- Stream format: Ogg, MP3, WebM, Matroska -->
|
||||
<format>Ogg</format>
|
||||
|
||||
<!-- Encoder name (defined below) to use for (re)encoding -->
|
||||
<encoder>OggEnc-Q1.5</encoder>
|
||||
@ -198,7 +198,7 @@
|
||||
<!-- Encoder name -->
|
||||
<name>OggEnc-Q1.5</name>
|
||||
<!-- Output stream format -->
|
||||
<format>Vorbis</format>
|
||||
<format>Ogg</format>
|
||||
<!-- Program and options -->
|
||||
<program>oggenc -r -B 16 -C 2 -R 44100 --raw-endianness 1 -q 1.5 -t @M@ -</program>
|
||||
</encoder>
|
||||
|
@ -16,7 +16,7 @@
|
||||
<streams>
|
||||
<stream>
|
||||
<mountpoint>/stream.ogg</mountpoint>
|
||||
<format>Vorbis</format>
|
||||
<format>Ogg</format>
|
||||
</stream>
|
||||
</streams>
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
<!--
|
||||
EXAMPLE: A valid configuration that contains the absolute minimum
|
||||
|
||||
This configuration streams Ogg Vorbis files as-is.
|
||||
This configuration streams Ogg files as-is.
|
||||
-->
|
||||
|
||||
<ezstream>
|
||||
@ -18,7 +18,7 @@
|
||||
<streams>
|
||||
<stream>
|
||||
<mountpoint>/stream.ogg</mountpoint>
|
||||
<format>Vorbis</format>
|
||||
<format>Ogg</format>
|
||||
</stream>
|
||||
</streams>
|
||||
|
||||
|
@ -18,7 +18,7 @@
|
||||
<streams>
|
||||
<stream>
|
||||
<mountpoint>/stream.ogg</mountpoint>
|
||||
<format>Vorbis</format>
|
||||
<format>Ogg</format>
|
||||
</stream>
|
||||
</streams>
|
||||
|
||||
|
@ -16,7 +16,7 @@
|
||||
<streams>
|
||||
<stream>
|
||||
<mountpoint>/video.ogg</mountpoint>
|
||||
<format>Theora</format>
|
||||
<format>Ogg</format>
|
||||
<!-- No encoder configured (see below). -->
|
||||
</stream>
|
||||
</streams>
|
||||
|
@ -169,12 +169,14 @@ cfg_stream_destroy(struct cfg_stream **s_p)
|
||||
int
|
||||
cfg_stream_str2fmt(const char *str, enum cfg_stream_format *fmt_p)
|
||||
{
|
||||
if (0 == strcasecmp(str, CFG_SFMT_VORBIS)) {
|
||||
*fmt_p = CFG_STREAM_VORBIS;
|
||||
if (0 == strcasecmp(str, CFG_SFMT_OGG)) {
|
||||
*fmt_p = CFG_STREAM_OGG;
|
||||
} else if (0 == strcasecmp(str, CFG_SFMT_MP3)) {
|
||||
*fmt_p = CFG_STREAM_MP3;
|
||||
} else if (0 == strcasecmp(str, CFG_SFMT_THEORA)) {
|
||||
*fmt_p = CFG_STREAM_THEORA;
|
||||
} else if (0 == strcasecmp(str, CFG_SFMT_WEBM)) {
|
||||
*fmt_p = CFG_STREAM_WEBM;
|
||||
} else if (0 == strcasecmp(str, CFG_SFMT_MATROSKA)) {
|
||||
*fmt_p = CFG_STREAM_MATROSKA;
|
||||
} else
|
||||
return (-1);
|
||||
return (0);
|
||||
@ -184,12 +186,14 @@ const char *
|
||||
cfg_stream_fmt2str(enum cfg_stream_format fmt)
|
||||
{
|
||||
switch (fmt) {
|
||||
case CFG_STREAM_VORBIS:
|
||||
return (CFG_SFMT_VORBIS);
|
||||
case CFG_STREAM_OGG:
|
||||
return (CFG_SFMT_OGG);
|
||||
case CFG_STREAM_MP3:
|
||||
return (CFG_SFMT_MP3);
|
||||
case CFG_STREAM_THEORA:
|
||||
return (CFG_SFMT_THEORA);
|
||||
case CFG_STREAM_WEBM:
|
||||
return (CFG_SFMT_WEBM);
|
||||
case CFG_STREAM_MATROSKA:
|
||||
return (CFG_SFMT_MATROSKA);
|
||||
default:
|
||||
return (NULL);
|
||||
}
|
||||
|
@ -17,17 +17,19 @@
|
||||
#ifndef __CFG_STREAM_H__
|
||||
#define __CFG_STREAM_H__
|
||||
|
||||
#define CFG_SFMT_VORBIS "VORBIS"
|
||||
#define CFG_SFMT_OGG "Ogg"
|
||||
#define CFG_SFMT_MP3 "MP3"
|
||||
#define CFG_SFMT_THEORA "THEORA"
|
||||
#define CFG_SFMT_WEBM "WebM"
|
||||
#define CFG_SFMT_MATROSKA "Matroska"
|
||||
|
||||
enum cfg_stream_format {
|
||||
CFG_STREAM_INVALID = 0,
|
||||
CFG_STREAM_VORBIS,
|
||||
CFG_STREAM_OGG,
|
||||
CFG_STREAM_MP3,
|
||||
CFG_STREAM_THEORA,
|
||||
CFG_STREAM_MIN = CFG_STREAM_VORBIS,
|
||||
CFG_STREAM_MAX = CFG_STREAM_THEORA,
|
||||
CFG_STREAM_WEBM,
|
||||
CFG_STREAM_MATROSKA,
|
||||
CFG_STREAM_MIN = CFG_STREAM_OGG,
|
||||
CFG_STREAM_MAX = CFG_STREAM_MATROSKA,
|
||||
};
|
||||
|
||||
typedef struct cfg_stream * cfg_stream_t;
|
||||
|
@ -206,9 +206,15 @@ _parse_ezconfig0(EZCONFIG *ez)
|
||||
if (ez->password)
|
||||
ENTITY_SET(srv, srv_list, cfg_server_set_password,
|
||||
"<sourcepassword>", ez->password);
|
||||
if (ez->format)
|
||||
ENTITY_SET(str, str_list, cfg_stream_set_format,
|
||||
"<format>", ez->format);
|
||||
if (ez->format) {
|
||||
if (0 == strcasecmp(ez->format, "vorbis") ||
|
||||
0 == strcasecmp(ez->format, "theora"))
|
||||
ENTITY_SET(str, str_list, cfg_stream_set_format,
|
||||
"<format>", "Ogg");
|
||||
else
|
||||
ENTITY_SET(str, str_list, cfg_stream_set_format,
|
||||
"<format>", ez->format);
|
||||
}
|
||||
if (ez->fileName) {
|
||||
if (0 == strcasecmp(ez->fileName, "stdin"))
|
||||
ENTITY_SET(in, in_list, cfg_intake_set_type,
|
||||
@ -281,9 +287,15 @@ _parse_ezconfig0(EZCONFIG *ez)
|
||||
"<svrinfoquality>", ez->serverQuality);
|
||||
ENTITY_SET(str, str_list, cfg_stream_set_public,
|
||||
"<svrinfopublic>", ez->serverPublic ? "yes" : "no");
|
||||
if (ez->reencode)
|
||||
ENTITY_SET(str, str_list, cfg_stream_set_encoder, "<reencode>",
|
||||
ez->format);
|
||||
if (ez->reencode) {
|
||||
if (0 == strcasecmp(ez->format, "vorbis") ||
|
||||
0 == strcasecmp(ez->format, "theora"))
|
||||
ENTITY_SET(str, str_list, cfg_stream_set_encoder,
|
||||
"<reencode>", "Ogg");
|
||||
else
|
||||
ENTITY_SET(str, str_list, cfg_stream_set_encoder,
|
||||
"<reencode>", ez->format);
|
||||
}
|
||||
|
||||
for (i = 0; i < MAX_FORMAT_ENCDEC; i++) {
|
||||
FORMAT_ENCDEC *ed = ez->encoderDecoders[i];
|
||||
@ -298,10 +310,26 @@ _parse_ezconfig0(EZCONFIG *ez)
|
||||
ENTITY_SET(enc, enc_list, cfg_encoder_set_program,
|
||||
"<encode>", ed->encoder);
|
||||
if (ed->format) {
|
||||
ENTITY_SET(enc, enc_list, cfg_encoder_set_name,
|
||||
"<format> (encoder)", ed->format);
|
||||
ENTITY_SET(enc, enc_list, cfg_encoder_set_format_str,
|
||||
"<format> (encoder)", ed->format);
|
||||
if (0 == strcasecmp(ed->format, "vorbis") ||
|
||||
0 == strcasecmp(ed->format, "theora")) {
|
||||
ENTITY_SET(enc, enc_list,
|
||||
cfg_encoder_set_name,
|
||||
"<format> (encoder)",
|
||||
"Ogg");
|
||||
ENTITY_SET(enc, enc_list,
|
||||
cfg_encoder_set_format_str,
|
||||
"<format> (encoder)",
|
||||
"Ogg");
|
||||
} else {
|
||||
ENTITY_SET(enc, enc_list,
|
||||
cfg_encoder_set_name,
|
||||
"<format> (encoder)",
|
||||
ed->format);
|
||||
ENTITY_SET(enc, enc_list,
|
||||
cfg_encoder_set_format_str,
|
||||
"<format> (encoder)",
|
||||
ed->format);
|
||||
}
|
||||
}
|
||||
if (0 > cfg_encoder_validate(enc, &err_str)) {
|
||||
log_warning("%s: %s: %s", v0_cfgfile,
|
||||
@ -313,16 +341,33 @@ _parse_ezconfig0(EZCONFIG *ez)
|
||||
if (ed->decoder) {
|
||||
cfg_decoder_t dec = NULL;
|
||||
|
||||
if (ed->format)
|
||||
dec = cfg_decoder_list_find(dec_list, ed->format);
|
||||
if (ed->format) {
|
||||
if (0 == strcasecmp(ed->format, "vorbis") ||
|
||||
0 == strcasecmp(ed->format, "theora"))
|
||||
dec = cfg_decoder_list_find(dec_list,
|
||||
"Ogg");
|
||||
else
|
||||
dec = cfg_decoder_list_find(dec_list,
|
||||
ed->format);
|
||||
}
|
||||
if (NULL == dec)
|
||||
dec = cfg_decoder_list_get(dec_list, CFG_DEFAULT);
|
||||
|
||||
ENTITY_SET(dec, dec_list, cfg_decoder_set_program,
|
||||
"<decode>", ed->decoder);
|
||||
if (ed->format)
|
||||
ENTITY_SET(dec, dec_list, cfg_decoder_set_name,
|
||||
"<format> (decoder)", ed->format);
|
||||
if (ed->format) {
|
||||
if (0 == strcasecmp(ed->format, "vorbis") ||
|
||||
0 == strcasecmp(ed->format, "theora"))
|
||||
ENTITY_SET(dec, dec_list,
|
||||
cfg_decoder_set_name,
|
||||
"<format> (decoder)",
|
||||
"Ogg");
|
||||
else
|
||||
ENTITY_SET(dec, dec_list,
|
||||
cfg_decoder_set_name,
|
||||
"<format> (decoder)",
|
||||
ed->format);
|
||||
}
|
||||
if (ed->match)
|
||||
ENTITY_SET(dec, dec_list, cfg_decoder_add_match,
|
||||
"<match>", ed->match);
|
||||
|
21
src/stream.c
21
src/stream.c
@ -216,8 +216,7 @@ _stream_cfg_stream(struct stream *s, cfg_stream_t cfg_stream)
|
||||
return (-1);
|
||||
}
|
||||
switch (cfg_stream_get_format(cfg_stream)) {
|
||||
case CFG_STREAM_VORBIS:
|
||||
case CFG_STREAM_THEORA:
|
||||
case CFG_STREAM_OGG:
|
||||
if (SHOUTERR_SUCCESS !=
|
||||
shout_set_format(s->shout, SHOUT_FORMAT_OGG)) {
|
||||
log_error("stream: %s: format_ogg: %s",
|
||||
@ -233,6 +232,24 @@ _stream_cfg_stream(struct stream *s, cfg_stream_t cfg_stream)
|
||||
return (-1);
|
||||
}
|
||||
break;
|
||||
case CFG_STREAM_WEBM:
|
||||
if (SHOUTERR_SUCCESS !=
|
||||
shout_set_format(s->shout, SHOUT_FORMAT_WEBM)) {
|
||||
log_error("stream: %s: format_mp3: %s",
|
||||
s->name, shout_get_error(s->shout));
|
||||
return (-1);
|
||||
}
|
||||
break;
|
||||
#ifdef SHOUT_FORMAT_MATROSKA
|
||||
case CFG_STREAM_MATROSKA:
|
||||
if (SHOUTERR_SUCCESS !=
|
||||
shout_set_format(s->shout, SHOUT_FORMAT_MATROSKA)) {
|
||||
log_error("stream: %s: format_mp3: %s",
|
||||
s->name, shout_get_error(s->shout));
|
||||
return (-1);
|
||||
}
|
||||
break;
|
||||
#endif /* SHOUT_FORMAT_MATROSKA */
|
||||
default:
|
||||
log_error("stream: %s: format: unsupported: %s",
|
||||
s->name, cfg_stream_get_format_str(cfg_stream));
|
||||
|
@ -77,12 +77,14 @@ START_TEST(test_encoder_set_format_str)
|
||||
ck_assert_str_eq(errstr, "unsupported stream format");
|
||||
|
||||
ck_assert_int_eq(cfg_encoder_set_format_str(enc, encoders,
|
||||
CFG_SFMT_VORBIS, NULL), 0);
|
||||
CFG_SFMT_OGG, NULL), 0);
|
||||
ck_assert_int_eq(cfg_encoder_set_format_str(enc, encoders,
|
||||
CFG_SFMT_MP3, NULL), 0);
|
||||
ck_assert_int_eq(cfg_encoder_set_format_str(enc, encoders,
|
||||
CFG_SFMT_THEORA, NULL), 0);
|
||||
ck_assert_uint_eq(cfg_encoder_get_format(enc), CFG_STREAM_THEORA);
|
||||
CFG_SFMT_MP3, NULL), 0);
|
||||
ck_assert_int_eq(cfg_encoder_set_format_str(enc, encoders,
|
||||
CFG_SFMT_MATROSKA, NULL), 0);
|
||||
ck_assert_uint_eq(cfg_encoder_get_format(enc), CFG_STREAM_MATROSKA);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
@ -101,7 +103,7 @@ START_TEST(test_encoder_validate)
|
||||
ck_assert_int_ne(cfg_encoder_validate(enc, &errstr), 0);
|
||||
ck_assert_str_eq(errstr, "format not set");
|
||||
|
||||
ck_assert_int_eq(cfg_encoder_set_format(enc, CFG_STREAM_VORBIS), 0);
|
||||
ck_assert_int_eq(cfg_encoder_set_format(enc, CFG_STREAM_OGG), 0);
|
||||
|
||||
ck_assert_int_ne(cfg_encoder_validate(enc, &errstr), 0);
|
||||
ck_assert_str_eq(errstr, "program not set");
|
||||
|
@ -47,24 +47,28 @@ START_TEST(test_stream_str2fmt)
|
||||
{
|
||||
enum cfg_stream_format fmt;
|
||||
|
||||
ck_assert_int_eq(cfg_stream_str2fmt(CFG_SFMT_VORBIS, &fmt), 0);
|
||||
ck_assert_int_eq(fmt, CFG_STREAM_VORBIS);
|
||||
ck_assert_int_eq(cfg_stream_str2fmt(CFG_SFMT_OGG, &fmt), 0);
|
||||
ck_assert_int_eq(fmt, CFG_STREAM_OGG);
|
||||
ck_assert_int_eq(cfg_stream_str2fmt(CFG_SFMT_MP3, &fmt), 0);
|
||||
ck_assert_int_eq(fmt, CFG_STREAM_MP3);
|
||||
ck_assert_int_eq(cfg_stream_str2fmt(CFG_SFMT_THEORA, &fmt), 0);
|
||||
ck_assert_int_eq(fmt, CFG_STREAM_THEORA);
|
||||
ck_assert_int_eq(cfg_stream_str2fmt(CFG_SFMT_WEBM, &fmt), 0);
|
||||
ck_assert_int_eq(fmt, CFG_STREAM_WEBM);
|
||||
ck_assert_int_eq(cfg_stream_str2fmt(CFG_SFMT_MATROSKA, &fmt), 0);
|
||||
ck_assert_int_eq(fmt, CFG_STREAM_MATROSKA);
|
||||
ck_assert_int_eq(cfg_stream_str2fmt("<something else>", &fmt), -1);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_stream_fmt2str)
|
||||
{
|
||||
ck_assert_str_eq(cfg_stream_fmt2str(CFG_STREAM_VORBIS),
|
||||
CFG_SFMT_VORBIS);
|
||||
ck_assert_str_eq(cfg_stream_fmt2str(CFG_STREAM_OGG),
|
||||
CFG_SFMT_OGG);
|
||||
ck_assert_str_eq(cfg_stream_fmt2str(CFG_STREAM_MP3),
|
||||
CFG_SFMT_MP3);
|
||||
ck_assert_str_eq(cfg_stream_fmt2str(CFG_STREAM_THEORA),
|
||||
CFG_SFMT_THEORA);
|
||||
ck_assert_str_eq(cfg_stream_fmt2str(CFG_STREAM_WEBM),
|
||||
CFG_SFMT_WEBM);
|
||||
ck_assert_str_eq(cfg_stream_fmt2str(CFG_STREAM_MATROSKA),
|
||||
CFG_SFMT_MATROSKA);
|
||||
ck_assert_ptr_eq(cfg_stream_fmt2str(CFG_STREAM_INVALID), NULL);
|
||||
}
|
||||
END_TEST
|
||||
@ -116,11 +120,11 @@ START_TEST(test_stream_format)
|
||||
"<something else>", &errstr2), -1);
|
||||
ck_assert_str_eq(errstr2, "unsupported stream format");
|
||||
|
||||
ck_assert_int_eq(cfg_stream_set_format(str, streams, CFG_SFMT_VORBIS,
|
||||
ck_assert_int_eq(cfg_stream_set_format(str, streams, CFG_SFMT_OGG,
|
||||
NULL), 0);
|
||||
ck_assert_int_eq(cfg_stream_get_format(str), CFG_STREAM_VORBIS);
|
||||
ck_assert_int_eq(cfg_stream_get_format(str), CFG_STREAM_OGG);
|
||||
ck_assert_str_eq(cfg_stream_get_format_str(str),
|
||||
cfg_stream_fmt2str(CFG_STREAM_VORBIS));
|
||||
cfg_stream_fmt2str(CFG_STREAM_OGG));
|
||||
}
|
||||
END_TEST
|
||||
|
||||
@ -197,7 +201,7 @@ START_TEST(test_stream_validate)
|
||||
ck_assert_int_ne(cfg_stream_validate(str, &errstr), 0);
|
||||
ck_assert_ptr_ne(errstr, NULL);
|
||||
ck_assert_str_eq(errstr, "format missing or unsupported");
|
||||
ck_assert_int_eq(cfg_stream_set_format(str, streams, CFG_SFMT_VORBIS,
|
||||
ck_assert_int_eq(cfg_stream_set_format(str, streams, CFG_SFMT_OGG,
|
||||
NULL), 0);
|
||||
|
||||
ck_assert_int_eq(cfg_stream_validate(str, NULL), 0);
|
||||
|
Loading…
Reference in New Issue
Block a user