mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-10-06 10:42:22 +00:00
amc: Add H.265 encoder mapping.
Add mime type mapping to enable the use of Android H.265 encoders Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/2572>
This commit is contained in:
parent
1a12d1344e
commit
3e1528f1fb
4 changed files with 85 additions and 25 deletions
|
@ -148,7 +148,8 @@ enum
|
||||||
HEVCHighTierLevel6 = 0x200000,
|
HEVCHighTierLevel6 = 0x200000,
|
||||||
HEVCMainTierLevel61 = 0x400000,
|
HEVCMainTierLevel61 = 0x400000,
|
||||||
HEVCHighTierLevel61 = 0x800000,
|
HEVCHighTierLevel61 = 0x800000,
|
||||||
HEVCMainTierLevel62 = 0x1000000
|
HEVCMainTierLevel62 = 0x1000000,
|
||||||
|
HEVCHighTierLevel62 = 0x2000000
|
||||||
};
|
};
|
||||||
|
|
||||||
enum
|
enum
|
||||||
|
|
|
@ -1141,7 +1141,8 @@ static const struct
|
||||||
HEVCHighTierLevel51, "high", "5.1"}, {
|
HEVCHighTierLevel51, "high", "5.1"}, {
|
||||||
HEVCHighTierLevel52, "high", "5.2"}, {
|
HEVCHighTierLevel52, "high", "5.2"}, {
|
||||||
HEVCHighTierLevel6, "high", "6"}, {
|
HEVCHighTierLevel6, "high", "6"}, {
|
||||||
HEVCHighTierLevel61, "high", "6.1"}
|
HEVCHighTierLevel61, "high", "6.1"}, {
|
||||||
|
HEVCHighTierLevel62, "high", "6.2"}
|
||||||
};
|
};
|
||||||
|
|
||||||
const gchar *
|
const gchar *
|
||||||
|
@ -2334,35 +2335,40 @@ gst_amc_codec_info_to_caps (const GstAmcCodecInfo * codec_info,
|
||||||
tmp2 = gst_structure_copy (tmp);
|
tmp2 = gst_structure_copy (tmp);
|
||||||
gst_structure_set (tmp2, "profile", G_TYPE_STRING, profile, NULL);
|
gst_structure_set (tmp2, "profile", G_TYPE_STRING, profile, NULL);
|
||||||
|
|
||||||
/* FIXME: Implement tier/level support here */
|
|
||||||
#if 0
|
|
||||||
if (codec_info->is_encoder) {
|
if (codec_info->is_encoder) {
|
||||||
const gchar *level, *tier;
|
const gchar *level, *tier;
|
||||||
gint k;
|
gint k;
|
||||||
GValue va = { 0, };
|
|
||||||
GValue v = { 0, };
|
GValue v = { 0, };
|
||||||
|
|
||||||
g_value_init (&va, GST_TYPE_LIST);
|
|
||||||
g_value_init (&v, G_TYPE_STRING);
|
g_value_init (&v, G_TYPE_STRING);
|
||||||
for (k = 1; k <= type->profile_levels[j].level && k != 0;
|
for (k = 1; k <= type->profile_levels[j].level && k != 0;
|
||||||
k <<= 1) {
|
k <<= 1) {
|
||||||
level = gst_amc_hevc_tier_level_to_string (k, &tier);
|
level = gst_amc_hevc_tier_level_to_string (k, &tier);
|
||||||
if (!level)
|
if (!level || !tier)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
g_value_set_string (&v, level);
|
tmp3 = gst_structure_copy (tmp2);
|
||||||
gst_value_list_append_value (&va, &v);
|
|
||||||
|
g_value_set_string (&v, tier);
|
||||||
|
gst_structure_set_value (tmp3, "tier", &v);
|
||||||
g_value_reset (&v);
|
g_value_reset (&v);
|
||||||
|
|
||||||
|
g_value_set_string (&v, level);
|
||||||
|
gst_structure_set_value (tmp3, "level", &v);
|
||||||
|
g_value_reset (&v);
|
||||||
|
|
||||||
|
encoded_ret = gst_caps_merge_structure (encoded_ret, tmp3);
|
||||||
|
|
||||||
|
have_profile_level = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
gst_structure_set_value (tmp2, "level", &va);
|
|
||||||
|
|
||||||
g_value_unset (&va);
|
|
||||||
g_value_unset (&v);
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
encoded_ret = gst_caps_merge_structure (encoded_ret, tmp2);
|
if (have_profile_level) {
|
||||||
|
gst_structure_free (tmp2);
|
||||||
|
} else {
|
||||||
|
encoded_ret = gst_caps_merge_structure (encoded_ret, tmp2);
|
||||||
|
}
|
||||||
|
|
||||||
have_profile_level = TRUE;
|
have_profile_level = TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -213,6 +213,21 @@ create_amc_format (GstAmcVideoEnc * encoder, GstVideoCodecState * input_state,
|
||||||
amc_level.key = "level"; /* named level ? */
|
amc_level.key = "level"; /* named level ? */
|
||||||
amc_level.id = gst_amc_avc_level_from_string (level_string);
|
amc_level.id = gst_amc_avc_level_from_string (level_string);
|
||||||
}
|
}
|
||||||
|
} else if (strcmp (name, "video/x-h265") == 0) {
|
||||||
|
const gchar *tier_string = gst_structure_get_string (s, "tier");
|
||||||
|
|
||||||
|
mime = "video/hevc";
|
||||||
|
|
||||||
|
if (profile_string) {
|
||||||
|
amc_profile.key = "profile"; /* named profile ? */
|
||||||
|
amc_profile.id = gst_amc_hevc_profile_from_string (profile_string);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (level_string && tier_string) {
|
||||||
|
amc_level.key = "level"; /* named level ? */
|
||||||
|
amc_level.id =
|
||||||
|
gst_amc_hevc_tier_level_from_string (tier_string, level_string);
|
||||||
|
}
|
||||||
} else if (strcmp (name, "video/x-vp8") == 0) {
|
} else if (strcmp (name, "video/x-vp8") == 0) {
|
||||||
mime = "video/x-vnd.on2.vp8";
|
mime = "video/x-vnd.on2.vp8";
|
||||||
} else if (strcmp (name, "video/x-vp9") == 0) {
|
} else if (strcmp (name, "video/x-vp9") == 0) {
|
||||||
|
@ -414,6 +429,32 @@ caps_from_amc_format (GstAmcFormat * amc_format)
|
||||||
|
|
||||||
gst_caps_set_simple (caps, "level", G_TYPE_STRING, level_string, NULL);
|
gst_caps_set_simple (caps, "level", G_TYPE_STRING, level_string, NULL);
|
||||||
}
|
}
|
||||||
|
} else if (strcmp (mime, "video/hevc") == 0) {
|
||||||
|
const gchar *profile_string, *level_string, *tier_string;
|
||||||
|
|
||||||
|
caps =
|
||||||
|
gst_caps_new_simple ("video/x-h265",
|
||||||
|
"stream-format", G_TYPE_STRING, "byte-stream", NULL);
|
||||||
|
|
||||||
|
if (gst_amc_format_get_int (amc_format, "profile", &amc_profile, NULL)) {
|
||||||
|
profile_string = gst_amc_avc_profile_to_string (amc_profile, NULL);
|
||||||
|
if (!profile_string)
|
||||||
|
goto unsupported_profile;
|
||||||
|
|
||||||
|
gst_caps_set_simple (caps, "profile", G_TYPE_STRING, profile_string,
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gst_amc_format_get_int (amc_format, "level", &amc_level, NULL)) {
|
||||||
|
level_string =
|
||||||
|
gst_amc_hevc_tier_level_to_string (amc_profile, &tier_string);
|
||||||
|
if (!level_string || !tier_string)
|
||||||
|
goto unsupported_level;
|
||||||
|
|
||||||
|
gst_caps_set_simple (caps,
|
||||||
|
"level", G_TYPE_STRING, level_string,
|
||||||
|
"tier", G_TYPE_STRING, tier_string, NULL);
|
||||||
|
}
|
||||||
} else if (strcmp (mime, "video/x-vnd.on2.vp8") == 0) {
|
} else if (strcmp (mime, "video/x-vnd.on2.vp8") == 0) {
|
||||||
caps = gst_caps_new_empty_simple ("video/x-vp8");
|
caps = gst_caps_new_empty_simple ("video/x-vp8");
|
||||||
} else if (strcmp (mime, "video/x-vnd.on2.vp9") == 0) {
|
} else if (strcmp (mime, "video/x-vnd.on2.vp9") == 0) {
|
||||||
|
@ -847,6 +888,7 @@ gst_amc_video_enc_set_src_caps (GstAmcVideoEnc * self, GstAmcFormat * format)
|
||||||
{
|
{
|
||||||
GstCaps *caps;
|
GstCaps *caps;
|
||||||
GstVideoCodecState *output_state;
|
GstVideoCodecState *output_state;
|
||||||
|
GstStructure *s;
|
||||||
|
|
||||||
caps = caps_from_amc_format (format);
|
caps = caps_from_amc_format (format);
|
||||||
if (!caps) {
|
if (!caps) {
|
||||||
|
@ -871,6 +913,17 @@ gst_amc_video_enc_set_src_caps (GstAmcVideoEnc * self, GstAmcFormat * format)
|
||||||
if (!gst_video_encoder_negotiate (GST_VIDEO_ENCODER (self)))
|
if (!gst_video_encoder_negotiate (GST_VIDEO_ENCODER (self)))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
|
output_state = gst_video_encoder_get_output_state (GST_VIDEO_ENCODER (self));
|
||||||
|
s = gst_caps_get_structure (output_state->caps, 0);
|
||||||
|
|
||||||
|
if (!strcmp (gst_structure_get_name (s), "video/x-h264") ||
|
||||||
|
!strcmp (gst_structure_get_name (s), "video/x-h265")) {
|
||||||
|
self->codec_data_in_bytestream = TRUE;
|
||||||
|
} else {
|
||||||
|
self->codec_data_in_bytestream = FALSE;
|
||||||
|
}
|
||||||
|
gst_video_codec_state_unref (output_state);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -906,14 +959,8 @@ gst_amc_video_enc_handle_output_frame (GstAmcVideoEnc * self,
|
||||||
* gstomxvideoenc.c and gstomxh264enc.c */
|
* gstomxvideoenc.c and gstomxh264enc.c */
|
||||||
if ((buffer_info->flags & BUFFER_FLAG_CODEC_CONFIG)
|
if ((buffer_info->flags & BUFFER_FLAG_CODEC_CONFIG)
|
||||||
&& buffer_info->size > 0) {
|
&& buffer_info->size > 0) {
|
||||||
GstStructure *s;
|
|
||||||
GstVideoCodecState *state;
|
|
||||||
|
|
||||||
state = gst_video_encoder_get_output_state (encoder);
|
|
||||||
s = gst_caps_get_structure (state->caps, 0);
|
|
||||||
if (!strcmp (gst_structure_get_name (s), "video/x-h264")) {
|
|
||||||
gst_video_codec_state_unref (state);
|
|
||||||
|
|
||||||
|
if (self->codec_data_in_bytestream) {
|
||||||
if (buffer_info->size > 4 &&
|
if (buffer_info->size > 4 &&
|
||||||
GST_READ_UINT32_BE (buf->data + buffer_info->offset) == 0x00000001) {
|
GST_READ_UINT32_BE (buf->data + buffer_info->offset) == 0x00000001) {
|
||||||
GList *l = NULL;
|
GList *l = NULL;
|
||||||
|
@ -933,14 +980,16 @@ gst_amc_video_enc_handle_output_frame (GstAmcVideoEnc * self,
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
GstBuffer *codec_data;
|
GstBuffer *codec_data;
|
||||||
|
GstVideoCodecState *output_state =
|
||||||
|
gst_video_encoder_get_output_state (GST_VIDEO_ENCODER (self));
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (self, "Handling codec data");
|
GST_DEBUG_OBJECT (self, "Handling codec data");
|
||||||
|
|
||||||
codec_data = gst_buffer_new_and_alloc (buffer_info->size);
|
codec_data = gst_buffer_new_and_alloc (buffer_info->size);
|
||||||
gst_buffer_fill (codec_data, 0, buf->data + buffer_info->offset,
|
gst_buffer_fill (codec_data, 0, buf->data + buffer_info->offset,
|
||||||
buffer_info->size);
|
buffer_info->size);
|
||||||
state->codec_data = codec_data;
|
output_state->codec_data = codec_data;
|
||||||
gst_video_codec_state_unref (state);
|
gst_video_codec_state_unref (output_state);
|
||||||
|
|
||||||
if (!gst_video_encoder_negotiate (encoder)) {
|
if (!gst_video_encoder_negotiate (encoder)) {
|
||||||
gst_video_codec_frame_unref (frame);
|
gst_video_codec_frame_unref (frame);
|
||||||
|
|
|
@ -56,6 +56,10 @@ struct _GstAmcVideoEnc
|
||||||
GstAmcCodec *codec;
|
GstAmcCodec *codec;
|
||||||
GstAmcFormat *amc_format;
|
GstAmcFormat *amc_format;
|
||||||
|
|
||||||
|
/* Set to TRUE if codec headers should be placed
|
||||||
|
* in the stream, or FALSE if they go in the headers */
|
||||||
|
gboolean codec_data_in_bytestream;
|
||||||
|
|
||||||
GstVideoCodecState *input_state;
|
GstVideoCodecState *input_state;
|
||||||
|
|
||||||
/* Input format of the codec */
|
/* Input format of the codec */
|
||||||
|
|
Loading…
Reference in a new issue