summaryrefslogtreecommitdiffstats
path: root/ext/wavpack/gstwavpackparse.c
diff options
context:
space:
mode:
authorSebastian Dröge <slomo@circular-chaos.org>2007-11-20 13:08:45 +0000
committerSebastian Dröge <slomo@circular-chaos.org>2007-11-20 13:08:45 +0000
commitded2cc6e39501f249ac16b88f18c1a92e136b95a (patch)
treed483394ee5020f2e84336e6996a4603f0494e7cc /ext/wavpack/gstwavpackparse.c
parentdfdc0fa8c9ee0dce74fa4b353209356baea620c8 (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.c69
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)