static gboolean gst_dshowvideodec_destroy_graph_and_filters (GstDshowVideoDec * vdec) { if (vdec->mediafilter) { IMediaFilter_Stop (vdec->mediafilter); } if (vdec->gstdshowsrcfilter) { IGstDshowInterface_Release (vdec->gstdshowsrcfilter); vdec->gstdshowsrcfilter = NULL; } if (vdec->srcfilter) { if (vdec->filtergraph) IFilterGraph_RemoveFilter (vdec->filtergraph, vdec->srcfilter); IBaseFilter_Release (vdec->srcfilter); vdec->srcfilter = NULL; } if (vdec->decfilter) { if (vdec->filtergraph) IFilterGraph_RemoveFilter (vdec->filtergraph, vdec->decfilter); IBaseFilter_Release (vdec->decfilter); vdec->decfilter = NULL; } if (vdec->sinkfilter) { if (vdec->filtergraph) IFilterGraph_RemoveFilter (vdec->filtergraph, 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 TRUE; }
static gboolean gst_dshowvideodec_sink_setcaps (GstPad * pad, GstCaps * caps) { gboolean ret = FALSE; HRESULT hres; GstStructure *s = gst_caps_get_structure (caps, 0); GstDshowVideoDec *vdec = (GstDshowVideoDec *) gst_pad_get_parent (pad); GstDshowVideoDecClass *klass = (GstDshowVideoDecClass *) G_OBJECT_GET_CLASS (vdec); GstBuffer *extradata = NULL; const GValue *v = NULL; gint size = 0; GstCaps *caps_out; AM_MEDIA_TYPE output_mediatype, input_mediatype; VIDEOINFOHEADER *input_vheader = NULL, *output_vheader = NULL; IPin *output_pin = NULL, *input_pin = NULL; IGstDshowInterface *gstdshowinterface = NULL; const GValue *fps; /* read data */ if (!gst_structure_get_int (s, "width", &vdec->width) || !gst_structure_get_int (s, "height", &vdec->height)) { GST_ELEMENT_ERROR (vdec, CORE, NEGOTIATION, ("error getting video width or height from caps"), (NULL)); goto end; } fps = gst_structure_get_value (s, "framerate"); if (!fps) { GST_ELEMENT_ERROR (vdec, CORE, NEGOTIATION, ("error getting video framerate from caps"), (NULL)); goto end; } vdec->fps_n = gst_value_get_fraction_numerator (fps); vdec->fps_d = gst_value_get_fraction_denominator (fps); if ((v = gst_structure_get_value (s, "codec_data"))) extradata = gst_value_get_buffer (v); /* define the input type format */ memset (&input_mediatype, 0, sizeof (AM_MEDIA_TYPE)); input_mediatype.majortype = klass->entry->input_majortype; input_mediatype.subtype = klass->entry->input_subtype; input_mediatype.bFixedSizeSamples = FALSE; input_mediatype.bTemporalCompression = TRUE; if (strstr (klass->entry->sinkcaps, "video/mpeg, mpegversion= (int) 1")) { size = sizeof (MPEG1VIDEOINFO) + (extradata ? GST_BUFFER_SIZE (extradata) - 1 : 0); input_vheader = g_malloc0 (size); input_vheader->bmiHeader.biSize = sizeof (BITMAPINFOHEADER); if (extradata) { MPEG1VIDEOINFO *mpeg_info = (MPEG1VIDEOINFO *) input_vheader; memcpy (mpeg_info->bSequenceHeader, GST_BUFFER_DATA (extradata), GST_BUFFER_SIZE (extradata)); mpeg_info->cbSequenceHeader = GST_BUFFER_SIZE (extradata); } input_mediatype.formattype = FORMAT_MPEGVideo; } else { size = sizeof (VIDEOINFOHEADER) + (extradata ? GST_BUFFER_SIZE (extradata) : 0); input_vheader = g_malloc0 (size); input_vheader->bmiHeader.biSize = sizeof (BITMAPINFOHEADER); if (extradata) { /* Codec data is appended after our header */ memcpy (((guchar *) input_vheader) + sizeof (VIDEOINFOHEADER), GST_BUFFER_DATA (extradata), GST_BUFFER_SIZE (extradata)); input_vheader->bmiHeader.biSize += GST_BUFFER_SIZE (extradata); } input_mediatype.formattype = FORMAT_VideoInfo; } input_vheader->rcSource.top = input_vheader->rcSource.left = 0; input_vheader->rcSource.right = vdec->width; input_vheader->rcSource.bottom = vdec->height; input_vheader->rcTarget = input_vheader->rcSource; input_vheader->bmiHeader.biWidth = vdec->width; input_vheader->bmiHeader.biHeight = vdec->height; input_vheader->bmiHeader.biPlanes = 1; input_vheader->bmiHeader.biBitCount = 16; input_vheader->bmiHeader.biCompression = klass->entry->format; input_vheader->bmiHeader.biSizeImage = (vdec->width * vdec->height) * (input_vheader->bmiHeader.biBitCount / 8); input_mediatype.cbFormat = size; input_mediatype.pbFormat = (BYTE *) input_vheader; input_mediatype.lSampleSize = input_vheader->bmiHeader.biSizeImage; hres = IBaseFilter_QueryInterface (vdec->srcfilter, &IID_IGstDshowInterface, (void **) &gstdshowinterface); if (hres != S_OK || !gstdshowinterface) { GST_ELEMENT_ERROR (vdec, CORE, NEGOTIATION, ("Can't get IGstDshowInterface interface from dshow fakesrc filter (error=%d)", hres), (NULL)); goto end; } /* save a reference to IGstDshowInterface to use it processing functions */ if (!vdec->gstdshowsrcfilter) { vdec->gstdshowsrcfilter = gstdshowinterface; IBaseFilter_AddRef (vdec->gstdshowsrcfilter); } IGstDshowInterface_gst_set_media_type (gstdshowinterface, &input_mediatype); IGstDshowInterface_Release (gstdshowinterface); gstdshowinterface = NULL; /* set the sample size for fakesrc filter to the output buffer size */ IGstDshowInterface_gst_set_sample_size (vdec->gstdshowsrcfilter, input_mediatype.lSampleSize); /* connect our fake src to decoder */ gst_dshow_get_pin_from_filter (vdec->srcfilter, PINDIR_OUTPUT, &output_pin); if (!output_pin) { GST_ELEMENT_ERROR (vdec, CORE, NEGOTIATION, ("Can't get output pin from our directshow fakesrc filter"), (NULL)); goto end; } gst_dshow_get_pin_from_filter (vdec->decfilter, PINDIR_INPUT, &input_pin); if (!input_pin) { GST_ELEMENT_ERROR (vdec, CORE, NEGOTIATION, ("Can't get input pin from decoder filter"), (NULL)); goto end; } hres = IFilterGraph_ConnectDirect (vdec->filtergraph, output_pin, input_pin, NULL); if (hres != S_OK) { GST_ELEMENT_ERROR (vdec, CORE, NEGOTIATION, ("Can't connect fakesrc with decoder (error=%d)", hres), (NULL)); goto end; } IPin_Release (input_pin); IPin_Release (output_pin); input_pin = NULL; output_pin = NULL; /* get decoder output video format */ if (!gst_dshowvideodec_get_filter_output_format (vdec, &klass->entry->output_subtype, &output_vheader, &size)) { GST_ELEMENT_ERROR (vdec, CORE, NEGOTIATION, ("Can't get decoder output video format"), (NULL)); goto end; } memset (&output_mediatype, 0, sizeof (AM_MEDIA_TYPE)); output_mediatype.majortype = klass->entry->output_majortype; output_mediatype.subtype = klass->entry->output_subtype; output_mediatype.bFixedSizeSamples = TRUE; output_mediatype.bTemporalCompression = FALSE; output_mediatype.lSampleSize = output_vheader->bmiHeader.biSizeImage; output_mediatype.formattype = FORMAT_VideoInfo; output_mediatype.cbFormat = size; output_mediatype.pbFormat = (char *) output_vheader; hres = IBaseFilter_QueryInterface (vdec->sinkfilter, &IID_IGstDshowInterface, (void **) &gstdshowinterface); if (hres != S_OK || !gstdshowinterface) { GST_ELEMENT_ERROR (vdec, CORE, NEGOTIATION, ("Can't get IGstDshowInterface interface from dshow fakesink filter (error=%d)", hres), (NULL)); goto end; } IGstDshowInterface_gst_set_media_type (gstdshowinterface, &output_mediatype); IGstDshowInterface_gst_set_buffer_callback (gstdshowinterface, gst_dshowvideodec_push_buffer, (byte *) vdec); IGstDshowInterface_Release (gstdshowinterface); gstdshowinterface = NULL; /* connect decoder to our fake sink */ gst_dshow_get_pin_from_filter (vdec->decfilter, PINDIR_OUTPUT, &output_pin); if (!output_pin) { GST_ELEMENT_ERROR (vdec, CORE, NEGOTIATION, ("Can't get output pin from our decoder filter"), (NULL)); goto end; } gst_dshow_get_pin_from_filter (vdec->sinkfilter, PINDIR_INPUT, &input_pin); if (!input_pin) { GST_ELEMENT_ERROR (vdec, CORE, NEGOTIATION, ("Can't get input pin from our directshow fakesink filter"), (NULL)); goto end; } hres = IFilterGraph_ConnectDirect (vdec->filtergraph, output_pin, input_pin, &output_mediatype); if (hres != S_OK) { GST_ELEMENT_ERROR (vdec, CORE, NEGOTIATION, ("Can't connect decoder with fakesink (error=%d)", hres), (NULL)); goto end; } /* negotiate output */ caps_out = gst_caps_from_string (klass->entry->srccaps); gst_caps_set_simple (caps_out, "width", G_TYPE_INT, vdec->width, "height", G_TYPE_INT, vdec->height, "framerate", GST_TYPE_FRACTION, vdec->fps_n, vdec->fps_d, NULL); if (!gst_pad_set_caps (vdec->srcpad, caps_out)) { gst_caps_unref (caps_out); GST_ELEMENT_ERROR (vdec, CORE, NEGOTIATION, ("Failed to negotiate output"), (NULL)); goto end; } gst_caps_unref (caps_out); hres = IMediaFilter_Run (vdec->mediafilter, -1); if (hres != S_OK) { GST_ELEMENT_ERROR (vdec, CORE, NEGOTIATION, ("Can't run the directshow graph (error=%d)", hres), (NULL)); goto end; } ret = TRUE; end: gst_object_unref (vdec); if (input_vheader) g_free (input_vheader); if (gstdshowinterface) IGstDshowInterface_Release (gstdshowinterface); if (input_pin) IPin_Release (input_pin); if (output_pin) IPin_Release (output_pin); return ret; }
static gboolean gst_dshowaudiosrc_prepare (GstAudioSrc * asrc, GstRingBufferSpec * spec) { HRESULT hres; IGstDshowInterface *srcinterface = NULL; IPin *input_pin = NULL; GstDshowAudioSrc *src = GST_DSHOWAUDIOSRC (asrc); /* search the negociated caps in our caps list to get its index and the corresponding mediatype */ if (gst_caps_is_subset (spec->caps, src->caps)) { guint i = 0; gint res = -1; for (; i < gst_caps_get_size (src->caps) && res == -1; i++) { GstCaps *capstmp = gst_caps_copy_nth (src->caps, i); if (gst_caps_is_subset (spec->caps, capstmp)) { res = i; } gst_caps_unref (capstmp); } if (res != -1 && src->pins_mediatypes) { /*get the corresponding media type and build the dshow graph */ GstCapturePinMediaType *pin_mediatype = NULL; GList *type = g_list_nth (src->pins_mediatypes, res); if (type) { pin_mediatype = (GstCapturePinMediaType *) type->data; hres = IBaseFilter_QueryInterface (src->dshow_fakesink, &IID_IGstDshowInterface, (void **) &srcinterface); if (hres != S_OK || !srcinterface) { GST_CAT_ERROR (dshowaudiosrc_debug, "Can't get IGstDshowInterface interface from our dshow fakesink filter (error=%d)", hres); goto error; } IGstDshowInterface_gst_set_media_type (srcinterface, pin_mediatype->mediatype); IGstDshowInterface_gst_set_buffer_callback (srcinterface, (byte *) gst_dshowaudiosrc_push_buffer, (byte *) src); if (srcinterface) { IGstDshowInterface_Release (srcinterface); } gst_dshow_get_pin_from_filter (src->dshow_fakesink, PINDIR_INPUT, &input_pin); if (!input_pin) { GST_CAT_ERROR (dshowaudiosrc_debug, "Can't get input pin from our directshow fakesink filter"); goto error; } hres = IFilterGraph_ConnectDirect (src->filter_graph, pin_mediatype->capture_pin, input_pin, NULL); IPin_Release (input_pin); if (hres != S_OK) { GST_CAT_ERROR (dshowaudiosrc_debug, "Can't connect capture filter with fakesink filter (error=%d)", hres); goto error; } spec->segsize = spec->rate * spec->channels; spec->segtotal = 1; } } } return TRUE; error: if (srcinterface) { IGstDshowInterface_Release (srcinterface); } return FALSE; }