mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-19 05:45:58 +00:00
vdpauh264dec: now works for simple streams
This commit is contained in:
parent
80749da166
commit
322d1ff946
3 changed files with 103 additions and 55 deletions
|
@ -48,8 +48,8 @@ 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;
|
||||
|
@ -58,6 +58,26 @@ gst_h264_dpb_fill_reference_frames (GstH264DPB * dpb,
|
|||
reference_frames[i].field_order_cnt[1] = frame->poc;
|
||||
reference_frames[i].frame_idx = frame->frame_num;
|
||||
}
|
||||
|
||||
for (i = dpb->n_frames; i < 16; i++) {
|
||||
reference_frames[i].surface = VDP_INVALID_HANDLE;
|
||||
reference_frames[i].top_is_reference = VDP_FALSE;
|
||||
reference_frames[i].bottom_is_reference = VDP_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gst_h264_dpb_remove (GstH264DPB * dpb, guint idx)
|
||||
{
|
||||
GstVdpH264Frame **frames;
|
||||
guint i;
|
||||
|
||||
frames = dpb->frames;
|
||||
gst_video_frame_unref (GST_VIDEO_FRAME_CAST (frames[idx]));
|
||||
dpb->n_frames--;
|
||||
|
||||
for (i = idx; i < dpb->n_frames; i++)
|
||||
frames[i] = frames[i + 1];
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -67,18 +87,10 @@ gst_h264_dpb_output (GstH264DPB * dpb, guint idx)
|
|||
|
||||
gst_video_frame_ref (GST_VIDEO_FRAME_CAST (frame));
|
||||
dpb->output (dpb, frame);
|
||||
frame->output_needed = FALSE;
|
||||
|
||||
if (!frame->is_reference) {
|
||||
GstVdpH264Frame **frames;
|
||||
guint i;
|
||||
|
||||
gst_video_frame_unref (GST_VIDEO_FRAME_CAST (frame));
|
||||
dpb->n_frames--;
|
||||
|
||||
frames = dpb->frames;
|
||||
for (i = idx; i < dpb->n_frames; i++)
|
||||
frames[i] = frames[i + 1];
|
||||
}
|
||||
if (!frame->is_reference)
|
||||
gst_h264_dpb_remove (dpb, idx);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
@ -153,6 +165,8 @@ gst_h264_dpb_flush (GstH264DPB * dpb, gboolean output)
|
|||
GstVideoFrame **frames;
|
||||
guint i;
|
||||
|
||||
GST_DEBUG ("flush");
|
||||
|
||||
if (output)
|
||||
while (gst_h264_dpb_bump (dpb, G_MAXUINT));
|
||||
|
||||
|
@ -171,6 +185,9 @@ gst_h264_dpb_mark_sliding (GstH264DPB * dpb)
|
|||
guint i;
|
||||
gint mark_idx;
|
||||
|
||||
if (dpb->n_frames != dpb->max_frames)
|
||||
return;
|
||||
|
||||
frames = dpb->frames;
|
||||
for (i = 0; i < dpb->n_frames; i++) {
|
||||
if (frames[i]->is_reference && !frames[i]->is_long_term) {
|
||||
|
@ -187,6 +204,8 @@ gst_h264_dpb_mark_sliding (GstH264DPB * dpb)
|
|||
}
|
||||
|
||||
frames[mark_idx]->is_reference = FALSE;
|
||||
if (!frames[mark_idx]->output_needed)
|
||||
gst_h264_dpb_remove (dpb, mark_idx);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -255,45 +255,46 @@ gst_h264_parser_parse_scaling_list (GstNalReader * reader,
|
|||
const guint8 fallback_8x8_inter[64], const guint8 fallback_8x8_intra[64],
|
||||
guint32 chroma_format_idc)
|
||||
{
|
||||
gint i;
|
||||
guint8 seq_scaling_list_present_flag[12] = { 0, };
|
||||
guint i;
|
||||
|
||||
GST_WARNING ("parsing scaling lists");
|
||||
|
||||
for (i = 0; i < ((chroma_format_idc) != 3) ? 8 : 12; i++) {
|
||||
READ_UINT8 (reader, seq_scaling_list_present_flag[i], 1);
|
||||
}
|
||||
|
||||
for (i = 0; i < 12; i++) {
|
||||
gboolean use_default = FALSE;
|
||||
|
||||
if (seq_scaling_list_present_flag[i]) {
|
||||
guint8 *scaling_list;
|
||||
guint size;
|
||||
guint j;
|
||||
guint8 last_scale, next_scale;
|
||||
if (i < ((chroma_format_idc != 3) ? 8 : 12)) {
|
||||
guint8 scaling_list_present_flag;
|
||||
|
||||
if (i <= 5) {
|
||||
scaling_list = scaling_lists_4x4[i];
|
||||
size = 16;
|
||||
} else {
|
||||
scaling_list = scaling_lists_8x8[i];
|
||||
size = 64;
|
||||
}
|
||||
READ_UINT8 (reader, scaling_list_present_flag, 1);
|
||||
if (scaling_list_present_flag) {
|
||||
guint8 *scaling_list;
|
||||
guint size;
|
||||
guint j;
|
||||
guint8 last_scale, next_scale;
|
||||
|
||||
last_scale = 8;
|
||||
next_scale = 8;
|
||||
for (j = 0; j < size; j++) {
|
||||
if (next_scale != 0) {
|
||||
gint32 delta_scale;
|
||||
|
||||
READ_SE (reader, delta_scale);
|
||||
next_scale = (last_scale + delta_scale + 256) % 256;
|
||||
use_default = (j == 0 && next_scale == 0);
|
||||
if (i <= 5) {
|
||||
scaling_list = scaling_lists_4x4[i];
|
||||
size = 16;
|
||||
} else {
|
||||
scaling_list = scaling_lists_8x8[i - 6];
|
||||
size = 64;
|
||||
}
|
||||
scaling_list[j] = (next_scale == 0) ? last_scale : next_scale;
|
||||
last_scale = scaling_list[j];
|
||||
}
|
||||
|
||||
last_scale = 8;
|
||||
next_scale = 8;
|
||||
for (j = 0; j < size; j++) {
|
||||
if (next_scale != 0) {
|
||||
gint32 delta_scale;
|
||||
|
||||
READ_SE (reader, delta_scale);
|
||||
next_scale = (last_scale + delta_scale + 256) % 256;
|
||||
use_default = (j == 0 && next_scale == 0);
|
||||
}
|
||||
scaling_list[j] = (next_scale == 0) ? last_scale : next_scale;
|
||||
last_scale = scaling_list[j];
|
||||
}
|
||||
} else
|
||||
use_default = TRUE;
|
||||
} else
|
||||
use_default = TRUE;
|
||||
|
||||
|
@ -396,8 +397,8 @@ gst_h264_parser_parse_sequence (GstH264Parser * parser, guint8 * data,
|
|||
|
||||
if (seq->profile_idc == 100 || seq->profile_idc == 110 ||
|
||||
seq->profile_idc == 122 || seq->profile_idc == 244 ||
|
||||
seq->profile_idc == 244 || seq->profile_idc == 44 ||
|
||||
seq->profile_idc == 83 || seq->profile_idc == 86) {
|
||||
seq->profile_idc == 44 || seq->profile_idc == 83 ||
|
||||
seq->profile_idc == 86) {
|
||||
READ_UE_ALLOWED (&reader, seq->chroma_format_idc, 0, 3);
|
||||
if (seq->chroma_format_idc == 3)
|
||||
READ_UINT8 (&reader, seq->separate_colour_plane_flag, 1);
|
||||
|
@ -497,8 +498,18 @@ gst_h264_parser_more_data (GstNalReader * reader)
|
|||
if (!gst_nal_reader_peek_bits_uint8 (reader, &rbsp_stop_one_bit, 1))
|
||||
return FALSE;
|
||||
|
||||
if (rbsp_stop_one_bit == 1)
|
||||
return FALSE;
|
||||
if (rbsp_stop_one_bit == 1) {
|
||||
guint8 zero_bits;
|
||||
|
||||
if (remaining == 1)
|
||||
return FALSE;
|
||||
|
||||
if (!gst_nal_reader_peek_bits_uint8 (reader, &zero_bits, remaining))
|
||||
return FALSE;
|
||||
|
||||
if ((zero_bits - (1 << (remaining - 1))) == 0)
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
@ -754,7 +765,7 @@ gst_h264_slice_parse_dec_ref_pic_marking (GstH264Slice * slice,
|
|||
|
||||
m = &slice->dec_ref_pic_marking;
|
||||
|
||||
if (slice->nal_unit.IdrPicFlag == 0) {
|
||||
if (slice->nal_unit.IdrPicFlag) {
|
||||
READ_UINT8 (reader, m->no_output_of_prior_pics_flag, 1);
|
||||
READ_UINT8 (reader, m->long_term_reference_flag, 1);
|
||||
} else {
|
||||
|
|
|
@ -183,9 +183,13 @@ gst_vdp_h264_dec_shape_output (GstBaseVideoDecoder * base_video_decoder,
|
|||
static void
|
||||
gst_vdp_h264_dec_output (GstH264DPB * dpb, GstVdpH264Frame * h264_frame)
|
||||
{
|
||||
GstBaseVideoDecoder *base_video_decoder;
|
||||
|
||||
GST_DEBUG ("poc: %d", h264_frame->poc);
|
||||
|
||||
gst_video_frame_unref (GST_VIDEO_FRAME_CAST (h264_frame));
|
||||
base_video_decoder = g_object_get_data (G_OBJECT (dpb), "decoder");
|
||||
gst_base_video_decoder_finish_frame (base_video_decoder,
|
||||
GST_VIDEO_FRAME_CAST (h264_frame));
|
||||
}
|
||||
|
||||
static guint
|
||||
|
@ -230,7 +234,9 @@ gst_vdp_h264_dec_init_frame_info (GstVdpH264Dec * h264_dec,
|
|||
|
||||
h264_frame->poc = gst_vdp_h264_dec_calculate_poc (h264_dec, slice);
|
||||
|
||||
h264_frame->output_needed = TRUE;
|
||||
h264_frame->is_long_term = FALSE;
|
||||
h264_frame->frame_num = slice->frame_num;
|
||||
|
||||
/* is reference */
|
||||
if (slice->nal_unit.ref_idc == 0)
|
||||
|
@ -266,14 +272,16 @@ gst_vdp_h264_dec_idr (GstVdpH264Dec * h264_dec, GstVdpH264Frame * h264_frame)
|
|||
|
||||
seq = slice->picture->sequence;
|
||||
if (seq != h264_dec->sequence) {
|
||||
GstFlowReturn ret;
|
||||
GstVdpDevice *device;
|
||||
|
||||
gst_base_video_decoder_update_src_caps (GST_BASE_VIDEO_DECODER (h264_dec));
|
||||
|
||||
device = gst_vdp_video_src_pad_get_device
|
||||
(GST_VDP_VIDEO_SRC_PAD (GST_BASE_VIDEO_DECODER_SRC_PAD (h264_dec)));
|
||||
ret = gst_vdp_video_src_pad_get_device
|
||||
(GST_VDP_VIDEO_SRC_PAD (GST_BASE_VIDEO_DECODER_SRC_PAD (h264_dec)),
|
||||
&device, NULL);
|
||||
|
||||
if (device) {
|
||||
if (ret == GST_FLOW_OK) {
|
||||
GstVideoState *state;
|
||||
VdpDecoderProfile profile;
|
||||
VdpStatus status;
|
||||
|
@ -344,6 +352,7 @@ gst_vdp_h264_dec_fill_info (GstVdpH264Dec * h264_dec,
|
|||
info.field_order_cnt[1] = h264_frame->poc;
|
||||
|
||||
info.is_reference = h264_frame->is_reference;
|
||||
info.frame_num = slice->frame_num;
|
||||
|
||||
info.field_pic_flag = slice->field_pic_flag;
|
||||
info.bottom_field_flag = slice->bottom_field_flag;
|
||||
|
@ -374,8 +383,13 @@ gst_vdp_h264_dec_fill_info (GstVdpH264Dec * h264_dec,
|
|||
pic->deblocking_filter_control_present_flag;
|
||||
info.redundant_pic_cnt_present_flag = pic->redundant_pic_cnt_present_flag;
|
||||
|
||||
memcpy (&info.scaling_lists_4x4, &pic->scaling_lists_4x4, 96);
|
||||
memcpy (&info.scaling_lists_8x8, &pic->scaling_lists_8x8, 128);
|
||||
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);
|
||||
}
|
||||
|
||||
gst_h264_dpb_fill_reference_frames (h264_dec->dpb, info.referenceFrames);
|
||||
|
||||
|
@ -652,6 +666,7 @@ gst_vdp_h264_dec_parse_data (GstBaseVideoDecoder * base_video_decoder,
|
|||
if (!gst_bit_reader_skip (&reader, 24))
|
||||
goto invalid_packet;
|
||||
}
|
||||
nal_unit.IdrPicFlag = (nal_unit.type == 5 ? 1 : 0);
|
||||
|
||||
data = GST_BUFFER_DATA (buf) + gst_bit_reader_get_pos (&reader) / 8;
|
||||
size = gst_bit_reader_get_remaining (&reader) / 8;
|
||||
|
@ -811,6 +826,7 @@ gst_vdp_h264_dec_start (GstBaseVideoDecoder * base_video_decoder)
|
|||
h264_dec->parser = g_object_new (GST_TYPE_H264_PARSER, NULL);
|
||||
|
||||
h264_dec->dpb = g_object_new (GST_TYPE_H264_DPB, NULL);
|
||||
g_object_set_data (G_OBJECT (h264_dec->dpb), "decoder", h264_dec);
|
||||
h264_dec->dpb->output = gst_vdp_h264_dec_output;
|
||||
|
||||
return TRUE;
|
||||
|
@ -822,6 +838,7 @@ gst_vdp_h264_dec_stop (GstBaseVideoDecoder * base_video_decoder)
|
|||
GstVdpH264Dec *h264_dec = GST_VDP_H264_DEC (base_video_decoder);
|
||||
|
||||
GstVdpVideoSrcPad *vdp_pad;
|
||||
GstFlowReturn ret;
|
||||
GstVdpDevice *device;
|
||||
|
||||
g_object_unref (h264_dec->parser);
|
||||
|
@ -831,7 +848,8 @@ gst_vdp_h264_dec_stop (GstBaseVideoDecoder * base_video_decoder)
|
|||
GST_VDP_VIDEO_SRC_PAD (GST_BASE_VIDEO_DECODER_SRC_PAD
|
||||
(base_video_decoder));
|
||||
|
||||
if ((device = gst_vdp_video_src_pad_get_device (vdp_pad))) {
|
||||
ret = gst_vdp_video_src_pad_get_device (vdp_pad, &device, NULL);
|
||||
if (ret == GST_FLOW_OK) {
|
||||
|
||||
if (h264_dec->decoder != VDP_INVALID_HANDLE)
|
||||
device->vdp_decoder_destroy (h264_dec->decoder);
|
||||
|
|
Loading…
Reference in a new issue