mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-29 19:50:40 +00:00
vdpauh264dec: improve further
This commit is contained in:
parent
322d1ff946
commit
3ea3a084e4
6 changed files with 301 additions and 93 deletions
|
@ -24,7 +24,8 @@
|
|||
enum
|
||||
{
|
||||
PROP_0,
|
||||
PROP_NUM_REF_FRAMES
|
||||
PROP_NUM_REF_FRAMES,
|
||||
PROP_MAX_LONGTERM_IDX
|
||||
};
|
||||
|
||||
GST_DEBUG_CATEGORY_STATIC (h264dpb_debug);
|
||||
|
@ -48,15 +49,15 @@ gst_h264_dpb_fill_reference_frames (GstH264DPB * dpb,
|
|||
GstVdpH264Frame *frame = frames[i];
|
||||
|
||||
reference_frames[i].surface =
|
||||
GST_VDP_VIDEO_BUFFER (GST_VIDEO_FRAME_CAST (frame)->
|
||||
src_buffer)->surface;
|
||||
GST_VDP_VIDEO_BUFFER (GST_VIDEO_FRAME_CAST (frame)->src_buffer)->
|
||||
surface;
|
||||
|
||||
reference_frames[i].is_long_term = frame->is_long_term;
|
||||
reference_frames[i].top_is_reference = frame->is_reference;
|
||||
reference_frames[i].bottom_is_reference = frame->is_reference;
|
||||
reference_frames[i].field_order_cnt[0] = frame->poc;
|
||||
reference_frames[i].field_order_cnt[1] = frame->poc;
|
||||
reference_frames[i].frame_idx = frame->frame_num;
|
||||
reference_frames[i].frame_idx = frame->frame_idx;
|
||||
}
|
||||
|
||||
for (i = dpb->n_frames; i < 16; i++) {
|
||||
|
@ -134,8 +135,11 @@ gst_h264_dpb_add (GstH264DPB * dpb, GstVdpH264Frame * h264_frame)
|
|||
|
||||
frames = dpb->frames;
|
||||
|
||||
if (h264_frame->is_reference) {
|
||||
if (h264_frame->is_reference && h264_frame->is_long_term &&
|
||||
(h264_frame->frame_idx > dpb->max_longterm_frame_idx))
|
||||
h264_frame->is_reference = FALSE;
|
||||
|
||||
if (h264_frame->is_reference) {
|
||||
while (dpb->n_frames == dpb->max_frames) {
|
||||
if (!gst_h264_dpb_bump (dpb, G_MAXUINT)) {
|
||||
GST_ERROR_OBJECT (dpb, "Couldn't make room in DPB");
|
||||
|
@ -146,14 +150,8 @@ gst_h264_dpb_add (GstH264DPB * dpb, GstVdpH264Frame * h264_frame)
|
|||
}
|
||||
|
||||
else {
|
||||
if (dpb->n_frames == dpb->max_frames) {
|
||||
while (gst_h264_dpb_bump (dpb, h264_frame->poc));
|
||||
|
||||
dpb->output (dpb, h264_frame);
|
||||
}
|
||||
|
||||
else
|
||||
dpb->frames[dpb->n_frames++] = h264_frame;
|
||||
while (gst_h264_dpb_bump (dpb, h264_frame->poc));
|
||||
dpb->output (dpb, h264_frame);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
@ -183,7 +181,7 @@ gst_h264_dpb_mark_sliding (GstH264DPB * dpb)
|
|||
{
|
||||
GstVdpH264Frame **frames;
|
||||
guint i;
|
||||
gint mark_idx;
|
||||
gint mark_idx = -1;
|
||||
|
||||
if (dpb->n_frames != dpb->max_frames)
|
||||
return;
|
||||
|
@ -199,7 +197,7 @@ gst_h264_dpb_mark_sliding (GstH264DPB * dpb)
|
|||
if (mark_idx != -1) {
|
||||
for (i = mark_idx; i < dpb->n_frames; i++) {
|
||||
if (frames[i]->is_reference && !frames[i]->is_long_term &&
|
||||
frames[i]->frame_num < frames[mark_idx]->frame_num)
|
||||
frames[i]->frame_idx < frames[mark_idx]->frame_idx)
|
||||
mark_idx = i;
|
||||
}
|
||||
|
||||
|
@ -209,6 +207,94 @@ gst_h264_dpb_mark_sliding (GstH264DPB * dpb)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
gst_h264_dpb_mark_long_term (GstH264DPB * dpb, guint16 pic_num,
|
||||
guint16 long_term_frame_idx)
|
||||
{
|
||||
GstVdpH264Frame **frames;
|
||||
guint i;
|
||||
gint mark_idx = -1;
|
||||
|
||||
frames = dpb->frames;
|
||||
for (i = 0; i < dpb->n_frames; i++) {
|
||||
if (frames[i]->is_reference && !frames[i]->is_long_term &&
|
||||
frames[i]->frame_idx == pic_num) {
|
||||
mark_idx = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (mark_idx != -1) {
|
||||
frames[mark_idx]->is_long_term = TRUE;
|
||||
frames[mark_idx]->frame_idx = long_term_frame_idx;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
gst_h264_dpb_mark_short_term_unused (GstH264DPB * dpb, guint16 pic_num)
|
||||
{
|
||||
GstVdpH264Frame **frames;
|
||||
guint i;
|
||||
gint mark_idx = -1;
|
||||
|
||||
frames = dpb->frames;
|
||||
for (i = 0; i < dpb->n_frames; i++) {
|
||||
if (frames[i]->is_reference && !frames[i]->is_long_term &&
|
||||
frames[i]->frame_idx == pic_num) {
|
||||
mark_idx = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (mark_idx != -1) {
|
||||
|
||||
frames[mark_idx]->is_reference = FALSE;
|
||||
if (!frames[mark_idx]->output_needed)
|
||||
gst_h264_dpb_remove (dpb, mark_idx);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
gst_h264_dpb_mark_long_term_unused (GstH264DPB * dpb, guint16 long_term_pic_num)
|
||||
{
|
||||
GstVdpH264Frame **frames;
|
||||
guint i;
|
||||
gint mark_idx = -1;
|
||||
|
||||
frames = dpb->frames;
|
||||
for (i = 0; i < dpb->n_frames; i++) {
|
||||
if (frames[i]->is_reference && frames[i]->is_long_term &&
|
||||
frames[i]->frame_idx == long_term_pic_num) {
|
||||
mark_idx = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (mark_idx != -1) {
|
||||
|
||||
frames[mark_idx]->is_reference = FALSE;
|
||||
if (!frames[mark_idx]->output_needed)
|
||||
gst_h264_dpb_remove (dpb, mark_idx);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
gst_h264_dpb_mark_all_unused (GstH264DPB * dpb)
|
||||
{
|
||||
GstVdpH264Frame **frames;
|
||||
guint i;
|
||||
|
||||
frames = dpb->frames;
|
||||
for (i = 0; i < dpb->n_frames; i++) {
|
||||
frames[i]->is_reference = FALSE;
|
||||
if (!frames[i]->output_needed) {
|
||||
gst_h264_dpb_remove (dpb, i);
|
||||
i--;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* GObject vmethod implementations */
|
||||
static void
|
||||
gst_h264_dpb_get_property (GObject * object, guint property_id,
|
||||
|
@ -220,6 +306,9 @@ gst_h264_dpb_get_property (GObject * object, guint property_id,
|
|||
case PROP_NUM_REF_FRAMES:
|
||||
g_value_set_uint (value, dpb->max_frames);
|
||||
break;
|
||||
case PROP_MAX_LONGTERM_IDX:
|
||||
g_value_set_int (value, dpb->max_longterm_frame_idx);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||
break;
|
||||
|
@ -244,6 +333,27 @@ gst_h264_dpb_set_property (GObject * object, guint property_id,
|
|||
break;
|
||||
}
|
||||
|
||||
case PROP_MAX_LONGTERM_IDX:
|
||||
{
|
||||
GstVdpH264Frame **frames;
|
||||
guint i;
|
||||
|
||||
dpb->max_longterm_frame_idx = g_value_get_int (value);
|
||||
|
||||
frames = dpb->frames;
|
||||
for (i = dpb->n_frames; i < dpb->n_frames; i++) {
|
||||
if (frames[i]->is_reference && frames[i]->is_long_term &&
|
||||
frames[i]->frame_idx > dpb->max_longterm_frame_idx) {
|
||||
frames[i]->is_reference = FALSE;
|
||||
if (!frames[i]->output_needed) {
|
||||
gst_h264_dpb_remove (dpb, i);
|
||||
i--;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||
break;
|
||||
|
@ -262,6 +372,7 @@ static void
|
|||
gst_h264_dpb_init (GstH264DPB * dpb)
|
||||
{
|
||||
dpb->n_frames = 0;
|
||||
dpb->max_longterm_frame_idx = -1;
|
||||
dpb->max_frames = MAX_DPB_SIZE;
|
||||
}
|
||||
|
||||
|
@ -279,4 +390,9 @@ gst_h264_dpb_class_init (GstH264DPBClass * klass)
|
|||
"How many reference frames the DPB should hold ",
|
||||
0, 16, 16, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
g_object_class_install_property (object_class, PROP_MAX_LONGTERM_IDX,
|
||||
g_param_spec_int ("max-longterm-frame-idx", "MaxLongTermFrameIDX",
|
||||
"Maximum long-term frame index",
|
||||
-1, G_MAXINT, -1, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
}
|
||||
|
|
|
@ -50,6 +50,7 @@ struct _GstH264DPB
|
|||
guint n_frames;
|
||||
|
||||
guint max_frames;
|
||||
gint max_longterm_frame_idx;
|
||||
|
||||
void (*output) (GstH264DPB *dpb, GstVdpH264Frame *h264_frame);
|
||||
};
|
||||
|
@ -67,6 +68,11 @@ void gst_h264_dpb_flush (GstH264DPB *dpb, gboolean output);
|
|||
|
||||
void gst_h264_dpb_mark_sliding (GstH264DPB *dpb);
|
||||
|
||||
void gst_h264_dpb_mark_long_term_unused (GstH264DPB *dpb, guint16 long_term_pic_num);
|
||||
void gst_h264_dpb_mark_short_term_unused (GstH264DPB *dpb, guint16 pic_num);
|
||||
void gst_h264_dpb_mark_all_unused (GstH264DPB *dpb);
|
||||
void gst_h264_dpb_mark_long_term (GstH264DPB *dpb, guint16 pic_num, guint16 long_term_frame_idx);
|
||||
|
||||
GType gst_h264_dpb_get_type (void) G_GNUC_CONST;
|
||||
|
||||
G_END_DECLS
|
||||
|
|
|
@ -257,7 +257,7 @@ gst_h264_parser_parse_scaling_list (GstNalReader * reader,
|
|||
{
|
||||
guint i;
|
||||
|
||||
GST_WARNING ("parsing scaling lists");
|
||||
GST_DEBUG ("parsing scaling lists");
|
||||
|
||||
for (i = 0; i < 12; i++) {
|
||||
gboolean use_default = FALSE;
|
||||
|
@ -460,6 +460,12 @@ gst_h264_parser_parse_sequence (GstH264Parser * parser, guint8 * data,
|
|||
goto error;
|
||||
}
|
||||
|
||||
/* calculate ChromaArrayType */
|
||||
if (seq->separate_colour_plane_flag)
|
||||
seq->ChromaArrayType = 0;
|
||||
else
|
||||
seq->ChromaArrayType = seq->chroma_format_idc;
|
||||
|
||||
GST_DEBUG ("adding sequence parameter set with id: %d to hash table",
|
||||
seq->id);
|
||||
g_hash_table_replace (parser->sequences, &seq->id, seq);
|
||||
|
@ -523,6 +529,7 @@ gst_h264_parser_parse_picture (GstH264Parser * parser, guint8 * data,
|
|||
GstH264Picture *pic;
|
||||
gint seq_parameter_set_id;
|
||||
GstH264Sequence *seq;
|
||||
guint8 pic_scaling_matrix_present_flag;
|
||||
|
||||
g_return_val_if_fail (GST_IS_H264_PARSER (parser), NULL);
|
||||
g_return_val_if_fail (data != NULL, NULL);
|
||||
|
@ -557,27 +564,28 @@ gst_h264_parser_parse_picture (GstH264Parser * parser, guint8 * data,
|
|||
|
||||
for (i = 0; i <= pic->num_slice_groups_minus1; i++)
|
||||
READ_UE (&reader, pic->run_length_minus1[i]);
|
||||
} else if (pic->slice_group_map_type == 2) {
|
||||
gint i;
|
||||
|
||||
for (i = 0; i <= pic->num_slice_groups_minus1; i++) {
|
||||
READ_UE (&reader, pic->top_left[i]);
|
||||
READ_UE (&reader, pic->bottom_right[i]);
|
||||
}
|
||||
} else if (pic->slice_group_map_type >= 3 && pic->slice_group_map_type <= 5) {
|
||||
READ_UINT8 (&reader, pic->slice_group_change_direction_flag, 1);
|
||||
READ_UE (&reader, pic->slice_group_change_rate_minus1);
|
||||
} else if (pic->slice_group_map_type == 6) {
|
||||
gint bits;
|
||||
gint i;
|
||||
|
||||
READ_UE (&reader, pic->pic_size_in_map_units_minus1);
|
||||
bits = ceil (log2 (pic->num_slice_groups_minus1 + 1));
|
||||
|
||||
pic->slice_group_id =
|
||||
g_new (guint8, pic->pic_size_in_map_units_minus1 + 1);
|
||||
for (i = 0; i <= pic->pic_size_in_map_units_minus1; i++)
|
||||
READ_UINT8 (&reader, pic->slice_group_id[i], bits);
|
||||
}
|
||||
} else if (pic->slice_group_map_type == 2) {
|
||||
gint i;
|
||||
|
||||
for (i = 0; i <= pic->num_slice_groups_minus1; i++) {
|
||||
READ_UE (&reader, pic->top_left[i]);
|
||||
READ_UE (&reader, pic->bottom_right[i]);
|
||||
}
|
||||
} else if (pic->slice_group_map_type >= 3 && pic->slice_group_map_type <= 5) {
|
||||
READ_UINT8 (&reader, pic->slice_group_change_direction_flag, 1);
|
||||
READ_UE (&reader, pic->slice_group_change_rate_minus1);
|
||||
} else if (pic->slice_group_map_type == 6) {
|
||||
gint bits;
|
||||
gint i;
|
||||
|
||||
READ_UE (&reader, pic->pic_size_in_map_units_minus1);
|
||||
bits = ceil (log2 (pic->num_slice_groups_minus1 + 1));
|
||||
|
||||
pic->slice_group_id = g_new (guint8, pic->pic_size_in_map_units_minus1 + 1);
|
||||
for (i = 0; i <= pic->pic_size_in_map_units_minus1; i++)
|
||||
READ_UINT8 (&reader, pic->slice_group_id[i], bits);
|
||||
}
|
||||
|
||||
READ_UE_ALLOWED (&reader, pic->num_ref_idx_l0_active_minus1, 0, 31);
|
||||
|
@ -597,8 +605,8 @@ gst_h264_parser_parse_picture (GstH264Parser * parser, guint8 * data,
|
|||
|
||||
READ_UINT8 (&reader, pic->transform_8x8_mode_flag, 1);
|
||||
|
||||
READ_UINT8 (&reader, pic->scaling_matrix_present_flag, 1);
|
||||
if (pic->scaling_matrix_present_flag) {
|
||||
READ_UINT8 (&reader, pic_scaling_matrix_present_flag, 1);
|
||||
if (pic_scaling_matrix_present_flag) {
|
||||
if (seq->scaling_matrix_present_flag) {
|
||||
if (!gst_h264_parser_parse_scaling_list (&reader,
|
||||
pic->scaling_lists_4x4, pic->scaling_lists_8x8,
|
||||
|
@ -613,6 +621,9 @@ gst_h264_parser_parse_picture (GstH264Parser * parser, guint8 * data,
|
|||
default_8x8_inter, default_8x8_intra, seq->chroma_format_idc))
|
||||
goto error;
|
||||
}
|
||||
} else {
|
||||
memcpy (&pic->scaling_lists_4x4, &seq->scaling_lists_4x4, 96);
|
||||
memcpy (&pic->scaling_lists_8x8, &seq->scaling_lists_8x8, 384);
|
||||
}
|
||||
|
||||
READ_SE_ALLOWED (&reader, pic->second_chroma_qp_index_offset, -12, 12);
|
||||
|
@ -653,7 +664,7 @@ gst_h264_slice_parse_pred_weight_table (GstH264Slice * slice,
|
|||
memset (p->chroma_offset_l0, 0, 64);
|
||||
}
|
||||
|
||||
for (i = 0; i <= pic->num_ref_idx_l0_active_minus1; i++) {
|
||||
for (i = 0; i <= slice->num_ref_idx_l0_active_minus1; i++) {
|
||||
guint8 luma_weight_l0_flag;
|
||||
|
||||
READ_UINT8 (reader, luma_weight_l0_flag, 1);
|
||||
|
@ -666,15 +677,17 @@ gst_h264_slice_parse_pred_weight_table (GstH264Slice * slice,
|
|||
gint j;
|
||||
|
||||
READ_UINT8 (reader, chroma_weight_l0_flag, 1);
|
||||
for (j = 0; j <= 2; j++) {
|
||||
READ_SE_ALLOWED (reader, p->chroma_weight_l0[i][j], -128, 127);
|
||||
READ_SE_ALLOWED (reader, p->chroma_offset_l0[i][j], -128, 127);
|
||||
if (chroma_weight_l0_flag) {
|
||||
for (j = 0; j < 2; j++) {
|
||||
READ_SE_ALLOWED (reader, p->chroma_weight_l0[i][j], -128, 127);
|
||||
READ_SE_ALLOWED (reader, p->chroma_offset_l0[i][j], -128, 127);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (GST_H264_IS_B_SLICE (slice->type)) {
|
||||
for (i = 0; i <= pic->num_ref_idx_l1_active_minus1; i++) {
|
||||
for (i = 0; i <= slice->num_ref_idx_l1_active_minus1; i++) {
|
||||
guint8 luma_weight_l1_flag;
|
||||
|
||||
READ_UINT8 (reader, luma_weight_l1_flag, 1);
|
||||
|
@ -687,9 +700,11 @@ gst_h264_slice_parse_pred_weight_table (GstH264Slice * slice,
|
|||
gint j;
|
||||
|
||||
READ_UINT8 (reader, chroma_weight_l1_flag, 1);
|
||||
for (j = 0; j <= 2; j++) {
|
||||
READ_SE_ALLOWED (reader, p->chroma_weight_l1[i][j], -128, 127);
|
||||
READ_SE_ALLOWED (reader, p->chroma_offset_l1[i][j], -128, 127);
|
||||
if (chroma_weight_l1_flag) {
|
||||
for (j = 0; j < 2; j++) {
|
||||
READ_SE_ALLOWED (reader, p->chroma_weight_l1[i][j], -128, 127);
|
||||
READ_SE_ALLOWED (reader, p->chroma_offset_l1[i][j], -128, 127);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -740,7 +755,7 @@ gst_h264_slice_parse_ref_pic_list_reordering (GstH264Slice * slice,
|
|||
if (reordering_of_pic_nums_idc == 0 || reordering_of_pic_nums_idc == 1) {
|
||||
guint32 abs_diff_num_minus1;
|
||||
READ_UE (reader, abs_diff_num_minus1);
|
||||
} else if (reordering_of_pic_nums_idc == 3) {
|
||||
} else if (reordering_of_pic_nums_idc == 2) {
|
||||
guint32 long_term_pic_num;
|
||||
|
||||
READ_UE (reader, long_term_pic_num);
|
||||
|
@ -772,32 +787,39 @@ gst_h264_slice_parse_dec_ref_pic_marking (GstH264Slice * slice,
|
|||
READ_UINT8 (reader, m->adaptive_ref_pic_marking_mode_flag, 1);
|
||||
if (m->adaptive_ref_pic_marking_mode_flag) {
|
||||
guint8 memory_management_control_operation;
|
||||
guint i = 0;
|
||||
|
||||
do {
|
||||
m->n_ref_pic_marking = 0;
|
||||
while (1) {
|
||||
READ_UE_ALLOWED (reader, memory_management_control_operation, 0, 6);
|
||||
m->ref_pic_marking[i].memory_management_control_operation =
|
||||
if (memory_management_control_operation == 0)
|
||||
break;
|
||||
|
||||
m->ref_pic_marking[m->n_ref_pic_marking].
|
||||
memory_management_control_operation =
|
||||
memory_management_control_operation;
|
||||
|
||||
if (memory_management_control_operation == 1 ||
|
||||
memory_management_control_operation == 3)
|
||||
READ_UE (reader, m->ref_pic_marking[i].difference_of_pic_nums_minus1);
|
||||
READ_UE (reader,
|
||||
m->ref_pic_marking[m->n_ref_pic_marking].
|
||||
difference_of_pic_nums_minus1);
|
||||
|
||||
if (memory_management_control_operation == 2)
|
||||
READ_UE (reader, m->ref_pic_marking[i].long_term_pic_num);
|
||||
READ_UE (reader,
|
||||
m->ref_pic_marking[m->n_ref_pic_marking].long_term_pic_num);
|
||||
|
||||
if (memory_management_control_operation == 3 ||
|
||||
memory_management_control_operation == 6)
|
||||
READ_UE (reader, m->ref_pic_marking[i].long_term_frame_idx);
|
||||
READ_UE (reader,
|
||||
m->ref_pic_marking[m->n_ref_pic_marking].long_term_frame_idx);
|
||||
|
||||
if (memory_management_control_operation == 4)
|
||||
READ_UE (reader, m->ref_pic_marking[i].max_long_term_frame_idx_plus1);
|
||||
READ_UE (reader,
|
||||
m->ref_pic_marking[m->n_ref_pic_marking].
|
||||
max_long_term_frame_idx_plus1);
|
||||
|
||||
i++;
|
||||
m->n_ref_pic_marking++;
|
||||
}
|
||||
while (memory_management_control_operation != 0);
|
||||
|
||||
m->n_ref_pic_marking = i;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -71,6 +71,7 @@ typedef struct _GstH264Sequence GstH264Sequence;
|
|||
typedef struct _GstH264Picture GstH264Picture;
|
||||
|
||||
typedef struct _GstH264DecRefPicMarking GstH264DecRefPicMarking;
|
||||
typedef struct _GstH264RefPicMarking GstH264RefPicMarking;
|
||||
typedef struct _GstH264PredWeightTable GstH264PredWeightTable;
|
||||
typedef struct _GstH264Slice GstH264Slice;
|
||||
|
||||
|
@ -239,33 +240,30 @@ struct _GstH264Picture
|
|||
|
||||
guint8 transform_8x8_mode_flag;
|
||||
|
||||
guint8 scaling_matrix_present_flag;
|
||||
/* if scaling_matrix_present_flag == 1 */
|
||||
guint8 scaling_lists_4x4[6][16];
|
||||
guint8 scaling_lists_8x8[6][64];
|
||||
|
||||
guint8 second_chroma_qp_index_offset;
|
||||
};
|
||||
|
||||
struct _GstH264RefPicMarking
|
||||
{
|
||||
guint8 memory_management_control_operation;
|
||||
|
||||
guint32 difference_of_pic_nums_minus1;
|
||||
guint32 long_term_pic_num;
|
||||
guint32 long_term_frame_idx;
|
||||
guint32 max_long_term_frame_idx_plus1;
|
||||
};
|
||||
|
||||
struct _GstH264DecRefPicMarking
|
||||
{
|
||||
/* if slice->nal_unit.IdrPicFlag */
|
||||
guint8 no_output_of_prior_pics_flag;
|
||||
guint8 long_term_reference_flag;
|
||||
|
||||
/* else */
|
||||
guint8 adaptive_ref_pic_marking_mode_flag;
|
||||
|
||||
struct {
|
||||
guint8 memory_management_control_operation;
|
||||
|
||||
union {
|
||||
guint32 difference_of_pic_nums_minus1;
|
||||
guint32 long_term_pic_num;
|
||||
guint32 long_term_frame_idx;
|
||||
guint32 max_long_term_frame_idx_plus1;
|
||||
};
|
||||
} ref_pic_marking[10];
|
||||
GstH264RefPicMarking ref_pic_marking[10];
|
||||
guint8 n_ref_pic_marking;
|
||||
};
|
||||
|
||||
|
|
|
@ -236,20 +236,33 @@ gst_vdp_h264_dec_init_frame_info (GstVdpH264Dec * h264_dec,
|
|||
|
||||
h264_frame->output_needed = TRUE;
|
||||
h264_frame->is_long_term = FALSE;
|
||||
h264_frame->frame_num = slice->frame_num;
|
||||
h264_frame->frame_idx = slice->frame_num;
|
||||
|
||||
/* is reference */
|
||||
if (slice->nal_unit.ref_idc == 0)
|
||||
h264_frame->is_reference = FALSE;
|
||||
else if (slice->nal_unit.IdrPicFlag) {
|
||||
h264_frame->is_reference = TRUE;
|
||||
h264_frame->is_long_term =
|
||||
slice->dec_ref_pic_marking.long_term_reference_flag;
|
||||
if (slice->dec_ref_pic_marking.long_term_reference_flag) {
|
||||
h264_frame->is_long_term = TRUE;
|
||||
h264_frame->frame_idx = 0;
|
||||
}
|
||||
} else {
|
||||
if (slice->dec_ref_pic_marking.adaptive_ref_pic_marking_mode_flag)
|
||||
GST_ERROR ("FIXME: implement adaptive ref pic marking");
|
||||
else
|
||||
h264_frame->is_reference = TRUE;
|
||||
h264_frame->is_reference = TRUE;
|
||||
|
||||
if (slice->dec_ref_pic_marking.adaptive_ref_pic_marking_mode_flag) {
|
||||
GstH264RefPicMarking *marking;
|
||||
guint i;
|
||||
|
||||
marking = slice->dec_ref_pic_marking.ref_pic_marking;
|
||||
for (i = 0; i < slice->dec_ref_pic_marking.n_ref_pic_marking; i++) {
|
||||
if (marking[i].memory_management_control_operation == 6) {
|
||||
h264_frame->is_long_term = TRUE;
|
||||
h264_frame->frame_idx = marking[i].long_term_frame_idx;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -269,6 +282,10 @@ gst_vdp_h264_dec_idr (GstVdpH264Dec * h264_dec, GstVdpH264Frame * h264_frame)
|
|||
else
|
||||
gst_h264_dpb_flush (h264_dec->dpb, TRUE);
|
||||
|
||||
if (slice->dec_ref_pic_marking.long_term_reference_flag)
|
||||
g_object_set (h264_dec->dpb, "max-longterm-frame-idx", 0, NULL);
|
||||
else
|
||||
g_object_set (h264_dec->dpb, "max-longterm-frame-idx", -1, NULL);
|
||||
|
||||
seq = slice->picture->sequence;
|
||||
if (seq != h264_dec->sequence) {
|
||||
|
@ -356,6 +373,8 @@ gst_vdp_h264_dec_fill_info (GstVdpH264Dec * h264_dec,
|
|||
|
||||
info.field_pic_flag = slice->field_pic_flag;
|
||||
info.bottom_field_flag = slice->bottom_field_flag;
|
||||
info.num_ref_idx_l0_active_minus1 = slice->num_ref_idx_l0_active_minus1;
|
||||
info.num_ref_idx_l1_active_minus1 = slice->num_ref_idx_l1_active_minus1;
|
||||
|
||||
info.num_ref_frames = seq->num_ref_frames;
|
||||
info.frame_mbs_only_flag = seq->frame_mbs_only_flag;
|
||||
|
@ -375,21 +394,14 @@ gst_vdp_h264_dec_fill_info (GstVdpH264Dec * h264_dec,
|
|||
info.chroma_qp_index_offset = pic->chroma_qp_index_offset;
|
||||
info.second_chroma_qp_index_offset = pic->second_chroma_qp_index_offset;
|
||||
info.pic_init_qp_minus26 = pic->pic_init_qp_minus26;
|
||||
info.num_ref_idx_l0_active_minus1 = pic->num_ref_idx_l0_active_minus1;
|
||||
info.num_ref_idx_l1_active_minus1 = pic->num_ref_idx_l1_active_minus1;
|
||||
info.entropy_coding_mode_flag = pic->entropy_coding_mode_flag;
|
||||
info.pic_order_present_flag = pic->pic_order_present_flag;
|
||||
info.deblocking_filter_control_present_flag =
|
||||
pic->deblocking_filter_control_present_flag;
|
||||
info.redundant_pic_cnt_present_flag = pic->redundant_pic_cnt_present_flag;
|
||||
|
||||
if (pic->scaling_matrix_present_flag) {
|
||||
memcpy (&info.scaling_lists_4x4, &pic->scaling_lists_4x4, 96);
|
||||
memcpy (&info.scaling_lists_8x8, &pic->scaling_lists_8x8, 128);
|
||||
} else {
|
||||
memcpy (&info.scaling_lists_4x4, &seq->scaling_lists_4x4, 96);
|
||||
memcpy (&info.scaling_lists_8x8, &seq->scaling_lists_8x8, 128);
|
||||
}
|
||||
memcpy (&info.scaling_lists_4x4, &pic->scaling_lists_4x4, 96);
|
||||
memcpy (&info.scaling_lists_8x8, &pic->scaling_lists_8x8, 128);
|
||||
|
||||
gst_h264_dpb_fill_reference_frames (h264_dec->dpb, info.referenceFrames);
|
||||
|
||||
|
@ -490,6 +502,8 @@ gst_vdp_h264_dec_handle_frame (GstBaseVideoDecoder * base_video_decoder,
|
|||
return GST_FLOW_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
gst_vdp_h264_dec_init_frame_info (h264_dec, h264_frame);
|
||||
|
||||
|
||||
|
@ -515,14 +529,66 @@ gst_vdp_h264_dec_handle_frame (GstBaseVideoDecoder * base_video_decoder,
|
|||
frame->src_buffer = GST_BUFFER_CAST (outbuf);
|
||||
|
||||
|
||||
|
||||
/* DPB handling */
|
||||
if (slice->nal_unit.ref_idc != 0 && !slice->nal_unit.IdrPicFlag) {
|
||||
if (slice->dec_ref_pic_marking.adaptive_ref_pic_marking_mode_flag)
|
||||
GST_ERROR ("FIXME: implement adaptive ref pic marking");
|
||||
else
|
||||
if (slice->dec_ref_pic_marking.adaptive_ref_pic_marking_mode_flag) {
|
||||
GstH264RefPicMarking *marking;
|
||||
guint i;
|
||||
|
||||
marking = slice->dec_ref_pic_marking.ref_pic_marking;
|
||||
for (i = 0; i < slice->dec_ref_pic_marking.n_ref_pic_marking; i++) {
|
||||
|
||||
switch (marking[i].memory_management_control_operation) {
|
||||
case 1:
|
||||
{
|
||||
guint16 pic_num;
|
||||
|
||||
pic_num = slice->frame_num -
|
||||
(marking[i].difference_of_pic_nums_minus1 + 1);
|
||||
gst_h264_dpb_mark_short_term_unused (h264_dec->dpb, pic_num);
|
||||
break;
|
||||
}
|
||||
|
||||
case 2:
|
||||
{
|
||||
gst_h264_dpb_mark_long_term_unused (h264_dec->dpb,
|
||||
marking[i].long_term_pic_num);
|
||||
break;
|
||||
}
|
||||
|
||||
case 3:
|
||||
{
|
||||
guint16 pic_num;
|
||||
|
||||
pic_num = slice->frame_num -
|
||||
(marking[i].difference_of_pic_nums_minus1 + 1);
|
||||
gst_h264_dpb_mark_long_term (h264_dec->dpb, pic_num,
|
||||
marking[i].long_term_frame_idx);
|
||||
break;
|
||||
}
|
||||
|
||||
case 4:
|
||||
{
|
||||
g_object_set (h264_dec->dpb, "max-longterm-frame-idx",
|
||||
marking[i].max_long_term_frame_idx_plus1 - 1, NULL);
|
||||
break;
|
||||
}
|
||||
|
||||
case 5:
|
||||
{
|
||||
gst_h264_dpb_mark_all_unused (h264_dec->dpb);
|
||||
g_object_set (h264_dec->dpb, "max-longterm-frame-idx", -1, NULL);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else
|
||||
gst_h264_dpb_mark_sliding (h264_dec->dpb);
|
||||
}
|
||||
|
||||
gst_h264_dpb_add (h264_dec->dpb, h264_frame);
|
||||
|
||||
return GST_FLOW_OK;
|
||||
|
|
|
@ -45,7 +45,7 @@ struct _GstVdpH264Frame
|
|||
GPtrArray *slices;
|
||||
|
||||
guint poc;
|
||||
guint16 frame_num;
|
||||
guint16 frame_idx;
|
||||
gboolean is_reference;
|
||||
gboolean is_long_term;
|
||||
gboolean output_needed;
|
||||
|
|
Loading…
Reference in a new issue