mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-05-23 02:38:16 +00:00
Merge branch 'androidmedia-caps' into 'main'
androidmedia: Read video codec details from VideoCapabilities Closes #3387 See merge request gstreamer/gstreamer!6796
This commit is contained in:
commit
4b3b7ef21b
|
@ -29,12 +29,22 @@ typedef struct _GstAmcCodecInfoHandle GstAmcCodecInfoHandle;
|
|||
typedef struct _GstAmcCodecCapabilitiesHandle GstAmcCodecCapabilitiesHandle;
|
||||
typedef struct _GstAmcCodecProfileLevel GstAmcCodecProfileLevel;
|
||||
|
||||
typedef struct _GstAmcVideoCapabilitiesHandle GstAmcVideoCapabilitiesHandle;
|
||||
|
||||
struct _GstAmcCodecProfileLevel
|
||||
{
|
||||
gint profile;
|
||||
gint level;
|
||||
};
|
||||
|
||||
typedef struct _GstAmcValueRange GstAmcValueRange;
|
||||
|
||||
struct _GstAmcValueRange
|
||||
{
|
||||
gint lower;
|
||||
gint upper;
|
||||
};
|
||||
|
||||
gboolean gst_amc_codeclist_get_count (gint * count, GError **err);
|
||||
GstAmcCodecInfoHandle * gst_amc_codeclist_get_codec_info_at (gint index,
|
||||
GError **err);
|
||||
|
@ -56,6 +66,16 @@ gint * gst_amc_codec_capabilities_handle_get_color_formats (
|
|||
GstAmcCodecProfileLevel * gst_amc_codec_capabilities_handle_get_profile_levels (
|
||||
GstAmcCodecCapabilitiesHandle * handle, gsize * length, GError ** err);
|
||||
|
||||
GstAmcVideoCapabilitiesHandle * gst_amc_capabilities_get_video_capabilities (GstAmcCodecCapabilitiesHandle * handle,
|
||||
GError **err);
|
||||
void gst_amc_capabilities_video_capabilities_handle_free (GstAmcVideoCapabilitiesHandle * handle);
|
||||
GstAmcValueRange gst_amc_video_capabilities_get_widths (
|
||||
GstAmcVideoCapabilitiesHandle * handle, GError ** err);
|
||||
GstAmcValueRange gst_amc_video_capabilities_get_heights (
|
||||
GstAmcVideoCapabilitiesHandle * handle, GError ** err);
|
||||
GstAmcValueRange gst_amc_video_capabilities_get_framerates (
|
||||
GstAmcVideoCapabilitiesHandle * handle, GError ** err);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_AMC_CODECLIST_H__ */
|
||||
|
|
|
@ -93,6 +93,7 @@ enum
|
|||
COLOR_Format18BitBGR666 = 41,
|
||||
COLOR_Format24BitARGB6666 = 42,
|
||||
COLOR_Format24BitABGR6666 = 43,
|
||||
COLOR_FormatYUVP010 = 54,
|
||||
COLOR_FormatAndroidOpaque = 0x7F000789,
|
||||
COLOR_TI_FormatYUV420PackedSemiPlanar = 0x7f000100,
|
||||
COLOR_INTEL_FormatYUV420PackedSemiPlanar = 0x7fa00e00,
|
||||
|
|
|
@ -50,6 +50,9 @@
|
|||
GST_DEBUG_CATEGORY (gst_amc_debug);
|
||||
#define GST_CAT_DEFAULT gst_amc_debug
|
||||
|
||||
/* Should be advanced whenever the codec cache structure changes */
|
||||
#define GST_AMC_CODEC_CACHE_VERSION 1
|
||||
|
||||
GQuark gst_amc_codec_info_quark = 0;
|
||||
|
||||
static GQueue codec_infos = G_QUEUE_INIT;
|
||||
|
@ -68,12 +71,17 @@ scan_codecs (GstPlugin * plugin)
|
|||
gboolean ret = TRUE;
|
||||
gint codec_count, i;
|
||||
const GstStructure *cache_data;
|
||||
const GValue *arr = NULL;
|
||||
GError *error = NULL;
|
||||
|
||||
GST_DEBUG ("Scanning codecs");
|
||||
|
||||
if ((cache_data = gst_plugin_get_cache_data (plugin))) {
|
||||
const GValue *arr = gst_structure_get_value (cache_data, "codecs");
|
||||
cache_data = gst_plugin_get_cache_data (plugin);
|
||||
if (cache_data)
|
||||
arr = gst_structure_get_value (cache_data,
|
||||
"codecs-" G_STRINGIFY (GST_AMC_CODEC_CACHE_VERSION));
|
||||
|
||||
if (arr) {
|
||||
guint i, n;
|
||||
|
||||
GST_DEBUG ("Getting codecs from cache");
|
||||
|
@ -108,6 +116,7 @@ scan_codecs (GstPlugin * plugin)
|
|||
const GValue *plarr;
|
||||
guint k, n3;
|
||||
GstAmcCodecType *gst_codec_type = &gst_codec_info->supported_types[j];
|
||||
const GValue *range, *frac;
|
||||
|
||||
mime = gst_structure_get_string (sts, "mime");
|
||||
gst_codec_type->mime = g_strdup (mime);
|
||||
|
@ -141,6 +150,24 @@ scan_codecs (GstPlugin * plugin)
|
|||
gst_codec_type->profile_levels[k].profile = g_value_get_int (p);
|
||||
gst_codec_type->profile_levels[k].level = g_value_get_int (l);
|
||||
}
|
||||
|
||||
if (g_str_has_prefix (mime, "video/")) {
|
||||
range = gst_structure_get_value (sts, "width");
|
||||
gst_codec_type->width.lower = gst_value_get_int_range_min (range);
|
||||
gst_codec_type->width.upper = gst_value_get_int_range_max (range);
|
||||
|
||||
range = gst_structure_get_value (sts, "height");
|
||||
gst_codec_type->height.lower = gst_value_get_int_range_min (range);
|
||||
gst_codec_type->height.upper = gst_value_get_int_range_max (range);
|
||||
|
||||
range = gst_structure_get_value (sts, "framerate");
|
||||
frac = gst_value_get_fraction_range_min (range);
|
||||
gst_codec_type->framerate.lower =
|
||||
gst_value_get_fraction_numerator (frac);
|
||||
frac = gst_value_get_fraction_range_max (range);
|
||||
gst_codec_type->framerate.upper =
|
||||
gst_value_get_fraction_numerator (frac);
|
||||
}
|
||||
}
|
||||
|
||||
g_queue_push_tail (&codec_infos, gst_codec_info);
|
||||
|
@ -283,6 +310,21 @@ scan_codecs (GstPlugin * plugin)
|
|||
}
|
||||
|
||||
if (g_str_has_prefix (gst_codec_type->mime, "video/")) {
|
||||
GstAmcVideoCapabilitiesHandle *vid_caps = NULL;
|
||||
|
||||
/* These function are safe to be called even if the API level
|
||||
does not give us the MediaCodecInfo.VideoCapabilities. In
|
||||
that case we will get the default values. */
|
||||
vid_caps =
|
||||
gst_amc_capabilities_get_video_capabilities (capabilities, &error);
|
||||
gst_codec_type->width =
|
||||
gst_amc_video_capabilities_get_widths (vid_caps, &error);
|
||||
gst_codec_type->height =
|
||||
gst_amc_video_capabilities_get_heights (vid_caps, &error);
|
||||
gst_codec_type->framerate =
|
||||
gst_amc_video_capabilities_get_framerates (vid_caps, &error);
|
||||
gst_amc_capabilities_video_capabilities_handle_free (vid_caps);
|
||||
|
||||
gst_codec_type->color_formats =
|
||||
gst_amc_codec_capabilities_handle_get_color_formats (capabilities,
|
||||
&gst_codec_type->n_color_formats, &error);
|
||||
|
@ -474,6 +516,37 @@ scan_codecs (GstPlugin * plugin)
|
|||
}
|
||||
gst_structure_set_value (sts, "profile-levels", &tmparr);
|
||||
|
||||
if (g_str_has_prefix (gst_codec_type->mime, "video/")) {
|
||||
GValue tmprange = { 0, };
|
||||
GValue tmpfracl = { 0, };
|
||||
GValue tmpfracu = { 0, };
|
||||
|
||||
g_value_init (&tmprange, GST_TYPE_INT_RANGE);
|
||||
gst_value_set_int_range (&tmprange,
|
||||
gst_codec_type->width.lower, gst_codec_type->width.upper);
|
||||
gst_structure_set_value (sts, "width", &tmprange);
|
||||
g_value_unset (&tmprange);
|
||||
|
||||
g_value_init (&tmprange, GST_TYPE_INT_RANGE);
|
||||
gst_value_set_int_range (&tmprange,
|
||||
gst_codec_type->height.lower, gst_codec_type->height.upper);
|
||||
gst_structure_set_value (sts, "height", &tmprange);
|
||||
g_value_unset (&tmprange);
|
||||
|
||||
g_value_init (&tmprange, GST_TYPE_FRACTION_RANGE);
|
||||
g_value_init (&tmpfracl, GST_TYPE_FRACTION);
|
||||
g_value_init (&tmpfracu, GST_TYPE_FRACTION);
|
||||
gst_value_set_fraction (&tmpfracl, gst_codec_type->framerate.lower,
|
||||
1);
|
||||
gst_value_set_fraction (&tmpfracu, gst_codec_type->framerate.upper,
|
||||
1);
|
||||
gst_value_set_fraction_range (&tmprange, &tmpfracl, &tmpfracu);
|
||||
gst_structure_set_value (sts, "framerate", &tmprange);
|
||||
g_value_unset (&tmprange);
|
||||
g_value_unset (&tmpfracl);
|
||||
g_value_unset (&tmpfracu);
|
||||
}
|
||||
|
||||
g_value_init (&stv, GST_TYPE_STRUCTURE);
|
||||
gst_value_set_structure (&stv, sts);
|
||||
gst_value_array_append_value (&starr, &stv);
|
||||
|
@ -491,7 +564,8 @@ scan_codecs (GstPlugin * plugin)
|
|||
gst_structure_free (cs);
|
||||
}
|
||||
|
||||
gst_structure_set_value (new_cache_data, "codecs", &arr);
|
||||
gst_structure_set_value (new_cache_data,
|
||||
"codecs-" G_STRINGIFY (GST_AMC_CODEC_CACHE_VERSION), &arr);
|
||||
g_value_unset (&arr);
|
||||
|
||||
gst_plugin_set_cache_data (plugin, new_cache_data);
|
||||
|
@ -523,7 +597,8 @@ static const struct
|
|||
COLOR_QCOM_FormatYVU420SemiPlanar32mMultiView, GST_VIDEO_FORMAT_NV12}, {
|
||||
COLOR_OMX_SEC_FormatNV12Tiled, GST_VIDEO_FORMAT_NV12}, {
|
||||
COLOR_FormatYCbYCr, GST_VIDEO_FORMAT_YUY2}, {
|
||||
COLOR_FormatYV12, GST_VIDEO_FORMAT_YV12}
|
||||
COLOR_FormatYV12, GST_VIDEO_FORMAT_YV12}, {
|
||||
COLOR_FormatYUVP010, GST_VIDEO_FORMAT_P010_10LE}
|
||||
};
|
||||
|
||||
static gboolean
|
||||
|
@ -2088,9 +2163,10 @@ gst_amc_codec_info_to_caps (const GstAmcCodecInfo * codec_info,
|
|||
|
||||
tmp = gst_structure_new ("video/x-raw",
|
||||
"format", G_TYPE_STRING, gst_video_format_to_string (format),
|
||||
"width", GST_TYPE_INT_RANGE, 1, G_MAXINT,
|
||||
"height", GST_TYPE_INT_RANGE, 1, G_MAXINT,
|
||||
"framerate", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT, 1, NULL);
|
||||
"width", GST_TYPE_INT_RANGE, type->width.lower, type->width.upper,
|
||||
"height", GST_TYPE_INT_RANGE, type->height.lower,
|
||||
type->height.upper, "framerate", GST_TYPE_FRACTION_RANGE,
|
||||
type->framerate.lower, 1, type->framerate.upper, 1, NULL);
|
||||
|
||||
raw_ret = gst_caps_merge_structure (raw_ret, tmp);
|
||||
}
|
||||
|
@ -2102,13 +2178,12 @@ gst_amc_codec_info_to_caps (const GstAmcCodecInfo * codec_info,
|
|||
gboolean have_profile_level = FALSE;
|
||||
|
||||
tmp = gst_structure_new ("video/mpeg",
|
||||
"width", GST_TYPE_INT_RANGE, 16, 4096,
|
||||
"height", GST_TYPE_INT_RANGE, 16, 4096,
|
||||
"framerate", GST_TYPE_FRACTION_RANGE,
|
||||
0, 1, G_MAXINT, 1,
|
||||
"mpegversion", G_TYPE_INT, 4,
|
||||
"systemstream", G_TYPE_BOOLEAN, FALSE,
|
||||
"parsed", G_TYPE_BOOLEAN, TRUE, NULL);
|
||||
"width", GST_TYPE_INT_RANGE, type->width.lower, type->width.upper,
|
||||
"height", GST_TYPE_INT_RANGE, type->height.lower,
|
||||
type->height.upper, "framerate", GST_TYPE_FRACTION_RANGE,
|
||||
type->framerate.lower, 1, type->framerate.upper, 1, "mpegversion",
|
||||
G_TYPE_INT, 4, "systemstream", G_TYPE_BOOLEAN, FALSE, "parsed",
|
||||
G_TYPE_BOOLEAN, TRUE, NULL);
|
||||
|
||||
if (type->n_profile_levels) {
|
||||
for (j = type->n_profile_levels - 1; j >= 0; j--) {
|
||||
|
@ -2177,12 +2252,11 @@ gst_amc_codec_info_to_caps (const GstAmcCodecInfo * codec_info,
|
|||
gboolean have_profile_level = FALSE;
|
||||
|
||||
tmp = gst_structure_new ("video/x-h263",
|
||||
"width", GST_TYPE_INT_RANGE, 16, 4096,
|
||||
"height", GST_TYPE_INT_RANGE, 16, 4096,
|
||||
"framerate", GST_TYPE_FRACTION_RANGE,
|
||||
0, 1, G_MAXINT, 1,
|
||||
"parsed", G_TYPE_BOOLEAN, TRUE,
|
||||
"variant", G_TYPE_STRING, "itu", NULL);
|
||||
"width", GST_TYPE_INT_RANGE, type->width.lower, type->width.upper,
|
||||
"height", GST_TYPE_INT_RANGE, type->height.lower,
|
||||
type->height.upper, "framerate", GST_TYPE_FRACTION_RANGE,
|
||||
type->framerate.lower, 1, type->framerate.upper, 1, "parsed",
|
||||
G_TYPE_BOOLEAN, TRUE, "variant", G_TYPE_STRING, "itu", NULL);
|
||||
|
||||
if (type->n_profile_levels) {
|
||||
for (j = type->n_profile_levels - 1; j >= 0; j--) {
|
||||
|
@ -2241,13 +2315,12 @@ gst_amc_codec_info_to_caps (const GstAmcCodecInfo * codec_info,
|
|||
gboolean have_profile_level = FALSE;
|
||||
|
||||
tmp = gst_structure_new ("video/x-h264",
|
||||
"width", GST_TYPE_INT_RANGE, 16, 4096,
|
||||
"height", GST_TYPE_INT_RANGE, 16, 4096,
|
||||
"framerate", GST_TYPE_FRACTION_RANGE,
|
||||
0, 1, G_MAXINT, 1,
|
||||
"parsed", G_TYPE_BOOLEAN, TRUE,
|
||||
"stream-format", G_TYPE_STRING, "byte-stream",
|
||||
"alignment", G_TYPE_STRING, "au", NULL);
|
||||
"width", GST_TYPE_INT_RANGE, type->width.lower, type->width.upper,
|
||||
"height", GST_TYPE_INT_RANGE, type->height.lower,
|
||||
type->height.upper, "framerate", GST_TYPE_FRACTION_RANGE,
|
||||
type->framerate.lower, 1, type->framerate.upper, 1, "parsed",
|
||||
G_TYPE_BOOLEAN, TRUE, "stream-format", G_TYPE_STRING,
|
||||
"byte-stream", "alignment", G_TYPE_STRING, "au", NULL);
|
||||
|
||||
if (type->n_profile_levels) {
|
||||
for (j = type->n_profile_levels - 1; j >= 0; j--) {
|
||||
|
@ -2317,13 +2390,12 @@ gst_amc_codec_info_to_caps (const GstAmcCodecInfo * codec_info,
|
|||
gboolean have_profile_level = FALSE;
|
||||
|
||||
tmp = gst_structure_new ("video/x-h265",
|
||||
"width", GST_TYPE_INT_RANGE, 16, 4096,
|
||||
"height", GST_TYPE_INT_RANGE, 16, 4096,
|
||||
"framerate", GST_TYPE_FRACTION_RANGE,
|
||||
0, 1, G_MAXINT, 1,
|
||||
"parsed", G_TYPE_BOOLEAN, TRUE,
|
||||
"stream-format", G_TYPE_STRING, "byte-stream",
|
||||
"alignment", G_TYPE_STRING, "au", NULL);
|
||||
"width", GST_TYPE_INT_RANGE, type->width.lower, type->width.upper,
|
||||
"height", GST_TYPE_INT_RANGE, type->height.lower,
|
||||
type->height.upper, "framerate", GST_TYPE_FRACTION_RANGE,
|
||||
type->framerate.lower, 1, type->framerate.upper, 1, "parsed",
|
||||
G_TYPE_BOOLEAN, TRUE, "stream-format", G_TYPE_STRING,
|
||||
"byte-stream", "alignment", G_TYPE_STRING, "au", NULL);
|
||||
|
||||
if (type->n_profile_levels) {
|
||||
for (j = type->n_profile_levels - 1; j >= 0; j--) {
|
||||
|
@ -2382,35 +2454,37 @@ gst_amc_codec_info_to_caps (const GstAmcCodecInfo * codec_info,
|
|||
}
|
||||
} else if (strcmp (type->mime, "video/x-vnd.on2.vp8") == 0) {
|
||||
tmp = gst_structure_new ("video/x-vp8",
|
||||
"width", GST_TYPE_INT_RANGE, 16, 4096,
|
||||
"height", GST_TYPE_INT_RANGE, 16, 4096,
|
||||
"framerate", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT, 1, NULL);
|
||||
"width", GST_TYPE_INT_RANGE, type->width.lower, type->width.upper,
|
||||
"height", GST_TYPE_INT_RANGE, type->height.lower,
|
||||
type->height.upper, "framerate", GST_TYPE_FRACTION_RANGE,
|
||||
type->framerate.lower, 1, type->framerate.upper, 1, NULL);
|
||||
|
||||
encoded_ret = gst_caps_merge_structure (encoded_ret, tmp);
|
||||
} else if (strcmp (type->mime, "video/x-vnd.on2.vp9") == 0) {
|
||||
tmp = gst_structure_new ("video/x-vp9",
|
||||
"width", GST_TYPE_INT_RANGE, 16, 4096,
|
||||
"height", GST_TYPE_INT_RANGE, 16, 4096,
|
||||
"framerate", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT, 1, NULL);
|
||||
"width", GST_TYPE_INT_RANGE, type->width.lower, type->width.upper,
|
||||
"height", GST_TYPE_INT_RANGE, type->height.lower,
|
||||
type->height.upper, "framerate", GST_TYPE_FRACTION_RANGE,
|
||||
type->framerate.lower, 1, type->framerate.upper, 1, NULL);
|
||||
|
||||
encoded_ret = gst_caps_merge_structure (encoded_ret, tmp);
|
||||
} else if (strcmp (type->mime, "video/av01") == 0) {
|
||||
tmp = gst_structure_new ("video/x-av1",
|
||||
"stream-format", G_TYPE_STRING, "obu-stream",
|
||||
"alignment", G_TYPE_STRING, "tu",
|
||||
"width", GST_TYPE_INT_RANGE, 16, 4096,
|
||||
"height", GST_TYPE_INT_RANGE, 16, 4096,
|
||||
"framerate", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT, 1, NULL);
|
||||
"width", GST_TYPE_INT_RANGE, type->width.lower, type->width.upper,
|
||||
"height", GST_TYPE_INT_RANGE, type->height.lower,
|
||||
type->height.upper, "framerate", GST_TYPE_FRACTION_RANGE,
|
||||
type->framerate.lower, 1, type->framerate.upper, 1, NULL);
|
||||
|
||||
encoded_ret = gst_caps_merge_structure (encoded_ret, tmp);
|
||||
} else if (strcmp (type->mime, "video/mpeg2") == 0) {
|
||||
tmp = gst_structure_new ("video/mpeg",
|
||||
"width", GST_TYPE_INT_RANGE, 16, 4096,
|
||||
"height", GST_TYPE_INT_RANGE, 16, 4096,
|
||||
"framerate", GST_TYPE_FRACTION_RANGE,
|
||||
0, 1, G_MAXINT, 1,
|
||||
"mpegversion", GST_TYPE_INT_RANGE, 1, 2,
|
||||
"systemstream", G_TYPE_BOOLEAN, FALSE,
|
||||
"width", GST_TYPE_INT_RANGE, type->width.lower, type->width.upper,
|
||||
"height", GST_TYPE_INT_RANGE, type->height.lower,
|
||||
type->height.upper, "framerate", GST_TYPE_FRACTION_RANGE,
|
||||
type->framerate.lower, 1, type->framerate.upper, 1, "mpegversion",
|
||||
GST_TYPE_INT_RANGE, 1, 2, "systemstream", G_TYPE_BOOLEAN, FALSE,
|
||||
"parsed", G_TYPE_BOOLEAN, TRUE, NULL);
|
||||
|
||||
encoded_ret = gst_caps_merge_structure (encoded_ret, tmp);
|
||||
|
|
|
@ -41,6 +41,11 @@ struct _GstAmcCodecType {
|
|||
|
||||
GstAmcCodecProfileLevel * profile_levels;
|
||||
gsize n_profile_levels;
|
||||
|
||||
/* video codecs only */
|
||||
GstAmcValueRange width;
|
||||
GstAmcValueRange height;
|
||||
GstAmcValueRange framerate;
|
||||
};
|
||||
|
||||
struct _GstAmcCodecInfo {
|
||||
|
|
|
@ -38,6 +38,11 @@ struct _GstAmcCodecCapabilitiesHandle
|
|||
jobject object;
|
||||
};
|
||||
|
||||
struct _GstAmcVideoCapabilitiesHandle
|
||||
{
|
||||
jobject object;
|
||||
};
|
||||
|
||||
static struct
|
||||
{
|
||||
jclass klass;
|
||||
|
@ -57,6 +62,7 @@ static struct
|
|||
static struct
|
||||
{
|
||||
jclass klass;
|
||||
jmethodID get_video_capabilities;
|
||||
jfieldID color_formats;
|
||||
jfieldID profile_levels;
|
||||
} media_codeccapabilities;
|
||||
|
@ -68,11 +74,100 @@ static struct
|
|||
jfieldID profile;
|
||||
} media_codecprofilelevel;
|
||||
|
||||
static struct
|
||||
{
|
||||
jclass klass;
|
||||
jmethodID get_supported_heights;
|
||||
jmethodID get_supported_widths;
|
||||
jmethodID get_supported_framerates;
|
||||
} media_videocapabilities;
|
||||
|
||||
static struct
|
||||
{
|
||||
jclass klass;
|
||||
jmethodID get_lower;
|
||||
jmethodID get_upper;
|
||||
} util_range;
|
||||
|
||||
static struct
|
||||
{
|
||||
jclass klass;
|
||||
jmethodID int_value;
|
||||
} lang_integer;
|
||||
|
||||
static gboolean
|
||||
gst_amc_codeclist_jni_static_init_21 (void)
|
||||
{
|
||||
JNIEnv *env;
|
||||
GError *err = NULL;
|
||||
|
||||
env = gst_amc_jni_get_env ();
|
||||
|
||||
media_codeccapabilities.get_video_capabilities =
|
||||
gst_amc_jni_get_method_id (env, &err, media_codeccapabilities.klass,
|
||||
"getVideoCapabilities",
|
||||
"()Landroid/media/MediaCodecInfo$VideoCapabilities;");
|
||||
if (!media_codeccapabilities.get_video_capabilities) {
|
||||
GST_ERROR
|
||||
("Failed to get android.media.MediaCodecInfo getVideoCapabilities(): %s",
|
||||
err->message);
|
||||
g_clear_error (&err);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
media_videocapabilities.klass =
|
||||
gst_amc_jni_get_class (env, &err,
|
||||
"android/media/MediaCodecInfo$VideoCapabilities");
|
||||
if (!media_videocapabilities.klass) {
|
||||
GST_ERROR
|
||||
("Failed to get android.media.MediaCodecInfo.VideoCapabilities class: %s",
|
||||
err->message);
|
||||
g_clear_error (&err);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
media_videocapabilities.get_supported_widths =
|
||||
gst_amc_jni_get_method_id (env, &err, media_videocapabilities.klass,
|
||||
"getSupportedWidths", "()Landroid/util/Range;");
|
||||
if (!media_videocapabilities.get_supported_widths) {
|
||||
GST_ERROR
|
||||
("Failed to get android.media.MediaCodecInfo.VideoCapabilities getSupportedWidths(): %s",
|
||||
err->message);
|
||||
g_clear_error (&err);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
media_videocapabilities.get_supported_heights =
|
||||
gst_amc_jni_get_method_id (env, &err, media_videocapabilities.klass,
|
||||
"getSupportedHeights", "()Landroid/util/Range;");
|
||||
if (!media_videocapabilities.get_supported_heights) {
|
||||
GST_ERROR
|
||||
("Failed to get android.media.MediaCodecInfo.VideoCapabilities getSupportedHeights(): %s",
|
||||
err->message);
|
||||
g_clear_error (&err);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
media_videocapabilities.get_supported_framerates =
|
||||
gst_amc_jni_get_method_id (env, &err, media_videocapabilities.klass,
|
||||
"getSupportedFrameRates", "()Landroid/util/Range;");
|
||||
if (!media_videocapabilities.get_supported_framerates) {
|
||||
GST_ERROR
|
||||
("Failed to get android.media.MediaCodecInfo.VideoCapabilities getSupportedFrameRates(): %s",
|
||||
err->message);
|
||||
g_clear_error (&err);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_amc_codeclist_jni_static_init (void)
|
||||
{
|
||||
JNIEnv *env;
|
||||
GError *err = NULL;
|
||||
gboolean api_level_gt_21 = android_get_device_api_level () > 21;
|
||||
|
||||
env = gst_amc_jni_get_env ();
|
||||
|
||||
|
@ -224,6 +319,50 @@ gst_amc_codeclist_jni_static_init (void)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
util_range.klass = gst_amc_jni_get_class (env, &err, "android/util/Range");
|
||||
if (!util_range.klass) {
|
||||
GST_ERROR ("Failed to get android.util.Range class: %s", err->message);
|
||||
g_clear_error (&err);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
util_range.get_lower =
|
||||
gst_amc_jni_get_method_id (env, &err, util_range.klass, "getLower",
|
||||
"()Ljava/lang/Comparable;");
|
||||
if (!util_range.get_lower) {
|
||||
GST_ERROR ("Failed to get android.util.Range getLower(): %s", err->message);
|
||||
g_clear_error (&err);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
util_range.get_upper =
|
||||
gst_amc_jni_get_method_id (env, &err, util_range.klass, "getUpper",
|
||||
"()Ljava/lang/Comparable;");
|
||||
if (!util_range.get_upper) {
|
||||
GST_ERROR ("Failed to get android.util.Range getUpper(): %s", err->message);
|
||||
g_clear_error (&err);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
lang_integer.klass = gst_amc_jni_get_class (env, &err, "java/lang/Integer");
|
||||
if (!lang_integer.klass) {
|
||||
GST_ERROR ("Failed to get java.lang.Integer class: %s", err->message);
|
||||
g_clear_error (&err);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
lang_integer.int_value =
|
||||
gst_amc_jni_get_method_id (env, &err, lang_integer.klass, "intValue",
|
||||
"()I");
|
||||
if (!lang_integer.int_value) {
|
||||
GST_ERROR ("Failed to get java.lang.Integer intValue(): %s", err->message);
|
||||
g_clear_error (&err);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (api_level_gt_21)
|
||||
return gst_amc_codeclist_jni_static_init_21 ();
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -518,3 +657,133 @@ done:
|
|||
|
||||
return ret;
|
||||
}
|
||||
|
||||
GstAmcVideoCapabilitiesHandle *
|
||||
gst_amc_capabilities_get_video_capabilities (GstAmcCodecCapabilitiesHandle *
|
||||
handle, GError ** err)
|
||||
{
|
||||
GstAmcVideoCapabilitiesHandle *ret = NULL;
|
||||
jobject object;
|
||||
JNIEnv *env;
|
||||
|
||||
env = gst_amc_jni_get_env ();
|
||||
|
||||
if (!gst_amc_jni_call_object_method (env, err, handle->object,
|
||||
media_codeccapabilities.get_video_capabilities, &object))
|
||||
goto done;
|
||||
|
||||
ret = g_new0 (GstAmcVideoCapabilitiesHandle, 1);
|
||||
ret->object = object;
|
||||
|
||||
done:
|
||||
return ret;
|
||||
}
|
||||
|
||||
void gst_amc_capabilities_video_capabilities_handle_free
|
||||
(GstAmcVideoCapabilitiesHandle * handle)
|
||||
{
|
||||
JNIEnv *env;
|
||||
|
||||
if (!handle)
|
||||
return;
|
||||
|
||||
env = gst_amc_jni_get_env ();
|
||||
|
||||
if (handle->object)
|
||||
gst_amc_jni_object_local_unref (env, handle->object);
|
||||
g_free (handle);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_amc_from_range (jobject range, GstAmcValueRange * res, GError ** err)
|
||||
{
|
||||
jobject lower, upper;
|
||||
JNIEnv *env;
|
||||
gint lower_int, upper_int;
|
||||
|
||||
env = gst_amc_jni_get_env ();
|
||||
|
||||
if (!gst_amc_jni_call_object_method (env, err, range,
|
||||
util_range.get_lower, &lower))
|
||||
return;
|
||||
|
||||
if (!gst_amc_jni_call_object_method (env, err, range,
|
||||
util_range.get_upper, &upper))
|
||||
return;
|
||||
|
||||
if (!gst_amc_jni_call_int_method (env, err, lower,
|
||||
lang_integer.int_value, &lower_int))
|
||||
return;
|
||||
|
||||
if (!gst_amc_jni_call_int_method (env, err, upper,
|
||||
lang_integer.int_value, &upper_int))
|
||||
return;
|
||||
|
||||
if (lower_int != upper_int) {
|
||||
res->lower = MAX (res->lower, lower_int);
|
||||
res->upper = MIN (res->upper, upper_int);
|
||||
}
|
||||
}
|
||||
|
||||
GstAmcValueRange
|
||||
gst_amc_video_capabilities_get_widths (GstAmcVideoCapabilitiesHandle * handle,
|
||||
GError ** err)
|
||||
{
|
||||
GstAmcValueRange ret = { 16, 4096 };
|
||||
jobject range;
|
||||
JNIEnv *env;
|
||||
|
||||
if (!handle)
|
||||
goto out;
|
||||
|
||||
env = gst_amc_jni_get_env ();
|
||||
|
||||
if (gst_amc_jni_call_object_method (env, err, handle->object,
|
||||
media_videocapabilities.get_supported_widths, &range))
|
||||
gst_amc_from_range (range, &ret, err);
|
||||
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
GstAmcValueRange
|
||||
gst_amc_video_capabilities_get_heights (GstAmcVideoCapabilitiesHandle * handle,
|
||||
GError ** err)
|
||||
{
|
||||
GstAmcValueRange ret = { 16, 4096 };
|
||||
jobject range;
|
||||
JNIEnv *env;
|
||||
|
||||
if (!handle)
|
||||
goto out;
|
||||
|
||||
env = gst_amc_jni_get_env ();
|
||||
|
||||
if (gst_amc_jni_call_object_method (env, err, handle->object,
|
||||
media_videocapabilities.get_supported_heights, &range))
|
||||
gst_amc_from_range (range, &ret, err);
|
||||
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
GstAmcValueRange
|
||||
gst_amc_video_capabilities_get_framerates (GstAmcVideoCapabilitiesHandle *
|
||||
handle, GError ** err)
|
||||
{
|
||||
GstAmcValueRange ret = { 0, G_MAXINT };
|
||||
jobject range;
|
||||
JNIEnv *env;
|
||||
|
||||
if (!handle)
|
||||
goto out;
|
||||
|
||||
env = gst_amc_jni_get_env ();
|
||||
|
||||
if (gst_amc_jni_call_object_method (env, err, handle->object,
|
||||
media_videocapabilities.get_supported_framerates, &range))
|
||||
gst_amc_from_range (range, &ret, err);
|
||||
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue