mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-19 14:56:36 +00:00
vp9: Add support for YV12, Y42B and Y444 color formats
The encoder does not work with Y42B and Y444 yet it seems.
This commit is contained in:
parent
9788976fd4
commit
9b7a6a3f90
2 changed files with 74 additions and 13 deletions
|
@ -123,7 +123,7 @@ static GstStaticPadTemplate gst_vp9_dec_src_template =
|
|||
GST_STATIC_PAD_TEMPLATE ("src",
|
||||
GST_PAD_SRC,
|
||||
GST_PAD_ALWAYS,
|
||||
GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE ("I420"))
|
||||
GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE ("{ I420, YV12, Y42B, Y444 }"))
|
||||
);
|
||||
|
||||
#define parent_class gst_vp9_dec_parent_class
|
||||
|
@ -397,7 +397,6 @@ open_codec (GstVP9Dec * dec, GstVideoCodecFrame * frame)
|
|||
vpx_codec_stream_info_t stream_info;
|
||||
vpx_codec_caps_t caps;
|
||||
vpx_codec_dec_cfg_t cfg;
|
||||
GstVideoCodecState *state = dec->input_state;
|
||||
vpx_codec_err_t status;
|
||||
GstMapInfo minfo;
|
||||
|
||||
|
@ -431,13 +430,6 @@ open_codec (GstVP9Dec * dec, GstVideoCodecFrame * frame)
|
|||
stream_info.w = dec->input_state->info.width;
|
||||
stream_info.h = dec->input_state->info.height;
|
||||
|
||||
g_assert (dec->output_state == NULL);
|
||||
dec->output_state =
|
||||
gst_video_decoder_set_output_state (GST_VIDEO_DECODER (dec),
|
||||
GST_VIDEO_FORMAT_I420, stream_info.w, stream_info.h, state);
|
||||
gst_video_decoder_negotiate (GST_VIDEO_DECODER (dec));
|
||||
gst_vp9_dec_send_tags (dec);
|
||||
|
||||
cfg.w = stream_info.w;
|
||||
cfg.h = stream_info.h;
|
||||
cfg.threads = dec->threads;
|
||||
|
@ -531,6 +523,50 @@ gst_vp9_dec_handle_frame (GstVideoDecoder * decoder, GstVideoCodecFrame * frame)
|
|||
|
||||
img = vpx_codec_get_frame (&dec->decoder, &iter);
|
||||
if (img) {
|
||||
GstVideoFormat fmt;
|
||||
|
||||
switch (img->fmt) {
|
||||
case VPX_IMG_FMT_I420:
|
||||
fmt = GST_VIDEO_FORMAT_I420;
|
||||
break;
|
||||
case VPX_IMG_FMT_YV12:
|
||||
fmt = GST_VIDEO_FORMAT_YV12;
|
||||
break;
|
||||
case VPX_IMG_FMT_I422:
|
||||
fmt = GST_VIDEO_FORMAT_Y42B;
|
||||
break;
|
||||
case VPX_IMG_FMT_I444:
|
||||
fmt = GST_VIDEO_FORMAT_Y444;
|
||||
break;
|
||||
default:
|
||||
vpx_img_free (img);
|
||||
GST_ELEMENT_ERROR (decoder, LIBRARY, ENCODE,
|
||||
("Failed to decode frame"), ("Unsupported color format %d",
|
||||
img->fmt));
|
||||
return GST_FLOW_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
/* FIXME: Width/height in the img is wrong */
|
||||
if (!dec->output_state || dec->output_state->info.finfo->format != fmt /*||
|
||||
dec->output_state->info.width != img->w ||
|
||||
dec->output_state->info.height != img->h */ ) {
|
||||
gboolean send_tags = !dec->output_state;
|
||||
|
||||
if (dec->output_state)
|
||||
gst_video_codec_state_unref (dec->output_state);
|
||||
|
||||
/* FIXME: The width/height in the img is wrong */
|
||||
dec->output_state =
|
||||
gst_video_decoder_set_output_state (GST_VIDEO_DECODER (dec),
|
||||
fmt, dec->input_state->info.width, dec->input_state->info.height,
|
||||
dec->input_state);
|
||||
gst_video_decoder_negotiate (GST_VIDEO_DECODER (dec));
|
||||
|
||||
if (send_tags)
|
||||
gst_vp9_dec_send_tags (dec);
|
||||
}
|
||||
|
||||
if (deadline < 0) {
|
||||
GST_LOG_OBJECT (dec, "Skipping late frame (%f s past deadline)",
|
||||
(double) -deadline / GST_SECOND);
|
||||
|
|
|
@ -353,11 +353,13 @@ static gboolean gst_vp9_enc_sink_event (GstVideoEncoder *
|
|||
static gboolean gst_vp9_enc_propose_allocation (GstVideoEncoder * encoder,
|
||||
GstQuery * query);
|
||||
|
||||
/* FIXME: Y42B and Y444 do not work yet it seems */
|
||||
static GstStaticPadTemplate gst_vp9_enc_sink_template =
|
||||
GST_STATIC_PAD_TEMPLATE ("sink",
|
||||
GST_PAD_SINK,
|
||||
GST_PAD_ALWAYS,
|
||||
GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE ("I420"))
|
||||
/*GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE ("{ I420, YV12, Y42B, Y444 }")) */
|
||||
GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE ("{ I420, YV12 }"))
|
||||
);
|
||||
|
||||
static GstStaticPadTemplate gst_vp9_enc_src_template =
|
||||
|
@ -1675,9 +1677,32 @@ gst_vp9_enc_set_format (GstVideoEncoder * video_encoder,
|
|||
image = &encoder->image;
|
||||
memset (image, 0, sizeof (*image));
|
||||
|
||||
image->fmt = VPX_IMG_FMT_I420;
|
||||
image->bps = 12;
|
||||
image->x_chroma_shift = image->y_chroma_shift = 1;
|
||||
switch (encoder->input_state->info.finfo->format) {
|
||||
case GST_VIDEO_FORMAT_I420:
|
||||
image->fmt = VPX_IMG_FMT_I420;
|
||||
image->bps = 12;
|
||||
image->x_chroma_shift = image->y_chroma_shift = 1;
|
||||
break;
|
||||
case GST_VIDEO_FORMAT_YV12:
|
||||
image->fmt = VPX_IMG_FMT_YV12;
|
||||
image->bps = 12;
|
||||
image->x_chroma_shift = image->y_chroma_shift = 1;
|
||||
break;
|
||||
case GST_VIDEO_FORMAT_Y42B:
|
||||
image->fmt = VPX_IMG_FMT_I422;
|
||||
image->bps = 16;
|
||||
image->x_chroma_shift = 1;
|
||||
image->y_chroma_shift = 0;
|
||||
break;
|
||||
case GST_VIDEO_FORMAT_Y444:
|
||||
image->fmt = VPX_IMG_FMT_I444;
|
||||
image->bps = 24;
|
||||
image->x_chroma_shift = image->y_chroma_shift = 0;
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
break;
|
||||
}
|
||||
image->w = image->d_w = GST_VIDEO_INFO_WIDTH (info);
|
||||
image->h = image->d_h = GST_VIDEO_INFO_HEIGHT (info);
|
||||
|
||||
|
|
Loading…
Reference in a new issue