/* rygel-audio-transcoder.c generated by valac 0.20.1, the Vala compiler
 * generated from rygel-audio-transcoder.vala, do not modify */

/*
 * Copyright (C) 2011 Nokia Corporation.
 * Copyright (C) 2012 Intel Corporation.
 *
 * Author: Jens Georg <jensg@openismus.com>
 *
 * This file is part of Rygel.
 *
 * Rygel is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * Rygel is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 */

#include <glib.h>
#include <glib-object.h>
#include <rygel-server.h>
#include <gst/pbutils/codec-utils.h>
#include <gst/pbutils/descriptions.h>
#include <gst/pbutils/encoding-profile.h>
#include <gst/pbutils/encoding-target.h>
#include <gst/pbutils/gstdiscoverer.h>
#include <gst/pbutils/gstpluginsbaseversion.h>
#include <gst/pbutils/install-plugins.h>
#include <gst/pbutils/missing-plugins.h>
#include <gst/pbutils/pbutils-enumtypes.h>
#include <gst/pbutils/pbutils.h>
#include <gst/gst.h>
#include <stdlib.h>
#include <string.h>
#include <libgupnp-av/gupnp-av.h>


#define RYGEL_TYPE_GST_TRANSCODER (rygel_gst_transcoder_get_type ())
#define RYGEL_GST_TRANSCODER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_TYPE_GST_TRANSCODER, RygelGstTranscoder))
#define RYGEL_GST_TRANSCODER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_TYPE_GST_TRANSCODER, RygelGstTranscoderClass))
#define RYGEL_IS_GST_TRANSCODER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_TYPE_GST_TRANSCODER))
#define RYGEL_IS_GST_TRANSCODER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_TYPE_GST_TRANSCODER))
#define RYGEL_GST_TRANSCODER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_TYPE_GST_TRANSCODER, RygelGstTranscoderClass))

typedef struct _RygelGstTranscoder RygelGstTranscoder;
typedef struct _RygelGstTranscoderClass RygelGstTranscoderClass;
typedef struct _RygelGstTranscoderPrivate RygelGstTranscoderPrivate;

#define RYGEL_TYPE_AUDIO_TRANSCODER (rygel_audio_transcoder_get_type ())
#define RYGEL_AUDIO_TRANSCODER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_TYPE_AUDIO_TRANSCODER, RygelAudioTranscoder))
#define RYGEL_AUDIO_TRANSCODER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_TYPE_AUDIO_TRANSCODER, RygelAudioTranscoderClass))
#define RYGEL_IS_AUDIO_TRANSCODER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_TYPE_AUDIO_TRANSCODER))
#define RYGEL_IS_AUDIO_TRANSCODER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_TYPE_AUDIO_TRANSCODER))
#define RYGEL_AUDIO_TRANSCODER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_TYPE_AUDIO_TRANSCODER, RygelAudioTranscoderClass))

typedef struct _RygelAudioTranscoder RygelAudioTranscoder;
typedef struct _RygelAudioTranscoderClass RygelAudioTranscoderClass;
typedef struct _RygelAudioTranscoderPrivate RygelAudioTranscoderPrivate;
#define _gst_mini_object_unref0(var) ((var == NULL) ? NULL : (var = (gst_mini_object_unref (var), NULL)))
#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))

struct _RygelGstTranscoder {
	RygelTranscoder parent_instance;
	RygelGstTranscoderPrivate * priv;
};

struct _RygelGstTranscoderClass {
	RygelTranscoderClass parent_class;
	GstEncodingProfile* (*get_encoding_profile) (RygelGstTranscoder* self);
};

struct _RygelAudioTranscoder {
	RygelGstTranscoder parent_instance;
	RygelAudioTranscoderPrivate * priv;
	gint audio_bitrate;
	GstCaps* container_format;
	GstCaps* audio_codec_format;
};

struct _RygelAudioTranscoderClass {
	RygelGstTranscoderClass parent_class;
};


static gpointer rygel_audio_transcoder_parent_class = NULL;

GType rygel_gst_transcoder_get_type (void) G_GNUC_CONST;
GType rygel_audio_transcoder_get_type (void) G_GNUC_CONST;
enum  {
	RYGEL_AUDIO_TRANSCODER_DUMMY_PROPERTY
};
#define RYGEL_AUDIO_TRANSCODER_NO_CONTAINER NULL
RygelAudioTranscoder* rygel_audio_transcoder_new (const gchar* content_type, const gchar* dlna_profile, gint audio_bitrate, const gchar* container_caps, const gchar* audio_codec_caps, const gchar* extension);
RygelAudioTranscoder* rygel_audio_transcoder_construct (GType object_type, const gchar* content_type, const gchar* dlna_profile, gint audio_bitrate, const gchar* container_caps, const gchar* audio_codec_caps, const gchar* extension);
RygelGstTranscoder* rygel_gst_transcoder_construct (GType object_type, const gchar* mime_type, const gchar* dlna_profile, const gchar* extension);
RygelAudioTranscoder* rygel_audio_transcoder_new_with_class (const gchar* content_type, const gchar* dlna_profile, gint audio_bitrate, const gchar* container_caps, const gchar* audio_codec_caps, const gchar* extension);
RygelAudioTranscoder* rygel_audio_transcoder_construct_with_class (GType object_type, const gchar* content_type, const gchar* dlna_profile, gint audio_bitrate, const gchar* container_caps, const gchar* audio_codec_caps, const gchar* extension);
static GUPnPDIDLLiteResource* rygel_audio_transcoder_real_add_resource (RygelTranscoder* base, GUPnPDIDLLiteItem* didl_item, RygelMediaItem* item, RygelTranscodeManager* manager, GError** error);
static guint rygel_audio_transcoder_real_get_distance (RygelTranscoder* base, RygelMediaItem* item);
static GstEncodingProfile* rygel_audio_transcoder_real_get_encoding_profile (RygelGstTranscoder* base);
const gchar* rygel_gst_transcoder_get_preset (RygelGstTranscoder* self);
static void rygel_audio_transcoder_finalize (GObject* obj);


RygelAudioTranscoder* rygel_audio_transcoder_construct (GType object_type, const gchar* content_type, const gchar* dlna_profile, gint audio_bitrate, const gchar* container_caps, const gchar* audio_codec_caps, const gchar* extension) {
	RygelAudioTranscoder * self = NULL;
	const gchar* _tmp0_;
	const gchar* _tmp1_;
	const gchar* _tmp2_;
	gint _tmp3_;
	const gchar* _tmp4_;
	const gchar* _tmp7_;
	GstCaps* _tmp8_ = NULL;
	g_return_val_if_fail (content_type != NULL, NULL);
	g_return_val_if_fail (dlna_profile != NULL, NULL);
	g_return_val_if_fail (audio_codec_caps != NULL, NULL);
	g_return_val_if_fail (extension != NULL, NULL);
	_tmp0_ = content_type;
	_tmp1_ = dlna_profile;
	_tmp2_ = extension;
	self = (RygelAudioTranscoder*) rygel_gst_transcoder_construct (object_type, _tmp0_, _tmp1_, _tmp2_);
	_tmp3_ = audio_bitrate;
	self->audio_bitrate = _tmp3_;
	_tmp4_ = container_caps;
	if (_tmp4_ != NULL) {
		const gchar* _tmp5_;
		GstCaps* _tmp6_ = NULL;
		_tmp5_ = container_caps;
		_tmp6_ = gst_caps_from_string (_tmp5_);
		_gst_mini_object_unref0 (self->container_format);
		self->container_format = _tmp6_;
	}
	_tmp7_ = audio_codec_caps;
	_tmp8_ = gst_caps_from_string (_tmp7_);
	_gst_mini_object_unref0 (self->audio_codec_format);
	self->audio_codec_format = _tmp8_;
	return self;
}


RygelAudioTranscoder* rygel_audio_transcoder_new (const gchar* content_type, const gchar* dlna_profile, gint audio_bitrate, const gchar* container_caps, const gchar* audio_codec_caps, const gchar* extension) {
	return rygel_audio_transcoder_construct (RYGEL_TYPE_AUDIO_TRANSCODER, content_type, dlna_profile, audio_bitrate, container_caps, audio_codec_caps, extension);
}


RygelAudioTranscoder* rygel_audio_transcoder_construct_with_class (GType object_type, const gchar* content_type, const gchar* dlna_profile, gint audio_bitrate, const gchar* container_caps, const gchar* audio_codec_caps, const gchar* extension) {
	RygelAudioTranscoder * self = NULL;
	const gchar* _tmp0_;
	const gchar* _tmp1_;
	const gchar* _tmp2_;
	gint _tmp3_;
	const gchar* _tmp4_;
	const gchar* _tmp7_;
	GstCaps* _tmp8_ = NULL;
	g_return_val_if_fail (content_type != NULL, NULL);
	g_return_val_if_fail (dlna_profile != NULL, NULL);
	g_return_val_if_fail (audio_codec_caps != NULL, NULL);
	g_return_val_if_fail (extension != NULL, NULL);
	_tmp0_ = content_type;
	_tmp1_ = dlna_profile;
	_tmp2_ = extension;
	self = (RygelAudioTranscoder*) rygel_gst_transcoder_construct (object_type, _tmp0_, _tmp1_, _tmp2_);
	_tmp3_ = audio_bitrate;
	self->audio_bitrate = _tmp3_;
	_tmp4_ = container_caps;
	if (_tmp4_ != NULL) {
		const gchar* _tmp5_;
		GstCaps* _tmp6_ = NULL;
		_tmp5_ = container_caps;
		_tmp6_ = gst_caps_from_string (_tmp5_);
		_gst_mini_object_unref0 (self->container_format);
		self->container_format = _tmp6_;
	}
	_tmp7_ = audio_codec_caps;
	_tmp8_ = gst_caps_from_string (_tmp7_);
	_gst_mini_object_unref0 (self->audio_codec_format);
	self->audio_codec_format = _tmp8_;
	return self;
}


RygelAudioTranscoder* rygel_audio_transcoder_new_with_class (const gchar* content_type, const gchar* dlna_profile, gint audio_bitrate, const gchar* container_caps, const gchar* audio_codec_caps, const gchar* extension) {
	return rygel_audio_transcoder_construct_with_class (RYGEL_TYPE_AUDIO_TRANSCODER, content_type, dlna_profile, audio_bitrate, container_caps, audio_codec_caps, extension);
}


static GUPnPDIDLLiteResource* rygel_audio_transcoder_real_add_resource (RygelTranscoder* base, GUPnPDIDLLiteItem* didl_item, RygelMediaItem* item, RygelTranscodeManager* manager, GError** error) {
	RygelAudioTranscoder * self;
	GUPnPDIDLLiteResource* result = NULL;
	GUPnPDIDLLiteItem* _tmp0_;
	RygelMediaItem* _tmp1_;
	RygelTranscodeManager* _tmp2_;
	GUPnPDIDLLiteResource* _tmp3_ = NULL;
	GUPnPDIDLLiteResource* resource;
	gint _tmp4_;
	GError * _inner_error_ = NULL;
	self = (RygelAudioTranscoder*) base;
	g_return_val_if_fail (didl_item != NULL, NULL);
	g_return_val_if_fail (item != NULL, NULL);
	g_return_val_if_fail (manager != NULL, NULL);
	_tmp0_ = didl_item;
	_tmp1_ = item;
	_tmp2_ = manager;
	_tmp3_ = RYGEL_TRANSCODER_CLASS (rygel_audio_transcoder_parent_class)->add_resource ((RygelTranscoder*) G_TYPE_CHECK_INSTANCE_CAST (self, RYGEL_TYPE_GST_TRANSCODER, RygelGstTranscoder), _tmp0_, _tmp1_, _tmp2_, &_inner_error_);
	resource = _tmp3_;
	if (_inner_error_ != NULL) {
		g_propagate_error (error, _inner_error_);
		return NULL;
	}
	if (resource == NULL) {
		result = NULL;
		_g_object_unref0 (resource);
		return result;
	}
	_tmp4_ = self->audio_bitrate;
	gupnp_didl_lite_resource_set_bitrate (resource, (_tmp4_ * 1000) / 8);
	result = resource;
	return result;
}


static gpointer _g_object_ref0 (gpointer self) {
	return self ? g_object_ref (self) : NULL;
}


static guint rygel_audio_transcoder_real_get_distance (RygelTranscoder* base, RygelMediaItem* item) {
	RygelAudioTranscoder * self;
	guint result = 0U;
	gboolean _tmp0_ = FALSE;
	RygelMediaItem* _tmp1_;
	gboolean _tmp3_;
	RygelMediaItem* _tmp5_;
	RygelAudioItem* _tmp6_;
	RygelAudioItem* audio_item;
	guint _tmp7_;
	guint distance;
	RygelAudioItem* _tmp8_;
	gint _tmp9_;
	gint _tmp10_;
	self = (RygelAudioTranscoder*) base;
	g_return_val_if_fail (item != NULL, 0U);
	_tmp1_ = item;
	if (!G_TYPE_CHECK_INSTANCE_TYPE (_tmp1_, RYGEL_TYPE_AUDIO_ITEM)) {
		_tmp0_ = TRUE;
	} else {
		RygelMediaItem* _tmp2_;
		_tmp2_ = item;
		_tmp0_ = G_TYPE_CHECK_INSTANCE_TYPE (_tmp2_, RYGEL_TYPE_VIDEO_ITEM);
	}
	_tmp3_ = _tmp0_;
	if (_tmp3_) {
		guint _tmp4_;
		_tmp4_ = G_MAXUINT;
		result = _tmp4_;
		return result;
	}
	_tmp5_ = item;
	_tmp6_ = _g_object_ref0 (G_TYPE_CHECK_INSTANCE_TYPE (_tmp5_, RYGEL_TYPE_AUDIO_ITEM) ? ((RygelAudioItem*) _tmp5_) : NULL);
	audio_item = _tmp6_;
	_tmp7_ = 0;
	distance = _tmp7_;
	_tmp8_ = audio_item;
	_tmp9_ = rygel_audio_item_get_bitrate (_tmp8_);
	_tmp10_ = _tmp9_;
	if (_tmp10_ > 0) {
		guint _tmp11_;
		RygelAudioItem* _tmp12_;
		gint _tmp13_;
		gint _tmp14_;
		gint _tmp15_;
		gint _tmp16_ = 0;
		_tmp11_ = distance;
		_tmp12_ = audio_item;
		_tmp13_ = rygel_audio_item_get_bitrate (_tmp12_);
		_tmp14_ = _tmp13_;
		_tmp15_ = self->audio_bitrate;
		_tmp16_ = abs (_tmp14_ - _tmp15_);
		distance = _tmp11_ + _tmp16_;
	}
	result = distance;
	_g_object_unref0 (audio_item);
	return result;
}


static GstEncodingProfile* rygel_audio_transcoder_real_get_encoding_profile (RygelGstTranscoder* base) {
	RygelAudioTranscoder * self;
	GstEncodingProfile* result = NULL;
	GstCaps* _tmp0_;
	const gchar* _tmp1_;
	const gchar* _tmp2_;
	GstEncodingAudioProfile* _tmp3_;
	GstEncodingAudioProfile* enc_audio_profile;
	GstEncodingAudioProfile* _tmp4_;
	GstCaps* _tmp5_;
	self = (RygelAudioTranscoder*) base;
	_tmp0_ = self->audio_codec_format;
	_tmp1_ = rygel_gst_transcoder_get_preset ((RygelGstTranscoder*) self);
	_tmp2_ = _tmp1_;
	_tmp3_ = gst_encoding_audio_profile_new (_tmp0_, _tmp2_, NULL, (guint) 1);
	enc_audio_profile = _tmp3_;
	_tmp4_ = enc_audio_profile;
	gst_encoding_profile_set_name ((GstEncodingProfile*) _tmp4_, "audio");
	_tmp5_ = self->container_format;
	if (_tmp5_ != NULL) {
		GstCaps* _tmp6_;
		const gchar* _tmp7_;
		const gchar* _tmp8_;
		GstEncodingContainerProfile* _tmp9_;
		GstEncodingContainerProfile* enc_container_profile;
		GstEncodingContainerProfile* _tmp10_;
		GstEncodingAudioProfile* _tmp11_;
		GstEncodingProfile* _tmp12_;
		_tmp6_ = self->container_format;
		_tmp7_ = rygel_gst_transcoder_get_preset ((RygelGstTranscoder*) self);
		_tmp8_ = _tmp7_;
		_tmp9_ = gst_encoding_container_profile_new ("container", NULL, _tmp6_, _tmp8_);
		enc_container_profile = _tmp9_;
		_tmp10_ = enc_container_profile;
		_tmp11_ = enc_audio_profile;
		_tmp12_ = _g_object_ref0 ((GstEncodingProfile*) _tmp11_);
		gst_encoding_container_profile_add_profile (_tmp10_, _tmp12_);
		result = (GstEncodingProfile*) enc_container_profile;
		_g_object_unref0 (enc_audio_profile);
		return result;
	}
	result = (GstEncodingProfile*) enc_audio_profile;
	return result;
}


static void rygel_audio_transcoder_class_init (RygelAudioTranscoderClass * klass) {
	rygel_audio_transcoder_parent_class = g_type_class_peek_parent (klass);
	RYGEL_TRANSCODER_CLASS (klass)->add_resource = rygel_audio_transcoder_real_add_resource;
	RYGEL_TRANSCODER_CLASS (klass)->get_distance = rygel_audio_transcoder_real_get_distance;
	RYGEL_GST_TRANSCODER_CLASS (klass)->get_encoding_profile = rygel_audio_transcoder_real_get_encoding_profile;
	G_OBJECT_CLASS (klass)->finalize = rygel_audio_transcoder_finalize;
}


static void rygel_audio_transcoder_instance_init (RygelAudioTranscoder * self) {
	self->container_format = NULL;
	self->audio_codec_format = NULL;
}


static void rygel_audio_transcoder_finalize (GObject* obj) {
	RygelAudioTranscoder * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, RYGEL_TYPE_AUDIO_TRANSCODER, RygelAudioTranscoder);
	_gst_mini_object_unref0 (self->container_format);
	_gst_mini_object_unref0 (self->audio_codec_format);
	G_OBJECT_CLASS (rygel_audio_transcoder_parent_class)->finalize (obj);
}


/**
 * Base class for all transcoders that handle audio.
 */
GType rygel_audio_transcoder_get_type (void) {
	static volatile gsize rygel_audio_transcoder_type_id__volatile = 0;
	if (g_once_init_enter (&rygel_audio_transcoder_type_id__volatile)) {
		static const GTypeInfo g_define_type_info = { sizeof (RygelAudioTranscoderClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) rygel_audio_transcoder_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (RygelAudioTranscoder), 0, (GInstanceInitFunc) rygel_audio_transcoder_instance_init, NULL };
		GType rygel_audio_transcoder_type_id;
		rygel_audio_transcoder_type_id = g_type_register_static (RYGEL_TYPE_GST_TRANSCODER, "RygelAudioTranscoder", &g_define_type_info, 0);
		g_once_init_leave (&rygel_audio_transcoder_type_id__volatile, rygel_audio_transcoder_type_id);
	}
	return rygel_audio_transcoder_type_id__volatile;
}



