1 /**************************************************************************
3 * Copyright 2016 Advanced Micro Devices, Inc.
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21 * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR
22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 **************************************************************************/
28 #include "pipe/p_video_codec.h"
29 #include "util/u_memory.h"
30 #include "util/u_video.h"
31 #include "vl/vl_rbsp.h"
33 #include "entrypoint.h"
36 #define DPB_MAX_SIZE 16
39 struct list_head list
;
40 struct pipe_video_buffer
*buffer
;
44 static void vid_dec_h265_BeginFrame(vid_dec_PrivateType
*priv
)
46 if (priv
->frame_started
)
49 vid_dec_NeedTarget(priv
);
52 struct pipe_video_codec templat
= {};
53 omx_base_video_PortType
*port
;
55 port
= (omx_base_video_PortType
*)
56 priv
->ports
[OMX_BASE_FILTER_INPUTPORT_INDEX
];
57 templat
.profile
= priv
->profile
;
58 templat
.entrypoint
= PIPE_VIDEO_ENTRYPOINT_BITSTREAM
;
59 templat
.chroma_format
= PIPE_VIDEO_CHROMA_FORMAT_420
;
60 templat
.expect_chunked_decode
= true;
61 templat
.width
= align(port
->sPortParam
.format
.video
.nFrameWidth
, 4);
62 templat
.height
= align(port
->sPortParam
.format
.video
.nFrameHeight
, 4);
63 templat
.level
= priv
->codec_data
.h265
.level_idc
;
64 priv
->codec
= priv
->pipe
->create_video_codec(priv
->pipe
, &templat
);
66 priv
->codec
->begin_frame(priv
->codec
, priv
->target
, &priv
->picture
.base
);
67 priv
->frame_started
= true;
70 static struct pipe_video_buffer
*vid_dec_h265_Flush(vid_dec_PrivateType
*priv
,
73 struct dpb_list
*entry
, *result
= NULL
;
74 struct pipe_video_buffer
*buf
;
76 /* search for the lowest poc and break on zeros */
77 LIST_FOR_EACH_ENTRY(entry
, &priv
->codec_data
.h265
.dpb_list
, list
) {
79 if (result
&& entry
->poc
== 0)
82 if (!result
|| entry
->poc
< result
->poc
)
91 --priv
->codec_data
.h265
.dpb_num
;
92 LIST_DEL(&result
->list
);
98 static void vid_dec_h265_EndFrame(vid_dec_PrivateType
*priv
)
100 struct dpb_list
*entry
= NULL
;
101 struct pipe_video_buffer
*tmp
;
103 if (!priv
->frame_started
)
106 priv
->codec
->end_frame(priv
->codec
, priv
->target
, &priv
->picture
.base
);
107 priv
->frame_started
= false;
109 /* add the decoded picture to the dpb list */
110 entry
= CALLOC_STRUCT(dpb_list
);
114 entry
->buffer
= priv
->target
;
116 LIST_ADDTAIL(&entry
->list
, &priv
->codec_data
.h265
.dpb_list
);
117 ++priv
->codec_data
.h265
.dpb_num
;
120 if (priv
->codec_data
.h265
.dpb_num
<= DPB_MAX_SIZE
)
123 tmp
= priv
->in_buffers
[0]->pInputPortPrivate
;
124 priv
->in_buffers
[0]->pInputPortPrivate
= vid_dec_h265_Flush(priv
, NULL
);
126 priv
->frame_finished
= priv
->in_buffers
[0]->pInputPortPrivate
!= NULL
;
129 static void vid_dec_h265_Decode(vid_dec_PrivateType
*priv
,
131 unsigned min_bits_left
)
135 /* resync to byte boundary */
136 vl_vlc_eatbits(vlc
, vl_vlc_valid_bits(vlc
) % 8);
139 void vid_dec_h265_Init(vid_dec_PrivateType
*priv
)
141 priv
->picture
.base
.profile
= PIPE_VIDEO_PROFILE_HEVC_MAIN
;
143 LIST_INITHEAD(&priv
->codec_data
.h265
.dpb_list
);
145 priv
->Decode
= vid_dec_h265_Decode
;
146 priv
->EndFrame
= vid_dec_h265_EndFrame
;
147 priv
->Flush
= vid_dec_h265_Flush
;