gboolean
dshow_vdec_register (GstPlugin * plugin)
{
  GTypeInfo info = {
    sizeof (GstDshowVideoDecClass),
    (GBaseInitFunc) gst_dshowvideodec_base_init,
    NULL,
    (GClassInitFunc) gst_dshowvideodec_class_init,
    NULL,
    NULL,
    sizeof (GstDshowVideoDec),
    0,
    (GInstanceInitFunc) gst_dshowvideodec_init,
  };
  gint i;
  HRESULT hr;

  GST_DEBUG_CATEGORY_INIT (dshowvideodec_debug, "dshowvideodec", 0,
      "Directshow filter video decoder");

  hr = CoInitialize (0);

  for (i = 0; i < sizeof (video_dec_codecs) / sizeof (VideoCodecEntry); i++) {
    GType type;
    CComPtr<IBaseFilter> filter;
    guint rank = GST_RANK_MARGINAL;

    filter = gst_dshow_find_filter (
            video_dec_codecs[i].input_majortype,
            video_dec_codecs[i].input_subtype,
            video_dec_codecs[i].output_majortype,
            video_dec_codecs[i].output_subtype,
            video_dec_codecs[i].preferred_filters);
    if (filter != NULL) {

      if (video_dec_codecs[i].format == GST_MAKE_FOURCC ('W', 'V', 'C', '1')) {
        /* FFMPEG WVC1 decoder sucks, get higher priority for ours */
        rank = GST_RANK_MARGINAL + 2;
      }
      GST_DEBUG ("Registering %s with rank %u", video_dec_codecs[i].element_name, rank);

      type = g_type_register_static (GST_TYPE_ELEMENT,
          video_dec_codecs[i].element_name, &info, (GTypeFlags)0);
      g_type_set_qdata (type, DSHOW_CODEC_QDATA, (gpointer) (video_dec_codecs + i));
      if (!gst_element_register (plugin, video_dec_codecs[i].element_name, rank, type)) {
        return FALSE;
      }
      GST_DEBUG ("Registered %s", video_dec_codecs[i].element_name);
    } else {
      GST_DEBUG ("Element %s not registered "
        "(the format is not supported by the system)",
        video_dec_codecs[i].element_name);
    }
  }

  if (SUCCEEDED(hr))
    CoUninitialize ();

  return TRUE;
}
gboolean
dshow_adec_register (GstPlugin * plugin)
{
  GTypeInfo info = {
    sizeof (GstDshowAudioDecClass),
    (GBaseInitFunc) gst_dshowaudiodec_base_init,
    NULL,
    (GClassInitFunc) gst_dshowaudiodec_class_init,
    NULL,
    NULL,
    sizeof (GstDshowAudioDec),
    0,
    (GInstanceInitFunc) gst_dshowaudiodec_init,
  };
  gint i;
  HRESULT hr;

  GST_DEBUG_CATEGORY_INIT (dshowaudiodec_debug, "dshowaudiodec", 0,
      "Directshow filter audio decoder");

  hr = CoInitialize(0);
  for (i = 0; i < sizeof (audio_dec_codecs) / sizeof (AudioCodecEntry); i++) {
    GType type;
    CComPtr<IBaseFilter> filter;
    GUID insubtype = GUID_MEDIASUBTYPE_FROM_FOURCC (audio_dec_codecs[i].format);
    GUID outsubtype = GUID_MEDIASUBTYPE_FROM_FOURCC (WAVE_FORMAT_PCM);

    filter = gst_dshow_find_filter (MEDIATYPE_Audio,
            insubtype,
            MEDIATYPE_Audio,
            outsubtype,
            audio_dec_codecs[i].preferred_filters);

    if (filter) 
    {
      GST_DEBUG ("Registering %s", audio_dec_codecs[i].element_name);

      tmp = &audio_dec_codecs[i];
      type = g_type_register_static (GST_TYPE_ELEMENT,
          audio_dec_codecs[i].element_name, &info, (GTypeFlags)0);
      if (!gst_element_register (plugin, audio_dec_codecs[i].element_name,
              GST_RANK_SECONDARY, type)) {
        return FALSE;
      }
      GST_CAT_DEBUG (dshowaudiodec_debug, "Registered %s",
          audio_dec_codecs[i].element_name);
    }
    else {
      GST_DEBUG ("Element %s not registered "
                 "(the format is not supported by the system)",
                 audio_dec_codecs[i].element_name);
    }
  }

  if (SUCCEEDED(hr))
    CoUninitialize ();

  return TRUE;
}
gboolean
dshow_vdec_register (GstPlugin * plugin)
{
  GTypeInfo info = {
    sizeof (GstDshowVideoDecClass),
    (GBaseInitFunc) gst_dshowvideodec_base_init,
    NULL,
    (GClassInitFunc) gst_dshowvideodec_class_init,
    NULL,
    NULL,
    sizeof (GstDshowVideoDec),
    0,
    (GInstanceInitFunc) gst_dshowvideodec_init,
  };
  gint i;
  HRESULT hr;

  GST_DEBUG_CATEGORY_INIT (dshowvideodec_debug, "dshowvideodec", 0,
      "Directshow filter video decoder");

  hr = CoInitialize (0);

  for (i = 0; i < sizeof (video_dec_codecs) / sizeof (VideoCodecEntry); i++) {
    GType type;
    CComPtr<IBaseFilter> filter;

    filter = gst_dshow_find_filter (
            video_dec_codecs[i].input_majortype,
            video_dec_codecs[i].input_subtype,
            video_dec_codecs[i].output_majortype,
            video_dec_codecs[i].output_subtype,
            video_dec_codecs[i].preferred_filters);
    if (filter != NULL) {

      GST_DEBUG ("Registering %s", video_dec_codecs[i].element_name);

      tmp = &video_dec_codecs[i];
      type =
          g_type_register_static (GST_TYPE_ELEMENT,
          video_dec_codecs[i].element_name, &info, (GTypeFlags)0);
      if (!gst_element_register (plugin, video_dec_codecs[i].element_name,
              GST_RANK_PRIMARY, type)) {
        return FALSE;
      }
      GST_DEBUG ("Registered %s", video_dec_codecs[i].element_name);
    } else {
      GST_DEBUG ("Element %s not registered "
        "(the format is not supported by the system)",
        video_dec_codecs[i].element_name);
    }
  }

  if (SUCCEEDED(hr))
    CoUninitialize ();

  return TRUE;
}
Beispiel #4
0
gboolean
dshow_vdec_register (GstPlugin * plugin)
{
  GTypeInfo info = {
    sizeof (GstDshowVideoDecClass),
    (GBaseInitFunc) gst_dshowvideodec_base_init,
    NULL,
    (GClassInitFunc) gst_dshowvideodec_class_init,
    NULL,
    NULL,
    sizeof (GstDshowVideoDec),
    0,
    (GInstanceInitFunc) gst_dshowvideodec_init,
  };
  gint i;

  GST_DEBUG_CATEGORY_INIT (dshowvideodec_debug, "dshowvideodec", 0,
      "Directshow filter video decoder");

  CoInitializeEx (NULL, COINIT_MULTITHREADED);
  for (i = 0; i < sizeof (video_dec_codecs) / sizeof (CodecEntry); i++) {
    GType type;

    if (gst_dshow_find_filter (video_dec_codecs[i].input_majortype,
            video_dec_codecs[i].input_subtype,
            video_dec_codecs[i].output_majortype,
            video_dec_codecs[i].output_subtype,
            video_dec_codecs[i].preferred_filter_substring, NULL)) {

      GST_CAT_DEBUG (dshowvideodec_debug, "Registering %s",
          video_dec_codecs[i].element_name);

      tmp = &video_dec_codecs[i];
      type =
          g_type_register_static (GST_TYPE_ELEMENT,
          video_dec_codecs[i].element_name, &info, 0);
      if (!gst_element_register (plugin, video_dec_codecs[i].element_name,
              GST_RANK_PRIMARY, type)) {
        return FALSE;
      }
      GST_CAT_DEBUG (dshowvideodec_debug, "Registered %s",
          video_dec_codecs[i].element_name);
    } else {
      GST_CAT_DEBUG (dshowvideodec_debug,
          "Element %s not registered (the format is not supported by the system)",
          video_dec_codecs[i].element_name);
    }
  }

  CoUninitialize ();
  return TRUE;
}
Beispiel #5
0
static gboolean
gst_dshowvideodec_create_graph_and_filters (GstDshowVideoDec * vdec)
{
  HRESULT hres = S_FALSE;
  GstDshowVideoDecClass *klass =
      (GstDshowVideoDecClass *) G_OBJECT_GET_CLASS (vdec);

  /* create the filter graph manager object */
  hres = CoCreateInstance (&CLSID_FilterGraph, NULL, CLSCTX_INPROC,
      &IID_IFilterGraph, (LPVOID *) & vdec->filtergraph);
  if (hres != S_OK || !vdec->filtergraph) {
    GST_ELEMENT_ERROR (vdec, STREAM, FAILED, ("Can't create an instance "
            "of the directshow graph manager (error=%d)", hres), (NULL));
    goto error;
  }

  hres = IFilterGraph_QueryInterface (vdec->filtergraph, &IID_IMediaFilter,
      (void **) &vdec->mediafilter);
  if (hres != S_OK || !vdec->mediafilter) {
    GST_ELEMENT_ERROR (vdec, STREAM, FAILED,
        ("Can't get IMediacontrol interface "
            "from the graph manager (error=%d)", hres), (NULL));
    goto error;
  }

  /* create fake src filter */
  hres = CoCreateInstance (&CLSID_DshowFakeSrc, NULL, CLSCTX_INPROC,
      &IID_IBaseFilter, (LPVOID *) & vdec->srcfilter);
  if (hres != S_OK || !vdec->srcfilter) {
    GST_ELEMENT_ERROR (vdec, STREAM, FAILED, ("Can't create an instance "
            "of the directshow fakesrc (error=%d)", hres), (NULL));
    goto error;
  }

  /* search a decoder filter and create it */
  if (!gst_dshow_find_filter (klass->entry->input_majortype,
          klass->entry->input_subtype,
          klass->entry->output_majortype,
          klass->entry->output_subtype,
          klass->entry->preferred_filter_substring, &vdec->decfilter)) {
    GST_ELEMENT_ERROR (vdec, STREAM, FAILED, ("Can't create an instance "
            "of the decoder filter"), (NULL));
    goto error;
  }

  /* create fake sink filter */
  hres = CoCreateInstance (&CLSID_DshowFakeSink, NULL, CLSCTX_INPROC,
      &IID_IBaseFilter, (LPVOID *) & vdec->sinkfilter);
  if (hres != S_OK || !vdec->sinkfilter) {
    GST_ELEMENT_ERROR (vdec, STREAM, FAILED, ("Can't create an instance "
            "of the directshow fakesink (error=%d)", hres), (NULL));
    goto error;
  }

  /* add filters to the graph */
  hres = IFilterGraph_AddFilter (vdec->filtergraph, vdec->srcfilter, L"src");
  if (hres != S_OK) {
    GST_ELEMENT_ERROR (vdec, STREAM, FAILED, ("Can't add fakesrc filter "
            "to the graph (error=%d)", hres), (NULL));
    goto error;
  }

  hres =
      IFilterGraph_AddFilter (vdec->filtergraph, vdec->decfilter, L"decoder");
  if (hres != S_OK) {
    GST_ELEMENT_ERROR (vdec, STREAM, FAILED, ("Can't add decoder filter "
            "to the graph (error=%d)", hres), (NULL));
    goto error;
  }

  hres = IFilterGraph_AddFilter (vdec->filtergraph, vdec->sinkfilter, L"sink");
  if (hres != S_OK) {
    GST_ELEMENT_ERROR (vdec, STREAM, FAILED, ("Can't add fakesink filter "
            "to the graph (error=%d)", hres), (NULL));
    goto error;
  }

  return TRUE;

error:
  if (vdec->srcfilter) {
    IBaseFilter_Release (vdec->srcfilter);
    vdec->srcfilter = NULL;
  }
  if (vdec->decfilter) {
    IBaseFilter_Release (vdec->decfilter);
    vdec->decfilter = NULL;
  }
  if (vdec->sinkfilter) {
    IBaseFilter_Release (vdec->sinkfilter);
    vdec->sinkfilter = NULL;
  }
  if (vdec->mediafilter) {
    IMediaFilter_Release (vdec->mediafilter);
    vdec->mediafilter = NULL;
  }
  if (vdec->filtergraph) {
    IFilterGraph_Release (vdec->filtergraph);
    vdec->filtergraph = NULL;
  }

  return FALSE;
}
static gboolean
gst_dshowvideodec_create_graph_and_filters (GstDshowVideoDec * vdec)
{
  HRESULT hres = S_FALSE;
  GstDshowVideoDecClass *klass =
      (GstDshowVideoDecClass *) G_OBJECT_GET_CLASS (vdec);
  IBaseFilter *srcfilter = NULL;
  IBaseFilter *sinkfilter = NULL;
  gboolean ret = FALSE;

  /* create the filter graph manager object */
  hres = CoCreateInstance (CLSID_FilterGraph, NULL, CLSCTX_INPROC,
      IID_IFilterGraph, (LPVOID *) & vdec->filtergraph);
  if (hres != S_OK || !vdec->filtergraph) {
    GST_ELEMENT_ERROR (vdec, STREAM, FAILED, ("Can't create an instance "
            "of the directshow graph manager (error=%d)", hres), (NULL));
    goto error;
  }

  hres = vdec->filtergraph->QueryInterface(IID_IMediaFilter,
      (void **) &vdec->mediafilter);
  if (hres != S_OK || !vdec->mediafilter) {
    GST_ELEMENT_ERROR (vdec, STREAM, FAILED,
        ("Can't get IMediacontrol interface "
            "from the graph manager (error=%d)", hres), (NULL));
    goto error;
  }

  /* create fake src filter */
  vdec->fakesrc = new FakeSrc();
  /* Created with a refcount of zero, so increment that */
  vdec->fakesrc->AddRef();

  hres = vdec->fakesrc->QueryInterface(IID_IBaseFilter,
      (void **) &srcfilter);
  if (FAILED (hres)) {
    GST_WARNING_OBJECT (vdec, "Failed to QI fakesrc to IBaseFilter");
    goto error;
  }

  /* search a decoder filter and create it */
  vdec->decfilter = gst_dshow_find_filter (
          klass->entry->input_majortype,
          klass->entry->input_subtype,
          klass->entry->output_majortype,
          klass->entry->output_subtype,
          klass->entry->preferred_filters);
  if (vdec->decfilter == NULL) {
    GST_ELEMENT_ERROR (vdec, STREAM, FAILED, ("Can't create an instance "
            "of the decoder filter"), (NULL));
    goto error;
  }

  /* create fake sink filter */
  vdec->fakesink = new VideoFakeSink(vdec);
  /* Created with a refcount of zero, so increment that */
  vdec->fakesink->AddRef();

  hres = vdec->fakesink->QueryInterface(IID_IBaseFilter,
      (void **) &sinkfilter);
  if (FAILED (hres)) {
    GST_WARNING_OBJECT (vdec, "Failed to QI fakesink to IBaseFilter");
    goto error;
  }

  /* add filters to the graph */
  hres = vdec->filtergraph->AddFilter (srcfilter, L"src");
  if (hres != S_OK) {
    GST_ELEMENT_ERROR (vdec, STREAM, FAILED, ("Can't add fakesrc filter "
            "to the graph (error=%d)", hres), (NULL));
    goto error;
  }

  hres = vdec->filtergraph->AddFilter(vdec->decfilter, L"decoder");
  if (hres != S_OK) {
    GST_ELEMENT_ERROR (vdec, STREAM, FAILED, ("Can't add decoder filter "
            "to the graph (error=%d)", hres), (NULL));
    goto error;
  }

  hres = vdec->filtergraph->AddFilter(sinkfilter, L"sink");
  if (hres != S_OK) {
    GST_ELEMENT_ERROR (vdec, STREAM, FAILED, ("Can't add fakesink filter "
            "to the graph (error=%d)", hres), (NULL));
    goto error;
  }

  vdec->setup = TRUE;

  ret = TRUE;

done:
  if (srcfilter)
    srcfilter->Release();
  if (sinkfilter)
    sinkfilter->Release();
  return ret;

error:
  if (vdec->fakesrc) {
    vdec->fakesrc->Release();
    vdec->fakesrc = NULL;
  }
  if (vdec->decfilter) {
    vdec->decfilter->Release();
    vdec->decfilter = NULL;
  }
  if (vdec->fakesink) {
    vdec->fakesink->Release();
    vdec->fakesink = NULL;
  }
  if (vdec->mediafilter) {
    vdec->mediafilter->Release();
    vdec->mediafilter = NULL;
  }
  if (vdec->filtergraph) {
    vdec->filtergraph->Release();
    vdec->filtergraph = NULL;
  }

  goto done;
}
static gboolean
gst_dshowaudiodec_create_graph_and_filters (GstDshowAudioDec * adec)
{
  HRESULT hres;
  GstDshowAudioDecClass *klass =
      (GstDshowAudioDecClass *) G_OBJECT_GET_CLASS (adec);
  CComQIPtr<IBaseFilter> srcfilter;
  CComQIPtr<IBaseFilter> sinkfilter;
  GUID insubtype = GUID_MEDIASUBTYPE_FROM_FOURCC (klass->entry->format);
  GUID outsubtype = GUID_MEDIASUBTYPE_FROM_FOURCC (WAVE_FORMAT_PCM);

  /* create the filter graph manager object */
  hres = adec->filtergraph.CoCreateInstance (
      CLSID_FilterGraph, NULL, CLSCTX_INPROC);
  if (FAILED (hres)) {
    GST_ELEMENT_ERROR (adec, STREAM, FAILED,
        ("Can't create an instance of the directshow graph manager (error=%d)",
            hres), (NULL));
    goto error;
  }

  hres = adec->filtergraph->QueryInterface (&adec->mediafilter);
  if (FAILED (hres)) {
    GST_WARNING_OBJECT (adec, "Can't QI filtergraph to mediafilter");
    goto error;
  }

  /* create fake src filter */
  adec->fakesrc = new FakeSrc();
  /* Created with a refcount of zero, so increment that */
  adec->fakesrc->AddRef();

  /* create decoder filter */
  adec->decfilter = gst_dshow_find_filter (MEDIATYPE_Audio,
          insubtype,
          MEDIATYPE_Audio,
          outsubtype,
          klass->entry->preferred_filters);
  if (adec->decfilter == NULL) {
    GST_ELEMENT_ERROR (adec, STREAM, FAILED,
        ("Can't create an instance of the decoder filter"), (NULL));
    goto error;
  }

  /* create fake sink filter */
  adec->fakesink = new AudioFakeSink(adec);
  /* Created with a refcount of zero, so increment that */
  adec->fakesink->AddRef();

  /* add filters to the graph */
  srcfilter = adec->fakesrc;
  hres = adec->filtergraph->AddFilter (srcfilter, L"src");
  if (hres != S_OK) {
    GST_ELEMENT_ERROR (adec, STREAM, FAILED,
        ("Can't add fakesrc filter to the graph (error=%d)", hres), (NULL));
    goto error;
  }

  hres = adec->filtergraph->AddFilter(adec->decfilter, L"decoder");
  if (hres != S_OK) {
    GST_ELEMENT_ERROR (adec, STREAM, FAILED,
        ("Can't add decoder filter to the graph (error=%d)", hres), (NULL));
    goto error;
  }

  sinkfilter = adec->fakesink;
  hres = adec->filtergraph->AddFilter(sinkfilter, L"sink");
  if (hres != S_OK) {
    GST_ELEMENT_ERROR (adec, STREAM, FAILED,
        ("Can't add fakesink filter to the graph (error=%d)", hres), (NULL));
    goto error;
  }

  return TRUE;

error:
  if (adec->fakesrc) {
    adec->fakesrc->Release();
    adec->fakesrc = NULL;
  }
  if (adec->fakesink) {
    adec->fakesink->Release();
    adec->fakesink = NULL;
  }
  adec->decfilter = 0;
  adec->mediafilter = 0;
  adec->filtergraph = 0;

  return FALSE;
}