gmyth-stream/gmemcoder/src/gmencoder.c
author renatofilho
Thu Jun 14 18:22:32 2007 +0100 (2007-06-14)
branchtrunk
changeset 753 8ee634511c1e
parent 749 fb471f7af20b
child 754 cb885ee44618
permissions -rw-r--r--
[svn r759] fixed indent using GNU Style
renatofilho@588
     1
#ifdef HAVE_CONFIG_H
renatofilho@588
     2
#include "config.h"
renatofilho@588
     3
#endif
renatofilho@588
     4
renatofilho@600
     5
#include <sys/stat.h>
renatofilho@600
     6
#include <fcntl.h>
renatofilho@600
     7
#include <unistd.h>
renatofilho@588
     8
#include <glib.h>
renatofilho@588
     9
#include <gst/gst.h>
renatofilho@588
    10
#include <string.h>
renatofilho@588
    11
renatofilho@588
    12
#include "gmencoder.h"
renatofilho@588
    13
renatofilho@588
    14
#define G_MENCODER_GET_PRIVATE(obj) \
renatofilho@588
    15
    (G_TYPE_INSTANCE_GET_PRIVATE ((obj), G_TYPE_MENCODER, GMencoderPrivate))
renatofilho@588
    16
renatofilho@634
    17
//#define SUPPORT_MULT_INPUT  0
renatofilho@588
    18
renatofilho@588
    19
typedef struct _GMencoderPrivate GMencoderPrivate;
renatofilho@600
    20
typedef struct _SetupInfo SetupInfo;
renatofilho@600
    21
renatofilho@600
    22
struct _SetupInfo
renatofilho@600
    23
{
renatofilho@752
    24
  gchar *video_encode;
renatofilho@752
    25
  gchar *mux_name;
renatofilho@752
    26
  gchar **video_encode_prop;
renatofilho@752
    27
  gdouble video_fps;
renatofilho@752
    28
  gdouble video_rate;
renatofilho@752
    29
  guint video_width;
renatofilho@752
    30
  guint video_height;
renatofilho@752
    31
  gchar *audio_encode;
renatofilho@752
    32
  gchar **audio_encode_prop;
renatofilho@752
    33
  guint audio_rate;
renatofilho@600
    34
};
renatofilho@600
    35
renatofilho@588
    36
renatofilho@588
    37
struct _GMencoderPrivate
morphbr@748
    38
{
renatofilho@752
    39
  GstElement *pipe;
renatofilho@752
    40
  GstElement *abin;
renatofilho@752
    41
  GstElement *vbin;
renatofilho@752
    42
  GstElement *sink;
renatofilho@752
    43
  GstElement *src;
renatofilho@752
    44
  gboolean ready;
renatofilho@752
    45
  SetupInfo *info;
renatofilho@752
    46
  GstClockTime videot;
renatofilho@752
    47
  GstClockTime audiot;
renatofilho@752
    48
  gint fd;
renatofilho@752
    49
  gint sources;
renatofilho@752
    50
  gint tick_id;
renatofilho@752
    51
  gint64 duration;
renatofilho@588
    52
};
renatofilho@588
    53
renatofilho@752
    54
enum
renatofilho@752
    55
{
renatofilho@752
    56
  PAUSED,
renatofilho@752
    57
  PLAYING,
renatofilho@752
    58
  STOPED,
renatofilho@752
    59
  EOS,
renatofilho@752
    60
  ERROR,
renatofilho@752
    61
  LAST_SIGNAL
renatofilho@588
    62
};
renatofilho@588
    63
renatofilho@752
    64
static void g_mencoder_class_init(GMencoderClass * klass);
renatofilho@752
    65
static void g_mencoder_init(GMencoder * object);
renatofilho@752
    66
static void g_mencoder_dispose(GObject * object);
renatofilho@752
    67
static void g_mencoder_finalize(GObject * object);
renatofilho@752
    68
static GstElement *_create_audio_bin(const gchar * encode,
renatofilho@752
    69
									 gchar ** encode_prop, gint rate);
renatofilho@752
    70
static GstElement *_create_video_bin(const gchar * encode,
renatofilho@752
    71
									 gchar ** encode_prop,
renatofilho@752
    72
									 gdouble fps,
renatofilho@752
    73
									 gint rate, guint width, guint height);
renatofilho@588
    74
morphbr@748
    75
static gboolean
renatofilho@752
    76
_pipeline_bus_cb(GstBus * bus, GstMessage * msg, gpointer user_data);
morphbr@748
    77
renatofilho@752
    78
static void _decodebin_new_pad_cb(GstElement * object,
renatofilho@752
    79
								  GstPad * pad,
renatofilho@752
    80
								  gboolean flag, gpointer user_data);
morphbr@748
    81
renatofilho@752
    82
static void _decodebin_unknown_type_cb(GstElement * object,
renatofilho@752
    83
									   GstPad * pad,
renatofilho@752
    84
									   GstCaps * caps, gpointer user_data);
morphbr@748
    85
renatofilho@752
    86
static void _close_output(GMencoder * self);
renatofilho@752
    87
static void _open_output(GMencoder * self, const gchar * uri);
morphbr@748
    88
renatofilho@752
    89
static GstElement *_create_source(const gchar * uri);
renatofilho@752
    90
static GstElement *_create_pipeline(GMencoder * self,
renatofilho@752
    91
									const gchar * video_encode,
renatofilho@752
    92
									const gchar * mux_name,
renatofilho@752
    93
									gchar ** video_encode_prop,
renatofilho@752
    94
									gdouble video_fps,
renatofilho@752
    95
									gdouble video_rate,
renatofilho@752
    96
									guint video_width,
renatofilho@752
    97
									guint video_height,
renatofilho@752
    98
									const gchar * audio_encode,
renatofilho@752
    99
									gchar ** audio_encode_prop,
renatofilho@752
   100
									guint audio_rate);
renatofilho@654
   101
renatofilho@752
   102
static gboolean _tick_cb(gpointer data);
renatofilho@588
   103
renatofilho@588
   104
static guint g_mencoder_signals[LAST_SIGNAL] = { 0 };
renatofilho@588
   105
renatofilho@588
   106
G_DEFINE_TYPE(GMencoder, g_mencoder, G_TYPE_OBJECT)
renatofilho@752
   107
	 static void g_mencoder_class_init(GMencoderClass * klass)
renatofilho@752
   108
{
renatofilho@752
   109
  GObjectClass *object_class;
renatofilho@752
   110
  object_class = (GObjectClass *) klass;
renatofilho@752
   111
  g_type_class_add_private(klass, sizeof(GMencoderPrivate));
renatofilho@588
   112
renatofilho@752
   113
  object_class->dispose = g_mencoder_dispose;
renatofilho@752
   114
  object_class->finalize = g_mencoder_finalize;
renatofilho@588
   115
renatofilho@752
   116
  g_mencoder_signals[PAUSED] =
renatofilho@752
   117
	g_signal_new("paused",
renatofilho@752
   118
				 G_OBJECT_CLASS_TYPE(object_class),
renatofilho@752
   119
				 G_SIGNAL_RUN_FIRST,
renatofilho@752
   120
				 0, NULL, NULL,
renatofilho@752
   121
				 g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
renatofilho@588
   122
renatofilho@752
   123
  g_mencoder_signals[PLAYING] =
renatofilho@752
   124
	g_signal_new("playing",
renatofilho@752
   125
				 G_OBJECT_CLASS_TYPE(object_class),
renatofilho@752
   126
				 G_SIGNAL_RUN_FIRST,
renatofilho@752
   127
				 0, NULL, NULL,
renatofilho@752
   128
				 g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
morphbr@748
   129
renatofilho@752
   130
  g_mencoder_signals[STOPED] =
renatofilho@752
   131
	g_signal_new("stoped",
renatofilho@752
   132
				 G_OBJECT_CLASS_TYPE(object_class),
renatofilho@752
   133
				 G_SIGNAL_RUN_FIRST,
renatofilho@752
   134
				 0, NULL, NULL,
renatofilho@752
   135
				 g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
renatofilho@588
   136
renatofilho@752
   137
  g_mencoder_signals[EOS] =
renatofilho@752
   138
	g_signal_new("eos",
renatofilho@752
   139
				 G_OBJECT_CLASS_TYPE(object_class),
renatofilho@752
   140
				 G_SIGNAL_RUN_FIRST,
renatofilho@752
   141
				 0, NULL, NULL,
renatofilho@752
   142
				 g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
renatofilho@588
   143
renatofilho@752
   144
  g_mencoder_signals[ERROR] =
renatofilho@752
   145
	g_signal_new("error",
renatofilho@752
   146
				 G_OBJECT_CLASS_TYPE(object_class),
renatofilho@752
   147
				 G_SIGNAL_RUN_LAST,
renatofilho@752
   148
				 0, NULL, NULL,
renatofilho@752
   149
				 g_cclosure_marshal_VOID__STRING,
renatofilho@752
   150
				 G_TYPE_NONE, 1, G_TYPE_STRING);
renatofilho@588
   151
}
renatofilho@588
   152
renatofilho@588
   153
static void
renatofilho@752
   154
g_mencoder_init(GMencoder * self)
renatofilho@588
   155
{
renatofilho@752
   156
  GMencoderPrivate *priv = G_MENCODER_GET_PRIVATE(self);
renatofilho@752
   157
  priv->info = g_new0(SetupInfo, 1);
renatofilho@588
   158
}
renatofilho@588
   159
morphbr@748
   160
static void
renatofilho@752
   161
g_mencoder_dispose(GObject * object)
renatofilho@588
   162
{
renatofilho@588
   163
}
renatofilho@588
   164
morphbr@748
   165
static void
renatofilho@752
   166
g_mencoder_finalize(GObject * object)
renatofilho@588
   167
{
renatofilho@752
   168
 //TODO: clear vars
renatofilho@752
   169
  g_mencoder_close_stream(G_MENCODER(object));
renatofilho@588
   170
}
renatofilho@588
   171
renatofilho@752
   172
GMencoder *
renatofilho@752
   173
g_mencoder_new(void)
renatofilho@588
   174
{
renatofilho@752
   175
  return g_object_new(G_TYPE_MENCODER, NULL);
renatofilho@588
   176
}
renatofilho@588
   177
renatofilho@600
   178
renatofilho@588
   179
static void
renatofilho@752
   180
_obj_set_prop(GObject * obj, const gchar * prop_name, const gchar * prop_val)
renatofilho@588
   181
{
renatofilho@752
   182
  GValue p = { 0 };
renatofilho@752
   183
  GValue v = { 0 };
renatofilho@752
   184
  GParamSpec *s = NULL;
renatofilho@752
   185
  GObjectClass *k = G_OBJECT_GET_CLASS(obj);
renatofilho@588
   186
renatofilho@588
   187
renatofilho@752
   188
  g_value_init(&v, G_TYPE_STRING);
renatofilho@752
   189
  g_value_set_string(&v, prop_val);
renatofilho@588
   190
renatofilho@752
   191
  s = g_object_class_find_property(k, prop_name);
renatofilho@752
   192
  if (s == NULL)
renatofilho@752
   193
	{
renatofilho@752
   194
	  g_print("Invalid property name: %s\n", prop_name);
renatofilho@752
   195
	  return;
renatofilho@752
   196
	}
renatofilho@588
   197
renatofilho@752
   198
  g_value_init(&p, s->value_type);
renatofilho@752
   199
  switch (s->value_type)
renatofilho@752
   200
	{
renatofilho@752
   201
	case G_TYPE_INT:
renatofilho@752
   202
	  g_value_set_int(&p, atoi(prop_val));
renatofilho@752
   203
	  break;
renatofilho@752
   204
	case G_TYPE_STRING:
renatofilho@752
   205
	  g_value_set_string(&p, prop_val);
renatofilho@752
   206
	  break;
renatofilho@752
   207
	default:
renatofilho@752
   208
	  return;
renatofilho@752
   209
	}
morphbr@748
   210
renatofilho@752
   211
  g_object_set_property(obj, prop_name, &p);
renatofilho@752
   212
  g_value_unset(&v);
renatofilho@752
   213
  g_value_unset(&p);
renatofilho@588
   214
}
renatofilho@588
   215
renatofilho@752
   216
static GstElement *
renatofilho@752
   217
_create_element_with_prop(const gchar * factory_name,
renatofilho@752
   218
						  const gchar * element_name, gchar ** prop)
renatofilho@588
   219
{
renatofilho@752
   220
  GstElement *ret;
renatofilho@752
   221
  int i;
renatofilho@588
   222
renatofilho@752
   223
  ret = gst_element_factory_make(factory_name, element_name);
renatofilho@752
   224
  if (ret == NULL)
renatofilho@752
   225
	return NULL;
renatofilho@588
   226
renatofilho@752
   227
  if (prop != NULL)
renatofilho@752
   228
	{
renatofilho@752
   229
	  for (i = 0; i < g_strv_length(prop); i++)
renatofilho@752
   230
		{
renatofilho@752
   231
		  if (prop[i] != NULL)
renatofilho@752
   232
			{
renatofilho@752
   233
			  char **v = g_strsplit(prop[i], "=", 2);
renatofilho@752
   234
			  if (g_strv_length(v) == 2)
renatofilho@752
   235
				{
renatofilho@752
   236
				  _obj_set_prop(G_OBJECT(ret), v[0], v[1]);
renatofilho@752
   237
				}
renatofilho@752
   238
			  g_strfreev(v);
renatofilho@752
   239
			}
renatofilho@752
   240
		}
renatofilho@752
   241
	}
renatofilho@588
   242
renatofilho@752
   243
  return ret;
renatofilho@588
   244
renatofilho@588
   245
}
renatofilho@588
   246
renatofilho@752
   247
static GstElement *
renatofilho@752
   248
_create_audio_bin(const gchar * encode, gchar ** encode_prop, gint rate)
renatofilho@588
   249
{
renatofilho@752
   250
  GstElement *abin = NULL;
renatofilho@752
   251
  GstElement *aqueue = NULL;
renatofilho@752
   252
  GstElement *aconvert = NULL;
renatofilho@752
   253
  GstElement *aencode = NULL;
renatofilho@752
   254
  GstElement *aqueue_src = NULL;
renatofilho@752
   255
  GstPad *apad = NULL;
renatofilho@588
   256
renatofilho@752
   257
 //audio/x-raw-int ! queue ! audioconvert ! faac ! rtpmp4gpay !  udpsink name=upd_audio host=224.0.0.1 port=5002
renatofilho@752
   258
  abin = gst_bin_new("abin");
renatofilho@752
   259
  aqueue = gst_element_factory_make("queue", "aqueue");
renatofilho@752
   260
  aconvert = gst_element_factory_make("audioconvert", "aconvert");
renatofilho@752
   261
  aencode =
renatofilho@752
   262
	_create_element_with_prop((encode ? encode : "lame"), "aencode",
renatofilho@752
   263
							  encode_prop);
renatofilho@752
   264
  aqueue_src = gst_element_factory_make("queue", "aqueue_src");
renatofilho@588
   265
renatofilho@752
   266
  if ((abin == NULL) || (aqueue == NULL) || (aconvert == NULL)
renatofilho@752
   267
	  || (aencode == NULL) || (aqueue_src == NULL))
renatofilho@752
   268
	{
renatofilho@752
   269
	  g_warning("Audio elements not found");
renatofilho@752
   270
	  goto error;
renatofilho@752
   271
	}
renatofilho@752
   272
renatofilho@752
   273
  g_object_set(G_OBJECT(aencode), "bitrate", 32, NULL);
renatofilho@752
   274
 /*
renatofilho@752
   275
    if (rate > 0) {
renatofilho@752
   276
    g_object_set (G_OBJECT (aencode), "bitrate", 32, NULL);
morphbr@748
   277
    }
renatofilho@752
   278
  */
renatofilho@588
   279
renatofilho@752
   280
  gst_bin_add_many(GST_BIN(abin), aqueue, aconvert, aencode, aqueue_src,
renatofilho@752
   281
				   NULL);
renatofilho@752
   282
  if (gst_element_link_many(aqueue, aconvert, aencode, aqueue_src, NULL) ==
renatofilho@752
   283
	  FALSE)
renatofilho@752
   284
	{
renatofilho@752
   285
	  g_warning("Not Link audio elements");
renatofilho@752
   286
	}
renatofilho@600
   287
renatofilho@752
   288
 //TODO: apply audio rate
renatofilho@588
   289
renatofilho@752
   290
 // ghost pad the audio bin
renatofilho@752
   291
  apad = gst_element_get_pad(aqueue, "sink");
renatofilho@752
   292
  gst_element_add_pad(abin, gst_ghost_pad_new("sink", apad));
renatofilho@752
   293
  gst_object_unref(apad);
renatofilho@588
   294
renatofilho@752
   295
  apad = gst_element_get_pad(aqueue_src, "src");
renatofilho@752
   296
  gst_element_add_pad(abin, gst_ghost_pad_new("src", apad));
renatofilho@752
   297
  gst_object_unref(apad);
morphbr@748
   298
renatofilho@752
   299
  return abin;
renatofilho@752
   300
error:
renatofilho@752
   301
  if (abin != NULL)
renatofilho@752
   302
	gst_object_unref(abin);
renatofilho@588
   303
renatofilho@752
   304
  if (aqueue != NULL)
renatofilho@752
   305
	gst_object_unref(aqueue);
renatofilho@588
   306
renatofilho@752
   307
  if (aconvert != NULL)
renatofilho@752
   308
	gst_object_unref(aconvert);
renatofilho@588
   309
renatofilho@752
   310
  if (aencode != NULL)
renatofilho@752
   311
	gst_object_unref(aencode);
renatofilho@588
   312
renatofilho@752
   313
  if (aqueue_src != NULL)
renatofilho@752
   314
	gst_object_unref(aqueue_src);
renatofilho@588
   315
renatofilho@752
   316
  if (apad != NULL)
renatofilho@752
   317
	gst_object_unref(apad);
renatofilho@588
   318
renatofilho@752
   319
  return NULL;
renatofilho@588
   320
}
renatofilho@588
   321
renatofilho@588
   322
renatofilho@588
   323
renatofilho@588
   324
renatofilho@588
   325
//queue ! videoscale ! video/x-raw-yuv,width=240,height=144 ! colorspace ! rate ! encode ! queue
renatofilho@752
   326
static GstElement *
renatofilho@752
   327
_create_video_bin(const gchar * encode,
renatofilho@752
   328
				  gchar ** encode_prop,
renatofilho@752
   329
				  gdouble fps, gint rate, guint width, guint height)
renatofilho@588
   330
{
renatofilho@752
   331
  GstElement *vbin = NULL;
renatofilho@752
   332
  GstElement *vqueue = NULL;
renatofilho@752
   333
  GstElement *vqueue_src = NULL;
renatofilho@752
   334
  GstElement *vcolorspace = NULL;
renatofilho@752
   335
  GstElement *vencode = NULL;
renatofilho@752
   336
  GstElement *vrate = NULL;
renatofilho@752
   337
  GstPad *vpad = NULL;
renatofilho@588
   338
renatofilho@752
   339
  vbin = gst_bin_new("vbin");
renatofilho@752
   340
  vqueue = gst_element_factory_make("queue", "vqueue");
renatofilho@752
   341
  vcolorspace = gst_element_factory_make("ffmpegcolorspace", "colorspace");
renatofilho@616
   342
renatofilho@752
   343
  vencode = _create_element_with_prop((encode !=
renatofilho@752
   344
									   NULL ? encode : "ffenc_mpeg1video"),
renatofilho@752
   345
									  "vencode", encode_prop);
renatofilho@752
   346
  vqueue_src = gst_element_factory_make("queue", "queue_src");
renatofilho@588
   347
renatofilho@752
   348
  if ((vbin == NULL) || (vqueue == NULL) || (vcolorspace == NULL)
renatofilho@752
   349
	  || (vencode == NULL) || (vqueue_src == NULL))
renatofilho@752
   350
	{
renatofilho@752
   351
	  g_warning("Video elements not found");
renatofilho@752
   352
	  goto error;
renatofilho@752
   353
	}
renatofilho@588
   354
renatofilho@752
   355
  gst_bin_add_many(GST_BIN(vbin), vqueue, vcolorspace, vencode, vqueue_src,
renatofilho@752
   356
				   NULL);
morphbr@748
   357
renatofilho@752
   358
  if ((width > 0) && (height > 0))
renatofilho@752
   359
	{
renatofilho@752
   360
	 //Scalling video
renatofilho@752
   361
	  GstCaps *vcaps;
renatofilho@752
   362
	  GstElement *vscale = gst_element_factory_make("videoscale", "vscale");
renatofilho@588
   363
renatofilho@752
   364
	  gst_bin_add(GST_BIN(vbin), vscale);
renatofilho@588
   365
renatofilho@752
   366
	  vcaps = gst_caps_new_simple("video/x-raw-yuv",
renatofilho@752
   367
								  "width", G_TYPE_INT, width,
renatofilho@752
   368
								  "height", G_TYPE_INT, height, NULL);
renatofilho@588
   369
renatofilho@752
   370
	  gst_element_link(vqueue, vscale);
morphbr@748
   371
renatofilho@752
   372
	  if (gst_element_link_filtered(vscale, vcolorspace, vcaps) == FALSE)
renatofilho@752
   373
		{
renatofilho@752
   374
		  g_warning("Fail to resize video");
renatofilho@752
   375
		  gst_object_unref(vcaps);
renatofilho@752
   376
		  gst_object_unref(vscale);
renatofilho@752
   377
		  goto error;
renatofilho@752
   378
		}
renatofilho@752
   379
	  gst_caps_unref(vcaps);
renatofilho@752
   380
	}
renatofilho@752
   381
  else
renatofilho@752
   382
	{
renatofilho@752
   383
	  gst_element_link(vqueue, vcolorspace);
renatofilho@752
   384
	}
renatofilho@588
   385
renatofilho@752
   386
  if (fps > 0)
renatofilho@752
   387
	{
renatofilho@752
   388
	 //Changing the video fps
renatofilho@752
   389
	  GstCaps *vcaps;
renatofilho@752
   390
	  vrate = gst_element_factory_make("videorate", "vrate");
renatofilho@588
   391
renatofilho@752
   392
	  gst_bin_add(GST_BIN(vbin), vrate);
renatofilho@588
   393
renatofilho@752
   394
	  if (gst_element_link(vcolorspace, vrate) == FALSE)
renatofilho@752
   395
		{
renatofilho@752
   396
		  g_warning("Fail to link video elements");
renatofilho@752
   397
		  goto error;
renatofilho@752
   398
		}
renatofilho@588
   399
renatofilho@752
   400
	  vcaps = gst_caps_new_simple("video/x-raw-yuv",
renatofilho@752
   401
								  "framerate", GST_TYPE_FRACTION,
renatofilho@752
   402
								  (int) (fps * 1000), 1000, NULL);
renatofilho@588
   403
renatofilho@752
   404
	  if (gst_element_link_filtered(vrate, vencode, vcaps) == FALSE)
renatofilho@752
   405
		{
renatofilho@752
   406
		  g_warning("Fail to link vrate with vencode.");
renatofilho@752
   407
		  goto error;
renatofilho@752
   408
		}
renatofilho@752
   409
	  gst_caps_unref(vcaps);
renatofilho@752
   410
	}
renatofilho@752
   411
  else
renatofilho@752
   412
	{
renatofilho@752
   413
	  if (gst_element_link(vcolorspace, vencode) == FALSE)
renatofilho@752
   414
		{
renatofilho@752
   415
		  g_warning("Fail to link colorspace and video encode element.");
renatofilho@752
   416
		  goto error;
renatofilho@752
   417
		}
renatofilho@752
   418
	}
morphbr@748
   419
renatofilho@752
   420
  gst_element_link(vencode, vqueue_src);
renatofilho@588
   421
renatofilho@752
   422
 // ghost pad the video  bin
renatofilho@752
   423
  vpad = gst_element_get_pad(vqueue, "sink");
renatofilho@752
   424
  gst_element_add_pad(vbin, gst_ghost_pad_new("sink", vpad));
renatofilho@752
   425
  gst_object_unref(vpad);
morphbr@748
   426
renatofilho@752
   427
  vpad = gst_element_get_pad(vqueue_src, "src");
renatofilho@752
   428
  gst_element_add_pad(vbin, gst_ghost_pad_new("src", vpad));
renatofilho@752
   429
  gst_object_unref(vpad);
renatofilho@588
   430
renatofilho@752
   431
  return vbin;
renatofilho@588
   432
renatofilho@752
   433
error:
renatofilho@752
   434
  if (vpad != NULL)
renatofilho@752
   435
	gst_object_unref(vpad);
renatofilho@588
   436
renatofilho@752
   437
  if (vbin != NULL)
renatofilho@752
   438
	gst_object_unref(vbin);
renatofilho@588
   439
renatofilho@752
   440
  if (vqueue != NULL)
renatofilho@752
   441
	gst_object_unref(vqueue);
renatofilho@588
   442
renatofilho@752
   443
  if (vencode != NULL)
renatofilho@752
   444
	gst_object_unref(vencode);
renatofilho@588
   445
renatofilho@752
   446
  if (vqueue_src != NULL)
renatofilho@752
   447
	gst_object_unref(vqueue_src);
renatofilho@588
   448
renatofilho@752
   449
  if (vcolorspace != NULL)
renatofilho@752
   450
	gst_object_unref(vcolorspace);
renatofilho@588
   451
renatofilho@752
   452
  return NULL;
renatofilho@588
   453
}
renatofilho@588
   454
renatofilho@588
   455
renatofilho@600
   456
renatofilho@600
   457
void
renatofilho@752
   458
g_mencoder_setup_stream(GMencoder * self,
renatofilho@752
   459
						const gchar * mux_name,
renatofilho@752
   460
						const gchar * video_encode,
renatofilho@752
   461
						gchar ** video_encode_prop,
renatofilho@752
   462
						gdouble video_fps,
renatofilho@752
   463
						gdouble video_rate,
renatofilho@752
   464
						guint video_width,
renatofilho@752
   465
						guint video_height,
renatofilho@752
   466
						const gchar * audio_encode,
renatofilho@752
   467
						gchar ** audio_encode_prop,
renatofilho@752
   468
						guint audio_rate, const gchar * out_uri)
renatofilho@600
   469
{
renatofilho@752
   470
  GMencoderPrivate *priv = G_MENCODER_GET_PRIVATE(self);
renatofilho@752
   471
  if (priv->ready == TRUE)
renatofilho@752
   472
	{
renatofilho@752
   473
	  g_warning("Stream already configured. You need close stream first.");
renatofilho@752
   474
	  return;
renatofilho@752
   475
	}
renatofilho@600
   476
renatofilho@752
   477
  _close_output(self);
renatofilho@752
   478
  _open_output(self, out_uri);
renatofilho@634
   479
renatofilho@752
   480
  priv->sources = 0;
renatofilho@752
   481
  priv->pipe = _create_pipeline(self,
renatofilho@752
   482
								video_encode,
renatofilho@752
   483
								mux_name,
renatofilho@752
   484
								video_encode_prop,
renatofilho@752
   485
								video_fps,
renatofilho@752
   486
								video_rate,
renatofilho@752
   487
								video_width,
renatofilho@752
   488
								video_height,
renatofilho@752
   489
								audio_encode, audio_encode_prop, audio_rate);
renatofilho@600
   490
renatofilho@600
   491
}
renatofilho@600
   492
renatofilho@600
   493
renatofilho@600
   494
gboolean
renatofilho@752
   495
g_mencoder_append_uri(GMencoder * self, const gchar * uri)
renatofilho@600
   496
{
renatofilho@752
   497
  GstPad *pad_src;
renatofilho@752
   498
  GstPad *pad_sink;
renatofilho@752
   499
  GstElement *src;
renatofilho@752
   500
  GMencoderPrivate *priv = G_MENCODER_GET_PRIVATE(self);
renatofilho@752
   501
  gboolean ret = FALSE;
renatofilho@752
   502
  GstElement *ap = NULL;
renatofilho@752
   503
  GstElement *vp = NULL;
renatofilho@634
   504
renatofilho@600
   505
renatofilho@752
   506
  g_return_val_if_fail(priv->pipe != NULL, FALSE);
renatofilho@752
   507
  g_return_val_if_fail(priv->ready == FALSE, FALSE);
renatofilho@600
   508
renatofilho@634
   509
#ifndef SUPPORT_MULT_INPUT
renatofilho@752
   510
  g_return_val_if_fail(priv->sources < 1, FALSE);
renatofilho@634
   511
#endif
renatofilho@634
   512
renatofilho@752
   513
  src = _create_source(uri);
renatofilho@752
   514
  if (src == NULL)
renatofilho@752
   515
	return FALSE;
renatofilho@600
   516
renatofilho@752
   517
  priv->src = gst_bin_get_by_name(GST_BIN(src), "src");
renatofilho@671
   518
renatofilho@752
   519
  gst_bin_add(GST_BIN(priv->pipe), src);
renatofilho@600
   520
renatofilho@634
   521
#ifdef SUPPORT_MULT_INPUT
renatofilho@752
   522
  ap = gst_bin_get_by_name(GST_BIN(priv->pipe), "ap");
renatofilho@752
   523
  vp = gst_bin_get_by_name(GST_BIN(priv->pipe), "vp");
renatofilho@634
   524
#else
renatofilho@752
   525
  ap = gst_bin_get_by_name(GST_BIN(priv->pipe), "abin");
renatofilho@752
   526
  vp = gst_bin_get_by_name(GST_BIN(priv->pipe), "vbin");
renatofilho@634
   527
#endif
renatofilho@634
   528
renatofilho@752
   529
  if ((vp == NULL) || (ap == NULL))
renatofilho@752
   530
	{
renatofilho@752
   531
	  g_warning("Fail to get output bin");
renatofilho@752
   532
	  goto error;
renatofilho@752
   533
	}
renatofilho@600
   534
renatofilho@752
   535
  pad_src = gst_element_get_pad(src, "src_audio");
renatofilho@752
   536
  pad_sink = gst_element_get_compatible_pad(ap,
renatofilho@752
   537
											pad_src,
renatofilho@752
   538
											gst_pad_get_caps(pad_src));
renatofilho@600
   539
renatofilho@752
   540
  if ((pad_sink == NULL) || (pad_src == NULL))
renatofilho@752
   541
	goto error;
renatofilho@600
   542
renatofilho@752
   543
  GstPadLinkReturn lret = gst_pad_link(pad_src, pad_sink);
renatofilho@752
   544
  if (lret != GST_PAD_LINK_OK)
renatofilho@752
   545
	goto error;
renatofilho@600
   546
renatofilho@752
   547
  gst_object_unref(pad_src);
renatofilho@752
   548
  gst_object_unref(pad_sink);
renatofilho@600
   549
renatofilho@752
   550
  pad_src = gst_element_get_pad(src, "src_video");
renatofilho@752
   551
  pad_sink = gst_element_get_compatible_pad(vp,
renatofilho@752
   552
											pad_src,
renatofilho@752
   553
											gst_pad_get_caps(pad_src));
renatofilho@600
   554
renatofilho@752
   555
  if ((pad_src == NULL) || (pad_sink == NULL))
renatofilho@752
   556
	goto error;
renatofilho@600
   557
renatofilho@752
   558
  if (gst_pad_link(pad_src, pad_sink) != GST_PAD_LINK_OK)
renatofilho@752
   559
	{
renatofilho@752
   560
	  g_warning("invalid source. video");
renatofilho@752
   561
	  goto error;
renatofilho@752
   562
	}
renatofilho@600
   563
renatofilho@752
   564
  priv->sources++;
renatofilho@752
   565
  ret = TRUE;
renatofilho@752
   566
error:
renatofilho@600
   567
renatofilho@752
   568
  if ((src != NULL) && (ret == FALSE))
renatofilho@752
   569
	{
renatofilho@752
   570
	  gst_bin_remove(GST_BIN(priv->pipe), src);
renatofilho@752
   571
	  gst_object_unref(src);
renatofilho@752
   572
	}
renatofilho@600
   573
renatofilho@752
   574
  if (ap != NULL)
renatofilho@752
   575
	gst_object_unref(ap);
renatofilho@600
   576
renatofilho@752
   577
  if (vp != NULL)
renatofilho@752
   578
	gst_object_unref(vp);
renatofilho@600
   579
renatofilho@752
   580
  if (pad_src != NULL)
renatofilho@752
   581
	gst_object_unref(pad_src);
renatofilho@600
   582
renatofilho@752
   583
  if (pad_sink != NULL)
renatofilho@752
   584
	gst_object_unref(pad_sink);
renatofilho@600
   585
renatofilho@752
   586
  return ret;
renatofilho@600
   587
}
renatofilho@600
   588
renatofilho@600
   589
renatofilho@600
   590
morphbr@748
   591
void
renatofilho@752
   592
g_mencoder_remove_uri(GMencoder * self, const gchar * uri)
renatofilho@600
   593
{
renatofilho@752
   594
 // GMencoderPrivate *priv = G_MENCODER_GET_PRIVATE (self);
renatofilho@752
   595
 //TODO: remove src
renatofilho@600
   596
}
renatofilho@600
   597
renatofilho@600
   598
void
renatofilho@752
   599
g_mencoder_play_stream(GMencoder * self)
renatofilho@600
   600
{
renatofilho@752
   601
  GMencoderPrivate *priv = G_MENCODER_GET_PRIVATE(self);
renatofilho@752
   602
  g_return_if_fail(priv->ready == FALSE);
renatofilho@752
   603
  priv->ready = TRUE;
renatofilho@752
   604
  gst_element_set_state(priv->pipe, GST_STATE_PLAYING);
renatofilho@752
   605
  priv->tick_id = g_timeout_add(500, _tick_cb, self);
renatofilho@600
   606
}
renatofilho@600
   607
renatofilho@600
   608
void
renatofilho@752
   609
g_mencoder_pause_stream(GMencoder * self)
renatofilho@600
   610
{
renatofilho@752
   611
  GMencoderPrivate *priv = G_MENCODER_GET_PRIVATE(self);
renatofilho@752
   612
  g_return_if_fail(priv->ready == TRUE);
renatofilho@752
   613
  gst_element_set_state(priv->pipe, GST_STATE_PAUSED);
renatofilho@600
   614
}
renatofilho@600
   615
renatofilho@600
   616
void
renatofilho@752
   617
g_mencoder_close_stream(GMencoder * self)
renatofilho@600
   618
{
renatofilho@600
   619
renatofilho@752
   620
  GMencoderPrivate *priv = G_MENCODER_GET_PRIVATE(self);
renatofilho@752
   621
  if (priv->tick_id != 0)
renatofilho@752
   622
	{
renatofilho@752
   623
	  g_source_remove(priv->tick_id);
renatofilho@752
   624
	  priv->tick_id = 0;
renatofilho@752
   625
	}
renatofilho@600
   626
renatofilho@752
   627
  if (priv->pipe != NULL)
renatofilho@752
   628
	{
renatofilho@752
   629
	 //TODO: fixe pipeline dispose
renatofilho@752
   630
	 //gst_element_set_state (priv->pipe, GST_STATE_NULL);
renatofilho@752
   631
	 //g_debug ("SETING STATE TO NULL: OK");
renatofilho@752
   632
	 //gst_element_set_state (priv->pipe, GST_STATE_NULL);
renatofilho@752
   633
	 //gst_object_unref (priv->pipe);
renatofilho@752
   634
	  gst_object_unref(priv->src);
renatofilho@752
   635
	  priv->src = NULL;
renatofilho@752
   636
	  priv->pipe = NULL;
renatofilho@752
   637
	  priv->abin = NULL;
renatofilho@752
   638
	  priv->vbin = NULL;
renatofilho@752
   639
	  priv->sink = NULL;
renatofilho@752
   640
	}
renatofilho@752
   641
  priv->ready = FALSE;
renatofilho@600
   642
}
renatofilho@600
   643
renatofilho@752
   644
static GstElement *
renatofilho@752
   645
_create_pipeline(GMencoder * self,
renatofilho@752
   646
				 const gchar * video_encode,
renatofilho@752
   647
				 const gchar * mux_name,
renatofilho@752
   648
				 gchar ** video_encode_prop,
renatofilho@752
   649
				 gdouble video_fps,
renatofilho@752
   650
				 gdouble video_rate,
renatofilho@752
   651
				 guint video_width,
renatofilho@752
   652
				 guint video_height,
renatofilho@752
   653
				 const gchar * audio_encode,
renatofilho@752
   654
				 gchar ** audio_encode_prop, guint audio_rate)
renatofilho@588
   655
{
renatofilho@752
   656
  GstBus *bus = NULL;
renatofilho@752
   657
  GstElement *pipe = NULL;
renatofilho@752
   658
  GstElement *sink = NULL;
renatofilho@752
   659
  GstElement *mux = NULL;
renatofilho@752
   660
  GstElement *abin = NULL;
renatofilho@752
   661
  GstElement *vbin = NULL;
renatofilho@752
   662
  GstElement *queue = NULL;
renatofilho@752
   663
  GstPad *aux_pad = NULL;
renatofilho@752
   664
  GstPad *mux_pad = NULL;
renatofilho@634
   665
#ifdef SUPPORT_MULT_INPUT
renatofilho@752
   666
  GstElement *ap = NULL;
renatofilho@752
   667
  GstElement *vp = NULL;
renatofilho@634
   668
#endif
renatofilho@752
   669
  GMencoderPrivate *priv = G_MENCODER_GET_PRIVATE(self);
renatofilho@588
   670
renatofilho@752
   671
  pipe = gst_pipeline_new("pipe");
renatofilho@588
   672
morphbr@748
   673
#ifdef SUPPORT_MULT_INPUT
renatofilho@752
   674
  ap = gst_element_factory_make("concatmux", "ap");
renatofilho@752
   675
  vp = gst_element_factory_make("concatmux", "vp");
renatofilho@752
   676
  gst_bin_add_many(GST_BIN(pipe), ap, vp, NULL);
renatofilho@634
   677
#endif
renatofilho@588
   678
renatofilho@752
   679
  mux = gst_element_factory_make((mux_name ? mux_name : "ffmux_mpeg"), "mux");
renatofilho@752
   680
  if (mux == NULL)
renatofilho@752
   681
	goto error;
renatofilho@588
   682
renatofilho@752
   683
  queue = gst_element_factory_make("queue", "queueu_sink");
renatofilho@712
   684
renatofilho@634
   685
renatofilho@752
   686
  sink = gst_element_factory_make("fdsink", "sink");
renatofilho@752
   687
  if (sink == NULL)
renatofilho@752
   688
	goto error;
renatofilho@588
   689
renatofilho@752
   690
  g_object_set(G_OBJECT(sink), "fd", priv->fd, "sync", FALSE, NULL);
renatofilho@600
   691
renatofilho@752
   692
  abin = _create_audio_bin(audio_encode, audio_encode_prop, audio_rate);
renatofilho@752
   693
  if (abin == NULL)
renatofilho@752
   694
	goto error;
renatofilho@588
   695
renatofilho@752
   696
  vbin =
renatofilho@752
   697
	_create_video_bin(video_encode, video_encode_prop, video_fps, video_rate,
renatofilho@752
   698
					  video_width, video_height);
renatofilho@752
   699
  if (vbin == NULL)
renatofilho@752
   700
	goto error;
renatofilho@588
   701
renatofilho@752
   702
 // Finish Pipe
renatofilho@752
   703
  gst_bin_add_many(GST_BIN(pipe), abin, vbin, mux, queue, sink, NULL);
renatofilho@600
   704
renatofilho@600
   705
morphbr@748
   706
#ifdef SUPPORT_MULT_INPUT
renatofilho@752
   707
  if (gst_element_link(ap, abin) == FALSE)
renatofilho@752
   708
	{
renatofilho@752
   709
	  g_warning("Fail to link concat and abin");
renatofilho@752
   710
	  goto error;
renatofilho@752
   711
	}
renatofilho@634
   712
renatofilho@752
   713
  if (gst_element_link(vp, vbin) == FALSE)
renatofilho@752
   714
	{
renatofilho@752
   715
	  g_warning("Fail to link concat and vbin");
renatofilho@752
   716
	}
morphbr@748
   717
#endif
renatofilho@588
   718
renatofilho@752
   719
 //Link bins with mux
renatofilho@752
   720
  aux_pad = gst_element_get_pad(abin, "src");
renatofilho@752
   721
  mux_pad =
renatofilho@752
   722
	gst_element_get_compatible_pad(mux, aux_pad, GST_PAD_CAPS(aux_pad));
renatofilho@752
   723
  if (mux_pad == NULL)
renatofilho@752
   724
	{
renatofilho@752
   725
	  g_warning("Mux element no have audio PAD");
renatofilho@752
   726
	  goto error;
renatofilho@752
   727
	}
renatofilho@752
   728
  GstPadLinkReturn ret = gst_pad_link(aux_pad, mux_pad);
renatofilho@752
   729
  if (ret != GST_PAD_LINK_OK)
renatofilho@752
   730
	{
renatofilho@752
   731
	  g_warning("Fail link audio and mux: %d", ret);
renatofilho@752
   732
	  goto error;
morphbr@748
   733
renatofilho@752
   734
	}
renatofilho@752
   735
  gst_object_unref(aux_pad);
renatofilho@752
   736
  gst_object_unref(mux_pad);
renatofilho@588
   737
renatofilho@752
   738
  aux_pad = gst_element_get_pad(vbin, "src");
renatofilho@752
   739
  mux_pad =
renatofilho@752
   740
	gst_element_get_compatible_pad(mux, aux_pad, GST_PAD_CAPS(aux_pad));
renatofilho@752
   741
  if (mux_pad == NULL)
renatofilho@752
   742
	{
renatofilho@752
   743
	  g_warning("Mux element no have video PAD");
renatofilho@752
   744
	  goto error;
renatofilho@752
   745
	}
renatofilho@752
   746
  ret = gst_pad_link(aux_pad, mux_pad);
renatofilho@752
   747
  if (ret != GST_PAD_LINK_OK)
renatofilho@752
   748
	{
renatofilho@752
   749
	  g_warning("Fail link video and mux: %d", ret);
renatofilho@752
   750
	  goto error;
renatofilho@752
   751
	}
renatofilho@752
   752
  gst_object_unref(aux_pad);
renatofilho@752
   753
  gst_object_unref(mux_pad);
renatofilho@752
   754
  aux_pad = NULL;
renatofilho@752
   755
  mux_pad = NULL;
renatofilho@588
   756
renatofilho@752
   757
 //Link mux with sink
renatofilho@752
   758
  gst_element_link_many(mux, queue, sink, NULL);
renatofilho@588
   759
renatofilho@752
   760
  bus = gst_pipeline_get_bus(GST_PIPELINE(pipe));
renatofilho@752
   761
  gst_bus_add_watch(bus, _pipeline_bus_cb, self);
renatofilho@752
   762
  gst_object_unref(bus);
renatofilho@752
   763
  return pipe;
renatofilho@588
   764
renatofilho@752
   765
error:
renatofilho@752
   766
  g_warning("Invalid uri");
morphbr@748
   767
renatofilho@752
   768
  if (pipe != NULL)
renatofilho@752
   769
	{
renatofilho@752
   770
	  gst_object_unref(pipe);
renatofilho@752
   771
	}
renatofilho@588
   772
renatofilho@588
   773
renatofilho@752
   774
  if (mux != NULL)
renatofilho@752
   775
	{
renatofilho@752
   776
	  gst_object_unref(mux);
renatofilho@752
   777
	}
renatofilho@588
   778
renatofilho@752
   779
  if (mux_pad != NULL)
renatofilho@752
   780
	{
renatofilho@752
   781
	  gst_object_unref(mux_pad);
renatofilho@752
   782
	}
renatofilho@588
   783
renatofilho@752
   784
  if (aux_pad != NULL)
renatofilho@752
   785
	{
renatofilho@752
   786
	  gst_object_unref(mux_pad);
renatofilho@752
   787
	}
renatofilho@588
   788
renatofilho@752
   789
  if (sink != NULL)
renatofilho@752
   790
	{
renatofilho@752
   791
	  gst_object_unref(sink);
renatofilho@752
   792
	}
renatofilho@588
   793
renatofilho@752
   794
  if (abin != NULL)
renatofilho@752
   795
	{
renatofilho@752
   796
	  gst_object_unref(abin);
renatofilho@752
   797
	}
renatofilho@588
   798
renatofilho@752
   799
  if (vbin != NULL)
renatofilho@752
   800
	{
renatofilho@752
   801
	  gst_object_unref(vbin);
renatofilho@752
   802
	}
renatofilho@588
   803
renatofilho@752
   804
  return FALSE;
renatofilho@588
   805
}
renatofilho@588
   806
renatofilho@600
   807
renatofilho@600
   808
static void
renatofilho@752
   809
_close_output(GMencoder * self)
renatofilho@588
   810
{
renatofilho@600
   811
}
renatofilho@600
   812
renatofilho@752
   813
static GstElement *
renatofilho@752
   814
_create_source(const gchar * uri)
renatofilho@600
   815
{
renatofilho@600
   816
renatofilho@752
   817
  GstElement *bsrc = NULL;
renatofilho@752
   818
  GstElement *src = NULL;
renatofilho@752
   819
  GstElement *queue = NULL;
renatofilho@752
   820
  GstElement *aqueue = NULL;
renatofilho@752
   821
  GstElement *vqueue = NULL;
renatofilho@752
   822
  GstElement *decode = NULL;
renatofilho@752
   823
  GstPad *src_pad = NULL;
renatofilho@600
   824
renatofilho@600
   825
renatofilho@752
   826
  bsrc = gst_bin_new(NULL);
renatofilho@600
   827
renatofilho@752
   828
 //src = gst_element_factory_make ("gnomevfssrc", "src");
renatofilho@752
   829
 //g_object_set (G_OBJECT (src), "location", uri, NULL);
renatofilho@752
   830
  src = gst_element_make_from_uri(GST_URI_SRC, uri, "src");
renatofilho@752
   831
  if (src == NULL)
renatofilho@752
   832
	goto error;
renatofilho@600
   833
renatofilho@752
   834
  decode = gst_element_factory_make("decodebin", "decode");
renatofilho@752
   835
  if (decode == NULL)
renatofilho@752
   836
	goto error;
renatofilho@600
   837
renatofilho@752
   838
  queue = gst_element_factory_make("queue", "queue_src");
renatofilho@752
   839
  aqueue = gst_element_factory_make("queue", "aqueue");
renatofilho@752
   840
  if (aqueue == NULL)
renatofilho@752
   841
	goto error;
renatofilho@600
   842
renatofilho@752
   843
  vqueue = gst_element_factory_make("queue", "vqueue");
renatofilho@752
   844
  if (vqueue == NULL)
renatofilho@752
   845
	goto error;
renatofilho@600
   846
renatofilho@752
   847
  gst_bin_add_many(GST_BIN(bsrc), src, queue, decode, aqueue, vqueue, NULL);
renatofilho@752
   848
  gst_element_link_many(src, queue, decode, NULL);
renatofilho@600
   849
renatofilho@752
   850
  g_signal_connect(G_OBJECT(decode),
renatofilho@752
   851
				   "new-decoded-pad",
renatofilho@752
   852
				   G_CALLBACK(_decodebin_new_pad_cb), bsrc);
renatofilho@600
   853
renatofilho@752
   854
  g_signal_connect(G_OBJECT(decode),
renatofilho@752
   855
				   "unknown-type",
renatofilho@752
   856
				   G_CALLBACK(_decodebin_unknown_type_cb), pipe);
renatofilho@600
   857
renatofilho@752
   858
  src_pad = gst_element_get_pad(aqueue, "src");
renatofilho@752
   859
  gst_element_add_pad(bsrc, gst_ghost_pad_new("src_audio", src_pad));
renatofilho@752
   860
  gst_object_unref(src_pad);
renatofilho@600
   861
renatofilho@752
   862
  src_pad = gst_element_get_pad(vqueue, "src");
renatofilho@752
   863
  gst_element_add_pad(bsrc, gst_ghost_pad_new("src_video", src_pad));
renatofilho@752
   864
  gst_object_unref(src_pad);
renatofilho@600
   865
renatofilho@752
   866
  return bsrc;
renatofilho@600
   867
renatofilho@752
   868
error:
renatofilho@752
   869
  if (src != NULL)
renatofilho@752
   870
	{
renatofilho@752
   871
	  gst_object_unref(src);
renatofilho@752
   872
	}
renatofilho@600
   873
renatofilho@752
   874
  if (decode != NULL)
renatofilho@752
   875
	{
renatofilho@752
   876
	  gst_object_unref(decode);
renatofilho@752
   877
	}
renatofilho@600
   878
renatofilho@752
   879
  if (aqueue != NULL)
renatofilho@752
   880
	{
renatofilho@752
   881
	  gst_object_unref(aqueue);
renatofilho@752
   882
	}
renatofilho@600
   883
renatofilho@752
   884
  if (vqueue != NULL)
renatofilho@752
   885
	{
renatofilho@752
   886
	  gst_object_unref(vqueue);
renatofilho@752
   887
	}
renatofilho@600
   888
renatofilho@752
   889
  return NULL;
renatofilho@600
   890
}
renatofilho@600
   891
renatofilho@600
   892
static void
renatofilho@752
   893
_open_output(GMencoder * self, const gchar * uri)
renatofilho@600
   894
{
renatofilho@752
   895
  gchar **i;
renatofilho@752
   896
  GMencoderPrivate *priv = G_MENCODER_GET_PRIVATE(self);
renatofilho@588
   897
renatofilho@752
   898
  i = g_strsplit(uri, "://", 0);
renatofilho@752
   899
  if (strcmp(i[0], "fd") == 0)
renatofilho@752
   900
	{
renatofilho@752
   901
	  priv->fd = atoi(i[1]);
renatofilho@752
   902
	}
renatofilho@752
   903
  else if (strcmp(i[0], "file") == 0)
renatofilho@752
   904
	{
renatofilho@752
   905
	  priv->fd = open(i[1], O_WRONLY | O_CREAT | O_TRUNC,
renatofilho@752
   906
					  S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
renatofilho@752
   907
	}
renatofilho@752
   908
  else
renatofilho@752
   909
	{
renatofilho@752
   910
	  g_warning("Output uri not supported");
renatofilho@752
   911
	}
renatofilho@588
   912
renatofilho@752
   913
  g_strfreev(i);
renatofilho@588
   914
}
renatofilho@588
   915
renatofilho@588
   916
static gboolean
renatofilho@752
   917
_pipeline_bus_cb(GstBus * bus, GstMessage * msg, gpointer user_data)
renatofilho@588
   918
{
renatofilho@752
   919
  GMencoderPrivate *priv = G_MENCODER_GET_PRIVATE(user_data);
renatofilho@600
   920
renatofilho@752
   921
  switch (GST_MESSAGE_TYPE(msg))
renatofilho@588
   922
	{
renatofilho@588
   923
renatofilho@752
   924
	case GST_MESSAGE_STATE_CHANGED:
renatofilho@752
   925
	  {
renatofilho@752
   926
		GstState oldstate;
renatofilho@752
   927
		GstState newstate;
renatofilho@752
   928
		GstState pendingstate;
renatofilho@588
   929
morphbr@748
   930
renatofilho@752
   931
		gst_message_parse_state_changed(msg, &oldstate,
renatofilho@752
   932
										&newstate, &pendingstate);
renatofilho@588
   933
renatofilho@752
   934
		if (pendingstate != GST_STATE_VOID_PENDING)
renatofilho@752
   935
		  break;
renatofilho@588
   936
renatofilho@752
   937
		if ((oldstate == GST_STATE_READY) && (newstate == GST_STATE_PAUSED))
renatofilho@752
   938
		  {
renatofilho@752
   939
			if (priv->ready)
renatofilho@752
   940
			  g_signal_emit(user_data, g_mencoder_signals[PAUSED], 0);
renatofilho@752
   941
		  }
renatofilho@752
   942
		else if ((oldstate == GST_STATE_PAUSED) &&
renatofilho@752
   943
				 (newstate == GST_STATE_PLAYING))
renatofilho@752
   944
		  {
renatofilho@752
   945
			g_signal_emit(user_data, g_mencoder_signals[PLAYING], 0);
renatofilho@752
   946
		  }
renatofilho@752
   947
		else if ((oldstate == GST_STATE_READY) &&
renatofilho@752
   948
				 (newstate == GST_STATE_NULL))
renatofilho@752
   949
		  {
renatofilho@752
   950
			g_signal_emit(user_data, g_mencoder_signals[STOPED], 0);
renatofilho@752
   951
		  }
renatofilho@752
   952
		break;
renatofilho@752
   953
	  }
renatofilho@678
   954
renatofilho@752
   955
	case GST_MESSAGE_ERROR:
renatofilho@752
   956
	  {
renatofilho@752
   957
		GError *error;
renatofilho@752
   958
		gchar *debug;
renatofilho@752
   959
		gchar *err_str;
morphbr@748
   960
renatofilho@752
   961
		if (priv->tick_id != 0)
renatofilho@752
   962
		  {
renatofilho@752
   963
			g_source_remove(priv->tick_id);
renatofilho@752
   964
			priv->tick_id = 0;
renatofilho@752
   965
		  }
morphbr@748
   966
renatofilho@752
   967
		gst_message_parse_error(msg, &error, &debug);
renatofilho@752
   968
		err_str = g_strdup_printf("Error [%d] %s (%s)", error->code,
renatofilho@752
   969
								  error->message, debug);
renatofilho@752
   970
		priv->ready = FALSE;
renatofilho@752
   971
		g_signal_emit(user_data, g_mencoder_signals[ERROR], 0, err_str);
renatofilho@752
   972
		g_free(err_str);
renatofilho@752
   973
		g_clear_error(&error);
renatofilho@752
   974
		g_free(debug);
renatofilho@752
   975
		break;
renatofilho@752
   976
	  }
morphbr@748
   977
renatofilho@752
   978
	case GST_MESSAGE_EOS:
renatofilho@752
   979
	  priv->ready = FALSE;
renatofilho@752
   980
	  g_signal_emit(user_data, g_mencoder_signals[EOS], 0);
renatofilho@752
   981
	  break;
morphbr@748
   982
renatofilho@752
   983
	case GST_MESSAGE_DURATION:
renatofilho@752
   984
	  {
renatofilho@752
   985
		GstFormat format;
renatofilho@752
   986
		gint64 duration;
renatofilho@752
   987
		gst_message_parse_duration(msg, &format, &duration);
renatofilho@752
   988
		if (format == GST_FORMAT_BYTES)
renatofilho@752
   989
		  priv->duration = duration;
renatofilho@752
   990
		break;
renatofilho@752
   991
	  }
renatofilho@752
   992
	default:
renatofilho@752
   993
	  {
renatofilho@752
   994
		break;
renatofilho@752
   995
	  }
renatofilho@588
   996
	}
renatofilho@752
   997
  return TRUE;
renatofilho@588
   998
}
renatofilho@588
   999
renatofilho@600
  1000
renatofilho@600
  1001
morphbr@748
  1002
static void
renatofilho@752
  1003
_decodebin_new_pad_cb(GstElement * object,
renatofilho@752
  1004
					  GstPad * pad, gboolean flag, gpointer user_data)
renatofilho@588
  1005
{
renatofilho@752
  1006
  GstCaps *caps;
renatofilho@752
  1007
  gchar *str_caps = NULL;
renatofilho@752
  1008
  GstElement *sink_element;
renatofilho@752
  1009
  GstPad *sink_pad;
renatofilho@588
  1010
renatofilho@752
  1011
  caps = gst_pad_get_caps(pad);
renatofilho@752
  1012
  str_caps = gst_caps_to_string(caps);
renatofilho@752
  1013
  if (strstr(str_caps, "audio") != NULL)
renatofilho@752
  1014
	{
renatofilho@752
  1015
	  sink_element = gst_bin_get_by_name(GST_BIN(user_data), "aqueue");
renatofilho@752
  1016
	}
renatofilho@752
  1017
  else if (strstr(str_caps, "video") != NULL)
renatofilho@752
  1018
	{
renatofilho@752
  1019
	  sink_element = gst_bin_get_by_name(GST_BIN(user_data), "vqueue");
renatofilho@752
  1020
	}
renatofilho@752
  1021
  else
renatofilho@752
  1022
	{
renatofilho@752
  1023
	  g_warning("invalid caps %s", str_caps);
renatofilho@752
  1024
	}
renatofilho@588
  1025
renatofilho@752
  1026
  sink_pad = gst_element_get_pad(sink_element, "sink");
renatofilho@752
  1027
  gst_pad_link(pad, sink_pad);
renatofilho@600
  1028
renatofilho@752
  1029
  gst_object_unref(sink_element);
renatofilho@752
  1030
  gst_object_unref(sink_pad);
renatofilho@752
  1031
  g_free(str_caps);
renatofilho@752
  1032
  gst_caps_unref(caps);
renatofilho@588
  1033
}
renatofilho@588
  1034
morphbr@748
  1035
static void
renatofilho@752
  1036
_decodebin_unknown_type_cb(GstElement * object,
renatofilho@752
  1037
						   GstPad * pad, GstCaps * caps, gpointer user_data)
renatofilho@588
  1038
{
renatofilho@752
  1039
  g_warning("Unknown Type");
renatofilho@752
  1040
 //priv->ready = FALSE;
renatofilho@588
  1041
}
renatofilho@654
  1042
renatofilho@654
  1043
static gboolean
renatofilho@752
  1044
_tick_cb(gpointer user_data)
renatofilho@654
  1045
{
renatofilho@752
  1046
  GstFormat format = GST_FORMAT_BYTES;
renatofilho@752
  1047
  gint64 cur = 0;
renatofilho@654
  1048
renatofilho@752
  1049
  GMencoderPrivate *priv = G_MENCODER_GET_PRIVATE(user_data);
renatofilho@654
  1050
renatofilho@752
  1051
  if (priv->duration == 0)
renatofilho@752
  1052
	{
renatofilho@752
  1053
	  gint64 d = 0;
renatofilho@752
  1054
	  if (gst_element_query_duration(priv->src, &format, &d))
renatofilho@752
  1055
		priv->duration = d;
renatofilho@752
  1056
	}
renatofilho@671
  1057
renatofilho@752
  1058
  if (priv->duration != 0)
renatofilho@752
  1059
	{
renatofilho@752
  1060
	  gst_element_query_position(priv->src, &format, &cur);
renatofilho@752
  1061
	  g_print("PROGRESS:%lli\n", (99 * cur) / priv->duration);
renatofilho@752
  1062
	}
renatofilho@654
  1063
renatofilho@752
  1064
  return TRUE;
renatofilho@654
  1065
}