mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-04 21:42:25 +00:00
gst/matroska/: Fix demuxing of WavPack files. Muxing is still broken.
Original commit message from CVS: * gst/matroska/matroska-demux.c: (gst_matroska_demux_add_wvpk_header), (gst_matroska_demux_audio_caps): * gst/matroska/matroska-ids.h: Fix demuxing of WavPack files. Muxing is still broken.
This commit is contained in:
parent
7afcb8068a
commit
96da520095
3 changed files with 135 additions and 37 deletions
|
@ -1,3 +1,11 @@
|
||||||
|
2008-06-19 Sebastian Dröge <slomo@circular-chaos.org>
|
||||||
|
|
||||||
|
* gst/matroska/matroska-demux.c:
|
||||||
|
(gst_matroska_demux_add_wvpk_header),
|
||||||
|
(gst_matroska_demux_audio_caps):
|
||||||
|
* gst/matroska/matroska-ids.h:
|
||||||
|
Fix demuxing of WavPack files. Muxing is still broken.
|
||||||
|
|
||||||
2008-06-19 Sebastian Dröge <slomo@circular-chaos.org>
|
2008-06-19 Sebastian Dröge <slomo@circular-chaos.org>
|
||||||
|
|
||||||
* gst/matroska/matroska-demux.c: (gst_matroska_track_free),
|
* gst/matroska/matroska-demux.c: (gst_matroska_track_free),
|
||||||
|
|
|
@ -3315,62 +3315,149 @@ gst_matroska_demux_add_wvpk_header (GstElement * element,
|
||||||
{
|
{
|
||||||
GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
|
GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (element);
|
||||||
|
|
||||||
GstBuffer *newbuf;
|
GstMatroskaTrackAudioContext *audiocontext =
|
||||||
|
(GstMatroskaTrackAudioContext *) stream;
|
||||||
|
GstBuffer *newbuf = NULL;
|
||||||
|
|
||||||
guint8 *data;
|
guint8 *data;
|
||||||
|
|
||||||
guint newlen;
|
guint newlen;
|
||||||
|
|
||||||
GstFlowReturn ret, cret;
|
GstFlowReturn ret, cret = GST_FLOW_OK;
|
||||||
|
|
||||||
/* we need to reconstruct the header of the wavpack block */
|
|
||||||
Wavpack4Header wvh;
|
Wavpack4Header wvh;
|
||||||
|
|
||||||
/* FIXME: broken for > 2 channels and hybrid files
|
|
||||||
http://www.matroska.org/technical/specs/codecid/wavpack.html */
|
|
||||||
|
|
||||||
wvh.ck_id[0] = 'w';
|
wvh.ck_id[0] = 'w';
|
||||||
wvh.ck_id[1] = 'v';
|
wvh.ck_id[1] = 'v';
|
||||||
wvh.ck_id[2] = 'p';
|
wvh.ck_id[2] = 'p';
|
||||||
wvh.ck_id[3] = 'k';
|
wvh.ck_id[3] = 'k';
|
||||||
/* -20 because ck_size is the size of the wavpack block -8
|
|
||||||
* and lace_size is the size of the wavpack block + 12
|
|
||||||
* (the three guint32 of the header that already are in the buffer) */
|
|
||||||
wvh.ck_size = GST_BUFFER_SIZE (*buf) + sizeof (Wavpack4Header) - 20;
|
|
||||||
wvh.version = GST_READ_UINT16_LE (stream->codec_priv);
|
wvh.version = GST_READ_UINT16_LE (stream->codec_priv);
|
||||||
wvh.track_no = 0;
|
wvh.track_no = 0;
|
||||||
wvh.index_no = 0;
|
wvh.index_no = 0;
|
||||||
wvh.total_samples = -1;
|
wvh.total_samples = -1;
|
||||||
wvh.block_index = 0;
|
wvh.block_index = audiocontext->wvpk_block_index;
|
||||||
|
|
||||||
/* block_samples, flags and crc are already in the buffer */
|
if (audiocontext->channels <= 2) {
|
||||||
newlen = GST_BUFFER_SIZE (*buf) + sizeof (Wavpack4Header) - 12;
|
guint32 block_samples;
|
||||||
ret = gst_pad_alloc_buffer_and_set_caps (stream->pad, GST_BUFFER_OFFSET_NONE,
|
|
||||||
newlen, stream->caps, &newbuf);
|
block_samples = GST_READ_UINT32_LE (GST_BUFFER_DATA (*buf));
|
||||||
cret = gst_matroska_demux_combine_flows (demux, stream, ret);
|
/* we need to reconstruct the header of the wavpack block */
|
||||||
if (ret != GST_FLOW_OK) {
|
|
||||||
GST_DEBUG_OBJECT (demux, "pad_alloc failed %s, combined %s",
|
/* -20 because ck_size is the size of the wavpack block -8
|
||||||
gst_flow_get_name (ret), gst_flow_get_name (cret));
|
* and lace_size is the size of the wavpack block + 12
|
||||||
return cret;
|
* (the three guint32 of the header that already are in the buffer) */
|
||||||
|
wvh.ck_size = GST_BUFFER_SIZE (*buf) + sizeof (Wavpack4Header) - 20;
|
||||||
|
|
||||||
|
/* block_samples, flags and crc are already in the buffer */
|
||||||
|
newlen = GST_BUFFER_SIZE (*buf) + sizeof (Wavpack4Header) - 12;
|
||||||
|
ret =
|
||||||
|
gst_pad_alloc_buffer_and_set_caps (stream->pad, GST_BUFFER_OFFSET_NONE,
|
||||||
|
newlen, stream->caps, &newbuf);
|
||||||
|
cret = gst_matroska_demux_combine_flows (demux, stream, ret);
|
||||||
|
if (ret != GST_FLOW_OK) {
|
||||||
|
GST_DEBUG_OBJECT (demux, "pad_alloc failed %s, combined %s",
|
||||||
|
gst_flow_get_name (ret), gst_flow_get_name (cret));
|
||||||
|
return cret;
|
||||||
|
}
|
||||||
|
|
||||||
|
data = GST_BUFFER_DATA (newbuf);
|
||||||
|
data[0] = 'w';
|
||||||
|
data[1] = 'v';
|
||||||
|
data[2] = 'p';
|
||||||
|
data[3] = 'k';
|
||||||
|
GST_WRITE_UINT32_LE (data + 4, wvh.ck_size);
|
||||||
|
GST_WRITE_UINT16_LE (data + 8, wvh.version);
|
||||||
|
GST_WRITE_UINT8 (data + 10, wvh.track_no);
|
||||||
|
GST_WRITE_UINT8 (data + 11, wvh.index_no);
|
||||||
|
GST_WRITE_UINT32_LE (data + 12, wvh.total_samples);
|
||||||
|
GST_WRITE_UINT32_LE (data + 16, wvh.block_index);
|
||||||
|
g_memmove (data + 20, GST_BUFFER_DATA (*buf), GST_BUFFER_SIZE (*buf));
|
||||||
|
gst_buffer_copy_metadata (newbuf, *buf,
|
||||||
|
GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS);
|
||||||
|
gst_buffer_unref (*buf);
|
||||||
|
*buf = newbuf;
|
||||||
|
audiocontext->wvpk_block_index += block_samples;
|
||||||
|
} else {
|
||||||
|
guint8 *outdata;
|
||||||
|
|
||||||
|
guint outpos = 0;
|
||||||
|
|
||||||
|
guint size;
|
||||||
|
|
||||||
|
guint32 block_samples, flags, crc, blocksize;
|
||||||
|
|
||||||
|
data = GST_BUFFER_DATA (*buf);
|
||||||
|
size = GST_BUFFER_SIZE (*buf);
|
||||||
|
|
||||||
|
if (size < 4) {
|
||||||
|
GST_ERROR_OBJECT (demux, "Too small wavpack buffer");
|
||||||
|
return GST_FLOW_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
block_samples = GST_READ_UINT32_LE (data);
|
||||||
|
data += 4;
|
||||||
|
size -= 4;
|
||||||
|
|
||||||
|
while (size > 12) {
|
||||||
|
flags = GST_READ_UINT32_LE (data);
|
||||||
|
data += 4;
|
||||||
|
size -= 4;
|
||||||
|
crc = GST_READ_UINT32_LE (data);
|
||||||
|
data += 4;
|
||||||
|
size -= 4;
|
||||||
|
blocksize = GST_READ_UINT32_LE (data);
|
||||||
|
data += 4;
|
||||||
|
size -= 4;
|
||||||
|
|
||||||
|
if (blocksize == 0 || size < blocksize)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (newbuf == NULL) {
|
||||||
|
newbuf = gst_buffer_new_and_alloc (sizeof (Wavpack4Header) + blocksize);
|
||||||
|
gst_buffer_set_caps (newbuf, stream->caps);
|
||||||
|
|
||||||
|
gst_buffer_copy_metadata (newbuf, *buf,
|
||||||
|
GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS);
|
||||||
|
|
||||||
|
outpos = 0;
|
||||||
|
outdata = GST_BUFFER_DATA (newbuf);
|
||||||
|
} else {
|
||||||
|
GST_BUFFER_SIZE (newbuf) += sizeof (Wavpack4Header) + blocksize;
|
||||||
|
GST_BUFFER_DATA (newbuf) =
|
||||||
|
g_realloc (GST_BUFFER_DATA (newbuf), GST_BUFFER_SIZE (newbuf));
|
||||||
|
GST_BUFFER_MALLOCDATA (newbuf) = GST_BUFFER_DATA (newbuf);
|
||||||
|
outdata = GST_BUFFER_DATA (newbuf);
|
||||||
|
}
|
||||||
|
|
||||||
|
outdata[outpos] = 'w';
|
||||||
|
outdata[outpos + 1] = 'v';
|
||||||
|
outdata[outpos + 2] = 'p';
|
||||||
|
outdata[outpos + 3] = 'k';
|
||||||
|
outpos += 4;
|
||||||
|
|
||||||
|
GST_WRITE_UINT32_LE (outdata + outpos,
|
||||||
|
blocksize + sizeof (Wavpack4Header) - 8);
|
||||||
|
GST_WRITE_UINT16_LE (outdata + outpos + 4, wvh.version);
|
||||||
|
GST_WRITE_UINT8 (outdata + outpos + 6, wvh.track_no);
|
||||||
|
GST_WRITE_UINT8 (outdata + outpos + 7, wvh.index_no);
|
||||||
|
GST_WRITE_UINT32_LE (outdata + outpos + 8, wvh.total_samples);
|
||||||
|
GST_WRITE_UINT32_LE (outdata + outpos + 12, wvh.block_index);
|
||||||
|
GST_WRITE_UINT32_LE (outdata + outpos + 16, block_samples);
|
||||||
|
GST_WRITE_UINT32_LE (outdata + outpos + 20, flags);
|
||||||
|
GST_WRITE_UINT32_LE (outdata + outpos + 24, crc);
|
||||||
|
outpos += 28;
|
||||||
|
|
||||||
|
g_memmove (outdata + outpos, data, blocksize);
|
||||||
|
outpos += blocksize;
|
||||||
|
data += blocksize;
|
||||||
|
size -= blocksize;
|
||||||
|
}
|
||||||
|
gst_buffer_unref (*buf);
|
||||||
|
*buf = newbuf;
|
||||||
|
audiocontext->wvpk_block_index += block_samples;
|
||||||
}
|
}
|
||||||
|
|
||||||
data = GST_BUFFER_DATA (newbuf);
|
|
||||||
data[0] = 'w';
|
|
||||||
data[1] = 'v';
|
|
||||||
data[2] = 'p';
|
|
||||||
data[3] = 'k';
|
|
||||||
GST_WRITE_UINT32_LE (data + 4, wvh.ck_size);
|
|
||||||
GST_WRITE_UINT16_LE (data + 8, wvh.version);
|
|
||||||
GST_WRITE_UINT8 (data + 10, wvh.track_no);
|
|
||||||
GST_WRITE_UINT8 (data + 11, wvh.index_no);
|
|
||||||
GST_WRITE_UINT32_LE (data + 12, wvh.total_samples);
|
|
||||||
GST_WRITE_UINT32_LE (data + 16, wvh.block_index);
|
|
||||||
g_memmove (data + 20, GST_BUFFER_DATA (*buf), GST_BUFFER_SIZE (*buf));
|
|
||||||
gst_buffer_copy_metadata (newbuf, *buf,
|
|
||||||
GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS);
|
|
||||||
gst_buffer_unref (*buf);
|
|
||||||
*buf = newbuf;
|
|
||||||
|
|
||||||
return cret;
|
return cret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5066,6 +5153,7 @@ gst_matroska_demux_audio_caps (GstMatroskaTrackAudioContext *
|
||||||
"framed", G_TYPE_BOOLEAN, TRUE, NULL);
|
"framed", G_TYPE_BOOLEAN, TRUE, NULL);
|
||||||
*codec_name = g_strdup ("Wavpack audio");
|
*codec_name = g_strdup ("Wavpack audio");
|
||||||
context->postprocess_frame = gst_matroska_demux_add_wvpk_header;
|
context->postprocess_frame = gst_matroska_demux_add_wvpk_header;
|
||||||
|
audiocontext->wvpk_block_index = 0;
|
||||||
} else if ((!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_14_4)) ||
|
} else if ((!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_14_4)) ||
|
||||||
(!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_14_4)) ||
|
(!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_14_4)) ||
|
||||||
(!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_COOK))) {
|
(!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_REAL_COOK))) {
|
||||||
|
|
|
@ -523,6 +523,8 @@ typedef struct _GstMatroskaTrackAudioContext {
|
||||||
GstMatroskaTrackContext parent;
|
GstMatroskaTrackContext parent;
|
||||||
|
|
||||||
guint samplerate, channels, bitdepth;
|
guint samplerate, channels, bitdepth;
|
||||||
|
|
||||||
|
guint32 wvpk_block_index;
|
||||||
} GstMatroskaTrackAudioContext;
|
} GstMatroskaTrackAudioContext;
|
||||||
|
|
||||||
typedef struct _GstMatroskaTrackSubtitleContext {
|
typedef struct _GstMatroskaTrackSubtitleContext {
|
||||||
|
|
Loading…
Reference in a new issue