Commit b61b78e1 authored by Moritz Grimm's avatar Moritz Grimm
Browse files

Modernize stream format options

Adds support for WebM/Matroska
Replaces Vorbis and Theora with Ogg
parent 4fe8ea45
......@@ -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);
......
......@@ -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);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment