Add support for more codecs

Only Speex, AAC and H264 are missing now, which require a little bit
more work.
This commit is contained in:
Sebastian Dröge 2016-12-04 23:51:38 +02:00
parent 7ef2679cb5
commit f9cd9e128d
3 changed files with 93 additions and 44 deletions

View file

@ -91,7 +91,8 @@ impl AudioFormat {
(flavors::SoundFormat::NELLYMOSER_16KHZ_MONO, _) => 16000,
(flavors::SoundFormat::NELLYMOSER_8KHZ_MONO, _) => 8000,
(flavors::SoundFormat::MP3_8KHZ, _) => 8000,
(_, flavors::SoundRate::_5_5KHZ) => 5500,
(flavors::SoundFormat::SPEEX, _) => 16000,
(_, flavors::SoundRate::_5_5KHZ) => 5512,
(_, flavors::SoundRate::_11KHZ) => 11025,
(_, flavors::SoundRate::_22KHZ) => 22050,
(_, flavors::SoundRate::_44KHZ) => 44100,
@ -128,20 +129,51 @@ impl AudioFormat {
}
fn to_string(&self) -> Option<String> {
match self.format {
flavors::SoundFormat::MP3 => {
let mut format = String::from("audio/mpeg, mpegversion=(int) 1, layer=(int) 3");
if self.rate != 0 {
format.push_str(&format!(", rate=(int) {}", self.rate));
}
if self.channels != 0 {
format.push_str(&format!(", channels=(int) {}", self.channels));
}
Some(format)
let mut format = match self.format {
flavors::SoundFormat::MP3 |
flavors::SoundFormat::MP3_8KHZ => {
Some(String::from("audio/mpeg, mpegversion=(int) 1, layer=(int) 3"))
}
_ => None,
flavors::SoundFormat::PCM_BE |
flavors::SoundFormat::PCM_LE => {
if self.rate != 0 && self.channels != 0 {
// Assume little-endian for "PCM_NE", it's probably more common and we have no
// way to know what the endianness of the system creating the stream was
Some(format!("audio/x-raw, layout=(string) interleaved, \
format=(string) {}",
if self.width == 8 { "U8" } else { "S16LE" }))
} else {
None
}
}
flavors::SoundFormat::ADPCM => Some(String::from("audio/x-adpcm, layout=(string) swf")),
flavors::SoundFormat::NELLYMOSER_16KHZ_MONO |
flavors::SoundFormat::NELLYMOSER_8KHZ_MONO |
flavors::SoundFormat::NELLYMOSER => Some(String::from("audio/x-nellymoser")),
flavors::SoundFormat::PCM_ALAW => Some(String::from("audio/x-alaw")),
flavors::SoundFormat::PCM_ULAW => Some(String::from("audio/x-mulaw")),
flavors::SoundFormat::AAC => {
// TODO: This requires getting the codec config from the stream
None
}
flavors::SoundFormat::SPEEX => {
// TODO: This requires creating a Speex streamheader...
None
}
flavors::SoundFormat::DEVICE_SPECIFIC => {
// Nobody knows
None
}
};
if self.rate != 0 {
format.as_mut().map(|f| f.push_str(&format!(", rate=(int) {}", self.rate)));
}
if self.channels != 0 {
format.as_mut().map(|f| f.push_str(&format!(", channels=(int) {}", self.channels)));
}
format
}
}
@ -199,29 +231,43 @@ impl VideoFormat {
}
fn to_string(&self) -> Option<String> {
match self.format {
flavors::CodecId::VP6 => {
let mut format = String::from("video/x-vp6-flash");
if let (Some(width), Some(height)) = (self.width, self.height) {
format.push_str(&format!(", width=(int) {}, height=(int) {}", width, height));
}
if let Some(par) = self.pixel_aspect_ratio {
if par.0 != 0 && par.1 != 0 {
format.push_str(&format!(", pixel-aspect-ratio=(fraction) {}/{}",
par.0,
par.1));
}
}
if let Some(fps) = self.framerate {
if fps.1 != 0 {
format.push_str(&format!(", framerate=(fraction) {}/{}", fps.0, fps.1));
}
}
Some(format)
let mut format = match self.format {
flavors::CodecId::H263 => Some(String::from("video/x-flash-video, flvversion=(int) 1")),
flavors::CodecId::SCREEN => Some(String::from("video/x-flash-screen")),
flavors::CodecId::VP6 => Some(String::from("video/x-vp6-flash")),
flavors::CodecId::VP6A => Some(String::from("video/x-vp6-alpha")),
flavors::CodecId::SCREEN2 => Some(String::from("video/x-flash-screen2")),
flavors::CodecId::H264 => {
// TODO: Need codec_data from the stream
None
}
_ => None,
flavors::CodecId::JPEG => {
// Unused according to spec
None
}
};
if let (Some(width), Some(height)) = (self.width, self.height) {
format.as_mut()
.map(|f| f.push_str(&format!(", width=(int) {}, height=(int) {}", width, height)));
}
if let Some(par) = self.pixel_aspect_ratio {
if par.0 != 0 && par.1 != 0 {
format.as_mut().map(|f| {
f.push_str(&format!(", pixel-aspect-ratio=(fraction) {}/{}", par.0, par.1))
});
}
}
if let Some(fps) = self.framerate {
if fps.1 != 0 {
format.as_mut()
.map(|f| f.push_str(&format!(", framerate=(fraction) {}/{}", fps.0, fps.1)));
}
}
format
}
}

View file

@ -329,8 +329,10 @@ gst_rs_demuxer_change_state (GstElement * element, GstStateChange transition)
gst_flow_combiner_clear (demuxer->flow_combiner);
for (i = 0; i < demuxer->n_srcpads; i++)
gst_element_remove_pad (GST_ELEMENT (demuxer), demuxer->srcpads[i]);
for (i = 0; i < G_N_ELEMENTS (demuxer->srcpads); i++) {
if (demuxer->srcpads[i])
gst_element_remove_pad (GST_ELEMENT (demuxer), demuxer->srcpads[i]);
}
memset (demuxer->srcpads, 0, sizeof (demuxer->srcpads));
break;
}
@ -359,7 +361,6 @@ gst_rs_demuxer_add_stream (GstRsDemuxer * demuxer, guint32 index,
gchar *name, *full_stream_id;
g_assert (demuxer->srcpads[index] == NULL);
g_assert (demuxer->n_srcpads == index);
templ =
gst_element_class_get_pad_template (GST_ELEMENT_GET_CLASS (demuxer),
@ -392,7 +393,6 @@ gst_rs_demuxer_add_stream (GstRsDemuxer * demuxer, guint32 index,
gst_flow_combiner_add_pad (demuxer->flow_combiner, pad);
gst_element_add_pad (GST_ELEMENT (demuxer), pad);
demuxer->n_srcpads++;
}
void
@ -424,14 +424,16 @@ gst_rs_demuxer_stream_eos (GstRsDemuxer * demuxer, guint32 index)
GstCaps *caps;
GstEvent *event;
g_assert (demuxer->srcpads[index] != NULL);
g_assert (index == -1 || demuxer->srcpads[index] != NULL);
event = gst_event_new_eos ();
if (index == -1) {
gint i;
for (i = 0; i < demuxer->n_srcpads; i++)
gst_pad_push_event (demuxer->srcpads[i], gst_event_ref (event));
for (i = 0; i < G_N_ELEMENTS (demuxer->srcpads); i++) {
if (demuxer->srcpads[i])
gst_pad_push_event (demuxer->srcpads[i], gst_event_ref (event));
}
gst_event_unref (event);
} else {
@ -461,8 +463,10 @@ gst_rs_demuxer_remove_all_streams (GstRsDemuxer * demuxer)
gst_flow_combiner_clear (demuxer->flow_combiner);
for (i = 0; i < demuxer->n_srcpads; i++)
gst_element_remove_pad (GST_ELEMENT (demuxer), demuxer->srcpads[i]);
for (i = 0; i < G_N_ELEMENTS (demuxer->srcpads); i++) {
if (demuxer->srcpads[i])
gst_element_remove_pad (GST_ELEMENT (demuxer), demuxer->srcpads[i]);
}
memset (demuxer->srcpads, 0, sizeof (demuxer->srcpads));
}

View file

@ -42,7 +42,6 @@ struct _GstRsDemuxer {
guint64 upstream_size;
GstPad *srcpads[32];
guint n_srcpads;
guint32 group_id;
GstSegment segment;