<html>
<head>
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
</head>
<body bgcolor="#FFFFFF" text="#000000">
<div class="moz-cite-prefix">On 25.11.2015 10:12, Julien Isorce
wrote:<br>
</div>
<blockquote
cite="mid:CAHWPjbVyCYF+Kc=71e58GmgU3U7oKfQhxGynOH7p4R_v6ZjYog@mail.gmail.com"
type="cite">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<div dir="ltr">
<div>For commit message please read:<br>
<br>
</div>
"HEVC case is left unchanged since delaying decoder creation is
not needed on AMD hardware."<br>
</div>
</blockquote>
<br>
In this case please update the commit message, but honestly I'm not
sure if we don't use the max_references somewhere in the DPB
calculation for HEVC.<br>
<br>
Some more comments below.<br>
<br>
<blockquote
cite="mid:CAHWPjbVyCYF+Kc=71e58GmgU3U7oKfQhxGynOH7p4R_v6ZjYog@mail.gmail.com"
type="cite">
<div dir="ltr"><br>
<div>instead of <br>
<br>
"XXX: do the same for HEVC"</div>
</div>
<div class="gmail_extra"><br>
<div class="gmail_quote">On 25 November 2015 at 09:07, Julien
Isorce <span dir="ltr"><<a moz-do-not-send="true"
href="mailto:julien.isorce@gmail.com" target="_blank">julien.isorce@gmail.com</a>></span>
wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0
.8ex;border-left:1px #ccc solid;padding-left:1ex">From:
Julien Isorce <<a moz-do-not-send="true"
href="mailto:julien.isorce@gmail.com">julien.isorce@gmail.com</a>><br>
<br>
In general max_references cannot be based on
num_render_targets.<br>
<br>
This patch allow to allocate accurate sizes for buffers.<br>
For other codecs it is a fixed value to 2.<br>
<br>
This is similar behaviour as vaapi/vdpau-driver.<br>
<br>
XXX: do the same for HEVC<br>
<br>
Signed-off-by: Julien Isorce <<a moz-do-not-send="true"
href="mailto:j.isorce@samsung.com">j.isorce@samsung.com</a>><br>
---<br>
src/gallium/state_trackers/va/context.c | 41
++++++++++++++--------------<br>
src/gallium/state_trackers/va/picture.c | 37
++++++++++++++++++-------<br>
src/gallium/state_trackers/va/picture_h264.c | 29
+++++++++++++++++++-<br>
src/gallium/state_trackers/va/va_private.h | 4 +--<br>
4 files changed, 78 insertions(+), 33 deletions(-)<br>
<br>
diff --git a/src/gallium/state_trackers/va/context.c
b/src/gallium/state_trackers/va/context.c<br>
index f0051e5..985007b 100644<br>
--- a/src/gallium/state_trackers/va/context.c<br>
+++ b/src/gallium/state_trackers/va/context.c<br>
@@ -187,7 +187,6 @@ vlVaCreateContext(VADriverContextP ctx,
VAConfigID config_id, int picture_width,<br>
int picture_height, int flag, VASurfaceID
*render_targets,<br>
int num_render_targets, VAContextID
*context_id)<br>
{<br>
- struct pipe_video_codec templat = {};<br>
vlVaDriver *drv;<br>
vlVaContext *context;<br>
int is_vpp;<br>
@@ -213,27 +212,28 @@ vlVaCreateContext(VADriverContextP
ctx, VAConfigID config_id, int picture_width,<br>
return VA_STATUS_ERROR_INVALID_CONTEXT;<br>
}<br>
} else {<br>
- templat.profile = config_id;<br>
- templat.entrypoint = PIPE_VIDEO_ENTRYPOINT_BITSTREAM;<br>
- templat.chroma_format = PIPE_VIDEO_CHROMA_FORMAT_420;<br>
- templat.width = picture_width;<br>
- templat.height = picture_height;<br>
- templat.max_references = num_render_targets;<br>
- templat.expect_chunked_decode = true;<br>
-<br>
- if (u_reduce_video_profile(templat.profile) ==<br>
- PIPE_VIDEO_FORMAT_MPEG4_AVC)<br>
- templat.level = u_get_h264_level(templat.width,
templat.height,<br>
- &templat.max_references);<br>
-<br>
- context->decoder =
drv->pipe->create_video_codec(drv->pipe,
&templat);<br>
- if (!context->decoder) {<br>
- FREE(context);<br>
- return VA_STATUS_ERROR_ALLOCATION_FAILED;<br>
+ context->templat.profile = config_id;<br>
+ context->templat.entrypoint =
PIPE_VIDEO_ENTRYPOINT_BITSTREAM;<br>
+ context->templat.chroma_format =
PIPE_VIDEO_CHROMA_FORMAT_420;<br>
+ context->templat.width = picture_width;<br>
+ context->templat.height = picture_height;<br>
+ context->templat.max_references = 2;<br>
+ context->templat.expect_chunked_decode = true;<br>
+<br>
+ /* Can only create decoders for which max_references
is known. */<br>
+ if
(u_reduce_video_profile(context->templat.profile) !=<br>
+ PIPE_VIDEO_FORMAT_MPEG4_AVC) {<br>
+ context->decoder =
drv->pipe->create_video_codec(drv->pipe,<br>
+ &context->templat);<br>
+ if (!context->decoder) {<br>
+ FREE(context);<br>
+ return VA_STATUS_ERROR_ALLOCATION_FAILED;<br>
+ }<br>
}<br>
<br>
- if
(u_reduce_video_profile(context->decoder->profile) ==<br>
+ if
(u_reduce_video_profile(context->templat.profile) ==<br>
PIPE_VIDEO_FORMAT_MPEG4_AVC) {<br>
</blockquote>
</div>
</div>
</blockquote>
<br>
Please join this check with the one above, maybe even make this a
switch statement.<br>
<br>
Apart from that looks good to me.<br>
<br>
<blockquote
cite="mid:CAHWPjbVyCYF+Kc=71e58GmgU3U7oKfQhxGynOH7p4R_v6ZjYog@mail.gmail.com"
type="cite">
<div class="gmail_extra">
<div class="gmail_quote">
<blockquote class="gmail_quote" style="margin:0 0 0
.8ex;border-left:1px #ccc solid;padding-left:1ex">
+ context->templat.max_references = 0;<br>
context->desc.h264.pps =
CALLOC_STRUCT(pipe_h264_pps);<br>
if (!context->desc.h264.pps) {<br>
FREE(context);<br>
@@ -247,8 +247,9 @@ vlVaCreateContext(VADriverContextP ctx,
VAConfigID config_id, int picture_width,<br>
}<br>
}<br>
<br>
- if
(u_reduce_video_profile(context->decoder->profile) ==<br>
+ if
(u_reduce_video_profile(context->templat.profile) ==<br>
PIPE_VIDEO_FORMAT_HEVC) {<br>
+ context->templat.max_references =
num_render_targets;<br>
context->desc.h265.pps =
CALLOC_STRUCT(pipe_h265_pps);<br>
if (!context->desc.h265.pps) {<br>
FREE(context);<br>
diff --git a/src/gallium/state_trackers/va/picture.c
b/src/gallium/state_trackers/va/picture.c<br>
index 25d2940..e80873b 100644<br>
--- a/src/gallium/state_trackers/va/picture.c<br>
+++ b/src/gallium/state_trackers/va/picture.c<br>
@@ -60,6 +60,12 @@ vlVaBeginPicture(VADriverContextP ctx,
VAContextID context_id, VASurfaceID rende<br>
<br>
context->target = surf->buffer;<br>
if (!context->decoder) {<br>
+ /* Decoder creation is delayed until max_references
is set. */<br>
+ if
(u_reduce_video_profile(context->templat.profile) ==<br>
+ PIPE_VIDEO_FORMAT_MPEG4_AVC)<br>
+ return context->templat.max_references == 0 ?<br>
+ VA_STATUS_SUCCESS :
VA_STATUS_ERROR_INVALID_CONTEXT;<br>
+<br>
/* VPP */<br>
if ((context->target->buffer_format !=
PIPE_FORMAT_B8G8R8A8_UNORM &&<br>
context->target->buffer_format !=
PIPE_FORMAT_R8G8B8A8_UNORM &&<br>
@@ -67,6 +73,7 @@ vlVaBeginPicture(VADriverContextP ctx,
VAContextID context_id, VASurfaceID rende<br>
context->target->buffer_format !=
PIPE_FORMAT_R8G8B8X8_UNORM) ||<br>
context->target->interlaced)<br>
return VA_STATUS_ERROR_UNIMPLEMENTED;<br>
+<br>
return VA_STATUS_SUCCESS;<br>
}<br>
<br>
@@ -86,16 +93,18 @@ vlVaGetReferenceFrame(vlVaDriver *drv,
VASurfaceID surface_id,<br>
*ref_frame = NULL;<br>
}<br>
<br>
-static void<br>
+static VAStatus<br>
handlePictureParameterBuffer(vlVaDriver *drv, vlVaContext
*context, vlVaBuffer *buf)<br>
{<br>
- switch
(u_reduce_video_profile(context->decoder->profile)) {<br>
+ VAStatus vaStatus = VA_STATUS_SUCCESS;<br>
+<br>
+ switch
(u_reduce_video_profile(context->templat.profile)) {<br>
case PIPE_VIDEO_FORMAT_MPEG12:<br>
vlVaHandlePictureParameterBufferMPEG12(drv, context,
buf);<br>
break;<br>
<br>
case PIPE_VIDEO_FORMAT_MPEG4_AVC:<br>
- vlVaHandlePictureParameterBufferH264(drv, context,
buf);<br>
+ vaStatus = vlVaHandlePictureParameterBufferH264(drv,
context, buf);<br>
break;<br>
<br>
case PIPE_VIDEO_FORMAT_VC1:<br>
@@ -113,12 +122,14 @@
handlePictureParameterBuffer(vlVaDriver *drv, vlVaContext
*context, vlVaBuffer *<br>
default:<br>
break;<br>
}<br>
+<br>
+ return vaStatus;<br>
}<br>
<br>
static void<br>
handleIQMatrixBuffer(vlVaContext *context, vlVaBuffer *buf)<br>
{<br>
- switch
(u_reduce_video_profile(context->decoder->profile)) {<br>
+ switch
(u_reduce_video_profile(context->templat.profile)) {<br>
case PIPE_VIDEO_FORMAT_MPEG12:<br>
vlVaHandleIQMatrixBufferMPEG12(context, buf);<br>
break;<br>
@@ -142,7 +153,7 @@ handleIQMatrixBuffer(vlVaContext
*context, vlVaBuffer *buf)<br>
static void<br>
handleSliceParameterBuffer(vlVaContext *context, vlVaBuffer
*buf)<br>
{<br>
- switch
(u_reduce_video_profile(context->decoder->profile)) {<br>
+ switch
(u_reduce_video_profile(context->templat.profile)) {<br>
case PIPE_VIDEO_FORMAT_MPEG4_AVC:<br>
vlVaHandleSliceParameterBufferH264(context, buf);<br>
break;<br>
@@ -178,8 +189,8 @@ bufHasStartcode(vlVaBuffer *buf,
unsigned int code, unsigned int bits)<br>
return 0;<br>
}<br>
<br>
-static void<br>
-handleVASliceDataBufferType(vlVaContext *context,
vlVaBuffer *buf)<br>
+static VAStatus<br>
+handleVASliceDataBufferType(vlVaDriver *drv, vlVaContext
*context, vlVaBuffer *buf)<br>
{<br>
enum pipe_video_format format;<br>
unsigned num_buffers = 0;<br>
@@ -189,7 +200,7 @@ handleVASliceDataBufferType(vlVaContext
*context, vlVaBuffer *buf)<br>
static const uint8_t start_code_h265[] = { 0x00, 0x00,
0x01 };<br>
static const uint8_t start_code_vc1[] = { 0x00, 0x00,
0x01, 0x0d };<br>
<br>
- format =
u_reduce_video_profile(context->decoder->profile);<br>
+ format =
u_reduce_video_profile(context->templat.profile);<br>
switch (format) {<br>
case PIPE_VIDEO_FORMAT_MPEG4_AVC:<br>
if (bufHasStartcode(buf, 0x000001, 24))<br>
@@ -232,6 +243,8 @@ handleVASliceDataBufferType(vlVaContext
*context, vlVaBuffer *buf)<br>
++num_buffers;<br>
context->decoder->decode_bitstream(context->decoder,
context->target, &context->desc.base,<br>
num_buffers, (const void * const*)buffers, sizes);<br>
+<br>
+ return VA_STATUS_SUCCESS;<br>
}<br>
<br>
VAStatus<br>
@@ -261,7 +274,7 @@ vlVaRenderPicture(VADriverContextP ctx,
VAContextID context_id, VABufferID *buff<br>
<br>
switch (buf->type) {<br>
case VAPictureParameterBufferType:<br>
- handlePictureParameterBuffer(drv, context, buf);<br>
+ vaStatus = handlePictureParameterBuffer(drv,
context, buf);<br>
break;<br>
<br>
case VAIQMatrixBufferType:<br>
@@ -273,7 +286,7 @@ vlVaRenderPicture(VADriverContextP ctx,
VAContextID context_id, VABufferID *buff<br>
break;<br>
<br>
case VASliceDataBufferType:<br>
- handleVASliceDataBufferType(context, buf);<br>
+ vaStatus = handleVASliceDataBufferType(drv,
context, buf);<br>
break;<br>
case VAProcPipelineParameterBufferType:<br>
vaStatus =
vlVaHandleVAProcPipelineParameterBufferType(drv, context,
buf);<br>
@@ -305,6 +318,10 @@ vlVaEndPicture(VADriverContextP ctx,
VAContextID context_id)<br>
return VA_STATUS_ERROR_INVALID_CONTEXT;<br>
<br>
if (!context->decoder) {<br>
+ if
(u_reduce_video_profile(context->templat.profile) ==<br>
+ PIPE_VIDEO_FORMAT_MPEG4_AVC)<br>
+ return VA_STATUS_ERROR_INVALID_CONTEXT;<br>
+<br>
/* VPP */<br>
return VA_STATUS_SUCCESS;<br>
}<br>
diff --git a/src/gallium/state_trackers/va/picture_h264.c
b/src/gallium/state_trackers/va/picture_h264.c<br>
index bd6c8a0..e9a8825 100644<br>
--- a/src/gallium/state_trackers/va/picture_h264.c<br>
+++ b/src/gallium/state_trackers/va/picture_h264.c<br>
@@ -26,9 +26,10 @@<br>
*<br>
**************************************************************************/<br>
<br>
+#include "util/u_video.h"<br>
#include "va_private.h"<br>
<br>
-void vlVaHandlePictureParameterBufferH264(vlVaDriver *drv,
vlVaContext *context, vlVaBuffer *buf)<br>
+VAStatus vlVaHandlePictureParameterBufferH264(vlVaDriver
*drv, vlVaContext *context, vlVaBuffer *buf)<br>
{<br>
VAPictureParameterBufferH264 *h264 = buf->data;<br>
<br>
@@ -90,6 +91,32 @@ void
vlVaHandlePictureParameterBufferH264(vlVaDriver *drv,
vlVaContext *context,<br>
h264->pic_fields.bits.redundant_pic_cnt_present_flag;<br>
/*reference_pic_flag*/<br>
context->desc.h264.frame_num = h264->frame_num;<br>
+<br>
+ if (!context->decoder &&
context->desc.h264.num_ref_frames > 0)<br>
+ context->templat.max_references =
MIN2(context->desc.h264.num_ref_frames, 16);<br>
+<br>
+ /* Create the decoder once max_references is known. */<br>
+ if (!context->decoder) {<br>
+ if (!context->target)<br>
+ return VA_STATUS_ERROR_INVALID_CONTEXT;<br>
+<br>
+ if (context->templat.max_references == 0)<br>
+ return VA_STATUS_ERROR_INVALID_BUFFER;<br>
+<br>
+ context->templat.level =
u_get_h264_level(context->templat.width,<br>
+ context->templat.height,
&context->templat.max_references);<br>
+<br>
+ context->decoder =
drv->pipe->create_video_codec(drv->pipe,<br>
+ &context->templat);<br>
+<br>
+ if (!context->decoder)<br>
+ return VA_STATUS_ERROR_ALLOCATION_FAILED;<br>
+<br>
+
context->decoder->begin_frame(context->decoder,
context->target,<br>
+ &context->desc.base);<br>
+ }<br>
+<br>
+ return VA_STATUS_SUCCESS;<br>
}<br>
<br>
void vlVaHandleIQMatrixBufferH264(vlVaContext *context,
vlVaBuffer *buf)<br>
diff --git a/src/gallium/state_trackers/va/va_private.h
b/src/gallium/state_trackers/va/va_private.h<br>
index ff1b9bd..cf9b29d 100644<br>
--- a/src/gallium/state_trackers/va/va_private.h<br>
+++ b/src/gallium/state_trackers/va/va_private.h<br>
@@ -215,7 +215,7 @@ typedef struct {<br>
} vlVaSubpicture;<br>
<br>
typedef struct {<br>
- struct pipe_video_codec *decoder;<br>
+ struct pipe_video_codec templat, *decoder;<br>
struct pipe_video_buffer *target;<br>
union {<br>
struct pipe_picture_desc base;<br>
@@ -353,7 +353,7 @@ VAStatus
vlVaHandleVAProcPipelineParameterBufferType(vlVaDriver *drv,
vlVaContex<br>
void vlVaGetReferenceFrame(vlVaDriver *drv, VASurfaceID
surface_id, struct pipe_video_buffer **ref_frame);<br>
void vlVaHandlePictureParameterBufferMPEG12(vlVaDriver
*drv, vlVaContext *context, vlVaBuffer *buf);<br>
void vlVaHandleIQMatrixBufferMPEG12(vlVaContext *context,
vlVaBuffer *buf);<br>
-void vlVaHandlePictureParameterBufferH264(vlVaDriver *drv,
vlVaContext *context, vlVaBuffer *buf);<br>
+VAStatus vlVaHandlePictureParameterBufferH264(vlVaDriver
*drv, vlVaContext *context, vlVaBuffer *buf);<br>
void vlVaHandleIQMatrixBufferH264(vlVaContext *context,
vlVaBuffer *buf);<br>
void vlVaHandleSliceParameterBufferH264(vlVaContext
*context, vlVaBuffer *buf);<br>
void vlVaHandlePictureParameterBufferVC1(vlVaDriver *drv,
vlVaContext *context, vlVaBuffer *buf);<br>
<span class="HOEnZb"><font color="#888888">--<br>
1.9.1<br>
<br>
</font></span></blockquote>
</div>
<br>
</div>
</blockquote>
<br>
</body>
</html>