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/gstwavpackparse.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/gstwavpackparse.c')
-rw-r--r-- | ext/wavpack/gstwavpackparse.c | 69 |
1 files changed, 62 insertions, 7 deletions
diff --git a/ext/wavpack/gstwavpackparse.c b/ext/wavpack/gstwavpackparse.c index 3ab84b4c..71c4d83d 100644 --- a/ext/wavpack/gstwavpackparse.c +++ b/ext/wavpack/gstwavpackparse.c @@ -70,7 +70,7 @@ static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src", GST_PAD_SOMETIMES, 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") ); @@ -189,7 +189,8 @@ gst_wavpack_parse_index_append_entry (GstWavpackParse * wvparse, /* do we have this one already? */ if (wvparse->entries) { entry = gst_wavpack_parse_index_get_last_entry (wvparse); - if (entry->byte_offset >= byte_offset) + if (entry->byte_offset >= byte_offset + || entry->sample_offset >= sample_offset) return; } @@ -245,6 +246,11 @@ gst_wavpack_parse_reset (GstWavpackParse * parse) g_list_foreach (parse->queued_events, (GFunc) gst_mini_object_unref, NULL); g_list_free (parse->queued_events); parse->queued_events = NULL; + + if (parse->pending_buffer) + gst_buffer_unref (parse->pending_buffer); + + parse->pending_buffer = NULL; } static const GstQueryType * @@ -422,8 +428,11 @@ gst_wavpack_parse_scan_to_find_sample (GstWavpackParse * parse, gst_wavpack_read_header (&header, GST_BUFFER_DATA (buf)); gst_buffer_unref (buf); - gst_wavpack_parse_index_append_entry (parse, off, header.block_index, - header.block_samples); + if (header.flags & INITIAL_BLOCK) + gst_wavpack_parse_index_append_entry (parse, off, header.block_index, + header.block_samples); + else + continue; if (header.block_index <= sample && sample < (header.block_index + header.block_samples)) { @@ -631,6 +640,11 @@ gst_wavpack_parse_sink_event (GstPad * pad, GstEvent * event) if (parse->adapter) { gst_adapter_clear (parse->adapter); } + if (parse->pending_buffer) { + gst_buffer_unref (parse->pending_buffer); + parse->pending_buffer = NULL; + parse->pending_offset = 0; + } ret = gst_pad_push_event (parse->srcpad, event); break; } @@ -646,6 +660,11 @@ gst_wavpack_parse_sink_event (GstPad * pad, GstEvent * event) * be a complete Wavpack block and we can't do anything with them */ gst_adapter_clear (parse->adapter); } + if (parse->pending_buffer) { + gst_buffer_unref (parse->pending_buffer); + parse->pending_buffer = NULL; + parse->pending_offset = 0; + } ret = gst_pad_push_event (parse->srcpad, event); break; } @@ -794,6 +813,7 @@ gst_wavpack_parse_create_src_pad (GstWavpackParse * wvparse, GstBuffer * buf, WavpackContext *wpc; gchar error_msg[80]; read_id rid; + gint channel_mask; rid.buffer = GST_BUFFER_DATA (buf); rid.length = GST_BUFFER_SIZE (buf); @@ -816,6 +836,23 @@ gst_wavpack_parse_create_src_pad (GstWavpackParse * wvparse, GstBuffer * buf, "channels", G_TYPE_INT, wvparse->channels, "rate", G_TYPE_INT, wvparse->samplerate, "framed", G_TYPE_BOOLEAN, TRUE, NULL); + + channel_mask = WavpackGetChannelMask (wpc); + if (channel_mask == 0) + channel_mask = + gst_wavpack_get_default_channel_mask (wvparse->channels); + + if (channel_mask != 0) { + if (!gst_wavpack_set_channel_layout (caps, channel_mask)) { + GST_WARNING_OBJECT (wvparse, "Failed to set channel layout"); + gst_caps_unref (caps); + caps = NULL; + WavpackCloseFile (wpc); + g_free (stream_reader); + break; + } + } + wvparse->srcpad = gst_pad_new_from_template (gst_element_class_get_pad_template (GST_ELEMENT_GET_CLASS (wvparse), "src"), "src"); @@ -880,6 +917,24 @@ gst_wavpack_parse_push_buffer (GstWavpackParse * wvparse, GstBuffer * buf, wvparse->queued_events = NULL; } + if (wvparse->pending_buffer == NULL) { + wvparse->pending_buffer = buf; + wvparse->pending_offset = header->block_index; + } else if (wvparse->pending_offset == header->block_index) { + wvparse->pending_buffer = gst_buffer_join (wvparse->pending_buffer, buf); + } else { + GST_ERROR ("Got incomplete block, dropping"); + gst_buffer_unref (wvparse->pending_buffer); + wvparse->pending_buffer = buf; + wvparse->pending_offset = header->block_index; + } + + if (!(header->flags & FINAL_BLOCK)) + return GST_FLOW_OK; + + buf = wvparse->pending_buffer; + wvparse->pending_buffer = NULL; + GST_BUFFER_TIMESTAMP (buf) = gst_util_uint64_scale_int (header->block_index, GST_SECOND, wvparse->samplerate); GST_BUFFER_DURATION (buf) = gst_util_uint64_scale_int (header->block_samples, @@ -1014,9 +1069,9 @@ gst_wavpack_parse_loop (GstElement * element) goto pause; } } - - gst_wavpack_parse_index_append_entry (parse, parse->current_offset, - header.block_index, header.block_samples); + if (header.flags & INITIAL_BLOCK) + gst_wavpack_parse_index_append_entry (parse, parse->current_offset, + header.block_index, header.block_samples); flow_ret = gst_wavpack_parse_push_buffer (parse, buf, &header); if (flow_ret != GST_FLOW_OK) |