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