X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fgallium%2Fstate_trackers%2Fomx%2Fvid_dec_h264.c;h=54f244b4a1e6221221302330eede4e406465fcd6;hb=2d140ae70ac6ad69f39d427d95bd622d5640a1b7;hp=7b57785c28f0dbe3d05c0b379d65bcadcdc195da;hpb=2b24e5831048727071a5e0359e1eb1f589d45cfb;p=mesa.git diff --git a/src/gallium/state_trackers/omx/vid_dec_h264.c b/src/gallium/state_trackers/omx/vid_dec_h264.c index 7b57785c28f..54f244b4a1e 100644 --- a/src/gallium/state_trackers/omx/vid_dec_h264.c +++ b/src/gallium/state_trackers/omx/vid_dec_h264.c @@ -33,7 +33,9 @@ #include "pipe/p_video_codec.h" #include "util/u_memory.h" +#include "util/u_video.h" #include "vl/vl_rbsp.h" +#include "vl/vl_zscan.h" #include "entrypoint.h" #include "vid_dec.h" @@ -43,6 +45,7 @@ struct dpb_list { struct list_head list; struct pipe_video_buffer *buffer; + OMX_TICKS timestamp; unsigned poc; }; @@ -80,7 +83,7 @@ static const uint8_t Default_8x8_Inter[64] = { static void vid_dec_h264_Decode(vid_dec_PrivateType *priv, struct vl_vlc *vlc, unsigned min_bits_left); static void vid_dec_h264_EndFrame(vid_dec_PrivateType *priv); -static struct pipe_video_buffer *vid_dec_h264_Flush(vid_dec_PrivateType *priv); +static struct pipe_video_buffer *vid_dec_h264_Flush(vid_dec_PrivateType *priv, OMX_TICKS *timestamp); void vid_dec_h264_Init(vid_dec_PrivateType *priv) { @@ -89,9 +92,10 @@ void vid_dec_h264_Init(vid_dec_PrivateType *priv) priv->Decode = vid_dec_h264_Decode; priv->EndFrame = vid_dec_h264_EndFrame; priv->Flush = vid_dec_h264_Flush; - + LIST_INITHEAD(&priv->codec_data.h264.dpb_list); priv->picture.h264.field_order_cnt[0] = priv->picture.h264.field_order_cnt[1] = INT_MAX; + priv->first_buf_in_frame = true; } static void vid_dec_h264_BeginFrame(vid_dec_PrivateType *priv) @@ -102,14 +106,34 @@ static void vid_dec_h264_BeginFrame(vid_dec_PrivateType *priv) return; vid_dec_NeedTarget(priv); + if (priv->first_buf_in_frame) + priv->timestamp = priv->timestamps[0]; + priv->first_buf_in_frame = false; priv->picture.h264.num_ref_frames = priv->picture.h264.pps->sps->max_num_ref_frames; + if (!priv->codec) { + struct pipe_video_codec templat = {}; + omx_base_video_PortType *port; + + port = (omx_base_video_PortType *)priv->ports[OMX_BASE_FILTER_INPUTPORT_INDEX]; + templat.profile = priv->profile; + templat.entrypoint = PIPE_VIDEO_ENTRYPOINT_BITSTREAM; + templat.chroma_format = PIPE_VIDEO_CHROMA_FORMAT_420; + templat.max_references = priv->picture.h264.num_ref_frames; + templat.expect_chunked_decode = true; + templat.width = port->sPortParam.format.video.nFrameWidth; + templat.height = port->sPortParam.format.video.nFrameHeight; + templat.level = priv->picture.h264.pps->sps->level_idc; + + priv->codec = priv->pipe->create_video_codec(priv->pipe, &templat); + } priv->codec->begin_frame(priv->codec, priv->target, &priv->picture.base); priv->frame_started = true; } -static struct pipe_video_buffer *vid_dec_h264_Flush(vid_dec_PrivateType *priv) +static struct pipe_video_buffer *vid_dec_h264_Flush(vid_dec_PrivateType *priv, + OMX_TICKS *timestamp) { struct dpb_list *entry, *result = NULL; struct pipe_video_buffer *buf; @@ -128,6 +152,8 @@ static struct pipe_video_buffer *vid_dec_h264_Flush(vid_dec_PrivateType *priv) return NULL; buf = result->buffer; + if (timestamp) + *timestamp = result->timestamp; --priv->codec_data.h264.dpb_num; LIST_DEL(&result->list); @@ -141,6 +167,7 @@ static void vid_dec_h264_EndFrame(vid_dec_PrivateType *priv) struct dpb_list *entry; struct pipe_video_buffer *tmp; bool top_field_first; + OMX_TICKS timestamp; if (!priv->frame_started) return; @@ -163,7 +190,9 @@ static void vid_dec_h264_EndFrame(vid_dec_PrivateType *priv) if (!entry) return; + priv->first_buf_in_frame = true; entry->buffer = priv->target; + entry->timestamp = priv->timestamp; entry->poc = MIN2(priv->picture.h264.field_order_cnt[0], priv->picture.h264.field_order_cnt[1]); LIST_ADDTAIL(&entry->list, &priv->codec_data.h264.dpb_list); ++priv->codec_data.h264.dpb_num; @@ -174,7 +203,8 @@ static void vid_dec_h264_EndFrame(vid_dec_PrivateType *priv) return; tmp = priv->in_buffers[0]->pInputPortPrivate; - priv->in_buffers[0]->pInputPortPrivate = vid_dec_h264_Flush(priv); + priv->in_buffers[0]->pInputPortPrivate = vid_dec_h264_Flush(priv, ×tamp); + priv->in_buffers[0]->nTimeStamp = timestamp; priv->target = tmp; priv->frame_finished = priv->in_buffers[0]->pInputPortPrivate != NULL; } @@ -188,6 +218,7 @@ static void scaling_list(struct vl_rbsp *rbsp, uint8_t *scalingList, unsigned si const uint8_t *defaultList, const uint8_t *fallbackList) { unsigned lastScale = 8, nextScale = 8; + const int *list; unsigned i; /* (pic|seq)_scaling_list_present_flag[i] */ @@ -197,6 +228,7 @@ static void scaling_list(struct vl_rbsp *rbsp, uint8_t *scalingList, unsigned si return; } + list = (sizeOfScalingList == 16) ? vl_zscan_normal_16 : vl_zscan_normal; for (i = 0; i < sizeOfScalingList; ++i ) { if (nextScale != 0) { @@ -207,15 +239,15 @@ static void scaling_list(struct vl_rbsp *rbsp, uint8_t *scalingList, unsigned si return; } } - scalingList[i] = nextScale == 0 ? lastScale : nextScale; - lastScale = scalingList[i]; + scalingList[list[i]] = nextScale == 0 ? lastScale : nextScale; + lastScale = scalingList[list[i]]; } } static struct pipe_h264_sps *seq_parameter_set_id(vid_dec_PrivateType *priv, struct vl_rbsp *rbsp) { unsigned id = vl_rbsp_ue(rbsp); - if (id >= Elements(priv->codec_data.h264.sps)) + if (id >= ARRAY_SIZE(priv->codec_data.h264.sps)) return NULL; /* invalid seq_parameter_set_id */ return &priv->codec_data.h264.sps[id]; @@ -224,7 +256,7 @@ static struct pipe_h264_sps *seq_parameter_set_id(vid_dec_PrivateType *priv, str static void seq_parameter_set(vid_dec_PrivateType *priv, struct vl_rbsp *rbsp) { struct pipe_h264_sps *sps; - unsigned profile_idc; + unsigned profile_idc, level_idc; unsigned i; /* Sequence parameter set */ @@ -252,7 +284,7 @@ static void seq_parameter_set(vid_dec_PrivateType *priv, struct vl_rbsp *rbsp) vl_rbsp_u(rbsp, 2); /* level_idc */ - vl_rbsp_u(rbsp, 8); + level_idc = vl_rbsp_u(rbsp, 8); sps = seq_parameter_set_id(priv, rbsp); if (!sps) @@ -262,6 +294,8 @@ static void seq_parameter_set(vid_dec_PrivateType *priv, struct vl_rbsp *rbsp) memset(sps->ScalingList4x4, 16, sizeof(sps->ScalingList4x4)); memset(sps->ScalingList8x8, 16, sizeof(sps->ScalingList8x8)); + sps->level_idc = level_idc; + if (profile_idc == 100 || profile_idc == 110 || profile_idc == 122 || profile_idc == 244 || profile_idc == 44 || profile_idc == 83 || profile_idc == 86 || profile_idc == 118 || profile_idc == 128 || profile_idc == 138) { @@ -361,7 +395,7 @@ static void seq_parameter_set(vid_dec_PrivateType *priv, struct vl_rbsp *rbsp) static struct pipe_h264_pps *pic_parameter_set_id(vid_dec_PrivateType *priv, struct vl_rbsp *rbsp) { unsigned id = vl_rbsp_ue(rbsp); - if (id >= Elements(priv->codec_data.h264.pps)) + if (id >= ARRAY_SIZE(priv->codec_data.h264.pps)) return NULL; /* invalid pic_parameter_set_id */ return &priv->codec_data.h264.pps[id]; @@ -706,6 +740,11 @@ static void slice_header(vid_dec_PrivateType *priv, struct vl_rbsp *rbsp, if (pic_order_cnt_lsb != priv->codec_data.h264.pic_order_cnt_lsb) vid_dec_h264_EndFrame(priv); + if (IdrPicFlag) { + priv->codec_data.h264.pic_order_cnt_msb = 0; + priv->codec_data.h264.pic_order_cnt_lsb = 0; + } + if ((pic_order_cnt_lsb < priv->codec_data.h264.pic_order_cnt_lsb) && (priv->codec_data.h264.pic_order_cnt_lsb - pic_order_cnt_lsb) >= (max_pic_order_cnt_lsb / 2)) pic_order_cnt_msb = priv->codec_data.h264.pic_order_cnt_msb + max_pic_order_cnt_lsb; @@ -729,10 +768,14 @@ static void slice_header(vid_dec_PrivateType *priv, struct vl_rbsp *rbsp, priv->codec_data.h264.delta_pic_order_cnt_bottom = delta_pic_order_cnt_bottom; } - priv->picture.h264.field_order_cnt[0] = pic_order_cnt_msb + pic_order_cnt_lsb; - priv->picture.h264.field_order_cnt[1] = pic_order_cnt_msb + pic_order_cnt_lsb; - if (!priv->picture.h264.field_pic_flag) - priv->picture.h264.field_order_cnt[1] += priv->codec_data.h264.delta_pic_order_cnt_bottom; + if (!priv->picture.h264.field_pic_flag) { + priv->picture.h264.field_order_cnt[0] = pic_order_cnt_msb + pic_order_cnt_lsb; + priv->picture.h264.field_order_cnt[1] = priv->picture.h264.field_order_cnt [0] + + priv->codec_data.h264.delta_pic_order_cnt_bottom; + } else if (!priv->picture.h264.bottom_field_flag) + priv->picture.h264.field_order_cnt[0] = pic_order_cnt_msb + pic_order_cnt_lsb; + else + priv->picture.h264.field_order_cnt[1] = pic_order_cnt_msb + pic_order_cnt_lsb; } else if (sps->pic_order_cnt_type == 1) { unsigned MaxFrameNum = 1 << (sps->log2_max_frame_num_minus4 + 4); @@ -798,7 +841,7 @@ static void slice_header(vid_dec_PrivateType *priv, struct vl_rbsp *rbsp, priv->picture.h264.field_order_cnt[0] = expectedPicOrderCnt + priv->codec_data.h264.delta_pic_order_cnt[0]; priv->picture.h264.field_order_cnt[1] = priv->picture.h264.field_order_cnt[0] + sps->offset_for_top_to_bottom_field + priv->codec_data.h264.delta_pic_order_cnt[1]; - + } else if (!priv->picture.h264.bottom_field_flag) priv->picture.h264.field_order_cnt[0] = expectedPicOrderCnt + priv->codec_data.h264.delta_pic_order_cnt[0]; else @@ -828,7 +871,7 @@ static void slice_header(vid_dec_PrivateType *priv, struct vl_rbsp *rbsp, if (!priv->picture.h264.field_pic_flag) { priv->picture.h264.field_order_cnt[0] = tempPicOrderCnt; priv->picture.h264.field_order_cnt[1] = tempPicOrderCnt; - + } else if (!priv->picture.h264.bottom_field_flag) priv->picture.h264.field_order_cnt[0] = tempPicOrderCnt; else @@ -845,7 +888,7 @@ static void slice_header(vid_dec_PrivateType *priv, struct vl_rbsp *rbsp, priv->picture.h264.num_ref_idx_l0_active_minus1 = pps->num_ref_idx_l0_default_active_minus1; priv->picture.h264.num_ref_idx_l1_active_minus1 = pps->num_ref_idx_l1_default_active_minus1; - + if (slice_type == PIPE_H264_SLICE_TYPE_P || slice_type == PIPE_H264_SLICE_TYPE_SP || slice_type == PIPE_H264_SLICE_TYPE_B) {