From: Sebastian Dröge Date: Fri, 29 Jul 2011 09:26:39 +0000 (+0200) Subject: omxmpeg4videoenc: Add support for setting profile/level via caps X-Git-Tag: 1.0.0~386 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=73cde0af8a3afb53de9d8ed2a7fbd656919a5618;p=platform%2Fupstream%2Fgst-omx.git omxmpeg4videoenc: Add support for setting profile/level via caps --- diff --git a/omx/gstomxmpeg4videoenc.c b/omx/gstomxmpeg4videoenc.c index c903f28..5e19b17 100644 --- a/omx/gstomxmpeg4videoenc.c +++ b/omx/gstomxmpeg4videoenc.c @@ -106,6 +106,109 @@ static gboolean gst_omx_mpeg4_video_enc_set_format (GstOMXVideoEnc * enc, GstOMXPort * port, GstVideoState * state) { + GstOMXMPEG4VideoEnc *self = GST_OMX_MPEG4_VIDEO_ENC (enc); + GstCaps *peercaps; + OMX_VIDEO_MPEG4PROFILETYPE profile = OMX_VIDEO_MPEG4ProfileSimple; + OMX_VIDEO_MPEG4LEVELTYPE level = OMX_VIDEO_MPEG4Level1; + + peercaps = gst_pad_peer_get_caps (GST_BASE_VIDEO_CODEC_SRC_PAD (enc)); + if (peercaps) { + GstStructure *s; + GstCaps *intersection; + const gchar *profile_string, *level_string; + OMX_VIDEO_PARAM_PROFILELEVELTYPE param; + OMX_ERRORTYPE err; + + intersection = + gst_caps_intersect (peercaps, + gst_pad_get_pad_template_caps (GST_BASE_VIDEO_CODEC_SRC_PAD (enc))); + gst_caps_unref (peercaps); + if (gst_caps_is_empty (intersection)) { + gst_caps_unref (intersection); + GST_ERROR_OBJECT (self, "Empty caps"); + return FALSE; + } + + s = gst_caps_get_structure (intersection, 0); + profile_string = gst_structure_get_string (s, "profile"); + if (profile_string) { + if (g_str_equal (profile_string, "simple")) { + profile = OMX_VIDEO_MPEG4ProfileSimple; + } else if (g_str_equal (profile_string, "simple-scalable")) { + profile = OMX_VIDEO_MPEG4ProfileSimpleScalable; + } else if (g_str_equal (profile_string, "core")) { + profile = OMX_VIDEO_MPEG4ProfileCore; + } else if (g_str_equal (profile_string, "main")) { + profile = OMX_VIDEO_MPEG4ProfileMain; + } else if (g_str_equal (profile_string, "n-bit")) { + profile = OMX_VIDEO_MPEG4ProfileNbit; + } else if (g_str_equal (profile_string, "scalable")) { + profile = OMX_VIDEO_MPEG4ProfileScalableTexture; + } else if (g_str_equal (profile_string, "simple-face")) { + profile = OMX_VIDEO_MPEG4ProfileSimpleFace; + } else if (g_str_equal (profile_string, "simple-fba")) { + profile = OMX_VIDEO_MPEG4ProfileSimpleFBA; + } else if (g_str_equal (profile_string, "basic-animated-texture")) { + profile = OMX_VIDEO_MPEG4ProfileBasicAnimated; + } else if (g_str_equal (profile_string, "hybrid")) { + profile = OMX_VIDEO_MPEG4ProfileHybrid; + } else if (g_str_equal (profile_string, "advanced-real-time-simple")) { + profile = OMX_VIDEO_MPEG4ProfileAdvancedRealTime; + } else if (g_str_equal (profile_string, "core-scalable")) { + profile = OMX_VIDEO_MPEG4ProfileCoreScalable; + } else if (g_str_equal (profile_string, "advanced-coding-efficiency")) { + profile = OMX_VIDEO_MPEG4ProfileAdvancedCoding; + } else if (g_str_equal (profile_string, "advanced-core")) { + profile = OMX_VIDEO_MPEG4ProfileAdvancedCore; + } else if (g_str_equal (profile_string, "advanced-scalable-texture")) { + profile = OMX_VIDEO_MPEG4ProfileAdvancedScalable; + } else if (g_str_equal (profile_string, "advanced-simple")) { + profile = OMX_VIDEO_MPEG4ProfileAdvancedSimple; + } else { + GST_ERROR_OBJECT (self, "Unsupported profile %s", profile_string); + return FALSE; + } + } + level_string = gst_structure_get_string (s, "level"); + if (level_string) { + if (g_str_equal (level_string, "0")) { + level = OMX_VIDEO_MPEG4Level0; + } else if (g_str_equal (level_string, "0b")) { + level = OMX_VIDEO_MPEG4Level0b; + } else if (g_str_equal (level_string, "1")) { + level = OMX_VIDEO_MPEG4Level1; + } else if (g_str_equal (level_string, "2")) { + level = OMX_VIDEO_MPEG4Level2; + } else if (g_str_equal (level_string, "3")) { + level = OMX_VIDEO_MPEG4Level3; + } else if (g_str_equal (level_string, "4")) { + level = OMX_VIDEO_MPEG4Level4; + } else if (g_str_equal (level_string, "4a")) { + level = OMX_VIDEO_MPEG4Level4a; + } else if (g_str_equal (level_string, "5")) { + level = OMX_VIDEO_MPEG4Level5; + } else { + GST_ERROR_OBJECT (self, "Unsupported level %s", level_string); + return FALSE; + } + } + + GST_OMX_INIT_STRUCT (¶m); + param.nPortIndex = GST_OMX_VIDEO_ENC (self)->out_port->index; + param.eProfile = profile; + param.eLevel = level; + + err = + gst_omx_component_set_parameter (GST_OMX_VIDEO_ENC (self)->component, + OMX_IndexParamVideoProfileLevelCurrent, ¶m); + if (err != OMX_ErrorNone) { + GST_ERROR_OBJECT (self, + "Error setting profile %d and level %d: %s (0x%08x)", profile, level, + gst_omx_error_to_string (err), err); + return FALSE; + } + } + return TRUE; } @@ -113,12 +216,110 @@ static GstCaps * gst_omx_mpeg4_video_enc_get_caps (GstOMXVideoEnc * enc, GstOMXPort * port, GstVideoState * state) { + GstOMXMPEG4VideoEnc *self = GST_OMX_MPEG4_VIDEO_ENC (enc); GstCaps *caps; + OMX_ERRORTYPE err; + OMX_VIDEO_PARAM_PROFILELEVELTYPE param; + const gchar *profile, *level; + + GST_OMX_INIT_STRUCT (¶m); + param.nPortIndex = GST_OMX_VIDEO_ENC (self)->out_port->index; + + err = + gst_omx_component_get_parameter (GST_OMX_VIDEO_ENC (self)->component, + OMX_IndexParamVideoProfileLevelCurrent, ¶m); + if (err != OMX_ErrorNone) + return NULL; + + switch (param.eProfile) { + case OMX_VIDEO_MPEG4ProfileSimple: + profile = "simple"; + break; + case OMX_VIDEO_MPEG4ProfileSimpleScalable: + profile = "simple-scalable"; + break; + case OMX_VIDEO_MPEG4ProfileCore: + profile = "core"; + break; + case OMX_VIDEO_MPEG4ProfileMain: + profile = "main"; + break; + case OMX_VIDEO_MPEG4ProfileNbit: + profile = "n-bit"; + break; + case OMX_VIDEO_MPEG4ProfileScalableTexture: + profile = "scalable"; + break; + case OMX_VIDEO_MPEG4ProfileSimpleFace: + profile = "simple-face"; + break; + case OMX_VIDEO_MPEG4ProfileSimpleFBA: + profile = "simple-fba"; + break; + case OMX_VIDEO_MPEG4ProfileBasicAnimated: + profile = "basic-animated-texture"; + break; + case OMX_VIDEO_MPEG4ProfileHybrid: + profile = "hybrid"; + break; + case OMX_VIDEO_MPEG4ProfileAdvancedRealTime: + profile = "advanced-real-time-simple"; + break; + case OMX_VIDEO_MPEG4ProfileCoreScalable: + profile = "core-scalable"; + break; + case OMX_VIDEO_MPEG4ProfileAdvancedCoding: + profile = "advanced-coding-efficiency"; + break; + case OMX_VIDEO_MPEG4ProfileAdvancedCore: + profile = "advanced-core"; + break; + case OMX_VIDEO_MPEG4ProfileAdvancedScalable: + profile = "advanced-scalable-texture"; + break; + case OMX_VIDEO_MPEG4ProfileAdvancedSimple: + profile = "advanced-simple"; + break; + default: + g_assert_not_reached (); + break; + } + + switch (param.eLevel) { + case OMX_VIDEO_MPEG4Level0: + level = "0"; + break; + case OMX_VIDEO_MPEG4Level0b: + level = "0b"; + break; + case OMX_VIDEO_MPEG4Level1: + level = "1"; + break; + case OMX_VIDEO_MPEG4Level2: + level = "2"; + break; + case OMX_VIDEO_MPEG4Level3: + level = "3"; + break; + case OMX_VIDEO_MPEG4Level4: + level = "4"; + break; + case OMX_VIDEO_MPEG4Level4a: + level = "4a"; + break; + case OMX_VIDEO_MPEG4Level5: + level = "5"; + break; + default: + g_assert_not_reached (); + break; + } caps = gst_caps_new_simple ("video/mpeg", "mpegversion", G_TYPE_INT, 4, "systemstream", G_TYPE_BOOLEAN, FALSE, "width", G_TYPE_INT, state->width, - "height", G_TYPE_INT, state->height, NULL); + "height", G_TYPE_INT, state->height, + "profile", G_TYPE_STRING, profile, "level", G_TYPE_STRING, level, NULL); if (state->fps_n != 0) gst_caps_set_simple (caps, "framerate", GST_TYPE_FRACTION, state->fps_n,