static gboolean sink_setcaps(GstPad *pad, GstCaps *caps) { struct obj *self; GstStructure *in_struc; const char *name; int codec_id; const GValue *codec_data; GstBuffer *buf; AVCodecContext *ctx; self = (struct obj *)((GstObject *)pad)->parent; ctx = self->av_ctx; if (ctx) { /* reset */ get_delayed(self); gst_av_codec_close(ctx); av_freep(&ctx->extradata); av_freep(&self->av_ctx); self->initialized = false; } in_struc = gst_caps_get_structure(caps, 0); name = gst_structure_get_name(in_struc); if (strcmp(name, "video/x-h263") == 0) codec_id = CODEC_ID_H263; else if (strcmp(name, "video/x-h264") == 0) codec_id = CODEC_ID_H264; else if (strcmp(name, "video/mpeg") == 0) { int version; gst_structure_get_int(in_struc, "mpegversion", &version); switch (version) { case 4: codec_id = CODEC_ID_MPEG4; break; case 2: codec_id = CODEC_ID_MPEG2VIDEO; break; case 1: codec_id = CODEC_ID_MPEG1VIDEO; break; default: codec_id = CODEC_ID_NONE; break; } } else if (strcmp(name, "video/x-divx") == 0) { int version; gst_structure_get_int(in_struc, "divxversion", &version); switch (version) { case 5: case 4: codec_id = CODEC_ID_MPEG4; break; case 3: codec_id = CODEC_ID_MSMPEG4V3; break; default: codec_id = CODEC_ID_NONE; break; } } else if (strcmp(name, "video/x-xvid") == 0) codec_id = CODEC_ID_MPEG4; else if (strcmp(name, "video/x-3ivx") == 0) codec_id = CODEC_ID_MPEG4; else if (strcmp(name, "video/x-vp8") == 0) codec_id = CODEC_ID_VP8; else if (strcmp(name, "video/x-theora") == 0) codec_id = CODEC_ID_THEORA; else if (strcmp(name, "video/x-wmv") == 0) { int version; gst_structure_get_int(in_struc, "wmvversion", &version); switch (version) { case 3: { guint32 fourcc; codec_id = CODEC_ID_WMV3; if (gst_structure_get_fourcc(in_struc, "fourcc", &fourcc) || gst_structure_get_fourcc(in_struc, "format", &fourcc)) { if (fourcc == GST_MAKE_FOURCC('W', 'V', 'C', '1')) codec_id = CODEC_ID_VC1; } break; } case 2: codec_id = CODEC_ID_WMV2; break; case 1: codec_id = CODEC_ID_WMV1; break; default: codec_id = CODEC_ID_NONE; break; } } else codec_id = CODEC_ID_NONE; self->codec = avcodec_find_decoder(codec_id); if (!self->codec) return false; switch (codec_id) { case CODEC_ID_H263: self->parse_func = gst_av_h263_parse; break; case CODEC_ID_H264: self->parse_func = gst_av_h264_parse; break; case CODEC_ID_MPEG4: self->parse_func = gst_av_mpeg4_parse; break; } self->av_ctx = ctx = avcodec_alloc_context3(self->codec); ctx->get_buffer = get_buffer; ctx->release_buffer = release_buffer; ctx->reget_buffer = reget_buffer; ctx->opaque = self; ctx->flags |= CODEC_FLAG_EMU_EDGE; gst_structure_get_int(in_struc, "width", &ctx->width); gst_structure_get_int(in_struc, "height", &ctx->height); gst_structure_get_fraction(in_struc, "pixel-aspect-ratio", &ctx->sample_aspect_ratio.num, &ctx->sample_aspect_ratio.den); gst_structure_get_fraction(in_struc, "framerate", &ctx->time_base.den, &ctx->time_base.num); /* bug in xvimagesink? */ if (!ctx->time_base.num) ctx->time_base = (AVRational){ 1, 0 }; if (codec_id == CODEC_ID_THEORA) { get_theora_extradata(ctx, in_struc); goto next; } codec_data = gst_structure_get_value(in_struc, "codec_data"); if (!codec_data) goto next; buf = gst_value_get_buffer(codec_data); if (!buf) goto next; ctx->extradata = av_malloc(buf->size + FF_INPUT_BUFFER_PADDING_SIZE); memcpy(ctx->extradata, buf->data, buf->size); memset(ctx->extradata + buf->size, 0, FF_INPUT_BUFFER_PADDING_SIZE); ctx->extradata_size = buf->size; if (self->parse_func) self->parse_func(self, buf); next: 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; guint size = 0; GstCaps *caps_out; AM_MEDIA_TYPE output_mediatype, input_mediatype; VIDEOINFOHEADER *input_vheader = NULL, *output_vheader = NULL; CComPtr<IPin> output_pin; CComPtr<IPin> input_pin; IBaseFilter *srcfilter = NULL; IBaseFilter *sinkfilter = NULL; const GValue *fps, *par; /* 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) { vdec->fps_n = gst_value_get_fraction_numerator (fps); vdec->fps_d = gst_value_get_fraction_denominator (fps); } else { /* Invent a sane default framerate; the timestamps matter * more anyway. */ vdec->fps_n = 25; vdec->fps_d = 1; } par = gst_structure_get_value (s, "pixel-aspect-ratio"); if (par) { vdec->par_n = gst_value_get_fraction_numerator (par); vdec->par_d = gst_value_get_fraction_denominator (par); } else { vdec->par_n = vdec->par_d = 1; } 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 = (VIDEOINFOHEADER *)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 = (VIDEOINFOHEADER *)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; vdec->fakesrc->GetOutputPin()->SetMediaType(&input_mediatype); /* set the sample size for fakesrc filter to the output buffer size */ vdec->fakesrc->GetOutputPin()->SetSampleSize(input_mediatype.lSampleSize); /* connect our fake src to decoder */ hres = vdec->fakesrc->QueryInterface(IID_IBaseFilter, (void **) &srcfilter); if (FAILED (hres)) { GST_ELEMENT_ERROR (vdec, CORE, NEGOTIATION, ("Can't QT fakesrc to IBaseFilter: %x", hres), (NULL)); goto end; } output_pin = gst_dshow_get_pin_from_filter (srcfilter, PINDIR_OUTPUT); if (!output_pin) { GST_ELEMENT_ERROR (vdec, CORE, NEGOTIATION, ("Can't get output pin from our directshow fakesrc filter"), (NULL)); goto end; } input_pin = gst_dshow_get_pin_from_filter (vdec->decfilter, PINDIR_INPUT); if (!input_pin) { GST_ELEMENT_ERROR (vdec, CORE, NEGOTIATION, ("Can't get input pin from decoder filter"), (NULL)); goto end; } hres = vdec->filtergraph->ConnectDirect (output_pin, input_pin, NULL); if (hres != S_OK) { GST_ELEMENT_ERROR (vdec, CORE, NEGOTIATION, ("Can't connect fakesrc with decoder (error=%x)", hres), (NULL)); goto end; } /* 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 = (BYTE *) output_vheader; vdec->fakesink->SetMediaType (&output_mediatype); /* connect decoder to our fake sink */ output_pin = gst_dshow_get_pin_from_filter (vdec->decfilter, PINDIR_OUTPUT); if (!output_pin) { GST_ELEMENT_ERROR (vdec, CORE, NEGOTIATION, ("Can't get output pin from our decoder filter"), (NULL)); goto end; } hres = vdec->fakesink->QueryInterface(IID_IBaseFilter, (void **) &sinkfilter); if (FAILED (hres)) { GST_ELEMENT_ERROR (vdec, CORE, NEGOTIATION, ("Can't QT fakesink to IBaseFilter: %x", hres), (NULL)); goto end; } input_pin = gst_dshow_get_pin_from_filter (sinkfilter, PINDIR_INPUT); if (!input_pin) { GST_ELEMENT_ERROR (vdec, CORE, NEGOTIATION, ("Can't get input pin from our directshow fakesink filter"), (NULL)); goto end; } hres = vdec->filtergraph->ConnectDirect(output_pin, input_pin, &output_mediatype); if (hres != S_OK) { GST_ELEMENT_ERROR (vdec, CORE, NEGOTIATION, ("Can't connect decoder with fakesink (error=%x)", 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, NULL); if (vdec->fps_n && vdec->fps_d) { gst_caps_set_simple (caps_out, "framerate", GST_TYPE_FRACTION, vdec->fps_n, vdec->fps_d, NULL); } gst_caps_set_simple (caps_out, "pixel-aspect-ratio", GST_TYPE_FRACTION, vdec->par_n, vdec->par_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 = vdec->mediafilter->Run (-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 (srcfilter) srcfilter->Release(); if (sinkfilter) sinkfilter->Release(); return ret; }
static gboolean gst_rdt_depay_setcaps (GstPad * pad, GstCaps * caps) { GstStructure *structure; GstRDTDepay *rdtdepay; GstCaps *srccaps; gint clock_rate = 1000; /* default */ const GValue *value; GstBuffer *header; rdtdepay = GST_RDT_DEPAY (GST_PAD_PARENT (pad)); structure = gst_caps_get_structure (caps, 0); if (gst_structure_has_field (structure, "clock-rate")) gst_structure_get_int (structure, "clock-rate", &clock_rate); /* config contains the RealMedia header as a buffer. */ value = gst_structure_get_value (structure, "config"); if (!value) goto no_header; header = gst_value_get_buffer (value); if (!header) goto no_header; /* get other values for newsegment */ value = gst_structure_get_value (structure, "npt-start"); if (value && G_VALUE_HOLDS_UINT64 (value)) rdtdepay->npt_start = g_value_get_uint64 (value); else rdtdepay->npt_start = 0; GST_DEBUG_OBJECT (rdtdepay, "NPT start %" G_GUINT64_FORMAT, rdtdepay->npt_start); value = gst_structure_get_value (structure, "npt-stop"); if (value && G_VALUE_HOLDS_UINT64 (value)) rdtdepay->npt_stop = g_value_get_uint64 (value); else rdtdepay->npt_stop = -1; GST_DEBUG_OBJECT (rdtdepay, "NPT stop %" G_GUINT64_FORMAT, rdtdepay->npt_stop); value = gst_structure_get_value (structure, "play-speed"); if (value && G_VALUE_HOLDS_DOUBLE (value)) rdtdepay->play_speed = g_value_get_double (value); else rdtdepay->play_speed = 1.0; value = gst_structure_get_value (structure, "play-scale"); if (value && G_VALUE_HOLDS_DOUBLE (value)) rdtdepay->play_scale = g_value_get_double (value); else rdtdepay->play_scale = 1.0; /* caps seem good, configure element */ rdtdepay->clock_rate = clock_rate; /* set caps on pad and on header */ srccaps = gst_caps_new_simple ("application/vnd.rn-realmedia", NULL); gst_pad_set_caps (rdtdepay->srcpad, srccaps); gst_caps_unref (srccaps); if (rdtdepay->header) gst_buffer_unref (rdtdepay->header); rdtdepay->header = gst_buffer_ref (header); return TRUE; /* ERRORS */ no_header: { GST_ERROR_OBJECT (rdtdepay, "no header found in caps, no 'config' field"); return FALSE; } }
/* h264 dec has its own sink_setcaps for supporting nalu convert codec data */ static gboolean sink_setcaps (GstPad * pad, GstCaps * caps) { GstStructure *structure; GstOmxBaseVideoDec *self; GstOmxH264Dec *h264_self; GstOmxBaseFilter *omx_base; GOmxCore *gomx; OMX_PARAM_PORTDEFINITIONTYPE param; gint width = 0; gint height = 0; self = GST_OMX_BASE_VIDEODEC (GST_PAD_PARENT (pad)); h264_self = GST_OMX_H264DEC (GST_PAD_PARENT (pad)); omx_base = GST_OMX_BASE_FILTER (self); gomx = (GOmxCore *) omx_base->gomx; GST_INFO_OBJECT (self, "setcaps (sink)(h264): %" GST_PTR_FORMAT, caps); g_return_val_if_fail (gst_caps_get_size (caps) == 1, FALSE); structure = gst_caps_get_structure (caps, 0); gst_structure_get_int (structure, "width", &width); gst_structure_get_int (structure, "height", &height); { const GValue *framerate = NULL; framerate = gst_structure_get_value (structure, "framerate"); if (framerate) { self->framerate_num = gst_value_get_fraction_numerator (framerate); self->framerate_denom = gst_value_get_fraction_denominator (framerate); } } G_OMX_INIT_PARAM (param); { const GValue *codec_data; GstBuffer *buffer; gboolean ret = FALSE; guint8 *buf_data = NULL; codec_data = gst_structure_get_value (structure, "codec_data"); if (codec_data) { buffer = gst_value_get_buffer (codec_data); buf_data = GST_BUFFER_DATA(buffer); if (GST_BUFFER_SIZE(buffer) < 4) GST_ERROR("codec data size is less than 4!!"); //check this. if ((buf_data[0] == 0x00)&&(buf_data[1] == 0x00)&& ((buf_data[2] == 0x01)||((buf_data[2] == 0x00)&&(buf_data[3] == 0x01)))) { h264_self->h264Format = GSTOMX_H264_FORMAT_NALU; GST_INFO_OBJECT(self, "H264 format is NALU"); } else { h264_self->h264Format = GSTOMX_H264_FORMAT_3GPP; GST_INFO_OBJECT(self, "H264 format is 3GPP"); } /* if codec data is 3gpp format, convert nalu format */ if(h264_self->h264Format == GSTOMX_H264_FORMAT_3GPP) { GstBuffer *nalu_dci = NULL; ret = convert_dci(h264_self, buffer, &nalu_dci); if (ret) { omx_base->codec_data = nalu_dci; } else { if (nalu_dci) { gst_buffer_unref (nalu_dci); } GST_ERROR_OBJECT(h264_self, "converting dci error."); omx_base->codec_data = buffer; gst_buffer_ref (buffer); } } else { /* not 3GPP format */ omx_base->codec_data = buffer; gst_buffer_ref (buffer); } h264_self->h264Format = GSTOMX_H264_FORMAT_UNKNOWN; } } /* Input port configuration. */ { param.nPortIndex = omx_base->in_port->port_index; OMX_GetParameter (gomx->omx_handle, OMX_IndexParamPortDefinition, ¶m); param.format.video.nFrameWidth = width; param.format.video.nFrameHeight = height; OMX_SetParameter (gomx->omx_handle, OMX_IndexParamPortDefinition, ¶m); } return gst_pad_set_caps (pad, caps); }
static gboolean gst_imx_audio_uniaudio_dec_set_format(GstAudioDecoder *dec, GstCaps *caps) { UniACodecParameter parameter; UniACodecMemoryOps memory_ops; GstImxAudioUniaudioDec *imx_audio_uniaudio_dec = GST_IMX_AUDIO_UNIAUDIO_DEC(dec); #define UNIA_SET_PARAMETER(PARAM_ID, DESC) \ do \ { \ if (imx_audio_uniaudio_dec->codec->set_parameter(imx_audio_uniaudio_dec->handle, (PARAM_ID), ¶meter) != ACODEC_SUCCESS) \ { \ GST_ERROR_OBJECT(dec, "setting %s parameter failed: %s", (DESC), imx_audio_uniaudio_dec->codec->get_last_error(imx_audio_uniaudio_dec->handle)); \ gst_imx_audio_uniaudio_dec_close_handle(imx_audio_uniaudio_dec); \ return FALSE; \ } \ } \ while (0) #define UNIA_SET_PARAMETER_EX(PARAM_ID, DESC, VALUE) \ do \ { \ if (imx_audio_uniaudio_dec->codec->set_parameter(imx_audio_uniaudio_dec->handle, (PARAM_ID), ((UniACodecParameter *)(VALUE))) != ACODEC_SUCCESS) \ { \ GST_ERROR_OBJECT(dec, "setting %s parameter failed: %s", (DESC), imx_audio_uniaudio_dec->codec->get_last_error(imx_audio_uniaudio_dec->handle)); \ gst_imx_audio_uniaudio_dec_close_handle(imx_audio_uniaudio_dec); \ return FALSE; \ } \ } \ while (0) if (imx_audio_uniaudio_dec->handle != NULL) { /* drain old decoder handle */ gst_imx_audio_uniaudio_dec_handle_frame(dec, NULL); gst_imx_audio_uniaudio_dec_close_handle(imx_audio_uniaudio_dec); } if ((imx_audio_uniaudio_dec->codec = gst_imx_audio_uniaudio_codec_table_get_codec(caps)) == NULL) { GST_ERROR_OBJECT(dec, "found no suitable codec for caps %" GST_PTR_FORMAT, (gpointer)caps); return FALSE; } memory_ops.Calloc = gst_imx_audio_uniaudio_dec_calloc; memory_ops.Malloc = gst_imx_audio_uniaudio_dec_malloc; memory_ops.Free = gst_imx_audio_uniaudio_dec_free; memory_ops.ReAlloc = gst_imx_audio_uniaudio_dec_realloc; if ((imx_audio_uniaudio_dec->handle = imx_audio_uniaudio_dec->codec->create_codec(&memory_ops)) == NULL) { GST_ERROR_OBJECT(dec, "creating codec handle for caps %" GST_PTR_FORMAT " failed", (gpointer)caps); return FALSE; } /* Get configuration parameters from caps */ { int samplerate, channels, bitrate, block_align, wmaversion; gchar const *stream_format, *sample_format; GValue const *value; gboolean framed, is_vorbis; GstBuffer *codec_data = NULL; GstStructure *structure = gst_caps_get_structure(caps, 0); imx_audio_uniaudio_dec->skip_header_counter = 0; is_vorbis = (g_strcmp0(gst_structure_get_name(structure), "audio/x-vorbis") == 0); parameter.framed = is_vorbis || (gst_structure_get_boolean(structure, "framed", &framed) && framed) || (gst_structure_get_boolean(structure, "parsed", &framed) && framed); GST_DEBUG_OBJECT(dec, "input is framed: %d", parameter.framed); UNIA_SET_PARAMETER(UNIA_FRAMED, "framed"); if (gst_structure_get_int(structure, "rate", &samplerate)) { GST_DEBUG_OBJECT(dec, "input caps sample rate: %d Hz", samplerate); parameter.samplerate = samplerate; UNIA_SET_PARAMETER(UNIA_SAMPLERATE, "sample rate"); } if (gst_structure_get_int(structure, "channels", &channels)) { CHAN_TABLE table; GST_DEBUG_OBJECT(dec, "input caps channel count: %d", channels); parameter.channels = channels; UNIA_SET_PARAMETER(UNIA_CHANNEL, "channel"); memset(&table, 0, sizeof(table)); table.size = CHANNEL_MAPS_SIZE; memcpy(&table.channel_table, uniaudio_channel_maps, sizeof(uniaudio_channel_maps)); UNIA_SET_PARAMETER_EX(UNIA_CHAN_MAP_TABLE, "channel map", &table); } if (gst_structure_get_int(structure, "bitrate", &bitrate)) { GST_DEBUG_OBJECT(dec, "input caps channel count: %d", bitrate); parameter.bitrate = bitrate; UNIA_SET_PARAMETER(UNIA_BITRATE, "bitrate"); } if (gst_structure_get_int(structure, "block_align", &block_align)) { GST_DEBUG_OBJECT(dec, "block alignment: %d", block_align); parameter.blockalign = block_align; UNIA_SET_PARAMETER(UNIA_WMA_BlOCKALIGN, "blockalign"); } if (gst_structure_get_int(structure, "wmaversion", &wmaversion)) { GST_DEBUG_OBJECT(dec, "WMA version: %d", wmaversion); parameter.version = wmaversion; UNIA_SET_PARAMETER(UNIA_WMA_VERSION, "wmaversion"); } if ((stream_format = gst_structure_get_string(structure, "stream-format")) != NULL) { GST_DEBUG_OBJECT(dec, "input caps stream format: %s", stream_format); if (g_strcmp0(stream_format, "raw") == 0) parameter.stream_type = STREAM_ADTS; if (g_strcmp0(stream_format, "adif") == 0) parameter.stream_type = STREAM_ADIF; if (g_strcmp0(stream_format, "raw") == 0) parameter.stream_type = STREAM_RAW; else parameter.stream_type = STREAM_UNKNOW; UNIA_SET_PARAMETER(UNIA_STREAM_TYPE, "stream type"); } if ((sample_format = gst_structure_get_string(structure, "format")) != NULL) { GstAudioFormat fmt; GstAudioFormatInfo const * fmtinfo; GST_DEBUG_OBJECT(dec, "input caps stream sample format: %s", sample_format); if ((fmt = gst_audio_format_from_string(sample_format)) == GST_AUDIO_FORMAT_UNKNOWN) { GST_ERROR_OBJECT(dec, "format is unknown, cannot continue"); return FALSE; } fmtinfo = gst_audio_format_get_info(fmt); g_assert(fmtinfo != NULL); parameter.depth = GST_AUDIO_FORMAT_INFO_DEPTH(fmtinfo); UNIA_SET_PARAMETER(UNIA_DEPTH, "depth"); } /* Handle codec data, either directly from a codec_data caps, * or assemble it from a list of buffers specified by the * streamheader caps (typically used by Vorbis audio) */ /* Cleanup old codec data first */ if (imx_audio_uniaudio_dec->codec_data != NULL) { gst_buffer_unref(imx_audio_uniaudio_dec->codec_data); imx_audio_uniaudio_dec->codec_data = NULL; } /* Check if either codec_data or streamheader caps exist */ if ((value = gst_structure_get_value(structure, "codec_data")) != NULL) { /* codec_data caps exist - simply make a copy of its buffer * (this makes sure we own that buffer properly) */ GstBuffer *caps_buffer; GST_DEBUG_OBJECT(dec, "reading codec_data value"); caps_buffer = gst_value_get_buffer(value); g_assert(caps_buffer != NULL); codec_data = gst_buffer_copy(caps_buffer); } else if ((value = gst_structure_get_value(structure, "streamheader")) != NULL) { /* streamheader caps exist, which are a list of buffers * these buffers need to be concatenated and then given as * one consecutive codec data buffer to the decoder */ guint i, num_buffers = gst_value_array_get_size(value); GstAdapter *streamheader_adapter = gst_adapter_new(); GST_DEBUG_OBJECT(dec, "reading streamheader value (%u headers)", num_buffers); imx_audio_uniaudio_dec->num_vorbis_headers = num_buffers; /* Use the GstAdapter to stitch these buffers together */ for (i = 0; i < num_buffers; ++i) { GValue const *array_value = gst_value_array_get_value(value, i); GstBuffer *buf = gst_value_get_buffer(array_value); GST_DEBUG_OBJECT(dec, "add streamheader buffer #%u with %" G_GSIZE_FORMAT " byte", i, gst_buffer_get_size(buf)); gst_adapter_push(streamheader_adapter, gst_buffer_copy(buf)); } codec_data = gst_adapter_take_buffer(streamheader_adapter, gst_adapter_available(streamheader_adapter)); g_object_unref(G_OBJECT(streamheader_adapter)); } /* At this point, if either codec_data or streamheader caps were found, * the codec_data pointer will refer to a valid non-empty buffer with * codec data inside. This buffer is owned by this audio decoder object, * and must be kept around for as long as the decoder needs to be ran, * since the set_parameter call below does *not* copy the codec data * bytes into some internal buffer. Instead, the uniaudio decoder plugin * expects the caller to keep the buffer valid. */ if ((codec_data != NULL) && (gst_buffer_get_size(codec_data) != 0)) { GstMapInfo map; gst_buffer_map(codec_data, &map, GST_MAP_READ); parameter.codecData.size = map.size; parameter.codecData.buf = (char *)(map.data); UNIA_SET_PARAMETER(UNIA_CODEC_DATA, "codec data"); gst_buffer_unmap(codec_data, &map); imx_audio_uniaudio_dec->codec_data = codec_data; GST_DEBUG_OBJECT(dec, "codec data: %" G_GUINT32_FORMAT " byte", (guint32)(parameter.codecData.size)); } } GST_DEBUG_OBJECT(dec, "decoder configured"); imx_audio_uniaudio_dec->has_audioinfo_set = FALSE; #undef UNIA_SET_PARAMETER return TRUE; }
static gboolean gst_amc_audio_dec_set_format (GstAudioDecoder * decoder, GstCaps * caps) { GstAmcAudioDec *self; GstStructure *s; GstAmcFormat *format; const gchar *mime; gboolean is_format_change = FALSE; gboolean needs_disable = FALSE; gchar *format_string; gint rate, channels; GError *err = NULL; self = GST_AMC_AUDIO_DEC (decoder); GST_DEBUG_OBJECT (self, "Setting new caps %" GST_PTR_FORMAT, caps); /* Check if the caps change is a real format change or if only irrelevant * parts of the caps have changed or nothing at all. */ is_format_change |= (!self->input_caps || !gst_caps_is_equal (self->input_caps, caps)); needs_disable = self->started; /* If the component is not started and a real format change happens * we have to restart the component. If no real format change * happened we can just exit here. */ if (needs_disable && !is_format_change) { /* Framerate or something minor changed */ self->input_caps_changed = TRUE; GST_DEBUG_OBJECT (self, "Already running and caps did not change the format"); return TRUE; } if (needs_disable && is_format_change) { gst_amc_audio_dec_drain (self); GST_AUDIO_DECODER_STREAM_UNLOCK (self); gst_amc_audio_dec_stop (GST_AUDIO_DECODER (self)); GST_AUDIO_DECODER_STREAM_LOCK (self); gst_amc_audio_dec_close (GST_AUDIO_DECODER (self)); if (!gst_amc_audio_dec_open (GST_AUDIO_DECODER (self))) { GST_ERROR_OBJECT (self, "Failed to open codec again"); return FALSE; } if (!gst_amc_audio_dec_start (GST_AUDIO_DECODER (self))) { GST_ERROR_OBJECT (self, "Failed to start codec again"); } } /* srcpad task is not running at this point */ mime = caps_to_mime (caps); if (!mime) { GST_ERROR_OBJECT (self, "Failed to convert caps to mime"); return FALSE; } s = gst_caps_get_structure (caps, 0); if (!gst_structure_get_int (s, "rate", &rate) || !gst_structure_get_int (s, "channels", &channels)) { GST_ERROR_OBJECT (self, "Failed to get rate/channels"); return FALSE; } format = gst_amc_format_new_audio (mime, rate, channels, &err); if (!format) { GST_ELEMENT_ERROR_FROM_ERROR (self, err); return FALSE; } /* FIXME: These buffers needs to be valid until the codec is stopped again */ g_list_foreach (self->codec_datas, (GFunc) gst_buffer_unref, NULL); g_list_free (self->codec_datas); self->codec_datas = NULL; if (gst_structure_has_field (s, "codec_data")) { const GValue *h = gst_structure_get_value (s, "codec_data"); GstBuffer *codec_data = gst_value_get_buffer (h); GstMapInfo minfo; guint8 *data; gst_buffer_map (codec_data, &minfo, GST_MAP_READ); data = g_memdup (minfo.data, minfo.size); self->codec_datas = g_list_prepend (self->codec_datas, data); gst_amc_format_set_buffer (format, "csd-0", data, minfo.size, &err); if (err) GST_ELEMENT_WARNING_FROM_ERROR (self, err); gst_buffer_unmap (codec_data, &minfo); } else if (gst_structure_has_field (s, "streamheader")) { const GValue *sh = gst_structure_get_value (s, "streamheader"); gint nsheaders = gst_value_array_get_size (sh); GstBuffer *buf; const GValue *h; gint i, j; gchar *fname; GstMapInfo minfo; guint8 *data; for (i = 0, j = 0; i < nsheaders; i++) { h = gst_value_array_get_value (sh, i); buf = gst_value_get_buffer (h); if (strcmp (mime, "audio/vorbis") == 0) { guint8 header_type; gst_buffer_extract (buf, 0, &header_type, 1); /* Only use the identification and setup packets */ if (header_type != 0x01 && header_type != 0x05) continue; } fname = g_strdup_printf ("csd-%d", j); gst_buffer_map (buf, &minfo, GST_MAP_READ); data = g_memdup (minfo.data, minfo.size); self->codec_datas = g_list_prepend (self->codec_datas, data); gst_amc_format_set_buffer (format, fname, data, minfo.size, &err); if (err) GST_ELEMENT_WARNING_FROM_ERROR (self, err); gst_buffer_unmap (buf, &minfo); g_free (fname); j++; } } format_string = gst_amc_format_to_string (format, &err); if (err) GST_ELEMENT_WARNING_FROM_ERROR (self, err); GST_DEBUG_OBJECT (self, "Configuring codec with format: %s", GST_STR_NULL (format_string)); g_free (format_string); if (!gst_amc_codec_configure (self->codec, format, NULL, 0, &err)) { GST_ERROR_OBJECT (self, "Failed to configure codec"); GST_ELEMENT_ERROR_FROM_ERROR (self, err); return FALSE; } gst_amc_format_free (format); if (!gst_amc_codec_start (self->codec, &err)) { GST_ERROR_OBJECT (self, "Failed to start codec"); GST_ELEMENT_ERROR_FROM_ERROR (self, err); return FALSE; } self->spf = -1; /* TODO: Implement for other codecs too */ if (gst_structure_has_name (s, "audio/mpeg")) { gint mpegversion = -1; gst_structure_get_int (s, "mpegversion", &mpegversion); if (mpegversion == 1) { gint layer = -1, mpegaudioversion = -1; gst_structure_get_int (s, "layer", &layer); gst_structure_get_int (s, "mpegaudioversion", &mpegaudioversion); if (layer == 1) self->spf = 384; else if (layer == 2) self->spf = 1152; else if (layer == 3 && mpegaudioversion != -1) self->spf = (mpegaudioversion == 1 ? 1152 : 576); } } self->started = TRUE; self->input_caps_changed = TRUE; /* Start the srcpad loop again */ self->flushing = FALSE; self->downstream_flow_ret = GST_FLOW_OK; gst_pad_start_task (GST_AUDIO_DECODER_SRC_PAD (self), (GstTaskFunction) gst_amc_audio_dec_loop, decoder, NULL); return TRUE; }
static GstFlowReturn mpegtsmux_create_stream (MpegTsMux * mux, MpegTsPadData * ts_data, GstPad * pad) { GstFlowReturn ret = GST_FLOW_ERROR; GstCaps *caps = gst_pad_get_negotiated_caps (pad); GstStructure *s; if (caps == NULL) { GST_DEBUG_OBJECT (pad, "Sink pad caps were not set before pushing"); return GST_FLOW_NOT_NEGOTIATED; } s = gst_caps_get_structure (caps, 0); g_return_val_if_fail (s != NULL, FALSE); if (gst_structure_has_name (s, "video/x-dirac")) { GST_DEBUG_OBJECT (pad, "Creating Dirac stream with PID 0x%04x", ts_data->pid); ts_data->stream = tsmux_create_stream (mux->tsmux, TSMUX_ST_VIDEO_DIRAC, ts_data->pid); } else if (gst_structure_has_name (s, "audio/x-ac3")) { GST_DEBUG_OBJECT (pad, "Creating AC3 stream with PID 0x%04x", ts_data->pid); ts_data->stream = tsmux_create_stream (mux->tsmux, TSMUX_ST_PS_AUDIO_AC3, ts_data->pid); } else if (gst_structure_has_name (s, "audio/x-dts")) { GST_DEBUG_OBJECT (pad, "Creating DTS stream with PID 0x%04x", ts_data->pid); ts_data->stream = tsmux_create_stream (mux->tsmux, TSMUX_ST_PS_AUDIO_DTS, ts_data->pid); } else if (gst_structure_has_name (s, "audio/x-lpcm")) { GST_DEBUG_OBJECT (pad, "Creating LPCM stream with PID 0x%04x", ts_data->pid); ts_data->stream = tsmux_create_stream (mux->tsmux, TSMUX_ST_PS_AUDIO_LPCM, ts_data->pid); } else if (gst_structure_has_name (s, "video/x-h264")) { const GValue *value; GST_DEBUG_OBJECT (pad, "Creating H264 stream with PID 0x%04x", ts_data->pid); /* Codec data contains SPS/PPS which need to go in stream for valid ES */ value = gst_structure_get_value (s, "codec_data"); if (value) { ts_data->codec_data = gst_buffer_ref (gst_value_get_buffer (value)); GST_DEBUG_OBJECT (pad, "we have additional codec data (%d bytes)", GST_BUFFER_SIZE (ts_data->codec_data)); ts_data->prepare_func = mpegtsmux_prepare_h264; ts_data->free_func = mpegtsmux_free_h264; } else { ts_data->codec_data = NULL; } ts_data->stream = tsmux_create_stream (mux->tsmux, TSMUX_ST_VIDEO_H264, ts_data->pid); } else if (gst_structure_has_name (s, "audio/mpeg")) { gint mpegversion; if (!gst_structure_get_int (s, "mpegversion", &mpegversion)) { GST_ELEMENT_ERROR (pad, STREAM, FORMAT, ("Invalid data format presented"), ("Caps with type audio/mpeg did not have mpegversion")); goto beach; } switch (mpegversion) { case 1: GST_DEBUG_OBJECT (pad, "Creating MPEG Audio, version 1 stream with " "PID 0x%04x", ts_data->pid); ts_data->stream = tsmux_create_stream (mux->tsmux, TSMUX_ST_AUDIO_MPEG1, ts_data->pid); break; case 2: GST_DEBUG_OBJECT (pad, "Creating MPEG Audio, version 2 stream with " "PID 0x%04x", ts_data->pid); ts_data->stream = tsmux_create_stream (mux->tsmux, TSMUX_ST_AUDIO_MPEG2, ts_data->pid); break; case 4: { const GValue *value; /* Codec data contains SPS/PPS which need to go in stream for valid ES */ value = gst_structure_get_value (s, "codec_data"); if (value) { ts_data->codec_data = gst_buffer_ref (gst_value_get_buffer (value)); GST_DEBUG_OBJECT (pad, "we have additional codec data (%d bytes)", GST_BUFFER_SIZE (ts_data->codec_data)); ts_data->prepare_func = mpegtsmux_prepare_aac; } else { ts_data->codec_data = NULL; } GST_DEBUG_OBJECT (pad, "Creating MPEG Audio, version 4 stream with " "PID 0x%04x", ts_data->pid); ts_data->stream = tsmux_create_stream (mux->tsmux, TSMUX_ST_AUDIO_AAC, ts_data->pid); break; } default: GST_WARNING_OBJECT (pad, "unsupported mpegversion %d", mpegversion); goto beach; } } else if (gst_structure_has_name (s, "video/mpeg")) { gint mpegversion; if (!gst_structure_get_int (s, "mpegversion", &mpegversion)) { GST_ELEMENT_ERROR (mux, STREAM, FORMAT, ("Invalid data format presented"), ("Caps with type video/mpeg did not have mpegversion")); goto beach; } if (mpegversion == 1) { GST_DEBUG_OBJECT (pad, "Creating MPEG Video, version 1 stream with PID 0x%04x", ts_data->pid); ts_data->stream = tsmux_create_stream (mux->tsmux, TSMUX_ST_VIDEO_MPEG1, ts_data->pid); } else if (mpegversion == 2) { GST_DEBUG_OBJECT (pad, "Creating MPEG Video, version 2 stream with PID 0x%04x", ts_data->pid); ts_data->stream = tsmux_create_stream (mux->tsmux, TSMUX_ST_VIDEO_MPEG2, ts_data->pid); } else { GST_DEBUG_OBJECT (pad, "Creating MPEG Video, version 4 stream with PID 0x%04x", ts_data->pid); ts_data->stream = tsmux_create_stream (mux->tsmux, TSMUX_ST_VIDEO_MPEG4, ts_data->pid); } } if (ts_data->stream != NULL) { gst_structure_get_int (s, "rate", &ts_data->stream->audio_sampling); gst_structure_get_int (s, "channels", &ts_data->stream->audio_channels); gst_structure_get_int (s, "bitrate", &ts_data->stream->audio_bitrate); tsmux_stream_set_buffer_release_func (ts_data->stream, release_buffer_cb); tsmux_program_add_stream (ts_data->prog, ts_data->stream); ret = GST_FLOW_OK; } beach: gst_caps_unref (caps); return ret; }
static gboolean gst_vdp_h264_dec_set_sink_caps (GstBaseVideoDecoder * base_video_decoder, GstCaps * caps) { GstVdpH264Dec *h264_dec; GstStructure *structure; const GValue *value; h264_dec = GST_VDP_H264_DEC (base_video_decoder); structure = gst_caps_get_structure (caps, 0); /* packetized video has a codec_data */ if ((value = gst_structure_get_value (structure, "codec_data"))) { GstBuffer *buf; GstBitReader reader; guint8 version; guint8 n_sps, n_pps; gint i; GST_DEBUG_OBJECT (h264_dec, "have packetized h264"); h264_dec->packetized = TRUE; buf = gst_value_get_buffer (value); GST_MEMDUMP ("avcC:", GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf)); /* parse the avcC data */ if (GST_BUFFER_SIZE (buf) < 7) { GST_ERROR_OBJECT (h264_dec, "avcC size %u < 7", GST_BUFFER_SIZE (buf)); return FALSE; } gst_bit_reader_init_from_buffer (&reader, buf); READ_UINT8 (&reader, version, 8); if (version != 1) return FALSE; SKIP (&reader, 30); READ_UINT8 (&reader, h264_dec->nal_length_size, 2); h264_dec->nal_length_size += 1; GST_DEBUG_OBJECT (h264_dec, "nal length %u", h264_dec->nal_length_size); SKIP (&reader, 3); READ_UINT8 (&reader, n_sps, 5); for (i = 0; i < n_sps; i++) { guint16 sps_length; guint8 *data; READ_UINT16 (&reader, sps_length, 16); sps_length -= 1; SKIP (&reader, 8); data = GST_BUFFER_DATA (buf) + gst_bit_reader_get_pos (&reader) / 8; if (!gst_h264_parser_parse_sequence (h264_dec->parser, data, sps_length)) return FALSE; SKIP (&reader, sps_length * 8); } READ_UINT8 (&reader, n_pps, 8); for (i = 0; i < n_pps; i++) { guint16 pps_length; guint8 *data; READ_UINT16 (&reader, pps_length, 16); pps_length -= 1; SKIP (&reader, 8); data = GST_BUFFER_DATA (buf) + gst_bit_reader_get_pos (&reader) / 8; if (!gst_h264_parser_parse_picture (h264_dec->parser, data, pps_length)) return FALSE; SKIP (&reader, pps_length * 8); } } return TRUE; }
static gboolean gst_rtp_mp4g_pay_setcaps (GstBaseRTPPayload * payload, GstCaps * caps) { GstRtpMP4GPay *rtpmp4gpay; GstStructure *structure; const GValue *codec_data; const gchar *media_type = NULL; gboolean res; rtpmp4gpay = GST_RTP_MP4G_PAY (payload); structure = gst_caps_get_structure (caps, 0); codec_data = gst_structure_get_value (structure, "codec_data"); if (codec_data) { GST_LOG_OBJECT (rtpmp4gpay, "got codec_data"); if (G_VALUE_TYPE (codec_data) == GST_TYPE_BUFFER) { GstBuffer *buffer; const gchar *name; buffer = gst_value_get_buffer (codec_data); GST_LOG_OBJECT (rtpmp4gpay, "configuring codec_data"); name = gst_structure_get_name (structure); /* parse buffer */ if (!strcmp (name, "audio/mpeg")) { res = gst_rtp_mp4g_pay_parse_audio_config (rtpmp4gpay, buffer); media_type = "audio"; } else if (!strcmp (name, "video/mpeg")) { res = gst_rtp_mp4g_pay_parse_video_config (rtpmp4gpay, buffer); media_type = "video"; } else { res = FALSE; } if (!res) goto config_failed; /* now we can configure the buffer */ if (rtpmp4gpay->config) gst_buffer_unref (rtpmp4gpay->config); rtpmp4gpay->config = gst_buffer_copy (buffer); } } if (media_type == NULL) goto config_failed; gst_basertppayload_set_options (payload, media_type, TRUE, "MPEG4-GENERIC", rtpmp4gpay->rate); res = gst_rtp_mp4g_pay_new_caps (rtpmp4gpay); return res; /* ERRORS */ config_failed: { GST_DEBUG_OBJECT (rtpmp4gpay, "failed to parse config"); return FALSE; } }
/** * rb_gst_process_embedded_image: * @taglist: a #GstTagList containing an image * @tag: the tag name * * Converts embedded image data extracted from a tag list into * a #GdkPixbuf. The returned #GdkPixbuf is owned by the caller. * * Returns: a #GdkPixbuf, or NULL. */ GdkPixbuf * rb_gst_process_embedded_image (const GstTagList *taglist, const char *tag) { GstBuffer *buf; GdkPixbufLoader *loader; GdkPixbuf *pixbuf; GError *error = NULL; const GValue *val = NULL; guint i; for (i = 0; ; i++) { const GValue *value; const char *media_type; GstStructure *caps_struct; int imgtype; value = gst_tag_list_get_value_index (taglist, tag, i); if (value == NULL) { break; } buf = gst_value_get_buffer (value); if (buf == NULL) { rb_debug ("apparently couldn't get image buffer"); continue; } caps_struct = gst_caps_get_structure (buf->caps, 0); media_type = gst_structure_get_name (caps_struct); /* other things to ignore? */ if (g_strcmp0 (media_type, "text/uri-list") == 0) { rb_debug ("ignoring text/uri-list image tag"); continue; } gst_structure_get_enum (caps_struct, "image-type", GST_TYPE_TAG_IMAGE_TYPE, &imgtype); rb_debug ("image type %d", imgtype); if (imgtype == GST_TAG_IMAGE_TYPE_UNDEFINED) { if (val == NULL) { rb_debug ("got undefined image type"); val = value; } } else if (imgtype == GST_TAG_IMAGE_TYPE_FRONT_COVER) { rb_debug ("got front cover image"); val = value; } } if (val == NULL) { rb_debug ("couldn't find an image to process"); return NULL; } rb_debug ("found image at value %u for tag %s", i, tag); loader = gdk_pixbuf_loader_new (); buf = gst_value_get_buffer (val); rb_debug ("sending %d bytes to pixbuf loader", buf->size); if (gdk_pixbuf_loader_write (loader, buf->data, buf->size, &error) == FALSE) { rb_debug ("pixbuf loader doesn't like the data: %s", error->message); g_error_free (error); g_object_unref (loader); return NULL; } pixbuf = gdk_pixbuf_loader_get_pixbuf (loader); if (pixbuf != NULL) { g_object_ref (pixbuf); } gdk_pixbuf_loader_close (loader, NULL); g_object_unref (loader); if (pixbuf == NULL) { rb_debug ("pixbuf loader didn't give us a pixbuf"); return NULL; } rb_debug ("returning embedded image: %d x %d / %d", gdk_pixbuf_get_width (pixbuf), gdk_pixbuf_get_height (pixbuf), gdk_pixbuf_get_bits_per_sample (pixbuf)); return pixbuf; }
static GstBusSyncReply bus_callback (GstBus * bus, GstMessage * message, gpointer data) { const GstStructure *st; const GValue *image; GstBuffer *buf = NULL; guint8 *data_buf = NULL; gchar *caps_string; guint size = 0; gchar *preview_filename = NULL; FILE *f = NULL; size_t written; switch (GST_MESSAGE_TYPE (message)) { case GST_MESSAGE_ERROR:{ GError *err; gchar *debug; gst_message_parse_error (message, &err, &debug); g_print ("Error: %s\n", err->message); g_error_free (err); g_free (debug); /* Write debug graph to file */ GST_DEBUG_BIN_TO_DOT_FILE_WITH_TS (GST_BIN (camera_bin), GST_DEBUG_GRAPH_SHOW_ALL, "camerabin.error"); g_main_loop_quit (loop); break; } case GST_MESSAGE_STATE_CHANGED: if (GST_IS_BIN (GST_MESSAGE_SRC (message))) { GstState oldstate, newstate; gst_message_parse_state_changed (message, &oldstate, &newstate, NULL); GST_DEBUG_OBJECT (GST_MESSAGE_SRC (message), "state-changed: %s -> %s", gst_element_state_get_name (oldstate), gst_element_state_get_name (newstate)); } break; case GST_MESSAGE_EOS: /* end-of-stream */ GST_INFO ("got eos() - should not happen"); g_main_loop_quit (loop); break; default: st = gst_message_get_structure (message); if (st) { if (gst_structure_has_name (message->structure, "prepare-xwindow-id")) { if (window) { gst_x_overlay_set_xwindow_id (GST_X_OVERLAY (GST_MESSAGE_SRC (message)), window); gst_message_unref (message); message = NULL; return GST_BUS_DROP; } } else if (gst_structure_has_name (st, "image-captured")) { GST_DEBUG ("image-captured"); } else if (gst_structure_has_name (st, "preview-image")) { GST_DEBUG ("preview-image"); //extract preview-image from msg image = gst_structure_get_value (st, "buffer"); if (image) { buf = gst_value_get_buffer (image); data_buf = GST_BUFFER_DATA (buf); size = GST_BUFFER_SIZE (buf); preview_filename = g_strdup_printf ("test_vga.rgb"); caps_string = gst_caps_to_string (GST_BUFFER_CAPS (buf)); g_print ("writing buffer to %s, buffer caps: %s\n", preview_filename, caps_string); g_free (caps_string); f = g_fopen (preview_filename, "w"); if (f) { written = fwrite (data_buf, size, 1, f); if (!written) { g_print ("errro writing file\n"); } fclose (f); } else { g_print ("error opening file for raw image writing\n"); } g_free (preview_filename); } } } /* unhandled message */ break; } return GST_BUS_PASS; }