mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-25 09:40:37 +00:00
h264: introduce GST_VAAPI_PICTURE_{SHORT,LONG}_TERM_REFERENCE flags.
Further get rid of GstVaapiPictureH264-local VAPictureH264.flags for reference bits, thus simplifying the reference picture marking process to only track a single set of reference flags. Also introduce a new long_term_frame_idx member.
This commit is contained in:
parent
af22813f59
commit
3c721e1123
1 changed files with 56 additions and 44 deletions
|
@ -80,14 +80,38 @@ typedef struct _GstVaapiSliceH264Class GstVaapiSliceH264Class;
|
||||||
* Extended picture flags:
|
* Extended picture flags:
|
||||||
*
|
*
|
||||||
* @GST_VAAPI_PICTURE_FLAG_IDR: flag that specifies an IDR picture
|
* @GST_VAAPI_PICTURE_FLAG_IDR: flag that specifies an IDR picture
|
||||||
|
* @GST_VAAPI_PICTURE_FLAG_SHORT_TERM_REFERENCE: flag that specifies
|
||||||
|
* "used for short-term reference"
|
||||||
|
* @GST_VAAPI_PICTURE_FLAG_LONG_TERM_REFERENCE: flag that specifies
|
||||||
|
* "used for long-term reference"
|
||||||
|
* @GST_VAAPI_PICTURE_FLAGS_REFERENCE: mask covering any kind of
|
||||||
|
* reference picture (short-term reference or long-term reference)
|
||||||
*/
|
*/
|
||||||
enum {
|
enum {
|
||||||
GST_VAAPI_PICTURE_FLAG_IDR = (GST_VAAPI_PICTURE_FLAG_LAST << 0),
|
GST_VAAPI_PICTURE_FLAG_IDR = (GST_VAAPI_PICTURE_FLAG_LAST << 0),
|
||||||
|
|
||||||
|
GST_VAAPI_PICTURE_FLAG_SHORT_TERM_REFERENCE = (
|
||||||
|
GST_VAAPI_PICTURE_FLAG_REFERENCE),
|
||||||
|
GST_VAAPI_PICTURE_FLAG_LONG_TERM_REFERENCE = (
|
||||||
|
GST_VAAPI_PICTURE_FLAG_REFERENCE | (GST_VAAPI_PICTURE_FLAG_LAST << 1)),
|
||||||
|
GST_VAAPI_PICTURE_FLAGS_REFERENCE = (
|
||||||
|
GST_VAAPI_PICTURE_FLAG_SHORT_TERM_REFERENCE |
|
||||||
|
GST_VAAPI_PICTURE_FLAG_LONG_TERM_REFERENCE),
|
||||||
};
|
};
|
||||||
|
|
||||||
#define GST_VAAPI_PICTURE_IS_IDR(picture) \
|
#define GST_VAAPI_PICTURE_IS_IDR(picture) \
|
||||||
(GST_VAAPI_PICTURE_FLAG_IS_SET(picture, GST_VAAPI_PICTURE_FLAG_IDR))
|
(GST_VAAPI_PICTURE_FLAG_IS_SET(picture, GST_VAAPI_PICTURE_FLAG_IDR))
|
||||||
|
|
||||||
|
#define GST_VAAPI_PICTURE_IS_SHORT_TERM_REFERENCE(picture) \
|
||||||
|
((GST_VAAPI_PICTURE_FLAGS(picture) & \
|
||||||
|
GST_VAAPI_PICTURE_FLAGS_REFERENCE) == \
|
||||||
|
GST_VAAPI_PICTURE_FLAG_SHORT_TERM_REFERENCE)
|
||||||
|
|
||||||
|
#define GST_VAAPI_PICTURE_IS_LONG_TERM_REFERENCE(picture) \
|
||||||
|
((GST_VAAPI_PICTURE_FLAGS(picture) & \
|
||||||
|
GST_VAAPI_PICTURE_FLAGS_REFERENCE) == \
|
||||||
|
GST_VAAPI_PICTURE_FLAG_LONG_TERM_REFERENCE)
|
||||||
|
|
||||||
struct _GstVaapiPictureH264 {
|
struct _GstVaapiPictureH264 {
|
||||||
GstVaapiPicture base;
|
GstVaapiPicture base;
|
||||||
VAPictureH264 info;
|
VAPictureH264 info;
|
||||||
|
@ -95,9 +119,9 @@ struct _GstVaapiPictureH264 {
|
||||||
gint32 poc;
|
gint32 poc;
|
||||||
gint32 frame_num; // Original frame_num from slice_header()
|
gint32 frame_num; // Original frame_num from slice_header()
|
||||||
gint32 frame_num_wrap; // Temporary for ref pic marking: FrameNumWrap
|
gint32 frame_num_wrap; // Temporary for ref pic marking: FrameNumWrap
|
||||||
|
gint32 long_term_frame_idx; // Temporary for ref pic marking: LongTermFrameIdx
|
||||||
gint32 pic_num; // Temporary for ref pic marking: PicNum
|
gint32 pic_num; // Temporary for ref pic marking: PicNum
|
||||||
gint32 long_term_pic_num; // Temporary for ref pic marking: LongTermPicNum
|
gint32 long_term_pic_num; // Temporary for ref pic marking: LongTermPicNum
|
||||||
guint is_long_term : 1;
|
|
||||||
guint output_flag : 1;
|
guint output_flag : 1;
|
||||||
guint output_needed : 1;
|
guint output_needed : 1;
|
||||||
};
|
};
|
||||||
|
@ -136,7 +160,6 @@ gst_vaapi_picture_h264_init(GstVaapiPictureH264 *picture)
|
||||||
va_pic->BottomFieldOrderCnt = 0;
|
va_pic->BottomFieldOrderCnt = 0;
|
||||||
|
|
||||||
picture->poc = 0;
|
picture->poc = 0;
|
||||||
picture->is_long_term = FALSE;
|
|
||||||
picture->output_needed = FALSE;
|
picture->output_needed = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1157,7 +1180,7 @@ compare_picture_long_term_frame_idx_inc(const void *a, const void *b)
|
||||||
const GstVaapiPictureH264 * const picA = *(GstVaapiPictureH264 **)a;
|
const GstVaapiPictureH264 * const picA = *(GstVaapiPictureH264 **)a;
|
||||||
const GstVaapiPictureH264 * const picB = *(GstVaapiPictureH264 **)b;
|
const GstVaapiPictureH264 * const picB = *(GstVaapiPictureH264 **)b;
|
||||||
|
|
||||||
return picA->info.frame_idx - picB->info.frame_idx;
|
return picA->long_term_frame_idx - picB->long_term_frame_idx;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 8.2.4.1 - Decoding process for picture numbers */
|
/* 8.2.4.1 - Decoding process for picture numbers */
|
||||||
|
@ -1201,12 +1224,12 @@ init_picture_refs_pic_num(
|
||||||
|
|
||||||
// (8-29, 8-32, 8-33)
|
// (8-29, 8-32, 8-33)
|
||||||
if (GST_VAAPI_PICTURE_IS_FRAME(picture))
|
if (GST_VAAPI_PICTURE_IS_FRAME(picture))
|
||||||
pic->long_term_pic_num = pic->info.frame_idx;
|
pic->long_term_pic_num = pic->long_term_frame_idx;
|
||||||
else {
|
else {
|
||||||
if (pic->base.structure == picture->base.structure)
|
if (pic->base.structure == picture->base.structure)
|
||||||
pic->long_term_pic_num = 2 * pic->info.frame_idx + 1;
|
pic->long_term_pic_num = 2 * pic->long_term_frame_idx + 1;
|
||||||
else
|
else
|
||||||
pic->long_term_pic_num = 2 * pic->info.frame_idx;
|
pic->long_term_pic_num = 2 * pic->long_term_frame_idx;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1449,10 +1472,7 @@ remove_reference_at(
|
||||||
g_return_val_if_fail(index < num_pictures, FALSE);
|
g_return_val_if_fail(index < num_pictures, FALSE);
|
||||||
|
|
||||||
picture = pictures[index];
|
picture = pictures[index];
|
||||||
GST_VAAPI_PICTURE_FLAG_UNSET(picture, GST_VAAPI_PICTURE_FLAG_REFERENCE);
|
GST_VAAPI_PICTURE_FLAG_UNSET(picture, GST_VAAPI_PICTURE_FLAGS_REFERENCE);
|
||||||
picture->is_long_term = FALSE;
|
|
||||||
picture->info.flags &= ~(VA_PICTURE_H264_SHORT_TERM_REFERENCE |
|
|
||||||
VA_PICTURE_H264_LONG_TERM_REFERENCE);
|
|
||||||
|
|
||||||
if (index != --num_pictures)
|
if (index != --num_pictures)
|
||||||
gst_vaapi_picture_replace(&pictures[index], pictures[num_pictures]);
|
gst_vaapi_picture_replace(&pictures[index], pictures[num_pictures]);
|
||||||
|
@ -1580,8 +1600,9 @@ exec_picture_refs_modification_1(
|
||||||
gint32 PicNumF;
|
gint32 PicNumF;
|
||||||
if (!ref_list[j])
|
if (!ref_list[j])
|
||||||
continue;
|
continue;
|
||||||
PicNumF = ref_list[j]->is_long_term ?
|
PicNumF =
|
||||||
MaxPicNum : ref_list[j]->pic_num;
|
GST_VAAPI_PICTURE_IS_SHORT_TERM_REFERENCE(ref_list[j]) ?
|
||||||
|
ref_list[j]->pic_num : MaxPicNum;
|
||||||
if (PicNumF != picNum)
|
if (PicNumF != picNum)
|
||||||
ref_list[n++] = ref_list[j];
|
ref_list[n++] = ref_list[j];
|
||||||
}
|
}
|
||||||
|
@ -1601,7 +1622,8 @@ exec_picture_refs_modification_1(
|
||||||
gint32 LongTermPicNumF;
|
gint32 LongTermPicNumF;
|
||||||
if (!ref_list[j])
|
if (!ref_list[j])
|
||||||
continue;
|
continue;
|
||||||
LongTermPicNumF = ref_list[j]->is_long_term ?
|
LongTermPicNumF =
|
||||||
|
GST_VAAPI_PICTURE_IS_LONG_TERM_REFERENCE(ref_list[j]) ?
|
||||||
ref_list[j]->long_term_pic_num : INT_MAX;
|
ref_list[j]->long_term_pic_num : INT_MAX;
|
||||||
if (LongTermPicNumF != l->value.long_term_pic_num)
|
if (LongTermPicNumF != l->value.long_term_pic_num)
|
||||||
ref_list[n++] = ref_list[j];
|
ref_list[n++] = ref_list[j];
|
||||||
|
@ -1699,7 +1721,6 @@ init_picture(
|
||||||
{
|
{
|
||||||
GstVaapiDecoderH264Private * const priv = decoder->priv;
|
GstVaapiDecoderH264Private * const priv = decoder->priv;
|
||||||
GstVaapiPicture * const base_picture = &picture->base;
|
GstVaapiPicture * const base_picture = &picture->base;
|
||||||
VAPictureH264 *pic;
|
|
||||||
|
|
||||||
priv->prev_frame_num = priv->frame_num;
|
priv->prev_frame_num = priv->frame_num;
|
||||||
priv->frame_num = slice_hdr->frame_num;
|
priv->frame_num = slice_hdr->frame_num;
|
||||||
|
@ -1716,11 +1737,6 @@ init_picture(
|
||||||
clear_references(decoder, priv->long_ref, &priv->long_ref_count );
|
clear_references(decoder, priv->long_ref, &priv->long_ref_count );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Initialize VA picture info */
|
|
||||||
pic = &picture->info;
|
|
||||||
pic->picture_id = picture->base.surface_id;
|
|
||||||
pic->frame_idx = priv->frame_num;
|
|
||||||
|
|
||||||
/* Initialize slice type */
|
/* Initialize slice type */
|
||||||
switch (slice_hdr->type % 5) {
|
switch (slice_hdr->type % 5) {
|
||||||
case GST_H264_P_SLICE:
|
case GST_H264_P_SLICE:
|
||||||
|
@ -1751,11 +1767,14 @@ init_picture(
|
||||||
if (nalu->ref_idc) {
|
if (nalu->ref_idc) {
|
||||||
GstH264DecRefPicMarking * const dec_ref_pic_marking =
|
GstH264DecRefPicMarking * const dec_ref_pic_marking =
|
||||||
&slice_hdr->dec_ref_pic_marking;
|
&slice_hdr->dec_ref_pic_marking;
|
||||||
GST_VAAPI_PICTURE_FLAG_SET(picture, GST_VAAPI_PICTURE_FLAG_REFERENCE);
|
|
||||||
if (GST_VAAPI_PICTURE_IS_IDR(picture)) {
|
if (GST_VAAPI_PICTURE_IS_IDR(picture) &&
|
||||||
if (dec_ref_pic_marking->long_term_reference_flag)
|
dec_ref_pic_marking->long_term_reference_flag)
|
||||||
picture->is_long_term = TRUE;
|
GST_VAAPI_PICTURE_FLAG_SET(picture,
|
||||||
}
|
GST_VAAPI_PICTURE_FLAG_LONG_TERM_REFERENCE);
|
||||||
|
else
|
||||||
|
GST_VAAPI_PICTURE_FLAG_SET(picture,
|
||||||
|
GST_VAAPI_PICTURE_FLAG_SHORT_TERM_REFERENCE);
|
||||||
}
|
}
|
||||||
|
|
||||||
init_picture_poc(decoder, picture, slice_hdr);
|
init_picture_poc(decoder, picture, slice_hdr);
|
||||||
|
@ -1861,11 +1880,10 @@ exec_ref_pic_marking_adaptive_mmco_3(
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
GstVaapiDecoderH264Private * const priv = decoder->priv;
|
GstVaapiDecoderH264Private * const priv = decoder->priv;
|
||||||
VAPictureH264 *pic;
|
|
||||||
gint32 i, picNumX;
|
gint32 i, picNumX;
|
||||||
|
|
||||||
for (i = 0; i < priv->long_ref_count; i++) {
|
for (i = 0; i < priv->long_ref_count; i++) {
|
||||||
if (priv->long_ref[i]->info.frame_idx == ref_pic_marking->long_term_frame_idx)
|
if (priv->long_ref[i]->long_term_frame_idx == ref_pic_marking->long_term_frame_idx)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (i != priv->long_ref_count)
|
if (i != priv->long_ref_count)
|
||||||
|
@ -1881,12 +1899,9 @@ exec_ref_pic_marking_adaptive_mmco_3(
|
||||||
gst_vaapi_picture_replace(&priv->long_ref[priv->long_ref_count++], picture);
|
gst_vaapi_picture_replace(&priv->long_ref[priv->long_ref_count++], picture);
|
||||||
gst_vaapi_picture_unref(picture);
|
gst_vaapi_picture_unref(picture);
|
||||||
|
|
||||||
picture->is_long_term = TRUE;
|
picture->long_term_frame_idx = ref_pic_marking->long_term_frame_idx;
|
||||||
pic = &picture->info;
|
GST_VAAPI_PICTURE_FLAG_SET(picture,
|
||||||
pic->frame_idx = ref_pic_marking->long_term_frame_idx;
|
GST_VAAPI_PICTURE_FLAG_LONG_TERM_REFERENCE);
|
||||||
pic->flags &= ~VA_PICTURE_H264_SHORT_TERM_REFERENCE;
|
|
||||||
pic->flags |= VA_PICTURE_H264_LONG_TERM_REFERENCE;
|
|
||||||
GST_VAAPI_PICTURE_FLAG_SET(picture, GST_VAAPI_PICTURE_FLAG_REFERENCE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 8.2.5.4.4. Mark pictures with LongTermFramIdx > max_long_term_frame_idx
|
/* 8.2.5.4.4. Mark pictures with LongTermFramIdx > max_long_term_frame_idx
|
||||||
|
@ -1904,7 +1919,7 @@ exec_ref_pic_marking_adaptive_mmco_4(
|
||||||
long_term_frame_idx = ref_pic_marking->max_long_term_frame_idx_plus1 - 1;
|
long_term_frame_idx = ref_pic_marking->max_long_term_frame_idx_plus1 - 1;
|
||||||
|
|
||||||
for (i = 0; i < priv->long_ref_count; i++) {
|
for (i = 0; i < priv->long_ref_count; i++) {
|
||||||
if ((gint32)priv->long_ref[i]->info.frame_idx <= long_term_frame_idx)
|
if (priv->long_ref[i]->long_term_frame_idx <= long_term_frame_idx)
|
||||||
continue;
|
continue;
|
||||||
remove_reference_at(decoder, priv->long_ref, &priv->long_ref_count, i);
|
remove_reference_at(decoder, priv->long_ref, &priv->long_ref_count, i);
|
||||||
i--;
|
i--;
|
||||||
|
@ -1949,8 +1964,9 @@ exec_ref_pic_marking_adaptive_mmco_6(
|
||||||
GstH264RefPicMarking *ref_pic_marking
|
GstH264RefPicMarking *ref_pic_marking
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
picture->is_long_term = TRUE;
|
picture->long_term_frame_idx = ref_pic_marking->long_term_frame_idx;
|
||||||
picture->info.frame_idx = ref_pic_marking->long_term_frame_idx;
|
GST_VAAPI_PICTURE_FLAG_SET(picture,
|
||||||
|
GST_VAAPI_PICTURE_FLAG_LONG_TERM_REFERENCE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 8.2.5.4. Adaptive memory control decoded reference picture marking process */
|
/* 8.2.5.4. Adaptive memory control decoded reference picture marking process */
|
||||||
|
@ -2024,14 +2040,10 @@ exec_ref_pic_marking(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (picture->is_long_term) {
|
if (GST_VAAPI_PICTURE_IS_LONG_TERM_REFERENCE(picture))
|
||||||
picture_ptr = &priv->long_ref[priv->long_ref_count++];
|
picture_ptr = &priv->long_ref[priv->long_ref_count++];
|
||||||
picture->info.flags |= VA_PICTURE_H264_LONG_TERM_REFERENCE;
|
else
|
||||||
}
|
|
||||||
else {
|
|
||||||
picture_ptr = &priv->short_ref[priv->short_ref_count++];
|
picture_ptr = &priv->short_ref[priv->short_ref_count++];
|
||||||
picture->info.flags |= VA_PICTURE_H264_SHORT_TERM_REFERENCE;
|
|
||||||
}
|
|
||||||
gst_vaapi_picture_replace(picture_ptr, picture);
|
gst_vaapi_picture_replace(picture_ptr, picture);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
@ -2052,12 +2064,12 @@ vaapi_fill_picture(VAPictureH264 *pic, GstVaapiPictureH264 *picture)
|
||||||
pic->picture_id = picture->base.surface_id;
|
pic->picture_id = picture->base.surface_id;
|
||||||
pic->flags = 0;
|
pic->flags = 0;
|
||||||
|
|
||||||
if (picture->info.flags & VA_PICTURE_H264_LONG_TERM_REFERENCE) {
|
if (GST_VAAPI_PICTURE_IS_LONG_TERM_REFERENCE(picture)) {
|
||||||
pic->flags |= VA_PICTURE_H264_LONG_TERM_REFERENCE;
|
pic->flags |= VA_PICTURE_H264_LONG_TERM_REFERENCE;
|
||||||
pic->frame_idx = picture->info.frame_idx;
|
pic->frame_idx = picture->long_term_frame_idx;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (picture->info.flags & VA_PICTURE_H264_SHORT_TERM_REFERENCE)
|
if (GST_VAAPI_PICTURE_IS_SHORT_TERM_REFERENCE(picture))
|
||||||
pic->flags |= VA_PICTURE_H264_SHORT_TERM_REFERENCE;
|
pic->flags |= VA_PICTURE_H264_SHORT_TERM_REFERENCE;
|
||||||
pic->frame_idx = picture->frame_num;
|
pic->frame_idx = picture->frame_num;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue