From 30aa38e29a03250192c3c0d4faa3c37a9d4d0357 Mon Sep 17 00:00:00 2001 From: Jon Bergli Heier Date: Sun, 5 Sep 2010 18:26:30 +0200 Subject: Rewrote encoder/decoder setup to use streams instead of buffers. --- decode_converter.c | 87 ----------------------------------------------- decode_converter.h | 31 ----------------- decoder.c | 9 ++--- decoder.h | 8 ++--- decoders/decoder_mpg123.c | 14 ++++++-- encode_converter.c | 87 ----------------------------------------------- encode_converter.h | 31 ----------------- encoder.c | 7 ++-- encoder.h | 8 ++--- encoders/encoder_lame.c | 14 ++++++-- transcode.c | 60 +++++++++++++++++++++++++++----- 11 files changed, 90 insertions(+), 266 deletions(-) delete mode 100644 decode_converter.c delete mode 100644 decode_converter.h delete mode 100644 encode_converter.c delete mode 100644 encode_converter.h 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 - -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 - -#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 - -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 - -#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 -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);*/ } -- cgit v1.2.3