Exemplo n.º 1
0
static gboolean
gst_type_find_element_setcaps (GstPad * pad, GstCaps * caps)
{
  GstTypeFindElement *typefind;

  typefind = GST_TYPE_FIND_ELEMENT (GST_PAD_PARENT (pad));

  /* don't operate on ANY caps */
  if (gst_caps_is_any (caps))
    return TRUE;

  g_signal_emit (typefind, gst_type_find_element_signals[HAVE_TYPE], 0,
      GST_TYPE_FIND_MAXIMUM, caps);

  /* Shortcircuit typefinding if we get caps */
  if (typefind->mode == MODE_TYPEFIND) {
    GST_DEBUG_OBJECT (typefind, "Skipping typefinding, using caps from "
        "upstream buffer: %" GST_PTR_FORMAT, caps);
    typefind->mode = MODE_NORMAL;

    gst_type_find_element_send_cached_events (typefind);
    if (typefind->store) {
      GST_DEBUG_OBJECT (typefind, "Pushing store: %d",
          GST_BUFFER_SIZE (typefind->store));
      gst_buffer_set_caps (typefind->store, typefind->caps);
      gst_pad_push (typefind->src, typefind->store);
      typefind->store = NULL;
    }
  }

  return TRUE;
}
Exemplo n.º 2
0
static void
stop_typefinding (GstTypeFindElement * typefind)
{
  GstState state;
  gboolean push_cached_buffers;

  gst_element_get_state (GST_ELEMENT (typefind), &state, NULL, 0);

  push_cached_buffers = (state >= GST_STATE_PAUSED);

  GST_DEBUG_OBJECT (typefind, "stopping typefinding%s",
      push_cached_buffers ? " and pushing cached buffers" : "");

  if (typefind->store) {
    if (!push_cached_buffers) {
      gst_buffer_unref (typefind->store);
    } else {
      GstPad *peer = gst_pad_get_peer (typefind->src);

      typefind->mode = MODE_NORMAL;
      gst_buffer_set_caps (typefind->store, typefind->caps);

      /* make sure the user gets a meaningful error message in this case,
       * which is not a core bug or bug of any kind (as the default error
       * message emitted by gstpad.c otherwise would make you think) */
      if (peer && GST_PAD_CHAINFUNC (peer) == NULL) {
        GST_DEBUG_OBJECT (typefind, "upstream only supports push mode, while "
            "downstream element only works in pull mode, erroring out");
        GST_ELEMENT_ERROR (typefind, STREAM, FAILED,
            ("%s cannot work in push mode. The operation is not supported "
                "with this source element or protocol.",
                G_OBJECT_TYPE_NAME (GST_PAD_PARENT (peer))),
            ("Downstream pad %s:%s has no chainfunction, and the upstream "
                "element does not support pull mode",
                GST_DEBUG_PAD_NAME (peer)));
        typefind->mode = MODE_ERROR;    /* make the chain function error out */
      } else {
        gst_type_find_element_send_cached_events (typefind);
        gst_pad_push (typefind->src, typefind->store);
      }

      if (peer)
        gst_object_unref (peer);
    }
    typefind->store = NULL;
  }
}
Exemplo n.º 3
0
static GstFlowReturn
gst_type_find_element_chain (GstPad * pad, GstBuffer * buffer)
{
    res = gst_type_find_element_chain_do_typefinding (typefind);
    {
        GstCaps *caps;
        caps = gst_type_find_helper_for_buffer (GST_OBJECT (typefind),
          typefind->store, &probability);
        // gstreamer/libs/gst/base/gsttypefindhelper.c
        // All available typefinders will be called on the data in order of rank. If
        // a typefinding function returns a probability of #GST_TYPE_FIND_MAXIMUM,
        // typefinding is stopped immediately and the found caps will be returned
        // right away. Otherwise, all available typefind functions will the tried,
        // and the caps with the highest probability will be returned
        {
            type_list = gst_type_find_factory_get_list ();
            type_list = g_list_sort (type_list, type_find_factory_rank_cmp);

            gst_type_find_factory_call_function (helper.factory, &find);
            {
                // find function from factory
                new_factory =
                    GST_TYPE_FIND_FACTORY (gst_plugin_feature_load (GST_PLUGIN_FEATURE (factory)));
                new_factory->function (find, new_factory->user_data);
                gst_object_unref (new_factory);
            } // gst_type_find_factory_call_function()
        } // gst_type_find_helper_for_buffer()

        /* probability is good enough too, so let's make it known ... */
        g_signal_emit (typefind, gst_type_find_element_signals[HAVE_TYPE], 0,
            probability, caps);

        // stop typefind
        stop_typefinding (typefind);
        {
            // TODO: why set itself to NULL?
            gst_element_get_state (GST_ELEMENT (typefind), &state, NULL, 0);

            // reset state to normal
            typefind->mode = MODE_NORMAL;

            // send cache event and buffers
            gst_type_find_element_send_cached_events (typefind);
            gst_pad_push (typefind->src, typefind->store);
        }
    } // gst_type_find_element_chain_do_typefinding()
}
static gboolean
gst_type_find_element_setcaps (GstTypeFindElement * typefind, GstCaps * caps)
{
  /* don't operate on ANY caps */
  if (gst_caps_is_any (caps))
    return TRUE;

  g_signal_emit (typefind, gst_type_find_element_signals[HAVE_TYPE], 0,
      GST_TYPE_FIND_MAXIMUM, caps);

  /* Shortcircuit typefinding if we get caps */
  if (typefind->mode == MODE_TYPEFIND) {
    GstBuffer *buffer;
    gsize avail;

    GST_DEBUG_OBJECT (typefind, "Skipping typefinding, using caps from "
        "upstream buffer: %" GST_PTR_FORMAT, caps);
    typefind->mode = MODE_NORMAL;

    gst_type_find_element_send_cached_events (typefind);
    GST_OBJECT_LOCK (typefind);
    avail = gst_adapter_available (typefind->adapter);
    if (avail == 0)
      goto no_data;

    buffer = gst_adapter_take_buffer (typefind->adapter, avail);
    GST_OBJECT_UNLOCK (typefind);

    GST_DEBUG_OBJECT (typefind, "Pushing buffer: %" G_GSIZE_FORMAT, avail);
    gst_pad_push (typefind->src, buffer);
  }

  return TRUE;

no_data:
  {
    GST_DEBUG_OBJECT (typefind, "no data to push");
    GST_OBJECT_UNLOCK (typefind);
    return TRUE;
  }
}
static void
stop_typefinding (GstTypeFindElement * typefind)
{
  GstState state;
  gboolean push_cached_buffers;
  gsize avail;
  GstBuffer *buffer;
  GstClockTime pts, dts;

  gst_element_get_state (GST_ELEMENT (typefind), &state, NULL, 0);

  push_cached_buffers = (state >= GST_STATE_PAUSED && typefind->caps);

  GST_DEBUG_OBJECT (typefind, "stopping typefinding%s",
      push_cached_buffers ? " and pushing cached events and buffers" : "");

  typefind->mode = MODE_NORMAL;
  if (push_cached_buffers)
    gst_type_find_element_send_cached_events (typefind);

  GST_OBJECT_LOCK (typefind);
  avail = gst_adapter_available (typefind->adapter);
  if (avail == 0)
    goto no_data;

  pts = gst_adapter_prev_pts (typefind->adapter, NULL);
  dts = gst_adapter_prev_dts (typefind->adapter, NULL);
  buffer = gst_adapter_take_buffer (typefind->adapter, avail);
  GST_BUFFER_PTS (buffer) = pts;
  GST_BUFFER_DTS (buffer) = dts;
  GST_BUFFER_OFFSET (buffer) = typefind->initial_offset;
  GST_OBJECT_UNLOCK (typefind);

  if (!push_cached_buffers) {
    gst_buffer_unref (buffer);
  } else {
    GstPad *peer = gst_pad_get_peer (typefind->src);

    /* make sure the user gets a meaningful error message in this case,
     * which is not a core bug or bug of any kind (as the default error
     * message emitted by gstpad.c otherwise would make you think) */
    if (peer && GST_PAD_CHAINFUNC (peer) == NULL) {
      GST_DEBUG_OBJECT (typefind, "upstream only supports push mode, while "
          "downstream element only works in pull mode, erroring out");
      GST_ELEMENT_ERROR (typefind, STREAM, FAILED,
          ("%s cannot work in push mode. The operation is not supported "
              "with this source element or protocol.",
              G_OBJECT_TYPE_NAME (GST_PAD_PARENT (peer))),
          ("Downstream pad %s:%s has no chainfunction, and the upstream "
              "element does not support pull mode", GST_DEBUG_PAD_NAME (peer)));
      typefind->mode = MODE_ERROR;      /* make the chain function error out */
      gst_buffer_unref (buffer);
    } else {
      gst_pad_push (typefind->src, buffer);
    }
    if (peer)
      gst_object_unref (peer);
  }
  return;

  /* ERRORS */
no_data:
  {
    GST_DEBUG_OBJECT (typefind, "we have no data to typefind");
    GST_OBJECT_UNLOCK (typefind);
    return;
  }
}