summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ext/flac/gstflacdec.c57
-rw-r--r--ext/flac/gstflacenc.c96
-rw-r--r--ext/flac/gstflacenc.h1
3 files changed, 119 insertions, 35 deletions
diff --git a/ext/flac/gstflacdec.c b/ext/flac/gstflacdec.c
index 0df31a0e..0c14598d 100644
--- a/ext/flac/gstflacdec.c
+++ b/ext/flac/gstflacdec.c
@@ -65,7 +65,8 @@ static gboolean gst_flacdec_src_event (GstPad *pad, GstEvent *event);
static FLAC__SeekableStreamDecoderReadStatus
gst_flacdec_read (const FLAC__SeekableStreamDecoder *decoder,
- FLAC__byte buffer[], unsigned *bytes, void *client_data);
+ FLAC__byte buffer[], unsigned *bytes,
+ void *client_data);
static FLAC__SeekableStreamDecoderSeekStatus
gst_flacdec_seek (const FLAC__SeekableStreamDecoder *decoder,
FLAC__uint64 position, void *client_data);
@@ -79,7 +80,8 @@ static FLAC__bool gst_flacdec_eof (const FLAC__SeekableStreamDecoder *decoder
void *client_data);
static FLAC__StreamDecoderWriteStatus
gst_flacdec_write (const FLAC__SeekableStreamDecoder *decoder,
- const FLAC__Frame *frame, const FLAC__int32 * const buffer[],
+ const FLAC__Frame *frame,
+ const FLAC__int32 * const buffer[],
void *client_data);
static void gst_flacdec_metadata_callback (const FLAC__SeekableStreamDecoder *decoder,
const FLAC__StreamMetadata *metadata,
@@ -199,7 +201,8 @@ gst_flacdec_error_callback (const FLAC__SeekableStreamDecoder *decoder,
}
static FLAC__SeekableStreamDecoderSeekStatus
-gst_flacdec_seek (const FLAC__SeekableStreamDecoder *decoder, FLAC__uint64 position, void *client_data)
+gst_flacdec_seek (const FLAC__SeekableStreamDecoder *decoder,
+ FLAC__uint64 position, void *client_data)
{
FlacDec *flacdec;
@@ -213,7 +216,8 @@ gst_flacdec_seek (const FLAC__SeekableStreamDecoder *decoder, FLAC__uint64 posit
}
static FLAC__SeekableStreamDecoderTellStatus
-gst_flacdec_tell (const FLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *position, void *client_data)
+gst_flacdec_tell (const FLAC__SeekableStreamDecoder *decoder,
+ FLAC__uint64 *position, void *client_data)
{
FlacDec *flacdec;
@@ -229,7 +233,8 @@ gst_flacdec_tell (const FLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *posi
}
static FLAC__SeekableStreamDecoderLengthStatus
-gst_flacdec_length (const FLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *length, void *client_data)
+gst_flacdec_length (const FLAC__SeekableStreamDecoder *decoder,
+ FLAC__uint64 *length, void *client_data)
{
FlacDec *flacdec;
@@ -245,7 +250,8 @@ gst_flacdec_length (const FLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *le
}
static FLAC__bool
-gst_flacdec_eof (const FLAC__SeekableStreamDecoder *decoder, void *client_data)
+gst_flacdec_eof (const FLAC__SeekableStreamDecoder *decoder,
+ void *client_data)
{
FlacDec *flacdec;
@@ -256,7 +262,9 @@ gst_flacdec_eof (const FLAC__SeekableStreamDecoder *decoder, void *client_data)
}
static FLAC__SeekableStreamDecoderReadStatus
-gst_flacdec_read (const FLAC__SeekableStreamDecoder *decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data)
+gst_flacdec_read (const FLAC__SeekableStreamDecoder *decoder,
+ FLAC__byte buffer[], unsigned *bytes,
+ void *client_data)
{
FlacDec *flacdec;
gint insize = 0;
@@ -309,8 +317,10 @@ gst_flacdec_read (const FLAC__SeekableStreamDecoder *decoder, FLAC__byte buffer[
}
static FLAC__StreamDecoderWriteStatus
-gst_flacdec_write (const FLAC__SeekableStreamDecoder *decoder, const FLAC__Frame *frame,
- const FLAC__int32 * const buffer[], void *client_data)
+gst_flacdec_write (const FLAC__SeekableStreamDecoder *decoder,
+ const FLAC__Frame *frame,
+ const FLAC__int32 * const buffer[],
+ void *client_data)
{
FlacDec *flacdec;
GstBuffer *outbuf;
@@ -342,7 +352,8 @@ gst_flacdec_write (const FLAC__SeekableStreamDecoder *decoder, const FLAC__Frame
&format, &bytes);
discont = gst_event_new_discontinuous (FALSE, GST_FORMAT_TIME, time,
GST_FORMAT_BYTES, bytes,
- GST_FORMAT_UNITS, flacdec->total_samples, NULL);
+ GST_FORMAT_UNITS, flacdec->total_samples,
+ NULL);
gst_pad_push (flacdec->srcpad, GST_BUFFER (discont));
}
@@ -417,9 +428,12 @@ gst_flacdec_loop (GstElement *element)
}
if (flacdec->seek_pending) {
- GST_DEBUG (GST_CAT_EVENT, "perform seek to sample %lld\n", flacdec->seek_value);
+ GST_DEBUG (GST_CAT_EVENT, "perform seek to sample %lld\n",
+ flacdec->seek_value);
- if (FLAC__seekable_stream_decoder_seek_absolute(flacdec->decoder, flacdec->seek_value)) {
+ if (FLAC__seekable_stream_decoder_seek_absolute (flacdec->decoder,
+ flacdec->seek_value))
+ {
flacdec->total_samples = flacdec->seek_value;
GST_DEBUG (GST_CAT_EVENT, "seek done\n");
}
@@ -430,7 +444,9 @@ gst_flacdec_loop (GstElement *element)
}
res = FLAC__seekable_stream_decoder_process_one_frame (flacdec->decoder);
- if (FLAC__seekable_stream_decoder_get_state (flacdec->decoder) == FLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM) {
+ if (FLAC__seekable_stream_decoder_get_state (flacdec->decoder) ==
+ FLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM)
+ {
GstEvent *event;
FLAC__seekable_stream_decoder_finish(flacdec->decoder);
@@ -539,11 +555,17 @@ gst_flacdec_src_query (GstPad *pad, GstPadQueryType type,
else
samples = flacdec->stream_samples;
- gst_pad_convert (flacdec->srcpad, GST_FORMAT_UNITS, samples, format, value);
+ gst_pad_convert (flacdec->srcpad,
+ GST_FORMAT_UNITS,
+ samples,
+ format, value);
break;
}
case GST_PAD_QUERY_POSITION:
- gst_pad_convert (flacdec->srcpad, GST_FORMAT_UNITS, flacdec->total_samples, format, value);
+ gst_pad_convert (flacdec->srcpad,
+ GST_FORMAT_UNITS,
+ flacdec->total_samples,
+ format, value);
break;
default:
res = FALSE;
@@ -568,7 +590,9 @@ gst_flacdec_src_event (GstPad *pad, GstEvent *event)
case GST_EVENT_SEEK:
format = GST_FORMAT_UNITS;
- if (gst_pad_convert (flacdec->srcpad, GST_EVENT_SEEK_FORMAT (event), GST_EVENT_SEEK_OFFSET (event),
+ if (gst_pad_convert (flacdec->srcpad,
+ GST_EVENT_SEEK_FORMAT (event),
+ GST_EVENT_SEEK_OFFSET (event),
&format, &flacdec->seek_value))
flacdec->seek_pending = TRUE;
else
@@ -590,7 +614,6 @@ gst_flacdec_change_state (GstElement *element)
switch (GST_STATE_TRANSITION (element)) {
case GST_STATE_NULL_TO_READY:
case GST_STATE_READY_TO_PAUSED:
- flacdec->init = TRUE;
flacdec->bs = gst_bytestream_new (flacdec->sinkpad);
flacdec->seek_pending = FALSE;
flacdec->total_samples = 0;
diff --git a/ext/flac/gstflacenc.c b/ext/flac/gstflacenc.c
index 3351e39b..a2e14ae3 100644
--- a/ext/flac/gstflacenc.c
+++ b/ext/flac/gstflacenc.c
@@ -50,13 +50,20 @@ static void gst_flacenc_class_init (FlacEncClass *klass);
static void gst_flacenc_chain (GstPad *pad, GstBuffer *buf);
-static void gst_flacenc_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec);
-static void gst_flacenc_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec);
+static void gst_flacenc_set_property (GObject *object, guint prop_id,
+ const GValue *value, GParamSpec *pspec);
+static void gst_flacenc_get_property (GObject *object, guint prop_id,
+ GValue *value, GParamSpec *pspec);
+static GstElementStateReturn
+ gst_flacenc_change_state (GstElement *element);
static FLAC__StreamEncoderWriteStatus
- gst_flacenc_write_callback (const FLAC__StreamEncoder *encoder, const FLAC__byte buffer[], unsigned bytes,
- unsigned samples, unsigned current_frame, void *client_data);
-static void gst_flacenc_metadata_callback (const FLAC__StreamEncoder *encoder, const FLAC__StreamMetadata *metadata,
+ gst_flacenc_write_callback (const FLAC__StreamEncoder *encoder,
+ const FLAC__byte buffer[], unsigned bytes,
+ unsigned samples, unsigned current_frame,
+ void *client_data);
+static void gst_flacenc_metadata_callback (const FLAC__StreamEncoder *encoder,
+ const FLAC__StreamMetadata *metadata,
void *client_data);
static GstElementClass *parent_class = NULL;
@@ -98,6 +105,8 @@ gst_flacenc_class_init (FlacEncClass *klass)
/* we have no properties atm so this is a bit silly */
gobject_class->set_property = gst_flacenc_set_property;
gobject_class->get_property = gst_flacenc_get_property;
+
+ gstelement_class->change_state = gst_flacenc_change_state;
}
static GstPadConnectReturn
@@ -114,9 +123,14 @@ gst_flacenc_sinkconnect (GstPad *pad, GstCaps *caps)
gst_caps_get_int (caps, "depth", &flacenc->depth);
gst_caps_get_int (caps, "rate", &flacenc->sample_rate);
- FLAC__stream_encoder_set_bits_per_sample (flacenc->encoder, flacenc->depth);
- FLAC__stream_encoder_set_sample_rate (flacenc->encoder, flacenc->sample_rate);
- FLAC__stream_encoder_set_channels (flacenc->encoder, flacenc->channels);
+ FLAC__stream_encoder_set_bits_per_sample (flacenc->encoder,
+ flacenc->depth);
+ FLAC__stream_encoder_set_sample_rate (flacenc->encoder,
+ flacenc->sample_rate);
+ FLAC__stream_encoder_set_channels (flacenc->encoder,
+ flacenc->channels);
+
+ flacenc->negotiated = TRUE;
return GST_PAD_CONNECT_OK;
}
@@ -136,16 +150,23 @@ gst_flacenc_init (FlacEnc *flacenc)
flacenc->first_buf = NULL;
flacenc->encoder = FLAC__stream_encoder_new();
- FLAC__stream_encoder_set_write_callback (flacenc->encoder, gst_flacenc_write_callback);
- FLAC__stream_encoder_set_metadata_callback (flacenc->encoder, gst_flacenc_metadata_callback);
- FLAC__stream_encoder_set_client_data (flacenc->encoder, flacenc);
+ FLAC__stream_encoder_set_write_callback (flacenc->encoder,
+ gst_flacenc_write_callback);
+ FLAC__stream_encoder_set_metadata_callback (flacenc->encoder,
+ gst_flacenc_metadata_callback);
+ FLAC__stream_encoder_set_client_data (flacenc->encoder,
+ flacenc);
GST_FLAG_SET (flacenc, GST_ELEMENT_EVENT_AWARE);
+
+ flacenc->negotiated = FALSE;
}
static FLAC__StreamEncoderWriteStatus
-gst_flacenc_write_callback (const FLAC__StreamEncoder *encoder, const FLAC__byte buffer[], unsigned bytes,
- unsigned samples, unsigned current_frame, void *client_data)
+gst_flacenc_write_callback (const FLAC__StreamEncoder *encoder,
+ const FLAC__byte buffer[], unsigned bytes,
+ unsigned samples, unsigned current_frame,
+ void *client_data)
{
FlacEnc *flacenc;
GstBuffer *outbuf;
@@ -170,7 +191,9 @@ gst_flacenc_write_callback (const FLAC__StreamEncoder *encoder, const FLAC__byte
}
static void
-gst_flacenc_metadata_callback (const FLAC__StreamEncoder *encoder, const FLAC__StreamMetadata *metadata, void *client_data)
+gst_flacenc_metadata_callback (const FLAC__StreamEncoder *encoder,
+ const FLAC__StreamMetadata *metadata,
+ void *client_data)
{
GstEvent *event;
FlacEnc *flacenc;
@@ -242,13 +265,21 @@ gst_flacenc_chain (GstPad *pad, GstBuffer *buf)
return;
}
+ if (!flacenc->negotiated) {
+ gst_element_error (GST_ELEMENT (flacenc),
+ "format not negotiated");
+ return;
+ }
+
channels = flacenc->channels;
depth = flacenc->depth;
insize = GST_BUFFER_SIZE (buf);
samples = insize / channels / ((depth+7)>>3);
- if (FLAC__stream_encoder_get_state (flacenc->encoder) == FLAC__STREAM_ENCODER_UNINITIALIZED) {
+ if (FLAC__stream_encoder_get_state (flacenc->encoder) ==
+ FLAC__STREAM_ENCODER_UNINITIALIZED)
+ {
FLAC__StreamEncoderState state;
state = FLAC__stream_encoder_init (flacenc->encoder);
@@ -277,7 +308,8 @@ gst_flacenc_chain (GstPad *pad, GstBuffer *buf)
}
}
- res = FLAC__stream_encoder_process (flacenc->encoder, (const FLAC__int32 **)data, samples);
+ res = FLAC__stream_encoder_process (flacenc->encoder,
+ (const FLAC__int32 **)data, samples);
for (i=0; i<channels; i++) {
g_free (data[i]);
@@ -287,7 +319,8 @@ gst_flacenc_chain (GstPad *pad, GstBuffer *buf)
}
static void
-gst_flacenc_set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
+gst_flacenc_set_property (GObject *object, guint prop_id,
+ const GValue *value, GParamSpec *pspec)
{
FlacEnc *this;
@@ -300,7 +333,8 @@ gst_flacenc_set_property(GObject *object, guint prop_id, const GValue *value, GP
}
static void
-gst_flacenc_get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
+gst_flacenc_get_property (GObject *object, guint prop_id,
+ GValue *value, GParamSpec *pspec)
{
FlacEnc *this;
@@ -313,3 +347,29 @@ gst_flacenc_get_property(GObject *object, guint prop_id, GValue *value, GParamSp
}
}
+static GstElementStateReturn
+gst_flacenc_change_state (GstElement *element)
+{
+ FlacEnc *flacenc = GST_FLACENC (element);
+
+ switch (GST_STATE_TRANSITION (element)) {
+ case GST_STATE_NULL_TO_READY:
+ case GST_STATE_READY_TO_PAUSED:
+ break;
+ case GST_STATE_PAUSED_TO_PLAYING:
+ case GST_STATE_PLAYING_TO_PAUSED:
+ break;
+ case GST_STATE_PAUSED_TO_READY:
+ flacenc->negotiated = FALSE;
+ break;
+ case GST_STATE_READY_TO_NULL:
+ default:
+ break;
+ }
+
+ if (GST_ELEMENT_CLASS (parent_class)->change_state)
+ return GST_ELEMENT_CLASS (parent_class)->change_state (element);
+
+ return GST_STATE_SUCCESS;
+}
+
diff --git a/ext/flac/gstflacenc.h b/ext/flac/gstflacenc.h
index bca59c87..27f09ab9 100644
--- a/ext/flac/gstflacenc.h
+++ b/ext/flac/gstflacenc.h
@@ -51,6 +51,7 @@ struct _FlacEnc {
gint channels;
gint depth;
gint sample_rate;
+ gboolean negotiated;
FLAC__StreamEncoder *encoder;
};