static void gst_raw_audio_parse_update_config_bpf (GstRawAudioParseConfig * config) { switch (config->format) { case GST_RAW_AUDIO_PARSE_FORMAT_PCM: { GstAudioFormatInfo const *fmt_info = gst_audio_format_get_info (config->pcm_format); g_assert (fmt_info != NULL); config->bpf = GST_AUDIO_FORMAT_INFO_WIDTH (fmt_info) * config->num_channels / 8; break; } case GST_RAW_AUDIO_PARSE_FORMAT_ALAW: case GST_RAW_AUDIO_PARSE_FORMAT_MULAW: /* A-law and mu-law both use 1 byte per sample */ config->bpf = 1 * config->num_channels; break; default: g_assert_not_reached (); } }
/** * gst_audio_info_init: * @info: a #GstAudioInfo * * Initialize @info with default values. */ void gst_audio_info_init (GstAudioInfo * info) { g_return_if_fail (info != NULL); memset (info, 0, sizeof (GstAudioInfo)); info->finfo = gst_audio_format_get_info (GST_AUDIO_FORMAT_UNKNOWN); }
/** * gst_audio_info_set_format: * @info: a #GstAudioInfo * @format: the format * @rate: the samplerate * @channels: the number of channels * @position: the channel positions * * Set the default info for the audio info of @format and @rate and @channels. * * Note: This initializes @info first, no values are preserved. */ void gst_audio_info_set_format (GstAudioInfo * info, GstAudioFormat format, gint rate, gint channels, const GstAudioChannelPosition * position) { const GstAudioFormatInfo *finfo; gint i; g_return_if_fail (info != NULL); g_return_if_fail (format != GST_AUDIO_FORMAT_UNKNOWN); g_return_if_fail (channels <= 64 || position == NULL); gst_audio_info_init (info); finfo = gst_audio_format_get_info (format); info->flags = 0; info->layout = GST_AUDIO_LAYOUT_INTERLEAVED; info->finfo = finfo; info->rate = rate; info->channels = channels; info->bpf = (finfo->width * channels) / 8; memset (&info->position, 0xff, sizeof (info->position)); if (!position && channels == 1) { info->position[0] = GST_AUDIO_CHANNEL_POSITION_MONO; return; } else if (!position && channels == 2) { info->position[0] = GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT; info->position[1] = GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT; return; } else { if (!position || !gst_audio_check_valid_channel_positions (position, channels, TRUE)) { if (position) g_warning ("Invalid channel positions"); } else { memcpy (&info->position, position, info->channels * sizeof (info->position[0])); if (info->position[0] == GST_AUDIO_CHANNEL_POSITION_NONE) info->flags |= GST_AUDIO_FLAG_UNPOSITIONED; return; } } /* Otherwise a NONE layout */ info->flags |= GST_AUDIO_FLAG_UNPOSITIONED; for (i = 0; i < MIN (64, channels); i++) info->position[i] = GST_AUDIO_CHANNEL_POSITION_NONE; }
static void do_perfect_stream_test (guint rate, const gchar * format, gdouble drop_probability, gdouble inject_probability) { GstElement *pipe, *src, *conv, *filter, *injector, *audiorate, *sink; GstMessage *msg; GstCaps *caps; GstPad *srcpad; GList *l, *bufs = NULL; GstClockTime next_time = GST_CLOCK_TIME_NONE; guint64 next_offset = GST_BUFFER_OFFSET_NONE; GstAudioFormat fmt; const GstAudioFormatInfo *finfo; gint width; fmt = gst_audio_format_from_string (format); g_assert (format != GST_AUDIO_FORMAT_UNKNOWN); finfo = gst_audio_format_get_info (fmt); width = GST_AUDIO_FORMAT_INFO_WIDTH (finfo); caps = gst_caps_new_simple ("audio/x-raw", "rate", G_TYPE_INT, rate, "format", G_TYPE_STRING, format, NULL); GST_INFO ("-------- drop=%.0f%% caps = %" GST_PTR_FORMAT " ---------- ", drop_probability * 100.0, caps); g_assert (drop_probability >= 0.0 && drop_probability <= 1.0); g_assert (inject_probability >= 0.0 && inject_probability <= 1.0); pipe = gst_pipeline_new ("pipeline"); fail_unless (pipe != NULL); src = gst_element_factory_make ("audiotestsrc", "audiotestsrc"); fail_unless (src != NULL); g_object_set (src, "num-buffers", 10, NULL); conv = gst_element_factory_make ("audioconvert", "audioconvert"); fail_unless (conv != NULL); filter = gst_element_factory_make ("capsfilter", "capsfilter"); fail_unless (filter != NULL); g_object_set (filter, "caps", caps, NULL); injector_inject_probability = inject_probability; injector = GST_ELEMENT (g_object_new (test_injector_get_type (), NULL)); srcpad = gst_element_get_static_pad (injector, "src"); fail_unless (srcpad != NULL); gst_pad_add_probe (srcpad, GST_PAD_PROBE_TYPE_BUFFER, probe_cb, &drop_probability, NULL); gst_object_unref (srcpad); audiorate = gst_element_factory_make ("audiorate", "audiorate"); fail_unless (audiorate != NULL); sink = gst_element_factory_make ("fakesink", "fakesink"); fail_unless (sink != NULL); g_object_set (sink, "signal-handoffs", TRUE, NULL); g_signal_connect (sink, "handoff", G_CALLBACK (got_buf), &bufs); gst_bin_add_many (GST_BIN (pipe), src, conv, filter, injector, audiorate, sink, NULL); gst_element_link_many (src, conv, filter, injector, audiorate, sink, NULL); fail_unless_equals_int (gst_element_set_state (pipe, GST_STATE_PLAYING), GST_STATE_CHANGE_ASYNC); fail_unless_equals_int (gst_element_get_state (pipe, NULL, NULL, -1), GST_STATE_CHANGE_SUCCESS); msg = gst_bus_poll (GST_ELEMENT_BUS (pipe), GST_MESSAGE_EOS | GST_MESSAGE_ERROR, -1); fail_unless_equals_string (GST_MESSAGE_TYPE_NAME (msg), "eos"); for (l = bufs; l != NULL; l = l->next) { GstBuffer *buf = GST_BUFFER (l->data); guint num_samples; fail_unless (GST_BUFFER_TIMESTAMP_IS_VALID (buf)); fail_unless (GST_BUFFER_DURATION_IS_VALID (buf)); fail_unless (GST_BUFFER_OFFSET_IS_VALID (buf)); fail_unless (GST_BUFFER_OFFSET_END_IS_VALID (buf)); GST_LOG ("buffer: ts=%" GST_TIME_FORMAT ", end_ts=%" GST_TIME_FORMAT " off=%" G_GINT64_FORMAT ", end_off=%" G_GINT64_FORMAT, GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)), GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf) + GST_BUFFER_DURATION (buf)), GST_BUFFER_OFFSET (buf), GST_BUFFER_OFFSET_END (buf)); if (GST_CLOCK_TIME_IS_VALID (next_time)) { fail_unless_equals_uint64 (next_time, GST_BUFFER_TIMESTAMP (buf)); } if (next_offset != GST_BUFFER_OFFSET_NONE) { fail_unless_equals_uint64 (next_offset, GST_BUFFER_OFFSET (buf)); } /* check buffer size for sanity */ fail_unless_equals_int (gst_buffer_get_size (buf) % (width / 8), 0); /* check there is actually as much data as there should be */ num_samples = GST_BUFFER_OFFSET_END (buf) - GST_BUFFER_OFFSET (buf); fail_unless_equals_int (gst_buffer_get_size (buf), num_samples * (width / 8)); next_time = GST_BUFFER_TIMESTAMP (buf) + GST_BUFFER_DURATION (buf); next_offset = GST_BUFFER_OFFSET_END (buf); } gst_message_unref (msg); gst_element_set_state (pipe, GST_STATE_NULL); gst_object_unref (pipe); g_list_foreach (bufs, (GFunc) gst_mini_object_unref, NULL); g_list_free (bufs); gst_caps_unref (caps); }
static gboolean gst_rtp_L16_depay_setcaps (GstRTPBaseDepayload * depayload, GstCaps * caps) { GstStructure *structure; GstRtpL16Depay *rtpL16depay; gint clock_rate, payload; gint channels; GstCaps *srccaps; gboolean res; const gchar *channel_order; const GstRTPChannelOrder *order; GstAudioInfo *info; rtpL16depay = GST_RTP_L16_DEPAY (depayload); structure = gst_caps_get_structure (caps, 0); payload = 96; gst_structure_get_int (structure, "payload", &payload); switch (payload) { case GST_RTP_PAYLOAD_L16_STEREO: channels = 2; clock_rate = 44100; break; case GST_RTP_PAYLOAD_L16_MONO: channels = 1; clock_rate = 44100; break; default: /* no fixed mapping, we need clock-rate */ channels = 0; clock_rate = 0; break; } /* caps can overwrite defaults */ clock_rate = gst_rtp_L16_depay_parse_int (structure, "clock-rate", clock_rate); if (clock_rate == 0) goto no_clockrate; channels = gst_rtp_L16_depay_parse_int (structure, "encoding-params", channels); if (channels == 0) { channels = gst_rtp_L16_depay_parse_int (structure, "channels", channels); if (channels == 0) { /* channels defaults to 1 otherwise */ channels = 1; } } depayload->clock_rate = clock_rate; info = &rtpL16depay->info; gst_audio_info_init (info); info->finfo = gst_audio_format_get_info (GST_AUDIO_FORMAT_S16BE); info->rate = clock_rate; info->channels = channels; info->bpf = (info->finfo->width / 8) * channels; /* add channel positions */ channel_order = gst_structure_get_string (structure, "channel-order"); order = gst_rtp_channels_get_by_order (channels, channel_order); rtpL16depay->order = order; if (order) { memcpy (info->position, order->pos, sizeof (GstAudioChannelPosition) * channels); gst_audio_channel_positions_to_valid_order (info->position, info->channels); } else { GST_ELEMENT_WARNING (rtpL16depay, STREAM, DECODE, (NULL), ("Unknown channel order '%s' for %d channels", GST_STR_NULL (channel_order), channels)); /* create default NONE layout */ gst_rtp_channels_create_default (channels, info->position); } srccaps = gst_audio_info_to_caps (info); res = gst_pad_set_caps (depayload->srcpad, srccaps); gst_caps_unref (srccaps); return res; /* ERRORS */ no_clockrate: { GST_ERROR_OBJECT (depayload, "no clock-rate specified"); return FALSE; } }
/* returns static descriptions and dynamic ones (such as video/x-raw), * or NULL if caps aren't known at all */ static gchar * format_info_get_desc (const FormatInfo * info, const GstCaps * caps) { const GstStructure *s; g_assert (info != NULL); if (info->desc != NULL) return g_strdup (_(info->desc)); s = gst_caps_get_structure (caps, 0); if (strcmp (info->type, "video/x-raw") == 0) { gchar *ret = NULL; const gchar *str = 0; GstVideoFormat format; const GstVideoFormatInfo *finfo; str = gst_structure_get_string (s, "format"); if (str == NULL) return g_strdup (_("Uncompressed video")); format = gst_video_format_from_string (str); if (format == GST_VIDEO_FORMAT_UNKNOWN) return g_strdup (_("Uncompressed video")); finfo = gst_video_format_get_info (format); if (GST_VIDEO_FORMAT_INFO_IS_GRAY (finfo)) { ret = g_strdup (_("Uncompressed gray")); } else if (GST_VIDEO_FORMAT_INFO_IS_YUV (finfo)) { const gchar *subs; gint w_sub, h_sub, n_semi; w_sub = GST_VIDEO_FORMAT_INFO_W_SUB (finfo, 1); h_sub = GST_VIDEO_FORMAT_INFO_H_SUB (finfo, 1); if (w_sub == 1 && h_sub == 1) { subs = "4:4:4"; } else if (w_sub == 2 && h_sub == 1) { subs = "4:2:2"; } else if (w_sub == 2 && h_sub == 2) { subs = "4:2:0"; } else if (w_sub == 4 && h_sub == 1) { subs = "4:1:1"; } else { subs = ""; } n_semi = GST_VIDEO_FORMAT_INFO_HAS_ALPHA (finfo) ? 3 : 2; if (GST_VIDEO_FORMAT_INFO_N_PLANES (finfo) == 1) { ret = g_strdup_printf (_("Uncompressed packed YUV %s"), subs); } else if (GST_VIDEO_FORMAT_INFO_N_PLANES (finfo) == n_semi) { ret = g_strdup_printf (_("Uncompressed semi-planar YUV %s"), subs); } else { ret = g_strdup_printf (_("Uncompressed planar YUV %s"), subs); } } else if (GST_VIDEO_FORMAT_INFO_IS_RGB (finfo)) { gboolean alpha, palette; gint bits; alpha = GST_VIDEO_FORMAT_INFO_HAS_ALPHA (finfo); palette = GST_VIDEO_FORMAT_INFO_HAS_PALETTE (finfo); bits = GST_VIDEO_FORMAT_INFO_BITS (finfo); if (palette) { ret = g_strdup_printf (_("Uncompressed palettized %d-bit %s"), bits, alpha ? "RGBA" : "RGB"); } else { ret = g_strdup_printf (_("Uncompressed %d-bit %s"), bits, alpha ? "RGBA" : "RGB"); } } else { ret = g_strdup (_("Uncompressed video")); } return ret; } else if (strcmp (info->type, "video/x-h263") == 0) { const gchar *variant, *ret; variant = gst_structure_get_string (s, "variant"); if (variant == NULL) ret = "H.263"; else if (strcmp (variant, "itu") == 0) ret = "ITU H.26n"; /* why not ITU H.263? (tpm) */ else if (strcmp (variant, "lead") == 0) ret = "Lead H.263"; else if (strcmp (variant, "microsoft") == 0) ret = "Microsoft H.263"; else if (strcmp (variant, "vdolive") == 0) ret = "VDOLive"; else if (strcmp (variant, "vivo") == 0) ret = "Vivo H.263"; else if (strcmp (variant, "xirlink") == 0) ret = "Xirlink H.263"; else { GST_WARNING ("Unknown H263 variant '%s'", variant); ret = "H.263"; } return g_strdup (ret); } else if (strcmp (info->type, "video/x-h264") == 0) { const gchar *variant, *ret; const gchar *profile; variant = gst_structure_get_string (s, "variant"); if (variant == NULL) ret = "H.264"; else if (strcmp (variant, "itu") == 0) ret = "ITU H.264"; else if (strcmp (variant, "videosoft") == 0) ret = "Videosoft H.264"; else if (strcmp (variant, "lead") == 0) ret = "Lead H.264"; else { GST_WARNING ("Unknown H264 variant '%s'", variant); ret = "H.264"; } /* profile */ profile = gst_structure_get_string (s, "profile"); if (profile != NULL) profile = pbutils_desc_get_h264_profile_name_from_nick (profile); if (profile == NULL) return g_strdup (ret); return g_strdup_printf ("%s (%s Profile)", ret, profile); } else if (strcmp (info->type, "video/x-h265") == 0) { const gchar *profile = gst_structure_get_string (s, "profile"); if (profile != NULL) profile = pbutils_desc_get_h265_profile_name_from_nick (profile); if (profile != NULL) return g_strdup_printf ("H.265 (%s Profile)", profile); return g_strdup ("H.265"); } else if (strcmp (info->type, "video/x-dirac") == 0) { const gchar *profile = gst_structure_get_string (s, "profile"); if (profile == NULL) return g_strdup ("Dirac"); if (strcmp (profile, "vc2-low-delay") == 0) return g_strdup_printf ("Dirac (%s)", "VC-2 Low Delay Profile"); else if (strcmp (profile, "vc2-simple") == 0) return g_strdup_printf ("Dirac (%s)", "VC-2 Simple Profile"); else if (strcmp (profile, "vc2-main") == 0) return g_strdup_printf ("Dirac (%s)", "VC-2 Main Profile"); else return g_strdup ("Dirac"); } else if (strcmp (info->type, "video/x-divx") == 0) { gint ver = 0; if (!gst_structure_get_int (s, "divxversion", &ver) || ver <= 2) { GST_WARNING ("Unexpected DivX version in %" GST_PTR_FORMAT, caps); return g_strdup ("DivX MPEG-4"); } return g_strdup_printf (_("DivX MPEG-4 Version %d"), ver); } else if (strcmp (info->type, "video/x-msmpeg") == 0) { gint ver = 0; if (!gst_structure_get_int (s, "msmpegversion", &ver) || ver < 40 || ver > 49) { GST_WARNING ("Unexpected msmpegversion in %" GST_PTR_FORMAT, caps); return g_strdup ("Microsoft MPEG-4 4.x"); } return g_strdup_printf ("Microsoft MPEG-4 4.%d", ver % 10); } else if (strcmp (info->type, "video/x-truemotion") == 0) { gint ver = 0; gst_structure_get_int (s, "trueversion", &ver); switch (ver) { case 1: return g_strdup_printf ("Duck TrueMotion 1"); case 2: return g_strdup_printf ("TrueMotion 2.0"); default: GST_WARNING ("Unexpected trueversion in %" GST_PTR_FORMAT, caps); break; } return g_strdup_printf ("TrueMotion"); } else if (strcmp (info->type, "video/x-xan") == 0) { gint ver = 0; if (!gst_structure_get_int (s, "wcversion", &ver) || ver < 1) { GST_WARNING ("Unexpected wcversion in %" GST_PTR_FORMAT, caps); return g_strdup ("Xan Wing Commander"); } return g_strdup_printf ("Xan Wing Commander %u", ver); } else if (strcmp (info->type, "video/x-indeo") == 0) { gint ver = 0; if (!gst_structure_get_int (s, "indeoversion", &ver) || ver < 2) { GST_WARNING ("Unexpected indeoversion in %" GST_PTR_FORMAT, caps); return g_strdup ("Intel Indeo"); } return g_strdup_printf ("Intel Indeo %u", ver); } else if (strcmp (info->type, "audio/x-wma") == 0) { gint ver = 0; gst_structure_get_int (s, "wmaversion", &ver); switch (ver) { case 1: case 2: case 3: return g_strdup_printf ("Windows Media Audio %d", ver + 6); default: break; } GST_WARNING ("Unexpected wmaversion in %" GST_PTR_FORMAT, caps); return g_strdup ("Windows Media Audio"); } else if (strcmp (info->type, "video/x-wmv") == 0) { gint ver = 0; const gchar *str; gst_structure_get_int (s, "wmvversion", &ver); str = gst_structure_get_string (s, "format"); switch (ver) { case 1: case 2: case 3: if (str && strncmp (str, "MSS", 3)) { return g_strdup_printf ("Windows Media Video %d Screen", ver + 6); } else { return g_strdup_printf ("Windows Media Video %d", ver + 6); } default: break; } GST_WARNING ("Unexpected wmvversion in %" GST_PTR_FORMAT, caps); return g_strdup ("Windows Media Video"); } else if (strcmp (info->type, "audio/x-mace") == 0) { gint ver = 0; gst_structure_get_int (s, "maceversion", &ver); if (ver == 3 || ver == 6) { return g_strdup_printf ("MACE-%d", ver); } else { GST_WARNING ("Unexpected maceversion in %" GST_PTR_FORMAT, caps); return g_strdup ("MACE"); } } else if (strcmp (info->type, "video/x-svq") == 0) { gint ver = 0; gst_structure_get_int (s, "svqversion", &ver); if (ver == 1 || ver == 3) { return g_strdup_printf ("Sorensen Video %d", ver); } else { GST_WARNING ("Unexpected svqversion in %" GST_PTR_FORMAT, caps); return g_strdup ("Sorensen Video"); } } else if (strcmp (info->type, "video/x-asus") == 0) { gint ver = 0; gst_structure_get_int (s, "asusversion", &ver); if (ver == 1 || ver == 2) { return g_strdup_printf ("Asus Video %d", ver); } else { GST_WARNING ("Unexpected asusversion in %" GST_PTR_FORMAT, caps); return g_strdup ("Asus Video"); } } else if (strcmp (info->type, "video/x-ati-vcr") == 0) { gint ver = 0; gst_structure_get_int (s, "vcrversion", &ver); if (ver == 1 || ver == 2) { return g_strdup_printf ("ATI VCR %d", ver); } else { GST_WARNING ("Unexpected acrversion in %" GST_PTR_FORMAT, caps); return g_strdup ("ATI VCR"); } } else if (strcmp (info->type, "audio/x-adpcm") == 0) { const GValue *layout_val; layout_val = gst_structure_get_value (s, "layout"); if (layout_val != NULL && G_VALUE_HOLDS_STRING (layout_val)) { const gchar *layout; if ((layout = g_value_get_string (layout_val))) { gchar *layout_upper, *ret; if (strcmp (layout, "swf") == 0) return g_strdup ("Shockwave ADPCM"); if (strcmp (layout, "microsoft") == 0) return g_strdup ("Microsoft ADPCM"); if (strcmp (layout, "quicktime") == 0) return g_strdup ("Quicktime ADPCM"); if (strcmp (layout, "westwood") == 0) return g_strdup ("Westwood ADPCM"); if (strcmp (layout, "yamaha") == 0) return g_strdup ("Yamaha ADPCM"); /* FIXME: other layouts: sbpro2, sbpro3, sbpro4, ct, g726, ea, * adx, xa, 4xm, smjpeg, dk4, dk3, dvi */ layout_upper = g_ascii_strup (layout, -1); ret = g_strdup_printf ("%s ADPCM", layout_upper); g_free (layout_upper); return ret; } } return g_strdup ("ADPCM"); } else if (strcmp (info->type, "audio/mpeg") == 0) { gint ver = 0, layer = 0; gst_structure_get_int (s, "mpegversion", &ver); switch (ver) { case 1: gst_structure_get_int (s, "layer", &layer); switch (layer) { case 1: case 2: case 3: return g_strdup_printf ("MPEG-1 Layer %d (MP%d)", layer, layer); default: break; } GST_WARNING ("Unexpected MPEG-1 layer in %" GST_PTR_FORMAT, caps); return g_strdup ("MPEG-1 Audio"); case 2: return g_strdup ("MPEG-2 AAC"); case 4: return g_strdup ("MPEG-4 AAC"); default: break; } GST_WARNING ("Unexpected audio mpegversion in %" GST_PTR_FORMAT, caps); return g_strdup ("MPEG Audio"); } else if (strcmp (info->type, "audio/x-pn-realaudio") == 0) { gint ver = 0; gst_structure_get_int (s, "raversion", &ver); switch (ver) { case 1: return g_strdup ("RealAudio 14k4bps"); case 2: return g_strdup ("RealAudio 28k8bps"); case 8: return g_strdup ("RealAudio G2 (Cook)"); default: break; } GST_WARNING ("Unexpected raversion in %" GST_PTR_FORMAT, caps); return g_strdup ("RealAudio"); } else if (strcmp (info->type, "video/x-pn-realvideo") == 0) { gint ver = 0; gst_structure_get_int (s, "rmversion", &ver); switch (ver) { case 1: return g_strdup ("RealVideo 1.0"); case 2: return g_strdup ("RealVideo 2.0"); case 3: return g_strdup ("RealVideo 3.0"); case 4: return g_strdup ("RealVideo 4.0"); default: break; } GST_WARNING ("Unexpected rmversion in %" GST_PTR_FORMAT, caps); return g_strdup ("RealVideo"); } else if (strcmp (info->type, "video/mpeg") == 0) { gboolean sysstream; gint ver = 0; if (!gst_structure_get_boolean (s, "systemstream", &sysstream)) { GST_WARNING ("Missing systemstream field in mpeg video caps " "%" GST_PTR_FORMAT, caps); sysstream = FALSE; } if (gst_structure_get_int (s, "mpegversion", &ver) && ver > 0 && ver <= 4) { if (sysstream) { return g_strdup_printf ("MPEG-%d System Stream", ver); } else { const gchar *profile = gst_structure_get_string (s, "profile"); if (profile != NULL) { if (ver == 4) profile = pbutils_desc_get_mpeg4v_profile_name_from_nick (profile); else if (ver == 2) profile = pbutils_desc_get_mpeg2v_profile_name_from_nick (profile); else profile = NULL; } if (profile != NULL) return g_strdup_printf ("MPEG-%d Video (%s Profile)", ver, profile); else return g_strdup_printf ("MPEG-%d Video", ver); } } GST_WARNING ("Missing mpegversion field in mpeg video caps " "%" GST_PTR_FORMAT, caps); return g_strdup ("MPEG Video"); } else if (strcmp (info->type, "audio/x-raw") == 0) { gint depth = 0; gboolean is_float; const gchar *str; GstAudioFormat format; const GstAudioFormatInfo *finfo; str = gst_structure_get_string (s, "format"); format = gst_audio_format_from_string (str); if (format == GST_AUDIO_FORMAT_UNKNOWN) return g_strdup (_("Uncompressed audio")); finfo = gst_audio_format_get_info (format); depth = GST_AUDIO_FORMAT_INFO_DEPTH (finfo); is_float = GST_AUDIO_FORMAT_INFO_IS_FLOAT (finfo); return g_strdup_printf (_("Raw %d-bit %s audio"), depth, is_float ? "floating-point" : "PCM"); } else if (strcmp (info->type, "video/x-tscc") == 0) { gint version; gst_structure_get_int (s, "tsccversion", &version); switch (version) { case 1: return g_strdup ("TechSmith Screen Capture 1"); case 2: return g_strdup ("TechSmith Screen Capture 2"); default: break; } GST_WARNING ("Unexpected version in %" GST_PTR_FORMAT, caps); return g_strdup ("TechSmith Screen Capture"); } return NULL; }
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; }