summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJon Bergli Heier <snakebite@jvnv.net>2010-09-05 18:26:30 +0200
committerJon Bergli Heier <snakebite@jvnv.net>2010-09-05 18:26:30 +0200
commit30aa38e29a03250192c3c0d4faa3c37a9d4d0357 (patch)
treee18de4873a9f3e993086b9cfdd1b5c2a3dcc171f
parentb6567cbdf77f0ebf1790b1e7d800ad4df88253ca (diff)
Rewrote encoder/decoder setup to use streams instead of buffers.
-rw-r--r--decode_converter.c87
-rw-r--r--decode_converter.h31
-rw-r--r--decoder.c9
-rw-r--r--decoder.h8
-rw-r--r--decoders/decoder_mpg123.c14
-rw-r--r--encode_converter.c87
-rw-r--r--encode_converter.h31
-rw-r--r--encoder.c7
-rw-r--r--encoder.h8
-rw-r--r--encoders/encoder_lame.c14
-rw-r--r--transcode.c60
11 files changed, 90 insertions, 266 deletions
diff --git a/decode_converter.c b/decode_converter.c
deleted file mode 100644
index 102d059..0000000
--- a/decode_converter.c
+++ /dev/null
@@ -1,87 +0,0 @@
-#include "decode_converter.h"
-
-#include <gio/gio.h>
-
-static void decode_converter_interface_init(GConverterIface *iface);
-static void decode_converter_finalize(GObject *object);
-
-static GConverterResult decoder_converter_convert(GConverter *converter,
- const void *inbuf, gsize inbuf_size, void *outbuf, gsize outbuf_size,
- GConverterFlags flags, gsize *bytes_read, gsize *bytes_written,
- GError **error);
-static void decode_converter_reset(GConverter *converter);
-
-static GObjectClass *parent_class = NULL;
-
-G_DEFINE_TYPE_WITH_CODE(DecodeConverter, decode_converter, G_TYPE_OBJECT,
- G_IMPLEMENT_INTERFACE(G_TYPE_CONVERTER,
- decode_converter_interface_init));
-
-static void decode_converter_class_init(DecodeConverterClass *klass) {
- GObjectClass *object_class;
-
- parent_class = (GObjectClass*)g_type_class_peek_parent(klass);
- object_class = (GObjectClass*)klass;
- object_class->finalize = decode_converter_finalize;
-}
-
-static void decode_converter_interface_init(GConverterIface *iface) {
- iface->convert = decoder_converter_convert;
- iface->reset = decode_converter_reset;
-}
-
-static void decode_converter_init(DecodeConverter *self) {
-}
-
-static void decode_converter_finalize(GObject *object) {
- DecodeConverter *dc;
-
- g_assert(CONVERTER_IS_DECODE(object));
-
- dc = DECODE_CONVERTER(object);
-
- dc->decoder.decoder->close(dc->decoder.data);
-}
-
-static GConverterResult decoder_converter_convert(GConverter *converter,
- const void *inbuf, gsize inbuf_size, void *outbuf, gsize outbuf_size,
- GConverterFlags flags, gsize *bytes_read, gsize *bytes_written,
- GError **error) {
- DecodeConverter *dc;
-
- dc = (DecodeConverter*)converter;
-
- gssize size = dc->decoder.decoder->decode(dc->decoder.data, inbuf, inbuf_size, outbuf, outbuf_size);
-
- if(size < 0) {
- *error = g_error_new(g_quark_from_string("DecodeConverter"),
- size, "decode() returned %ld", size);
- return G_CONVERTER_ERROR;
- } else if(size == 0) {
- return G_CONVERTER_FINISHED;
- }
- *bytes_read = inbuf_size;
- *bytes_written = size;
- return G_CONVERTER_CONVERTED;
-}
-
-static void decode_converter_reset(GConverter *converter) {
- DecodeConverter *dc;
-
- dc = (DecodeConverter*)converter;
-
- dc->decoder.decoder->close(&dc->decoder.data);
-}
-
-DecodeConverter *decode_converter_new(const struct decoder_plugin *decoder_plugin) {
- DecodeConverter *dc;
-
- dc = (DecodeConverter*)g_object_new(CONVERTER_TYPE_DECODE, NULL);
-
- g_assert(dc != NULL);
-
- dc->decoder.decoder = decoder_plugin;
- dc->decoder.decoder->init(&dc->decoder.data);
-
- return dc;
-}
diff --git a/decode_converter.h b/decode_converter.h
deleted file mode 100644
index 5523541..0000000
--- a/decode_converter.h
+++ /dev/null
@@ -1,31 +0,0 @@
-#ifndef DECODE_CONVERTER_H
-#define DECODE_CONVERTER_H
-
-#include "decoder.h"
-
-#include <glib-object.h>
-
-#define CONVERTER_TYPE_DECODE (decode_converter_get_type())
-#define DECODE_CONVERTER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), CONVERTER_TYPE_DECODE, DecodeConverter))
-#define CONVERTER_IS_DECODE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), CONVERTER_TYPE_DECODE))
-#define DECODE_CONVERTER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), CONVERTER_TYPE_DECODE, DecodeConverterClass))
-#define CONVERTER_IS_DECODE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), CONVERTER_TYPE_DECODE))
-#define DECODE_CONVERTER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), CONVERTER_TYPE_DECODE, DecodeConverterClass))
-
-typedef struct _DecodeConverter DecodeConverter;
-typedef struct _DecodeConverterClass DecodeConverterClass;
-
-struct _DecodeConverter {
- GObject parent_instance;
-
- struct decoder decoder;
-};
-
-struct _DecodeConverterClass {
- GObjectClass parent_class;
-};
-
-GType decode_converter_get_type();
-DecodeConverter *decode_converter_new(const struct decoder_plugin *decoder_plugin);
-
-#endif
diff --git a/decoder.c b/decoder.c
index a31d624..1746467 100644
--- a/decoder.c
+++ b/decoder.c
@@ -4,10 +4,9 @@ gboolean decoder_init(struct decoder *decoder) {
return decoder->decoder->init(&(decoder->data));
}
-gssize decoder_decode(struct decoder *decoder, const guchar *inbuf,
- gsize inbuf_size, guchar *outbuf, gsize outbuf_size) {
- return decoder->decoder->decode(decoder->data, inbuf, inbuf_size,
- outbuf, outbuf_size);
+gssize decoder_decode(struct decoder *decoder, GInputStream *input,
+ GOutputStream *output) {
+ return decoder->decoder->decode(decoder->data, input, output);
}
void decoder_close(struct decoder *decoder) {
@@ -15,9 +14,11 @@ void decoder_close(struct decoder *decoder) {
}
extern const struct decoder_plugin decoder_mpg123_decoder;
+extern const struct decoder_plugin decoder_flac_decoder;
static const struct decoder_plugin *decoder_plugins[] = {
&decoder_mpg123_decoder,
+ &decoder_flac_decoder,
NULL,
};
diff --git a/decoder.h b/decoder.h
index 36aa04d..4464a50 100644
--- a/decoder.h
+++ b/decoder.h
@@ -9,8 +9,8 @@ struct decoder_plugin {
const gchar * const *extensions;
gboolean (*init)(gpointer *data);
- gssize (*decode)(gpointer data, const guchar *inbuf, gsize inbuf_size,
- guchar *outbuf, gsize outbuf_size);
+ gssize (*decode)(gpointer data, GInputStream *input,
+ GOutputStream *output);
void (*close)(gpointer data);
};
@@ -21,8 +21,8 @@ struct decoder {
};
gboolean decoder_init(struct decoder *decoder);
-gssize decoder_decode(struct decoder *decoder, const guchar *inbuf,
- gsize inbuf_size, guchar *outbuf, gsize outbuf_size);
+gssize decoder_decode(struct decoder *decoder, GInputStream *input,
+ GOutputStream *output);
void decoder_close(struct decoder *decoder);
const struct decoder_plugin *decoder_get(const gchar *name);
diff --git a/decoders/decoder_mpg123.c b/decoders/decoder_mpg123.c
index e80bac3..a7cf3d0 100644
--- a/decoders/decoder_mpg123.c
+++ b/decoders/decoder_mpg123.c
@@ -29,13 +29,19 @@ static gboolean mpg123_decoder_init(gpointer *data) {
return TRUE;
}
-static gssize mpg123_decoder_decode(gpointer data, const guchar *inbuf,
- gsize inbuf_size, guchar *outbuf, gsize outbuf_size) {
+static gssize mpg123_decoder_decode(gpointer data, GInputStream *input,
+ GOutputStream *output) {
mpg123_handle *handle = data;
gssize size;
int ret;
+ const int inbuf_size = 0x400*8;
+ const int outbuf_size = 0x400*8;
+ char inbuf[inbuf_size];
+ char outbuf[inbuf_size];
- if(mpg123_feed(handle, inbuf, inbuf_size) != MPG123_OK) {
+ gsize inbuf_read = g_input_stream_read(input, inbuf, inbuf_size, NULL, NULL);
+
+ if(mpg123_feed(handle, inbuf, inbuf_read) != MPG123_OK) {
g_debug("asdfasdf");
g_warning(mpg123_strerror(handle));
return -1;
@@ -57,6 +63,8 @@ static gssize mpg123_decoder_decode(gpointer data, const guchar *inbuf,
return -1;
}
+ g_output_stream_write(output, outbuf, size, NULL, NULL);
+
return size;
}
diff --git a/encode_converter.c b/encode_converter.c
deleted file mode 100644
index e113351..0000000
--- a/encode_converter.c
+++ /dev/null
@@ -1,87 +0,0 @@
-#include "encode_converter.h"
-
-#include <gio/gio.h>
-
-static void encode_converter_interface_init(GConverterIface *iface);
-static void encode_converter_finalize(GObject *object);
-
-static GConverterResult encoder_converter_convert(GConverter *converter,
- const void *inbuf, gsize inbuf_size, void *outbuf, gsize outbuf_size,
- GConverterFlags flags, gsize *bytes_read, gsize *bytes_written,
- GError **error);
-static void encode_converter_reset(GConverter *converter);
-
-static GObjectClass *parent_class = NULL;
-
-G_DEFINE_TYPE_WITH_CODE(EncodeConverter, encode_converter, G_TYPE_OBJECT,
- G_IMPLEMENT_INTERFACE(G_TYPE_CONVERTER,
- encode_converter_interface_init));
-
-static void encode_converter_class_init(EncodeConverterClass *klass) {
- GObjectClass *object_class;
-
- parent_class = (GObjectClass*)g_type_class_peek_parent(klass);
- object_class = (GObjectClass*)klass;
- object_class->finalize = encode_converter_finalize;
-}
-
-static void encode_converter_interface_init(GConverterIface *iface) {
- iface->convert = encoder_converter_convert;
- iface->reset = encode_converter_reset;
-}
-
-static void encode_converter_init(EncodeConverter *self) {
-}
-
-static void encode_converter_finalize(GObject *object) {
- EncodeConverter *dc;
-
- g_assert(CONVERTER_IS_ENCODE(object));
-
- dc = ENCODE_CONVERTER(object);
-
- dc->encoder.encoder->close(dc->encoder.data);
-}
-
-static GConverterResult encoder_converter_convert(GConverter *converter,
- const void *inbuf, gsize inbuf_size, void *outbuf, gsize outbuf_size,
- GConverterFlags flags, gsize *bytes_read, gsize *bytes_written,
- GError **error) {
- EncodeConverter *dc;
-
- dc = (EncodeConverter*)converter;
-
- gssize size = dc->encoder.encoder->encode(dc->encoder.data, inbuf, inbuf_size, outbuf, outbuf_size);
-
- if(size < 0) {
- *error = g_error_new(g_quark_from_string("EncodeConverter"),
- size, "encode() returned %ld", size);
- return G_CONVERTER_ERROR;
- } else if(size == 0) {
- return G_CONVERTER_FINISHED;
- }
- *bytes_read = inbuf_size;
- *bytes_written = size;
- return G_CONVERTER_CONVERTED;
-}
-
-static void encode_converter_reset(GConverter *converter) {
- EncodeConverter *ec;
-
- ec = (EncodeConverter*)converter;
-
- ec->encoder.encoder->close(&ec->encoder.data);
-}
-
-EncodeConverter *encode_converter_new(const struct encoder_plugin *encoder_plugin) {
- EncodeConverter *dc;
-
- dc = (EncodeConverter*)g_object_new(CONVERTER_TYPE_ENCODE, NULL);
-
- g_assert(dc != NULL);
-
- dc->encoder.encoder = encoder_plugin;
- dc->encoder.encoder->init(&dc->encoder.data);
-
- return dc;
-}
diff --git a/encode_converter.h b/encode_converter.h
deleted file mode 100644
index 054598e..0000000
--- a/encode_converter.h
+++ /dev/null
@@ -1,31 +0,0 @@
-#ifndef ENCODE_CONVERTER_H
-#define ENCODE_CONVERTER_H
-
-#include "encoder.h"
-
-#include <glib-object.h>
-
-#define CONVERTER_TYPE_ENCODE (encode_converter_get_type())
-#define ENCODE_CONVERTER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), CONVERTER_TYPE_ENCODE, EncodeConverter))
-#define CONVERTER_IS_ENCODE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), CONVERTER_TYPE_ENCODE))
-#define ENCODE_CONVERTER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), CONVERTER_TYPE_ENCODE, EncodeConverterClass))
-#define CONVERTER_IS_ENCODE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), CONVERTER_TYPE_ENCODE))
-#define ENCODE_CONVERTER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), CONVERTER_TYPE_ENCODE, EncodeConverterClass))
-
-typedef struct _EncodeConverter EncodeConverter;
-typedef struct _EncodeConverterClass EncodeConverterClass;
-
-struct _EncodeConverter {
- GObject parent_instance;
-
- struct encoder encoder;
-};
-
-struct _EncodeConverterClass {
- GObjectClass parent_class;
-};
-
-GType encode_converter_get_type();
-EncodeConverter *encode_converter_new(const struct encoder_plugin *encoder_plugin);
-
-#endif
diff --git a/encoder.c b/encoder.c
index 4e0ffb8..d039c9c 100644
--- a/encoder.c
+++ b/encoder.c
@@ -4,10 +4,9 @@ gboolean encoder_init(struct encoder *encoder) {
return encoder->encoder->init(&encoder->data);
}
-gssize encoder_encode(struct encoder *encoder, const guchar *inbuf, gsize inbuf_size,
- guchar *outbuf, gsize outbuf_size) {
- return encoder->encoder->encode(encoder->data, inbuf, inbuf_size,
- outbuf, outbuf_size);
+gssize encoder_encode(struct encoder *encoder, GInputStream *input,
+ GOutputStream *output) {
+ return encoder->encoder->encode(encoder->data, input, output);
}
void encoder_close(struct encoder *encoder) {
diff --git a/encoder.h b/encoder.h
index 68dc3fb..c57eead 100644
--- a/encoder.h
+++ b/encoder.h
@@ -8,8 +8,8 @@ struct encoder_plugin {
const gchar *name;
gboolean (*init)(gpointer *data);
- gssize (*encode)(gpointer data, const guchar *inbuf, gsize inbuf_size,
- guchar *outbuf, gsize outbuf_size);
+ gssize (*encode)(gpointer data, GInputStream *input,
+ GOutputStream *output);
void (*close)(gpointer data);
};
@@ -20,8 +20,8 @@ struct encoder {
};
gboolean encoder_init(struct encoder *encoder);
-gssize encoder_encode(struct encoder *encoder, const guchar *inbuf, gsize inbuf_size,
- guchar *outbuf, gsize outbuf_size);
+gssize encoder_encode(struct encoder *encoder, GInputStream *input,
+ GOutputStream *output);
void encoder_close(struct encoder *encoder);
const struct encoder_plugin *encoder_get(const gchar *name);
diff --git a/encoders/encoder_lame.c b/encoders/encoder_lame.c
index ec50047..b28e52e 100644
--- a/encoders/encoder_lame.c
+++ b/encoders/encoder_lame.c
@@ -12,13 +12,21 @@ static gboolean lame_encoder_init(gpointer *data) {
return (ret >= 0 ? TRUE : FALSE);
}
-static gssize lame_encoder_encode(gpointer data, const guchar *inbuf, gsize inbuf_size,
- guchar *outbuf, gsize outbuf_size) {
+static gssize lame_encoder_encode(gpointer data, GInputStream *input,
+ GOutputStream *output) {
lame_global_flags *gfp = data;
+ const inbuf_size = 0x400*8;
+ const outbuf_size = 0x400*8;
+ gchar inbuf[inbuf_size];
+ gchar outbuf[inbuf_size];
- int ret = lame_encode_buffer_interleaved(gfp, (short*)inbuf, inbuf_size / 4,
+ int inbuf_read = g_input_stream_read(input, inbuf, inbuf_size, NULL, NULL);
+
+ int ret = lame_encode_buffer_interleaved(gfp, (short*)inbuf, inbuf_read / 4,
outbuf, outbuf_size);
+ g_output_stream_write(output, outbuf, ret, NULL, NULL);
+
return ret;
}
diff --git a/transcode.c b/transcode.c
index 54418cd..ebd7ded 100644
--- a/transcode.c
+++ b/transcode.c
@@ -4,11 +4,11 @@
#include <glib.h>
-void transcode(GInputStream *input, const struct decoder_plugin *decoder,
- GOutputStream *output, const struct encoder_plugin *encoder) {
+void transcode(GInputStream *input, const struct decoder_plugin *_decoder,
+ GOutputStream *output, const struct encoder_plugin *_encoder) {
GError *error = NULL;
- DecodeConverter *dc = decode_converter_new(decoder);
+ /*DecodeConverter *dc = decode_converter_new(decoder);
GInputStream *decoded_stream = g_converter_input_stream_new(input,
(GConverter*)dc);
@@ -17,16 +17,60 @@ void transcode(GInputStream *input, const struct decoder_plugin *decoder,
(GConverter*)ec);
gssize size = g_output_stream_splice(output, encoded_stream,
- G_OUTPUT_STREAM_SPLICE_NONE, NULL, &error);
+ G_OUTPUT_STREAM_SPLICE_NONE, NULL, &error);*/
- if(size == -1 && error != NULL) {
+ gboolean decode_done = FALSE, encode_done = FALSE;
+ struct decoder *decoder = g_new0(struct decoder, 1);
+ struct encoder *encoder = g_new0(struct encoder, 1);
+ decoder->decoder = _decoder;
+ encoder->encoder = _encoder;
+ decoder_init(decoder);
+ encoder_init(encoder);
+
+ /* holds decoded audio passed to encoder */
+ GInputStream *decoded_in = g_memory_input_stream_new();
+
+ while(decode_done == FALSE || encode_done == FALSE) {
+ /* holds decoded audio from decoder */
+ GOutputStream *decoded_out = g_memory_output_stream_new(NULL, 0, g_realloc, g_free);
+
+ if(decode_done == FALSE && decoder_decode(decoder, input, decoded_out) <= 0) {
+ g_debug("decoding done");
+ decode_done = TRUE;
+ }
+
+ /* temp variables */
+ gpointer data = g_memory_output_stream_get_data((GMemoryOutputStream*)decoded_out);
+ gsize size = g_memory_output_stream_get_data_size((GMemoryOutputStream*)decoded_out);
+
+ if(size > 0) {
+ data = g_memdup(data, size);
+ g_memory_input_stream_add_data((GMemoryInputStream*)decoded_in, data, size, g_free);
+ }
+
+ g_object_unref(decoded_out);
+
+ if(encode_done == FALSE && encoder_encode(encoder, decoded_in, output) <= 0) {
+ g_debug("encoding done");
+ encode_done = TRUE;
+ }
+ }
+
+ g_object_unref(decoded_in);
+
+ /*if(size == -1 && error != NULL) {
g_warning(error->message);
g_error_free(error);
- }
+ }*/
+
+ decoder_close(decoder);
+ encoder_close(encoder);
+ g_free(decoder);
+ g_free(encoder);
- g_object_unref(encoded_stream);
+ /*g_object_unref(encoded_stream);
g_object_unref(ec);
g_object_unref(decoded_stream);
- g_object_unref(dc);
+ g_object_unref(dc);*/
}