summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLeo Liu <leo.liu@amd.com>2016-08-29 13:09:12 -0400
committerLeo Liu <leo.liu@amd.com>2016-09-06 10:08:01 -0400
commit6d186a79f2d28dff93eddece5b0f0fdc0897301f (patch)
treef973b71154cb1cb8b76d80857ff47d3725db7a2c
parent0c374a7770ce3aee1048ffc1dbc82170017133ac (diff)
st/omx/dec: add initial omx hevc support
Mainly based on the h264 implementation. Signed-off-by: Leo Liu <leo.liu@amd.com> Acked-by: Christian König <christian.koenig@amd.com>
-rw-r--r--src/gallium/state_trackers/omx/Makefile.sources1
-rw-r--r--src/gallium/state_trackers/omx/vid_dec.h11
-rw-r--r--src/gallium/state_trackers/omx/vid_dec_h265.c148
3 files changed, 160 insertions, 0 deletions
diff --git a/src/gallium/state_trackers/omx/Makefile.sources b/src/gallium/state_trackers/omx/Makefile.sources
index d25cd2e3934..ab60ce803cb 100644
--- a/src/gallium/state_trackers/omx/Makefile.sources
+++ b/src/gallium/state_trackers/omx/Makefile.sources
@@ -5,5 +5,6 @@ C_SOURCES := \
vid_dec.h \
vid_dec_mpeg12.c \
vid_dec_h264.c \
+ vid_dec_h265.c \
vid_enc.c \
vid_enc.h
diff --git a/src/gallium/state_trackers/omx/vid_dec.h b/src/gallium/state_trackers/omx/vid_dec.h
index d268925ab26..4568e6d6b9d 100644
--- a/src/gallium/state_trackers/omx/vid_dec.h
+++ b/src/gallium/state_trackers/omx/vid_dec.h
@@ -94,11 +94,19 @@ DERIVEDCLASS(vid_dec_PrivateType, omx_base_filter_PrivateType)
struct list_head dpb_list; \
unsigned dpb_num; \
} h264; \
+ struct { \
+ unsigned level_idc; \
+ struct pipe_h265_sps sps[16]; \
+ struct pipe_h265_pps pps[64]; \
+ struct list_head dpb_list; \
+ unsigned dpb_num; \
+ } h265; \
} codec_data; \
union { \
struct pipe_picture_desc base; \
struct pipe_mpeg12_picture_desc mpeg12; \
struct pipe_h264_picture_desc h264; \
+ struct pipe_h265_picture_desc h265; \
} picture; \
unsigned num_in_buffers; \
OMX_BUFFERHEADERTYPE *in_buffers[2]; \
@@ -126,4 +134,7 @@ void vid_dec_mpeg12_Init(vid_dec_PrivateType *priv);
/* vid_dec_h264.c */
void vid_dec_h264_Init(vid_dec_PrivateType *priv);
+/* vid_dec_h265.c */
+void vid_dec_h265_Init(vid_dec_PrivateType *priv);
+
#endif
diff --git a/src/gallium/state_trackers/omx/vid_dec_h265.c b/src/gallium/state_trackers/omx/vid_dec_h265.c
new file mode 100644
index 00000000000..49936b0219a
--- /dev/null
+++ b/src/gallium/state_trackers/omx/vid_dec_h265.c
@@ -0,0 +1,148 @@
+/**************************************************************************
+ *
+ * Copyright 2016 Advanced Micro Devices, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+#include "pipe/p_video_codec.h"
+#include "util/u_memory.h"
+#include "util/u_video.h"
+#include "vl/vl_rbsp.h"
+
+#include "entrypoint.h"
+#include "vid_dec.h"
+
+#define DPB_MAX_SIZE 16
+
+struct dpb_list {
+ struct list_head list;
+ struct pipe_video_buffer *buffer;
+ unsigned poc;
+};
+
+static void vid_dec_h265_BeginFrame(vid_dec_PrivateType *priv)
+{
+ if (priv->frame_started)
+ return;
+
+ vid_dec_NeedTarget(priv);
+
+ 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.expect_chunked_decode = true;
+ templat.width = align(port->sPortParam.format.video.nFrameWidth, 4);
+ templat.height = align(port->sPortParam.format.video.nFrameHeight, 4);
+ templat.level = priv->codec_data.h265.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_h265_Flush(vid_dec_PrivateType *priv,
+ OMX_TICKS *timestamp)
+{
+ struct dpb_list *entry, *result = NULL;
+ struct pipe_video_buffer *buf;
+
+ /* search for the lowest poc and break on zeros */
+ LIST_FOR_EACH_ENTRY(entry, &priv->codec_data.h265.dpb_list, list) {
+
+ if (result && entry->poc == 0)
+ break;
+
+ if (!result || entry->poc < result->poc)
+ result = entry;
+ }
+
+ if (!result)
+ return NULL;
+
+ buf = result->buffer;
+
+ --priv->codec_data.h265.dpb_num;
+ LIST_DEL(&result->list);
+ FREE(result);
+
+ return buf;
+}
+
+static void vid_dec_h265_EndFrame(vid_dec_PrivateType *priv)
+{
+ struct dpb_list *entry = NULL;
+ struct pipe_video_buffer *tmp;
+
+ if (!priv->frame_started)
+ return;
+
+ priv->codec->end_frame(priv->codec, priv->target, &priv->picture.base);
+ priv->frame_started = false;
+
+ /* add the decoded picture to the dpb list */
+ entry = CALLOC_STRUCT(dpb_list);
+ if (!entry)
+ return;
+
+ entry->buffer = priv->target;
+
+ LIST_ADDTAIL(&entry->list, &priv->codec_data.h265.dpb_list);
+ ++priv->codec_data.h265.dpb_num;
+ priv->target = NULL;
+
+ if (priv->codec_data.h265.dpb_num <= DPB_MAX_SIZE)
+ return;
+
+ tmp = priv->in_buffers[0]->pInputPortPrivate;
+ priv->in_buffers[0]->pInputPortPrivate = vid_dec_h265_Flush(priv, NULL);
+ priv->target = tmp;
+ priv->frame_finished = priv->in_buffers[0]->pInputPortPrivate != NULL;
+}
+
+static void vid_dec_h265_Decode(vid_dec_PrivateType *priv,
+ struct vl_vlc *vlc,
+ unsigned min_bits_left)
+{
+ /* TODO */
+
+ /* resync to byte boundary */
+ vl_vlc_eatbits(vlc, vl_vlc_valid_bits(vlc) % 8);
+}
+
+void vid_dec_h265_Init(vid_dec_PrivateType *priv)
+{
+ priv->picture.base.profile = PIPE_VIDEO_PROFILE_HEVC_MAIN;
+
+ LIST_INITHEAD(&priv->codec_data.h265.dpb_list);
+
+ priv->Decode = vid_dec_h265_Decode;
+ priv->EndFrame = vid_dec_h265_EndFrame;
+ priv->Flush = vid_dec_h265_Flush;
+}