summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSreerenj Balachandran <sreerenj.balachandran@intel.com>2020-12-02 12:03:23 -0800
committerSreerenj Balachandran <sreerenj.balachandran@intel.com>2020-12-02 12:03:23 -0800
commit60eca871f1bca3d601e1a30baa1f1f2e78fcad35 (patch)
tree5a82f420e296a013a085fdd20cb59b9536ba4893
parent564ca931f490fefce38793547db993073897bcad (diff)
Fix temporal SVC reference picture model for VP9Enc
Now the 2 layer temporal model is similar to libvpx mode. eg: libvpx: ./vp9_spatial_svc_encoder --width=1280 --height=720 --passes=1 --rc-end-usage=1 --target-bitrate=4096 --min-bitrate=4096 --max-bitrate=4096 --spatial-layers=1 --temporal-layers=2 --temporal-layering-mode=2 --timebase=1/30 --kf-dist=30 -o sample_vp9.webm /home/sreerenj/Videos/raw/sample_1280_720_300f_i420.yuv eg: gst:gst-launch-1.0 videotestsrc num-buffers=300 ! video/x-raw, width=1280, height=720, framerate=30/1 ! vaapivp9enc enable-software-brc=true bitrate=4096 k-svc=false temporal-svc=true ! webmmux ! filesink location=sample.webm
-rw-r--r--gst-libs/gst/vaapi/gstvaapiencoder_vp9.c84
1 files changed, 59 insertions, 25 deletions
diff --git a/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c b/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c
index fbd8b856..798c7f1f 100644
--- a/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c
+++ b/gst-libs/gst/vaapi/gstvaapiencoder_vp9.c
@@ -30,6 +30,8 @@
#include "gstvaapisurface.h"
#include "gstvaapifilter.h"
+#define GST_VP9_REF_FRAMES_TEMPORAL_SVC 2
+
#if USE_LIBMEBO
#include <libmebo/libmebo.h>
#endif
@@ -406,24 +408,37 @@ get_ref_indices_k_svc (guint ref_list_idx, guint spatial_group_count,
}
static void
-get_ref_indices_temporal_svc (guint ref_list_idx, guint temporal_id,
+get_ref_indices_temporal_svc (guint frame_num, guint ref_list_idx, guint temporal_id,
guint * last_idx, guint * gf_idx, guint * arf_idx,
guint * ref_frame_ctrl_l0, guint8 * refresh_frame_flags)
{
gint last_filled_idx;
- last_filled_idx = (ref_list_idx - 1) & (GST_VP9_REF_FRAMES - 1);
+ last_filled_idx = (ref_list_idx - 1) % GST_VP9_REF_FRAMES_TEMPORAL_SVC;
*ref_frame_ctrl_l0 = 0x07;
- *refresh_frame_flags = 1 << ((last_filled_idx + 1) % GST_VP9_REF_FRAMES);
+
+ if (frame_num % 2 != 0)
+ *refresh_frame_flags = 2;
+ else
+ *refresh_frame_flags = 1;
+
+ //g_message ("Debug: frame_num=%d get_ref_indices last-filled-idx= %d temporal_id=%d refresh_frame_flags=%d",frame_num, last_filled_idx, temporal_id,*refresh_frame_flags);
//Non Base Layer
if (temporal_id == 1) {
- *last_idx = last_filled_idx;
- *arf_idx = *gf_idx = (last_filled_idx - 1) & (GST_VP9_REF_FRAMES - 1);
+ *last_idx = *gf_idx = last_filled_idx;
+ if (frame_num == 1) {
+ *arf_idx = *last_idx;
+ } else {
+ if (last_filled_idx == 0)
+ *arf_idx = 1;
+ else
+ *arf_idx = 0;
+ }
} else if (temporal_id == 0) {
//Base Layer
- *last_idx = *arf_idx = *gf_idx = ((last_filled_idx-1) & (GST_VP9_REF_FRAMES - 1));
+ *last_idx = *arf_idx = *gf_idx = 0;;
} else {
g_message ("Temproal id is >1, something went wrong! ");
}
@@ -480,7 +495,29 @@ fill_picture_temporal_svc (GstVaapiEncoderVP9 * encoder,
guint8 refresh_frame_flags = 0;
guint width, height;
guint ref_frame_ctrl_l0 = 0;
+ guint i =0;
+ /* Update Reference Frame list */
+ if (picture->type == GST_VAAPI_PICTURE_TYPE_I)
+ memset (pic_param->reference_frames, 0xFF,
+ sizeof (pic_param->reference_frames));
+ else {
+ for (i = 0; i < G_N_ELEMENTS (pic_param->reference_frames); i++) {
+ if (encoder->ref_list[i])
+ pic_param->reference_frames[i] =
+ GST_VAAPI_SURFACE_PROXY_SURFACE_ID (encoder->ref_list[i]);
+ else
+ pic_param->reference_frames[i] = VA_INVALID_ID;
+ }
+ }
+ pic_param->luma_ac_qindex = encoder->yac_qi;
+ pic_param->luma_dc_qindex_delta = 1;
+ pic_param->chroma_ac_qindex_delta = 1;
+ pic_param->chroma_dc_qindex_delta = 1;
+ pic_param->filter_level = encoder->loop_filter_level;
+ pic_param->sharpness_level = encoder->sharpness_level;
+
+ pic_param->pic_flags.bits.show_frame = 1;
width =
gst_vaapi_surface_get_width (GST_VAAPI_SURFACE_PROXY_SURFACE (surface));
height =
@@ -497,7 +534,7 @@ fill_picture_temporal_svc (GstVaapiEncoderVP9 * encoder,
if (picture->type == GST_VAAPI_PICTURE_TYPE_P) {
pic_param->pic_flags.bits.frame_type = GST_VP9_INTER_FRAME;
- get_ref_indices_temporal_svc (encoder->ref_list_idx, picture->temporal_id,
+ get_ref_indices_temporal_svc (encoder->frame_num-1,encoder->ref_list_idx, picture->temporal_id,
&last_idx, &gf_idx, &arf_idx, &ref_frame_ctrl_l0, &refresh_frame_flags);
pic_param->ref_flags.bits.ref_frame_ctrl_l0 = ref_frame_ctrl_l0;
@@ -524,6 +561,10 @@ fill_picture (GstVaapiEncoderVP9 * encoder,
pic_param->reconstructed_frame = GST_VAAPI_SURFACE_PROXY_SURFACE_ID (surface);
pic_param->coded_buf = GST_VAAPI_CODED_BUFFER_ID (codedbuf);
+ //temporal-svc
+ if (encoder->temporal_svc && (encoder->num_temporal_layers))
+ return fill_picture_temporal_svc (encoder, picture, codedbuf, surface, pic_param);
+
/* Update Reference Frame list */
if (picture->type == GST_VAAPI_PICTURE_TYPE_I)
memset (pic_param->reference_frames, 0xFF,
@@ -548,9 +589,6 @@ fill_picture (GstVaapiEncoderVP9 * encoder,
if (encoder->k_svc && (encoder->num_spatial_layers))
return fill_picture_k_svc (encoder, picture, codedbuf, surface, pic_param);
- //temporal-svc
- if (encoder->temporal_svc && (encoder->num_temporal_layers))
- return fill_picture_temporal_svc (encoder, picture, codedbuf, surface, pic_param);
/* It is possible to have dynamic scaling with gpu by providing
* src and destination resoltuion. For now we are just using
@@ -658,22 +696,11 @@ update_ref_list_temporal_svc (GstVaapiEncoderVP9 * encoder,
GstVaapiEncPicture * picture, GstVaapiSurfaceProxy * ref)
{
guint i;
-
- if (picture->type == GST_VAAPI_PICTURE_TYPE_I) {
- for (i = 0; i < G_N_ELEMENTS (encoder->ref_list); i++)
- gst_vaapi_surface_proxy_replace (&encoder->ref_list[i], ref);
- gst_vaapi_surface_proxy_unref (ref);
- /* set next free slot index */
- encoder->ref_list_idx = 1;
- return;
- } else {
- if (encoder->ref_list_idx == 0)
- encoder->ref_list_idx = 1;
- }
i = encoder->ref_list_idx;
gst_vaapi_surface_proxy_replace (&encoder->ref_list[i], ref);
gst_vaapi_surface_proxy_unref (ref);
- encoder->ref_list_idx = (encoder->ref_list_idx + 1) % GST_VP9_REF_FRAMES;
+ encoder->ref_list_idx = (encoder->ref_list_idx + 1) % GST_VP9_REF_FRAMES_TEMPORAL_SVC;
+ //g_message ("Debug: update_ref_list: ref_list_idx=next_free_slot = %d",encoder->ref_list_idx);
}
static GstVaapiEncoderStatus
@@ -813,7 +840,10 @@ gst_vaapi_encoder_vp9_encode (GstVaapiEncoder * base_encoder,
encoder->loop_filter_level = lf;
- g_message ("QP = %d : LF_Strength = %d",qp,lf);
+ if (picture->type != GST_VAAPI_PICTURE_TYPE_P)
+ g_message ("KeyFrame: QP = %d : LF_Strength = %d",qp,lf);
+ else
+ g_message ("PFrame: QP = %d : LF_Strength = %d",qp,lf);
}
#endif
@@ -843,7 +873,10 @@ gst_vaapi_encoder_vp9_encode (GstVaapiEncoder * base_encoder,
if (encoder->software_brc) {
gint32 buf_size;
buf_size = gst_vaapi_coded_buffer_get_size (GST_VAAPI_CODED_BUFFER_PROXY_BUFFER (codedbuf));
- g_message ("PostEncodeBufferSize = %d ",buf_size);
+ if (picture->type != GST_VAAPI_PICTURE_TYPE_P)
+ g_message ("KeyFrame: PostEncodeBufferSize = %d ",buf_size);
+ else
+ g_message ("PFrame: PostEncodeBufferSize = %d ",buf_size);
libmebo_rate_controller_update_frame_size (encoder->libmebo_rc, buf_size);
}
@@ -1021,6 +1054,7 @@ gst_vaapi_encoder_vp9_reordering_temporal_svc (GstVaapiEncoder * base_encoder,
picture->temporal_id = encoder->temporal_id;
encoder->temporal_id = (encoder->temporal_id + 1) % encoder->num_temporal_layers;
+ //g_message ("Debug:Reordering_TemporalId = %d \n",picture->temporal_id);
return status;
}
static GstVaapiEncoderStatus