diff options
author | Carl-Anton Ingmarsson <ca.ingmarsson@gmail.com> | 2010-06-22 14:17:28 +0200 |
---|---|---|
committer | Carl-Anton Ingmarsson <ca.ingmarsson@gmail.com> | 2010-06-23 21:51:53 +0200 |
commit | 3ea3a084e4f7ddf1adab1c9fb15cacdb87803b4b (patch) | |
tree | a95195303d0239e23c1009e88684b5b206788036 /sys/vdpau | |
parent | 322d1ff9460b7eeedc78d2c07d2195b785be2f3f (diff) |
vdpauh264dec: improve further
Diffstat (limited to 'sys/vdpau')
-rw-r--r-- | sys/vdpau/h264/gsth264dpb.c | 146 | ||||
-rw-r--r-- | sys/vdpau/h264/gsth264dpb.h | 6 | ||||
-rw-r--r-- | sys/vdpau/h264/gsth264parser.c | 106 | ||||
-rw-r--r-- | sys/vdpau/h264/gsth264parser.h | 26 | ||||
-rw-r--r-- | sys/vdpau/h264/gstvdph264dec.c | 106 | ||||
-rw-r--r-- | sys/vdpau/h264/gstvdph264frame.h | 2 |
6 files changed, 300 insertions, 92 deletions
diff --git a/sys/vdpau/h264/gsth264dpb.c b/sys/vdpau/h264/gsth264dpb.c index a2d695686..3f61b61c4 100644 --- a/sys/vdpau/h264/gsth264dpb.c +++ b/sys/vdpau/h264/gsth264dpb.c @@ -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)); + } diff --git a/sys/vdpau/h264/gsth264dpb.h b/sys/vdpau/h264/gsth264dpb.h index ff5fe0f55..d8962fe8e 100644 --- a/sys/vdpau/h264/gsth264dpb.h +++ b/sys/vdpau/h264/gsth264dpb.h @@ -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 diff --git a/sys/vdpau/h264/gsth264parser.c b/sys/vdpau/h264/gsth264parser.c index 6d442d8d3..8de7c2fdb 100644 --- a/sys/vdpau/h264/gsth264parser.c +++ b/sys/vdpau/h264/gsth264parser.c @@ -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; + } 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)); - for (i = 0; i <= pic->num_slice_groups_minus1; i++) { - READ_UE (&reader, pic->top_left[i]); - READ_UE (&reader, pic->bottom_right[i]); + 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 >= 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; } } diff --git a/sys/vdpau/h264/gsth264parser.h b/sys/vdpau/h264/gsth264parser.h index 2c18c0532..1c8e6c204 100644 --- a/sys/vdpau/h264/gsth264parser.h +++ b/sys/vdpau/h264/gsth264parser.h @@ -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; }; diff --git a/sys/vdpau/h264/gstvdph264dec.c b/sys/vdpau/h264/gstvdph264dec.c index 93071fb21..0a1adb1b3 100644 --- a/sys/vdpau/h264/gstvdph264dec.c +++ b/sys/vdpau/h264/gstvdph264dec.c @@ -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; diff --git a/sys/vdpau/h264/gstvdph264frame.h b/sys/vdpau/h264/gstvdph264frame.h index adbb1501e..2b8666894 100644 --- a/sys/vdpau/h264/gstvdph264frame.h +++ b/sys/vdpau/h264/gstvdph264frame.h @@ -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; |