static void setup (void) { GstTagSetter *setter; gchar *desc_str; GstCaps *filter_caps; GstBus *bus; gint i; GST_INFO ("init"); main_loop = g_main_loop_new (NULL, TRUE); camera = gst_check_setup_element ("camerabin"); setup_camerabin_elements (camera); g_signal_connect (camera, "image-done", G_CALLBACK (capture_done), main_loop); bus = gst_pipeline_get_bus (GST_PIPELINE (camera)); gst_bus_add_watch (bus, (GstBusFunc) capture_bus_cb, main_loop); gst_bus_set_sync_handler (bus, bus_sync_callback, main_loop); gst_object_unref (bus); filter_caps = gst_caps_from_string ("video/x-raw-yuv,format=(fourcc)I420"); g_object_set (G_OBJECT (camera), "filter-caps", filter_caps, NULL); gst_caps_unref (filter_caps); /* force a low framerate here to not timeout the tests because of the * encoders */ g_signal_emit_by_name (camera, "set-video-resolution-fps", 320, 240, 5, 1, NULL); /* Set some default tags */ setter = GST_TAG_SETTER (camera); desc_str = g_strdup_printf ("Created by %s", g_get_real_name ()); gst_tag_setter_add_tags (setter, GST_TAG_MERGE_REPLACE, GST_TAG_DESCRIPTION, desc_str, NULL); g_free (desc_str); if (gst_element_set_state (GST_ELEMENT (camera), GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE) { GST_WARNING ("setting camerabin to PLAYING failed"); gst_element_set_state (GST_ELEMENT (camera), GST_STATE_NULL); gst_object_unref (camera); camera = NULL; } /* create the taglists */ for (i = 0; i < TAGLISTS_COUNT; i++) { taglists[i] = gst_tag_list_new_full (GST_TAG_ARTIST, "test-artist", GST_TAG_GEO_LOCATION_LONGITUDE, g_random_double_range (-180, 180), GST_TAG_GEO_LOCATION_LATITUDE, g_random_double_range (-90, 90), GST_TAG_GEO_LOCATION_ELEVATION, g_random_double_range (0, 3000), NULL); } GST_INFO ("init finished"); }
static GstFlowReturn gst_multipart_demux_chain (GstPad * pad, GstBuffer * buf) { GstMultipartDemux *multipart; GstAdapter *adapter; GstClockTime timestamp; gint size = 1; GstFlowReturn res; multipart = GST_MULTIPART_DEMUX (gst_pad_get_parent (pad)); adapter = multipart->adapter; res = GST_FLOW_OK; timestamp = GST_BUFFER_TIMESTAMP (buf); if (GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_DISCONT)) { gst_adapter_clear (adapter); } gst_adapter_push (adapter, buf); while (gst_adapter_available (adapter) > 0) { GstMultipartPad *srcpad; GstBuffer *outbuf; gboolean created; gint datalen; if (G_UNLIKELY (!multipart->header_completed)) { if ((size = multipart_parse_header (multipart)) < 0) { goto nodata; } else { gst_adapter_flush (adapter, size); multipart->header_completed = TRUE; } } if ((size = multipart_find_boundary (multipart, &datalen)) < 0) { goto nodata; } /* Invalidate header info */ multipart->header_completed = FALSE; multipart->content_length = -1; if (G_UNLIKELY (datalen <= 0)) { GST_DEBUG_OBJECT (multipart, "skipping empty content."); gst_adapter_flush (adapter, size - datalen); } else { srcpad = gst_multipart_find_pad_by_mime (multipart, multipart->mime_type, &created); outbuf = gst_adapter_take_buffer (adapter, datalen); gst_adapter_flush (adapter, size - datalen); gst_buffer_set_caps (outbuf, GST_PAD_CAPS (srcpad->pad)); if (created) { GstTagList *tags; /* Push new segment, first buffer has 0 timestamp */ gst_pad_push_event (srcpad->pad, gst_event_new_new_segment (FALSE, 1.0, GST_FORMAT_TIME, 0, -1, 0)); tags = gst_tag_list_new_full (GST_TAG_CONTAINER_FORMAT, "Multipart", NULL); gst_pad_push_event (srcpad->pad, gst_event_new_tag (tags)); GST_BUFFER_TIMESTAMP (outbuf) = 0; } else { GST_BUFFER_TIMESTAMP (outbuf) = timestamp; } GST_DEBUG_OBJECT (multipart, "pushing buffer with timestamp %" GST_TIME_FORMAT, GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (outbuf))); GST_DEBUG_OBJECT (multipart, "buffer has caps %" GST_PTR_FORMAT, GST_BUFFER_CAPS (outbuf)); res = gst_pad_push (srcpad->pad, outbuf); res = gst_multipart_combine_flows (multipart, srcpad, res); if (res != GST_FLOW_OK) break; } } nodata: gst_object_unref (multipart); if (G_UNLIKELY (size == MULTIPART_DATA_ERROR)) return GST_FLOW_ERROR; if (G_UNLIKELY (size == MULTIPART_DATA_EOS)) return GST_FLOW_UNEXPECTED; return res; }
static gboolean mpegvideoparse_handle_sequence (MpegVideoParse * mpegvideoparse, GstBuffer * buf) { MPEGSeqHdr new_hdr; guint8 *cur, *end; cur = GST_BUFFER_DATA (buf); end = GST_BUFFER_DATA (buf) + GST_BUFFER_SIZE (buf); memset (&new_hdr, 0, sizeof (MPEGSeqHdr)); if (G_UNLIKELY (!mpeg_util_parse_sequence_hdr (&new_hdr, cur, end))) return FALSE; if (new_hdr.width < 16 || new_hdr.width > 4096 || new_hdr.height < 16 || new_hdr.height > 4096) { GST_WARNING_OBJECT (mpegvideoparse, "Width/height out of valid range " "[16, 4096]"); return FALSE; } if (memcmp (&mpegvideoparse->seq_hdr, &new_hdr, sizeof (MPEGSeqHdr)) != 0) { GstCaps *caps; GstBuffer *seq_buf; /* * Profile indication - 1 => High, 2 => Spatially Scalable, * 3 => SNR Scalable, 4 => Main, 5 => Simple * 4:2:2 and Multi-view have profile = 0, with the escape bit set to 1 */ const gchar *profiles[] = { "high", "spatial", "snr", "main", "simple" }; /* * Level indication - 4 => High, 6 => High-1440, 8 => Main, 10 => Low, * except in the case of profile = 0 */ const gchar *levels[] = { "high", "high-1440", "main", "low" }; /* Store the entire sequence header + sequence header extension for output as codec_data */ seq_buf = gst_buffer_copy (buf); gst_buffer_replace (&mpegvideoparse->seq_hdr_buf, seq_buf); gst_buffer_unref (seq_buf); caps = gst_caps_new_simple ("video/mpeg", "systemstream", G_TYPE_BOOLEAN, FALSE, "parsed", G_TYPE_BOOLEAN, TRUE, "mpegversion", G_TYPE_INT, new_hdr.mpeg_version, "width", G_TYPE_INT, new_hdr.width, "height", G_TYPE_INT, new_hdr.height, "framerate", GST_TYPE_FRACTION, new_hdr.fps_n, new_hdr.fps_d, "pixel-aspect-ratio", GST_TYPE_FRACTION, new_hdr.par_w, new_hdr.par_h, "interlaced", G_TYPE_BOOLEAN, !new_hdr.progressive, "codec_data", GST_TYPE_BUFFER, seq_buf, NULL); if (new_hdr.mpeg_version == 2) { const gchar *profile = NULL, *level = NULL; if (new_hdr.profile > 0 && new_hdr.profile < 6) profile = profiles[new_hdr.profile - 1]; if ((new_hdr.level > 3) && (new_hdr.level < 11) && (new_hdr.level % 2 == 0)) level = levels[(new_hdr.level >> 1) - 1]; if (new_hdr.profile == 8) { /* Non-hierarchical profile */ switch (new_hdr.level) { case 2: level = levels[0]; case 5: level = levels[2]; profile = "4:2:2"; break; case 10: level = levels[0]; case 11: level = levels[1]; case 13: level = levels[2]; case 14: level = levels[3]; profile = "multiview"; break; default: break; } } if (profile) gst_caps_set_simple (caps, "profile", G_TYPE_STRING, profile, NULL); else GST_DEBUG ("Invalid profile - %u", new_hdr.profile); if (level) gst_caps_set_simple (caps, "level", G_TYPE_STRING, level, NULL); else GST_DEBUG ("Invalid level - %u", new_hdr.level); } GST_DEBUG ("New mpegvideoparse caps: %" GST_PTR_FORMAT, caps); if (!gst_pad_set_caps (mpegvideoparse->srcpad, caps)) { gst_caps_unref (caps); return FALSE; } gst_caps_unref (caps); if (new_hdr.bitrate > 0) { GstTagList *taglist; taglist = gst_tag_list_new_full (GST_TAG_BITRATE, new_hdr.bitrate, NULL); gst_element_found_tags_for_pad (GST_ELEMENT_CAST (mpegvideoparse), mpegvideoparse->srcpad, taglist); } /* And update the new_hdr into our stored version */ mpegvideoparse->seq_hdr = new_hdr; }