mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-10-04 09:42:19 +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
|
enum
|
||||||
{
|
{
|
||||||
PROP_0,
|
PROP_0,
|
||||||
PROP_NUM_REF_FRAMES
|
PROP_NUM_REF_FRAMES,
|
||||||
|
PROP_MAX_LONGTERM_IDX
|
||||||
};
|
};
|
||||||
|
|
||||||
GST_DEBUG_CATEGORY_STATIC (h264dpb_debug);
|
GST_DEBUG_CATEGORY_STATIC (h264dpb_debug);
|
||||||
|
@ -48,15 +49,15 @@ gst_h264_dpb_fill_reference_frames (GstH264DPB * dpb,
|
||||||
GstVdpH264Frame *frame = frames[i];
|
GstVdpH264Frame *frame = frames[i];
|
||||||
|
|
||||||
reference_frames[i].surface =
|
reference_frames[i].surface =
|
||||||
GST_VDP_VIDEO_BUFFER (GST_VIDEO_FRAME_CAST (frame)->
|
GST_VDP_VIDEO_BUFFER (GST_VIDEO_FRAME_CAST (frame)->src_buffer)->
|
||||||
src_buffer)->surface;
|
surface;
|
||||||
|
|
||||||
reference_frames[i].is_long_term = frame->is_long_term;
|
reference_frames[i].is_long_term = frame->is_long_term;
|
||||||
reference_frames[i].top_is_reference = frame->is_reference;
|
reference_frames[i].top_is_reference = frame->is_reference;
|
||||||
reference_frames[i].bottom_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[0] = frame->poc;
|
||||||
reference_frames[i].field_order_cnt[1] = 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++) {
|
for (i = dpb->n_frames; i < 16; i++) {
|
||||||
|
@ -134,8 +135,11 @@ gst_h264_dpb_add (GstH264DPB * dpb, GstVdpH264Frame * h264_frame)
|
||||||
|
|
||||||
frames = dpb->frames;
|
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) {
|
while (dpb->n_frames == dpb->max_frames) {
|
||||||
if (!gst_h264_dpb_bump (dpb, G_MAXUINT)) {
|
if (!gst_h264_dpb_bump (dpb, G_MAXUINT)) {
|
||||||
GST_ERROR_OBJECT (dpb, "Couldn't make room in DPB");
|
GST_ERROR_OBJECT (dpb, "Couldn't make room in DPB");
|
||||||
|
@ -146,14 +150,8 @@ gst_h264_dpb_add (GstH264DPB * dpb, GstVdpH264Frame * h264_frame)
|
||||||
}
|
}
|
||||||
|
|
||||||
else {
|
else {
|
||||||
if (dpb->n_frames == dpb->max_frames) {
|
while (gst_h264_dpb_bump (dpb, h264_frame->poc));
|
||||||
while (gst_h264_dpb_bump (dpb, h264_frame->poc));
|
dpb->output (dpb, h264_frame);
|
||||||
|
|
||||||
dpb->output (dpb, h264_frame);
|
|
||||||
}
|
|
||||||
|
|
||||||
else
|
|
||||||
dpb->frames[dpb->n_frames++] = h264_frame;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -183,7 +181,7 @@ gst_h264_dpb_mark_sliding (GstH264DPB * dpb)
|
||||||
{
|
{
|
||||||
GstVdpH264Frame **frames;
|
GstVdpH264Frame **frames;
|
||||||
guint i;
|
guint i;
|
||||||
gint mark_idx;
|
gint mark_idx = -1;
|
||||||
|
|
||||||
if (dpb->n_frames != dpb->max_frames)
|
if (dpb->n_frames != dpb->max_frames)
|
||||||
return;
|
return;
|
||||||
|
@ -199,7 +197,7 @@ gst_h264_dpb_mark_sliding (GstH264DPB * dpb)
|
||||||
if (mark_idx != -1) {
|
if (mark_idx != -1) {
|
||||||
for (i = mark_idx; i < dpb->n_frames; i++) {
|
for (i = mark_idx; i < dpb->n_frames; i++) {
|
||||||
if (frames[i]->is_reference && !frames[i]->is_long_term &&
|
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;
|
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 */
|
/* GObject vmethod implementations */
|
||||||
static void
|
static void
|
||||||
gst_h264_dpb_get_property (GObject * object, guint property_id,
|
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:
|
case PROP_NUM_REF_FRAMES:
|
||||||
g_value_set_uint (value, dpb->max_frames);
|
g_value_set_uint (value, dpb->max_frames);
|
||||||
break;
|
break;
|
||||||
|
case PROP_MAX_LONGTERM_IDX:
|
||||||
|
g_value_set_int (value, dpb->max_longterm_frame_idx);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||||
break;
|
break;
|
||||||
|
@ -244,6 +333,27 @@ gst_h264_dpb_set_property (GObject * object, guint property_id,
|
||||||
break;
|
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:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||||
break;
|
break;
|
||||||
|
@ -262,6 +372,7 @@ static void
|
||||||
gst_h264_dpb_init (GstH264DPB * dpb)
|
gst_h264_dpb_init (GstH264DPB * dpb)
|
||||||
{
|
{
|
||||||
dpb->n_frames = 0;
|
dpb->n_frames = 0;
|
||||||
|
dpb->max_longterm_frame_idx = -1;
|
||||||
dpb->max_frames = MAX_DPB_SIZE;
|
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 ",
|
"How many reference frames the DPB should hold ",
|
||||||
0, 16, 16, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
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 n_frames;
|
||||||
|
|
||||||
guint max_frames;
|
guint max_frames;
|
||||||
|
gint max_longterm_frame_idx;
|
||||||
|
|
||||||
void (*output) (GstH264DPB *dpb, GstVdpH264Frame *h264_frame);
|
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_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;
|
GType gst_h264_dpb_get_type (void) G_GNUC_CONST;
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
|
@ -257,7 +257,7 @@ gst_h264_parser_parse_scaling_list (GstNalReader * reader,
|
||||||
{
|
{
|
||||||
guint i;
|
guint i;
|
||||||
|
|
||||||
GST_WARNING ("parsing scaling lists");
|
GST_DEBUG ("parsing scaling lists");
|
||||||
|
|
||||||
for (i = 0; i < 12; i++) {
|
for (i = 0; i < 12; i++) {
|
||||||
gboolean use_default = FALSE;
|
gboolean use_default = FALSE;
|
||||||
|
@ -460,6 +460,12 @@ gst_h264_parser_parse_sequence (GstH264Parser * parser, guint8 * data,
|
||||||
goto error;
|
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",
|
GST_DEBUG ("adding sequence parameter set with id: %d to hash table",
|
||||||
seq->id);
|
seq->id);
|
||||||
g_hash_table_replace (parser->sequences, &seq->id, seq);
|
g_hash_table_replace (parser->sequences, &seq->id, seq);
|
||||||
|
@ -523,6 +529,7 @@ gst_h264_parser_parse_picture (GstH264Parser * parser, guint8 * data,
|
||||||
GstH264Picture *pic;
|
GstH264Picture *pic;
|
||||||
gint seq_parameter_set_id;
|
gint seq_parameter_set_id;
|
||||||
GstH264Sequence *seq;
|
GstH264Sequence *seq;
|
||||||
|
guint8 pic_scaling_matrix_present_flag;
|
||||||
|
|
||||||
g_return_val_if_fail (GST_IS_H264_PARSER (parser), NULL);
|
g_return_val_if_fail (GST_IS_H264_PARSER (parser), NULL);
|
||||||
g_return_val_if_fail (data != NULL, 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++)
|
for (i = 0; i <= pic->num_slice_groups_minus1; i++)
|
||||||
READ_UE (&reader, pic->run_length_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);
|
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->transform_8x8_mode_flag, 1);
|
||||||
|
|
||||||
READ_UINT8 (&reader, pic->scaling_matrix_present_flag, 1);
|
READ_UINT8 (&reader, pic_scaling_matrix_present_flag, 1);
|
||||||
if (pic->scaling_matrix_present_flag) {
|
if (pic_scaling_matrix_present_flag) {
|
||||||
if (seq->scaling_matrix_present_flag) {
|
if (seq->scaling_matrix_present_flag) {
|
||||||
if (!gst_h264_parser_parse_scaling_list (&reader,
|
if (!gst_h264_parser_parse_scaling_list (&reader,
|
||||||
pic->scaling_lists_4x4, pic->scaling_lists_8x8,
|
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))
|
default_8x8_inter, default_8x8_intra, seq->chroma_format_idc))
|
||||||
goto error;
|
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);
|
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);
|
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;
|
guint8 luma_weight_l0_flag;
|
||||||
|
|
||||||
READ_UINT8 (reader, luma_weight_l0_flag, 1);
|
READ_UINT8 (reader, luma_weight_l0_flag, 1);
|
||||||
|
@ -666,15 +677,17 @@ gst_h264_slice_parse_pred_weight_table (GstH264Slice * slice,
|
||||||
gint j;
|
gint j;
|
||||||
|
|
||||||
READ_UINT8 (reader, chroma_weight_l0_flag, 1);
|
READ_UINT8 (reader, chroma_weight_l0_flag, 1);
|
||||||
for (j = 0; j <= 2; j++) {
|
if (chroma_weight_l0_flag) {
|
||||||
READ_SE_ALLOWED (reader, p->chroma_weight_l0[i][j], -128, 127);
|
for (j = 0; j < 2; j++) {
|
||||||
READ_SE_ALLOWED (reader, p->chroma_offset_l0[i][j], -128, 127);
|
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)) {
|
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;
|
guint8 luma_weight_l1_flag;
|
||||||
|
|
||||||
READ_UINT8 (reader, luma_weight_l1_flag, 1);
|
READ_UINT8 (reader, luma_weight_l1_flag, 1);
|
||||||
|
@ -687,9 +700,11 @@ gst_h264_slice_parse_pred_weight_table (GstH264Slice * slice,
|
||||||
gint j;
|
gint j;
|
||||||
|
|
||||||
READ_UINT8 (reader, chroma_weight_l1_flag, 1);
|
READ_UINT8 (reader, chroma_weight_l1_flag, 1);
|
||||||
for (j = 0; j <= 2; j++) {
|
if (chroma_weight_l1_flag) {
|
||||||
READ_SE_ALLOWED (reader, p->chroma_weight_l1[i][j], -128, 127);
|
for (j = 0; j < 2; j++) {
|
||||||
READ_SE_ALLOWED (reader, p->chroma_offset_l1[i][j], -128, 127);
|
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) {
|
if (reordering_of_pic_nums_idc == 0 || reordering_of_pic_nums_idc == 1) {
|
||||||
guint32 abs_diff_num_minus1;
|
guint32 abs_diff_num_minus1;
|
||||||
READ_UE (reader, 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;
|
guint32 long_term_pic_num;
|
||||||
|
|
||||||
READ_UE (reader, 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);
|
READ_UINT8 (reader, m->adaptive_ref_pic_marking_mode_flag, 1);
|
||||||
if (m->adaptive_ref_pic_marking_mode_flag) {
|
if (m->adaptive_ref_pic_marking_mode_flag) {
|
||||||
guint8 memory_management_control_operation;
|
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);
|
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;
|
memory_management_control_operation;
|
||||||
|
|
||||||
if (memory_management_control_operation == 1 ||
|
if (memory_management_control_operation == 1 ||
|
||||||
memory_management_control_operation == 3)
|
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)
|
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 ||
|
if (memory_management_control_operation == 3 ||
|
||||||
memory_management_control_operation == 6)
|
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)
|
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 _GstH264Picture GstH264Picture;
|
||||||
|
|
||||||
typedef struct _GstH264DecRefPicMarking GstH264DecRefPicMarking;
|
typedef struct _GstH264DecRefPicMarking GstH264DecRefPicMarking;
|
||||||
|
typedef struct _GstH264RefPicMarking GstH264RefPicMarking;
|
||||||
typedef struct _GstH264PredWeightTable GstH264PredWeightTable;
|
typedef struct _GstH264PredWeightTable GstH264PredWeightTable;
|
||||||
typedef struct _GstH264Slice GstH264Slice;
|
typedef struct _GstH264Slice GstH264Slice;
|
||||||
|
|
||||||
|
@ -239,33 +240,30 @@ struct _GstH264Picture
|
||||||
|
|
||||||
guint8 transform_8x8_mode_flag;
|
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_4x4[6][16];
|
||||||
guint8 scaling_lists_8x8[6][64];
|
guint8 scaling_lists_8x8[6][64];
|
||||||
|
|
||||||
guint8 second_chroma_qp_index_offset;
|
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
|
struct _GstH264DecRefPicMarking
|
||||||
{
|
{
|
||||||
/* if slice->nal_unit.IdrPicFlag */
|
/* if slice->nal_unit.IdrPicFlag */
|
||||||
guint8 no_output_of_prior_pics_flag;
|
guint8 no_output_of_prior_pics_flag;
|
||||||
guint8 long_term_reference_flag;
|
guint8 long_term_reference_flag;
|
||||||
|
|
||||||
/* else */
|
|
||||||
guint8 adaptive_ref_pic_marking_mode_flag;
|
guint8 adaptive_ref_pic_marking_mode_flag;
|
||||||
|
GstH264RefPicMarking ref_pic_marking[10];
|
||||||
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];
|
|
||||||
guint8 n_ref_pic_marking;
|
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->output_needed = TRUE;
|
||||||
h264_frame->is_long_term = FALSE;
|
h264_frame->is_long_term = FALSE;
|
||||||
h264_frame->frame_num = slice->frame_num;
|
h264_frame->frame_idx = slice->frame_num;
|
||||||
|
|
||||||
/* is reference */
|
/* is reference */
|
||||||
if (slice->nal_unit.ref_idc == 0)
|
if (slice->nal_unit.ref_idc == 0)
|
||||||
h264_frame->is_reference = FALSE;
|
h264_frame->is_reference = FALSE;
|
||||||
else if (slice->nal_unit.IdrPicFlag) {
|
else if (slice->nal_unit.IdrPicFlag) {
|
||||||
h264_frame->is_reference = TRUE;
|
h264_frame->is_reference = TRUE;
|
||||||
h264_frame->is_long_term =
|
if (slice->dec_ref_pic_marking.long_term_reference_flag) {
|
||||||
slice->dec_ref_pic_marking.long_term_reference_flag;
|
h264_frame->is_long_term = TRUE;
|
||||||
|
h264_frame->frame_idx = 0;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if (slice->dec_ref_pic_marking.adaptive_ref_pic_marking_mode_flag)
|
h264_frame->is_reference = TRUE;
|
||||||
GST_ERROR ("FIXME: implement adaptive ref pic marking");
|
|
||||||
else
|
if (slice->dec_ref_pic_marking.adaptive_ref_pic_marking_mode_flag) {
|
||||||
h264_frame->is_reference = TRUE;
|
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
|
else
|
||||||
gst_h264_dpb_flush (h264_dec->dpb, TRUE);
|
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;
|
seq = slice->picture->sequence;
|
||||||
if (seq != h264_dec->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.field_pic_flag = slice->field_pic_flag;
|
||||||
info.bottom_field_flag = slice->bottom_field_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.num_ref_frames = seq->num_ref_frames;
|
||||||
info.frame_mbs_only_flag = seq->frame_mbs_only_flag;
|
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.chroma_qp_index_offset = pic->chroma_qp_index_offset;
|
||||||
info.second_chroma_qp_index_offset = pic->second_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.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.entropy_coding_mode_flag = pic->entropy_coding_mode_flag;
|
||||||
info.pic_order_present_flag = pic->pic_order_present_flag;
|
info.pic_order_present_flag = pic->pic_order_present_flag;
|
||||||
info.deblocking_filter_control_present_flag =
|
info.deblocking_filter_control_present_flag =
|
||||||
pic->deblocking_filter_control_present_flag;
|
pic->deblocking_filter_control_present_flag;
|
||||||
info.redundant_pic_cnt_present_flag = pic->redundant_pic_cnt_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_4x4, &pic->scaling_lists_4x4, 96);
|
memcpy (&info.scaling_lists_8x8, &pic->scaling_lists_8x8, 128);
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
gst_h264_dpb_fill_reference_frames (h264_dec->dpb, info.referenceFrames);
|
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;
|
return GST_FLOW_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
gst_vdp_h264_dec_init_frame_info (h264_dec, h264_frame);
|
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);
|
frame->src_buffer = GST_BUFFER_CAST (outbuf);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* DPB handling */
|
/* DPB handling */
|
||||||
if (slice->nal_unit.ref_idc != 0 && !slice->nal_unit.IdrPicFlag) {
|
if (slice->nal_unit.ref_idc != 0 && !slice->nal_unit.IdrPicFlag) {
|
||||||
if (slice->dec_ref_pic_marking.adaptive_ref_pic_marking_mode_flag)
|
if (slice->dec_ref_pic_marking.adaptive_ref_pic_marking_mode_flag) {
|
||||||
GST_ERROR ("FIXME: implement adaptive ref pic marking");
|
GstH264RefPicMarking *marking;
|
||||||
else
|
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_mark_sliding (h264_dec->dpb);
|
||||||
}
|
}
|
||||||
|
|
||||||
gst_h264_dpb_add (h264_dec->dpb, h264_frame);
|
gst_h264_dpb_add (h264_dec->dpb, h264_frame);
|
||||||
|
|
||||||
return GST_FLOW_OK;
|
return GST_FLOW_OK;
|
||||||
|
|
|
@ -45,7 +45,7 @@ struct _GstVdpH264Frame
|
||||||
GPtrArray *slices;
|
GPtrArray *slices;
|
||||||
|
|
||||||
guint poc;
|
guint poc;
|
||||||
guint16 frame_num;
|
guint16 frame_idx;
|
||||||
gboolean is_reference;
|
gboolean is_reference;
|
||||||
gboolean is_long_term;
|
gboolean is_long_term;
|
||||||
gboolean output_needed;
|
gboolean output_needed;
|
||||||
|
|
Loading…
Reference in a new issue