mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-22 08:17:01 +00:00
av1enc: Add to configure image formats
Expanded to support image format to YV12/I422/I444. It's related to the color bit-depth and profile of the codec. It can make configuring appropriate profile according to bit-depth and format. https://bugzilla.gnome.org/show_bug.cgi?id=791674
This commit is contained in:
parent
cc9d65a512
commit
51d5db3f47
3 changed files with 92 additions and 3 deletions
|
@ -198,7 +198,7 @@ GST_STATIC_PAD_TEMPLATE ("sink",
|
||||||
GST_PAD_SINK,
|
GST_PAD_SINK,
|
||||||
GST_PAD_ALWAYS,
|
GST_PAD_ALWAYS,
|
||||||
GST_STATIC_CAPS ("video/x-raw, "
|
GST_STATIC_CAPS ("video/x-raw, "
|
||||||
"format = (string) \"I420\", "
|
"format = (string) { I420, Y42B, Y444, YV12 }, "
|
||||||
"framerate = (fraction) [0, MAX], "
|
"framerate = (fraction) [0, MAX], "
|
||||||
"width = (int) [ 4, MAX ], "
|
"width = (int) [ 4, MAX ], "
|
||||||
"height = (int) [ 4, MAX ]")
|
"height = (int) [ 4, MAX ]")
|
||||||
|
@ -382,6 +382,7 @@ gst_av1_enc_init (GstAV1Enc * av1enc)
|
||||||
|
|
||||||
av1enc->keyframe_dist = 30;
|
av1enc->keyframe_dist = 30;
|
||||||
av1enc->cpu_used = DEFAULT_CPU_USED;
|
av1enc->cpu_used = DEFAULT_CPU_USED;
|
||||||
|
av1enc->format = AOM_IMG_FMT_I420;
|
||||||
|
|
||||||
av1enc->aom_cfg.rc_dropframe_thresh = DEFAULT_DROP_FRAME;
|
av1enc->aom_cfg.rc_dropframe_thresh = DEFAULT_DROP_FRAME;
|
||||||
av1enc->aom_cfg.rc_resize_mode = DEFAULT_RESIZE_MODE;
|
av1enc->aom_cfg.rc_resize_mode = DEFAULT_RESIZE_MODE;
|
||||||
|
@ -404,7 +405,7 @@ gst_av1_enc_init (GstAV1Enc * av1enc)
|
||||||
av1enc->aom_cfg.g_timebase.num = DEFAULT_TIMEBASE_N;
|
av1enc->aom_cfg.g_timebase.num = DEFAULT_TIMEBASE_N;
|
||||||
av1enc->aom_cfg.g_timebase.den = DEFAULT_TIMEBASE_D;
|
av1enc->aom_cfg.g_timebase.den = DEFAULT_TIMEBASE_D;
|
||||||
av1enc->aom_cfg.g_bit_depth = DEFAULT_BIT_DEPTH;
|
av1enc->aom_cfg.g_bit_depth = DEFAULT_BIT_DEPTH;
|
||||||
av1enc->aom_cfg.g_input_bit_depth = (int) DEFAULT_BIT_DEPTH;
|
av1enc->aom_cfg.g_input_bit_depth = (unsigned int) DEFAULT_BIT_DEPTH;
|
||||||
|
|
||||||
g_mutex_init (&av1enc->encoder_lock);
|
g_mutex_init (&av1enc->encoder_lock);
|
||||||
}
|
}
|
||||||
|
@ -552,6 +553,54 @@ gst_av1_enc_get_downstream_profile (GstAV1Enc * av1enc)
|
||||||
return profile;
|
return profile;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gst_av1_enc_adjust_profile (GstAV1Enc * av1enc, GstVideoFormat format)
|
||||||
|
{
|
||||||
|
guint depth = av1enc->aom_cfg.g_bit_depth;
|
||||||
|
guint profile = av1enc->aom_cfg.g_profile;
|
||||||
|
gboolean update = FALSE;
|
||||||
|
|
||||||
|
switch (profile) {
|
||||||
|
case 0:
|
||||||
|
if (depth < 12 && format == GST_VIDEO_FORMAT_Y444) {
|
||||||
|
profile = 1;
|
||||||
|
update = TRUE;
|
||||||
|
} else if (depth == 12 || format == GST_VIDEO_FORMAT_Y42B) {
|
||||||
|
profile = 2;
|
||||||
|
update = TRUE;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
if (depth == 12 || format == GST_VIDEO_FORMAT_Y42B) {
|
||||||
|
profile = 2;
|
||||||
|
update = TRUE;
|
||||||
|
} else if (depth < 12 && format == GST_VIDEO_FORMAT_I420) {
|
||||||
|
profile = 0;
|
||||||
|
update = TRUE;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
if (depth < 12) {
|
||||||
|
if (format == GST_VIDEO_FORMAT_Y444) {
|
||||||
|
profile = 1;
|
||||||
|
update = TRUE;
|
||||||
|
} else if (format == GST_VIDEO_FORMAT_I420) {
|
||||||
|
profile = 0;
|
||||||
|
update = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (update) {
|
||||||
|
GST_INFO_OBJECT (av1enc, "profile updated to %d from %d",
|
||||||
|
profile, av1enc->aom_cfg.g_profile);
|
||||||
|
av1enc->aom_cfg.g_profile = profile;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_av1_enc_set_format (GstVideoEncoder * encoder, GstVideoCodecState * state)
|
gst_av1_enc_set_format (GstVideoEncoder * encoder, GstVideoCodecState * state)
|
||||||
{
|
{
|
||||||
|
@ -591,6 +640,18 @@ gst_av1_enc_set_format (GstVideoEncoder * encoder, GstVideoCodecState * state)
|
||||||
av1enc->aom_cfg.g_error_resilient = AOM_ERROR_RESILIENT_DEFAULT;
|
av1enc->aom_cfg.g_error_resilient = AOM_ERROR_RESILIENT_DEFAULT;
|
||||||
/* TODO: do more configuration including bit_depth config */
|
/* TODO: do more configuration including bit_depth config */
|
||||||
|
|
||||||
|
av1enc->format =
|
||||||
|
gst_video_format_to_av1_img_format (GST_VIDEO_INFO_FORMAT (info));
|
||||||
|
|
||||||
|
if (av1enc->aom_cfg.g_bit_depth != DEFAULT_BIT_DEPTH) {
|
||||||
|
av1enc->aom_cfg.g_input_bit_depth = av1enc->aom_cfg.g_bit_depth;
|
||||||
|
if (av1enc->aom_cfg.g_bit_depth > 8)
|
||||||
|
av1enc->format |= AOM_IMG_FMT_HIGHBITDEPTH;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Adjust profile according to format and bit-depth */
|
||||||
|
gst_av1_enc_adjust_profile (av1enc, GST_VIDEO_INFO_FORMAT (info));
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (av1enc, "Calling encoder init with config:");
|
GST_DEBUG_OBJECT (av1enc, "Calling encoder init with config:");
|
||||||
gst_av1_enc_debug_encoder_cfg (&av1enc->aom_cfg);
|
gst_av1_enc_debug_encoder_cfg (&av1enc->aom_cfg);
|
||||||
|
|
||||||
|
@ -672,7 +733,7 @@ gst_av1_enc_handle_frame (GstVideoEncoder * encoder, GstVideoCodecFrame * frame)
|
||||||
GstFlowReturn ret = GST_FLOW_OK;
|
GstFlowReturn ret = GST_FLOW_OK;
|
||||||
GstVideoFrame vframe;
|
GstVideoFrame vframe;
|
||||||
|
|
||||||
if (!aom_img_alloc (&raw, AOM_IMG_FMT_I420, av1enc->aom_cfg.g_w,
|
if (!aom_img_alloc (&raw, av1enc->format, av1enc->aom_cfg.g_w,
|
||||||
av1enc->aom_cfg.g_h, 1)) {
|
av1enc->aom_cfg.g_h, 1)) {
|
||||||
GST_ERROR_OBJECT (encoder, "Failed to initialize encoder");
|
GST_ERROR_OBJECT (encoder, "Failed to initialize encoder");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
|
@ -23,6 +23,19 @@
|
||||||
|
|
||||||
#include "gstav1utils.h"
|
#include "gstav1utils.h"
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
enum aom_img_fmt aom_format;
|
||||||
|
GstVideoFormat gst_format;
|
||||||
|
} AomImageFormat;
|
||||||
|
|
||||||
|
static const AomImageFormat img_formats[] = {
|
||||||
|
{AOM_IMG_FMT_YV12, GST_VIDEO_FORMAT_YV12},
|
||||||
|
{AOM_IMG_FMT_I420, GST_VIDEO_FORMAT_I420},
|
||||||
|
{AOM_IMG_FMT_I422, GST_VIDEO_FORMAT_Y42B},
|
||||||
|
{AOM_IMG_FMT_I444, GST_VIDEO_FORMAT_Y444},
|
||||||
|
};
|
||||||
|
|
||||||
const char *
|
const char *
|
||||||
gst_av1_get_error_name (aom_codec_err_t status)
|
gst_av1_get_error_name (aom_codec_err_t status)
|
||||||
{
|
{
|
||||||
|
@ -49,3 +62,16 @@ gst_av1_get_error_name (aom_codec_err_t status)
|
||||||
return "unknown";
|
return "unknown";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gint
|
||||||
|
gst_video_format_to_av1_img_format (GstVideoFormat format)
|
||||||
|
{
|
||||||
|
guint i;
|
||||||
|
|
||||||
|
for (i = 0; i < G_N_ELEMENTS (img_formats); i++)
|
||||||
|
if (img_formats[i].gst_format == format)
|
||||||
|
return img_formats[i].aom_format;
|
||||||
|
|
||||||
|
GST_WARNING ("av1 img format not found");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
|
@ -18,11 +18,13 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <gst/gst.h>
|
#include <gst/gst.h>
|
||||||
|
#include <gst/video/video.h>
|
||||||
#include <aom/aom_codec.h>
|
#include <aom/aom_codec.h>
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
const char *gst_av1_get_error_name (aom_codec_err_t status);
|
const char *gst_av1_get_error_name (aom_codec_err_t status);
|
||||||
|
gint gst_video_format_to_av1_img_format (GstVideoFormat format);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue