diff options
author | Sebastian Dröge <slomo@circular-chaos.org> | 2007-11-20 13:08:45 +0000 |
---|---|---|
committer | Sebastian Dröge <slomo@circular-chaos.org> | 2007-11-20 13:08:45 +0000 |
commit | ded2cc6e39501f249ac16b88f18c1a92e136b95a (patch) | |
tree | d483394ee5020f2e84336e6996a4603f0494e7cc /ext/wavpack/gstwavpackdec.c | |
parent | dfdc0fa8c9ee0dce74fa4b353209356baea620c8 (diff) |
ext/wavpack/: Add support for encoding, parsing and decoding multichannel files with up to 8 channels. This also impr...
Original commit message from CVS:
* ext/wavpack/gstwavpackcommon.c:
(gst_wavpack_get_default_channel_mask),
(gst_wavpack_set_channel_layout),
(gst_wavpack_get_default_channel_positions),
(gst_wavpack_get_channel_mask_from_positions),
(gst_wavpack_set_channel_mapping):
* ext/wavpack/gstwavpackcommon.h:
* ext/wavpack/gstwavpackdec.c: (gst_wavpack_dec_reset),
(gst_wavpack_dec_sink_set_caps), (gst_wavpack_dec_chain):
* ext/wavpack/gstwavpackdec.h:
* ext/wavpack/gstwavpackenc.c: (gst_wavpack_enc_reset),
(gst_wavpack_enc_init), (gst_wavpack_enc_sink_set_caps),
(gst_wavpack_enc_set_wp_config), (gst_wavpack_enc_push_block),
(gst_wavpack_enc_fix_channel_order), (gst_wavpack_enc_chain),
(gst_wavpack_enc_rewrite_first_block),
(gst_wavpack_enc_sink_event):
* ext/wavpack/gstwavpackenc.h:
* ext/wavpack/gstwavpackparse.c:
(gst_wavpack_parse_index_append_entry), (gst_wavpack_parse_reset),
(gst_wavpack_parse_scan_to_find_sample),
(gst_wavpack_parse_sink_event), (gst_wavpack_parse_create_src_pad),
(gst_wavpack_parse_push_buffer), (gst_wavpack_parse_loop):
* ext/wavpack/gstwavpackparse.h:
Add support for encoding, parsing and decoding multichannel
files with up to 8 channels. This also improves the robustness
of parsing quite a bit.
* ext/wavpack/gstwavpackstreamreader.c:
(gst_wavpack_stream_reader_read_bytes),
(gst_wavpack_stream_reader_get_pos),
(gst_wavpack_stream_reader_set_pos_abs),
(gst_wavpack_stream_reader_set_pos_rel),
(gst_wavpack_stream_reader_push_back_byte),
(gst_wavpack_stream_reader_get_length),
(gst_wavpack_stream_reader_can_seek),
(gst_wavpack_stream_reader_write_bytes):
Improve debugging.
Diffstat (limited to 'ext/wavpack/gstwavpackdec.c')
-rw-r--r-- | ext/wavpack/gstwavpackdec.c | 48 |
1 files changed, 43 insertions, 5 deletions
diff --git a/ext/wavpack/gstwavpackdec.c b/ext/wavpack/gstwavpackdec.c index c4aa1d04..0dde6c7d 100644 --- a/ext/wavpack/gstwavpackdec.c +++ b/ext/wavpack/gstwavpackdec.c @@ -42,6 +42,7 @@ #include <gst/gst.h> #include <gst/audio/audio.h> +#include <gst/audio/multichannel.h> #include <math.h> #include <string.h> @@ -62,7 +63,7 @@ static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink", GST_PAD_ALWAYS, GST_STATIC_CAPS ("audio/x-wavpack, " "width = (int) [ 1, 32 ], " - "channels = (int) [ 1, 2 ], " + "channels = (int) [ 1, 8 ], " "rate = (int) [ 6000, 192000 ], " "framed = (boolean) true") ); @@ -72,7 +73,7 @@ static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src", GST_STATIC_CAPS ("audio/x-raw-int, " "width = (int) 32, " "depth = (int) [ 1, 32 ], " - "channels = (int) [ 1, 2 ], " + "channels = (int) [ 1, 8 ], " "rate = (int) [ 6000, 192000 ], " "endianness = (int) BYTE_ORDER, " "signed = (boolean) true") ); @@ -126,6 +127,7 @@ gst_wavpack_dec_reset (GstWavpackDec * dec) dec->error_count = 0; dec->channels = 0; + dec->channel_mask = 0; dec->sample_rate = 0; dec->depth = 0; @@ -177,6 +179,7 @@ gst_wavpack_dec_sink_set_caps (GstPad * pad, GstCaps * caps) gst_structure_get_int (structure, "rate", &dec->sample_rate) && gst_structure_get_int (structure, "width", &dec->depth)) { GstCaps *caps; + GstAudioChannelPosition *pos; caps = gst_caps_new_simple ("audio/x-raw-int", "rate", G_TYPE_INT, dec->sample_rate, @@ -186,6 +189,22 @@ gst_wavpack_dec_sink_set_caps (GstPad * pad, GstCaps * caps) "endianness", G_TYPE_INT, G_BYTE_ORDER, "signed", G_TYPE_BOOLEAN, TRUE, NULL); + /* If we already have the channel layout set from upstream + * take this */ + if (gst_structure_has_field (structure, "channel-positions")) { + pos = gst_audio_get_channel_positions (structure); + if (pos != NULL && dec->channels > 2) { + GstStructure *new_str = gst_caps_get_structure (caps, 0); + + gst_audio_set_channel_positions (new_str, pos); + dec->channel_mask = + gst_wavpack_get_channel_mask_from_positions (pos, dec->channels); + } + + if (pos != NULL) + g_free (pos); + } + GST_DEBUG_OBJECT (dec, "setting caps %" GST_PTR_FORMAT, caps); /* should always succeed */ @@ -248,7 +267,10 @@ gst_wavpack_dec_chain (GstPad * pad, GstBuffer * buf) if (!gst_wavpack_read_header (&wph, GST_BUFFER_DATA (buf))) goto invalid_header; - if (GST_BUFFER_SIZE (buf) != wph.ckSize + 4 * 1 + 4) + if (GST_BUFFER_SIZE (buf) < wph.ckSize + 4 * 1 + 4) + goto input_not_framed; + + if (!(wph.flags & INITIAL_BLOCK)) goto input_not_framed; dec->wv_id.buffer = GST_BUFFER_DATA (buf); @@ -282,10 +304,12 @@ gst_wavpack_dec_chain (GstPad * pad, GstBuffer * buf) format_changed = (dec->sample_rate != WavpackGetSampleRate (dec->context)) || (dec->channels != WavpackGetNumChannels (dec->context)) || - (dec->depth != WavpackGetBitsPerSample (dec->context)); + (dec->depth != WavpackGetBitsPerSample (dec->context)) || + (dec->channel_mask != WavpackGetChannelMask (dec->context)); if (!GST_PAD_CAPS (dec->srcpad) || format_changed) { GstCaps *caps; + gint channel_mask; dec->sample_rate = WavpackGetSampleRate (dec->context); dec->channels = WavpackGetNumChannels (dec->context); @@ -299,6 +323,18 @@ gst_wavpack_dec_chain (GstPad * pad, GstBuffer * buf) "endianness", G_TYPE_INT, G_BYTE_ORDER, "signed", G_TYPE_BOOLEAN, TRUE, NULL); + channel_mask = WavpackGetChannelMask (dec->context); + if (channel_mask == 0) + channel_mask = gst_wavpack_get_default_channel_mask (dec->channels); + + dec->channel_mask = channel_mask; + + /* Only set the channel layout for more than two channels + * otherwise things break unfortunately */ + if (channel_mask != 0 && dec->channels > 2) + if (!gst_wavpack_set_channel_layout (caps, channel_mask)) + GST_WARNING_OBJECT (dec, "Failed to set channel layout"); + GST_DEBUG_OBJECT (dec, "setting caps %" GST_PTR_FORMAT, caps); /* should always succeed */ @@ -367,7 +403,9 @@ invalid_header: decode_error: { GST_ELEMENT_ERROR (dec, STREAM, DECODE, (NULL), - ("Failed to decode wavpack stream")); + ("Failed to decode wavpack stream: %s", + (dec->context) ? WavpackGetErrorMessage (dec-> + context) : "couldn't create decoder context")); gst_buffer_unref (outbuf); gst_buffer_unref (buf); return GST_FLOW_ERROR; |