mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-28 04:31:06 +00:00
h264: introduce per-field POC in GstVaapiPictureH264.
Use the POC member available in the GstVaapiPicture base class and get rid of the dependency on the local VAPictureH264 TopFieldOrderCnt and BottomFieldOrderCnt. Rather, use a simple field_poc[] array initialized to INT_MAX, so that to simplify picture POC calculation for non frame pictures.
This commit is contained in:
parent
3c721e1123
commit
3480fcc8d7
1 changed files with 29 additions and 38 deletions
|
@ -45,6 +45,10 @@ typedef struct _GstVaapiPictureH264Class GstVaapiPictureH264Class;
|
||||||
typedef struct _GstVaapiSliceH264 GstVaapiSliceH264;
|
typedef struct _GstVaapiSliceH264 GstVaapiSliceH264;
|
||||||
typedef struct _GstVaapiSliceH264Class GstVaapiSliceH264Class;
|
typedef struct _GstVaapiSliceH264Class GstVaapiSliceH264Class;
|
||||||
|
|
||||||
|
// Used for field_poc[]
|
||||||
|
#define TOP_FIELD 0
|
||||||
|
#define BOTTOM_FIELD 1
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------- */
|
/* ------------------------------------------------------------------------- */
|
||||||
/* --- H.264 Pictures --- */
|
/* --- H.264 Pictures --- */
|
||||||
/* ------------------------------------------------------------------------- */
|
/* ------------------------------------------------------------------------- */
|
||||||
|
@ -114,9 +118,8 @@ enum {
|
||||||
|
|
||||||
struct _GstVaapiPictureH264 {
|
struct _GstVaapiPictureH264 {
|
||||||
GstVaapiPicture base;
|
GstVaapiPicture base;
|
||||||
VAPictureH264 info;
|
|
||||||
GstH264PPS *pps;
|
GstH264PPS *pps;
|
||||||
gint32 poc;
|
gint32 field_poc[2];
|
||||||
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 long_term_frame_idx; // Temporary for ref pic marking: LongTermFrameIdx
|
||||||
|
@ -152,14 +155,8 @@ gst_vaapi_picture_h264_create(
|
||||||
static void
|
static void
|
||||||
gst_vaapi_picture_h264_init(GstVaapiPictureH264 *picture)
|
gst_vaapi_picture_h264_init(GstVaapiPictureH264 *picture)
|
||||||
{
|
{
|
||||||
VAPictureH264 *va_pic;
|
picture->field_poc[0] = G_MAXINT32;
|
||||||
|
picture->field_poc[1] = G_MAXINT32;
|
||||||
va_pic = &picture->info;
|
|
||||||
va_pic->flags = 0;
|
|
||||||
va_pic->TopFieldOrderCnt = 0;
|
|
||||||
va_pic->BottomFieldOrderCnt = 0;
|
|
||||||
|
|
||||||
picture->poc = 0;
|
|
||||||
picture->output_needed = FALSE;
|
picture->output_needed = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -291,10 +288,6 @@ G_DEFINE_TYPE(GstVaapiDecoderH264,
|
||||||
GST_VAAPI_TYPE_DECODER_H264, \
|
GST_VAAPI_TYPE_DECODER_H264, \
|
||||||
GstVaapiDecoderH264Private))
|
GstVaapiDecoderH264Private))
|
||||||
|
|
||||||
// Used for field_poc[]
|
|
||||||
#define TOP_FIELD 0
|
|
||||||
#define BOTTOM_FIELD 1
|
|
||||||
|
|
||||||
struct _GstVaapiDecoderH264Private {
|
struct _GstVaapiDecoderH264Private {
|
||||||
GstAdapter *adapter;
|
GstAdapter *adapter;
|
||||||
GstH264NalParser *parser;
|
GstH264NalParser *parser;
|
||||||
|
@ -448,7 +441,7 @@ dpb_bump(GstVaapiDecoderH264 *decoder)
|
||||||
lowest_poc_index = i++;
|
lowest_poc_index = i++;
|
||||||
for (; i < priv->dpb_count; i++) {
|
for (; i < priv->dpb_count; i++) {
|
||||||
GstVaapiPictureH264 * const picture = priv->dpb[i];
|
GstVaapiPictureH264 * const picture = priv->dpb[i];
|
||||||
if (picture->output_needed && picture->poc < priv->dpb[lowest_poc_index]->poc)
|
if (picture->output_needed && picture->base.poc < priv->dpb[lowest_poc_index]->base.poc)
|
||||||
lowest_poc_index = i;
|
lowest_poc_index = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -507,7 +500,7 @@ dpb_add(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture)
|
||||||
while (priv->dpb_count == priv->dpb_size) {
|
while (priv->dpb_count == priv->dpb_size) {
|
||||||
for (i = 0; i < priv->dpb_count; i++) {
|
for (i = 0; i < priv->dpb_count; i++) {
|
||||||
if (priv->dpb[i]->output_needed &&
|
if (priv->dpb[i]->output_needed &&
|
||||||
priv->dpb[i]->poc < picture->poc)
|
priv->dpb[i]->base.poc < picture->base.poc)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (i == priv->dpb_count)
|
if (i == priv->dpb_count)
|
||||||
|
@ -1106,7 +1099,6 @@ init_picture_poc(
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
GstVaapiDecoderH264Private * const priv = decoder->priv;
|
GstVaapiDecoderH264Private * const priv = decoder->priv;
|
||||||
VAPictureH264 * const pic = &picture->info;
|
|
||||||
GstH264PPS * const pps = slice_hdr->pps;
|
GstH264PPS * const pps = slice_hdr->pps;
|
||||||
GstH264SPS * const sps = pps->sequence;
|
GstH264SPS * const sps = pps->sequence;
|
||||||
|
|
||||||
|
@ -1123,10 +1115,10 @@ init_picture_poc(
|
||||||
}
|
}
|
||||||
|
|
||||||
if (picture->base.structure != GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD)
|
if (picture->base.structure != GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD)
|
||||||
pic->TopFieldOrderCnt = priv->field_poc[TOP_FIELD];
|
picture->field_poc[TOP_FIELD] = priv->field_poc[TOP_FIELD];
|
||||||
if (picture->base.structure != GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD)
|
if (picture->base.structure != GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD)
|
||||||
pic->BottomFieldOrderCnt = priv->field_poc[BOTTOM_FIELD];
|
picture->field_poc[BOTTOM_FIELD] = priv->field_poc[BOTTOM_FIELD];
|
||||||
picture->poc = MIN(pic->TopFieldOrderCnt, pic->BottomFieldOrderCnt);
|
picture->base.poc = MIN(picture->field_poc[0], picture->field_poc[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
@ -1153,7 +1145,7 @@ compare_picture_poc_dec(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 picB->poc - picA->poc;
|
return picB->base.poc - picA->base.poc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
@ -1162,7 +1154,7 @@ compare_picture_poc_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->poc - picB->poc;
|
return picA->base.poc - picB->base.poc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
@ -1318,7 +1310,7 @@ init_picture_refs_b_slice(
|
||||||
// 1. Short-term references
|
// 1. Short-term references
|
||||||
ref_list = priv->RefPicList0;
|
ref_list = priv->RefPicList0;
|
||||||
for (n = 0, i = 0; i < priv->short_ref_count; i++) {
|
for (n = 0, i = 0; i < priv->short_ref_count; i++) {
|
||||||
if (priv->short_ref[i]->poc < picture->poc)
|
if (priv->short_ref[i]->base.poc < picture->base.poc)
|
||||||
ref_list[n++] = priv->short_ref[i];
|
ref_list[n++] = priv->short_ref[i];
|
||||||
}
|
}
|
||||||
SORT_REF_LIST(ref_list, n, poc_dec);
|
SORT_REF_LIST(ref_list, n, poc_dec);
|
||||||
|
@ -1326,7 +1318,7 @@ init_picture_refs_b_slice(
|
||||||
|
|
||||||
ref_list = &priv->RefPicList0[priv->RefPicList0_count];
|
ref_list = &priv->RefPicList0[priv->RefPicList0_count];
|
||||||
for (n = 0, i = 0; i < priv->short_ref_count; i++) {
|
for (n = 0, i = 0; i < priv->short_ref_count; i++) {
|
||||||
if (priv->short_ref[i]->poc >= picture->poc)
|
if (priv->short_ref[i]->base.poc >= picture->base.poc)
|
||||||
ref_list[n++] = priv->short_ref[i];
|
ref_list[n++] = priv->short_ref[i];
|
||||||
}
|
}
|
||||||
SORT_REF_LIST(ref_list, n, poc_inc);
|
SORT_REF_LIST(ref_list, n, poc_inc);
|
||||||
|
@ -1347,7 +1339,7 @@ init_picture_refs_b_slice(
|
||||||
// 1. Short-term references
|
// 1. Short-term references
|
||||||
ref_list = priv->RefPicList1;
|
ref_list = priv->RefPicList1;
|
||||||
for (n = 0, i = 0; i < priv->short_ref_count; i++) {
|
for (n = 0, i = 0; i < priv->short_ref_count; i++) {
|
||||||
if (priv->short_ref[i]->poc > picture->poc)
|
if (priv->short_ref[i]->base.poc > picture->base.poc)
|
||||||
ref_list[n++] = priv->short_ref[i];
|
ref_list[n++] = priv->short_ref[i];
|
||||||
}
|
}
|
||||||
SORT_REF_LIST(ref_list, n, poc_inc);
|
SORT_REF_LIST(ref_list, n, poc_inc);
|
||||||
|
@ -1355,7 +1347,7 @@ init_picture_refs_b_slice(
|
||||||
|
|
||||||
ref_list = &priv->RefPicList1[priv->RefPicList1_count];
|
ref_list = &priv->RefPicList1[priv->RefPicList1_count];
|
||||||
for (n = 0, i = 0; i < priv->short_ref_count; i++) {
|
for (n = 0, i = 0; i < priv->short_ref_count; i++) {
|
||||||
if (priv->short_ref[i]->poc <= picture->poc)
|
if (priv->short_ref[i]->base.poc <= picture->base.poc)
|
||||||
ref_list[n++] = priv->short_ref[i];
|
ref_list[n++] = priv->short_ref[i];
|
||||||
}
|
}
|
||||||
SORT_REF_LIST(ref_list, n, poc_dec);
|
SORT_REF_LIST(ref_list, n, poc_dec);
|
||||||
|
@ -1384,7 +1376,7 @@ init_picture_refs_b_slice(
|
||||||
if (priv->short_ref_count > 0) {
|
if (priv->short_ref_count > 0) {
|
||||||
ref_list = short_ref0;
|
ref_list = short_ref0;
|
||||||
for (n = 0, i = 0; i < priv->short_ref_count; i++) {
|
for (n = 0, i = 0; i < priv->short_ref_count; i++) {
|
||||||
if (priv->short_ref[i]->poc <= picture->poc)
|
if (priv->short_ref[i]->base.poc <= picture->base.poc)
|
||||||
ref_list[n++] = priv->short_ref[i];
|
ref_list[n++] = priv->short_ref[i];
|
||||||
}
|
}
|
||||||
SORT_REF_LIST(ref_list, n, poc_dec);
|
SORT_REF_LIST(ref_list, n, poc_dec);
|
||||||
|
@ -1392,7 +1384,7 @@ init_picture_refs_b_slice(
|
||||||
|
|
||||||
ref_list = &short_ref0[short_ref0_count];
|
ref_list = &short_ref0[short_ref0_count];
|
||||||
for (n = 0, i = 0; i < priv->short_ref_count; i++) {
|
for (n = 0, i = 0; i < priv->short_ref_count; i++) {
|
||||||
if (priv->short_ref[i]->poc > picture->poc)
|
if (priv->short_ref[i]->base.poc > picture->base.poc)
|
||||||
ref_list[n++] = priv->short_ref[i];
|
ref_list[n++] = priv->short_ref[i];
|
||||||
}
|
}
|
||||||
SORT_REF_LIST(ref_list, n, poc_inc);
|
SORT_REF_LIST(ref_list, n, poc_inc);
|
||||||
|
@ -1403,7 +1395,7 @@ init_picture_refs_b_slice(
|
||||||
if (priv->short_ref_count > 0) {
|
if (priv->short_ref_count > 0) {
|
||||||
ref_list = short_ref1;
|
ref_list = short_ref1;
|
||||||
for (n = 0, i = 0; i < priv->short_ref_count; i++) {
|
for (n = 0, i = 0; i < priv->short_ref_count; i++) {
|
||||||
if (priv->short_ref[i]->poc > picture->poc)
|
if (priv->short_ref[i]->base.poc > picture->base.poc)
|
||||||
ref_list[n++] = priv->short_ref[i];
|
ref_list[n++] = priv->short_ref[i];
|
||||||
}
|
}
|
||||||
SORT_REF_LIST(ref_list, n, poc_inc);
|
SORT_REF_LIST(ref_list, n, poc_inc);
|
||||||
|
@ -1411,7 +1403,7 @@ init_picture_refs_b_slice(
|
||||||
|
|
||||||
ref_list = &short_ref1[short_ref1_count];
|
ref_list = &short_ref1[short_ref1_count];
|
||||||
for (n = 0, i = 0; i < priv->short_ref_count; i++) {
|
for (n = 0, i = 0; i < priv->short_ref_count; i++) {
|
||||||
if (priv->short_ref[i]->poc <= picture->poc)
|
if (priv->short_ref[i]->base.poc <= picture->base.poc)
|
||||||
ref_list[n++] = priv->short_ref[i];
|
ref_list[n++] = priv->short_ref[i];
|
||||||
}
|
}
|
||||||
SORT_REF_LIST(ref_list, n, poc_dec);
|
SORT_REF_LIST(ref_list, n, poc_dec);
|
||||||
|
@ -1935,7 +1927,6 @@ exec_ref_pic_marking_adaptive_mmco_5(
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
GstVaapiDecoderH264Private * const priv = decoder->priv;
|
GstVaapiDecoderH264Private * const priv = decoder->priv;
|
||||||
VAPictureH264 * const pic = &picture->info;
|
|
||||||
|
|
||||||
clear_references(decoder, priv->short_ref, &priv->short_ref_count);
|
clear_references(decoder, priv->short_ref, &priv->short_ref_count);
|
||||||
clear_references(decoder, priv->long_ref, &priv->long_ref_count );
|
clear_references(decoder, priv->long_ref, &priv->long_ref_count );
|
||||||
|
@ -1950,10 +1941,10 @@ exec_ref_pic_marking_adaptive_mmco_5(
|
||||||
|
|
||||||
/* Update TopFieldOrderCnt and BottomFieldOrderCnt (8.2.1) */
|
/* Update TopFieldOrderCnt and BottomFieldOrderCnt (8.2.1) */
|
||||||
if (picture->base.structure != GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD)
|
if (picture->base.structure != GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD)
|
||||||
pic->TopFieldOrderCnt -= picture->poc;
|
picture->field_poc[TOP_FIELD] -= picture->base.poc;
|
||||||
if (picture->base.structure != GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD)
|
if (picture->base.structure != GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD)
|
||||||
pic->BottomFieldOrderCnt -= picture->poc;
|
picture->field_poc[BOTTOM_FIELD] -= picture->base.poc;
|
||||||
picture->poc = 0;
|
picture->base.poc = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 8.2.5.4.6. Assign a long-term frame index to the current picture */
|
/* 8.2.5.4.6. Assign a long-term frame index to the current picture */
|
||||||
|
@ -2076,17 +2067,17 @@ vaapi_fill_picture(VAPictureH264 *pic, GstVaapiPictureH264 *picture)
|
||||||
|
|
||||||
switch (picture->base.structure) {
|
switch (picture->base.structure) {
|
||||||
case GST_VAAPI_PICTURE_STRUCTURE_FRAME:
|
case GST_VAAPI_PICTURE_STRUCTURE_FRAME:
|
||||||
pic->TopFieldOrderCnt = picture->info.TopFieldOrderCnt;
|
pic->TopFieldOrderCnt = picture->field_poc[TOP_FIELD];
|
||||||
pic->BottomFieldOrderCnt = picture->info.BottomFieldOrderCnt;
|
pic->BottomFieldOrderCnt = picture->field_poc[BOTTOM_FIELD];
|
||||||
break;
|
break;
|
||||||
case GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD:
|
case GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD:
|
||||||
pic->flags |= VA_PICTURE_H264_TOP_FIELD;
|
pic->flags |= VA_PICTURE_H264_TOP_FIELD;
|
||||||
pic->TopFieldOrderCnt = picture->info.BottomFieldOrderCnt;
|
pic->TopFieldOrderCnt = picture->field_poc[TOP_FIELD];
|
||||||
pic->BottomFieldOrderCnt = 0;
|
pic->BottomFieldOrderCnt = 0;
|
||||||
break;
|
break;
|
||||||
case GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD:
|
case GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD:
|
||||||
pic->flags |= VA_PICTURE_H264_BOTTOM_FIELD;
|
pic->flags |= VA_PICTURE_H264_BOTTOM_FIELD;
|
||||||
pic->BottomFieldOrderCnt = picture->info.BottomFieldOrderCnt;
|
pic->BottomFieldOrderCnt = picture->field_poc[BOTTOM_FIELD];
|
||||||
pic->TopFieldOrderCnt = 0;
|
pic->TopFieldOrderCnt = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue