static void gst_overlay_loop (GstElement * element) { GstOverlay *overlay; GstBuffer *out; GstBuffer *in1 = NULL, *in2 = NULL, *in3 = NULL; int size; overlay = GST_OVERLAY (element); in1 = GST_BUFFER (gst_pad_pull (overlay->sinkpad1)); if (GST_IS_EVENT (in1)) { gst_pad_push (overlay->srcpad, GST_DATA (in1)); /* FIXME */ return; } in2 = GST_BUFFER (gst_pad_pull (overlay->sinkpad2)); if (GST_IS_EVENT (in2)) { gst_pad_push (overlay->srcpad, GST_DATA (in2)); /* FIXME */ return; } in3 = GST_BUFFER (gst_pad_pull (overlay->sinkpad3)); if (GST_IS_EVENT (in3)) { gst_pad_push (overlay->srcpad, GST_DATA (in3)); /* FIXME */ return; } g_return_if_fail (in1 != NULL); g_return_if_fail (in2 != NULL); g_return_if_fail (in3 != NULL); size = (overlay->width * overlay->height * 3) / 2; g_return_if_fail (GST_BUFFER_SIZE (in1) != size); g_return_if_fail (GST_BUFFER_SIZE (in2) != size); g_return_if_fail (GST_BUFFER_SIZE (in3) != size); out = gst_buffer_new_and_alloc (size); gst_overlay_blend_i420 (GST_BUFFER_DATA (out), GST_BUFFER_DATA (in1), GST_BUFFER_DATA (in2), GST_BUFFER_DATA (in3), overlay->width, overlay->height); GST_BUFFER_TIMESTAMP (out) = GST_BUFFER_TIMESTAMP (in1); GST_BUFFER_DURATION (out) = GST_BUFFER_DURATION (in1); gst_buffer_unref (in1); gst_buffer_unref (in2); gst_buffer_unref (in3); gst_pad_push (overlay->srcpad, GST_DATA (out)); }
/** GstXineInput ***********************************************************/ enum { ARG_0, ARG_LOCATION }; GST_BOILERPLATE (GstXineInput, gst_xine_input, GstXine, GST_TYPE_XINE); static void gst_xine_input_dispose (GObject * object); static void gst_xine_input_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec); static void gst_xine_input_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec); static GstStateChangeReturn gst_xine_input_change_state (GstElement * element, GstStateChange transition); static void gst_xine_input_base_init (gpointer g_class) { } static void gst_xine_input_class_init (GstXineInputClass * klass) { GstElementClass *element = GST_ELEMENT_CLASS (klass); GObjectClass *object = G_OBJECT_CLASS (klass); element->change_state = gst_xine_input_change_state; object->set_property = gst_xine_input_set_property; object->get_property = gst_xine_input_get_property; object->dispose = gst_xine_input_dispose; g_object_class_install_property (object, ARG_LOCATION, g_param_spec_string ("location", "location", "location", NULL, G_PARAM_READWRITE)); } static void gst_xine_input_init (GstXineInput * xine, GstXineInputClass * g_class) { } static void gst_xine_input_dispose (GObject * object) { GstXineInput *xine = GST_XINE_INPUT (object); g_free (xine->location); xine->location = NULL; GST_CALL_PARENT (G_OBJECT_CLASS, dispose, (object)); } static void gst_xine_input_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec) { GstXineInput *xine = GST_XINE_INPUT (object); switch (prop_id) { case ARG_LOCATION: if (gst_element_get_state (GST_ELEMENT (xine)) != GST_STATE_NULL) return; if (xine->location) g_free (xine->location); xine->location = g_strdup (g_value_get_string (value)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); return; } } static void gst_xine_input_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec) { GstXineInput *xine = GST_XINE_INPUT (object); switch (prop_id) { case ARG_LOCATION: g_value_set_string (value, xine->location); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); return; } } #define BUFFER_SIZE 4096 /* FIXME: what size? */ static GstData * gst_xine_input_get (GstPad * pad) { GstXineInput *xine = GST_XINE_INPUT (gst_object_get_parent (GST_OBJECT (pad))); GstBuffer *buf; gint real_size, position; /* FIXME: how does xine figure out EOS? */ position = xine->input->get_current_pos (xine->input); if (position > 0 && position == xine->input->get_length (xine->input)) { gst_element_set_eos (GST_ELEMENT (xine)); return GST_DATA (gst_event_new (GST_EVENT_EOS)); } buf = gst_pad_alloc_buffer_and_set_caps (xine->srcpad, GST_BUFFER_OFFSET_NONE, xine->blocksize); GST_BUFFER_OFFSET (buf) = position; real_size = xine->input->read (xine->input, GST_BUFFER_DATA (buf), GST_BUFFER_MAXSIZE (buf)); GST_BUFFER_SIZE (buf) = real_size; if (real_size < 0) { GST_ELEMENT_ERROR (xine, RESOURCE, READ, (NULL), ("error %d reading data", real_size)); gst_data_unref (GST_DATA (buf)); return NULL; } else if (real_size == 0) { buf_element_t *element; if (xine->input->get_capabilities (xine->input) & INPUT_CAP_BLOCK) element = xine->input->read_block (xine->input, gst_xine_get_stream (GST_XINE (xine))->audio_fifo, xine->blocksize); if (element == NULL) { /* FIXME: is this EOS? */ gst_element_set_eos (GST_ELEMENT (xine)); return GST_DATA (gst_event_new (GST_EVENT_EOS)); } else { GST_BUFFER_SIZE (buf) = element->size; /* FIXME: put buf_element_t data in buffer */ memcpy (GST_BUFFER_DATA (buf), element->mem, element->size); element->free_buffer (element); } } GST_BUFFER_OFFSET_END (buf) = xine->input->get_current_pos (xine->input); return GST_DATA (buf); }
static void gst_mikmod_loop (GstElement * element) { GstMikMod *mikmod; GstBuffer *buffer_in; g_return_if_fail (element != NULL); g_return_if_fail (GST_IS_MIKMOD (element)); mikmod = GST_MIKMOD (element); srcpad = mikmod->srcpad; mikmod->Buffer = NULL; if (!mikmod->initialized) { while ((buffer_in = GST_BUFFER (gst_pad_pull (mikmod->sinkpad)))) { if (GST_IS_EVENT (buffer_in)) { GstEvent *event = GST_EVENT (buffer_in); if (GST_EVENT_TYPE (event) == GST_EVENT_EOS) break; } else { if (mikmod->Buffer) { mikmod->Buffer = gst_buffer_append (mikmod->Buffer, buffer_in); } else { mikmod->Buffer = buffer_in; } } } if (!GST_PAD_CAPS (mikmod->srcpad)) { if (GST_PAD_LINK_SUCCESSFUL (gst_pad_renegotiate (mikmod->srcpad))) { GST_ELEMENT_ERROR (mikmod, CORE, NEGOTIATION, (NULL), (NULL)); return; } } MikMod_RegisterDriver (&drv_gst); MikMod_RegisterAllLoaders (); MikMod_Init (""); reader = GST_READER_new (mikmod); module = Player_LoadGeneric (reader, 64, 0); gst_buffer_unref (mikmod->Buffer); if (!Player_Active ()) Player_Start (module); mikmod->initialized = TRUE; } if (Player_Active ()) { timestamp = (module->sngtime / 1024.0) * GST_SECOND; drv_gst.Update (); } else { gst_element_set_eos (GST_ELEMENT (mikmod)); gst_pad_push (mikmod->srcpad, GST_DATA (gst_event_new (GST_EVENT_EOS))); } }
static void gst_tarkinenc_setup (TarkinEnc * tarkinenc) { gint i; GstBuffer *outbuf; ogg_stream_init (&tarkinenc->os, 1); tarkin_info_init (&tarkinenc->ti); tarkinenc->ti.inter.numerator = 1; tarkinenc->ti.inter.denominator = 1; tarkin_comment_init (&tarkinenc->tc); tarkin_comment_add_tag (&tarkinenc->tc, "TITLE", "GStreamer produced file"); tarkin_comment_add_tag (&tarkinenc->tc, "ARTIST", "C coders ;)"); tarkinenc->tarkin_stream = tarkin_stream_new (); tarkin_analysis_init (tarkinenc->tarkin_stream, &tarkinenc->ti, free_frame, packet_out, (void *) tarkinenc); tarkin_analysis_add_layer (tarkinenc->tarkin_stream, &tarkinenc->layer[0]); tarkin_analysis_headerout (tarkinenc->tarkin_stream, &tarkinenc->tc, tarkinenc->op, &tarkinenc->op[1], &tarkinenc->op[2]); for (i = 0; i < 3; i++) { ogg_stream_packetin (&tarkinenc->os, &tarkinenc->op[i]); } ogg_stream_flush (&tarkinenc->os, &tarkinenc->og); tarkinenc->frame_num = 0; outbuf = gst_buffer_new (); GST_BUFFER_DATA (outbuf) = tarkinenc->og.header; GST_BUFFER_SIZE (outbuf) = tarkinenc->og.header_len; GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_DONTFREE); gst_pad_push (tarkinenc->srcpad, GST_DATA (outbuf)); outbuf = gst_buffer_new (); GST_BUFFER_DATA (outbuf) = tarkinenc->og.body; GST_BUFFER_SIZE (outbuf) = tarkinenc->og.body_len; GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_DONTFREE); gst_pad_push (tarkinenc->srcpad, GST_DATA (outbuf)); tarkinenc->setup = TRUE; }
static void write_metadata (GstWavEnc * wavenc) { GString *info_str; GList *props; int total = 4; gboolean need_to_write = FALSE; info_str = g_string_new ("LIST INFO"); for (props = wavenc->metadata->properties->properties; props; props = props->next) { GstPropsEntry *entry = props->data; const char *name; guint32 id; name = gst_props_entry_get_name (entry); id = get_id_from_name (name); if (id != 0) { const char *text; char *tmp; int len, req, i; need_to_write = TRUE; /* We've got at least one entry */ gst_props_entry_get_string (entry, &text); len = strlen (text) + 1; /* The length in the file includes the \0 */ tmp = g_strdup_printf ("%" GST_FOURCC_FORMAT "%d%s", GST_FOURCC_ARGS (id), GUINT32_TO_LE (len), text); g_string_append (info_str, tmp); g_free (tmp); /* Check that we end on an even boundary */ req = ((len + 8) + 1) & ~1; for (i = 0; i < req - len; i++) { g_string_append_printf (info_str, "%c", 0); } total += req; } } if (need_to_write) { GstBuffer *buf; /* Now we've got all the strings together, we can write our length in */ info_str->str[4] = GUINT32_TO_LE (total); buf = gst_buffer_new (); gst_buffer_set_data (buf, info_str->str, info_str->len); gst_pad_push (wavenc->srcpad, GST_DATA (buf)); g_string_free (info_str, FALSE); } }
static void gst_xine_audio_sink_chain (GstPad * pad, GstData * data) { GstXineAudioSink *xine = GST_XINE_AUDIO_SINK (gst_object_get_parent (GST_OBJECT (pad))); while (xine->driver->write (xine->driver, (guint16 *) GST_BUFFER_DATA (data), GST_BUFFER_SIZE (data) / xine->open) == 0); gst_data_unref (GST_DATA (data)); }
static void gst_rfc2250_enc_new_buffer (GstRFC2250Enc * enc) { if (enc->packet) { gst_pad_push (enc->srcpad, GST_DATA (enc->packet)); } enc->packet = gst_buffer_new (); enc->flags = 0; enc->remaining = enc->MTU; }
static GstData * gst_v4ljpegsrc_get (GstPad * pad) { GstV4lJpegSrc *v4ljpegsrc; GstV4lSrc *v4lsrc; GstData *data; GstBuffer *buf; GstBuffer *outbuf; int jpeg_size; g_return_val_if_fail (pad != NULL, NULL); v4ljpegsrc = GST_V4LJPEGSRC (gst_pad_get_parent (pad)); v4lsrc = GST_V4LSRC (v4ljpegsrc); /* Fetch from the v4lsrc class get fn. */ data = v4ljpegsrc->getfn (pad); /* If not a buffer, return it unchanged */ if (!data || (!GST_IS_BUFFER (data))) return data; buf = GST_BUFFER (data); /* Confirm that the buffer contains jpeg data */ /* * Create a new subbuffer from the jpeg data * The first 2 bytes in the buffer are the size of the jpeg data */ if (GST_BUFFER_SIZE (buf) > 2) { jpeg_size = (int) (GST_READ_UINT16_LE (GST_BUFFER_DATA (buf))) * 8; } else jpeg_size = 0; /* Check that the size is sensible */ if ((jpeg_size <= 0) || (jpeg_size > GST_BUFFER_SIZE (buf) - 2)) { GST_ELEMENT_ERROR (v4ljpegsrc, STREAM, FORMAT, (NULL), ("Invalid non-jpeg frame from camera")); return NULL; } GST_DEBUG_OBJECT (v4ljpegsrc, "Creating JPEG subbuffer of size %d", jpeg_size); outbuf = gst_buffer_create_sub (buf, 2, jpeg_size); /* Copy timestamps onto the subbuffer */ gst_buffer_stamp (outbuf, buf); /* Release the main buffer */ gst_buffer_unref (buf); return GST_DATA (outbuf); }
static void write_cues (GstWavEnc * wavenc) { GString *cue_string, *point_string; GstBuffer *buf; GList *cue_list, *c; int num_cues, total = 4; if (gst_props_get (wavenc->metadata->properties, "cues", &cue_list, NULL) == FALSE) { /* No cues, move along please, nothing to see here */ return; } /* Space for 'cue ', chunk size and number of cuepoints */ cue_string = g_string_new ("cue "); #define CUEPOINT_SIZE 24 point_string = g_string_sized_new (CUEPOINT_SIZE); for (c = cue_list, num_cues = 0; c; c = c->next, num_cues++) { GstCaps *cue_caps = c->data; guint32 pos; gst_props_get (cue_caps->properties, "position", &pos, NULL); point_string->str[0] = GUINT32_TO_LE (num_cues + 1); point_string->str[4] = GUINT32_TO_LE (0); /* Fixme: There is probably a macro for this */ point_string->str[8] = 'd'; point_string->str[9] = 'a'; point_string->str[10] = 't'; point_string->str[11] = 'a'; point_string->str[12] = GUINT32_TO_LE (0); point_string->str[16] = GUINT32_TO_LE (0); point_string->str[20] = GUINT32_TO_LE (pos); total += CUEPOINT_SIZE; } /* Set the length and chunk size */ cue_string->str[4] = GUINT32_TO_LE (total); cue_string->str[8] = GUINT32_TO_LE (num_cues); /* Stick the cue points on the end */ g_string_append (cue_string, point_string->str); g_string_free (point_string, TRUE); buf = gst_buffer_new (); gst_buffer_set_data (buf, cue_string->str, cue_string->len); gst_pad_push (wavenc->srcpad, GST_DATA (buf)); g_string_free (cue_string, FALSE); }
TarkinError packet_out (void *stream, ogg_packet * op) { ogg_page og; TarkinStream *s = stream; TarkinEnc *te = s->user_ptr; GstBuffer *outbuf; ogg_stream_packetin (&te->os, op); if (op->e_o_s) { ogg_stream_flush (&te->os, &og); outbuf = gst_buffer_new (); GST_BUFFER_DATA (outbuf) = og.header; GST_BUFFER_SIZE (outbuf) = og.header_len; GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_DONTFREE); gst_pad_push (te->srcpad, GST_DATA (outbuf)); outbuf = gst_buffer_new (); GST_BUFFER_DATA (outbuf) = og.body; GST_BUFFER_SIZE (outbuf) = og.body_len; GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_DONTFREE); gst_pad_push (te->srcpad, GST_DATA (outbuf)); } else { while (ogg_stream_pageout (&te->os, &og)) { outbuf = gst_buffer_new (); GST_BUFFER_DATA (outbuf) = og.header; GST_BUFFER_SIZE (outbuf) = og.header_len; GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_DONTFREE); gst_pad_push (te->srcpad, GST_DATA (outbuf)); outbuf = gst_buffer_new (); GST_BUFFER_DATA (outbuf) = og.body; GST_BUFFER_SIZE (outbuf) = og.body_len; GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_DONTFREE); gst_pad_push (te->srcpad, GST_DATA (outbuf)); } } return (TARKIN_OK); }
void gst_vbidec_show_text (GstVBIDec * vbidec, char *text, int len) { //fprintf(stderr, "%*s\n", len, text); if (len > 0) { if (GST_PAD_IS_USABLE (vbidec->srcpad)) { GstBuffer *buf = gst_buffer_new_and_alloc (len); memcpy (GST_BUFFER_DATA (buf), text, len); GST_BUFFER_SIZE (buf) = len; // FIXME //GST_BUFFER_TIMESTAMP (buf) = vbidec->... //... //fprintf(stderr, "vbi text pushed\n"); gst_pad_push (vbidec->srcpad, GST_DATA (buf)); } } }
static void gst_rtjpegdec_chain (GstPad * pad, GstData * _data) { GstBuffer *buf = GST_BUFFER (_data); GstRTJpegDec *rtjpegdec; guchar *data; gulong size; g_return_if_fail (pad != NULL); g_return_if_fail (GST_IS_PAD (pad)); g_return_if_fail (buf != NULL); rtjpegdec = GST_RTJPEGDEC (GST_OBJECT_PARENT (pad)); data = GST_BUFFER_DATA (buf); size = GST_BUFFER_SIZE (buf); g_warning ("would be encoding frame here\n"); gst_pad_push (rtjpegdec->srcpad, GST_DATA (buf)); }
static void gst_hermes_colorspace_chain (GstPad * pad, GstData * _data) { GstBuffer *buf = GST_BUFFER (_data); GstHermesColorspace *space; GstBuffer *outbuf = NULL; g_return_if_fail (pad != NULL); g_return_if_fail (GST_IS_PAD (pad)); g_return_if_fail (buf != NULL); space = GST_HERMES_COLORSPACE (gst_pad_get_parent (pad)); g_return_if_fail (space != NULL); g_return_if_fail (GST_IS_COLORSPACE (space)); if (space->passthru) { gst_pad_push (space->srcpad, _data); return; } if (GST_BUFFER_SIZE (buf) < space->sink_size) { g_critical ("input size is smaller than expected"); } outbuf = gst_pad_alloc_buffer_and_set_caps (space->srcpad, GST_BUFFER_OFFSET_NONE, space->src_size); Hermes_ConverterCopy (space->h_handle, GST_BUFFER_DATA (buf), 0, 0, space->width, space->height, space->sink_stride, GST_BUFFER_DATA (outbuf), 0, 0, space->width, space->height, space->src_stride); GST_BUFFER_TIMESTAMP (outbuf) = GST_BUFFER_TIMESTAMP (buf); GST_BUFFER_DURATION (outbuf) = GST_BUFFER_DURATION (buf); gst_buffer_unref (buf); gst_pad_push (space->srcpad, GST_DATA (outbuf)); }
static void gst_rfc2250_enc_loop (GstElement * element) { GstRFC2250Enc *enc = GST_RFC2250_ENC (element); GstData *data; guint id; gboolean mpeg2; data = gst_mpeg_packetize_read (enc->packetize); id = GST_MPEG_PACKETIZE_ID (enc->packetize); mpeg2 = GST_MPEG_PACKETIZE_IS_MPEG2 (enc->packetize); if (GST_IS_BUFFER (data)) { GstBuffer *buffer = GST_BUFFER (data); GST_DEBUG ("rfc2250enc: have chunk 0x%02X", id); switch (id) { case SEQUENCE_START_CODE: gst_rfc2250_enc_new_buffer (enc); enc->flags |= ENC_HAVE_SEQ; break; case GOP_START_CODE: if (enc->flags & ENC_HAVE_DATA) { gst_rfc2250_enc_new_buffer (enc); } enc->flags |= ENC_HAVE_GOP; break; case PICTURE_START_CODE: if (enc->flags & ENC_HAVE_DATA) { gst_rfc2250_enc_new_buffer (enc); } enc->flags |= ENC_HAVE_PIC; break; case EXT_START_CODE: case USER_START_CODE: case SEQUENCE_ERROR_START_CODE: case SEQUENCE_END_START_CODE: break; default: /* do this here because of the long range */ if (id >= SLICE_MIN_START_CODE && id <= SLICE_MAX_START_CODE) { enc->flags |= ENC_HAVE_DATA; gst_rfc2250_enc_add_slice (enc, buffer); buffer = NULL; break; } break; } if (buffer) { gst_buffer_merge (enc->packet, buffer); enc->remaining -= GST_BUFFER_SIZE (buffer); gst_buffer_unref (buffer); } } else { if (enc->packet) { gst_pad_push (enc->srcpad, GST_DATA (enc->packet)); enc->packet = NULL; enc->flags = 0; enc->remaining = enc->MTU; } gst_pad_event_default (enc->sinkpad, GST_EVENT (data)); } }
static void gst_median_chain (GstPad * pad, GstData * _data) { GstBuffer *buf = GST_BUFFER (_data); GstMedian *median; guchar *data; gulong size; GstBuffer *outbuf; /* GstMeta *meta; */ int lumsize, chromsize; g_return_if_fail (pad != NULL); g_return_if_fail (GST_IS_PAD (pad)); g_return_if_fail (buf != NULL); median = GST_MEDIAN (GST_OBJECT_PARENT (pad)); if (!median->active) { gst_pad_push (median->srcpad, GST_DATA (buf)); return; } data = GST_BUFFER_DATA (buf); size = GST_BUFFER_SIZE (buf); GST_DEBUG ("median: have buffer of %d", GST_BUFFER_SIZE (buf)); outbuf = gst_buffer_new (); GST_BUFFER_DATA (outbuf) = g_malloc (GST_BUFFER_SIZE (buf)); GST_BUFFER_SIZE (outbuf) = GST_BUFFER_SIZE (buf); lumsize = median->width * median->height; chromsize = lumsize / 4; if (median->filtersize == 5) { median_5 (data, GST_BUFFER_DATA (outbuf), median->width, median->height); if (!median->lum_only) { median_5 (data + lumsize, GST_BUFFER_DATA (outbuf) + lumsize, median->width / 2, median->height / 2); median_5 (data + lumsize + chromsize, GST_BUFFER_DATA (outbuf) + lumsize + chromsize, median->width / 2, median->height / 2); } else { memcpy (GST_BUFFER_DATA (outbuf) + lumsize, data + lumsize, chromsize * 2); } } else { median_9 (data, GST_BUFFER_DATA (outbuf), median->width, median->height); if (!median->lum_only) { median_9 (data + lumsize, GST_BUFFER_DATA (outbuf) + lumsize, median->width / 2, median->height / 2); median_9 (data + lumsize + chromsize, GST_BUFFER_DATA (outbuf) + lumsize + chromsize, median->width / 2, median->height / 2); } else { memcpy (GST_BUFFER_DATA (outbuf) + lumsize, data + lumsize, chromsize * 2); } } GST_BUFFER_TIMESTAMP (outbuf) = GST_BUFFER_TIMESTAMP (buf); gst_buffer_unref (buf); gst_pad_push (median->srcpad, GST_DATA (outbuf)); }
static void gst_videodrop_chain (GstPad * pad, GstData * data) { GstVideodrop *videodrop = GST_VIDEODROP (gst_pad_get_parent (pad)); GstBuffer *buf; if (GST_IS_EVENT (data)) { GstEvent *event = GST_EVENT (data); if (GST_EVENT_TYPE (event) == GST_EVENT_DISCONTINUOUS) { /* since we rely on timestamps of the source, we need to handle * changes in time carefully. */ gint64 time; if (gst_event_discont_get_value (event, GST_FORMAT_TIME, &time)) { videodrop->total = videodrop->pass = 0; videodrop->time_adjust = time; } else { GST_ELEMENT_ERROR (videodrop, STREAM, TOO_LAZY, (NULL), ("Received discont, but no time information")); gst_event_unref (event); return; } /* FIXME: increase timestamp / speed */ } gst_pad_event_default (pad, event); return; } buf = GST_BUFFER (data); videodrop->total++; GST_DEBUG ("Received buffer at %u:%02u:%02u:%09u, fps=%lf, pass=%" G_GUINT64_FORMAT " of " G_GUINT64_FORMAT ", speed=%lf", (guint) (GST_BUFFER_TIMESTAMP (buf) / (GST_SECOND * 60 * 60)), (guint) ((GST_BUFFER_TIMESTAMP (buf) / (GST_SECOND * 60)) % 60), (guint) ((GST_BUFFER_TIMESTAMP (buf) / GST_SECOND) % 60), (guint) (GST_BUFFER_TIMESTAMP (buf) % GST_SECOND), videodrop->to_fps, videodrop->total, videodrop->pass, videodrop->speed); while (((GST_BUFFER_TIMESTAMP (buf) - videodrop->time_adjust) / videodrop->speed * videodrop->to_fps / GST_SECOND) >= videodrop->pass) { /* since we write to the struct (time/duration), we need a new struct, * but we don't want to copy around data - a subbuffer is the easiest * way to accomplish that... */ GstBuffer *copy = gst_buffer_create_sub (buf, 0, GST_BUFFER_SIZE (buf)); /* adjust timestamp/duration and push forward */ GST_BUFFER_TIMESTAMP (copy) = (videodrop->time_adjust / videodrop->speed) + GST_SECOND * videodrop->pass / videodrop->to_fps; GST_BUFFER_DURATION (copy) = GST_SECOND / videodrop->to_fps; GST_DEBUG ("Sending out buffer from out %u:%02u:%02u:%09u", (guint) (GST_BUFFER_TIMESTAMP (copy) / (GST_SECOND * 60 * 60)), (guint) ((GST_BUFFER_TIMESTAMP (copy) / (GST_SECOND * 60)) % 60), (guint) ((GST_BUFFER_TIMESTAMP (copy) / GST_SECOND) % 60), (guint) (GST_BUFFER_TIMESTAMP (copy) % GST_SECOND)); gst_pad_push (videodrop->srcpad, GST_DATA (copy)); videodrop->pass++; } gst_buffer_unref (buf); }
static void write_labels (GstWavEnc * wavenc) { GstBuffer *buf; GString *info_str; int total = 4; GList *caps; info_str = g_string_new ("LIST adtl"); if (gst_props_get (wavenc->metadata->properties, "ltxts", &caps, NULL)) { GList *p; int i; for (p = caps, i = 1; p; p = p->next, i++) { GstCaps *ltxt_caps = p->data; GString *ltxt; char *label = NULL; int len, req, j; gst_props_get (ltxt_caps->properties, "name", &label, NULL); len = strlen (label); #define LTXT_SIZE 28 ltxt = g_string_new ("ltxt "); ltxt->str[8] = GUINT32_TO_LE (i); /* Identifier */ ltxt->str[12] = GUINT32_TO_LE (0); /* Sample Length */ ltxt->str[16] = GUINT32_TO_LE (0); /* FIXME: Don't save the purpose yet */ ltxt->str[20] = GUINT16_TO_LE (0); /* Country */ ltxt->str[22] = GUINT16_TO_LE (0); /* Language */ ltxt->str[24] = GUINT16_TO_LE (0); /* Dialect */ ltxt->str[26] = GUINT16_TO_LE (0); /* Code Page */ g_string_append (ltxt, label); g_free (label); len += LTXT_SIZE; ltxt->str[4] = GUINT32_TO_LE (len); /* Check that we end on an even boundary */ req = ((len + 8) + 1) & ~1; for (j = 0; j < req - len; j++) { g_string_append_printf (ltxt, "%c", 0); } total += req; g_string_append (info_str, ltxt->str); g_string_free (ltxt, TRUE); } } if (gst_props_get (wavenc->metadata->properties, "labels", &caps, NULL)) { GList *p; int i; for (p = caps, i = 1; p; p = p->next, i++) { GstCaps *labl_caps = p->data; GString *labl; char *label = NULL; int len, req, j; gst_props_get (labl_caps->properties, "name", &label, NULL); len = strlen (label); #define LABL_SIZE 4 labl = g_string_new ("labl "); labl->str[8] = GUINT32_TO_LE (i); g_string_append (labl, label); g_free (label); len += LABL_SIZE; labl->str[4] = GUINT32_TO_LE (len); /* Check our size */ req = ((len + 8) + 1) & ~1; for (j = 0; j < req - len; j++) { g_string_append_printf (labl, "%c", 0); } total += req; g_string_append (info_str, labl->str); g_string_free (labl, TRUE); } } if (gst_props_get (wavenc->metadata->properties, "notes", &caps, NULL)) { GList *p; int i; for (p = caps, i = 1; p; p = p->next, i++) { GstCaps *note_caps = p->data; GString *note; char *label = NULL; int len, req, j; gst_props_get (note_caps->properties, "name", &label, NULL); len = strlen (label); #define NOTE_SIZE 4 note = g_string_new ("note "); note->str[8] = GUINT32_TO_LE (i); g_string_append (note, label); g_free (label); len += NOTE_SIZE; note->str[4] = GUINT32_TO_LE (len); /* Size check */ req = ((len + 8) + 1) & ~1; for (j = 0; j < req - len; j++) { g_string_append_printf (note, "%c", 0); } total += req; g_string_append (info_str, note->str); g_string_free (note, TRUE); } } info_str->str[4] = GUINT32_TO_LE (total); buf = gst_buffer_new (); gst_buffer_set_data (buf, info_str->str, info_str->len); gst_pad_push (wavenc->srcpad, GST_DATA (buf)); g_string_free (info_str, FALSE); }
static void gst_tarkindec_chain (GstPad * pad, GstData * _data) { GstBuffer *buf = GST_BUFFER (_data); TarkinDec *tarkindec; g_return_if_fail (pad != NULL); g_return_if_fail (GST_IS_PAD (pad)); g_return_if_fail (buf != NULL); tarkindec = GST_TARKINDEC (gst_pad_get_parent (pad)); if (!tarkindec->setup) { GST_ELEMENT_ERROR (tarkindec, CORE, NEGOTATION, (NULL), ("decoder not initialized (input is not tarkin?)")); if (GST_IS_BUFFER (buf)) gst_buffer_unref (buf); else gst_pad_event_default (pad, GST_EVENT (buf)); return; } if (GST_IS_EVENT (buf)) { switch (GST_EVENT_TYPE (buf)) { case GST_EVENT_EOS: default: gst_pad_event_default (pad, GST_EVENT (buf)); break; } } else { gchar *data; gulong size; gchar *buffer; guchar *rgb; TarkinTime date; TarkinVideoLayerDesc *layer; /* data to decode */ data = GST_BUFFER_DATA (buf); size = GST_BUFFER_SIZE (buf); buffer = ogg_sync_buffer (&tarkindec->oy, size); memcpy (buffer, data, size); ogg_sync_wrote (&tarkindec->oy, size); if (ogg_sync_pageout (&tarkindec->oy, &tarkindec->og)) { ogg_stream_pagein (&tarkindec->os, &tarkindec->og); while (ogg_stream_packetout (&tarkindec->os, &tarkindec->op)) { if (tarkindec->op.e_o_s) break; if (tarkindec->nheader < 3) { /* 3 first packets to headerin */ tarkin_synthesis_headerin (&tarkindec->ti, &tarkindec->tc, &tarkindec->op); if (tarkindec->nheader == 2) { tarkin_synthesis_init (tarkindec->tarkin_stream, &tarkindec->ti); } tarkindec->nheader++; } else { tarkin_synthesis_packetin (tarkindec->tarkin_stream, &tarkindec->op); while (tarkin_synthesis_frameout (tarkindec->tarkin_stream, &rgb, 0, &date) == 0) { GstBuffer *outbuf; layer = &tarkindec->tarkin_stream->layer->desc; if (!GST_PAD_CAPS (tarkindec->srcpad)) { if (gst_pad_try_set_caps (tarkindec->srcpad, GST_CAPS_NEW ("tarkin_raw", "video/x-raw-rgb", "bpp", GST_PROPS_INT (24), "depth", GST_PROPS_INT (24), "endianness", GST_PROPS_INT (G_BYTE_ORDER), "red_mask", GST_PROPS_INT (0xff0000), "green_mask", GST_PROPS_INT (0xff00), "blue_mask", GST_PROPS_INT (0xff), "width", GST_PROPS_INT (layer->width), "height", GST_PROPS_INT (layer->height), "framerate", GST_PROPS_FLOAT (0.) /* FIXME!!! */ )) <= 0) { GST_ELEMENT_ERROR (tarkindec, CORE, NEGOTATION, (NULL), ("could not output format")); gst_buffer_unref (buf); return; } } outbuf = gst_buffer_new (); GST_BUFFER_DATA (outbuf) = rgb; GST_BUFFER_SIZE (outbuf) = layer->width * layer->height * 3; GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_DONTFREE); gst_pad_push (tarkindec->srcpad, GST_DATA (outbuf)); tarkin_synthesis_freeframe (tarkindec->tarkin_stream, rgb); } } } } gst_buffer_unref (buf); } }
static void gst_fameenc_chain (GstPad * pad, GstData * _data) { GstBuffer *buf = GST_BUFFER (_data); GstFameEnc *fameenc; guchar *data; gulong size; gint frame_size; gint length; g_return_if_fail (pad != NULL); g_return_if_fail (GST_IS_PAD (pad)); g_return_if_fail (buf != NULL); g_return_if_fail (GST_IS_BUFFER (buf)); fameenc = GST_FAMEENC (gst_pad_get_parent (pad)); data = (guchar *) GST_BUFFER_DATA (buf); size = GST_BUFFER_SIZE (buf); GST_DEBUG ("gst_fameenc_chain: got buffer of %ld bytes in '%s'", size, GST_OBJECT_NAME (fameenc)); /* the data contains the three planes side by side, with size w * h, w * h /4, * w * h / 4 */ fameenc->fy.w = fameenc->fp.width; fameenc->fy.h = fameenc->fp.height; frame_size = fameenc->fp.width * fameenc->fp.height; fameenc->fy.p = 0; fameenc->fy.y = data; fameenc->fy.u = data + frame_size; fameenc->fy.v = fameenc->fy.u + (frame_size >> 2); fame_start_frame (fameenc->fc, &fameenc->fy, NULL); while ((length = fame_encode_slice (fameenc->fc)) != 0) { GstBuffer *outbuf; outbuf = gst_buffer_new (); /* FIXME: safeguard, remove me when a better way is found */ if (length > FAMEENC_BUFFER_SIZE) g_warning ("FAMEENC_BUFFER_SIZE is defined too low, encoded slice has size %d !\n", length); if (!fameenc->time_interval) { fameenc->time_interval = GST_SECOND * fameenc->fp.frame_rate_den / fameenc->fp.frame_rate_num; } fameenc->next_time += fameenc->time_interval; GST_BUFFER_SIZE (outbuf) = length; GST_BUFFER_TIMESTAMP (outbuf) = fameenc->next_time; GST_BUFFER_DATA (outbuf) = g_malloc (length); memcpy (GST_BUFFER_DATA (outbuf), fameenc->buffer, length); GST_BUFFER_TIMESTAMP (outbuf) = GST_BUFFER_TIMESTAMP (buf); GST_DEBUG ("gst_fameenc_chain: pushing buffer of size %d", GST_BUFFER_SIZE (outbuf)); gst_pad_push (fameenc->srcpad, GST_DATA (outbuf)); } fame_end_frame (fameenc->fc, NULL); gst_buffer_unref (buf); }
static void gst_snapshot_chain (GstPad * pad, GstData * _data) { GstBuffer *buf = GST_BUFFER (_data); GstSnapshot *snapshot; guchar *data; gulong size; gint i; png_byte *row_pointers[MAX_HEIGHT]; FILE *fp; g_return_if_fail (pad != NULL); g_return_if_fail (GST_IS_PAD (pad)); g_return_if_fail (buf != NULL); snapshot = GST_SNAPSHOT (GST_OBJECT_PARENT (pad)); data = GST_BUFFER_DATA (buf); size = GST_BUFFER_SIZE (buf); GST_DEBUG ("snapshot: have buffer of %d\n", GST_BUFFER_SIZE (buf)); snapshot->cur_frame++; if (snapshot->cur_frame == snapshot->frame || snapshot->snapshot_asked == TRUE) { snapshot->snapshot_asked = FALSE; GST_INFO ("dumpfile : %s\n", snapshot->location); fp = fopen (snapshot->location, "wb"); if (fp == NULL) g_warning (" Can not open %s\n", snapshot->location); else { snapshot->png_struct_ptr = png_create_write_struct (PNG_LIBPNG_VER_STRING, (png_voidp) NULL, user_error_fn, user_warning_fn); if (snapshot->png_struct_ptr == NULL) g_warning ("Failed to initialize png structure"); snapshot->png_info_ptr = png_create_info_struct (snapshot->png_struct_ptr); if (setjmp (snapshot->png_struct_ptr->jmpbuf)) png_destroy_write_struct (&snapshot->png_struct_ptr, &snapshot->png_info_ptr); png_set_filter (snapshot->png_struct_ptr, 0, PNG_FILTER_NONE | PNG_FILTER_VALUE_NONE); png_init_io (snapshot->png_struct_ptr, fp); png_set_compression_level (snapshot->png_struct_ptr, 9); png_set_IHDR (snapshot->png_struct_ptr, snapshot->png_info_ptr, snapshot->width, snapshot->height, snapshot->to_bpp / 3, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); for (i = 0; i < snapshot->height; i++) row_pointers[i] = data + (snapshot->width * i * snapshot->to_bpp / 8); png_write_info (snapshot->png_struct_ptr, snapshot->png_info_ptr); png_write_image (snapshot->png_struct_ptr, row_pointers); png_write_end (snapshot->png_struct_ptr, NULL); png_destroy_info_struct (snapshot->png_struct_ptr, &snapshot->png_info_ptr); png_destroy_write_struct (&snapshot->png_struct_ptr, (png_infopp) NULL); fclose (fp); } } gst_pad_push (snapshot->srcpad, GST_DATA (buf)); }
static void gst_chart_chain (GstPad * pad, GstData * _data) { GstBuffer *bufin = GST_BUFFER (_data); GstChart *chart; GstBuffer *bufout; guint32 samples_in; guint32 sizeout; gint16 *datain; guchar *dataout; g_return_if_fail (bufin != NULL); g_return_if_fail (pad != NULL); g_return_if_fail (GST_IS_PAD (pad)); g_return_if_fail (GST_IS_CHART (GST_OBJECT_PARENT (pad))); chart = GST_CHART (GST_OBJECT_PARENT (pad)); g_return_if_fail (chart != NULL); GST_DEBUG ("CHART: chainfunc called"); samples_in = GST_BUFFER_SIZE (bufin) / sizeof (gint16); datain = (gint16 *) (GST_BUFFER_DATA (bufin)); GST_DEBUG ("input buffer has %d samples", samples_in); if (chart->next_time <= GST_BUFFER_TIMESTAMP (bufin)) { chart->next_time = GST_BUFFER_TIMESTAMP (bufin); GST_DEBUG ("in: %" G_GINT64_FORMAT, GST_BUFFER_TIMESTAMP (bufin)); } chart->samples_since_last_frame += samples_in; if (chart->samples_between_frames <= chart->samples_since_last_frame) { chart->samples_since_last_frame = 0; /* get data to draw into buffer */ if (samples_in >= chart->width) { /* make a new buffer for the output */ bufout = gst_buffer_new (); sizeout = chart->bpp / 8 * chart->width * chart->height; dataout = g_malloc (sizeout); GST_BUFFER_SIZE (bufout) = sizeout; GST_BUFFER_DATA (bufout) = dataout; GST_DEBUG ("CHART: made new buffer: size %d, width %d, height %d", sizeout, chart->width, chart->height); /* take data and draw to new buffer */ /* FIXME: call different routines for different properties */ draw_chart_16bpp (dataout, chart->width, chart->height, (gint16 *) datain, samples_in); gst_buffer_unref (bufin); /* set timestamp */ GST_BUFFER_TIMESTAMP (bufout) = chart->next_time; GST_DEBUG ("CHART: outputting buffer"); /* output buffer */ GST_BUFFER_FLAG_SET (bufout, GST_BUFFER_READONLY); gst_pad_push (chart->srcpad, GST_DATA (bufout)); } } else { GST_DEBUG ("CHART: skipping buffer"); gst_buffer_unref (bufin); } GST_DEBUG ("CHART: exiting chainfunc"); }