Beispiel #1
0
static GstFlowReturn
gst_cmml_enc_push_clip (GstCmmlEnc * enc, GstCmmlTagClip * clip,
    GstClockTime prev_clip_time)
{
  GstFlowReturn res;
  GstBuffer *buffer;
  gchar *clip_string;
  gint64 granulepos;

  /* encode the clip */
  clip_string =
      (gchar *) gst_cmml_parser_tag_clip_to_string (enc->parser, clip);

  res = gst_cmml_enc_new_buffer (enc,
      (guchar *) clip_string, strlen (clip_string), &buffer);
  g_free (clip_string);
  if (res != GST_FLOW_OK)
    goto done;

  GST_INFO_OBJECT (enc, "encoding clip"
      "(start-time: %" GST_TIME_FORMAT " end-time: %" GST_TIME_FORMAT,
      GST_TIME_ARGS (clip->start_time), GST_TIME_ARGS (clip->end_time));

  /* set the granulepos */
  granulepos = gst_cmml_clock_time_to_granule (prev_clip_time, clip->start_time,
      enc->granulerate_n, enc->granulerate_d, enc->granuleshift);
  if (granulepos == -1) {
    gst_buffer_unref (buffer);
    goto granule_overflow;
  }

  GST_BUFFER_OFFSET (buffer) = clip->start_time;
  GST_BUFFER_OFFSET_END (buffer) = granulepos;
  GST_BUFFER_TIMESTAMP (buffer) = clip->start_time;

  res = gst_cmml_enc_push (enc, buffer);
  if (GST_FLOW_IS_FATAL (res))
    goto done;

  if (clip->end_time != GST_CLOCK_TIME_NONE) {
    /* create a new empty clip for the same cmml track starting at end_time
     */
    GObject *end_clip = g_object_new (GST_TYPE_CMML_TAG_CLIP,
        "start-time", clip->end_time, "track", clip->track, NULL);

    /* encode the empty end clip */
    gst_cmml_enc_push_clip (enc, GST_CMML_TAG_CLIP (end_clip),
        clip->start_time);
    g_object_unref (end_clip);
  }
done:
  return res;

granule_overflow:
  GST_ELEMENT_ERROR (enc, STREAM, ENCODE, (NULL), ("granulepos overflow"));
  return GST_FLOW_ERROR;
}
Beispiel #2
0
static void
gst_cmml_tag_clip_set_property (GObject * object, guint property_id,
    const GValue * value, GParamSpec * pspec)
{
  GstCmmlTagClip *clip = GST_CMML_TAG_CLIP (object);

  switch (property_id) {
    case GST_CMML_TAG_CLIP_EMPTY:
      clip->empty = g_value_get_boolean (value);
      break;
    case GST_CMML_TAG_CLIP_ID:
      g_free (clip->id);
      clip->id = (guchar *) g_value_dup_string (value);
      break;
    case GST_CMML_TAG_CLIP_TRACK:
      g_free (clip->track);
      clip->track = (guchar *) g_value_dup_string (value);
      break;
    case GST_CMML_TAG_CLIP_START_TIME:
      clip->start_time = g_value_get_uint64 (value);
      break;
    case GST_CMML_TAG_CLIP_END_TIME:
      clip->end_time = g_value_get_uint64 (value);
      break;
    case GST_CMML_TAG_CLIP_ANCHOR_HREF:
      g_free (clip->anchor_href);
      clip->anchor_href = (guchar *) g_value_dup_string (value);
      break;
    case GST_CMML_TAG_CLIP_ANCHOR_TEXT:
      g_free (clip->anchor_text);
      clip->anchor_text = (guchar *) g_value_dup_string (value);
      break;
    case GST_CMML_TAG_CLIP_IMG_SRC:
      g_free (clip->img_src);
      clip->img_src = (guchar *) g_value_dup_string (value);
      break;
    case GST_CMML_TAG_CLIP_IMG_ALT:
      g_free (clip->img_alt);
      clip->img_alt = (guchar *) g_value_dup_string (value);
      break;
    case GST_CMML_TAG_CLIP_DESC_TEXT:
      g_free (clip->desc_text);
      clip->desc_text = (guchar *) g_value_dup_string (value);
      break;
    case GST_CMML_TAG_CLIP_META:
    {
      GValueArray *va = (GValueArray *) g_value_get_boxed (value);

      if (clip->meta)
        g_value_array_free (clip->meta);

      clip->meta = va != NULL ? g_value_array_copy (va) : NULL;

      break;
    }
  }
}
Beispiel #3
0
static gboolean
gst_cmml_dec_sink_event (GstPad * pad, GstEvent * event)
{
  GstCmmlDec *dec = GST_CMML_DEC (GST_PAD_PARENT (pad));

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_EOS:
    {
      GstBuffer *buffer;
      GstCmmlTagClip *clip;
      GList *clips, *walk;

      GST_INFO_OBJECT (dec, "got EOS, flushing clips");

      /* since we output a clip when the next one in the same track is found, on
       * EOS we need to output the last clip (if any) of every track
       */
      clips = gst_cmml_track_list_get_clips (dec->tracks);
      for (walk = clips; walk; walk = g_list_next (walk)) {
        clip = GST_CMML_TAG_CLIP (walk->data);
        gst_cmml_dec_push_clip (dec, clip);
        if (dec->wait_clip_end) {
          clip->end_time = dec->timestamp;
          gst_cmml_dec_send_clip_tag (dec, clip);
        }
      }
      g_list_free (clips);

      /* send the cmml end tag */
      dec->flow_return = gst_cmml_dec_new_buffer (dec,
          (guchar *) "</cmml>", strlen ("</cmml>"), &buffer);

      if (dec->flow_return == GST_FLOW_OK)
        dec->flow_return = gst_pad_push (dec->srcpad, buffer);
      if (dec->flow_return == GST_FLOW_NOT_LINKED)
        dec->flow_return = GST_FLOW_OK; /* Ignore NOT_LINKED */

      break;
    }
    default:
      break;
  }

  return gst_pad_event_default (pad, event);
}
Beispiel #4
0
static void
gst_cmml_tag_clip_finalize (GObject * object)
{
  GstCmmlTagClip *clip = GST_CMML_TAG_CLIP (object);

  g_free (clip->id);
  g_free (clip->track);
  g_free (clip->anchor_href);
  g_free (clip->anchor_text);
  g_free (clip->img_src);
  g_free (clip->img_alt);
  g_free (clip->desc_text);
  if (clip->meta)
    g_value_array_free (clip->meta);

  if (G_OBJECT_CLASS (gst_cmml_tag_clip_parent_class)->finalize)
    G_OBJECT_CLASS (gst_cmml_tag_clip_parent_class)->finalize (object);
}
Beispiel #5
0
static void
gst_cmml_tag_clip_get_property (GObject * object, guint property_id,
    GValue * value, GParamSpec * pspec)
{
  GstCmmlTagClip *clip = GST_CMML_TAG_CLIP (object);

  switch (property_id) {
    case GST_CMML_TAG_CLIP_EMPTY:
      g_value_set_boolean (value, clip->empty);
      break;
    case GST_CMML_TAG_CLIP_ID:
      g_value_set_string (value, (gchar *) clip->id);
      break;
    case GST_CMML_TAG_CLIP_TRACK:
      g_value_set_string (value, (gchar *) clip->track);
      break;
    case GST_CMML_TAG_CLIP_START_TIME:
      g_value_set_uint64 (value, clip->start_time);
      break;
    case GST_CMML_TAG_CLIP_END_TIME:
      g_value_set_uint64 (value, clip->end_time);
      break;
    case GST_CMML_TAG_CLIP_ANCHOR_HREF:
      g_value_set_string (value, (gchar *) clip->anchor_href);
      break;
    case GST_CMML_TAG_CLIP_ANCHOR_TEXT:
      g_value_set_string (value, (gchar *) clip->anchor_text);
      break;
    case GST_CMML_TAG_CLIP_IMG_SRC:
      g_value_set_string (value, (gchar *) clip->img_src);
      break;
    case GST_CMML_TAG_CLIP_IMG_ALT:
      g_value_set_string (value, (gchar *) clip->img_alt);
      break;
    case GST_CMML_TAG_CLIP_DESC_TEXT:
      g_value_set_string (value, (gchar *) clip->desc_text);
      break;
    case GST_CMML_TAG_CLIP_META:
      g_value_set_boxed (value, clip->meta);
      break;
  }
}
Beispiel #6
0
guchar *
gst_cmml_parser_tag_object_to_string (GstCmmlParser * parser, GObject * tag)
{
  guchar *tag_string = NULL;
  GType tag_type = G_OBJECT_TYPE (tag);

  if (tag_type == GST_TYPE_CMML_TAG_STREAM)
    tag_string = gst_cmml_parser_tag_stream_to_string (parser,
        GST_CMML_TAG_STREAM (tag));
  else if (tag_type == GST_TYPE_CMML_TAG_HEAD)
    tag_string = gst_cmml_parser_tag_head_to_string (parser,
        GST_CMML_TAG_HEAD (tag));
  else if (tag_type == GST_TYPE_CMML_TAG_CLIP)
    tag_string = gst_cmml_parser_tag_clip_to_string (parser,
        GST_CMML_TAG_CLIP (tag));
  else
    g_warning ("could not convert object to cmml");

  return tag_string;
}