mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-20 08:41:07 +00:00
gst/wavenc/gstwavenc.*: Properly write wav files with width!=depth by having the depth most significant bytes set and...
Original commit message from CVS: * gst/wavenc/gstwavenc.c: (gst_wavenc_create_header_buf), (gst_wavenc_sink_setcaps), (gst_wavenc_format_samples), (gst_wavenc_chain), (gst_wavenc_change_state): * gst/wavenc/gstwavenc.h: Properly write wav files with width!=depth by having the depth most significant bytes set and all others zero. Fixes #442535.
This commit is contained in:
parent
6ce8b13eb4
commit
10da08ace4
3 changed files with 67 additions and 4 deletions
|
@ -1,3 +1,12 @@
|
||||||
|
2007-06-03 Sebastian Dröge <slomo@circular-chaos.org>
|
||||||
|
|
||||||
|
* gst/wavenc/gstwavenc.c: (gst_wavenc_create_header_buf),
|
||||||
|
(gst_wavenc_sink_setcaps), (gst_wavenc_format_samples),
|
||||||
|
(gst_wavenc_chain), (gst_wavenc_change_state):
|
||||||
|
* gst/wavenc/gstwavenc.h:
|
||||||
|
Properly write wav files with width!=depth by having the depth most
|
||||||
|
significant bytes set and all others zero. Fixes #442535.
|
||||||
|
|
||||||
2007-06-01 Wim Taymans <wim@fluendo.com>
|
2007-06-01 Wim Taymans <wim@fluendo.com>
|
||||||
|
|
||||||
* gst/rtsp/rtspconnection.c:
|
* gst/rtsp/rtspconnection.c:
|
||||||
|
|
|
@ -195,8 +195,7 @@ gst_wavenc_create_header_buf (GstWavEnc * wavenc, guint audio_data_size)
|
||||||
wave.format.len = 16;
|
wave.format.len = 16;
|
||||||
|
|
||||||
wave.common.wFormatTag = WAVE_FORMAT_PCM;
|
wave.common.wFormatTag = WAVE_FORMAT_PCM;
|
||||||
wave.common.wBlockAlign =
|
wave.common.wBlockAlign = (wavenc->width / 8) * wave.common.wChannels;
|
||||||
(GST_ROUND_UP_8 (wavenc->depth) / 8) * wave.common.wChannels;
|
|
||||||
wave.common.dwAvgBytesPerSec =
|
wave.common.dwAvgBytesPerSec =
|
||||||
wave.common.wBlockAlign * wave.common.dwSamplesPerSec;
|
wave.common.wBlockAlign * wave.common.dwSamplesPerSec;
|
||||||
|
|
||||||
|
@ -275,10 +274,11 @@ gst_wavenc_sink_setcaps (GstPad * pad, GstCaps * caps)
|
||||||
|
|
||||||
wavenc->channels = chans;
|
wavenc->channels = chans;
|
||||||
wavenc->depth = depth;
|
wavenc->depth = depth;
|
||||||
|
wavenc->width = width;
|
||||||
wavenc->rate = rate;
|
wavenc->rate = rate;
|
||||||
|
|
||||||
GST_LOG_OBJECT (wavenc, "accepted caps: chans=%u width=%u depth=%u rate=%u",
|
GST_LOG_OBJECT (wavenc, "accepted caps: chans=%u width=%u depth=%u rate=%u",
|
||||||
wavenc->channels, width, wavenc->depth, wavenc->rate);
|
wavenc->channels, wavenc->width, wavenc->depth, wavenc->rate);
|
||||||
|
|
||||||
gst_object_unref (wavenc);
|
gst_object_unref (wavenc);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -608,6 +608,52 @@ gst_wavenc_event (GstPad * pad, GstEvent * event)
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Copied from gst-plugins-base/gst/audioconvert/audioconvert.c */
|
||||||
|
#define READ24_FROM_LE(p) (p[0] | (p[1] << 8) | (p[2] << 16))
|
||||||
|
#define WRITE24_TO_LE(p,v) p[0] = v & 0xff; p[1] = (v >> 8) & 0xff; p[2] = (v >> 16) & 0xff
|
||||||
|
|
||||||
|
/* Correctly format samples with width!=depth for the wav format, i.e.
|
||||||
|
* have the data in the highest depth bits and all others zero */
|
||||||
|
static void
|
||||||
|
gst_wavenc_format_samples (GstBuffer * buf, guint width, guint depth)
|
||||||
|
{
|
||||||
|
guint8 *data = GST_BUFFER_DATA (buf);
|
||||||
|
guint nsamples = (GST_BUFFER_SIZE (buf) * 8) / width;
|
||||||
|
guint32 tmp;
|
||||||
|
|
||||||
|
for (; nsamples; nsamples--) {
|
||||||
|
switch (width) {
|
||||||
|
|
||||||
|
case 8:
|
||||||
|
tmp = *data;
|
||||||
|
*data = *data << (width - depth);
|
||||||
|
data += 1;
|
||||||
|
break;
|
||||||
|
case 16:
|
||||||
|
tmp = GST_READ_UINT16_LE (data);
|
||||||
|
tmp = tmp << (width - depth);
|
||||||
|
GST_WRITE_UINT16_LE (data, tmp);
|
||||||
|
data += 2;
|
||||||
|
break;
|
||||||
|
case 24:
|
||||||
|
tmp = READ24_FROM_LE (data);
|
||||||
|
tmp = tmp << (width - depth);
|
||||||
|
WRITE24_TO_LE (data, tmp);
|
||||||
|
data += 3;
|
||||||
|
break;
|
||||||
|
case 32:
|
||||||
|
tmp = GST_READ_UINT32_LE (data);
|
||||||
|
tmp = tmp << (width - depth);
|
||||||
|
GST_WRITE_UINT32_LE (data, tmp);
|
||||||
|
data += 4;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef READ24_FROM_LE
|
||||||
|
#undef WRITE24_TO_LE
|
||||||
|
|
||||||
static GstFlowReturn
|
static GstFlowReturn
|
||||||
gst_wavenc_chain (GstPad * pad, GstBuffer * buf)
|
gst_wavenc_chain (GstPad * pad, GstBuffer * buf)
|
||||||
{
|
{
|
||||||
|
@ -633,7 +679,13 @@ gst_wavenc_chain (GstPad * pad, GstBuffer * buf)
|
||||||
GST_LOG_OBJECT (wavenc, "pushing %u bytes raw audio, ts=%" GST_TIME_FORMAT,
|
GST_LOG_OBJECT (wavenc, "pushing %u bytes raw audio, ts=%" GST_TIME_FORMAT,
|
||||||
GST_BUFFER_SIZE (buf), GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)));
|
GST_BUFFER_SIZE (buf), GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)));
|
||||||
|
|
||||||
|
if (wavenc->width != wavenc->depth) {
|
||||||
|
buf = gst_buffer_make_writable (buf);
|
||||||
|
gst_wavenc_format_samples (buf, wavenc->width, wavenc->depth);
|
||||||
|
} else {
|
||||||
buf = gst_buffer_make_metadata_writable (buf);
|
buf = gst_buffer_make_metadata_writable (buf);
|
||||||
|
}
|
||||||
|
|
||||||
gst_buffer_set_caps (buf, GST_PAD_CAPS (wavenc->srcpad));
|
gst_buffer_set_caps (buf, GST_PAD_CAPS (wavenc->srcpad));
|
||||||
GST_BUFFER_OFFSET (buf) = WAV_HEADER_LEN + wavenc->length;
|
GST_BUFFER_OFFSET (buf) = WAV_HEADER_LEN + wavenc->length;
|
||||||
GST_BUFFER_OFFSET_END (buf) = GST_BUFFER_OFFSET_NONE;
|
GST_BUFFER_OFFSET_END (buf) = GST_BUFFER_OFFSET_NONE;
|
||||||
|
@ -653,6 +705,7 @@ gst_wavenc_change_state (GstElement * element, GstStateChange transition)
|
||||||
case GST_STATE_CHANGE_NULL_TO_READY:
|
case GST_STATE_CHANGE_NULL_TO_READY:
|
||||||
wavenc->channels = 0;
|
wavenc->channels = 0;
|
||||||
wavenc->depth = 0;
|
wavenc->depth = 0;
|
||||||
|
wavenc->width = 0;
|
||||||
wavenc->rate = 0;
|
wavenc->rate = 0;
|
||||||
wavenc->length = 0;
|
wavenc->length = 0;
|
||||||
wavenc->sent_header = FALSE;
|
wavenc->sent_header = FALSE;
|
||||||
|
|
|
@ -47,6 +47,7 @@ struct _GstWavEnc {
|
||||||
GstPad *srcpad;
|
GstPad *srcpad;
|
||||||
|
|
||||||
/* useful audio data */
|
/* useful audio data */
|
||||||
|
guint width;
|
||||||
guint depth;
|
guint depth;
|
||||||
guint rate;
|
guint rate;
|
||||||
guint channels;
|
guint channels;
|
||||||
|
|
Loading…
Reference in a new issue