mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 04:01:08 +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>
|
||||
|
||||
* gst/rtsp/rtspconnection.c:
|
||||
|
|
|
@ -195,8 +195,7 @@ gst_wavenc_create_header_buf (GstWavEnc * wavenc, guint audio_data_size)
|
|||
wave.format.len = 16;
|
||||
|
||||
wave.common.wFormatTag = WAVE_FORMAT_PCM;
|
||||
wave.common.wBlockAlign =
|
||||
(GST_ROUND_UP_8 (wavenc->depth) / 8) * wave.common.wChannels;
|
||||
wave.common.wBlockAlign = (wavenc->width / 8) * wave.common.wChannels;
|
||||
wave.common.dwAvgBytesPerSec =
|
||||
wave.common.wBlockAlign * wave.common.dwSamplesPerSec;
|
||||
|
||||
|
@ -275,10 +274,11 @@ gst_wavenc_sink_setcaps (GstPad * pad, GstCaps * caps)
|
|||
|
||||
wavenc->channels = chans;
|
||||
wavenc->depth = depth;
|
||||
wavenc->width = width;
|
||||
wavenc->rate = rate;
|
||||
|
||||
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);
|
||||
return TRUE;
|
||||
|
@ -608,6 +608,52 @@ gst_wavenc_event (GstPad * pad, GstEvent * event)
|
|||
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
|
||||
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_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);
|
||||
}
|
||||
|
||||
gst_buffer_set_caps (buf, GST_PAD_CAPS (wavenc->srcpad));
|
||||
GST_BUFFER_OFFSET (buf) = WAV_HEADER_LEN + wavenc->length;
|
||||
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:
|
||||
wavenc->channels = 0;
|
||||
wavenc->depth = 0;
|
||||
wavenc->width = 0;
|
||||
wavenc->rate = 0;
|
||||
wavenc->length = 0;
|
||||
wavenc->sent_header = FALSE;
|
||||
|
|
|
@ -47,6 +47,7 @@ struct _GstWavEnc {
|
|||
GstPad *srcpad;
|
||||
|
||||
/* useful audio data */
|
||||
guint width;
|
||||
guint depth;
|
||||
guint rate;
|
||||
guint channels;
|
||||
|
|
Loading…
Reference in a new issue