static GstFlowReturn gst_speex_dec_parse_comments (GstSpeexDec * dec, GstBuffer * buf) { GstTagList *list; gchar *ver, *encoder = NULL; list = gst_tag_list_from_vorbiscomment_buffer (buf, NULL, 0, &encoder); if (!list) { GST_WARNING_OBJECT (dec, "couldn't decode comments"); list = gst_tag_list_new (); } if (encoder) { gst_tag_list_add (list, GST_TAG_MERGE_REPLACE, GST_TAG_ENCODER, encoder, NULL); } gst_tag_list_add (list, GST_TAG_MERGE_REPLACE, GST_TAG_AUDIO_CODEC, "Speex", NULL); ver = g_strndup (dec->header->speex_version, SPEEX_HEADER_VERSION_LENGTH); g_strstrip (ver); if (ver != NULL && *ver != '\0') { gst_tag_list_add (list, GST_TAG_MERGE_REPLACE, GST_TAG_ENCODER_VERSION, ver, NULL); } if (dec->header->bitrate > 0) { gst_tag_list_add (list, GST_TAG_MERGE_REPLACE, GST_TAG_BITRATE, (guint) dec->header->bitrate, NULL); } GST_INFO_OBJECT (dec, "tags: %" GST_PTR_FORMAT, list); gst_audio_decoder_merge_tags (GST_AUDIO_DECODER (dec), list, GST_TAG_MERGE_REPLACE); gst_tag_list_free (list); g_free (encoder); g_free (ver); return GST_FLOW_OK; }
// used by movieplay void cPlayback::Close(void) { lt_info( "%s:%s\n", FILENAME, __FUNCTION__); Stop(); // disconnect bus handler if (m_gst_playbin) { // disconnect sync handler callback GstBus * bus = gst_pipeline_get_bus(GST_PIPELINE (m_gst_playbin)); gst_bus_set_sync_handler(bus, NULL, NULL); gst_object_unref(bus); lt_info( "%s:%s - GST bus handler closed\n", FILENAME, __FUNCTION__); } if (m_stream_tags) gst_tag_list_free(m_stream_tags); // close gst if (m_gst_playbin) { if (audioSink) { gst_object_unref(GST_OBJECT(audioSink)); audioSink = NULL; lt_info( "%s:%s - GST audio Sink closed\n", FILENAME, __FUNCTION__); } if (videoSink) { gst_object_unref(GST_OBJECT(videoSink)); videoSink = NULL; lt_info( "%s:%s - GST video Sink closed\n", FILENAME, __FUNCTION__); } // unref m_gst_playbin gst_object_unref (GST_OBJECT (m_gst_playbin)); lt_info( "%s:%s - GST playbin closed\n", FILENAME, __FUNCTION__); m_gst_playbin = NULL; } }
void GstEnginePipeline::TagMessageReceived(GstMessage* msg) { GstTagList* taglist = nullptr; gst_message_parse_tag(msg, &taglist); Engine::SimpleMetaBundle bundle; bundle.title = ParseTag(taglist, GST_TAG_TITLE); bundle.artist = ParseTag(taglist, GST_TAG_ARTIST); bundle.comment = ParseTag(taglist, GST_TAG_COMMENT); bundle.album = ParseTag(taglist, GST_TAG_ALBUM); gst_tag_list_free(taglist); if (ignore_tags_) return; if (!bundle.title.isEmpty() || !bundle.artist.isEmpty() || !bundle.comment.isEmpty() || !bundle.album.isEmpty()) emit MetadataFound(id(), bundle); }
static void nemo_preview_cover_art_fetcher_dispose (GObject *object) { NemoPreviewCoverArtFetcherPrivate *priv = NEMO_PREVIEW_COVER_ART_FETCHER_GET_PRIVATE (object); g_clear_object (&priv->cover); g_clear_object (&priv->input_stream); if (priv->taglist != NULL) { gst_tag_list_free (priv->taglist); priv->taglist = NULL; } g_free (priv->asin); priv->asin = NULL; G_OBJECT_CLASS (nemo_preview_cover_art_fetcher_parent_class)->dispose (object); }
static gboolean gst_vorbis_enc_stop (GstAudioEncoder * enc) { GstVorbisEnc *vorbisenc = GST_VORBISENC (enc); GST_DEBUG_OBJECT (enc, "stop"); vorbis_block_clear (&vorbisenc->vb); vorbis_dsp_clear (&vorbisenc->vd); vorbis_info_clear (&vorbisenc->vi); g_free (vorbisenc->last_message); vorbisenc->last_message = NULL; gst_tag_list_free (vorbisenc->tags); vorbisenc->tags = NULL; gst_tag_setter_reset_tags (GST_TAG_SETTER (enc)); return TRUE; }
static void gst_shout2send_finalize (GstShout2send * shout2send) { g_free (shout2send->ip); g_free (shout2send->password); g_free (shout2send->username); g_free (shout2send->streamname); g_free (shout2send->description); g_free (shout2send->genre); g_free (shout2send->mount); g_free (shout2send->url); gst_tag_list_free (shout2send->tags); gst_poll_free (shout2send->timer); G_OBJECT_CLASS (parent_class)->finalize ((GObject *) (shout2send)); }
/* takes ownership of tag list */ static gboolean gst_icydemux_tag_found (GstICYDemux * icydemux, GstTagList * tags) { /* send the tag event if we have finished typefinding and have a src pad */ if (icydemux->srcpad) return gst_icydemux_send_tag_event (icydemux, tags); /* if we haven't a source pad yet, cache the tags */ if (!icydemux->cached_tags) { icydemux->cached_tags = tags; } else { gst_tag_list_insert (icydemux->cached_tags, tags, GST_TAG_MERGE_REPLACE_ALL); gst_tag_list_free (tags); } return TRUE; }
static gboolean gst_vorbis_enc_stop (GstAudioEncoder * enc) { GstVorbisEnc *vorbisenc = GST_VORBISENC (enc); GST_DEBUG_OBJECT (enc, "stop"); vorbis_block_clear (&vorbisenc->vb); vorbis_dsp_clear (&vorbisenc->vd); vorbis_info_clear (&vorbisenc->vi); g_free (vorbisenc->last_message); vorbisenc->last_message = NULL; gst_tag_list_free (vorbisenc->tags); vorbisenc->tags = NULL; g_slist_foreach (vorbisenc->headers, (GFunc) gst_buffer_unref, NULL); vorbisenc->headers = NULL; return TRUE; }
static void gst_kate_util_decode_base_reset (GstKateDecoderBase * decoder) { g_free (decoder->language); decoder->language = NULL; g_free (decoder->category); decoder->category = NULL; if (decoder->tags) { gst_tag_list_free (decoder->tags); decoder->tags = NULL; } decoder->original_canvas_width = 0; decoder->original_canvas_height = 0; if (decoder->event_queue) { gst_kate_util_decoder_base_free_event_queue (decoder); } decoder->initialized = FALSE; }
void GstPlayer::parseMessage(GstMessage *msg){ switch (GST_MESSAGE_TYPE(msg)) { case GST_MESSAGE_STATE_CHANGED: { this->handleStateChangeMessage(msg); break; } case GST_MESSAGE_DURATION: this->queryDuration(); break; case GST_MESSAGE_TAG: { //QLOG_TRACE() << "[GST]" << GST_MESSAGE_TYPE_NAME(msg); GstTagList * tagList; // We should merge & store the list each time we get a new tag // We should also send a signal for every new tag that is defined gst_message_parse_tag(msg,&tagList); gst_tag_list_foreach(tagList,handleGstTag,this->track); gst_tag_list_free(tagList); break; } case GST_MESSAGE_EOS: { QLOG_TRACE() << "[GST] End-of-stream"; this->requestStop(); //g_main_loop_quit(loop); break; } case GST_MESSAGE_ERROR: { GError *err; gst_message_parse_error(msg, &err, NULL); QLOG_TRACE() << "[GST] [ERROR] " << err->message; error = true; g_error_free(err); // TODO: handle some errors // - Resource not found // // g_main_loop_quit(loop); break; } default: //QLOG_TRACE() << "[GST]" << GST_MESSAGE_TYPE_NAME(msg); break; } }
static void gst_icydemux_reset (GstICYDemux * icydemux) { /* Unknown at the moment (this is a fatal error if don't have a value by the * time we get to our chain function) */ icydemux->meta_interval = -1; icydemux->remaining = 0; icydemux->typefinding = TRUE; gst_caps_replace (&(icydemux->src_caps), NULL); gst_icydemux_remove_srcpad (icydemux); if (icydemux->cached_tags) { gst_tag_list_free (icydemux->cached_tags); icydemux->cached_tags = NULL; } if (icydemux->cached_events) { g_list_foreach (icydemux->cached_events, (GFunc) gst_mini_object_unref, NULL); g_list_free (icydemux->cached_events); icydemux->cached_events = NULL; } if (icydemux->meta_adapter) { gst_adapter_clear (icydemux->meta_adapter); g_object_unref (icydemux->meta_adapter); icydemux->meta_adapter = NULL; } if (icydemux->typefind_buf) { gst_buffer_unref (icydemux->typefind_buf); icydemux->typefind_buf = NULL; } if (icydemux->content_type) { g_free (icydemux->content_type); icydemux->content_type = NULL; } }
bool ParseTagMessage (GstMessage *msg, TagMap_t& map, const QString& region) { GstTagList *tagList = nullptr; gst_message_parse_tag (msg, &tagList); if (!tagList) return false; TagFunctionData data { map, region }; gst_tag_list_foreach (tagList, TagFunction, &data); #if GST_VERSION_MAJOR < 1 gst_tag_list_free (tagList); #else gst_tag_list_unref (tagList); #endif return true; }
static GdkPixbuf * gst_thumbnailer_cover_by_name (GstElement *play, const gchar *signal_name, GCancellable *cancellable) { GstTagList *tags = NULL; GdkPixbuf *cover; g_signal_emit_by_name (G_OBJECT (play), signal_name, 0, &tags); if (tags == NULL) return FALSE; /* check the tags for a cover */ cover = gst_thumbnailer_cover_from_tags (tags, cancellable); gst_tag_list_free (tags); return cover; }
gboolean flv_script_data_read(FlvScriptDataReader* reader, FlvMetadata* metadata) { guint8 value_type; gchar* str; gboolean result; /* Parse only 'onMetaData' blocks, return TRUE for any other valid blocks. */ if (!flv_script_data_read_ui8(reader, &value_type)) return TRUE; if (value_type != FLV_SCRIPT_DATA_TYPE_STRING) return TRUE; if (!flv_script_data_read_string(reader, &str, FALSE)) return FALSE; if (strcmp(str, "onMetaData") != 0) { g_free(str); return TRUE; } g_free(str); /*onMetaData block should have ECMA Array type. Return FALSE for other types. */ if (!flv_script_data_read_ui8(reader, &value_type)) return FALSE; if (value_type != FLV_SCRIPT_DATA_TYPE_ECMA) return FALSE; /* Initialize metadata->tags member */ if (metadata->tag_list == NULL) metadata->tag_list = gst_tag_list_new(); /* Read tag contents */ result = flv_script_data_read_ecma(reader, flv_metadata_value_handler, metadata); /* Reset allocated memory if something went wrong */ if (!result) { gst_tag_list_free(metadata->tag_list); metadata->tag_list = NULL; } return result; }
static void gst_flac_tag_dispose (GObject * object) { GstFlacTag *tag = GST_FLAC_TAG (object); if (tag->adapter) { g_object_unref (tag->adapter); tag->adapter = NULL; } if (tag->vorbiscomment) { gst_buffer_unref (tag->vorbiscomment); tag->vorbiscomment = NULL; } if (tag->tags) { gst_tag_list_free (tag->tags); tag->tags = NULL; } G_OBJECT_CLASS (parent_class)->dispose (object); }
static gboolean gst_opus_enc_stop (GstAudioEncoder * benc) { GstOpusEnc *enc = GST_OPUS_ENC (benc); GST_DEBUG_OBJECT (enc, "stop"); enc->header_sent = FALSE; if (enc->state) { opus_multistream_encoder_destroy (enc->state); enc->state = NULL; } gst_tag_list_free (enc->tags); enc->tags = NULL; g_slist_foreach (enc->headers, (GFunc) gst_buffer_unref, NULL); g_slist_free (enc->headers); enc->headers = NULL; gst_tag_setter_reset_tags (GST_TAG_SETTER (enc)); return TRUE; }
static void gst_kate_enc_set_metadata (GstKateEnc * ke) { GstTagList *merged_tags; const GstTagList *user_tags; user_tags = gst_tag_setter_get_tag_list (GST_TAG_SETTER (ke)); GST_DEBUG_OBJECT (ke, "upstream tags = %" GST_PTR_FORMAT, ke->tags); GST_DEBUG_OBJECT (ke, "user-set tags = %" GST_PTR_FORMAT, user_tags); /* gst_tag_list_merge() will handle NULL for either or both lists fine */ merged_tags = gst_tag_list_merge (user_tags, ke->tags, gst_tag_setter_get_tag_merge_mode (GST_TAG_SETTER (ke))); if (merged_tags) { GST_DEBUG_OBJECT (ke, "merged tags = %" GST_PTR_FORMAT, merged_tags); gst_tag_list_foreach (merged_tags, gst_kate_enc_metadata_set1, ke); gst_tag_list_free (merged_tags); } }
static void gst_real_audio_demux_reset (GstRealAudioDemux * demux) { gst_adapter_clear (demux->adapter); if (demux->srcpad) { GST_DEBUG_OBJECT (demux, "Removing source pad"); gst_element_remove_pad (GST_ELEMENT (demux), demux->srcpad); demux->srcpad = NULL; } if (demux->pending_tags) { gst_tag_list_free (demux->pending_tags); demux->pending_tags = NULL; } demux->state = REAL_AUDIO_DEMUX_STATE_MARKER; demux->ra_version = 0; demux->data_offset = 0; demux->packet_size = 0; demux->sample_rate = 0; demux->sample_width = 0; demux->channels = 0; demux->fourcc = 0; demux->need_newsegment = TRUE; demux->segment_running = FALSE; demux->byterate_num = 0; demux->byterate_denom = 0; demux->duration = 0; demux->upstream_size = 0; demux->offset = 0; gst_adapter_clear (demux->adapter); }
static gboolean bus_call (GstBus *bus, GstMessage *msg, gpointer data) { GMainLoop *loop = (GMainLoop *) data; switch (GST_MESSAGE_TYPE (msg)) { case GST_MESSAGE_EOS: g_print ("end-of-stream\n"); break; case GST_MESSAGE_ERROR: { gchar *debug; GError *error; gst_message_parse_error (msg, &error, &debug); g_free (debug); g_printerr ("Error: %s\n", error->message); g_error_free (error); g_main_loop_quit (loop); break; } case GST_MESSAGE_TAG: { GstTagList *tags = NULL; gst_message_parse_tag (msg, &tags); gst_tag_list_foreach(tags,print_one_tag,NULL); gst_tag_list_free(tags); break; } default: break; }; return TRUE; }
static gboolean brasero_normalize_bus_messages (GstBus *bus, GstMessage *msg, BraseroNormalize *normalize) { GstTagList *tags = NULL; GError *error = NULL; gchar *debug; switch (GST_MESSAGE_TYPE (msg)) { case GST_MESSAGE_TAG: /* This is the information we've been waiting for. * NOTE: levels for whole album is delivered at the end */ gst_message_parse_tag (msg, &tags); gst_tag_list_foreach (tags, (GstTagForeachFunc) foreach_tag, normalize); gst_tag_list_free (tags); return TRUE; case GST_MESSAGE_ERROR: gst_message_parse_error (msg, &error, &debug); BRASERO_JOB_LOG (normalize, debug); g_free (debug); brasero_job_error (BRASERO_JOB (normalize), error); return FALSE; case GST_MESSAGE_EOS: brasero_normalize_song_end_reached (normalize); return FALSE; case GST_MESSAGE_STATE_CHANGED: break; default: return TRUE; } return TRUE; }
static void gst_rsvg_dec_reset (GstRsvgDec * dec) { gst_adapter_clear (dec->adapter); dec->width = dec->height = 0; dec->fps_n = 0; dec->fps_d = 1; dec->first_timestamp = GST_CLOCK_TIME_NONE; dec->frame_count = 0; gst_segment_init (&dec->segment, GST_FORMAT_UNDEFINED); dec->need_newsegment = TRUE; g_list_foreach (dec->pending_events, (GFunc) gst_mini_object_unref, NULL); g_list_free (dec->pending_events); dec->pending_events = NULL; if (dec->pending_tags) { gst_tag_list_free (dec->pending_tags); dec->pending_tags = NULL; } }
static gboolean actually_emit_stream_and_tags (RBPlayerGst *player) { GList *t; _rb_player_emit_playing_stream (RB_PLAYER (player), player->priv->stream_data); /* process any tag lists we received while starting the stream */ for (t = player->priv->stream_tags; t != NULL; t = t->next) { GstTagList *tags; tags = (GstTagList *)t->data; rb_debug ("processing buffered taglist"); gst_tag_list_foreach (tags, (GstTagForeachFunc) process_tag, player); gst_tag_list_free (tags); } g_list_free (player->priv->stream_tags); player->priv->stream_tags = NULL; player->priv->emit_stream_idle_id = 0; return FALSE; }
GST_END_TEST GST_START_TEST (test_add) { GstTagList *list = NULL; /* check additions */ /* unfixed */ NEW_LIST_UNFIXED (GST_TAG_MERGE_REPLACE_ALL); check_tags (list, UTAG, UNFIXED4, NULL); NEW_LIST_UNFIXED (GST_TAG_MERGE_REPLACE); check_tags (list, UTAG, UNFIXED4, NULL); NEW_LIST_UNFIXED (GST_TAG_MERGE_PREPEND); check_tags (list, UTAG, UNFIXED4, UNFIXED3, UNFIXED2, UNFIXED1, NULL); NEW_LIST_UNFIXED (GST_TAG_MERGE_APPEND); check_tags (list, UTAG, UNFIXED1, UNFIXED2, UNFIXED3, UNFIXED4, NULL); NEW_LIST_UNFIXED (GST_TAG_MERGE_KEEP); check_tags (list, UTAG, UNFIXED1, NULL); NEW_LIST_UNFIXED (GST_TAG_MERGE_KEEP_ALL); check_tags (list, UTAG, NULL); /* fixed */ NEW_LIST_FIXED (GST_TAG_MERGE_REPLACE_ALL); check_tags (list, FTAG, FIXED4, NULL); NEW_LIST_FIXED (GST_TAG_MERGE_REPLACE); check_tags (list, FTAG, FIXED4, NULL); NEW_LIST_FIXED (GST_TAG_MERGE_PREPEND); check_tags (list, FTAG, FIXED4, NULL); NEW_LIST_FIXED (GST_TAG_MERGE_APPEND); check_tags (list, FTAG, FIXED1, NULL); NEW_LIST_FIXED (GST_TAG_MERGE_KEEP); check_tags (list, FTAG, FIXED1, NULL); NEW_LIST_FIXED (GST_TAG_MERGE_KEEP_ALL); check_tags (list, FTAG, NULL); /* clean up */ if (list) gst_tag_list_free (list); }
/** * gst_tag_list_from_exif_buffer: * @buffer: The exif buffer * @byte_order: byte order of the data * @base_offset: Offset from the tiff header to this buffer * * Parses the IFD and IFD tags data contained in the buffer and puts it * on a taglist. The base_offset is used to subtract from the offset in * the tag entries and be able to get the offset relative to the buffer * start * * Returns: The parsed taglist * * Since: 0.10.30 */ GstTagList * gst_tag_list_from_exif_buffer (const GstBuffer * buffer, gint byte_order, guint32 base_offset) { GstExifReader reader; g_return_val_if_fail (byte_order == G_LITTLE_ENDIAN || byte_order == G_BIG_ENDIAN, NULL); gst_exif_reader_init (&reader, byte_order, buffer, base_offset); if (!parse_exif_ifd (&reader, 0, tag_map_ifd0)) goto read_error; return reader.taglist; read_error: { if (reader.taglist) gst_tag_list_free (reader.taglist); GST_WARNING ("Failed to parse the exif buffer"); return NULL; } }
static void gst_vorbis_enc_set_metadata (GstVorbisEnc * enc) { GstTagList *merged_tags; const GstTagList *user_tags; vorbis_comment_init (&enc->vc); user_tags = gst_tag_setter_get_tag_list (GST_TAG_SETTER (enc)); GST_DEBUG_OBJECT (enc, "upstream tags = %" GST_PTR_FORMAT, enc->tags); GST_DEBUG_OBJECT (enc, "user-set tags = %" GST_PTR_FORMAT, user_tags); /* gst_tag_list_merge() will handle NULL for either or both lists fine */ merged_tags = gst_tag_list_merge (user_tags, enc->tags, gst_tag_setter_get_tag_merge_mode (GST_TAG_SETTER (enc))); if (merged_tags) { GST_DEBUG_OBJECT (enc, "merged tags = %" GST_PTR_FORMAT, merged_tags); gst_tag_list_foreach (merged_tags, gst_vorbis_enc_metadata_set1, enc); gst_tag_list_free (merged_tags); } }
static void on_message (GstBus * bus, GstMessage * message, gpointer data) { switch (GST_MESSAGE_TYPE (message)) { case GST_MESSAGE_WARNING: case GST_MESSAGE_ERROR: g_error ("Got error"); gtk_main_quit (); break; case GST_MESSAGE_TAG:{ GstTagList *tags; GValue v = { 0, }; g_print ("Got tags\n"); gst_message_parse_tag (message, &tags); if (gst_tag_list_copy_value (&v, tags, "mxf-structure")) { const GstStructure *s; GtkTreeIter iter; s = gst_value_get_structure (&v); gtk_tree_store_append (treestore, &iter, NULL); insert_structure (s, &iter); gtk_widget_show_all (window); g_value_unset (&v); } gst_tag_list_free (tags); break; } default: break; } }
static void gst_aiff_parse_reset (GstAiffParse * aiff) { aiff->state = AIFF_PARSE_START; /* These will all be set correctly in the fmt chunk */ aiff->rate = 0; aiff->width = 0; aiff->depth = 0; aiff->channels = 0; aiff->bps = 0; aiff->offset = 0; aiff->end_offset = 0; aiff->dataleft = 0; aiff->datasize = 0; aiff->datastart = 0; aiff->duration = 0; aiff->got_comm = FALSE; if (aiff->caps) { gst_caps_unref (aiff->caps); aiff->caps = NULL; } if (aiff->seek_event) gst_event_unref (aiff->seek_event); aiff->seek_event = NULL; if (aiff->adapter) { gst_adapter_clear (aiff->adapter); aiff->adapter = NULL; } if (aiff->tags != NULL) { gst_tag_list_free (aiff->tags); aiff->tags = NULL; } }
void GstEnginePipeline::TagMessageReceived(GstMessage* msg) { GstTagList* taglist = nullptr; gst_message_parse_tag(msg, &taglist); Engine::SimpleMetaBundle bundle; bundle.title = ParseTag(taglist, GST_TAG_TITLE); if (IsAkamaiTag(bundle.title)) { QPair<QString, QString> artistTitlePair = ParseAkamaiTag(bundle.title); bundle.artist = artistTitlePair.first; bundle.title = artistTitlePair.second; } else { bundle.artist = ParseTag(taglist, GST_TAG_ARTIST); bundle.comment = ParseTag(taglist, GST_TAG_COMMENT); bundle.album = ParseTag(taglist, GST_TAG_ALBUM); } gst_tag_list_free(taglist); if (ignore_tags_) return; if (!bundle.title.isEmpty() || !bundle.artist.isEmpty() || !bundle.comment.isEmpty() || !bundle.album.isEmpty()) emit MetadataFound(id(), bundle); }
static inline void extract_and_queue_tags (GstJpegParse * parse, guint size, guint8 * data, GstTagList * (*tag_func) (GstBuffer * buff)) { GstTagList *tags; GstBuffer *buf; buf = gst_buffer_new_wrapped_full (data, NULL, 0, size); tags = tag_func (buf); gst_buffer_unref (buf); if (tags) { GstTagList *taglist = parse->priv->tags; if (taglist) { gst_tag_list_insert (taglist, tags, GST_TAG_MERGE_REPLACE); gst_tag_list_free (tags); } else { parse->priv->tags = tags; } GST_DEBUG_OBJECT (parse, "collected tags: %" GST_PTR_FORMAT, parse->priv->tags); } }
static void test_tags (const gchar * tag_str) { GstElement *pipeline; GstBus *bus; GMainLoop *loop; GstTagList *sent_tags; gint i, j, n_recv, n_sent; const gchar *name_sent, *name_recv; const GValue *value_sent, *value_recv; gboolean found, ok; gint comparison; GstElement *videotestsrc, *jpegenc, *metadatamux, *metadatademux, *fakesink; GstTagSetter *setter; GST_DEBUG ("testing tags : %s", tag_str); if (received_tags) { gst_tag_list_free (received_tags); received_tags = NULL; } pipeline = gst_pipeline_new ("pipeline"); fail_unless (pipeline != NULL); videotestsrc = gst_element_factory_make ("videotestsrc", "src"); fail_unless (videotestsrc != NULL); g_object_set (G_OBJECT (videotestsrc), "num-buffers", 1, NULL); jpegenc = gst_element_factory_make ("jpegenc", "enc"); if (jpegenc == NULL) { g_print ("Cannot test - jpegenc not available\n"); return; } metadatamux = gst_element_factory_make ("metadatamux", "mux"); g_object_set (G_OBJECT (metadatamux), "exif", TRUE, NULL); fail_unless (metadatamux != NULL); metadatademux = gst_element_factory_make ("metadatademux", "demux"); fail_unless (metadatademux != NULL); fakesink = gst_element_factory_make ("fakesink", "sink"); fail_unless (fakesink != NULL); gst_bin_add_many (GST_BIN (pipeline), videotestsrc, jpegenc, metadatamux, metadatademux, fakesink, NULL); ok = gst_element_link_many (videotestsrc, jpegenc, metadatamux, metadatademux, fakesink, NULL); fail_unless (ok == TRUE); loop = g_main_loop_new (NULL, TRUE); fail_unless (loop != NULL); bus = gst_element_get_bus (pipeline); fail_unless (bus != NULL); gst_bus_add_watch (bus, bus_handler, loop); gst_object_unref (bus); gst_element_set_state (pipeline, GST_STATE_READY); setter = GST_TAG_SETTER (metadatamux); fail_unless (setter != NULL); sent_tags = gst_structure_from_string (tag_str, NULL); fail_unless (sent_tags != NULL); gst_tag_setter_merge_tags (setter, sent_tags, GST_TAG_MERGE_REPLACE); gst_element_set_state (pipeline, GST_STATE_PLAYING); g_main_loop_run (loop); GST_DEBUG ("mainloop done : %p", received_tags); /* verify tags */ fail_unless (received_tags != NULL); n_recv = gst_structure_n_fields (received_tags); n_sent = gst_structure_n_fields (sent_tags); /* we also get e.g. an exif binary block */ fail_unless (n_recv >= n_sent); /* FIXME: compare taglits values */ for (i = 0; i < n_sent; i++) { name_sent = gst_structure_nth_field_name (sent_tags, i); value_sent = gst_structure_get_value (sent_tags, name_sent); found = FALSE; for (j = 0; j < n_recv; j++) { name_recv = gst_structure_nth_field_name (received_tags, j); if (!strcmp (name_sent, name_recv)) { value_recv = gst_structure_get_value (received_tags, name_recv); comparison = gst_value_compare (value_sent, value_recv); if (comparison != GST_VALUE_EQUAL) { gchar *vs = g_strdup_value_contents (value_sent); gchar *vr = g_strdup_value_contents (value_recv); GST_DEBUG ("sent = %s:'%s', recv = %s:'%s'", G_VALUE_TYPE_NAME (value_sent), vs, G_VALUE_TYPE_NAME (value_recv), vr); g_free (vs); g_free (vr); } fail_unless (comparison == GST_VALUE_EQUAL, "tag item %s has been received with different type or value", name_sent); found = TRUE; break; } } fail_unless (found, "tag item %s is lost", name_sent); } gst_tag_list_free (received_tags); received_tags = NULL; gst_tag_list_free (sent_tags); gst_element_set_state (pipeline, GST_STATE_NULL); g_main_loop_unref (loop); g_object_unref (pipeline); }