summaryrefslogtreecommitdiff
path: root/sys/vdpau
diff options
context:
space:
mode:
authorCarl-Anton Ingmarsson <ca.ingmarsson@gmail.com>2010-06-22 14:17:28 +0200
committerCarl-Anton Ingmarsson <ca.ingmarsson@gmail.com>2010-06-23 21:51:53 +0200
commit3ea3a084e4f7ddf1adab1c9fb15cacdb87803b4b (patch)
treea95195303d0239e23c1009e88684b5b206788036 /sys/vdpau
parent322d1ff9460b7eeedc78d2c07d2195b785be2f3f (diff)
vdpauh264dec: improve further
Diffstat (limited to 'sys/vdpau')
-rw-r--r--sys/vdpau/h264/gsth264dpb.c146
-rw-r--r--sys/vdpau/h264/gsth264dpb.h6
-rw-r--r--sys/vdpau/h264/gsth264parser.c106
-rw-r--r--sys/vdpau/h264/gsth264parser.h26
-rw-r--r--sys/vdpau/h264/gstvdph264dec.c106
-rw-r--r--sys/vdpau/h264/gstvdph264frame.h2
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;