vdpauh264dec: improve further

This commit is contained in:
Carl-Anton Ingmarsson 2010-06-22 14:17:28 +02:00
parent 322d1ff946
commit 3ea3a084e4
6 changed files with 301 additions and 93 deletions

View file

@ -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));
}

View file

@ -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

View file

@ -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;
}
}

View file

@ -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;
};

View file

@ -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;

View file

@ -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;