From 8914ebc9649cd6be6fd078d0bf1200b79aade7cb Mon Sep 17 00:00:00 2001
From: Max Kellermann <max@duempel.org>
Date: Mon, 18 Jan 2010 10:59:11 +0100
Subject: [PATCH] decoder/ffmpeg: merged ffmpeg_helper() into ffmpeg_decode()

---
 src/decoder/ffmpeg_decoder_plugin.c | 183 ++++++++++------------------
 1 file changed, 67 insertions(+), 116 deletions(-)

diff --git a/src/decoder/ffmpeg_decoder_plugin.c b/src/decoder/ffmpeg_decoder_plugin.c
index 6e4119136..369e8d426 100644
--- a/src/decoder/ffmpeg_decoder_plugin.c
+++ b/src/decoder/ffmpeg_decoder_plugin.c
@@ -45,14 +45,6 @@
 #undef G_LOG_DOMAIN
 #define G_LOG_DOMAIN "ffmpeg"
 
-struct ffmpeg_context {
-	int audio_stream;
-	AVFormatContext *format_context;
-	AVCodecContext *codec_context;
-	struct decoder *decoder;
-	struct input_stream *input;
-};
-
 struct ffmpeg_stream {
 	/** hack - see url_to_struct() */
 	char url[64];
@@ -160,82 +152,6 @@ append_uri_suffix(struct ffmpeg_stream *stream, const char *uri)
 	g_free(base);
 }
 
-static bool
-ffmpeg_helper(struct input_stream *input,
-	      bool (*callback)(struct ffmpeg_context *ctx),
-	      struct ffmpeg_context *ctx)
-{
-	AVFormatContext *format_context;
-	AVCodecContext *codec_context;
-	AVCodec *codec;
-	int audio_stream;
-	struct ffmpeg_stream stream = {
-		.url = "mpd://X", /* only the mpd:// prefix matters */
-	};
-	bool ret;
-
-	if (input->uri != NULL)
-		append_uri_suffix(&stream, input->uri);
-
-	stream.input = input;
-	if (ctx && ctx->decoder) {
-		stream.decoder = ctx->decoder; //are we in decoding loop ?
-	} else {
-		stream.decoder = NULL;
-	}
-
-	//ffmpeg works with ours "fileops" helper
-	if (av_open_input_file(&format_context, stream.url, NULL, 0, NULL) != 0) {
-		g_warning("Open failed\n");
-		return false;
-	}
-
-	if (av_find_stream_info(format_context)<0) {
-		g_warning("Couldn't find stream info\n");
-		av_close_input_file(format_context);
-		return false;
-	}
-
-	audio_stream = ffmpeg_find_audio_stream(format_context);
-	if (audio_stream == -1) {
-		g_warning("No audio stream inside\n");
-		av_close_input_file(format_context);
-		return false;
-	}
-
-	codec_context = format_context->streams[audio_stream]->codec;
-	if (codec_context->codec_name[0] != 0)
-		g_debug("codec '%s'", codec_context->codec_name);
-
-	codec = avcodec_find_decoder(codec_context->codec_id);
-
-	if (!codec) {
-		g_warning("Unsupported audio codec\n");
-		av_close_input_file(format_context);
-		return false;
-	}
-
-	if (avcodec_open(codec_context, codec)<0) {
-		g_warning("Could not open codec\n");
-		av_close_input_file(format_context);
-		return false;
-	}
-
-	if (callback) {
-		ctx->audio_stream = audio_stream;
-		ctx->format_context = format_context;
-		ctx->codec_context = codec_context;
-
-		ret = callback(ctx);
-	} else
-		ret = true;
-
-	avcodec_close(codec_context);
-	av_close_input_file(format_context);
-
-	return ret;
-}
-
 /**
  * On some platforms, libavcodec wants the output buffer aligned to 16
  * bytes (because it uses SSE/Altivec internally).  This function
@@ -321,46 +237,91 @@ ffmpeg_sample_format(G_GNUC_UNUSED const AVCodecContext *codec_context)
 #endif
 }
 
-static bool
-ffmpeg_decode_internal(struct ffmpeg_context *ctx)
+static void
+ffmpeg_decode(struct decoder *decoder, struct input_stream *input)
 {
+	struct ffmpeg_stream stream = {
+		.url = "mpd://X", /* only the mpd:// prefix matters */
+		.decoder = decoder,
+		.input = input,
+	};
+	AVFormatContext *format_context;
+	AVCodecContext *codec_context;
+	AVCodec *codec;
+	int audio_stream;
+
+	if (input->uri != NULL)
+		append_uri_suffix(&stream, input->uri);
+
+	//ffmpeg works with ours "fileops" helper
+	if (av_open_input_file(&format_context, stream.url, NULL, 0, NULL) != 0) {
+		g_warning("Open failed\n");
+		av_close_input_file(format_context);
+		return;
+	}
+
+	if (av_find_stream_info(format_context)<0) {
+		g_warning("Couldn't find stream info\n");
+		av_close_input_file(format_context);
+		return;
+	}
+
+	audio_stream = ffmpeg_find_audio_stream(format_context);
+	if (audio_stream == -1) {
+		g_warning("No audio stream inside\n");
+		av_close_input_file(format_context);
+		return;
+	}
+
+	codec_context = format_context->streams[audio_stream]->codec;
+	if (codec_context->codec_name[0] != 0)
+		g_debug("codec '%s'", codec_context->codec_name);
+
+	codec = avcodec_find_decoder(codec_context->codec_id);
+
+	if (!codec) {
+		g_warning("Unsupported audio codec\n");
+		av_close_input_file(format_context);
+		return;
+	}
+
+	if (avcodec_open(codec_context, codec)<0) {
+		g_warning("Could not open codec\n");
+		av_close_input_file(format_context);
+		return;
+	}
+
 	GError *error = NULL;
-	struct decoder *decoder = ctx->decoder;
-	AVCodecContext *codec_context = ctx->codec_context;
-	AVFormatContext *format_context = ctx->format_context;
-	AVPacket packet;
 	struct audio_format audio_format;
-	enum decoder_command cmd;
-	int total_time;
-
-	total_time = 0;
-
 	if (!audio_format_init_checked(&audio_format,
 				       codec_context->sample_rate,
 				       ffmpeg_sample_format(codec_context),
 				       codec_context->channels, &error)) {
 		g_warning("%s", error->message);
 		g_error_free(error);
-		return false;
+		avcodec_close(codec_context);
+		av_close_input_file(format_context);
+		return;
 	}
 
-	//there is some problem with this on some demux (mp3 at least)
-	if (format_context->duration != (int64_t)AV_NOPTS_VALUE) {
-		total_time = format_context->duration / AV_TIME_BASE;
-	}
+	int total_time = format_context->duration != (int64_t)AV_NOPTS_VALUE
+		? format_context->duration / AV_TIME_BASE
+		: 0;
 
 	decoder_initialized(decoder, &audio_format,
-			    ctx->input->seekable, total_time);
+			    input->seekable, total_time);
 
+	enum decoder_command cmd;
 	do {
+		AVPacket packet;
 		if (av_read_frame(format_context, &packet) < 0)
 			/* end of file */
 			break;
 
-		if (packet.stream_index == ctx->audio_stream)
-			cmd = ffmpeg_send_packet(decoder, ctx->input,
+		if (packet.stream_index == audio_stream)
+			cmd = ffmpeg_send_packet(decoder, input,
 						 &packet, codec_context,
-						 &format_context->streams[ctx->audio_stream]->time_base);
+						 &format_context->streams[audio_stream]->time_base);
 		else
 			cmd = decoder_get_command(decoder);
 
@@ -377,18 +338,8 @@ ffmpeg_decode_internal(struct ffmpeg_context *ctx)
 		}
 	} while (cmd != DECODE_COMMAND_STOP);
 
-	return true;
-}
-
-static void
-ffmpeg_decode(struct decoder *decoder, struct input_stream *input)
-{
-	struct ffmpeg_context ctx;
-
-	ctx.input = input;
-	ctx.decoder = decoder;
-
-	ffmpeg_helper(input, ffmpeg_decode_internal, &ctx);
+	avcodec_close(codec_context);
+	av_close_input_file(format_context);
 }
 
 #if LIBAVFORMAT_VERSION_INT >= ((52<<16)+(31<<8)+0)