gst-gpac/src/gpacmux.c
author melunko
Thu Feb 21 17:54:48 2008 +0000 (2008-02-21)
branchtrunk
changeset 919 ec8c246e9d29
child 920 e3e434d3ed83
permissions -rw-r--r--
[svn r928] Added some information at README
melunko@917
     1
melunko@917
     2
#ifdef HAVE_CONFIG_H
melunko@917
     3
#include "config.h"
melunko@917
     4
#endif
melunko@917
     5
melunko@917
     6
#include <gst/gst.h>
melunko@917
     7
#include <gst/base/gstcollectpads.h>
melunko@917
     8
melunko@917
     9
#include <stdlib.h> 
melunko@917
    10
#include <string.h>
melunko@917
    11
melunko@917
    12
/* gpac includes */
melunko@917
    13
#include <gpac/isomedia.h>
melunko@917
    14
melunko@917
    15
#define GST_TYPE_GPAC_MUX (gst_gpac_mux_get_type())
melunko@917
    16
#define GST_GPAC_MUX(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_GPAC_MUX, GstGpacMux))
melunko@917
    17
#define GST_GPAC_MUX_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_GPAC_MUX, GstGpacMux))
melunko@917
    18
#define GST_IS_GPAC_MUX(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_GPAC_MUX))
melunko@917
    19
#define GST_IS_GPAC_MUX_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_GPAC_MUX))
melunko@917
    20
melunko@917
    21
typedef struct _GstGpacMux GstGpacMux;
melunko@917
    22
typedef struct _GstGpacMuxClass GstGpacMuxClass;
melunko@917
    23
melunko@917
    24
typedef enum
melunko@917
    25
{
melunko@917
    26
  GST_GPAC_PAD_STATE_CONTROL = 0,
melunko@917
    27
  GST_GPAC_PAD_STATE_DATA = 1
melunko@917
    28
}
melunko@917
    29
GstGpacPadState;
melunko@917
    30
melunko@917
    31
typedef struct
melunko@917
    32
{
melunko@917
    33
  GstCollectData collect;       /* we extend the CollectData */
melunko@917
    34
melunko@917
    35
  gint track_number;
melunko@917
    36
  guint32 di; /* outDescriptionIndex */
melunko@917
    37
melunko@917
    38
  guint32 frame_count;
melunko@917
    39
  gboolean is_video;
melunko@917
    40
melunko@917
    41
} GstGpacPad;
melunko@917
    42
melunko@917
    43
struct _GstGpacMux
melunko@917
    44
{
melunko@917
    45
  GstElement element;
melunko@917
    46
melunko@917
    47
  GstPad *srcpad;
melunko@917
    48
  GstCollectPads *collect;
melunko@917
    49
melunko@917
    50
  GF_ISOFile *file;
melunko@917
    51
melunko@917
    52
};
melunko@917
    53
melunko@917
    54
struct _GstGpacMuxClass
melunko@917
    55
{
melunko@917
    56
  GstElementClass parent_class;
melunko@917
    57
};
melunko@917
    58
melunko@917
    59
/* elementfactory information */
melunko@917
    60
static const GstElementDetails gst_gpac_mux_details =
melunko@917
    61
GST_ELEMENT_DETAILS ("Gpac muxer",
melunko@917
    62
    "Codec/Muxer",
melunko@917
    63
    "mux mp4 streams",
melunko@917
    64
    "Hallyson Melo <hallyson.melo@indt.org.br");
melunko@917
    65
melunko@917
    66
/* GpacMux signals and args */
melunko@917
    67
enum
melunko@917
    68
{
melunko@917
    69
  /* FILL ME */
melunko@917
    70
  LAST_SIGNAL
melunko@917
    71
};
melunko@917
    72
melunko@917
    73
static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src",
melunko@917
    74
    GST_PAD_SRC,
melunko@917
    75
    GST_PAD_ALWAYS,
melunko@917
    76
    GST_STATIC_CAPS ("video/quicktime")
melunko@917
    77
    );
melunko@917
    78
melunko@917
    79
static GstStaticPadTemplate audio_sink_factory = GST_STATIC_PAD_TEMPLATE ("audio_%d",
melunko@917
    80
    GST_PAD_SINK,
melunko@917
    81
    GST_PAD_REQUEST,
melunko@917
    82
    GST_STATIC_CAPS (
melunko@917
    83
        "audio/mpeg, " 
melunko@917
    84
        "mpegversion = (int) 4, " 
melunko@917
    85
        "channels = (int) { 1, 2 }, " 
melunko@917
    86
        "rate = (int) [ 8000, 96000 ]")
melunko@917
    87
    );
melunko@917
    88
    //GST_STATIC_CAPS ("audio/mpeg, mpegversion = 1, layer = 3")
melunko@917
    89
melunko@917
    90
static GstStaticPadTemplate video_sink_factory = GST_STATIC_PAD_TEMPLATE ("video_%d",
melunko@917
    91
    GST_PAD_SINK,
melunko@917
    92
    GST_PAD_REQUEST,
melunko@917
    93
    GST_STATIC_CAPS ("video/mpeg, mpegversion = 4")
melunko@917
    94
   );
melunko@917
    95
melunko@917
    96
static void gst_gpac_mux_base_init (gpointer g_class);
melunko@917
    97
static void gst_gpac_mux_class_init (GstGpacMuxClass * klass);
melunko@917
    98
static void gst_gpac_mux_init (GstGpacMux * gpac_mux);
melunko@917
    99
static void gst_gpac_mux_finalize (GObject * object);
melunko@917
   100
melunko@917
   101
static GstFlowReturn
melunko@917
   102
gst_gpac_mux_collected (GstCollectPads * pads, GstGpacMux * gpac_mux);
melunko@917
   103
melunko@917
   104
static gboolean gst_gpac_mux_handle_src_event (GstPad * pad, GstEvent * event);
melunko@917
   105
static GstPad *gst_gpac_mux_request_new_pad (GstElement * element,
melunko@917
   106
    GstPadTemplate * templ, const gchar * name);
melunko@917
   107
static void gst_gpac_mux_release_pad (GstElement * element, GstPad * pad);
melunko@917
   108
melunko@917
   109
static GstStateChangeReturn gst_gpac_mux_change_state (GstElement * element,
melunko@917
   110
    GstStateChange transition);
melunko@917
   111
melunko@917
   112
static GstElementClass *parent_class = NULL;
melunko@917
   113
melunko@917
   114
GType
melunko@917
   115
gst_gpac_mux_get_type (void)
melunko@917
   116
{
melunko@917
   117
  static GType gpac_mux_type = 0;
melunko@917
   118
melunko@917
   119
  if (G_UNLIKELY (gpac_mux_type == 0)) {
melunko@917
   120
    static const GTypeInfo gpac_mux_info = {
melunko@917
   121
      sizeof (GstGpacMuxClass),
melunko@917
   122
      gst_gpac_mux_base_init,
melunko@917
   123
      NULL,
melunko@917
   124
      (GClassInitFunc) gst_gpac_mux_class_init,
melunko@917
   125
      NULL,
melunko@917
   126
      NULL,
melunko@917
   127
      sizeof (GstGpacMux),
melunko@917
   128
      0,
melunko@917
   129
      (GInstanceInitFunc) gst_gpac_mux_init,
melunko@917
   130
    };
melunko@917
   131
melunko@917
   132
    gpac_mux_type =
melunko@917
   133
        g_type_register_static (GST_TYPE_ELEMENT, "GstGpacMux", &gpac_mux_info,
melunko@917
   134
        0);
melunko@917
   135
  }
melunko@917
   136
  return gpac_mux_type;
melunko@917
   137
}
melunko@917
   138
melunko@917
   139
static void
melunko@917
   140
gst_gpac_mux_base_init (gpointer g_class)
melunko@917
   141
{
melunko@917
   142
  GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
melunko@917
   143
melunko@917
   144
  gst_element_class_add_pad_template (element_class,
melunko@917
   145
      gst_static_pad_template_get (&src_factory));
melunko@917
   146
  gst_element_class_add_pad_template (element_class,
melunko@917
   147
      gst_static_pad_template_get (&audio_sink_factory));
melunko@917
   148
  gst_element_class_add_pad_template (element_class,
melunko@917
   149
      gst_static_pad_template_get (&video_sink_factory));
melunko@917
   150
melunko@917
   151
  gst_element_class_set_details (element_class, &gst_gpac_mux_details);
melunko@917
   152
}
melunko@917
   153
melunko@917
   154
static void
melunko@917
   155
gst_gpac_mux_class_init (GstGpacMuxClass * klass)
melunko@917
   156
{
melunko@917
   157
  GObjectClass *gobject_class;
melunko@917
   158
  GstElementClass *gstelement_class;
melunko@917
   159
melunko@917
   160
  gobject_class = (GObjectClass *) klass;
melunko@917
   161
  gstelement_class = (GstElementClass *) klass;
melunko@917
   162
melunko@917
   163
  parent_class = g_type_class_peek_parent (klass);
melunko@917
   164
melunko@917
   165
  gobject_class->finalize = gst_gpac_mux_finalize;
melunko@917
   166
melunko@917
   167
  gstelement_class->request_new_pad = gst_gpac_mux_request_new_pad;
melunko@917
   168
  gstelement_class->release_pad = gst_gpac_mux_release_pad;
melunko@917
   169
melunko@917
   170
  gstelement_class->change_state = gst_gpac_mux_change_state;
melunko@917
   171
melunko@917
   172
}
melunko@917
   173
melunko@917
   174
static void
melunko@917
   175
gst_gpac_mux_init (GstGpacMux * gpac_mux)
melunko@917
   176
{
melunko@917
   177
  GstElementClass *klass = GST_ELEMENT_GET_CLASS (gpac_mux);
melunko@917
   178
melunko@917
   179
  gpac_mux->srcpad =
melunko@917
   180
      gst_pad_new_from_template (gst_element_class_get_pad_template (klass,
melunko@917
   181
          "src"), "src");
melunko@917
   182
  gst_pad_set_event_function (gpac_mux->srcpad, gst_gpac_mux_handle_src_event);
melunko@917
   183
  gst_element_add_pad (GST_ELEMENT (gpac_mux), gpac_mux->srcpad);
melunko@917
   184
melunko@917
   185
  gpac_mux->collect = gst_collect_pads_new ();
melunko@917
   186
  gst_collect_pads_set_function (gpac_mux->collect,
melunko@917
   187
      (GstCollectPadsFunction) GST_DEBUG_FUNCPTR (gst_gpac_mux_collected),
melunko@917
   188
      gpac_mux);
melunko@917
   189
melunko@917
   190
  /* Opens gpac library */
melunko@917
   191
  /* FIXME */
melunko@917
   192
  gpac_mux->file = gf_isom_open("/tmp/gpac.mp4", GF_ISOM_OPEN_WRITE, NULL);
melunko@917
   193
  gf_isom_set_storage_mode(gpac_mux->file, GF_ISOM_STORE_FLAT /*STREAMABLE*/);
melunko@917
   194
melunko@917
   195
  //gst_gpac_mux_clear (gpac_mux);
melunko@917
   196
}
melunko@917
   197
melunko@917
   198
static void
melunko@917
   199
gst_gpac_mux_finalize (GObject * object)
melunko@917
   200
{
melunko@917
   201
  GstGpacMux *gpac_mux;
melunko@917
   202
melunko@917
   203
  gpac_mux = GST_GPAC_MUX (object);
melunko@917
   204
melunko@917
   205
  if (gpac_mux->collect) {
melunko@917
   206
    gst_object_unref (gpac_mux->collect);
melunko@917
   207
    gpac_mux->collect = NULL;
melunko@917
   208
  }
melunko@917
   209
melunko@917
   210
  G_OBJECT_CLASS (parent_class)->finalize (object);
melunko@917
   211
}
melunko@917
   212
melunko@917
   213
static void
melunko@917
   214
gst_gpac_mux_gpac_pad_destroy_notify (GstCollectData * data)
melunko@917
   215
{
melunko@917
   216
  GstGpacPad *gpacpad = (GstGpacPad *) data;
melunko@917
   217
  GstBuffer *buf;
melunko@917
   218
melunko@917
   219
/*  if (gpacpad->pagebuffers) {
melunko@917
   220
    while ((buf = g_queue_pop_head (gpacpad->pagebuffers)) != NULL) {
melunko@917
   221
      gst_buffer_unref (buf);
melunko@917
   222
    }
melunko@917
   223
    g_queue_free (gpacpad->pagebuffers);
melunko@917
   224
    gpacpad->pagebuffers = NULL;
melunko@917
   225
  }*/
melunko@917
   226
}
melunko@917
   227
melunko@917
   228
static GstPadLinkReturn
melunko@917
   229
gst_gpac_mux_sinkconnect (GstPad * pad, GstPad * peer)
melunko@917
   230
{
melunko@917
   231
  GstGpacMux *gpac_mux;
melunko@917
   232
melunko@917
   233
  gpac_mux = GST_GPAC_MUX (gst_pad_get_parent (pad));
melunko@917
   234
melunko@917
   235
  GST_DEBUG_OBJECT (gpac_mux, "sinkconnect triggered on %s", GST_PAD_NAME (pad));
melunko@917
   236
melunko@917
   237
  gst_object_unref (gpac_mux);
melunko@917
   238
melunko@917
   239
  return GST_PAD_LINK_OK;
melunko@917
   240
}
melunko@917
   241
melunko@917
   242
static GstPad *
melunko@917
   243
gst_gpac_mux_request_new_pad (GstElement * element,
melunko@917
   244
    GstPadTemplate * templ, const gchar * req_name)
melunko@917
   245
{
melunko@917
   246
  GstGpacMux *gpac_mux;
melunko@917
   247
  GstPad *newpad;
melunko@917
   248
  GstElementClass *klass;
melunko@917
   249
  gchar *padname = NULL;
melunko@917
   250
  gint serial;
melunko@917
   251
  gboolean is_video = FALSE;
melunko@917
   252
melunko@917
   253
  g_return_val_if_fail (templ != NULL, NULL);
melunko@917
   254
melunko@917
   255
  if (templ->direction != GST_PAD_SINK)
melunko@917
   256
    goto wrong_direction;
melunko@917
   257
melunko@917
   258
  g_return_val_if_fail (GST_IS_GPAC_MUX (element), NULL);
melunko@917
   259
  gpac_mux = GST_GPAC_MUX (element);
melunko@917
   260
melunko@917
   261
  klass = GST_ELEMENT_GET_CLASS (element);
melunko@917
   262
melunko@917
   263
    if (req_name == NULL || strlen (req_name) < 6) {
melunko@917
   264
      /* no name given when requesting the pad, use random serial number */
melunko@917
   265
      serial = rand ();
melunko@917
   266
    } else {
melunko@917
   267
      /* parse serial number from requested padname */
melunko@917
   268
      serial = atoi (&req_name[5]);
melunko@917
   269
    }
melunko@917
   270
melunko@917
   271
  if (templ == gst_element_class_get_pad_template (klass, "video_%d")) {
melunko@917
   272
    is_video = TRUE;      
melunko@917
   273
    padname = g_strdup_printf ("video_%d", serial);
melunko@917
   274
  } else if (templ != gst_element_class_get_pad_template (klass, "audio_%d")) {
melunko@917
   275
    goto wrong_template;
melunko@917
   276
  } else {
melunko@917
   277
    padname = g_strdup_printf ("audio_%d", serial);
melunko@917
   278
  }
melunko@917
   279
melunko@917
   280
melunko@917
   281
  {
melunko@917
   282
    
melunko@917
   283
    /* create new pad with the name */
melunko@917
   284
    GST_DEBUG_OBJECT (gpac_mux, "Creating new pad for serial %d", serial);
melunko@917
   285
    printf ("XXXX new pad from template\n");
melunko@917
   286
    newpad = gst_pad_new_from_template (templ, padname);
melunko@917
   287
    g_free (padname);
melunko@917
   288
melunko@917
   289
    /* construct our own wrapper data structure for the pad to
melunko@917
   290
     * keep track of its status */
melunko@917
   291
    {
melunko@917
   292
      GstGpacPad *gpacpad;
melunko@917
   293
melunko@917
   294
      gpacpad = (GstGpacPad *)
melunko@917
   295
          gst_collect_pads_add_pad_full (gpac_mux->collect, newpad,
melunko@917
   296
          sizeof (GstGpacPad), gst_gpac_mux_gpac_pad_destroy_notify);
melunko@917
   297
melunko@917
   298
      /* gpac new track */
melunko@917
   299
      gpacpad->is_video = is_video;
melunko@917
   300
      if (gpacpad->is_video) {
melunko@917
   301
        gpacpad->track_number = gf_isom_new_track(gpac_mux->file, 0, 
melunko@917
   302
          GF_ISOM_MEDIA_VISUAL, 10 * 1000 /* time scale */);
melunko@917
   303
      } else {
melunko@917
   304
        gpacpad->track_number = gf_isom_new_track(gpac_mux->file, 0, 
melunko@917
   305
          GF_ISOM_MEDIA_AUDIO, 48000 /*time scale */);
melunko@917
   306
        
melunko@917
   307
      }
melunko@917
   308
      if (gpacpad->track_number == 0) {
melunko@917
   309
        g_warning ("Error while adding the new gpac track");
melunko@917
   310
      } else {
melunko@917
   311
        gf_isom_set_track_enabled(gpac_mux->file, gpacpad->track_number, 1);
melunko@917
   312
        if (is_video) {
melunko@917
   313
          GF_ESD *esd = gf_odf_desc_esd_new (0);
melunko@917
   314
          esd->ESID = gf_isom_get_track_id(gpac_mux->file, gpacpad->track_number);
melunko@917
   315
melunko@917
   316
          gf_isom_new_mpeg4_description( gpac_mux->file, gpacpad->track_number,
melunko@917
   317
                        esd, NULL, NULL, &(gpacpad->di));
melunko@917
   318
melunko@917
   319
           gf_isom_set_visual_info (gpac_mux->file, gpacpad->track_number, gpacpad->di, 320, 240);//fixme
melunko@917
   320
          //gf_isom_set_cts_packing (gpac_mux->file, gpacpad->track_number, 0);
melunko@917
   321
        } else {
melunko@917
   322
          GF_ESD *esd = gf_odf_desc_esd_new (2);
melunko@917
   323
          esd->ESID = gf_isom_get_track_id(gpac_mux->file, gpacpad->track_number);
melunko@917
   324
melunko@917
   325
          gf_isom_new_mpeg4_description(gpac_mux->file, gpacpad->track_number,
melunko@917
   326
                         esd, NULL, NULL, &(gpacpad->di));
melunko@917
   327
melunko@917
   328
          gf_isom_set_audio_info(gpac_mux->file, gpacpad->track_number, 
melunko@917
   329
                          gpacpad->di, 48000, 2 /*num channels */, 16);
melunko@917
   330
        }
melunko@917
   331
      }
melunko@917
   332
    }
melunko@917
   333
  }
melunko@917
   334
melunko@917
   335
  /* setup some pad functions */
melunko@917
   336
  gst_pad_set_link_function (newpad, gst_gpac_mux_sinkconnect);
melunko@917
   337
  /* dd the pad to the element */
melunko@917
   338
  gst_element_add_pad (element, newpad);
melunko@917
   339
melunko@917
   340
  return newpad;
melunko@917
   341
melunko@917
   342
  /* ERRORS */
melunko@917
   343
wrong_direction:
melunko@917
   344
  {
melunko@917
   345
    g_warning ("gpac_mux: request pad that is not a SINK pad\n");
melunko@917
   346
    return NULL;
melunko@917
   347
  }
melunko@917
   348
wrong_template:
melunko@917
   349
  {
melunko@917
   350
    g_warning ("gpac_mux: this is not our template!\n");
melunko@917
   351
    return NULL;
melunko@917
   352
  }
melunko@917
   353
}
melunko@917
   354
melunko@917
   355
static void
melunko@917
   356
gst_gpac_mux_release_pad (GstElement * element, GstPad * pad)
melunko@917
   357
{
melunko@917
   358
  GstGpacMux *gpac_mux;
melunko@917
   359
melunko@917
   360
  gpac_mux = GST_GPAC_MUX (gst_pad_get_parent (pad));
melunko@917
   361
melunko@917
   362
  gst_collect_pads_remove_pad (gpac_mux->collect, pad);
melunko@917
   363
  gst_element_remove_pad (element, pad);
melunko@917
   364
}
melunko@917
   365
melunko@917
   366
/* handle events */
melunko@917
   367
static gboolean
melunko@917
   368
gst_gpac_mux_handle_src_event (GstPad * pad, GstEvent * event)
melunko@917
   369
{
melunko@917
   370
  GstEventType type;
melunko@917
   371
melunko@917
   372
  type = event ? GST_EVENT_TYPE (event) : GST_EVENT_UNKNOWN;
melunko@917
   373
melunko@917
   374
  switch (type) {
melunko@917
   375
    case GST_EVENT_SEEK:
melunko@917
   376
      /* disable seeking for now */
melunko@917
   377
      return FALSE;
melunko@917
   378
    default:
melunko@917
   379
      break;
melunko@917
   380
  }
melunko@917
   381
melunko@917
   382
  return gst_pad_event_default (pad, event);
melunko@917
   383
}
melunko@917
   384
melunko@917
   385
static GstFlowReturn
melunko@917
   386
gst_gpac_mux_push_buffer (GstGpacMux * mux, GstBuffer * buffer)
melunko@917
   387
{
melunko@917
   388
  GstCaps *caps;
melunko@917
   389
#if 0
melunko@917
   390
  /* fix up OFFSET and OFFSET_END again */
melunko@917
   391
  GST_BUFFER_OFFSET (buffer) = mux->offset;
melunko@917
   392
  mux->offset += GST_BUFFER_SIZE (buffer);
melunko@917
   393
  GST_BUFFER_OFFSET_END (buffer) = mux->offset;
melunko@917
   394
melunko@917
   395
  /* Ensure we have monotonically increasing timestamps in the output. */
melunko@917
   396
  if (GST_BUFFER_TIMESTAMP_IS_VALID (buffer)) {
melunko@917
   397
    if (mux->last_ts != GST_CLOCK_TIME_NONE &&
melunko@917
   398
        GST_BUFFER_TIMESTAMP (buffer) < mux->last_ts)
melunko@917
   399
      GST_BUFFER_TIMESTAMP (buffer) = mux->last_ts;
melunko@917
   400
    else
melunko@917
   401
      mux->last_ts = GST_BUFFER_TIMESTAMP (buffer);
melunko@917
   402
  }
melunko@917
   403
#endif
melunko@917
   404
  
melunko@917
   405
  caps = gst_pad_get_negotiated_caps (mux->srcpad);
melunko@917
   406
  gst_buffer_set_caps (buffer, caps);
melunko@917
   407
  if (caps != NULL) {
melunko@917
   408
    gst_caps_unref (caps);
melunko@917
   409
  }
melunko@917
   410
melunko@917
   411
  return gst_pad_push (mux->srcpad, buffer);
melunko@917
   412
}
melunko@917
   413
melunko@917
   414
static gboolean
melunko@917
   415
all_pads_eos (GstCollectPads * pads)
melunko@917
   416
{
melunko@917
   417
  GSList *iter;
melunko@917
   418
  gboolean alleos = TRUE;
melunko@917
   419
melunko@917
   420
  iter = pads->data;
melunko@917
   421
  while (iter) {
melunko@917
   422
    GstBuffer *buf;
melunko@917
   423
    GstCollectData *data = (GstCollectData *) iter->data;
melunko@917
   424
melunko@917
   425
    buf = gst_collect_pads_peek (pads, data);
melunko@917
   426
    if (buf) {
melunko@917
   427
      alleos = FALSE;
melunko@917
   428
      gst_buffer_unref (buf);
melunko@917
   429
      goto beach;
melunko@917
   430
    }
melunko@917
   431
    iter = iter->next;
melunko@917
   432
  }
melunko@917
   433
beach:
melunko@917
   434
  return alleos;
melunko@917
   435
}
melunko@917
   436
 
melunko@917
   437
static GstFlowReturn
melunko@917
   438
gst_gpac_mux_collected (GstCollectPads * pads, GstGpacMux * gpac_mux)
melunko@917
   439
{
melunko@917
   440
  GstFlowReturn ret = GST_FLOW_OK;
melunko@917
   441
  GSList *iter;
melunko@917
   442
  GstBuffer *buf;
melunko@917
   443
  gint i = 0;
melunko@917
   444
melunko@917
   445
  GST_LOG_OBJECT (gpac_mux, "collected");
melunko@917
   446
melunko@917
   447
  iter = gpac_mux->collect->data;
melunko@917
   448
  while (iter) {
melunko@917
   449
    GstCollectData *data = (GstCollectData *) iter->data;
melunko@917
   450
    GstGpacPad *pad = (GstGpacPad *) data;
melunko@917
   451
melunko@917
   452
    buf = gst_collect_pads_pop (gpac_mux->collect, data);
melunko@917
   453
  if (buf == NULL) {
melunko@917
   454
    iter = g_slist_next (iter);
melunko@917
   455
      continue;
melunko@917
   456
  }
melunko@917
   457
    GST_LOG_OBJECT (data->pad, "popped buffer %" GST_PTR_FORMAT, buf);
melunko@917
   458
melunko@917
   459
    /* gpac output */
melunko@917
   460
    printf ("xxxxxx buffer size: %d\n", GST_BUFFER_SIZE(buf)); fflush (stdout);
melunko@917
   461
    if (pad->frame_count < 300) {
melunko@917
   462
      GF_ISOSample *sample = gf_isom_sample_new();
melunko@917
   463
melunko@917
   464
       sample->dataLength = GST_BUFFER_SIZE(buf);
melunko@917
   465
       sample->data = GST_BUFFER_DATA(buf);
melunko@917
   466
       sample->CTS_Offset = 0;
melunko@917
   467
melunko@917
   468
      if (pad->is_video) {
melunko@917
   469
        sample->IsRAP = 0;
melunko@917
   470
        sample->DTS += 1000*pad->frame_count;
melunko@917
   471
      } else {
melunko@917
   472
        sample->IsRAP = 0;
melunko@917
   473
        sample->DTS = 2048*pad->frame_count;
melunko@917
   474
      }
melunko@917
   475
melunko@917
   476
      gf_isom_add_sample(gpac_mux->file, pad->track_number, 
melunko@917
   477
                      pad->di, sample);
melunko@917
   478
      sample->data = NULL;
melunko@917
   479
melunko@917
   480
      gf_isom_sample_del(&sample);
melunko@917
   481
melunko@917
   482
      printf ("xxxx frames %d\n", pad->frame_count);
melunko@917
   483
melunko@917
   484
    } else if (pad->frame_count == 300) {
melunko@917
   485
      printf ("XXX closing gpac output file\n"); fflush (stdout);
melunko@917
   486
      gf_isom_close (gpac_mux->file);
melunko@917
   487
    }
melunko@917
   488
melunko@917
   489
    /* gstreamer output (push) */
melunko@917
   490
    if (gst_gpac_mux_push_buffer (gpac_mux, buf) != GST_FLOW_OK) {
melunko@917
   491
      printf ("EEEEEEEE push failed\n");
melunko@917
   492
    }
melunko@917
   493
melunko@917
   494
    iter = g_slist_next (iter);
melunko@917
   495
    pad->frame_count++;
melunko@917
   496
    i++;
melunko@917
   497
  }
melunko@917
   498
melunko@917
   499
  /* fixme */
melunko@917
   500
  return ret;
melunko@917
   501
}
melunko@917
   502
melunko@917
   503
/* reset all variables in the gpac pads. */
melunko@917
   504
static void
melunko@917
   505
gst_gpac_mux_init_collectpads (GstCollectPads * collect)
melunko@917
   506
{
melunko@917
   507
  GSList *walk;
melunko@917
   508
melunko@917
   509
  walk = collect->data;
melunko@917
   510
  while (walk) {
melunko@917
   511
    GstGpacPad *gpacpad = (GstGpacPad *) walk->data;
melunko@917
   512
melunko@917
   513
    //ogg_stream_init (&gpacpad->stream, gpacpad->serial);
melunko@917
   514
    //gpacpad->packetno = 0;
melunko@917
   515
    //gpacpad->pageno = 0;
melunko@917
   516
    //gpacpad->eos = FALSE;
melunko@917
   517
    /* we assume there will be some control data first for this pad */
melunko@917
   518
    //gpacpad->state = GST_GPAC_PAD_STATE_CONTROL;
melunko@917
   519
    //gpacpad->new_page = TRUE;
melunko@917
   520
    //gpacpad->first_delta = FALSE;
melunko@917
   521
    //gpacpad->prev_delta = FALSE;
melunko@917
   522
    //gpacpad->pagebuffers = g_queue_new ();
melunko@917
   523
melunko@917
   524
    walk = g_slist_next (walk);
melunko@917
   525
  }
melunko@917
   526
}
melunko@917
   527
melunko@917
   528
/* Clear all buffers from the collectpads object */
melunko@917
   529
static void
melunko@917
   530
gst_gpac_mux_clear_collectpads (GstCollectPads * collect)
melunko@917
   531
{
melunko@917
   532
  GSList *walk;
melunko@917
   533
melunko@917
   534
  for (walk = collect->data; walk; walk = g_slist_next (walk)) {
melunko@917
   535
    GstGpacPad *gpacpad = (GstGpacPad *) walk->data;
melunko@917
   536
    GstBuffer *buf;
melunko@917
   537
melunko@917
   538
    //gpac_stream_clear (&gpacpad->stream);
melunko@917
   539
/*
melunko@917
   540
    while ((buf = g_queue_pop_head (gpacpad->pagebuffers)) != NULL) {
melunko@917
   541
      gst_buffer_unref (buf);
melunko@917
   542
    }
melunko@917
   543
    g_queue_free (gpacpad->pagebuffers);
melunko@917
   544
    gpacpad->pagebuffers = NULL;*/
melunko@917
   545
  }
melunko@917
   546
}
melunko@917
   547
melunko@917
   548
static GstStateChangeReturn
melunko@917
   549
gst_gpac_mux_change_state (GstElement * element, GstStateChange transition)
melunko@917
   550
{
melunko@917
   551
  GstGpacMux *gpac_mux;
melunko@917
   552
  GstStateChangeReturn ret;
melunko@917
   553
melunko@917
   554
  gpac_mux = GST_GPAC_MUX (element);
melunko@917
   555
melunko@917
   556
  switch (transition) {
melunko@917
   557
    case GST_STATE_CHANGE_NULL_TO_READY:
melunko@917
   558
      break;
melunko@917
   559
    case GST_STATE_CHANGE_READY_TO_PAUSED:
melunko@917
   560
      //gst_gpac_mux_clear (gpac_mux);
melunko@917
   561
      //gst_gpac_mux_init_collectpads (gpac_mux->collect);
melunko@917
   562
      gst_collect_pads_start (gpac_mux->collect);
melunko@917
   563
      break;
melunko@917
   564
    case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
melunko@917
   565
      break;
melunko@917
   566
    case GST_STATE_CHANGE_PAUSED_TO_READY:
melunko@917
   567
      gst_collect_pads_stop (gpac_mux->collect);
melunko@917
   568
      break;
melunko@917
   569
    default:
melunko@917
   570
      break;
melunko@917
   571
  }
melunko@917
   572
melunko@917
   573
  ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
melunko@917
   574
melunko@917
   575
  switch (transition) {
melunko@917
   576
    case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
melunko@917
   577
      break;
melunko@917
   578
    case GST_STATE_CHANGE_PAUSED_TO_READY:
melunko@917
   579
      gst_gpac_mux_clear_collectpads (gpac_mux->collect);
melunko@917
   580
      break;
melunko@917
   581
    case GST_STATE_CHANGE_READY_TO_NULL:
melunko@917
   582
      break;
melunko@917
   583
    default:
melunko@917
   584
      break;
melunko@917
   585
  }
melunko@917
   586
melunko@917
   587
  return ret;
melunko@917
   588
melunko@917
   589
}
melunko@917
   590
melunko@917
   591
static gboolean
melunko@917
   592
gst_gpac_mux_plugin_init (GstPlugin * plugin)
melunko@917
   593
{
melunko@917
   594
  return gst_element_register (plugin, "gpacmux", GST_RANK_NONE,
melunko@917
   595
      GST_TYPE_GPAC_MUX);
melunko@917
   596
}
melunko@917
   597
melunko@917
   598
GST_PLUGIN_DEFINE(GST_VERSION_MAJOR,
melunko@917
   599
                  GST_VERSION_MINOR,
melunko@917
   600
                  "gpacmux",
melunko@917
   601
                  "Muxes audio and video",
melunko@917
   602
                  gst_gpac_mux_plugin_init, VERSION, GST_LICENSE, GST_PACKAGE_NAME,
melunko@917
   603
                  GST_PACKAGE_ORIGIN)
melunko@917
   604