/** * gst_pb_utils_get_encoder_description: * @caps: the (fixed) #GstCaps for which an encoder description is needed * * Returns a localised string describing an encoder for the format specified * in @caps, for use in error dialogs or other messages to be seen by the user. * Should never return NULL unless @factory_name or @caps are invalid. * * This function is mainly for internal use, applications would typically * use gst_missing_plugin_message_get_description() to get a description of * a missing feature from a missing-plugin message. * * Returns: a newly-allocated description string, or NULL on error. Free * string with g_free() when not needed any longer. */ gchar * gst_pb_utils_get_encoder_description (const GstCaps * caps) { gchar *str, *ret; GstCaps *tmp; g_return_val_if_fail (caps != NULL, NULL); g_return_val_if_fail (GST_IS_CAPS (caps), NULL); tmp = copy_and_clean_caps (caps); g_return_val_if_fail (gst_caps_is_fixed (tmp), NULL); /* special-case RTP caps */ if (caps_are_rtp_caps (tmp, "video", &str)) { ret = g_strdup_printf (_("%s video RTP payloader"), str); } else if (caps_are_rtp_caps (tmp, "audio", &str)) { ret = g_strdup_printf (_("%s audio RTP payloader"), str); } else if (caps_are_rtp_caps (tmp, "application", &str)) { ret = g_strdup_printf (_("%s RTP payloader"), str); } else { const FormatInfo *info; str = gst_pb_utils_get_codec_description (tmp); info = find_format_info (tmp); if (info != NULL && (info->flags & FLAG_CONTAINER) != 0) { ret = g_strdup_printf (_("%s muxer"), str); } else { ret = g_strdup_printf (_("%s encoder"), str); } } g_free (str); gst_caps_unref (tmp); return ret; }
/* Print information regarding a stream */ void print_stream_info (GstDiscovererStreamInfo *info, gint depth) { gchar *desc = NULL; GstCaps *caps; const GstTagList *tags; caps = gst_discoverer_stream_info_get_caps (info); if (caps) { if (gst_caps_is_fixed (caps)) desc = gst_pb_utils_get_codec_description (caps); else desc = gst_caps_to_string (caps); gst_caps_unref (caps); } g_print ("%*s%s: %s\n", 2 * depth, " ", gst_discoverer_stream_info_get_stream_type_nick (info), (desc ? desc : "")); if (desc) { g_free (desc); desc = NULL; } tags = gst_discoverer_stream_info_get_tags (info); if (tags) { g_print ("%*sTags:\n", 2 * (depth + 1), " "); gst_tag_list_foreach (tags, print_tag_foreach, GINT_TO_POINTER (depth + 2)); } }
static GstEncodingProfile * create_profile (GstCaps * cf, GstCaps * vf, GstCaps * af) { GstEncodingContainerProfile *cprof = NULL; cprof = gst_encoding_container_profile_new ((gchar *) "test-application-profile", NULL, cf, NULL); if (vf) gst_encoding_container_profile_add_profile (cprof, (GstEncodingProfile *) gst_encoding_video_profile_new (vf, NULL, NULL, 0)); if (af) gst_encoding_container_profile_add_profile (cprof, (GstEncodingProfile *) gst_encoding_audio_profile_new (af, NULL, NULL, 0)); /* Let's print out some info */ if (!silent) { gchar *desc = gst_pb_utils_get_codec_description (cf); gchar *cd = gst_caps_to_string (cf); g_print ("Encoding parameters\n"); g_print (" Container format : %s (%s)\n", desc, cd); g_free (desc); g_free (cd); if (vf) { desc = gst_pb_utils_get_codec_description (vf); cd = gst_caps_to_string (vf); g_print (" Video format : %s (%s)\n", desc, cd); g_free (desc); g_free (cd); } if (af) { desc = gst_pb_utils_get_codec_description (af); cd = gst_caps_to_string (af); g_print (" Audio format : %s (%s)\n", desc, cd); g_free (desc); g_free (cd); } } return (GstEncodingProfile *) cprof; }
static gchar * generate_filename (const GstCaps * container, const GstCaps * vcodec, const GstCaps * acodec) { gchar *a, *b, *c; gchar *res = NULL; guint i; a = gst_pb_utils_get_codec_description (container); b = gst_pb_utils_get_codec_description (vcodec); c = gst_pb_utils_get_codec_description (acodec); if (!a) a = g_strdup_printf ("%.10s", g_uri_escape_string (gst_caps_to_string (container), NULL, FALSE)); if (!b) b = g_strdup_printf ("%.10s", g_uri_escape_string (gst_caps_to_string (vcodec), NULL, FALSE)); if (!c) c = g_strdup_printf ("%.10s", g_uri_escape_string (gst_caps_to_string (acodec), NULL, FALSE)); for (i = 0; i < 256 && res == NULL; i++) { res = g_strdup_printf ("%s-%s-%s-%d.file", a, b, c, i); if (g_file_test (res, G_FILE_TEST_EXISTS)) { g_free (res); res = NULL; } } /* Make sure file doesn't already exist */ g_free (a); g_free (b); g_free (c); return res; }
static void print_stream_info (GstDiscovererStreamInfo * info, void *depth) { gchar *desc = NULL; GstCaps *caps; caps = gst_discoverer_stream_info_get_caps (info); if (caps) { if (gst_caps_is_fixed (caps) && !verbose) desc = gst_pb_utils_get_codec_description (caps); else desc = gst_caps_to_string (caps); gst_caps_unref (caps); } g_print ("%*s%s: %s\n", 2 * GPOINTER_TO_INT (depth), " ", gst_discoverer_stream_info_get_stream_type_nick (info), desc); if (desc) { g_free (desc); desc = NULL; } if (verbose) { if (GST_IS_DISCOVERER_AUDIO_INFO (info)) desc = gst_stream_audio_information_to_string (info, GPOINTER_TO_INT (depth) + 1); else if (GST_IS_DISCOVERER_VIDEO_INFO (info)) desc = gst_stream_video_information_to_string (info, GPOINTER_TO_INT (depth) + 1); else if (GST_IS_DISCOVERER_SUBTITLE_INFO (info)) desc = gst_stream_subtitle_information_to_string (info, GPOINTER_TO_INT (depth) + 1); if (desc) { g_print ("%s", desc); g_free (desc); } } }
static GstFlowReturn gst_real_audio_demux_parse_header (GstRealAudioDemux * demux) { const guint8 *data; gchar *codec_name = NULL; GstCaps *caps = NULL; guint avail; g_assert (demux->ra_version == 4 || demux->ra_version == 3); avail = gst_adapter_available (demux->adapter); if (avail < 16) return GST_FLOW_OK; if (!gst_real_audio_demux_get_data_offset_from_header (demux)) return GST_FLOW_ERROR; /* shouldn't happen */ GST_DEBUG_OBJECT (demux, "data_offset = %u", demux->data_offset); if (avail + 6 < demux->data_offset) { GST_DEBUG_OBJECT (demux, "Need %u bytes, but only %u available now", demux->data_offset - 6, avail); return GST_FLOW_OK; } data = gst_adapter_peek (demux->adapter, demux->data_offset - 6); g_assert (data); switch (demux->ra_version) { case 3: demux->fourcc = GST_RM_AUD_14_4; demux->packet_size = 20; demux->sample_rate = 8000; demux->channels = 1; demux->sample_width = 16; demux->flavour = 1; demux->leaf_size = 0; demux->height = 0; break; case 4: demux->flavour = GST_READ_UINT16_BE (data + 16); /* demux->frame_size = GST_READ_UINT32_BE (data + 36); */ demux->leaf_size = GST_READ_UINT16_BE (data + 38); demux->height = GST_READ_UINT16_BE (data + 34); demux->packet_size = GST_READ_UINT32_BE (data + 18); demux->sample_rate = GST_READ_UINT16_BE (data + 42); demux->sample_width = GST_READ_UINT16_BE (data + 46); demux->channels = GST_READ_UINT16_BE (data + 48); demux->fourcc = GST_READ_UINT32_LE (data + 56); demux->pending_tags = gst_rm_utils_read_tags (data + 63, demux->data_offset - 63, gst_rm_utils_read_string8); break; default: g_assert_not_reached (); #if 0 case 5: demux->flavour = GST_READ_UINT16_BE (data + 16); /* demux->frame_size = GST_READ_UINT32_BE (data + 36); */ demux->leaf_size = GST_READ_UINT16_BE (data + 38); demux->height = GST_READ_UINT16_BE (data + 34); demux->sample_rate = GST_READ_UINT16_BE (data + 48); demux->sample_width = GST_READ_UINT16_BE (data + 52); demux->n_channels = GST_READ_UINT16_BE (data + 54); demux->fourcc = RMDEMUX_FOURCC_GET (data + 60); break; #endif } GST_INFO_OBJECT (demux, "packet_size = %u", demux->packet_size); GST_INFO_OBJECT (demux, "sample_rate = %u", demux->sample_rate); GST_INFO_OBJECT (demux, "sample_width = %u", demux->sample_width); GST_INFO_OBJECT (demux, "channels = %u", demux->channels); GST_INFO_OBJECT (demux, "fourcc = '%" GST_FOURCC_FORMAT "' (%08X)", GST_FOURCC_ARGS (demux->fourcc), demux->fourcc); switch (demux->fourcc) { case GST_RM_AUD_14_4: caps = gst_caps_new_simple ("audio/x-pn-realaudio", "raversion", G_TYPE_INT, 1, NULL); demux->byterate_num = 1000; demux->byterate_denom = 1; break; case GST_RM_AUD_28_8: /* FIXME: needs descrambling */ caps = gst_caps_new_simple ("audio/x-pn-realaudio", "raversion", G_TYPE_INT, 2, NULL); break; case GST_RM_AUD_DNET: caps = gst_caps_new_simple ("audio/x-ac3", "rate", G_TYPE_INT, demux->sample_rate, NULL); if (demux->packet_size == 0 || demux->sample_rate == 0) goto broken_file; demux->byterate_num = demux->packet_size * demux->sample_rate; demux->byterate_denom = 1536; break; /* Sipro/ACELP.NET Voice Codec (MIME unknown) */ case GST_RM_AUD_SIPR: caps = gst_caps_new_simple ("audio/x-sipro", NULL); break; default: GST_WARNING_OBJECT (demux, "unknown fourcc %08X", demux->fourcc); break; } if (caps == NULL) goto unknown_fourcc; gst_caps_set_simple (caps, "flavor", G_TYPE_INT, demux->flavour, "rate", G_TYPE_INT, demux->sample_rate, "channels", G_TYPE_INT, demux->channels, "width", G_TYPE_INT, demux->sample_width, "leaf_size", G_TYPE_INT, demux->leaf_size, "packet_size", G_TYPE_INT, demux->packet_size, "height", G_TYPE_INT, demux->height, NULL); GST_INFO_OBJECT (demux, "Adding source pad, caps %" GST_PTR_FORMAT, caps); demux->srcpad = gst_pad_new_from_static_template (&src_template, "src"); gst_pad_use_fixed_caps (demux->srcpad); gst_pad_set_caps (demux->srcpad, caps); codec_name = gst_pb_utils_get_codec_description (caps); gst_caps_unref (caps); gst_pad_set_event_function (demux->srcpad, GST_DEBUG_FUNCPTR (gst_real_audio_demux_src_event)); gst_pad_set_query_function (demux->srcpad, GST_DEBUG_FUNCPTR (gst_real_audio_demux_src_query)); gst_pad_set_active (demux->srcpad, TRUE); gst_element_add_pad (GST_ELEMENT (demux), demux->srcpad); if (demux->byterate_num > 0 && demux->byterate_denom > 0) { GstFormat bformat = GST_FORMAT_BYTES; gint64 size_bytes = 0; GST_INFO_OBJECT (demux, "byte rate = %u/%u = %u bytes/sec", demux->byterate_num, demux->byterate_denom, demux->byterate_num / demux->byterate_denom); if (gst_pad_query_peer_duration (demux->sinkpad, &bformat, &size_bytes)) { demux->duration = gst_real_demux_get_timestamp_from_offset (demux, size_bytes); demux->upstream_size = size_bytes; GST_INFO_OBJECT (demux, "upstream_size = %" G_GUINT64_FORMAT, demux->upstream_size); GST_INFO_OBJECT (demux, "duration = %" GST_TIME_FORMAT, GST_TIME_ARGS (demux->duration)); } } demux->need_newsegment = TRUE; if (codec_name) { if (demux->pending_tags == NULL) demux->pending_tags = gst_tag_list_new (); gst_tag_list_add (demux->pending_tags, GST_TAG_MERGE_REPLACE, GST_TAG_AUDIO_CODEC, codec_name, NULL); g_free (codec_name); } gst_adapter_flush (demux->adapter, demux->data_offset - 6); demux->state = REAL_AUDIO_DEMUX_STATE_DATA; demux->need_newsegment = TRUE; return GST_FLOW_OK; /* ERRORS */ unknown_fourcc: { GST_ELEMENT_ERROR (GST_ELEMENT (demux), STREAM, DECODE, (NULL), ("Unknown fourcc '%" GST_FOURCC_FORMAT "'", GST_FOURCC_ARGS (demux->fourcc))); return GST_FLOW_ERROR; } broken_file: { GST_ELEMENT_ERROR (GST_ELEMENT (demux), STREAM, DECODE, (NULL), ("Broken file - invalid sample_rate or other header value")); return GST_FLOW_ERROR; } }
static void list_codecs (void) { GstCaps *l, *caps; GstStructure *st; guint i, len; gchar *tmpstr, *desc; caps = gst_caps_new_empty (); g_print ("Available container formats:\n"); l = gst_caps_list_container_formats (GST_RANK_NONE); len = gst_caps_get_size (l); for (i = 0; i < len; i++) { st = gst_caps_steal_structure (l, 0); gst_caps_append_structure (caps, st); tmpstr = gst_caps_to_string (caps); desc = gst_pb_utils_get_codec_description (caps); g_print (" %s - %s\n", desc, tmpstr); g_free (tmpstr); if (desc) g_free (desc); gst_caps_remove_structure (caps, 0); } g_print ("\n"); gst_caps_unref (l); g_print ("Available video codecs:\n"); l = gst_caps_list_video_encoding_formats (GST_RANK_NONE); len = gst_caps_get_size (l); for (i = 0; i < len; i++) { st = gst_caps_steal_structure (l, 0); gst_caps_append_structure (caps, st); tmpstr = gst_caps_to_string (caps); desc = gst_pb_utils_get_codec_description (caps); g_print (" %s - %s\n", desc, tmpstr); g_free (tmpstr); if (desc) g_free (desc); gst_caps_remove_structure (caps, 0); } g_print ("\n"); gst_caps_unref (l); g_print ("Available audio codecs:\n"); l = gst_caps_list_audio_encoding_formats (GST_RANK_NONE); len = gst_caps_get_size (l); for (i = 0; i < len; i++) { st = gst_caps_steal_structure (l, 0); gst_caps_append_structure (caps, st); tmpstr = gst_caps_to_string (caps); desc = gst_pb_utils_get_codec_description (caps); g_print (" %s - %s\n", desc, tmpstr); g_free (tmpstr); if (desc) g_free (desc); gst_caps_remove_structure (caps, 0); } g_print ("\n"); gst_caps_unref (l); gst_caps_unref (caps); }
gchar * lgm_filename_to_uri (const gchar *filename) { gchar *uri, *path; GError *err = NULL; #ifdef G_OS_WIN32 if (g_path_is_absolute(filename) || !gst_uri_is_valid (filename)) { #else if (!gst_uri_is_valid (filename)) { #endif if (!g_path_is_absolute (filename)) { gchar *cur_dir; cur_dir = g_get_current_dir (); path = g_build_filename (cur_dir, filename, NULL); g_free (cur_dir); } else { path = g_strdup (filename); } uri = g_filename_to_uri (path, NULL, &err); g_free (path); path = NULL; if (err != NULL) { g_error_free (err); return NULL; } } else { uri = g_strdup (filename); } return uri; } GstDiscovererResult lgm_discover_uri ( const gchar *filename, guint64 *duration, guint *width, guint *height, guint *fps_n, guint *fps_d, guint *par_n, guint *par_d, gchar **container, gchar **video_codec, gchar **audio_codec, GError **err) { GstDiscoverer *discoverer; GstDiscovererInfo *info; GList *videos = NULL, *audios = NULL; GstDiscovererStreamInfo *sinfo = NULL; GstDiscovererVideoInfo *vinfo = NULL; GstDiscovererAudioInfo *ainfo = NULL; GstDiscovererResult ret; gchar *uri; uri = lgm_filename_to_uri (filename); if (uri == NULL) { return GST_DISCOVERER_URI_INVALID; } *duration = *width = *height = *fps_n = *fps_d = *par_n = *par_d = 0; *container = *audio_codec = *video_codec = NULL; discoverer = gst_discoverer_new (4 * GST_SECOND, err); if (*err != NULL) { g_free (uri); return GST_DISCOVERER_ERROR; } info = gst_discoverer_discover_uri (discoverer, uri, err); g_free (uri); if (*err != NULL) { if (info != NULL) { return gst_discoverer_info_get_result (info); } else { return GST_DISCOVERER_ERROR; } } sinfo = gst_discoverer_info_get_stream_info (info); *duration = gst_discoverer_info_get_duration (info); if (GST_IS_DISCOVERER_CONTAINER_INFO (sinfo)) { GstCaps *caps; caps = gst_discoverer_stream_info_get_caps ( GST_DISCOVERER_STREAM_INFO(sinfo)); *container = gst_pb_utils_get_codec_description (caps); gst_caps_unref (caps); } if (GST_IS_DISCOVERER_AUDIO_INFO (sinfo)) { ainfo = GST_DISCOVERER_AUDIO_INFO (sinfo); } else { audios = gst_discoverer_info_get_audio_streams (info); if (audios != NULL) { ainfo = audios->data; } } if (ainfo != NULL) { GstCaps *caps; caps = gst_discoverer_stream_info_get_caps ( GST_DISCOVERER_STREAM_INFO (ainfo)); *audio_codec = gst_pb_utils_get_codec_description (caps); gst_caps_unref (caps); } if (audios != NULL) { gst_discoverer_stream_info_list_free (audios); } if (GST_IS_DISCOVERER_VIDEO_INFO (sinfo)) { vinfo = GST_DISCOVERER_VIDEO_INFO (sinfo); } else { videos = gst_discoverer_info_get_video_streams (info); if (videos != NULL) { vinfo = videos->data; } } if (vinfo != NULL) { GstCaps *caps; caps = gst_discoverer_stream_info_get_caps ( GST_DISCOVERER_STREAM_INFO (vinfo)); *video_codec = gst_pb_utils_get_codec_description (caps); gst_caps_unref (caps); *height = gst_discoverer_video_info_get_height (vinfo); *width = gst_discoverer_video_info_get_width (vinfo); *fps_n = gst_discoverer_video_info_get_framerate_num (vinfo); *fps_d = gst_discoverer_video_info_get_framerate_denom (vinfo); *par_n = gst_discoverer_video_info_get_par_num (vinfo); *par_d = gst_discoverer_video_info_get_par_denom (vinfo); } if (videos != NULL) { gst_discoverer_stream_info_list_free (videos); } ret = gst_discoverer_info_get_result (info); gst_discoverer_info_unref (info); g_object_unref (discoverer); return ret; }