[FFmpeg-devel] [PATCH 1/3] libavcodec/vaapi_encode: Change the way to call async to increase performance

2021-10-27 Thread Wenbin Chen
Fix: #7706. After commit 5fdcf85bbffe7451c2, vaapi encoder's performance
decrease. The reason is that vaRenderPicture() and vaSyncSurface() are
called at the same time (vaRenderPicture() always followed by a
vaSyncSurface()). When we encode stream with B frames, we need buffer to
reorder frames, so we can send serveral frames to HW at once to increase
performance. Now I changed them to be called in a
asynchronous way, which will make better use of hardware.
1080p transcoding increases about 17% fps on my environment.

Signed-off-by: Wenbin Chen 
---
 libavcodec/vaapi_encode.c | 41 ---
 libavcodec/vaapi_encode.h |  3 +++
 2 files changed, 33 insertions(+), 11 deletions(-)

diff --git a/libavcodec/vaapi_encode.c b/libavcodec/vaapi_encode.c
index ec054ae701..5927849233 100644
--- a/libavcodec/vaapi_encode.c
+++ b/libavcodec/vaapi_encode.c
@@ -951,8 +951,10 @@ static int vaapi_encode_pick_next(AVCodecContext *avctx,
 if (!pic && ctx->end_of_stream) {
 --b_counter;
 pic = ctx->pic_end;
-if (pic->encode_issued)
+if (pic->encode_complete)
 return AVERROR_EOF;
+else if (pic->encode_issued)
+return AVERROR(EAGAIN);
 }
 
 if (!pic) {
@@ -1177,20 +1179,31 @@ int ff_vaapi_encode_receive_packet(AVCodecContext 
*avctx, AVPacket *pkt)
 return AVERROR(EAGAIN);
 }
 
-pic = NULL;
-err = vaapi_encode_pick_next(avctx, &pic);
-if (err < 0)
-return err;
-av_assert0(pic);
+while (av_fifo_size(ctx->encode_fifo) <= MAX_PICTURE_REFERENCES * 
sizeof(VAAPIEncodePicture *)) {
+pic = NULL;
+err = vaapi_encode_pick_next(avctx, &pic);
+if (err < 0)
+break;
+av_assert0(pic);
 
-pic->encode_order = ctx->encode_order++;
+pic->encode_order = ctx->encode_order +
+(av_fifo_size(ctx->encode_fifo) / 
sizeof(VAAPIEncodePicture *));
 
-err = vaapi_encode_issue(avctx, pic);
-if (err < 0) {
-av_log(avctx, AV_LOG_ERROR, "Encode failed: %d.\n", err);
-return err;
+err = vaapi_encode_issue(avctx, pic);
+if (err < 0) {
+av_log(avctx, AV_LOG_ERROR, "Encode failed: %d.\n", err);
+return err;
+}
+
+av_fifo_generic_write(ctx->encode_fifo, &pic, sizeof(pic), NULL);
 }
 
+if (!av_fifo_size(ctx->encode_fifo))
+return err;
+
+av_fifo_generic_read(ctx->encode_fifo, &pic, sizeof(pic), NULL);
+ctx->encode_order = pic->encode_order + 1;
+
 err = vaapi_encode_output(avctx, pic, pkt);
 if (err < 0) {
 av_log(avctx, AV_LOG_ERROR, "Output failed: %d.\n", err);
@@ -2520,6 +2533,11 @@ av_cold int ff_vaapi_encode_init(AVCodecContext *avctx)
 }
 }
 
+ctx->encode_fifo = av_fifo_alloc((MAX_PICTURE_REFERENCES + 1) *
+  sizeof(VAAPIEncodePicture *));
+if (!ctx->encode_fifo)
+return AVERROR(ENOMEM);
+
 return 0;
 
 fail:
@@ -2552,6 +2570,7 @@ av_cold int ff_vaapi_encode_close(AVCodecContext *avctx)
 
 av_freep(&ctx->codec_sequence_params);
 av_freep(&ctx->codec_picture_params);
+av_fifo_freep(&ctx->encode_fifo);
 
 av_buffer_unref(&ctx->recon_frames_ref);
 av_buffer_unref(&ctx->input_frames_ref);
diff --git a/libavcodec/vaapi_encode.h b/libavcodec/vaapi_encode.h
index b41604a883..89fe8de466 100644
--- a/libavcodec/vaapi_encode.h
+++ b/libavcodec/vaapi_encode.h
@@ -29,6 +29,7 @@
 
 #include "libavutil/hwcontext.h"
 #include "libavutil/hwcontext_vaapi.h"
+#include "libavutil/fifo.h"
 
 #include "avcodec.h"
 #include "hwconfig.h"
@@ -345,6 +346,8 @@ typedef struct VAAPIEncodeContext {
 int roi_warned;
 
 AVFrame *frame;
+
+AVFifoBuffer *encode_fifo;
 } VAAPIEncodeContext;
 
 enum {
-- 
2.25.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH 2/3] libavcodec/vaapi_encode: Add new API adaption to vaapi_encode

2021-10-27 Thread Wenbin Chen
Add vaSyncBuffer to VAAPI encoder. Old version API vaSyncSurface wait
surface to complete. When surface is used for multiple operation, it
wait all operation to finish. vaSyncBuffer only wait one channel to
finish.

Add wait param to vaapi_encode_wait() to prepare for the async_depth
option. "wait=1" means wait until operation ready. "wait=0" means
query operation's status. If ready return 0, if still in progress
return EAGAIN.

Signed-off-by: Wenbin Chen 
---
 libavcodec/vaapi_encode.c | 47 +--
 1 file changed, 40 insertions(+), 7 deletions(-)

diff --git a/libavcodec/vaapi_encode.c b/libavcodec/vaapi_encode.c
index 5927849233..db0ae136a1 100644
--- a/libavcodec/vaapi_encode.c
+++ b/libavcodec/vaapi_encode.c
@@ -134,7 +134,8 @@ static int 
vaapi_encode_make_misc_param_buffer(AVCodecContext *avctx,
 }
 
 static int vaapi_encode_wait(AVCodecContext *avctx,
- VAAPIEncodePicture *pic)
+ VAAPIEncodePicture *pic,
+ uint8_t wait)
 {
 VAAPIEncodeContext *ctx = avctx->priv_data;
 VAStatus vas;
@@ -150,11 +151,43 @@ static int vaapi_encode_wait(AVCodecContext *avctx,
"(input surface %#x).\n", pic->display_order,
pic->encode_order, pic->input_surface);
 
-vas = vaSyncSurface(ctx->hwctx->display, pic->input_surface);
-if (vas != VA_STATUS_SUCCESS) {
-av_log(avctx, AV_LOG_ERROR, "Failed to sync to picture completion: "
-   "%d (%s).\n", vas, vaErrorStr(vas));
+#if VA_CHECK_VERSION(1, 9, 0)
+// Try vaSyncBuffer.
+vas = vaSyncBuffer(ctx->hwctx->display,
+   pic->output_buffer,
+   wait ? VA_TIMEOUT_INFINITE : 0);
+if (vas == VA_STATUS_ERROR_TIMEDOUT) {
+return AVERROR(EAGAIN);
+} else if (vas != VA_STATUS_SUCCESS && vas != 
VA_STATUS_ERROR_UNIMPLEMENTED) {
+av_log(avctx, AV_LOG_ERROR, "Failed to sync to output buffer 
completion: "
+"%d (%s).\n", vas, vaErrorStr(vas));
 return AVERROR(EIO);
+} else if (vas == VA_STATUS_ERROR_UNIMPLEMENTED)
+// If vaSyncBuffer is not implemented, try old version API.
+#endif
+{
+if (!wait) {
+VASurfaceStatus surface_status;
+vas = vaQuerySurfaceStatus(ctx->hwctx->display,
+pic->input_surface,
+&surface_status);
+if (vas == VA_STATUS_SUCCESS &&
+surface_status != VASurfaceReady &&
+surface_status != VASurfaceSkipped) {
+return AVERROR(EAGAIN);
+} else if (vas != VA_STATUS_SUCCESS) {
+av_log(avctx, AV_LOG_ERROR, "Failed to query surface status: "
+"%d (%s).\n", vas, vaErrorStr(vas));
+return AVERROR(EIO);
+}
+} else {
+vas = vaSyncSurface(ctx->hwctx->display, pic->input_surface);
+if (vas != VA_STATUS_SUCCESS) {
+av_log(avctx, AV_LOG_ERROR, "Failed to sync to picture 
completion: "
+"%d (%s).\n", vas, vaErrorStr(vas));
+return AVERROR(EIO);
+}
+}
 }
 
 // Input is definitely finished with now.
@@ -633,7 +666,7 @@ static int vaapi_encode_output(AVCodecContext *avctx,
 uint8_t *ptr;
 int err;
 
-err = vaapi_encode_wait(avctx, pic);
+err = vaapi_encode_wait(avctx, pic, 1);
 if (err < 0)
 return err;
 
@@ -695,7 +728,7 @@ fail:
 static int vaapi_encode_discard(AVCodecContext *avctx,
 VAAPIEncodePicture *pic)
 {
-vaapi_encode_wait(avctx, pic);
+vaapi_encode_wait(avctx, pic, 1);
 
 if (pic->output_buffer_ref) {
 av_log(avctx, AV_LOG_DEBUG, "Discard output for pic "
-- 
2.25.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH 3/3] libavcodec/vaapi_encode: Add async_depth to vaapi_encoder to increase performance

2021-10-27 Thread Wenbin Chen
Add async_depth to increase encoder's performance. Reuse encode_fifo as
async buffer. Encoder puts all reordered frame to HW and then check
fifo size. If fifo < async_depth and the top frame is not ready, it will
return AVERROR(EAGAIN) to require more frames.

1080p transcoding (no B frames) with -async_depth=4 can increase 20%
performance on my environment.
The async increases performance but also introduces frame delay.

Signed-off-by: Wenbin Chen 
---
 libavcodec/vaapi_encode.c | 20 +++-
 libavcodec/vaapi_encode.h | 12 ++--
 2 files changed, 25 insertions(+), 7 deletions(-)

diff --git a/libavcodec/vaapi_encode.c b/libavcodec/vaapi_encode.c
index db0ae136a1..616fb7c089 100644
--- a/libavcodec/vaapi_encode.c
+++ b/libavcodec/vaapi_encode.c
@@ -1158,7 +1158,8 @@ static int vaapi_encode_send_frame(AVCodecContext *avctx, 
AVFrame *frame)
 if (ctx->input_order == ctx->decode_delay)
 ctx->dts_pts_diff = pic->pts - ctx->first_pts;
 if (ctx->output_delay > 0)
-ctx->ts_ring[ctx->input_order % (3 * ctx->output_delay)] = 
pic->pts;
+ctx->ts_ring[ctx->input_order %
+(3 * ctx->output_delay + ctx->async_depth)] = pic->pts;
 
 pic->display_order = ctx->input_order;
 ++ctx->input_order;
@@ -1212,7 +1213,8 @@ int ff_vaapi_encode_receive_packet(AVCodecContext *avctx, 
AVPacket *pkt)
 return AVERROR(EAGAIN);
 }
 
-while (av_fifo_size(ctx->encode_fifo) <= MAX_PICTURE_REFERENCES * 
sizeof(VAAPIEncodePicture *)) {
+while (av_fifo_size(ctx->encode_fifo) <
+MAX_ASYNC_DEPTH * sizeof(VAAPIEncodePicture *)) {
 pic = NULL;
 err = vaapi_encode_pick_next(avctx, &pic);
 if (err < 0)
@@ -1234,6 +1236,14 @@ int ff_vaapi_encode_receive_packet(AVCodecContext 
*avctx, AVPacket *pkt)
 if (!av_fifo_size(ctx->encode_fifo))
 return err;
 
+if (av_fifo_size(ctx->encode_fifo) < ctx->async_depth * 
sizeof(VAAPIEncodePicture *) &&
+!ctx->end_of_stream) {
+av_fifo_generic_peek(ctx->encode_fifo, &pic, sizeof(pic), NULL);
+err = vaapi_encode_wait(avctx, pic, 0);
+if (err < 0)
+return err;
+}
+
 av_fifo_generic_read(ctx->encode_fifo, &pic, sizeof(pic), NULL);
 ctx->encode_order = pic->encode_order + 1;
 
@@ -1252,7 +1262,7 @@ int ff_vaapi_encode_receive_packet(AVCodecContext *avctx, 
AVPacket *pkt)
 pkt->dts = ctx->ts_ring[pic->encode_order] - ctx->dts_pts_diff;
 } else {
 pkt->dts = ctx->ts_ring[(pic->encode_order - ctx->decode_delay) %
-(3 * ctx->output_delay)];
+(3 * ctx->output_delay + ctx->async_depth)];
 }
 av_log(avctx, AV_LOG_DEBUG, "Output packet: pts %"PRId64" dts 
%"PRId64".\n",
pkt->pts, pkt->dts);
@@ -2566,8 +2576,8 @@ av_cold int ff_vaapi_encode_init(AVCodecContext *avctx)
 }
 }
 
-ctx->encode_fifo = av_fifo_alloc((MAX_PICTURE_REFERENCES + 1) *
-  sizeof(VAAPIEncodePicture *));
+ctx->encode_fifo = av_fifo_alloc(MAX_ASYNC_DEPTH *
+ sizeof(VAAPIEncodePicture *));
 if (!ctx->encode_fifo)
 return AVERROR(ENOMEM);
 
diff --git a/libavcodec/vaapi_encode.h b/libavcodec/vaapi_encode.h
index 89fe8de466..1bf5d7c337 100644
--- a/libavcodec/vaapi_encode.h
+++ b/libavcodec/vaapi_encode.h
@@ -48,6 +48,7 @@ enum {
 MAX_TILE_ROWS  = 22,
 // A.4.1: table A.6 allows at most 20 tile columns for any level.
 MAX_TILE_COLS  = 20,
+MAX_ASYNC_DEPTH= 64,
 };
 
 extern const AVCodecHWConfigInternal *const ff_vaapi_encode_hw_configs[];
@@ -298,7 +299,8 @@ typedef struct VAAPIEncodeContext {
 // Timestamp handling.
 int64_t first_pts;
 int64_t dts_pts_diff;
-int64_t ts_ring[MAX_REORDER_DELAY * 3];
+int64_t ts_ring[MAX_REORDER_DELAY * 3 +
+MAX_ASYNC_DEPTH];
 
 // Slice structure.
 int slice_block_rows;
@@ -348,6 +350,8 @@ typedef struct VAAPIEncodeContext {
 AVFrame *frame;
 
 AVFifoBuffer *encode_fifo;
+
+int async_depth;
 } VAAPIEncodeContext;
 
 enum {
@@ -458,7 +462,11 @@ int ff_vaapi_encode_close(AVCodecContext *avctx);
 { "b_depth", \
   "Maximum B-frame reference depth", \
   OFFSET(common.desired_b_depth), AV_OPT_TYPE_INT, \
-  { .i64 = 1 }, 1, INT_MAX, FLAGS }
+  { .i64 = 1 }, 1, INT_MAX, FLAGS }, \
+{ "async_depth", "Maximum processing parallelism. " \
+  "Increase this to improve single channel performance", \
+  OFFSET(common.async_depth), AV_OPT_TYPE_INT, \
+  {

[FFmpeg-devel] [PATCH 1/4] libavutil/hwcontext_d3d11va: Add nb_surfaces to AVD3D11VAFramesContext

2021-11-03 Thread Wenbin Chen
Adding nb_surfaces in AVD3D11VAFramesContext in the end of the structure
to support flexible size of this arrays and align to
AVDXVA2FramesContext and AVVAAPIFramesContext.

Signed-off-by Wenbin Chen 
---
 libavutil/hwcontext_d3d11va.c | 3 +--
 libavutil/hwcontext_d3d11va.h | 2 ++
 2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/libavutil/hwcontext_d3d11va.c b/libavutil/hwcontext_d3d11va.c
index 8ab96bad25..086e7b9daa 100644
--- a/libavutil/hwcontext_d3d11va.c
+++ b/libavutil/hwcontext_d3d11va.c
@@ -72,7 +72,6 @@ static av_cold void load_functions(void)
 }
 
 typedef struct D3D11VAFramesContext {
-int nb_surfaces;
 int nb_surfaces_used;
 
 DXGI_FORMAT format;
@@ -287,7 +286,7 @@ static int d3d11va_frames_init(AVHWFramesContext *ctx)
 hwctx->texture_infos = av_calloc(ctx->initial_pool_size, 
sizeof(*hwctx->texture_infos));
 if (!hwctx->texture_infos)
 return AVERROR(ENOMEM);
-s->nb_surfaces = ctx->initial_pool_size;
+hwctx->nb_surfaces = ctx->initial_pool_size;
 
 ctx->internal->pool_internal = 
av_buffer_pool_init2(sizeof(AVD3D11FrameDescriptor),
 ctx, 
d3d11va_pool_alloc, NULL);
diff --git a/libavutil/hwcontext_d3d11va.h b/libavutil/hwcontext_d3d11va.h
index 77d2d72f1b..b0df470190 100644
--- a/libavutil/hwcontext_d3d11va.h
+++ b/libavutil/hwcontext_d3d11va.h
@@ -173,6 +173,8 @@ typedef struct AVD3D11VAFramesContext {
  * This field is ignored/invalid if a user-allocated texture is provided.
 */
 AVD3D11FrameDescriptor *texture_infos;
+
+int nb_surfaces;
 } AVD3D11VAFramesContext;
 
 #endif /* AVUTIL_HWCONTEXT_D3D11VA_H */
-- 
2.25.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH 2/4] libavutil/hwcontext_qsv: fix a bug when malloc handle_pairs_internal

2021-11-03 Thread Wenbin Chen
This commandline cause core dumped:
ffmpeg -hwaccel vaapi -hwaccel_device /dev/dri/renderD128 \
-hwaccel_output_format vaapi -i input.264 \
-vf "hwmap=derive_device=qsv,format=qsv" \
-c:v h264_qsv output.264

reason: We use nb_surfaces to assign surface to handle_pairs_internal
but handle_pairs_internal is alloced with the size of init_pool_size.
This lead to access to illegal address.

Now change it to use nb_surfaces to allocate handle_pairs_internal and the
core dumped error is unseen. Also change D3D11VA to use nb_surfaces
to align to VAAPI and DXVA2.

Signed-off-by: Wenbin Chen 
---
 libavutil/hwcontext_qsv.c | 13 ++---
 1 file changed, 6 insertions(+), 7 deletions(-)

diff --git a/libavutil/hwcontext_qsv.c b/libavutil/hwcontext_qsv.c
index c18747f7eb..5a285fd25b 100644
--- a/libavutil/hwcontext_qsv.c
+++ b/libavutil/hwcontext_qsv.c
@@ -1123,8 +1123,7 @@ static int qsv_frames_derive_to(AVHWFramesContext 
*dst_ctx,
 case AV_HWDEVICE_TYPE_VAAPI:
 {
 AVVAAPIFramesContext *src_hwctx = src_ctx->hwctx;
-s->handle_pairs_internal = av_calloc(src_ctx->initial_pool_size,
- 
sizeof(*s->handle_pairs_internal));
+s->handle_pairs_internal = av_calloc(src_hwctx->nb_surfaces, 
sizeof(*s->handle_pairs_internal));
 if (!s->handle_pairs_internal)
 return AVERROR(ENOMEM);
 s->surfaces_internal = av_calloc(src_hwctx->nb_surfaces,
@@ -1146,15 +1145,15 @@ static int qsv_frames_derive_to(AVHWFramesContext 
*dst_ctx,
 case AV_HWDEVICE_TYPE_D3D11VA:
 {
 AVD3D11VAFramesContext *src_hwctx = src_ctx->hwctx;
-s->handle_pairs_internal = av_calloc(src_ctx->initial_pool_size,
+s->handle_pairs_internal = av_calloc(src_ctx->nb_surfaces,
  
sizeof(*s->handle_pairs_internal));
 if (!s->handle_pairs_internal)
 return AVERROR(ENOMEM);
-s->surfaces_internal = av_calloc(src_ctx->initial_pool_size,
+s->surfaces_internal = av_calloc(src_ctx->nb_surfaces,
  sizeof(*s->surfaces_internal));
 if (!s->surfaces_internal)
 return AVERROR(ENOMEM);
-for (i = 0; i < src_ctx->initial_pool_size; i++) {
+for (i = 0; i < src_ctx->nb_surfaces; i++) {
 qsv_init_surface(dst_ctx, &s->surfaces_internal[i]);
 s->handle_pairs_internal[i].first = 
(mfxMemId)src_hwctx->texture_infos[i].texture;
 if (src_hwctx->BindFlags & D3D11_BIND_RENDER_TARGET) {
@@ -1164,7 +1163,7 @@ static int qsv_frames_derive_to(AVHWFramesContext 
*dst_ctx,
 }
 s->surfaces_internal[i].Data.MemId = 
(mfxMemId)&s->handle_pairs_internal[i];
 }
-dst_hwctx->nb_surfaces = src_ctx->initial_pool_size;
+dst_hwctx->nb_surfaces = src_ctx->nb_surfaces;
 if (src_hwctx->BindFlags & D3D11_BIND_RENDER_TARGET) {
 dst_hwctx->frame_type |= 
MFX_MEMTYPE_VIDEO_MEMORY_PROCESSOR_TARGET;
 } else {
@@ -1177,7 +1176,7 @@ static int qsv_frames_derive_to(AVHWFramesContext 
*dst_ctx,
 case AV_HWDEVICE_TYPE_DXVA2:
 {
 AVDXVA2FramesContext *src_hwctx = src_ctx->hwctx;
-s->handle_pairs_internal = av_calloc(src_ctx->initial_pool_size,
+s->handle_pairs_internal = av_calloc(src_ctx->nb_surfaces,
  
sizeof(*s->handle_pairs_internal));
 if (!s->handle_pairs_internal)
 return AVERROR(ENOMEM);
-- 
2.25.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH 3/4] libavutil/hwcontext_qsv: fix a bug for mapping vaapi frame to qsv

2021-11-03 Thread Wenbin Chen
From: nyanmisaka 

The data stored in data[3] in VAAPI AVFrame is VASurfaceID while
the data stored in pair->first is the pointer of VASurfaceID, so
we need to do cast to make following commandline works:

ffmpeg -hwaccel vaapi -hwaccel_device /dev/dri/renderD128 \
-hwaccel_output_format vaapi -i input.264 \
-vf "hwmap=derive_device=qsv,format=qsv" -c:v h264_qsv output.264

Signed-off-by: nyanmisaka 
Signed-off-by: Wenbin Chen 
---
 libavutil/hwcontext_qsv.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libavutil/hwcontext_qsv.c b/libavutil/hwcontext_qsv.c
index 5a285fd25b..8075c27862 100644
--- a/libavutil/hwcontext_qsv.c
+++ b/libavutil/hwcontext_qsv.c
@@ -1219,7 +1219,7 @@ static int qsv_map_to(AVHWFramesContext *dst_ctx,
 case AV_PIX_FMT_VAAPI:
 {
 mfxHDLPair *pair = (mfxHDLPair*)hwctx->surfaces[i].Data.MemId;
-if (pair->first == src->data[3]) {
+if (*(VASurfaceID*)pair->first == (VASurfaceID)src->data[3]) {
 index = i;
 break;
 }
-- 
2.25.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH 4/4] libavutil/hwcontext_opencl: fix a bug for mapping qsv frame to opencl

2021-11-03 Thread Wenbin Chen
From: nyanmisaka 

mfxHDLPair was added to qsv, so modify qsv->opencl map function as well.
Now the following commandline works:

ffmpeg -v verbose -init_hw_device vaapi=va:/dev/dri/renderD128 \
-init_hw_device qsv=qs@va -init_hw_device opencl=ocl@va -filter_hw_device ocl \
-hwaccel qsv -hwaccel_output_format qsv -hwaccel_device qs -c:v h264_qsv \
-i input.264 -vf "hwmap=derive_device=opencl,format=opencl,avgblur_opencl, \
hwmap=derive_device=qsv:reverse=1:extra_hw_frames=32,format=qsv" \
-c:v h264_qsv output.264

Signed-off-by: nyanmisaka 
Signed-off-by: Wenbin Chen 
---
 libavutil/hwcontext_opencl.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/libavutil/hwcontext_opencl.c b/libavutil/hwcontext_opencl.c
index 26a3a24593..4b6e74ff6f 100644
--- a/libavutil/hwcontext_opencl.c
+++ b/libavutil/hwcontext_opencl.c
@@ -2249,7 +2249,8 @@ static int opencl_map_from_qsv(AVHWFramesContext *dst_fc, 
AVFrame *dst,
 #if CONFIG_LIBMFX
 if (src->format == AV_PIX_FMT_QSV) {
 mfxFrameSurface1 *mfx_surface = (mfxFrameSurface1*)src->data[3];
-va_surface = *(VASurfaceID*)mfx_surface->Data.MemId;
+mfxHDLPair *pair = (mfxHDLPair*)mfx_surface->Data.MemId;
+va_surface = *(VASurfaceID*)pair->first;
 } else
 #endif
 if (src->format == AV_PIX_FMT_VAAPI) {
-- 
2.25.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH 1/7] hwcontext_vaapi: Use PRIME_2 memory type for modifiers.

2021-11-09 Thread Wenbin Chen
From: Bas Nieuwenhuizen 

This way we can pass explicit modifiers in. Sometimes the
modifier matters for the number of memory planes that
libva accepts, in particular when dealing with
driver-compressed textures. Furthermore the driver might
not actually be able to determine the implicit modifier
if all the buffer-passing has used explicit modifier.
All these issues should be resolved by passing in the
modifier, and for that we switch to using the PRIME_2
memory type.

Tested with experimental radeonsi patches for modifiers
and kmsgrab. Also tested with radeonsi without the
patches to double-check it works without PRIME_2 support.

v2:
  Cache PRIME_2 support to avoid doing two calls every time on
  libva drivers that do not support it.

v3:
  Remove prime2_vas usage.

Signed-off-by: Bas Nieuwenhuizen 
---
 libavutil/hwcontext_vaapi.c | 158 ++--
 1 file changed, 114 insertions(+), 44 deletions(-)

diff --git a/libavutil/hwcontext_vaapi.c b/libavutil/hwcontext_vaapi.c
index 83e542876d..75acc851d6 100644
--- a/libavutil/hwcontext_vaapi.c
+++ b/libavutil/hwcontext_vaapi.c
@@ -79,6 +79,9 @@ typedef struct VAAPIFramesContext {
 unsigned int rt_format;
 // Whether vaDeriveImage works.
 int derive_works;
+// Caches whether VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_2 is unsupported for
+// surface imports.
+int prime_2_import_unsupported;
 } VAAPIFramesContext;
 
 typedef struct VAAPIMapping {
@@ -1022,32 +1025,17 @@ static void vaapi_unmap_from_drm(AVHWFramesContext 
*dst_fc,
 static int vaapi_map_from_drm(AVHWFramesContext *src_fc, AVFrame *dst,
   const AVFrame *src, int flags)
 {
+VAAPIFramesContext *src_vafc = src_fc->internal->priv;
 AVHWFramesContext  *dst_fc =
 (AVHWFramesContext*)dst->hw_frames_ctx->data;
 AVVAAPIDeviceContext  *dst_dev = dst_fc->device_ctx->hwctx;
 const AVDRMFrameDescriptor *desc;
 const VAAPIFormatDescriptor *format_desc;
 VASurfaceID surface_id;
-VAStatus vas;
+VAStatus vas = VA_STATUS_SUCCESS;
+int use_prime2;
 uint32_t va_fourcc;
-int err, i, j, k;
-
-unsigned long buffer_handle;
-VASurfaceAttribExternalBuffers buffer_desc;
-VASurfaceAttrib attrs[2] = {
-{
-.type  = VASurfaceAttribMemoryType,
-.flags = VA_SURFACE_ATTRIB_SETTABLE,
-.value.type= VAGenericValueTypeInteger,
-.value.value.i = VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME,
-},
-{
-.type  = VASurfaceAttribExternalBufferDescriptor,
-.flags = VA_SURFACE_ATTRIB_SETTABLE,
-.value.type= VAGenericValueTypePointer,
-.value.value.p = &buffer_desc,
-}
-};
+int err, i, j;
 
 desc = (AVDRMFrameDescriptor*)src->data[0];
 
@@ -1083,35 +1071,117 @@ static int vaapi_map_from_drm(AVHWFramesContext 
*src_fc, AVFrame *dst,
 format_desc = vaapi_format_from_fourcc(va_fourcc);
 av_assert0(format_desc);
 
-buffer_handle = desc->objects[0].fd;
-buffer_desc.pixel_format = va_fourcc;
-buffer_desc.width= src_fc->width;
-buffer_desc.height   = src_fc->height;
-buffer_desc.data_size= desc->objects[0].size;
-buffer_desc.buffers  = &buffer_handle;
-buffer_desc.num_buffers  = 1;
-buffer_desc.flags= 0;
-
-k = 0;
-for (i = 0; i < desc->nb_layers; i++) {
-for (j = 0; j < desc->layers[i].nb_planes; j++) {
-buffer_desc.pitches[k] = desc->layers[i].planes[j].pitch;
-buffer_desc.offsets[k] = desc->layers[i].planes[j].offset;
-++k;
+use_prime2 = !src_vafc->prime_2_import_unsupported &&
+ desc->objects[0].format_modifier != DRM_FORMAT_MOD_INVALID;
+if (use_prime2) {
+VADRMPRIMESurfaceDescriptor prime_desc;
+VASurfaceAttrib prime_attrs[2] = {
+{
+.type  = VASurfaceAttribMemoryType,
+.flags = VA_SURFACE_ATTRIB_SETTABLE,
+.value.type= VAGenericValueTypeInteger,
+.value.value.i = VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_2,
+},
+{
+.type  = VASurfaceAttribExternalBufferDescriptor,
+.flags = VA_SURFACE_ATTRIB_SETTABLE,
+.value.type= VAGenericValueTypePointer,
+.value.value.p = &prime_desc,
+}
+};
+prime_desc.fourcc = va_fourcc;
+prime_desc.width = src_fc->width;
+prime_desc.height = src_fc->height;
+prime_desc.num_objects = desc->nb_objects;
+for (i = 0; i < desc->nb_objects; ++i) {
+prime_desc.objects[i].fd = desc->objects[i].fd;
+prime_desc.objects[i].size = desc->objects[i].size;
+prime_desc.objects[i].drm_format_modifier =
+desc->objects[i].format_modifier;
 }
-}
-buffer_desc.num_planes = k;
 
-if (format_desc->chroma_planes

[FFmpeg-devel] [PATCH 3/7] libavutil/hwcontext_vulkan: Add one_memory flag to make vulkan compatible with vaapi device.

2021-11-09 Thread Wenbin Chen
Vaapi can import external surface, but all the planes of the external
frames should be in the same drm object. A new flag is introduced and
vulkan can choose to allocate planes in one memory according this flag.
This flag will be enabled when the vulkan device is derived from vaapi
device, so that this change will not affect current vulkan behaviour.

Signed-off-by: Wenbin Chen 
---
 libavutil/hwcontext_vulkan.c | 12 +++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/libavutil/hwcontext_vulkan.c b/libavutil/hwcontext_vulkan.c
index 6041580117..ccf3e58f49 100644
--- a/libavutil/hwcontext_vulkan.c
+++ b/libavutil/hwcontext_vulkan.c
@@ -100,6 +100,9 @@ typedef struct VulkanDevicePriv {
 /* Settings */
 int use_linear_images;
 
+/* map all planes to one memory */
+int use_one_memory;
+
 /* Nvidia */
 int dev_is_nvidia;
 } VulkanDevicePriv;
@@ -1245,6 +1248,11 @@ static int 
vulkan_device_create_internal(AVHWDeviceContext *ctx,
 if (opt_d)
 p->use_linear_images = strtol(opt_d->value, NULL, 10);
 
+opt_d = av_dict_get(opts, "one_memory", NULL, 0);
+if (opt_d)
+p->use_one_memory = strtol(opt_d->value, NULL, 10);
+
+
 hwctx->enabled_dev_extensions = dev_info.ppEnabledExtensionNames;
 hwctx->nb_enabled_dev_extensions = dev_info.enabledExtensionCount;
 
@@ -1365,8 +1373,10 @@ static int vulkan_device_derive(AVHWDeviceContext *ctx,
 return AVERROR_EXTERNAL;
 }
 
-if (strstr(vendor, "Intel"))
+if (strstr(vendor, "Intel")) {
+av_dict_set_int(&opts, "one_memory", 1, 0);
 dev_select.vendor_id = 0x8086;
+}
 if (strstr(vendor, "AMD"))
 dev_select.vendor_id = 0x1002;
 
-- 
2.25.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH 2/7] libavutil/hwcontext_vaapi: Add a new nv12 format map to support vulkan frame

2021-11-09 Thread Wenbin Chen
Vulkan will map nv12 to R8 and GR88, so add this map to vaapi to support
vulkan frame.

Signed-off-by: Wenbin Chen 
---
 libavutil/hwcontext_vaapi.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/libavutil/hwcontext_vaapi.c b/libavutil/hwcontext_vaapi.c
index 75acc851d6..994b744e4d 100644
--- a/libavutil/hwcontext_vaapi.c
+++ b/libavutil/hwcontext_vaapi.c
@@ -992,6 +992,7 @@ static const struct {
 } vaapi_drm_format_map[] = {
 #ifdef DRM_FORMAT_R8
 DRM_MAP(NV12, 2, DRM_FORMAT_R8,  DRM_FORMAT_RG88),
+DRM_MAP(NV12, 2, DRM_FORMAT_R8,  DRM_FORMAT_GR88),
 #endif
 DRM_MAP(NV12, 1, DRM_FORMAT_NV12),
 #if defined(VA_FOURCC_P010) && defined(DRM_FORMAT_R16)
-- 
2.25.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH 6/7] libavutil/hwcontext_vulkan: fix a sem_wait bug when export drm

2021-11-09 Thread Wenbin Chen
sem_sig_val is wrongly assigned to pWaitSemaphoreValues when export drm. Now fix
it.

Signed-off-by: Wenbin Chen 
---
 libavutil/hwcontext_vulkan.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/libavutil/hwcontext_vulkan.c b/libavutil/hwcontext_vulkan.c
index b857d1a9ed..29ade94b7f 100644
--- a/libavutil/hwcontext_vulkan.c
+++ b/libavutil/hwcontext_vulkan.c
@@ -1718,7 +1718,7 @@ static int prepare_frame(AVHWFramesContext *hwfc, 
VulkanExecCtx *ectx,
 const int planes = av_pix_fmt_count_planes(hwfc->sw_format);
 VulkanDevicePriv *p = hwfc->device_ctx->internal->priv;
 FFVulkanFunctions *vk = &p->vkfn;
-uint64_t sem_sig_val[AV_NUM_DATA_POINTERS];
+uint64_t sem_sig_val[AV_NUM_DATA_POINTERS], 
sem_wait_val[AV_NUM_DATA_POINTERS];
 
 VkImageMemoryBarrier img_bar[AV_NUM_DATA_POINTERS] = { 0 };
 
@@ -1738,6 +1738,7 @@ static int prepare_frame(AVHWFramesContext *hwfc, 
VulkanExecCtx *ectx,
 VkPipelineStageFlagBits wait_st[AV_NUM_DATA_POINTERS];
 for (int i = 0; i < planes; i++) {
 wait_st[i] = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
+sem_wait_val[i] = frame->sem_value[i];
 sem_sig_val[i] = frame->sem_value[i] + 1;
 }
 
@@ -1756,7 +1757,7 @@ static int prepare_frame(AVHWFramesContext *hwfc, 
VulkanExecCtx *ectx,
 new_layout = VK_IMAGE_LAYOUT_GENERAL;
 new_access = VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_MEMORY_WRITE_BIT;
 dst_qf = VK_QUEUE_FAMILY_EXTERNAL_KHR;
-s_timeline_sem_info.pWaitSemaphoreValues = sem_sig_val;
+s_timeline_sem_info.pWaitSemaphoreValues = sem_wait_val;
 s_timeline_sem_info.waitSemaphoreValueCount = planes;
 s_info.pWaitSemaphores = frame->sem;
 s_info.pWaitDstStageMask = wait_st;
-- 
2.25.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH 4/7] libavutil/hwcontext_vulkan: Allocate vkFrame in one memory

2021-11-09 Thread Wenbin Chen
The vaapi can import external frame, but the planes of the external
frames should be in the same drm object. I add a new function to
allocate vkFrame in one memory and vulkan device will choose a way
to allocate memory according to one_memory flag.
A new variable is added to AVVKFrame to store the offset of each plane.

Signed-off-by: Wenbin Chen 
---
 libavutil/hwcontext_vulkan.c | 46 +++-
 libavutil/hwcontext_vulkan.h |  1 +
 2 files changed, 46 insertions(+), 1 deletion(-)

diff --git a/libavutil/hwcontext_vulkan.c b/libavutil/hwcontext_vulkan.c
index ccf3e58f49..f7878ed9c3 100644
--- a/libavutil/hwcontext_vulkan.c
+++ b/libavutil/hwcontext_vulkan.c
@@ -1600,6 +1600,9 @@ static int alloc_bind_mem(AVHWFramesContext *hwfc, 
AVVkFrame *f,
 FFVulkanFunctions *vk = &p->vkfn;
 const int planes = av_pix_fmt_count_planes(hwfc->sw_format);
 VkBindImageMemoryInfo bind_info[AV_NUM_DATA_POINTERS] = { { 0 } };
+VkMemoryRequirements memory_requirements = { 0 };
+int mem_size = 0;
+int mem_size_list[AV_NUM_DATA_POINTERS] = { 0 };
 
 AVVulkanDeviceContext *hwctx = ctx->hwctx;
 
@@ -1627,6 +1630,23 @@ static int alloc_bind_mem(AVHWFramesContext *hwfc, 
AVVkFrame *f,
 req.memoryRequirements.size = FFALIGN(req.memoryRequirements.size,
   
p->props.properties.limits.minMemoryMapAlignment);
 
+if (p->use_one_memory) {
+if (ded_req.prefersDedicatedAllocation | 
ded_req.requiresDedicatedAllocation) {
+av_log(hwfc, AV_LOG_ERROR, "Cannot use dedicated allocation 
for intel vaapi\n");
+return AVERROR(EINVAL);
+}
+if (memory_requirements.size == 0) {
+memory_requirements = req.memoryRequirements;
+} else if (memory_requirements.memoryTypeBits != 
req.memoryRequirements.memoryTypeBits) {
+av_log(hwfc, AV_LOG_ERROR, "the param for each planes are not 
the same\n");
+return AVERROR(EINVAL);
+}
+
+mem_size_list[i] = req.memoryRequirements.size;
+mem_size += mem_size_list[i];
+continue;
+}
+
 /* In case the implementation prefers/requires dedicated allocation */
 use_ded_mem = ded_req.prefersDedicatedAllocation |
   ded_req.requiresDedicatedAllocation;
@@ -1648,6 +1668,29 @@ static int alloc_bind_mem(AVHWFramesContext *hwfc, 
AVVkFrame *f,
 bind_info[i].memory = f->mem[i];
 }
 
+if (p->use_one_memory) {
+memory_requirements.size = mem_size;
+
+/* Allocate memory */
+if ((err = alloc_mem(ctx, &memory_requirements,
+f->tiling == VK_IMAGE_TILING_LINEAR ?
+VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT :
+VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
+(void *)(((uint8_t *)alloc_pnext)),
+&f->flags, &f->mem[0])))
+return err;
+
+f->size[0] = memory_requirements.size;
+
+for (int i = 0; i < planes; i++) {
+bind_info[i].sType  = VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO;
+bind_info[i].image  = f->img[i];
+bind_info[i].memory = f->mem[0];
+bind_info[i].memoryOffset = i == 0 ? 0 : mem_size_list[i-1];
+f->offset[i] = bind_info[i].memoryOffset;
+}
+}
+
 /* Bind the allocated memory to the images */
 ret = vk->BindImageMemory2(hwctx->act_dev, planes, bind_info);
 if (ret != VK_SUCCESS) {
@@ -2924,7 +2967,8 @@ static int vulkan_map_to_drm(AVHWFramesContext *hwfc, 
AVFrame *dst,
 continue;
 
 vk->GetImageSubresourceLayout(hwctx->act_dev, f->img[i], &sub, 
&layout);
-drm_desc->layers[i].planes[0].offset   = layout.offset;
+drm_desc->layers[i].planes[0].offset   = p->use_one_memory ?
+f->offset[i] : 
layout.offset;
 drm_desc->layers[i].planes[0].pitch= layout.rowPitch;
 }
 
diff --git a/libavutil/hwcontext_vulkan.h b/libavutil/hwcontext_vulkan.h
index 9264f70dbf..efb602ef27 100644
--- a/libavutil/hwcontext_vulkan.h
+++ b/libavutil/hwcontext_vulkan.h
@@ -189,6 +189,7 @@ typedef struct AVVkFrame {
  */
 VkDeviceMemory mem[AV_NUM_DATA_POINTERS];
 size_t size[AV_NUM_DATA_POINTERS];
+size_t offset[AV_NUM_DATA_POINTERS];
 
 /**
  * OR'd flags for all memory allocated
-- 
2.25.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH 5/7] libavutil/hwcontext_vulkan: Add hwupload and hwdownload support when using one_memory flag.

2021-11-09 Thread Wenbin Chen
Add hwupload and hwdownload support to vulkan when frames are allocated
in one memory

Signed-off-by: Wenbin Chen 
---
 libavutil/hwcontext_vulkan.c | 10 --
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/libavutil/hwcontext_vulkan.c b/libavutil/hwcontext_vulkan.c
index f7878ed9c3..b857d1a9ed 100644
--- a/libavutil/hwcontext_vulkan.c
+++ b/libavutil/hwcontext_vulkan.c
@@ -2138,7 +2138,7 @@ static int vulkan_map_frame_to_mem(AVHWFramesContext 
*hwfc, AVFrame *dst,
const AVFrame *src, int flags)
 {
 VkResult ret;
-int err, mapped_mem_count = 0;
+int err, mapped_mem_count = 0, loop = 0;
 AVVkFrame *f = (AVVkFrame *)src->data[0];
 AVVulkanDeviceContext *hwctx = hwfc->device_ctx->hwctx;
 const int planes = av_pix_fmt_count_planes(hwfc->sw_format);
@@ -2167,7 +2167,8 @@ static int vulkan_map_frame_to_mem(AVHWFramesContext 
*hwfc, AVFrame *dst,
 dst->width  = src->width;
 dst->height = src->height;
 
-for (int i = 0; i < planes; i++) {
+loop = p->use_one_memory ? 1 : planes;
+for (int i = 0; i < loop; i++) {
 ret = vk->MapMemory(hwctx->act_dev, f->mem[i], 0,
 VK_WHOLE_SIZE, 0, (void **)&dst->data[i]);
 if (ret != VK_SUCCESS) {
@@ -2178,6 +2179,11 @@ static int vulkan_map_frame_to_mem(AVHWFramesContext 
*hwfc, AVFrame *dst,
 }
 mapped_mem_count++;
 }
+if (p->use_one_memory) {
+for (int i = 0; i < planes; i++) {
+dst->data[i] = dst->data[0] + f->offset[i];
+}
+}
 
 /* Check if the memory contents matter */
 if (((flags & AV_HWFRAME_MAP_READ) || !(flags & AV_HWFRAME_MAP_OVERWRITE)) 
&&
-- 
2.25.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH 7/7] libavutil/hwcontext_vulkan: specify the modifier to create VKImage

2021-11-09 Thread Wenbin Chen
When vulkan image exports to drm, the tilling need to be
VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT. Now add code to create vulkan
image using this format.

Now the following command line works:

ffmpeg -hwaccel vaapi -hwaccel_device /dev/dri/renderD128 
-hwaccel_output_format \
vaapi -i input_1080p.264 -vf "hwmap=derive_device=vulkan,format=vulkan, \
scale_vulkan=1920:1080,hwmap=derive_device=vaapi,format=vaapi" -c:v h264_vaapi 
output.264

Signed-off-by: Wenbin Chen 
---
 libavutil/hwcontext_vulkan.c | 76 +---
 libavutil/hwcontext_vulkan.h |  5 +++
 2 files changed, 75 insertions(+), 6 deletions(-)

diff --git a/libavutil/hwcontext_vulkan.c b/libavutil/hwcontext_vulkan.c
index 29ade94b7f..e252c2177e 100644
--- a/libavutil/hwcontext_vulkan.c
+++ b/libavutil/hwcontext_vulkan.c
@@ -1919,6 +1919,7 @@ static void try_export_flags(AVHWFramesContext *hwfc,
 AVVulkanDeviceContext *dev_hwctx = hwfc->device_ctx->hwctx;
 VulkanDevicePriv *p = hwfc->device_ctx->internal->priv;
 FFVulkanFunctions *vk = &p->vkfn;
+const int has_modifiers = hwctx->tiling == 
VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT;
 VkExternalImageFormatProperties eprops = {
 .sType = VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES_KHR,
 };
@@ -1926,9 +1927,18 @@ static void try_export_flags(AVHWFramesContext *hwfc,
 .sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2,
 .pNext = &eprops,
 };
+VkPhysicalDeviceImageDrmFormatModifierInfoEXT phy_dev_mod_info = {
+.sType = 
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_DRM_FORMAT_MODIFIER_INFO_EXT,
+.pNext = NULL,
+.pQueueFamilyIndices   = p->qfs,
+.queueFamilyIndexCount = p->num_qfs,
+.sharingMode   = p->num_qfs > 1 ? VK_SHARING_MODE_CONCURRENT :
+  VK_SHARING_MODE_EXCLUSIVE,
+};
 VkPhysicalDeviceExternalImageFormatInfo enext = {
 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO,
 .handleType = exp,
+.pNext = has_modifiers ? &phy_dev_mod_info : NULL,
 };
 VkPhysicalDeviceImageFormatInfo2 pinfo = {
 .sType  = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2,
@@ -1940,11 +1950,15 @@ static void try_export_flags(AVHWFramesContext *hwfc,
 .flags  = VK_IMAGE_CREATE_ALIAS_BIT,
 };
 
-ret = vk->GetPhysicalDeviceImageFormatProperties2(dev_hwctx->phys_dev,
-  &pinfo, &props);
-if (ret == VK_SUCCESS) {
-*iexp |= exp;
-*comp_handle_types |= 
eprops.externalMemoryProperties.compatibleHandleTypes;
+for (int i = 0; i < (has_modifiers ? hwctx->modifier_count : 1); i++) {
+if (has_modifiers && hwctx->modifier_count)
+phy_dev_mod_info.drmFormatModifier = hwctx->modifiers[i];
+ret = vk->GetPhysicalDeviceImageFormatProperties2(dev_hwctx->phys_dev,
+&pinfo, &props);
+if (ret == VK_SUCCESS) {
+*iexp |= exp;
+*comp_handle_types |= 
eprops.externalMemoryProperties.compatibleHandleTypes;
+}
 }
 }
 
@@ -2007,6 +2021,7 @@ fail:
 static void vulkan_frames_uninit(AVHWFramesContext *hwfc)
 {
 VulkanFramesPriv *fp = hwfc->internal->priv;
+AVVulkanFramesContext *hwctx = hwfc->hwctx;
 
 free_exec_ctx(hwfc, &fp->conv_ctx);
 free_exec_ctx(hwfc, &fp->upload_ctx);
@@ -2021,11 +2036,60 @@ static int vulkan_frames_init(AVHWFramesContext *hwfc)
 VulkanFramesPriv *fp = hwfc->internal->priv;
 AVVulkanDeviceContext *dev_hwctx = hwfc->device_ctx->hwctx;
 VulkanDevicePriv *p = hwfc->device_ctx->internal->priv;
+const int has_modifiers = !!(p->extensions & FF_VK_EXT_DRM_MODIFIER_FLAGS);
 
 /* Default pool flags */
-hwctx->tiling = hwctx->tiling ? hwctx->tiling : p->use_linear_images ?
+hwctx->tiling = hwctx->tiling ? hwctx->tiling : has_modifiers ?
+VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT : 
p->use_linear_images ?
 VK_IMAGE_TILING_LINEAR : VK_IMAGE_TILING_OPTIMAL;
 
+/* get the supported modifier */
+if (has_modifiers) {
+const VkFormat *fmt = av_vkfmt_from_pixfmt(hwfc->sw_format);
+FFVulkanFunctions *vk = &p->vkfn;
+VkDrmFormatModifierPropertiesEXT mod_props[MAX_VULKAN_MODIFIERS];
+
+VkDrmFormatModifierPropertiesListEXT mod_props_list = {
+.sType = VK_STRUCTURE_TYPE_DRM_FORMAT_MODIFIER_PROPERTIES_LIST_EXT,
+.pNext = NULL,
+.drmFormatModifierCount = 0,
+.pDrmFormatModifierProperties = NULL,
+};
+VkFormatProperties2 prop = {
+.sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2,
+.pNext = &mod

[FFmpeg-devel] [PATCH 1/3] libavcodec/vaapi_decode: fix the problem that init_pool_size < nb_surface

2021-11-16 Thread Wenbin Chen
For vaapi if the init_pool_size is not zero, the pool size is fixed.
This means max surfaces is init_pool_size, but when mapping vaapi
frame to qsv frame, the init_pool_size < nb_surface. The cause is that
vaapi_decode_make_config() config the init_pool_size and it is called
twice. The first time is to init frame_context and the second time is to
init codec. On the second time the init_pool_size is changed to original
value so the init_pool_size is lower than the reall size because
pool_size used to initialize frame_context need to plus thread_count and
3 (guarantee 4 base work surfaces). Now add code to make sure
init_pool_size is only set once. Now the following commandline works:

ffmpeg -hwaccel vaapi -hwaccel_device /dev/dri/renderD128 \
-hwaccel_output_format vaapi -i input.264 \
-vf "hwmap=derive_device=qsv,format=qsv" \
-c:v h264_qsv output.264

Signed-off-by: Wenbin Chen 
---
 libavcodec/vaapi_decode.c | 34 ++
 1 file changed, 18 insertions(+), 16 deletions(-)

diff --git a/libavcodec/vaapi_decode.c b/libavcodec/vaapi_decode.c
index 665af370ed..aab8162989 100644
--- a/libavcodec/vaapi_decode.c
+++ b/libavcodec/vaapi_decode.c
@@ -572,22 +572,24 @@ static int vaapi_decode_make_config(AVCodecContext *avctx,
 if (err < 0)
 goto fail;
 
-frames->initial_pool_size = 1;
-// Add per-codec number of surfaces used for storing reference frames.
-switch (avctx->codec_id) {
-case AV_CODEC_ID_H264:
-case AV_CODEC_ID_HEVC:
-case AV_CODEC_ID_AV1:
-frames->initial_pool_size += 16;
-break;
-case AV_CODEC_ID_VP9:
-frames->initial_pool_size += 8;
-break;
-case AV_CODEC_ID_VP8:
-frames->initial_pool_size += 3;
-break;
-default:
-frames->initial_pool_size += 2;
+if (!frames->initial_pool_size) {
+frames->initial_pool_size = 1;
+// Add per-codec number of surfaces used for storing reference 
frames.
+switch (avctx->codec_id) {
+case AV_CODEC_ID_H264:
+case AV_CODEC_ID_HEVC:
+case AV_CODEC_ID_AV1:
+frames->initial_pool_size += 16;
+break;
+case AV_CODEC_ID_VP9:
+frames->initial_pool_size += 8;
+break;
+case AV_CODEC_ID_VP8:
+frames->initial_pool_size += 3;
+break;
+default:
+frames->initial_pool_size += 2;
+}
 }
 }
 
-- 
2.25.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH 2/3] libavutil/hwcontext_qsv: fix a bug for mapping vaapi frame to qsv

2021-11-16 Thread Wenbin Chen
From: nyanmisaka 

The data stored in data[3] in VAAPI AVFrame is VASurfaceID while
the data stored in pair->first is the pointer of VASurfaceID, so
we need to do cast to make following commandline works:

ffmpeg -hwaccel vaapi -hwaccel_device /dev/dri/renderD128 \
-hwaccel_output_format vaapi -i input.264 \
-vf "hwmap=derive_device=qsv,format=qsv" -c:v h264_qsv output.264

Signed-off-by: nyanmisaka 
Signed-off-by: Wenbin Chen 
---
 libavutil/hwcontext_qsv.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libavutil/hwcontext_qsv.c b/libavutil/hwcontext_qsv.c
index c18747f7eb..d83754193a 100644
--- a/libavutil/hwcontext_qsv.c
+++ b/libavutil/hwcontext_qsv.c
@@ -1220,7 +1220,7 @@ static int qsv_map_to(AVHWFramesContext *dst_ctx,
 case AV_PIX_FMT_VAAPI:
 {
 mfxHDLPair *pair = (mfxHDLPair*)hwctx->surfaces[i].Data.MemId;
-if (pair->first == src->data[3]) {
+if (*(VASurfaceID*)pair->first == (VASurfaceID)src->data[3]) {
 index = i;
 break;
 }
-- 
2.25.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH 3/3] libavutil/hwcontext_opencl: fix a bug for mapping qsv frame to opencl

2021-11-16 Thread Wenbin Chen
From: nyanmisaka 

mfxHDLPair was added to qsv, so modify qsv->opencl map function as well.
Now the following commandline works:

ffmpeg -v verbose -init_hw_device vaapi=va:/dev/dri/renderD128 \
-init_hw_device qsv=qs@va -init_hw_device opencl=ocl@va -filter_hw_device ocl \
-hwaccel qsv -hwaccel_output_format qsv -hwaccel_device qs -c:v h264_qsv \
-i input.264 -vf "hwmap=derive_device=opencl,format=opencl,avgblur_opencl, \
hwmap=derive_device=qsv:reverse=1:extra_hw_frames=32,format=qsv" \
-c:v h264_qsv output.264

Signed-off-by: nyanmisaka 
Signed-off-by: Wenbin Chen 
---
 libavutil/hwcontext_opencl.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/libavutil/hwcontext_opencl.c b/libavutil/hwcontext_opencl.c
index 26a3a24593..4b6e74ff6f 100644
--- a/libavutil/hwcontext_opencl.c
+++ b/libavutil/hwcontext_opencl.c
@@ -2249,7 +2249,8 @@ static int opencl_map_from_qsv(AVHWFramesContext *dst_fc, 
AVFrame *dst,
 #if CONFIG_LIBMFX
 if (src->format == AV_PIX_FMT_QSV) {
 mfxFrameSurface1 *mfx_surface = (mfxFrameSurface1*)src->data[3];
-va_surface = *(VASurfaceID*)mfx_surface->Data.MemId;
+mfxHDLPair *pair = (mfxHDLPair*)mfx_surface->Data.MemId;
+va_surface = *(VASurfaceID*)pair->first;
 } else
 #endif
 if (src->format == AV_PIX_FMT_VAAPI) {
-- 
2.25.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH V2 2/5] libavutil/hwcontext_vaapi: Add a new nv12 format map to support vulkan frame

2021-11-23 Thread Wenbin Chen
Vulkan will map nv12 to R8 and GR88, so add this map to vaapi to support
vulkan frame.

Signed-off-by: Wenbin Chen 
---
 libavutil/hwcontext_vaapi.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/libavutil/hwcontext_vaapi.c b/libavutil/hwcontext_vaapi.c
index 75acc851d6..994b744e4d 100644
--- a/libavutil/hwcontext_vaapi.c
+++ b/libavutil/hwcontext_vaapi.c
@@ -992,6 +992,7 @@ static const struct {
 } vaapi_drm_format_map[] = {
 #ifdef DRM_FORMAT_R8
 DRM_MAP(NV12, 2, DRM_FORMAT_R8,  DRM_FORMAT_RG88),
+DRM_MAP(NV12, 2, DRM_FORMAT_R8,  DRM_FORMAT_GR88),
 #endif
 DRM_MAP(NV12, 1, DRM_FORMAT_NV12),
 #if defined(VA_FOURCC_P010) && defined(DRM_FORMAT_R16)
-- 
2.25.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH V2 3/5] libavutil/hwcontext_vulkan: Allocate vkFrame in one memory

2021-11-23 Thread Wenbin Chen
The vaapi can import external frame, but the planes of the external
frames should be in the same drm object. A new option "contiguous_planes"
is added to device. This flag tells device to allocate places in one
memory. When device is derived from vaapi this flag will be enabled.
A new flag frame_flag is also added to AVVulkanFramesContext. User
can use this flag to force enable or disable this behaviour.
A new variable "offset "is added to AVVKFrame. It describe describe the
offset from the memory currently bound to the VkImage.

Signed-off-by: Wenbin Chen 
---
 libavutil/hwcontext_vulkan.c | 62 ++--
 libavutil/hwcontext_vulkan.h | 22 +
 2 files changed, 82 insertions(+), 2 deletions(-)

diff --git a/libavutil/hwcontext_vulkan.c b/libavutil/hwcontext_vulkan.c
index f1e750cd3e..4100e8b0a2 100644
--- a/libavutil/hwcontext_vulkan.c
+++ b/libavutil/hwcontext_vulkan.c
@@ -103,6 +103,9 @@ typedef struct VulkanDevicePriv {
 /* Settings */
 int use_linear_images;
 
+/* allocate planes in a contiguous memory */
+int contiguous_planes;
+
 /* Nvidia */
 int dev_is_nvidia;
 } VulkanDevicePriv;
@@ -1266,6 +1269,11 @@ static int 
vulkan_device_create_internal(AVHWDeviceContext *ctx,
 if (opt_d)
 p->use_linear_images = strtol(opt_d->value, NULL, 10);
 
+opt_d = av_dict_get(opts, "contiguous_planes", NULL, 0);
+if (opt_d)
+p->contiguous_planes = strtol(opt_d->value, NULL, 10);
+
+
 hwctx->enabled_dev_extensions = dev_info.ppEnabledExtensionNames;
 hwctx->nb_enabled_dev_extensions = dev_info.enabledExtensionCount;
 
@@ -1410,8 +1418,10 @@ static int vulkan_device_derive(AVHWDeviceContext *ctx,
 return AVERROR_EXTERNAL;
 }
 
-if (strstr(vendor, "Intel"))
+if (strstr(vendor, "Intel")) {
+av_dict_set_int(&opts, "contiguous_planes", 1, 0);
 dev_select.vendor_id = 0x8086;
+}
 if (strstr(vendor, "AMD"))
 dev_select.vendor_id = 0x1002;
 
@@ -1634,8 +1644,12 @@ static int alloc_bind_mem(AVHWFramesContext *hwfc, 
AVVkFrame *f,
 AVHWDeviceContext *ctx = hwfc->device_ctx;
 VulkanDevicePriv *p = ctx->internal->priv;
 FFVulkanFunctions *vk = &p->vkfn;
+AVVulkanFramesContext *hwfctx = hwfc->hwctx;
 const int planes = av_pix_fmt_count_planes(hwfc->sw_format);
 VkBindImageMemoryInfo bind_info[AV_NUM_DATA_POINTERS] = { { 0 } };
+VkMemoryRequirements memory_requirements = { 0 };
+int mem_size = 0;
+int mem_size_list[AV_NUM_DATA_POINTERS] = { 0 };
 
 AVVulkanDeviceContext *hwctx = ctx->hwctx;
 
@@ -1663,6 +1677,19 @@ static int alloc_bind_mem(AVHWFramesContext *hwfc, 
AVVkFrame *f,
 req.memoryRequirements.size = FFALIGN(req.memoryRequirements.size,
   
p->props.properties.limits.minMemoryMapAlignment);
 
+if (hwfctx->contiguous_planes == AV_VK_FRAME_FLAG_CONTIGUOUS_MEMORY) {
+if (memory_requirements.size == 0) {
+memory_requirements = req.memoryRequirements;
+} else if (memory_requirements.memoryTypeBits != 
req.memoryRequirements.memoryTypeBits) {
+av_log(hwfc, AV_LOG_ERROR, "the param for each planes are not 
the same\n");
+return AVERROR(EINVAL);
+}
+
+mem_size_list[i] = req.memoryRequirements.size;
+mem_size += mem_size_list[i];
+continue;
+}
+
 /* In case the implementation prefers/requires dedicated allocation */
 use_ded_mem = ded_req.prefersDedicatedAllocation |
   ded_req.requiresDedicatedAllocation;
@@ -1684,6 +1711,29 @@ static int alloc_bind_mem(AVHWFramesContext *hwfc, 
AVVkFrame *f,
 bind_info[i].memory = f->mem[i];
 }
 
+if (hwfctx->contiguous_planes == AV_VK_FRAME_FLAG_CONTIGUOUS_MEMORY) {
+memory_requirements.size = mem_size;
+
+/* Allocate memory */
+if ((err = alloc_mem(ctx, &memory_requirements,
+f->tiling == VK_IMAGE_TILING_LINEAR ?
+VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT :
+VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
+(void *)(((uint8_t *)alloc_pnext)),
+&f->flags, &f->mem[0])))
+return err;
+
+f->size[0] = memory_requirements.size;
+
+for (int i = 0; i < planes; i++) {
+bind_info[i].sType  = VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO;
+bind_info[i].image  = f->img[i];
+bind_info[i].memory = f->mem[0];
+bind_info[i].memoryOffset = i == 0 ? 0 : mem_size_list[i-1];
+f->offset[i] = bind_info[i].memoryOffset;
+}
+ 

[FFmpeg-devel] [PATCH V2 1/5] hwcontext_vaapi: Use PRIME_2 memory type for modifiers.

2021-11-23 Thread Wenbin Chen
From: Bas Nieuwenhuizen 

This way we can pass explicit modifiers in. Sometimes the
modifier matters for the number of memory planes that
libva accepts, in particular when dealing with
driver-compressed textures. Furthermore the driver might
not actually be able to determine the implicit modifier
if all the buffer-passing has used explicit modifier.
All these issues should be resolved by passing in the
modifier, and for that we switch to using the PRIME_2
memory type.

Tested with experimental radeonsi patches for modifiers
and kmsgrab. Also tested with radeonsi without the
patches to double-check it works without PRIME_2 support.

v2:
  Cache PRIME_2 support to avoid doing two calls every time on
  libva drivers that do not support it.

v3:
  Remove prime2_vas usage.

Signed-off-by: Bas Nieuwenhuizen 
---
 libavutil/hwcontext_vaapi.c | 158 ++--
 1 file changed, 114 insertions(+), 44 deletions(-)

diff --git a/libavutil/hwcontext_vaapi.c b/libavutil/hwcontext_vaapi.c
index 83e542876d..75acc851d6 100644
--- a/libavutil/hwcontext_vaapi.c
+++ b/libavutil/hwcontext_vaapi.c
@@ -79,6 +79,9 @@ typedef struct VAAPIFramesContext {
 unsigned int rt_format;
 // Whether vaDeriveImage works.
 int derive_works;
+// Caches whether VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_2 is unsupported for
+// surface imports.
+int prime_2_import_unsupported;
 } VAAPIFramesContext;
 
 typedef struct VAAPIMapping {
@@ -1022,32 +1025,17 @@ static void vaapi_unmap_from_drm(AVHWFramesContext 
*dst_fc,
 static int vaapi_map_from_drm(AVHWFramesContext *src_fc, AVFrame *dst,
   const AVFrame *src, int flags)
 {
+VAAPIFramesContext *src_vafc = src_fc->internal->priv;
 AVHWFramesContext  *dst_fc =
 (AVHWFramesContext*)dst->hw_frames_ctx->data;
 AVVAAPIDeviceContext  *dst_dev = dst_fc->device_ctx->hwctx;
 const AVDRMFrameDescriptor *desc;
 const VAAPIFormatDescriptor *format_desc;
 VASurfaceID surface_id;
-VAStatus vas;
+VAStatus vas = VA_STATUS_SUCCESS;
+int use_prime2;
 uint32_t va_fourcc;
-int err, i, j, k;
-
-unsigned long buffer_handle;
-VASurfaceAttribExternalBuffers buffer_desc;
-VASurfaceAttrib attrs[2] = {
-{
-.type  = VASurfaceAttribMemoryType,
-.flags = VA_SURFACE_ATTRIB_SETTABLE,
-.value.type= VAGenericValueTypeInteger,
-.value.value.i = VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME,
-},
-{
-.type  = VASurfaceAttribExternalBufferDescriptor,
-.flags = VA_SURFACE_ATTRIB_SETTABLE,
-.value.type= VAGenericValueTypePointer,
-.value.value.p = &buffer_desc,
-}
-};
+int err, i, j;
 
 desc = (AVDRMFrameDescriptor*)src->data[0];
 
@@ -1083,35 +1071,117 @@ static int vaapi_map_from_drm(AVHWFramesContext 
*src_fc, AVFrame *dst,
 format_desc = vaapi_format_from_fourcc(va_fourcc);
 av_assert0(format_desc);
 
-buffer_handle = desc->objects[0].fd;
-buffer_desc.pixel_format = va_fourcc;
-buffer_desc.width= src_fc->width;
-buffer_desc.height   = src_fc->height;
-buffer_desc.data_size= desc->objects[0].size;
-buffer_desc.buffers  = &buffer_handle;
-buffer_desc.num_buffers  = 1;
-buffer_desc.flags= 0;
-
-k = 0;
-for (i = 0; i < desc->nb_layers; i++) {
-for (j = 0; j < desc->layers[i].nb_planes; j++) {
-buffer_desc.pitches[k] = desc->layers[i].planes[j].pitch;
-buffer_desc.offsets[k] = desc->layers[i].planes[j].offset;
-++k;
+use_prime2 = !src_vafc->prime_2_import_unsupported &&
+ desc->objects[0].format_modifier != DRM_FORMAT_MOD_INVALID;
+if (use_prime2) {
+VADRMPRIMESurfaceDescriptor prime_desc;
+VASurfaceAttrib prime_attrs[2] = {
+{
+.type  = VASurfaceAttribMemoryType,
+.flags = VA_SURFACE_ATTRIB_SETTABLE,
+.value.type= VAGenericValueTypeInteger,
+.value.value.i = VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_2,
+},
+{
+.type  = VASurfaceAttribExternalBufferDescriptor,
+.flags = VA_SURFACE_ATTRIB_SETTABLE,
+.value.type= VAGenericValueTypePointer,
+.value.value.p = &prime_desc,
+}
+};
+prime_desc.fourcc = va_fourcc;
+prime_desc.width = src_fc->width;
+prime_desc.height = src_fc->height;
+prime_desc.num_objects = desc->nb_objects;
+for (i = 0; i < desc->nb_objects; ++i) {
+prime_desc.objects[i].fd = desc->objects[i].fd;
+prime_desc.objects[i].size = desc->objects[i].size;
+prime_desc.objects[i].drm_format_modifier =
+desc->objects[i].format_modifier;
 }
-}
-buffer_desc.num_planes = k;
 
-if (format_desc->chroma_planes

[FFmpeg-devel] [PATCH V2 4/5] libavutil/hwcontext_vulkan: Add hwupload and hwdownload support when using contiguous_planes flag.

2021-11-23 Thread Wenbin Chen
Add hwupload and hwdownload support to vulkan when frames are allocated
in one memory

Signed-off-by: Wenbin Chen 
---
 libavutil/hwcontext_vulkan.c | 12 ++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/libavutil/hwcontext_vulkan.c b/libavutil/hwcontext_vulkan.c
index 4100e8b0a2..6421115385 100644
--- a/libavutil/hwcontext_vulkan.c
+++ b/libavutil/hwcontext_vulkan.c
@@ -2212,9 +2212,10 @@ static int vulkan_map_frame_to_mem(AVHWFramesContext 
*hwfc, AVFrame *dst,
const AVFrame *src, int flags)
 {
 VkResult ret;
-int err, mapped_mem_count = 0;
+int err, mapped_mem_count = 0, loop = 0;
 AVVkFrame *f = (AVVkFrame *)src->data[0];
 AVVulkanDeviceContext *hwctx = hwfc->device_ctx->hwctx;
+AVVulkanFramesContext *hwfctx = hwfc->hwctx;
 const int planes = av_pix_fmt_count_planes(hwfc->sw_format);
 VulkanDevicePriv *p = hwfc->device_ctx->internal->priv;
 FFVulkanFunctions *vk = &p->vkfn;
@@ -2241,7 +2242,9 @@ static int vulkan_map_frame_to_mem(AVHWFramesContext 
*hwfc, AVFrame *dst,
 dst->width  = src->width;
 dst->height = src->height;
 
-for (int i = 0; i < planes; i++) {
+loop = hwfctx->contiguous_planes == AV_VK_FRAME_FLAG_CONTIGUOUS_MEMORY ?
+   1 : planes;
+for (int i = 0; i < loop; i++) {
 ret = vk->MapMemory(hwctx->act_dev, f->mem[i], 0,
 VK_WHOLE_SIZE, 0, (void **)&dst->data[i]);
 if (ret != VK_SUCCESS) {
@@ -2252,6 +2255,11 @@ static int vulkan_map_frame_to_mem(AVHWFramesContext 
*hwfc, AVFrame *dst,
 }
 mapped_mem_count++;
 }
+if (hwfctx->contiguous_planes == AV_VK_FRAME_FLAG_CONTIGUOUS_MEMORY) {
+for (int i = 0; i < planes; i++) {
+dst->data[i] = dst->data[0] + f->offset[i];
+}
+}
 
 /* Check if the memory contents matter */
 if (((flags & AV_HWFRAME_MAP_READ) || !(flags & AV_HWFRAME_MAP_OVERWRITE)) 
&&
-- 
2.25.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH V2 5/5] libavutil/hwcontext_vulkan: specify the modifier to create VKImage

2021-11-23 Thread Wenbin Chen
When vulkan image exports to drm, the tilling need to be
VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT. Now add code to create vulkan
image using this format.

Now the following command line works:

ffmpeg -hwaccel vaapi -hwaccel_device /dev/dri/renderD128 
-hwaccel_output_format \
vaapi -i input_1080p.264 -vf "hwmap=derive_device=vulkan,format=vulkan, \
scale_vulkan=1920:1080,hwmap=derive_device=vaapi,format=vaapi" -c:v h264_vaapi 
output.264

Signed-off-by: Wenbin Chen 
---
 libavutil/hwcontext_vulkan.c | 130 +--
 1 file changed, 124 insertions(+), 6 deletions(-)

diff --git a/libavutil/hwcontext_vulkan.c b/libavutil/hwcontext_vulkan.c
index 6421115385..4b951fb202 100644
--- a/libavutil/hwcontext_vulkan.c
+++ b/libavutil/hwcontext_vulkan.c
@@ -230,6 +230,28 @@ const VkFormat *av_vkfmt_from_pixfmt(enum AVPixelFormat p)
 return NULL;
 }
 
+static void *find_in_structure_list(VkBaseOutStructure *stru_list, 
VkStructureType sType) {
+if (!stru_list)
+return NULL;
+
+for(;stru_list;stru_list = stru_list->pNext)
+if (stru_list->sType == sType)
+return stru_list;
+
+return NULL;
+}
+
+static void append_to_structure_list(VkBaseOutStructure **stru_list, 
VkBaseOutStructure *added_stru) {
+VkBaseOutStructure *p;
+if (!*stru_list) {
+*stru_list = added_stru;
+return;
+}
+for(p = *stru_list; p->pNext; p = p->pNext);
+p->pNext = added_stru;
+return;
+}
+
 static int pixfmt_is_supported(AVHWDeviceContext *dev_ctx, enum AVPixelFormat 
p,
int linear)
 {
@@ -1979,6 +2001,10 @@ static void try_export_flags(AVHWFramesContext *hwfc,
 AVVulkanDeviceContext *dev_hwctx = hwfc->device_ctx->hwctx;
 VulkanDevicePriv *p = hwfc->device_ctx->internal->priv;
 FFVulkanFunctions *vk = &p->vkfn;
+const int has_modifiers = hwctx->tiling == 
VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT;
+int loop_count;
+VkImageDrmFormatModifierListCreateInfoEXT *modifier_info = 
find_in_structure_list(hwctx->create_pnext,
+
VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_LIST_CREATE_INFO_EXT);
 VkExternalImageFormatProperties eprops = {
 .sType = VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES_KHR,
 };
@@ -1986,9 +2012,18 @@ static void try_export_flags(AVHWFramesContext *hwfc,
 .sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2,
 .pNext = &eprops,
 };
+VkPhysicalDeviceImageDrmFormatModifierInfoEXT phy_dev_mod_info = {
+.sType = 
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_DRM_FORMAT_MODIFIER_INFO_EXT,
+.pNext = NULL,
+.pQueueFamilyIndices   = p->qfs,
+.queueFamilyIndexCount = p->num_qfs,
+.sharingMode   = p->num_qfs > 1 ? VK_SHARING_MODE_CONCURRENT :
+  VK_SHARING_MODE_EXCLUSIVE,
+};
 VkPhysicalDeviceExternalImageFormatInfo enext = {
 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO,
 .handleType = exp,
+.pNext = has_modifiers && modifier_info ? &phy_dev_mod_info : NULL,
 };
 VkPhysicalDeviceImageFormatInfo2 pinfo = {
 .sType  = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2,
@@ -2000,11 +2035,16 @@ static void try_export_flags(AVHWFramesContext *hwfc,
 .flags  = VK_IMAGE_CREATE_ALIAS_BIT,
 };
 
-ret = vk->GetPhysicalDeviceImageFormatProperties2(dev_hwctx->phys_dev,
-  &pinfo, &props);
-if (ret == VK_SUCCESS) {
-*iexp |= exp;
-*comp_handle_types |= 
eprops.externalMemoryProperties.compatibleHandleTypes;
+loop_count = has_modifiers && modifier_info ? 
modifier_info->drmFormatModifierCount : 1;
+for (int i = 0; i < loop_count; i++) {
+if (has_modifiers && modifier_info)
+phy_dev_mod_info.drmFormatModifier = 
modifier_info->pDrmFormatModifiers[i];
+ret = vk->GetPhysicalDeviceImageFormatProperties2(dev_hwctx->phys_dev,
+&pinfo, &props);
+if (ret == VK_SUCCESS) {
+*iexp |= exp;
+*comp_handle_types |= 
eprops.externalMemoryProperties.compatibleHandleTypes;
+}
 }
 }
 
@@ -2074,6 +2114,20 @@ fail:
 static void vulkan_frames_uninit(AVHWFramesContext *hwfc)
 {
 VulkanFramesPriv *fp = hwfc->internal->priv;
+AVVulkanFramesContext *hwctx = hwfc->hwctx;
+VkBaseOutStructure *structure_p_next,*structure_p = hwctx->create_pnext;
+VkImageDrmFormatModifierListCreateInfoEXT *modifier_info;
+while (structure_p) {
+structure_p_next = structure_p->pNext;
+switch (structure_p->sType) {
+case VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_LIST_CREATE_INF

[FFmpeg-devel] [PATCH V3 1/5] hwcontext_vaapi: Use PRIME_2 memory type for modifiers.

2021-11-25 Thread Wenbin Chen
From: Bas Nieuwenhuizen 

This way we can pass explicit modifiers in. Sometimes the
modifier matters for the number of memory planes that
libva accepts, in particular when dealing with
driver-compressed textures. Furthermore the driver might
not actually be able to determine the implicit modifier
if all the buffer-passing has used explicit modifier.
All these issues should be resolved by passing in the
modifier, and for that we switch to using the PRIME_2
memory type.

Tested with experimental radeonsi patches for modifiers
and kmsgrab. Also tested with radeonsi without the
patches to double-check it works without PRIME_2 support.

v2:
  Cache PRIME_2 support to avoid doing two calls every time on
  libva drivers that do not support it.

v3:
  Remove prime2_vas usage.

Signed-off-by: Bas Nieuwenhuizen 
---
 libavutil/hwcontext_vaapi.c | 158 ++--
 1 file changed, 114 insertions(+), 44 deletions(-)

diff --git a/libavutil/hwcontext_vaapi.c b/libavutil/hwcontext_vaapi.c
index 83e542876d..75acc851d6 100644
--- a/libavutil/hwcontext_vaapi.c
+++ b/libavutil/hwcontext_vaapi.c
@@ -79,6 +79,9 @@ typedef struct VAAPIFramesContext {
 unsigned int rt_format;
 // Whether vaDeriveImage works.
 int derive_works;
+// Caches whether VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_2 is unsupported for
+// surface imports.
+int prime_2_import_unsupported;
 } VAAPIFramesContext;
 
 typedef struct VAAPIMapping {
@@ -1022,32 +1025,17 @@ static void vaapi_unmap_from_drm(AVHWFramesContext 
*dst_fc,
 static int vaapi_map_from_drm(AVHWFramesContext *src_fc, AVFrame *dst,
   const AVFrame *src, int flags)
 {
+VAAPIFramesContext *src_vafc = src_fc->internal->priv;
 AVHWFramesContext  *dst_fc =
 (AVHWFramesContext*)dst->hw_frames_ctx->data;
 AVVAAPIDeviceContext  *dst_dev = dst_fc->device_ctx->hwctx;
 const AVDRMFrameDescriptor *desc;
 const VAAPIFormatDescriptor *format_desc;
 VASurfaceID surface_id;
-VAStatus vas;
+VAStatus vas = VA_STATUS_SUCCESS;
+int use_prime2;
 uint32_t va_fourcc;
-int err, i, j, k;
-
-unsigned long buffer_handle;
-VASurfaceAttribExternalBuffers buffer_desc;
-VASurfaceAttrib attrs[2] = {
-{
-.type  = VASurfaceAttribMemoryType,
-.flags = VA_SURFACE_ATTRIB_SETTABLE,
-.value.type= VAGenericValueTypeInteger,
-.value.value.i = VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME,
-},
-{
-.type  = VASurfaceAttribExternalBufferDescriptor,
-.flags = VA_SURFACE_ATTRIB_SETTABLE,
-.value.type= VAGenericValueTypePointer,
-.value.value.p = &buffer_desc,
-}
-};
+int err, i, j;
 
 desc = (AVDRMFrameDescriptor*)src->data[0];
 
@@ -1083,35 +1071,117 @@ static int vaapi_map_from_drm(AVHWFramesContext 
*src_fc, AVFrame *dst,
 format_desc = vaapi_format_from_fourcc(va_fourcc);
 av_assert0(format_desc);
 
-buffer_handle = desc->objects[0].fd;
-buffer_desc.pixel_format = va_fourcc;
-buffer_desc.width= src_fc->width;
-buffer_desc.height   = src_fc->height;
-buffer_desc.data_size= desc->objects[0].size;
-buffer_desc.buffers  = &buffer_handle;
-buffer_desc.num_buffers  = 1;
-buffer_desc.flags= 0;
-
-k = 0;
-for (i = 0; i < desc->nb_layers; i++) {
-for (j = 0; j < desc->layers[i].nb_planes; j++) {
-buffer_desc.pitches[k] = desc->layers[i].planes[j].pitch;
-buffer_desc.offsets[k] = desc->layers[i].planes[j].offset;
-++k;
+use_prime2 = !src_vafc->prime_2_import_unsupported &&
+ desc->objects[0].format_modifier != DRM_FORMAT_MOD_INVALID;
+if (use_prime2) {
+VADRMPRIMESurfaceDescriptor prime_desc;
+VASurfaceAttrib prime_attrs[2] = {
+{
+.type  = VASurfaceAttribMemoryType,
+.flags = VA_SURFACE_ATTRIB_SETTABLE,
+.value.type= VAGenericValueTypeInteger,
+.value.value.i = VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_2,
+},
+{
+.type  = VASurfaceAttribExternalBufferDescriptor,
+.flags = VA_SURFACE_ATTRIB_SETTABLE,
+.value.type= VAGenericValueTypePointer,
+.value.value.p = &prime_desc,
+}
+};
+prime_desc.fourcc = va_fourcc;
+prime_desc.width = src_fc->width;
+prime_desc.height = src_fc->height;
+prime_desc.num_objects = desc->nb_objects;
+for (i = 0; i < desc->nb_objects; ++i) {
+prime_desc.objects[i].fd = desc->objects[i].fd;
+prime_desc.objects[i].size = desc->objects[i].size;
+prime_desc.objects[i].drm_format_modifier =
+desc->objects[i].format_modifier;
 }
-}
-buffer_desc.num_planes = k;
 
-if (format_desc->chroma_planes

[FFmpeg-devel] [PATCH V3 2/5] libavutil/hwcontext_vaapi: Add a new nv12 format map to support vulkan frame

2021-11-25 Thread Wenbin Chen
Vulkan will map nv12 to R8 and GR88, so add this map to vaapi to support
vulkan frame.

Signed-off-by: Wenbin Chen 
---
 libavutil/hwcontext_vaapi.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/libavutil/hwcontext_vaapi.c b/libavutil/hwcontext_vaapi.c
index 75acc851d6..994b744e4d 100644
--- a/libavutil/hwcontext_vaapi.c
+++ b/libavutil/hwcontext_vaapi.c
@@ -992,6 +992,7 @@ static const struct {
 } vaapi_drm_format_map[] = {
 #ifdef DRM_FORMAT_R8
 DRM_MAP(NV12, 2, DRM_FORMAT_R8,  DRM_FORMAT_RG88),
+DRM_MAP(NV12, 2, DRM_FORMAT_R8,  DRM_FORMAT_GR88),
 #endif
 DRM_MAP(NV12, 1, DRM_FORMAT_NV12),
 #if defined(VA_FOURCC_P010) && defined(DRM_FORMAT_R16)
-- 
2.25.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH V3 3/5] libavutil/hwcontext_vulkan: Allocate vkFrame in one memory

2021-11-25 Thread Wenbin Chen
The vaapi can import external frame, but the planes of the external
frames should be in the same drm object. A new option "contiguous_planes"
is added to device. This flag tells device to allocate places in one
memory. When device is derived from vaapi this flag will be enabled.
A new flag frame_flag is also added to AVVulkanFramesContext. User
can use this flag to force enable or disable this behaviour.
A new variable "offset "is added to AVVKFrame. It describe describe the
offset from the memory currently bound to the VkImage.

Signed-off-by: Wenbin Chen 
---
 libavutil/hwcontext_vulkan.c | 67 +++-
 libavutil/hwcontext_vulkan.h | 24 +
 2 files changed, 90 insertions(+), 1 deletion(-)

diff --git a/libavutil/hwcontext_vulkan.c b/libavutil/hwcontext_vulkan.c
index 644ed947f8..b8076fb425 100644
--- a/libavutil/hwcontext_vulkan.c
+++ b/libavutil/hwcontext_vulkan.c
@@ -103,8 +103,14 @@ typedef struct VulkanDevicePriv {
 /* Settings */
 int use_linear_images;
 
+/* allocate planes in a contiguous memory */
+int contiguous_planes;
+
 /* Nvidia */
 int dev_is_nvidia;
+
+/* Intel */
+int dev_is_intel;
 } VulkanDevicePriv;
 
 typedef struct VulkanFramesPriv {
@@ -146,6 +152,8 @@ typedef struct AVVkFrameInternal {
 }  
\
 } while(0)
 
+#define VKF_FLAG(x, f) (((x) & (~AV_VK_FRAME_FLAG_NONE)) & (f))
+
 static const struct {
 enum AVPixelFormat pixfmt;
 const VkFormat vkfmts[4];
@@ -1268,6 +1276,13 @@ static int 
vulkan_device_create_internal(AVHWDeviceContext *ctx,
 if (opt_d)
 p->use_linear_images = strtol(opt_d->value, NULL, 10);
 
+opt_d = av_dict_get(opts, "contiguous_planes", NULL, 0);
+if (opt_d)
+p->contiguous_planes = strtol(opt_d->value, NULL, 10);
+else
+p->contiguous_planes = -1;
+
+
 hwctx->enabled_dev_extensions = dev_info.ppEnabledExtensionNames;
 hwctx->nb_enabled_dev_extensions = dev_info.enabledExtensionCount;
 
@@ -1319,6 +1334,8 @@ static int vulkan_device_init(AVHWDeviceContext *ctx)
 
 p->dev_is_nvidia = (p->props.properties.vendorID == 0x10de);
 
+p->dev_is_intel = (p->props.properties.vendorID == 0x8086);
+
 vk->GetPhysicalDeviceQueueFamilyProperties(hwctx->phys_dev, &queue_num, 
NULL);
 if (!queue_num) {
 av_log(ctx, AV_LOG_ERROR, "Failed to get queues!\n");
@@ -1636,8 +1653,12 @@ static int alloc_bind_mem(AVHWFramesContext *hwfc, 
AVVkFrame *f,
 AVHWDeviceContext *ctx = hwfc->device_ctx;
 VulkanDevicePriv *p = ctx->internal->priv;
 FFVulkanFunctions *vk = &p->vkfn;
+AVVulkanFramesContext *hwfctx = hwfc->hwctx;
 const int planes = av_pix_fmt_count_planes(hwfc->sw_format);
 VkBindImageMemoryInfo bind_info[AV_NUM_DATA_POINTERS] = { { 0 } };
+VkMemoryRequirements memory_requirements = { 0 };
+int mem_size = 0;
+int mem_size_list[AV_NUM_DATA_POINTERS] = { 0 };
 
 AVVulkanDeviceContext *hwctx = ctx->hwctx;
 
@@ -1665,6 +1686,19 @@ static int alloc_bind_mem(AVHWFramesContext *hwfc, 
AVVkFrame *f,
 req.memoryRequirements.size = FFALIGN(req.memoryRequirements.size,
   
p->props.properties.limits.minMemoryMapAlignment);
 
+if (VKF_FLAG(hwfctx->flags, AV_VK_FRAME_FLAG_CONTIGUOUS_MEMORY)) {
+if (memory_requirements.size == 0) {
+memory_requirements = req.memoryRequirements;
+} else if (memory_requirements.memoryTypeBits != 
req.memoryRequirements.memoryTypeBits) {
+av_log(hwfc, AV_LOG_ERROR, "the param for each planes are not 
the same\n");
+return AVERROR(EINVAL);
+}
+
+mem_size_list[i] = req.memoryRequirements.size;
+mem_size += mem_size_list[i];
+continue;
+}
+
 /* In case the implementation prefers/requires dedicated allocation */
 use_ded_mem = ded_req.prefersDedicatedAllocation |
   ded_req.requiresDedicatedAllocation;
@@ -1686,6 +1720,29 @@ static int alloc_bind_mem(AVHWFramesContext *hwfc, 
AVVkFrame *f,
 bind_info[i].memory = f->mem[i];
 }
 
+if (VKF_FLAG(hwfctx->flags, AV_VK_FRAME_FLAG_CONTIGUOUS_MEMORY)) {
+memory_requirements.size = mem_size;
+
+/* Allocate memory */
+if ((err = alloc_mem(ctx, &memory_requirements,
+f->tiling == VK_IMAGE_TILING_LINEAR ?
+VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT :
+VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
+(void *)(((uint8_t *)alloc_pnext)),
+&f->flags, &f->mem[0])))
+return err;
+
+f

[FFmpeg-devel] [PATCH V3 4/5] libavutil/hwcontext_vulkan: Add support to hwmap to software frame when using contiguous_planes flag.

2021-11-25 Thread Wenbin Chen
Add support to map vulkan frames to software frames when
using contiguous_planes flag.

Signed-off-by: Wenbin Chen 
---
 libavutil/hwcontext_vulkan.c | 11 +--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/libavutil/hwcontext_vulkan.c b/libavutil/hwcontext_vulkan.c
index b8076fb425..0648e59243 100644
--- a/libavutil/hwcontext_vulkan.c
+++ b/libavutil/hwcontext_vulkan.c
@@ -2221,9 +2221,10 @@ static int vulkan_map_frame_to_mem(AVHWFramesContext 
*hwfc, AVFrame *dst,
const AVFrame *src, int flags)
 {
 VkResult ret;
-int err, mapped_mem_count = 0;
+int err, mapped_mem_count = 0, loop = 0;
 AVVkFrame *f = (AVVkFrame *)src->data[0];
 AVVulkanDeviceContext *hwctx = hwfc->device_ctx->hwctx;
+AVVulkanFramesContext *hwfctx = hwfc->hwctx;
 const int planes = av_pix_fmt_count_planes(hwfc->sw_format);
 VulkanDevicePriv *p = hwfc->device_ctx->internal->priv;
 FFVulkanFunctions *vk = &p->vkfn;
@@ -2250,7 +2251,9 @@ static int vulkan_map_frame_to_mem(AVHWFramesContext 
*hwfc, AVFrame *dst,
 dst->width  = src->width;
 dst->height = src->height;
 
-for (int i = 0; i < planes; i++) {
+loop = VKF_FLAG(hwfctx->flags, AV_VK_FRAME_FLAG_CONTIGUOUS_MEMORY) ?
+   1 : planes;
+for (int i = 0; i < loop; i++) {
 ret = vk->MapMemory(hwctx->act_dev, f->mem[i], 0,
 VK_WHOLE_SIZE, 0, (void **)&dst->data[i]);
 if (ret != VK_SUCCESS) {
@@ -2261,6 +2264,10 @@ static int vulkan_map_frame_to_mem(AVHWFramesContext 
*hwfc, AVFrame *dst,
 }
 mapped_mem_count++;
 }
+if (VKF_FLAG(hwfctx->flags, AV_VK_FRAME_FLAG_CONTIGUOUS_MEMORY)) {
+for (int i = 0; i < planes; i++)
+dst->data[i] = dst->data[0] + f->offset[i];
+}
 
 /* Check if the memory contents matter */
 if (((flags & AV_HWFRAME_MAP_READ) || !(flags & AV_HWFRAME_MAP_OVERWRITE)) 
&&
-- 
2.25.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH V3 5/5] libavutil/hwcontext_vulkan: specify the modifier to create VKImage

2021-11-25 Thread Wenbin Chen
When vulkan image exports to drm, the tilling need to be
VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT. Now add code to create vulkan
image using this format.

Now the following command line works:

ffmpeg -hwaccel vaapi -hwaccel_device /dev/dri/renderD128 
-hwaccel_output_format \
vaapi -i input_1080p.264 -vf "hwmap=derive_device=vulkan,format=vulkan, \
scale_vulkan=1920:1080,hwmap=derive_device=vaapi,format=vaapi" -c:v h264_vaapi 
output.264

Signed-off-by: Wenbin Chen 
---
 libavutil/hwcontext_vulkan.c | 127 +--
 1 file changed, 121 insertions(+), 6 deletions(-)

diff --git a/libavutil/hwcontext_vulkan.c b/libavutil/hwcontext_vulkan.c
index 0648e59243..903a75618a 100644
--- a/libavutil/hwcontext_vulkan.c
+++ b/libavutil/hwcontext_vulkan.c
@@ -120,6 +120,9 @@ typedef struct VulkanFramesPriv {
 /* Image transfers */
 VulkanExecCtx upload_ctx;
 VulkanExecCtx download_ctx;
+
+/*modifier info*/
+VkImageDrmFormatModifierListCreateInfoEXT *modifier_info;
 } VulkanFramesPriv;
 
 typedef struct AVVkFrameInternal {
@@ -235,6 +238,28 @@ const VkFormat *av_vkfmt_from_pixfmt(enum AVPixelFormat p)
 return NULL;
 }
 
+static void *find_in_structure_list(VkBaseOutStructure *stru_list, 
VkStructureType sType) {
+if (!stru_list)
+return NULL;
+
+for(;stru_list;stru_list = stru_list->pNext)
+if (stru_list->sType == sType)
+return stru_list;
+
+return NULL;
+}
+
+static void append_to_structure_list(VkBaseOutStructure **stru_list, 
VkBaseOutStructure *added_stru) {
+VkBaseOutStructure *p;
+if (!*stru_list) {
+*stru_list = added_stru;
+return;
+}
+for(p = *stru_list; p->pNext; p = p->pNext);
+p->pNext = added_stru;
+return;
+}
+
 static int pixfmt_is_supported(AVHWDeviceContext *dev_ctx, enum AVPixelFormat 
p,
int linear)
 {
@@ -1988,6 +2013,10 @@ static void try_export_flags(AVHWFramesContext *hwfc,
 AVVulkanDeviceContext *dev_hwctx = hwfc->device_ctx->hwctx;
 VulkanDevicePriv *p = hwfc->device_ctx->internal->priv;
 FFVulkanFunctions *vk = &p->vkfn;
+const int has_modifiers = hwctx->tiling == 
VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT;
+int loop_count;
+VkImageDrmFormatModifierListCreateInfoEXT *modifier_info = 
find_in_structure_list(hwctx->create_pnext,
+
VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_LIST_CREATE_INFO_EXT);
 VkExternalImageFormatProperties eprops = {
 .sType = VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES_KHR,
 };
@@ -1995,9 +2024,18 @@ static void try_export_flags(AVHWFramesContext *hwfc,
 .sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2,
 .pNext = &eprops,
 };
+VkPhysicalDeviceImageDrmFormatModifierInfoEXT phy_dev_mod_info = {
+.sType = 
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_DRM_FORMAT_MODIFIER_INFO_EXT,
+.pNext = NULL,
+.pQueueFamilyIndices   = p->qfs,
+.queueFamilyIndexCount = p->num_qfs,
+.sharingMode   = p->num_qfs > 1 ? VK_SHARING_MODE_CONCURRENT :
+  VK_SHARING_MODE_EXCLUSIVE,
+};
 VkPhysicalDeviceExternalImageFormatInfo enext = {
 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO,
 .handleType = exp,
+.pNext = has_modifiers && modifier_info ? &phy_dev_mod_info : NULL,
 };
 VkPhysicalDeviceImageFormatInfo2 pinfo = {
 .sType  = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2,
@@ -2009,11 +2047,16 @@ static void try_export_flags(AVHWFramesContext *hwfc,
 .flags  = VK_IMAGE_CREATE_ALIAS_BIT,
 };
 
-ret = vk->GetPhysicalDeviceImageFormatProperties2(dev_hwctx->phys_dev,
-  &pinfo, &props);
-if (ret == VK_SUCCESS) {
-*iexp |= exp;
-*comp_handle_types |= 
eprops.externalMemoryProperties.compatibleHandleTypes;
+loop_count = has_modifiers && modifier_info ? 
modifier_info->drmFormatModifierCount : 1;
+for (int i = 0; i < loop_count; i++) {
+if (has_modifiers && modifier_info)
+phy_dev_mod_info.drmFormatModifier = 
modifier_info->pDrmFormatModifiers[i];
+ret = vk->GetPhysicalDeviceImageFormatProperties2(dev_hwctx->phys_dev,
+&pinfo, &props);
+if (ret == VK_SUCCESS) {
+*iexp |= exp;
+*comp_handle_types |= 
eprops.externalMemoryProperties.compatibleHandleTypes;
+}
 }
 }
 
@@ -2084,6 +2127,12 @@ static void vulkan_frames_uninit(AVHWFramesContext *hwfc)
 {
 VulkanFramesPriv *fp = hwfc->internal->priv;
 
+if (fp->modifier_info) {
+if (fp->modifier_info->pDrmFormatModifiers)
+

[FFmpeg-devel] [PATCH V4 1/5] hwcontext_vaapi: Use PRIME_2 memory type for modifiers.

2021-11-29 Thread Wenbin Chen
From: Bas Nieuwenhuizen 

This way we can pass explicit modifiers in. Sometimes the
modifier matters for the number of memory planes that
libva accepts, in particular when dealing with
driver-compressed textures. Furthermore the driver might
not actually be able to determine the implicit modifier
if all the buffer-passing has used explicit modifier.
All these issues should be resolved by passing in the
modifier, and for that we switch to using the PRIME_2
memory type.

Tested with experimental radeonsi patches for modifiers
and kmsgrab. Also tested with radeonsi without the
patches to double-check it works without PRIME_2 support.

v2:
  Cache PRIME_2 support to avoid doing two calls every time on
  libva drivers that do not support it.

v3:
  Remove prime2_vas usage.

Signed-off-by: Bas Nieuwenhuizen 
---
 libavutil/hwcontext_vaapi.c | 158 ++--
 1 file changed, 114 insertions(+), 44 deletions(-)

diff --git a/libavutil/hwcontext_vaapi.c b/libavutil/hwcontext_vaapi.c
index 83e542876d..75acc851d6 100644
--- a/libavutil/hwcontext_vaapi.c
+++ b/libavutil/hwcontext_vaapi.c
@@ -79,6 +79,9 @@ typedef struct VAAPIFramesContext {
 unsigned int rt_format;
 // Whether vaDeriveImage works.
 int derive_works;
+// Caches whether VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_2 is unsupported for
+// surface imports.
+int prime_2_import_unsupported;
 } VAAPIFramesContext;
 
 typedef struct VAAPIMapping {
@@ -1022,32 +1025,17 @@ static void vaapi_unmap_from_drm(AVHWFramesContext 
*dst_fc,
 static int vaapi_map_from_drm(AVHWFramesContext *src_fc, AVFrame *dst,
   const AVFrame *src, int flags)
 {
+VAAPIFramesContext *src_vafc = src_fc->internal->priv;
 AVHWFramesContext  *dst_fc =
 (AVHWFramesContext*)dst->hw_frames_ctx->data;
 AVVAAPIDeviceContext  *dst_dev = dst_fc->device_ctx->hwctx;
 const AVDRMFrameDescriptor *desc;
 const VAAPIFormatDescriptor *format_desc;
 VASurfaceID surface_id;
-VAStatus vas;
+VAStatus vas = VA_STATUS_SUCCESS;
+int use_prime2;
 uint32_t va_fourcc;
-int err, i, j, k;
-
-unsigned long buffer_handle;
-VASurfaceAttribExternalBuffers buffer_desc;
-VASurfaceAttrib attrs[2] = {
-{
-.type  = VASurfaceAttribMemoryType,
-.flags = VA_SURFACE_ATTRIB_SETTABLE,
-.value.type= VAGenericValueTypeInteger,
-.value.value.i = VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME,
-},
-{
-.type  = VASurfaceAttribExternalBufferDescriptor,
-.flags = VA_SURFACE_ATTRIB_SETTABLE,
-.value.type= VAGenericValueTypePointer,
-.value.value.p = &buffer_desc,
-}
-};
+int err, i, j;
 
 desc = (AVDRMFrameDescriptor*)src->data[0];
 
@@ -1083,35 +1071,117 @@ static int vaapi_map_from_drm(AVHWFramesContext 
*src_fc, AVFrame *dst,
 format_desc = vaapi_format_from_fourcc(va_fourcc);
 av_assert0(format_desc);
 
-buffer_handle = desc->objects[0].fd;
-buffer_desc.pixel_format = va_fourcc;
-buffer_desc.width= src_fc->width;
-buffer_desc.height   = src_fc->height;
-buffer_desc.data_size= desc->objects[0].size;
-buffer_desc.buffers  = &buffer_handle;
-buffer_desc.num_buffers  = 1;
-buffer_desc.flags= 0;
-
-k = 0;
-for (i = 0; i < desc->nb_layers; i++) {
-for (j = 0; j < desc->layers[i].nb_planes; j++) {
-buffer_desc.pitches[k] = desc->layers[i].planes[j].pitch;
-buffer_desc.offsets[k] = desc->layers[i].planes[j].offset;
-++k;
+use_prime2 = !src_vafc->prime_2_import_unsupported &&
+ desc->objects[0].format_modifier != DRM_FORMAT_MOD_INVALID;
+if (use_prime2) {
+VADRMPRIMESurfaceDescriptor prime_desc;
+VASurfaceAttrib prime_attrs[2] = {
+{
+.type  = VASurfaceAttribMemoryType,
+.flags = VA_SURFACE_ATTRIB_SETTABLE,
+.value.type= VAGenericValueTypeInteger,
+.value.value.i = VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_2,
+},
+{
+.type  = VASurfaceAttribExternalBufferDescriptor,
+.flags = VA_SURFACE_ATTRIB_SETTABLE,
+.value.type= VAGenericValueTypePointer,
+.value.value.p = &prime_desc,
+}
+};
+prime_desc.fourcc = va_fourcc;
+prime_desc.width = src_fc->width;
+prime_desc.height = src_fc->height;
+prime_desc.num_objects = desc->nb_objects;
+for (i = 0; i < desc->nb_objects; ++i) {
+prime_desc.objects[i].fd = desc->objects[i].fd;
+prime_desc.objects[i].size = desc->objects[i].size;
+prime_desc.objects[i].drm_format_modifier =
+desc->objects[i].format_modifier;
 }
-}
-buffer_desc.num_planes = k;
 
-if (format_desc->chroma_planes

[FFmpeg-devel] [PATCH V4 2/5] libavutil/hwcontext_vaapi: Add a new nv12 format map to support vulkan frame

2021-11-29 Thread Wenbin Chen
Vulkan will map nv12 to R8 and GR88, so add this map to vaapi to support
vulkan frame.

Signed-off-by: Wenbin Chen 
---
 libavutil/hwcontext_vaapi.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/libavutil/hwcontext_vaapi.c b/libavutil/hwcontext_vaapi.c
index 75acc851d6..994b744e4d 100644
--- a/libavutil/hwcontext_vaapi.c
+++ b/libavutil/hwcontext_vaapi.c
@@ -992,6 +992,7 @@ static const struct {
 } vaapi_drm_format_map[] = {
 #ifdef DRM_FORMAT_R8
 DRM_MAP(NV12, 2, DRM_FORMAT_R8,  DRM_FORMAT_RG88),
+DRM_MAP(NV12, 2, DRM_FORMAT_R8,  DRM_FORMAT_GR88),
 #endif
 DRM_MAP(NV12, 1, DRM_FORMAT_NV12),
 #if defined(VA_FOURCC_P010) && defined(DRM_FORMAT_R16)
-- 
2.25.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH V4 3/5] libavutil/hwcontext_vulkan: Allocate vkFrame in one memory

2021-11-29 Thread Wenbin Chen
The vaapi can import external frame, but the planes of the external
frames should be in the same drm object. A new option "contiguous_planes"
is added to device. This flag tells device to allocate places in one
memory. When device is derived from vaapi this flag will be enabled.
A new flag frame_flag is also added to AVVulkanFramesContext. User
can use this flag to force enable or disable this behaviour.
A new variable "offset "is added to AVVKFrame. It describe describe the
offset from the memory currently bound to the VkImage.

Signed-off-by: Wenbin Chen 
---
 libavutil/hwcontext_vulkan.c | 68 +++-
 libavutil/hwcontext_vulkan.h | 24 +
 2 files changed, 91 insertions(+), 1 deletion(-)

diff --git a/libavutil/hwcontext_vulkan.c b/libavutil/hwcontext_vulkan.c
index a0437c9661..eef9009ae1 100644
--- a/libavutil/hwcontext_vulkan.c
+++ b/libavutil/hwcontext_vulkan.c
@@ -103,8 +103,14 @@ typedef struct VulkanDevicePriv {
 /* Settings */
 int use_linear_images;
 
+/* allocate planes in a contiguous memory */
+int contiguous_planes;
+
 /* Nvidia */
 int dev_is_nvidia;
+
+/* Intel */
+int dev_is_intel;
 } VulkanDevicePriv;
 
 typedef struct VulkanFramesPriv {
@@ -153,6 +159,8 @@ typedef struct AVVkFrameInternal {
 av_free((void *)props);
\
 }
 
+#define VKF_FLAG(x, f) (((x) & (~AV_VK_FRAME_FLAG_NONE)) & (f))
+
 static const struct {
 enum AVPixelFormat pixfmt;
 const VkFormat vkfmts[4];
@@ -1374,6 +1382,13 @@ static int 
vulkan_device_create_internal(AVHWDeviceContext *ctx,
 if (opt_d)
 p->use_linear_images = strtol(opt_d->value, NULL, 10);
 
+opt_d = av_dict_get(opts, "contiguous_planes", NULL, 0);
+if (opt_d)
+p->contiguous_planes = strtol(opt_d->value, NULL, 10);
+else
+p->contiguous_planes = -1;
+
+
 hwctx->enabled_dev_extensions = dev_info.ppEnabledExtensionNames;
 hwctx->nb_enabled_dev_extensions = dev_info.enabledExtensionCount;
 
@@ -1425,6 +1440,8 @@ static int vulkan_device_init(AVHWDeviceContext *ctx)
 
 p->dev_is_nvidia = (p->props.properties.vendorID == 0x10de);
 
+p->dev_is_intel = (p->props.properties.vendorID == 0x8086);
+
 vk->GetPhysicalDeviceQueueFamilyProperties(hwctx->phys_dev, &queue_num, 
NULL);
 if (!queue_num) {
 av_log(ctx, AV_LOG_ERROR, "Failed to get queues!\n");
@@ -1742,8 +1759,12 @@ static int alloc_bind_mem(AVHWFramesContext *hwfc, 
AVVkFrame *f,
 AVHWDeviceContext *ctx = hwfc->device_ctx;
 VulkanDevicePriv *p = ctx->internal->priv;
 FFVulkanFunctions *vk = &p->vkfn;
+AVVulkanFramesContext *hwfctx = hwfc->hwctx;
 const int planes = av_pix_fmt_count_planes(hwfc->sw_format);
 VkBindImageMemoryInfo bind_info[AV_NUM_DATA_POINTERS] = { { 0 } };
+VkMemoryRequirements memory_requirements = { 0 };
+int mem_size = 0;
+int mem_size_list[AV_NUM_DATA_POINTERS] = { 0 };
 
 AVVulkanDeviceContext *hwctx = ctx->hwctx;
 
@@ -1771,6 +1792,19 @@ static int alloc_bind_mem(AVHWFramesContext *hwfc, 
AVVkFrame *f,
 req.memoryRequirements.size = FFALIGN(req.memoryRequirements.size,
   
p->props.properties.limits.minMemoryMapAlignment);
 
+if (VKF_FLAG(hwfctx->flags, AV_VK_FRAME_FLAG_CONTIGUOUS_MEMORY)) {
+if (memory_requirements.size == 0) {
+memory_requirements = req.memoryRequirements;
+} else if (memory_requirements.memoryTypeBits != 
req.memoryRequirements.memoryTypeBits) {
+av_log(hwfc, AV_LOG_ERROR, "the param for each planes are not 
the same\n");
+return AVERROR(EINVAL);
+}
+
+mem_size_list[i] = req.memoryRequirements.size;
+mem_size += mem_size_list[i];
+continue;
+}
+
 /* In case the implementation prefers/requires dedicated allocation */
 use_ded_mem = ded_req.prefersDedicatedAllocation |
   ded_req.requiresDedicatedAllocation;
@@ -1792,6 +1826,29 @@ static int alloc_bind_mem(AVHWFramesContext *hwfc, 
AVVkFrame *f,
 bind_info[i].memory = f->mem[i];
 }
 
+if (VKF_FLAG(hwfctx->flags, AV_VK_FRAME_FLAG_CONTIGUOUS_MEMORY)) {
+memory_requirements.size = mem_size;
+
+/* Allocate memory */
+if ((err = alloc_mem(ctx, &memory_requirements,
+f->tiling == VK_IMAGE_TILING_LINEAR ?
+VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT :
+VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
+(void *)(((uint8_t *)alloc_pnext)),
+&f->flags, &f->mem[0])))
+return err;
+
+f

[FFmpeg-devel] [PATCH V4 4/5] libavutil/hwcontext_vulkan: Add support to hwmap to software frame when using contiguous_planes flag.

2021-11-29 Thread Wenbin Chen
Add support to map vulkan frames to software frames when
using contiguous_planes flag.

Signed-off-by: Wenbin Chen 
---
 libavutil/hwcontext_vulkan.c | 11 +--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/libavutil/hwcontext_vulkan.c b/libavutil/hwcontext_vulkan.c
index eef9009ae1..f980b72720 100644
--- a/libavutil/hwcontext_vulkan.c
+++ b/libavutil/hwcontext_vulkan.c
@@ -2327,9 +2327,10 @@ static int vulkan_map_frame_to_mem(AVHWFramesContext 
*hwfc, AVFrame *dst,
const AVFrame *src, int flags)
 {
 VkResult ret;
-int err, mapped_mem_count = 0;
+int err, mapped_mem_count = 0, loop = 0;
 AVVkFrame *f = (AVVkFrame *)src->data[0];
 AVVulkanDeviceContext *hwctx = hwfc->device_ctx->hwctx;
+AVVulkanFramesContext *hwfctx = hwfc->hwctx;
 const int planes = av_pix_fmt_count_planes(hwfc->sw_format);
 VulkanDevicePriv *p = hwfc->device_ctx->internal->priv;
 FFVulkanFunctions *vk = &p->vkfn;
@@ -2356,7 +2357,9 @@ static int vulkan_map_frame_to_mem(AVHWFramesContext 
*hwfc, AVFrame *dst,
 dst->width  = src->width;
 dst->height = src->height;
 
-for (int i = 0; i < planes; i++) {
+loop = VKF_FLAG(hwfctx->flags, AV_VK_FRAME_FLAG_CONTIGUOUS_MEMORY) ?
+   1 : planes;
+for (int i = 0; i < loop; i++) {
 ret = vk->MapMemory(hwctx->act_dev, f->mem[i], 0,
 VK_WHOLE_SIZE, 0, (void **)&dst->data[i]);
 if (ret != VK_SUCCESS) {
@@ -2367,6 +2370,10 @@ static int vulkan_map_frame_to_mem(AVHWFramesContext 
*hwfc, AVFrame *dst,
 }
 mapped_mem_count++;
 }
+if (VKF_FLAG(hwfctx->flags, AV_VK_FRAME_FLAG_CONTIGUOUS_MEMORY)) {
+for (int i = 0; i < planes; i++)
+dst->data[i] = dst->data[0] + f->offset[i];
+}
 
 /* Check if the memory contents matter */
 if (((flags & AV_HWFRAME_MAP_READ) || !(flags & AV_HWFRAME_MAP_OVERWRITE)) 
&&
-- 
2.25.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH V4 5/5] libavutil/hwcontext_vulkan: specify the modifier to create VKImage

2021-11-29 Thread Wenbin Chen
When vulkan image exports to drm, the tilling need to be
VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT. Now add code to create vulkan
image using this format.

Now the following command line works:

ffmpeg -hwaccel vaapi -hwaccel_device /dev/dri/renderD128 
-hwaccel_output_format \
vaapi -i input_1080p.264 -vf "hwmap=derive_device=vulkan,format=vulkan, \
scale_vulkan=1920:1080,hwmap=derive_device=vaapi,format=vaapi" -c:v h264_vaapi 
output.264

Signed-off-by: Wenbin Chen 
---
 libavutil/hwcontext_vulkan.c | 127 +--
 1 file changed, 121 insertions(+), 6 deletions(-)

diff --git a/libavutil/hwcontext_vulkan.c b/libavutil/hwcontext_vulkan.c
index f980b72720..8224c0d4e4 100644
--- a/libavutil/hwcontext_vulkan.c
+++ b/libavutil/hwcontext_vulkan.c
@@ -120,6 +120,9 @@ typedef struct VulkanFramesPriv {
 /* Image transfers */
 VulkanExecCtx upload_ctx;
 VulkanExecCtx download_ctx;
+
+/*modifier info*/
+VkImageDrmFormatModifierListCreateInfoEXT *modifier_info;
 } VulkanFramesPriv;
 
 typedef struct AVVkFrameInternal {
@@ -242,6 +245,28 @@ const VkFormat *av_vkfmt_from_pixfmt(enum AVPixelFormat p)
 return NULL;
 }
 
+static void *find_in_structure_list(VkBaseOutStructure *stru_list, 
VkStructureType sType) {
+if (!stru_list)
+return NULL;
+
+for(;stru_list;stru_list = stru_list->pNext)
+if (stru_list->sType == sType)
+return stru_list;
+
+return NULL;
+}
+
+static void append_to_structure_list(VkBaseOutStructure **stru_list, 
VkBaseOutStructure *added_stru) {
+VkBaseOutStructure *p;
+if (!*stru_list) {
+*stru_list = added_stru;
+return;
+}
+for(p = *stru_list; p->pNext; p = p->pNext);
+p->pNext = added_stru;
+return;
+}
+
 static int pixfmt_is_supported(AVHWDeviceContext *dev_ctx, enum AVPixelFormat 
p,
int linear)
 {
@@ -2094,6 +2119,10 @@ static void try_export_flags(AVHWFramesContext *hwfc,
 AVVulkanDeviceContext *dev_hwctx = hwfc->device_ctx->hwctx;
 VulkanDevicePriv *p = hwfc->device_ctx->internal->priv;
 FFVulkanFunctions *vk = &p->vkfn;
+const int has_modifiers = hwctx->tiling == 
VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT;
+int loop_count;
+VkImageDrmFormatModifierListCreateInfoEXT *modifier_info = 
find_in_structure_list(hwctx->create_pnext,
+
VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_LIST_CREATE_INFO_EXT);
 VkExternalImageFormatProperties eprops = {
 .sType = VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES_KHR,
 };
@@ -2101,9 +2130,18 @@ static void try_export_flags(AVHWFramesContext *hwfc,
 .sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2,
 .pNext = &eprops,
 };
+VkPhysicalDeviceImageDrmFormatModifierInfoEXT phy_dev_mod_info = {
+.sType = 
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_DRM_FORMAT_MODIFIER_INFO_EXT,
+.pNext = NULL,
+.pQueueFamilyIndices   = p->qfs,
+.queueFamilyIndexCount = p->num_qfs,
+.sharingMode   = p->num_qfs > 1 ? VK_SHARING_MODE_CONCURRENT :
+  VK_SHARING_MODE_EXCLUSIVE,
+};
 VkPhysicalDeviceExternalImageFormatInfo enext = {
 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO,
 .handleType = exp,
+.pNext = has_modifiers && modifier_info ? &phy_dev_mod_info : NULL,
 };
 VkPhysicalDeviceImageFormatInfo2 pinfo = {
 .sType  = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2,
@@ -2115,11 +2153,16 @@ static void try_export_flags(AVHWFramesContext *hwfc,
 .flags  = VK_IMAGE_CREATE_ALIAS_BIT,
 };
 
-ret = vk->GetPhysicalDeviceImageFormatProperties2(dev_hwctx->phys_dev,
-  &pinfo, &props);
-if (ret == VK_SUCCESS) {
-*iexp |= exp;
-*comp_handle_types |= 
eprops.externalMemoryProperties.compatibleHandleTypes;
+loop_count = has_modifiers && modifier_info ? 
modifier_info->drmFormatModifierCount : 1;
+for (int i = 0; i < loop_count; i++) {
+if (has_modifiers && modifier_info)
+phy_dev_mod_info.drmFormatModifier = 
modifier_info->pDrmFormatModifiers[i];
+ret = vk->GetPhysicalDeviceImageFormatProperties2(dev_hwctx->phys_dev,
+&pinfo, &props);
+if (ret == VK_SUCCESS) {
+*iexp |= exp;
+*comp_handle_types |= 
eprops.externalMemoryProperties.compatibleHandleTypes;
+}
 }
 }
 
@@ -2190,6 +2233,12 @@ static void vulkan_frames_uninit(AVHWFramesContext *hwfc)
 {
 VulkanFramesPriv *fp = hwfc->internal->priv;
 
+if (fp->modifier_info) {
+if (fp->modifier_info->pDrmFormatModifiers)
+

[FFmpeg-devel] [PATCH V2 1/3] libavcodec/vaapi_decode: fix the problem that init_pool_size < nb_surface

2021-11-30 Thread Wenbin Chen
For vaapi if the init_pool_size is not zero, the pool size is fixed.
This means max surfaces is init_pool_size, but when mapping vaapi
frame to qsv frame, the init_pool_size < nb_surface. The cause is that
vaapi_decode_make_config() config the init_pool_size and it is called
twice. The first time is to init frame_context and the second time is to
init codec. On the second time the init_pool_size is changed to original
value so the init_pool_size is lower than the reall size because
pool_size used to initialize frame_context need to plus thread_count and
3 (guarantee 4 base work surfaces). Now add code to make sure
init_pool_size is only set once. Now the following commandline works:

ffmpeg -hwaccel vaapi -hwaccel_device /dev/dri/renderD128 \
-hwaccel_output_format vaapi -i input.264 \
-vf "hwmap=derive_device=qsv,format=qsv" \
-c:v h264_qsv output.264

Signed-off-by: Wenbin Chen 
---
 libavcodec/vaapi_decode.c | 34 ++
 1 file changed, 18 insertions(+), 16 deletions(-)

diff --git a/libavcodec/vaapi_decode.c b/libavcodec/vaapi_decode.c
index 665af370ed..aab8162989 100644
--- a/libavcodec/vaapi_decode.c
+++ b/libavcodec/vaapi_decode.c
@@ -572,22 +572,24 @@ static int vaapi_decode_make_config(AVCodecContext *avctx,
 if (err < 0)
 goto fail;
 
-frames->initial_pool_size = 1;
-// Add per-codec number of surfaces used for storing reference frames.
-switch (avctx->codec_id) {
-case AV_CODEC_ID_H264:
-case AV_CODEC_ID_HEVC:
-case AV_CODEC_ID_AV1:
-frames->initial_pool_size += 16;
-break;
-case AV_CODEC_ID_VP9:
-frames->initial_pool_size += 8;
-break;
-case AV_CODEC_ID_VP8:
-frames->initial_pool_size += 3;
-break;
-default:
-frames->initial_pool_size += 2;
+if (!frames->initial_pool_size) {
+frames->initial_pool_size = 1;
+// Add per-codec number of surfaces used for storing reference 
frames.
+switch (avctx->codec_id) {
+case AV_CODEC_ID_H264:
+case AV_CODEC_ID_HEVC:
+case AV_CODEC_ID_AV1:
+frames->initial_pool_size += 16;
+break;
+case AV_CODEC_ID_VP9:
+frames->initial_pool_size += 8;
+break;
+case AV_CODEC_ID_VP8:
+frames->initial_pool_size += 3;
+break;
+default:
+frames->initial_pool_size += 2;
+}
 }
 }
 
-- 
2.25.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH V2 2/3] libavutil/hwcontext_qsv: fix a bug for mapping vaapi frame to qsv

2021-11-30 Thread Wenbin Chen
From: nyanmisaka 

The data stored in data[3] in VAAPI AVFrame is VASurfaceID while
the data stored in pair->first is the pointer of VASurfaceID, so
we need to do cast to make following commandline works:

ffmpeg -hwaccel vaapi -hwaccel_device /dev/dri/renderD128 \
-hwaccel_output_format vaapi -i input.264 \
-vf "hwmap=derive_device=qsv,format=qsv" -c:v h264_qsv output.264

Signed-off-by: nyanmisaka 
Signed-off-by: Wenbin Chen 
---
 libavutil/hwcontext_qsv.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libavutil/hwcontext_qsv.c b/libavutil/hwcontext_qsv.c
index 268be9f8a1..a5d154a24d 100644
--- a/libavutil/hwcontext_qsv.c
+++ b/libavutil/hwcontext_qsv.c
@@ -1218,7 +1218,7 @@ static int qsv_map_to(AVHWFramesContext *dst_ctx,
 case AV_PIX_FMT_VAAPI:
 {
 mfxHDLPair *pair = (mfxHDLPair*)hwctx->surfaces[i].Data.MemId;
-if (pair->first == src->data[3]) {
+if (*(VASurfaceID*)pair->first == (VASurfaceID)src->data[3]) {
 index = i;
 break;
 }
-- 
2.25.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH V2 3/3] libavutil/hwcontext_opencl: fix a bug for mapping qsv frame to opencl

2021-11-30 Thread Wenbin Chen
From: nyanmisaka 

mfxHDLPair was added to qsv, so modify qsv->opencl map function as well.
Now the following commandline works:

ffmpeg -v verbose -init_hw_device vaapi=va:/dev/dri/renderD128 \
-init_hw_device qsv=qs@va -init_hw_device opencl=ocl@va -filter_hw_device ocl \
-hwaccel qsv -hwaccel_output_format qsv -hwaccel_device qs -c:v h264_qsv \
-i input.264 -vf "hwmap=derive_device=opencl,format=opencl,avgblur_opencl, \
hwmap=derive_device=qsv:reverse=1:extra_hw_frames=32,format=qsv" \
-c:v h264_qsv output.264

Signed-off-by: nyanmisaka 
Signed-off-by: Wenbin Chen 
---
 libavutil/hwcontext_opencl.c | 3 ++-
 libavutil/hwcontext_qsv.h| 5 +
 2 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/libavutil/hwcontext_opencl.c b/libavutil/hwcontext_opencl.c
index 26a3a24593..ab812999cd 100644
--- a/libavutil/hwcontext_opencl.c
+++ b/libavutil/hwcontext_opencl.c
@@ -48,6 +48,7 @@
 #if HAVE_OPENCL_VAAPI_INTEL_MEDIA
 #if CONFIG_LIBMFX
 #include 
+#include "hwcontext_qsv.h"
 #endif
 #include 
 #include 
@@ -2249,7 +2250,7 @@ static int opencl_map_from_qsv(AVHWFramesContext *dst_fc, 
AVFrame *dst,
 #if CONFIG_LIBMFX
 if (src->format == AV_PIX_FMT_QSV) {
 mfxFrameSurface1 *mfx_surface = (mfxFrameSurface1*)src->data[3];
-va_surface = *(VASurfaceID*)mfx_surface->Data.MemId;
+va_surface = *MFXSURFACEP_TO_VASURFACEP(mfx_surface);
 } else
 #endif
 if (src->format == AV_PIX_FMT_VAAPI) {
diff --git a/libavutil/hwcontext_qsv.h b/libavutil/hwcontext_qsv.h
index b98d611cfc..957df01ef1 100644
--- a/libavutil/hwcontext_qsv.h
+++ b/libavutil/hwcontext_qsv.h
@@ -29,6 +29,11 @@
  * contain AVBufferRefs whose data pointer points to an mfxFrameSurface1 
struct.
  */
 
+#if CONFIG_VAAPI
+#define MFXSURFACEP_TO_VASURFACEP(surf) \
+(VASurfaceID*)(((mfxHDLPair*)surf->Data.MemId)->first)
+#endif
+
 /**
  * This struct is allocated as AVHWDeviceContext.hwctx
  */
-- 
2.25.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH V5 1/5] hwcontext_vaapi: Use PRIME_2 memory type for modifiers.

2021-12-01 Thread Wenbin Chen
From: Bas Nieuwenhuizen 

This way we can pass explicit modifiers in. Sometimes the
modifier matters for the number of memory planes that
libva accepts, in particular when dealing with
driver-compressed textures. Furthermore the driver might
not actually be able to determine the implicit modifier
if all the buffer-passing has used explicit modifier.
All these issues should be resolved by passing in the
modifier, and for that we switch to using the PRIME_2
memory type.

Tested with experimental radeonsi patches for modifiers
and kmsgrab. Also tested with radeonsi without the
patches to double-check it works without PRIME_2 support.

v2:
  Cache PRIME_2 support to avoid doing two calls every time on
  libva drivers that do not support it.

v3:
  Remove prime2_vas usage.

Signed-off-by: Bas Nieuwenhuizen 
---
 libavutil/hwcontext_vaapi.c | 158 ++--
 1 file changed, 114 insertions(+), 44 deletions(-)

diff --git a/libavutil/hwcontext_vaapi.c b/libavutil/hwcontext_vaapi.c
index 83e542876d..75acc851d6 100644
--- a/libavutil/hwcontext_vaapi.c
+++ b/libavutil/hwcontext_vaapi.c
@@ -79,6 +79,9 @@ typedef struct VAAPIFramesContext {
 unsigned int rt_format;
 // Whether vaDeriveImage works.
 int derive_works;
+// Caches whether VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_2 is unsupported for
+// surface imports.
+int prime_2_import_unsupported;
 } VAAPIFramesContext;
 
 typedef struct VAAPIMapping {
@@ -1022,32 +1025,17 @@ static void vaapi_unmap_from_drm(AVHWFramesContext 
*dst_fc,
 static int vaapi_map_from_drm(AVHWFramesContext *src_fc, AVFrame *dst,
   const AVFrame *src, int flags)
 {
+VAAPIFramesContext *src_vafc = src_fc->internal->priv;
 AVHWFramesContext  *dst_fc =
 (AVHWFramesContext*)dst->hw_frames_ctx->data;
 AVVAAPIDeviceContext  *dst_dev = dst_fc->device_ctx->hwctx;
 const AVDRMFrameDescriptor *desc;
 const VAAPIFormatDescriptor *format_desc;
 VASurfaceID surface_id;
-VAStatus vas;
+VAStatus vas = VA_STATUS_SUCCESS;
+int use_prime2;
 uint32_t va_fourcc;
-int err, i, j, k;
-
-unsigned long buffer_handle;
-VASurfaceAttribExternalBuffers buffer_desc;
-VASurfaceAttrib attrs[2] = {
-{
-.type  = VASurfaceAttribMemoryType,
-.flags = VA_SURFACE_ATTRIB_SETTABLE,
-.value.type= VAGenericValueTypeInteger,
-.value.value.i = VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME,
-},
-{
-.type  = VASurfaceAttribExternalBufferDescriptor,
-.flags = VA_SURFACE_ATTRIB_SETTABLE,
-.value.type= VAGenericValueTypePointer,
-.value.value.p = &buffer_desc,
-}
-};
+int err, i, j;
 
 desc = (AVDRMFrameDescriptor*)src->data[0];
 
@@ -1083,35 +1071,117 @@ static int vaapi_map_from_drm(AVHWFramesContext 
*src_fc, AVFrame *dst,
 format_desc = vaapi_format_from_fourcc(va_fourcc);
 av_assert0(format_desc);
 
-buffer_handle = desc->objects[0].fd;
-buffer_desc.pixel_format = va_fourcc;
-buffer_desc.width= src_fc->width;
-buffer_desc.height   = src_fc->height;
-buffer_desc.data_size= desc->objects[0].size;
-buffer_desc.buffers  = &buffer_handle;
-buffer_desc.num_buffers  = 1;
-buffer_desc.flags= 0;
-
-k = 0;
-for (i = 0; i < desc->nb_layers; i++) {
-for (j = 0; j < desc->layers[i].nb_planes; j++) {
-buffer_desc.pitches[k] = desc->layers[i].planes[j].pitch;
-buffer_desc.offsets[k] = desc->layers[i].planes[j].offset;
-++k;
+use_prime2 = !src_vafc->prime_2_import_unsupported &&
+ desc->objects[0].format_modifier != DRM_FORMAT_MOD_INVALID;
+if (use_prime2) {
+VADRMPRIMESurfaceDescriptor prime_desc;
+VASurfaceAttrib prime_attrs[2] = {
+{
+.type  = VASurfaceAttribMemoryType,
+.flags = VA_SURFACE_ATTRIB_SETTABLE,
+.value.type= VAGenericValueTypeInteger,
+.value.value.i = VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_2,
+},
+{
+.type  = VASurfaceAttribExternalBufferDescriptor,
+.flags = VA_SURFACE_ATTRIB_SETTABLE,
+.value.type= VAGenericValueTypePointer,
+.value.value.p = &prime_desc,
+}
+};
+prime_desc.fourcc = va_fourcc;
+prime_desc.width = src_fc->width;
+prime_desc.height = src_fc->height;
+prime_desc.num_objects = desc->nb_objects;
+for (i = 0; i < desc->nb_objects; ++i) {
+prime_desc.objects[i].fd = desc->objects[i].fd;
+prime_desc.objects[i].size = desc->objects[i].size;
+prime_desc.objects[i].drm_format_modifier =
+desc->objects[i].format_modifier;
 }
-}
-buffer_desc.num_planes = k;
 
-if (format_desc->chroma_planes

[FFmpeg-devel] [PATCH V5 2/5] libavutil/hwcontext_vaapi: Add a new nv12 format map to support vulkan frame

2021-12-01 Thread Wenbin Chen
Vulkan will map nv12 to R8 and GR88, so add this map to vaapi to support
vulkan frame.

Signed-off-by: Wenbin Chen 
---
 libavutil/hwcontext_vaapi.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/libavutil/hwcontext_vaapi.c b/libavutil/hwcontext_vaapi.c
index 75acc851d6..994b744e4d 100644
--- a/libavutil/hwcontext_vaapi.c
+++ b/libavutil/hwcontext_vaapi.c
@@ -992,6 +992,7 @@ static const struct {
 } vaapi_drm_format_map[] = {
 #ifdef DRM_FORMAT_R8
 DRM_MAP(NV12, 2, DRM_FORMAT_R8,  DRM_FORMAT_RG88),
+DRM_MAP(NV12, 2, DRM_FORMAT_R8,  DRM_FORMAT_GR88),
 #endif
 DRM_MAP(NV12, 1, DRM_FORMAT_NV12),
 #if defined(VA_FOURCC_P010) && defined(DRM_FORMAT_R16)
-- 
2.25.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH V5 3/5] libavutil/hwcontext_vulkan: Allocate vkFrame in one memory

2021-12-01 Thread Wenbin Chen
The vaapi can import external frame, but the planes of the external
frames should be in the same drm object. A new option "contiguous_planes"
is added to device. This flag tells device to allocate places in one
memory. When device is derived from vaapi this flag will be enabled.
A new flag frame_flag is also added to AVVulkanFramesContext. User
can use this flag to force enable or disable this behaviour.
A new variable "offset "is added to AVVKFrame. It describe describe the
offset from the memory currently bound to the VkImage.

Signed-off-by: Wenbin Chen 
---
 libavutil/hwcontext_vulkan.c | 68 +++-
 libavutil/hwcontext_vulkan.h | 24 +
 2 files changed, 91 insertions(+), 1 deletion(-)

diff --git a/libavutil/hwcontext_vulkan.c b/libavutil/hwcontext_vulkan.c
index a0437c9661..eef9009ae1 100644
--- a/libavutil/hwcontext_vulkan.c
+++ b/libavutil/hwcontext_vulkan.c
@@ -103,8 +103,14 @@ typedef struct VulkanDevicePriv {
 /* Settings */
 int use_linear_images;
 
+/* allocate planes in a contiguous memory */
+int contiguous_planes;
+
 /* Nvidia */
 int dev_is_nvidia;
+
+/* Intel */
+int dev_is_intel;
 } VulkanDevicePriv;
 
 typedef struct VulkanFramesPriv {
@@ -153,6 +159,8 @@ typedef struct AVVkFrameInternal {
 av_free((void *)props);
\
 }
 
+#define VKF_FLAG(x, f) (((x) & (~AV_VK_FRAME_FLAG_NONE)) & (f))
+
 static const struct {
 enum AVPixelFormat pixfmt;
 const VkFormat vkfmts[4];
@@ -1374,6 +1382,13 @@ static int 
vulkan_device_create_internal(AVHWDeviceContext *ctx,
 if (opt_d)
 p->use_linear_images = strtol(opt_d->value, NULL, 10);
 
+opt_d = av_dict_get(opts, "contiguous_planes", NULL, 0);
+if (opt_d)
+p->contiguous_planes = strtol(opt_d->value, NULL, 10);
+else
+p->contiguous_planes = -1;
+
+
 hwctx->enabled_dev_extensions = dev_info.ppEnabledExtensionNames;
 hwctx->nb_enabled_dev_extensions = dev_info.enabledExtensionCount;
 
@@ -1425,6 +1440,8 @@ static int vulkan_device_init(AVHWDeviceContext *ctx)
 
 p->dev_is_nvidia = (p->props.properties.vendorID == 0x10de);
 
+p->dev_is_intel = (p->props.properties.vendorID == 0x8086);
+
 vk->GetPhysicalDeviceQueueFamilyProperties(hwctx->phys_dev, &queue_num, 
NULL);
 if (!queue_num) {
 av_log(ctx, AV_LOG_ERROR, "Failed to get queues!\n");
@@ -1742,8 +1759,12 @@ static int alloc_bind_mem(AVHWFramesContext *hwfc, 
AVVkFrame *f,
 AVHWDeviceContext *ctx = hwfc->device_ctx;
 VulkanDevicePriv *p = ctx->internal->priv;
 FFVulkanFunctions *vk = &p->vkfn;
+AVVulkanFramesContext *hwfctx = hwfc->hwctx;
 const int planes = av_pix_fmt_count_planes(hwfc->sw_format);
 VkBindImageMemoryInfo bind_info[AV_NUM_DATA_POINTERS] = { { 0 } };
+VkMemoryRequirements memory_requirements = { 0 };
+int mem_size = 0;
+int mem_size_list[AV_NUM_DATA_POINTERS] = { 0 };
 
 AVVulkanDeviceContext *hwctx = ctx->hwctx;
 
@@ -1771,6 +1792,19 @@ static int alloc_bind_mem(AVHWFramesContext *hwfc, 
AVVkFrame *f,
 req.memoryRequirements.size = FFALIGN(req.memoryRequirements.size,
   
p->props.properties.limits.minMemoryMapAlignment);
 
+if (VKF_FLAG(hwfctx->flags, AV_VK_FRAME_FLAG_CONTIGUOUS_MEMORY)) {
+if (memory_requirements.size == 0) {
+memory_requirements = req.memoryRequirements;
+} else if (memory_requirements.memoryTypeBits != 
req.memoryRequirements.memoryTypeBits) {
+av_log(hwfc, AV_LOG_ERROR, "the param for each planes are not 
the same\n");
+return AVERROR(EINVAL);
+}
+
+mem_size_list[i] = req.memoryRequirements.size;
+mem_size += mem_size_list[i];
+continue;
+}
+
 /* In case the implementation prefers/requires dedicated allocation */
 use_ded_mem = ded_req.prefersDedicatedAllocation |
   ded_req.requiresDedicatedAllocation;
@@ -1792,6 +1826,29 @@ static int alloc_bind_mem(AVHWFramesContext *hwfc, 
AVVkFrame *f,
 bind_info[i].memory = f->mem[i];
 }
 
+if (VKF_FLAG(hwfctx->flags, AV_VK_FRAME_FLAG_CONTIGUOUS_MEMORY)) {
+memory_requirements.size = mem_size;
+
+/* Allocate memory */
+if ((err = alloc_mem(ctx, &memory_requirements,
+f->tiling == VK_IMAGE_TILING_LINEAR ?
+VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT :
+VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
+(void *)(((uint8_t *)alloc_pnext)),
+&f->flags, &f->mem[0])))
+return err;
+
+f

[FFmpeg-devel] [PATCH V5 4/5] libavutil/hwcontext_vulkan: Add support to hwmap to software frame when using contiguous_planes flag.

2021-12-01 Thread Wenbin Chen
Add support to map vulkan frames to software frames when
using contiguous_planes flag.

Signed-off-by: Wenbin Chen 
---
 libavutil/hwcontext_vulkan.c | 11 +--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/libavutil/hwcontext_vulkan.c b/libavutil/hwcontext_vulkan.c
index eef9009ae1..f980b72720 100644
--- a/libavutil/hwcontext_vulkan.c
+++ b/libavutil/hwcontext_vulkan.c
@@ -2327,9 +2327,10 @@ static int vulkan_map_frame_to_mem(AVHWFramesContext 
*hwfc, AVFrame *dst,
const AVFrame *src, int flags)
 {
 VkResult ret;
-int err, mapped_mem_count = 0;
+int err, mapped_mem_count = 0, loop = 0;
 AVVkFrame *f = (AVVkFrame *)src->data[0];
 AVVulkanDeviceContext *hwctx = hwfc->device_ctx->hwctx;
+AVVulkanFramesContext *hwfctx = hwfc->hwctx;
 const int planes = av_pix_fmt_count_planes(hwfc->sw_format);
 VulkanDevicePriv *p = hwfc->device_ctx->internal->priv;
 FFVulkanFunctions *vk = &p->vkfn;
@@ -2356,7 +2357,9 @@ static int vulkan_map_frame_to_mem(AVHWFramesContext 
*hwfc, AVFrame *dst,
 dst->width  = src->width;
 dst->height = src->height;
 
-for (int i = 0; i < planes; i++) {
+loop = VKF_FLAG(hwfctx->flags, AV_VK_FRAME_FLAG_CONTIGUOUS_MEMORY) ?
+   1 : planes;
+for (int i = 0; i < loop; i++) {
 ret = vk->MapMemory(hwctx->act_dev, f->mem[i], 0,
 VK_WHOLE_SIZE, 0, (void **)&dst->data[i]);
 if (ret != VK_SUCCESS) {
@@ -2367,6 +2370,10 @@ static int vulkan_map_frame_to_mem(AVHWFramesContext 
*hwfc, AVFrame *dst,
 }
 mapped_mem_count++;
 }
+if (VKF_FLAG(hwfctx->flags, AV_VK_FRAME_FLAG_CONTIGUOUS_MEMORY)) {
+for (int i = 0; i < planes; i++)
+dst->data[i] = dst->data[0] + f->offset[i];
+}
 
 /* Check if the memory contents matter */
 if (((flags & AV_HWFRAME_MAP_READ) || !(flags & AV_HWFRAME_MAP_OVERWRITE)) 
&&
-- 
2.25.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH V5 5/5] libavutil/hwcontext_vulkan: specify the modifier to create VKImage

2021-12-01 Thread Wenbin Chen
When vulkan image exports to drm, the tilling need to be
VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT. Now add code to create vulkan
image using this format.

Now the following command line works:

ffmpeg -hwaccel vaapi -hwaccel_device /dev/dri/renderD128 
-hwaccel_output_format \
vaapi -i input_1080p.264 -vf "hwmap=derive_device=vulkan,format=vulkan, \
scale_vulkan=1920:1080,hwmap=derive_device=vaapi,format=vaapi" -c:v h264_vaapi 
output.264

Signed-off-by: Wenbin Chen 
---
 libavutil/hwcontext_vulkan.c | 127 +--
 1 file changed, 121 insertions(+), 6 deletions(-)

diff --git a/libavutil/hwcontext_vulkan.c b/libavutil/hwcontext_vulkan.c
index f980b72720..8224c0d4e4 100644
--- a/libavutil/hwcontext_vulkan.c
+++ b/libavutil/hwcontext_vulkan.c
@@ -120,6 +120,9 @@ typedef struct VulkanFramesPriv {
 /* Image transfers */
 VulkanExecCtx upload_ctx;
 VulkanExecCtx download_ctx;
+
+/*modifier info*/
+VkImageDrmFormatModifierListCreateInfoEXT *modifier_info;
 } VulkanFramesPriv;
 
 typedef struct AVVkFrameInternal {
@@ -242,6 +245,28 @@ const VkFormat *av_vkfmt_from_pixfmt(enum AVPixelFormat p)
 return NULL;
 }
 
+static void *find_in_structure_list(VkBaseOutStructure *stru_list, 
VkStructureType sType) {
+if (!stru_list)
+return NULL;
+
+for(;stru_list;stru_list = stru_list->pNext)
+if (stru_list->sType == sType)
+return stru_list;
+
+return NULL;
+}
+
+static void append_to_structure_list(VkBaseOutStructure **stru_list, 
VkBaseOutStructure *added_stru) {
+VkBaseOutStructure *p;
+if (!*stru_list) {
+*stru_list = added_stru;
+return;
+}
+for(p = *stru_list; p->pNext; p = p->pNext);
+p->pNext = added_stru;
+return;
+}
+
 static int pixfmt_is_supported(AVHWDeviceContext *dev_ctx, enum AVPixelFormat 
p,
int linear)
 {
@@ -2094,6 +2119,10 @@ static void try_export_flags(AVHWFramesContext *hwfc,
 AVVulkanDeviceContext *dev_hwctx = hwfc->device_ctx->hwctx;
 VulkanDevicePriv *p = hwfc->device_ctx->internal->priv;
 FFVulkanFunctions *vk = &p->vkfn;
+const int has_modifiers = hwctx->tiling == 
VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT;
+int loop_count;
+VkImageDrmFormatModifierListCreateInfoEXT *modifier_info = 
find_in_structure_list(hwctx->create_pnext,
+
VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_LIST_CREATE_INFO_EXT);
 VkExternalImageFormatProperties eprops = {
 .sType = VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES_KHR,
 };
@@ -2101,9 +2130,18 @@ static void try_export_flags(AVHWFramesContext *hwfc,
 .sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2,
 .pNext = &eprops,
 };
+VkPhysicalDeviceImageDrmFormatModifierInfoEXT phy_dev_mod_info = {
+.sType = 
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_DRM_FORMAT_MODIFIER_INFO_EXT,
+.pNext = NULL,
+.pQueueFamilyIndices   = p->qfs,
+.queueFamilyIndexCount = p->num_qfs,
+.sharingMode   = p->num_qfs > 1 ? VK_SHARING_MODE_CONCURRENT :
+  VK_SHARING_MODE_EXCLUSIVE,
+};
 VkPhysicalDeviceExternalImageFormatInfo enext = {
 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO,
 .handleType = exp,
+.pNext = has_modifiers && modifier_info ? &phy_dev_mod_info : NULL,
 };
 VkPhysicalDeviceImageFormatInfo2 pinfo = {
 .sType  = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2,
@@ -2115,11 +2153,16 @@ static void try_export_flags(AVHWFramesContext *hwfc,
 .flags  = VK_IMAGE_CREATE_ALIAS_BIT,
 };
 
-ret = vk->GetPhysicalDeviceImageFormatProperties2(dev_hwctx->phys_dev,
-  &pinfo, &props);
-if (ret == VK_SUCCESS) {
-*iexp |= exp;
-*comp_handle_types |= 
eprops.externalMemoryProperties.compatibleHandleTypes;
+loop_count = has_modifiers && modifier_info ? 
modifier_info->drmFormatModifierCount : 1;
+for (int i = 0; i < loop_count; i++) {
+if (has_modifiers && modifier_info)
+phy_dev_mod_info.drmFormatModifier = 
modifier_info->pDrmFormatModifiers[i];
+ret = vk->GetPhysicalDeviceImageFormatProperties2(dev_hwctx->phys_dev,
+&pinfo, &props);
+if (ret == VK_SUCCESS) {
+*iexp |= exp;
+*comp_handle_types |= 
eprops.externalMemoryProperties.compatibleHandleTypes;
+}
 }
 }
 
@@ -2190,6 +2233,12 @@ static void vulkan_frames_uninit(AVHWFramesContext *hwfc)
 {
 VulkanFramesPriv *fp = hwfc->internal->priv;
 
+if (fp->modifier_info) {
+if (fp->modifier_info->pDrmFormatModifiers)
+

[FFmpeg-devel] [PATCH] libavutil/hwcontext_qsv: clean padding when upload qsv frames

2021-12-01 Thread Wenbin Chen
When we upload a frame that is not padded as MSDK requires, we create a
new AVFrame to copy data. The frame's padding data is uninitialized so
it brings run to run problem. For example, If we run the following
command serveral times we will get different outputs.

ffmpeg -init_hw_device qsv=qsv:hw -qsv_device /dev/dri/renderD128
-filter_hw_device qsv -f rawvideo -s 192x200 -pix_fmt p010
-i 192x200_P010.yuv -vf "format=nv12,hwupload=extra_hw_frames=16"
-c:v hevc_qsv output.265

According to 
https://github.com/Intel-Media-SDK/MediaSDK/blob/master/doc/mediasdk-man.md#encoding-procedures
"Note: It is the application's responsibility to fill pixels outside
of crop window when it is smaller than frame to be encoded. Especially
in cases when crops are not aligned to minimum coding block size (16
for AVC, 8 for HEVC and VP9)"

I add a function to fill padding area with border pixel to fix this
run2run problem, and also move the new AVFrame to global structure
to reduce redundant allocation operation to increase preformance.

Signed-off-by: Wenbin Chen 
---
 libavutil/hwcontext_qsv.c | 96 +--
 1 file changed, 83 insertions(+), 13 deletions(-)

diff --git a/libavutil/hwcontext_qsv.c b/libavutil/hwcontext_qsv.c
index 268be9f8a1..983494666b 100644
--- a/libavutil/hwcontext_qsv.c
+++ b/libavutil/hwcontext_qsv.c
@@ -47,6 +47,7 @@
 #include "pixfmt.h"
 #include "pixdesc.h"
 #include "time.h"
+#include "imgutils.h"
 
 #define QSV_VERSION_ATLEAST(MAJOR, MINOR)   \
 (MFX_VERSION_MAJOR > (MAJOR) || \
@@ -90,6 +91,7 @@ typedef struct QSVFramesContext {
 
 mfxExtOpaqueSurfaceAlloc opaque_alloc;
 mfxExtBuffer *ext_buffers[1];
+AVFrame realigned_tmp_frame;
 } QSVFramesContext;
 
 static const struct {
@@ -137,6 +139,54 @@ static uint32_t qsv_get_d3d11va_bind_flags(int mem_type)
 }
 #endif
 
+static int qsv_fill_border(AVFrame *dst, const AVFrame *src)
+{
+const AVPixFmtDescriptor *desc;
+int i, planes_nb = 0;
+if (dst->format != src->format)
+return AVERROR(EINVAL);
+
+desc = av_pix_fmt_desc_get(dst->format);
+
+for (i = 0; i < desc->nb_components; i++)
+planes_nb = FFMAX(planes_nb, desc->comp[i].plane + 1);
+
+for (i = 0; i < planes_nb; i++) {
+int sheight, dheight, y;
+ptrdiff_t swidth = av_image_get_linesize(src->format,
+ src->width,
+ i);
+ptrdiff_t dwidth = av_image_get_linesize(dst->format,
+ dst->width,
+ i);
+const AVComponentDescriptor comp = desc->comp[i];
+if (swidth < 0 || dwidth < 0) {
+av_log(NULL, AV_LOG_ERROR, "av_image_get_linesize failed\n");
+return AVERROR(EINVAL);
+}
+sheight = src->height;
+dheight = dst->height;
+if (i) {
+sheight = AV_CEIL_RSHIFT(src->height, desc->log2_chroma_h);
+dheight = AV_CEIL_RSHIFT(dst->height, desc->log2_chroma_h);
+}
+//fill right padding
+for (y = 0; y < sheight; y++) {
+void *line_ptr = dst->data[i] + y*dst->linesize[i] + swidth;
+av_memcpy_backptr(line_ptr,
+   comp.depth > 8 ? 2 : 1,
+   dwidth - swidth);
+}
+//fill bottom padding
+for (y = sheight; y < dheight; y++) {
+memcpy(dst->data[i]+y*dst->linesize[i],
+   dst->data[i]+(sheight-1)*dst->linesize[i],
+   dwidth);
+}
+}
+return 0;
+}
+
 static int qsv_device_init(AVHWDeviceContext *ctx)
 {
 AVQSVDeviceContext *hwctx = ctx->hwctx;
@@ -220,6 +270,7 @@ static void qsv_frames_uninit(AVHWFramesContext *ctx)
 av_freep(&s->surface_ptrs);
 av_freep(&s->surfaces_internal);
 av_freep(&s->handle_pairs_internal);
+av_frame_unref(&s->realigned_tmp_frame);
 av_buffer_unref(&s->child_frames_ref);
 }
 
@@ -1014,12 +1065,13 @@ static int qsv_transfer_data_to(AVHWFramesContext *ctx, 
AVFrame *dst,
 QSVFramesContext   *s = ctx->internal->priv;
 mfxFrameSurface1   in = {{ 0 }};
 mfxFrameSurface1 *out = (mfxFrameSurface1*)dst->data[3];
+mfxFrameInfo tmp_info;
 
 mfxSyncPoint sync = NULL;
 mfxStatus err;
 int ret = 0;
 /* make a copy if the input is not padded as libmfx requires */
-AVFrame tmp_frame;
+AVFrame *tmp_frame = &s->realigned_tmp_frame;
 const AVFrame *src_frame;
 int realigned = 0;
 
@@ -1048,24 +1100,40 @@ static int qsv_transfer_data_to(AVHWFramesContext *ctx, 
AVFrame *dst,
 if (ret < 0)
 return ret;
 
+/* According to MSDK spec

[FFmpeg-devel] [PATCH] libavcodec/qsvdec: skip non-key frame after "seek" function

2021-02-18 Thread wenbin . chen
From: "Chen,Wenbin" 

Fix #9095. Qsv decoder assume that after calling seek funcion, the first
frame should be key frame. However this is not true for some videos. If
the frame is not key frame after seek(), there will be error. Conditional
statements are added to skip these frame until reading a key frame.

Signed-off-by: Wenbin Chen 
---
 libavcodec/qsvdec.c | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/libavcodec/qsvdec.c b/libavcodec/qsvdec.c
index d10f90a0db..8133406085 100644
--- a/libavcodec/qsvdec.c
+++ b/libavcodec/qsvdec.c
@@ -616,6 +616,13 @@ int ff_qsv_process_data(AVCodecContext *avctx, QSVContext 
*q,
 }
 
 if (!q->initialized) {
+
+/*  skip non-key frame when decoder is reinitialized. 
+Adding before will skip all the non-key frames so add 
+it here */
+if (ret < 0)
+return ret;
+
 ret = qsv_decode_init_context(avctx, q, ¶m);
 if (ret < 0)
 goto reinit_fail;
-- 
2.25.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

[FFmpeg-devel] [PATCH] libavcodec/vaapi_encode: Change libva call to async way

2021-03-07 Thread wenbin . chen
From: "Chen,Wenbin" 

Fix: #7706. After commit 5fdcf85bbffe7451c2, vaapi encoder's performance
drop 20~30%. One reason is that vaRenderPicture() and vaSyncSurface() are
called at the same time (vaRenderPicture() always followed by a
vaSyncSurface()). Now I changed them to be called in a
asynchronous way, which will make better use of hardware.

Another reason of performance drop is that in old version, ffmpeg-vaapi
use CQP as default while the ffmpeg-vaapi of lastest version does not,
so the same command line will have a even bigger performance gap. To
test this patch you'd better specify the bitrate (-b:v XXX).

Signed-off-by: Wenbin CHEN 
---
 libavcodec/vaapi_encode.c | 42 +--
 libavcodec/vaapi_encode.h |  3 +++
 2 files changed, 34 insertions(+), 11 deletions(-)

diff --git a/libavcodec/vaapi_encode.c b/libavcodec/vaapi_encode.c
index 518e5b2c00..851dea3fc2 100644
--- a/libavcodec/vaapi_encode.c
+++ b/libavcodec/vaapi_encode.c
@@ -950,8 +950,10 @@ static int vaapi_encode_pick_next(AVCodecContext *avctx,
 if (!pic && ctx->end_of_stream) {
 --b_counter;
 pic = ctx->pic_end;
-if (pic->encode_issued)
+if (pic->encode_complete)
 return AVERROR_EOF;
+else if (pic->encode_issued)
+return AVERROR(EAGAIN);
 }
 
 if (!pic) {
@@ -1176,20 +1178,34 @@ int ff_vaapi_encode_receive_packet(AVCodecContext 
*avctx, AVPacket *pkt)
 return AVERROR(EAGAIN);
 }
 
-pic = NULL;
-err = vaapi_encode_pick_next(avctx, &pic);
-if (err < 0)
-return err;
-av_assert0(pic);
+if (av_fifo_size(ctx->encode_fifo) == 0) {
+while (!err) {
+pic = NULL;
+err = vaapi_encode_pick_next(avctx, &pic);
+if (err == AVERROR(EAGAIN))
+break;
+else if (err < 0)
+return err;
+av_assert0(pic);
 
-pic->encode_order = ctx->encode_order++;
+pic->encode_order = ctx->encode_order++;
 
-err = vaapi_encode_issue(avctx, pic);
-if (err < 0) {
-av_log(avctx, AV_LOG_ERROR, "Encode failed: %d.\n", err);
-return err;
+err = vaapi_encode_issue(avctx, pic);
+if (err < 0) {
+av_log(avctx, AV_LOG_ERROR, "Encode failed: %d.\n", err);
+return err;
+}
+
+av_fifo_generic_write(ctx->encode_fifo, &pic, sizeof(pic), NULL);
+}
 }
 
+if (av_fifo_size(ctx->encode_fifo) == 0)
+return err;
+
+av_fifo_generic_read(ctx->encode_fifo, &pic, sizeof(pic), NULL);
+ctx->encode_order = pic->encode_order+1;
+
 err = vaapi_encode_output(avctx, pic, pkt);
 if (err < 0) {
 av_log(avctx, AV_LOG_ERROR, "Output failed: %d.\n", err);
@@ -2519,6 +2535,10 @@ av_cold int ff_vaapi_encode_init(AVCodecContext *avctx)
 }
 }
 
+ctx->encode_fifo = av_fifo_alloc((MAX_PICTURE_REFERENCES+1)* 
sizeof(VAAPIEncodePicture *));
+if (!ctx->encode_fifo)
+return AVERROR(ENOMEM);
+
 return 0;
 
 fail:
diff --git a/libavcodec/vaapi_encode.h b/libavcodec/vaapi_encode.h
index b41604a883..89fe8de466 100644
--- a/libavcodec/vaapi_encode.h
+++ b/libavcodec/vaapi_encode.h
@@ -29,6 +29,7 @@
 
 #include "libavutil/hwcontext.h"
 #include "libavutil/hwcontext_vaapi.h"
+#include "libavutil/fifo.h"
 
 #include "avcodec.h"
 #include "hwconfig.h"
@@ -345,6 +346,8 @@ typedef struct VAAPIEncodeContext {
 int roi_warned;
 
 AVFrame *frame;
+
+AVFifoBuffer *encode_fifo;
 } VAAPIEncodeContext;
 
 enum {
-- 
2.25.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

[FFmpeg-devel] [PATCH] libavcodec/qsvdec.c: using queue count to unref frame

2021-03-10 Thread wenbin . chen
From: "Chen,Wenbin" 

MSDK vc1 and av1 sometimes output frame into the same suface, but
ffmpeg-qsv assume the surface will be used only once, so it will
unref the frame when it receives the outpur surface. Now change
it to unref frame according to queue count.

Signed-off-by Wenbin Chen 
---
 libavcodec/qsvdec.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/libavcodec/qsvdec.c b/libavcodec/qsvdec.c
index d10f90a0db..e073e10699 100644
--- a/libavcodec/qsvdec.c
+++ b/libavcodec/qsvdec.c
@@ -470,7 +470,7 @@ static int qsv_decode(AVCodecContext *avctx, QSVContext *q,
 return AVERROR_BUG;
 }
 
-out_frame->queued = 1;
+out_frame->queued += 1;
 av_fifo_generic_write(q->async_fifo, &out_frame, sizeof(out_frame), 
NULL);
 av_fifo_generic_write(q->async_fifo, &sync,  sizeof(sync),  
NULL);
 } else {
@@ -483,7 +483,7 @@ static int qsv_decode(AVCodecContext *avctx, QSVContext *q,
 
 av_fifo_generic_read(q->async_fifo, &out_frame, sizeof(out_frame), 
NULL);
 av_fifo_generic_read(q->async_fifo, &sync,  sizeof(sync),  
NULL);
-out_frame->queued = 0;
+out_frame->queued -= 1;
 
 if (avctx->pix_fmt != AV_PIX_FMT_QSV) {
 do {
-- 
2.25.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

[FFmpeg-devel] [PATCH V2] libavcodec/qsvdec.c: using queue count to unref frame

2021-03-11 Thread wenbin . chen
From: "Chen,Wenbin" 

MSDK vc1 and av1 sometimes output frame into the same suface, but
ffmpeg-qsv assume the surface will be used only once, so it will
unref the frame when it receives the output surface. Now change
it to unref frame according to queue count.

Signed-off-by Wenbin Chen 
---
 libavcodec/qsvdec.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/libavcodec/qsvdec.c b/libavcodec/qsvdec.c
index 5f2e641373..3abd7bd4a2 100644
--- a/libavcodec/qsvdec.c
+++ b/libavcodec/qsvdec.c
@@ -513,7 +513,7 @@ static int qsv_decode(AVCodecContext *avctx, QSVContext *q,
 return AVERROR_BUG;
 }
 
-out_frame->queued = 1;
+out_frame->queued += 1;
 av_fifo_generic_write(q->async_fifo, &out_frame, sizeof(out_frame), 
NULL);
 av_fifo_generic_write(q->async_fifo, &sync,  sizeof(sync),  
NULL);
 } else {
@@ -526,7 +526,7 @@ static int qsv_decode(AVCodecContext *avctx, QSVContext *q,
 
 av_fifo_generic_read(q->async_fifo, &out_frame, sizeof(out_frame), 
NULL);
 av_fifo_generic_read(q->async_fifo, &sync,  sizeof(sync),  
NULL);
-out_frame->queued = 0;
+out_frame->queued -= 1;
 
 if (avctx->pix_fmt != AV_PIX_FMT_QSV) {
 do {
-- 
2.25.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

[FFmpeg-devel] [PATCH] libavcodec/qsvdec: reinit decoder according to decode() return value

2021-03-21 Thread wenbin . chen
From: "Chen,Wenbin" 

FFmpeg-qsv decoder reinit codec when width and height change, but there
are not only resolution change need to reinit codec. I change it to use
return value from DecodeFrameAsync() to decide whether decoder need to
be reinitialized.

Signed-off-by Wenbin Chen 
---
 libavcodec/qsvdec.c | 10 --
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/libavcodec/qsvdec.c b/libavcodec/qsvdec.c
index bca6e217fa..124f3e0a7a 100644
--- a/libavcodec/qsvdec.c
+++ b/libavcodec/qsvdec.c
@@ -438,6 +438,12 @@ static int qsv_decode(AVCodecContext *avctx, QSVContext *q,
 
 } while (ret == MFX_WRN_DEVICE_BUSY || ret == MFX_ERR_MORE_SURFACE);
 
+if (ret == MFX_ERR_INCOMPATIBLE_VIDEO_PARAM) {
+q->reinit_flag = 1;
+av_log(avctx, AV_LOG_VERBOSE, "Video parameter change\n");
+return 0;
+}
+
 if (ret != MFX_ERR_NONE &&
 ret != MFX_ERR_MORE_DATA &&
 ret != MFX_WRN_VIDEO_PARAM_CHANGED &&
@@ -591,9 +597,9 @@ int ff_qsv_process_data(AVCodecContext *avctx, QSVContext 
*q,
 
 ret = qsv_decode_header(avctx, q, pkt, pix_fmt, ¶m);
 
-if (ret >= 0 && (q->orig_pix_fmt != 
ff_qsv_map_fourcc(param.mfx.FrameInfo.FourCC) ||
+if (q->reinit_flag || (ret >= 0 && (q->orig_pix_fmt != 
ff_qsv_map_fourcc(param.mfx.FrameInfo.FourCC) ||
 avctx->coded_width  != param.mfx.FrameInfo.Width ||
-avctx->coded_height != param.mfx.FrameInfo.Height)) {
+avctx->coded_height != param.mfx.FrameInfo.Height))) {
 AVPacket zero_pkt = {0};
 
 if (q->buffered_count) {
-- 
2.25.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

[FFmpeg-devel] [PATCH] libavcodec/qsvdec: use the param from decodeHeader to configure surface

2021-03-21 Thread wenbin . chen
From: "Chen,Wenbin" 

MSDK recognizes both yuv420p10 and yuv420p9 as MFX_FOURCC_P010, but param
are different. When decode yuv420p9 video, ffmpeg-qsv will use
yuv420p10le to configure surface which is different with param from
DecoderHeader and this will lead to error. Now change it use
param from decoderHeader to configure surface.

Signed-off-by Wenbin Chen 
---
 libavcodec/qsvdec.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/libavcodec/qsvdec.c b/libavcodec/qsvdec.c
index 569ccd4fba..3ab48ea7a2 100644
--- a/libavcodec/qsvdec.c
+++ b/libavcodec/qsvdec.c
@@ -309,13 +309,13 @@ static int alloc_frame(AVCodecContext *avctx, QSVContext 
*q, QSVFrame *frame)
 if (frame->frame->format == AV_PIX_FMT_QSV) {
 frame->surface = *(mfxFrameSurface1*)frame->frame->data[3];
 } else {
-frame->surface.Info = q->frame_info;
-
 frame->surface.Data.PitchLow = frame->frame->linesize[0];
 frame->surface.Data.Y= frame->frame->data[0];
 frame->surface.Data.UV   = frame->frame->data[1];
 }
 
+frame->surface.Info = q->frame_info;
+
 if (q->frames_ctx.mids) {
 ret = ff_qsv_find_surface_idx(&q->frames_ctx, frame);
 if (ret < 0)
-- 
2.25.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

[FFmpeg-devel] [PATCH] libavcodec/qsvenc: add more ChromaFormat support for mjpeg-qsv

2021-03-21 Thread wenbin . chen
From: "Chen,Wenbin" 

ChromaForamt for mjpeg-qsv is always set to yuv420, and this will be
wrong when encode other pixel format (for example yuyv422). I change
this assignment to be adaptive to pix_fmt.

Signed-off-by: Wenbin Chen 
---
 libavcodec/qsvenc.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/libavcodec/qsvenc.c b/libavcodec/qsvenc.c
index 566a5c8552..a0fc206364 100644
--- a/libavcodec/qsvenc.c
+++ b/libavcodec/qsvenc.c
@@ -445,7 +445,8 @@ static int init_video_param_jpeg(AVCodecContext *avctx, 
QSVEncContext *q)
 q->param.mfx.FrameInfo.CropH  = avctx->height;
 q->param.mfx.FrameInfo.AspectRatioW   = avctx->sample_aspect_ratio.num;
 q->param.mfx.FrameInfo.AspectRatioH   = avctx->sample_aspect_ratio.den;
-q->param.mfx.FrameInfo.ChromaFormat   = MFX_CHROMAFORMAT_YUV420;
+q->param.mfx.FrameInfo.ChromaFormat   = MFX_CHROMAFORMAT_YUV420 +
+!desc->log2_chroma_w + 
!desc->log2_chroma_h;
 q->param.mfx.FrameInfo.BitDepthLuma   = desc->comp[0].depth;
 q->param.mfx.FrameInfo.BitDepthChroma = desc->comp[0].depth;
 q->param.mfx.FrameInfo.Shift  = desc->comp[0].depth > 8;
-- 
2.25.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

[FFmpeg-devel] [PATCH] libavfilter/qsvvpp: change the output frame's width and height

2021-03-21 Thread wenbin . chen
From: "Chen,Wenbin" 

qsvvpp align the width and height with 16, and that may lead to error.
For example, when we use qsvvpp to resize frame to 1080p, qsvvpp will
align frame to 1088 which is different from the height of
encoder (1080) and this will be treated as resolution change. Now I 
assign the out_link's w/h to output
frame to overwrite the w/h got from hw_frame_ctx.

Signed-off-by: Wenbin Chen 
---
 libavfilter/qsvvpp.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/libavfilter/qsvvpp.c b/libavfilter/qsvvpp.c
index f216b3f248..8658a70083 100644
--- a/libavfilter/qsvvpp.c
+++ b/libavfilter/qsvvpp.c
@@ -476,6 +476,9 @@ static QSVFrame *query_frame(QSVVPPContext *s, AVFilterLink 
*outlink)
 return NULL;
 }
 
+out_frame->frame->width  = outlink->w;
+out_frame->frame->height = outlink->h;
+
 out_frame->surface = (mfxFrameSurface1 *)out_frame->frame->data[3];
 } else {
 /* Get a frame with aligned dimensions.
-- 
2.25.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

[FFmpeg-devel] [PATCH V2] libavcodec/qsvdec: reinit decoder according to decode() return value

2021-03-23 Thread wenbin . chen
From: "Chen,Wenbin" 

FFmpeg-qsv decoder reinit codec when width and height change, but there
are not only resolution change need to reinit codec. I change it to use
return value from DecodeFrameAsync() to decide whether decoder need to
be reinitialized.

Signed-off-by Wenbin Chen 
---
 libavcodec/qsvdec.c | 11 +--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/libavcodec/qsvdec.c b/libavcodec/qsvdec.c
index 5f2e641373..88232f5d8d 100644
--- a/libavcodec/qsvdec.c
+++ b/libavcodec/qsvdec.c
@@ -481,6 +481,13 @@ static int qsv_decode(AVCodecContext *avctx, QSVContext *q,
 
 } while (ret == MFX_WRN_DEVICE_BUSY || ret == MFX_ERR_MORE_SURFACE);
 
+if (ret == MFX_ERR_INCOMPATIBLE_VIDEO_PARAM) {
+q->reinit_flag = 1;
+av_log(avctx, AV_LOG_DEBUG, "Video parameter change\n");
+av_freep(&sync);
+return 0;
+}
+
 if (ret != MFX_ERR_NONE &&
 ret != MFX_ERR_MORE_DATA &&
 ret != MFX_WRN_VIDEO_PARAM_CHANGED &&
@@ -632,9 +639,9 @@ static int qsv_process_data(AVCodecContext *avctx, 
QSVContext *q,
 
 ret = qsv_decode_header(avctx, q, pkt, pix_fmt, ¶m);
 
-if (ret >= 0 && (q->orig_pix_fmt != 
ff_qsv_map_fourcc(param.mfx.FrameInfo.FourCC) ||
+if (q->reinit_flag || (ret >= 0 && (q->orig_pix_fmt != 
ff_qsv_map_fourcc(param.mfx.FrameInfo.FourCC) ||
 avctx->coded_width  != param.mfx.FrameInfo.Width ||
-avctx->coded_height != param.mfx.FrameInfo.Height)) {
+avctx->coded_height != param.mfx.FrameInfo.Height))) {
 AVPacket zero_pkt = {0};
 
 if (q->buffered_count) {
-- 
2.25.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

[FFmpeg-devel] [PATCH V2] libavfilter/qsvvpp: change the output frame's width and height

2021-03-23 Thread wenbin . chen
From: "Chen,Wenbin" 

qsvvpp align the width and height with 16, and that may lead to error.
For example, when we use qsvvpp to resize frame to 1080p, qsvvpp will
align frame to 1088 which is different from the height of
encoder (1080) and this will be treated as resolution change. Now I
assign the out_link's w/h to output
frame to overwrite the w/h got from hw_frame_ctx.

Signed-off-by: Wenbin Chen 
---
 libavfilter/qsvvpp.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/libavfilter/qsvvpp.c b/libavfilter/qsvvpp.c
index f216b3f248..70d6cb49e3 100644
--- a/libavfilter/qsvvpp.c
+++ b/libavfilter/qsvvpp.c
@@ -486,9 +486,6 @@ static QSVFrame *query_frame(QSVVPPContext *s, AVFilterLink 
*outlink)
 if (!out_frame->frame)
 return NULL;
 
-out_frame->frame->width  = outlink->w;
-out_frame->frame->height = outlink->h;
-
 ret = map_frame_to_surface(out_frame->frame,
   &out_frame->surface_internal);
 if (ret < 0)
@@ -497,6 +494,8 @@ static QSVFrame *query_frame(QSVVPPContext *s, AVFilterLink 
*outlink)
 out_frame->surface = &out_frame->surface_internal;
 }
 
+out_frame->frame->width  = outlink->w;
+out_frame->frame->height = outlink->h;
 out_frame->surface->Info = s->vpp_param.vpp.Out;
 
 return out_frame;
-- 
2.25.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

[FFmpeg-devel] [PATCH V3] libavfilter/qsvvpp: change the output frame's width and height

2021-03-28 Thread wenbin . chen
From: "Chen,Wenbin" 

qsvvpp align the width and height with 16, and that right. But qsvvpp asign 
this value
to frame->width and frame->height, and that may lead to error.
For example, when we use qsvvpp to resize frame to 1080p, qsvvpp will
align frame to 1088 and set frame->height to 1088, which is different from the 
height of
encoder (1080) and this will be treated as resolution change. The aligend value 
can 
be kept in hw_frame_ctx as it is hardware dependent. Now I
assign the out_link's w/h to output
frame to overwrite the w/h got from hw_frame_ctx.

Signed-off-by: Wenbin Chen 
---
 libavfilter/qsvvpp.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/libavfilter/qsvvpp.c b/libavfilter/qsvvpp.c
index f216b3f248..70d6cb49e3 100644
--- a/libavfilter/qsvvpp.c
+++ b/libavfilter/qsvvpp.c
@@ -486,9 +486,6 @@ static QSVFrame *query_frame(QSVVPPContext *s, AVFilterLink 
*outlink)
 if (!out_frame->frame)
 return NULL;
 
-out_frame->frame->width  = outlink->w;
-out_frame->frame->height = outlink->h;
-
 ret = map_frame_to_surface(out_frame->frame,
   &out_frame->surface_internal);
 if (ret < 0)
@@ -497,6 +494,8 @@ static QSVFrame *query_frame(QSVVPPContext *s, AVFilterLink 
*outlink)
 out_frame->surface = &out_frame->surface_internal;
 }
 
+out_frame->frame->width  = outlink->w;
+out_frame->frame->height = outlink->h;
 out_frame->surface->Info = s->vpp_param.vpp.Out;
 
 return out_frame;
-- 
2.25.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

[FFmpeg-devel] [PATCH] libavcodec/qsvenc: add mbbrc to hevc_qsv

2021-04-12 Thread wenbin . chen
From: "Chen,Wenbin" 

Add mbbrc to hevc_qsv
For detailed description, please see "mbbrc" part in:
https://github.com/Intel-Media-SDK/MediaSDK/blob/master/doc/mediasdk-man.md#mfxextcodingoption2

Signed-off-by: Wenbin Chen 
---
 libavcodec/qsvenc.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/libavcodec/qsvenc.c b/libavcodec/qsvenc.c
index 566a5c8552..19e246a8fb 100644
--- a/libavcodec/qsvenc.c
+++ b/libavcodec/qsvenc.c
@@ -701,8 +701,6 @@ FF_ENABLE_DEPRECATION_WARNINGS
 
 if (q->bitrate_limit >= 0)
 q->extco2.BitrateLimit = q->bitrate_limit ? 
MFX_CODINGOPTION_ON : MFX_CODINGOPTION_OFF;
-if (q->mbbrc >= 0)
-q->extco2.MBBRC = q->mbbrc ? MFX_CODINGOPTION_ON : 
MFX_CODINGOPTION_OFF;
 
 if (q->max_frame_size >= 0)
 q->extco2.MaxFrameSize = q->max_frame_size;
@@ -755,6 +753,9 @@ FF_ENABLE_DEPRECATION_WARNINGS
 q->extco2.MaxQPP = q->extco2.MaxQPB = q->extco2.MaxQPI;
 }
 #endif
+if (q->mbbrc >= 0)
+q->extco2.MBBRC = q->mbbrc ? MFX_CODINGOPTION_ON : 
MFX_CODINGOPTION_OFF;
+
 q->extco2.Header.BufferId = MFX_EXTBUFF_CODING_OPTION2;
 q->extco2.Header.BufferSz = sizeof(q->extco2);
 
-- 
2.25.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

[FFmpeg-devel] [PATCH 1/3] libavcodec/qsvdec: reinit decoder according to decode() return value

2021-04-25 Thread wenbin . chen
From: "Chen,Wenbin" 

FFmpeg-qsv decoder reinit codec when width and height change, but there
are not only resolution change need to reinit codec. I change it to use
return value from DecodeFrameAsync() to decide whether decoder need to
be reinitialized.

Signed-off-by Wenbin Chen 
Signed-off-by Guangxin Xu 
---
 libavcodec/qsvdec.c | 11 +--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/libavcodec/qsvdec.c b/libavcodec/qsvdec.c
index 5f2e641373..88232f5d8d 100644
--- a/libavcodec/qsvdec.c
+++ b/libavcodec/qsvdec.c
@@ -481,6 +481,13 @@ static int qsv_decode(AVCodecContext *avctx, QSVContext *q,
 
 } while (ret == MFX_WRN_DEVICE_BUSY || ret == MFX_ERR_MORE_SURFACE);
 
+if (ret == MFX_ERR_INCOMPATIBLE_VIDEO_PARAM) {
+q->reinit_flag = 1;
+av_log(avctx, AV_LOG_DEBUG, "Video parameter change\n");
+av_freep(&sync);
+return 0;
+}
+
 if (ret != MFX_ERR_NONE &&
 ret != MFX_ERR_MORE_DATA &&
 ret != MFX_WRN_VIDEO_PARAM_CHANGED &&
@@ -632,9 +639,9 @@ static int qsv_process_data(AVCodecContext *avctx, 
QSVContext *q,
 
 ret = qsv_decode_header(avctx, q, pkt, pix_fmt, ¶m);
 
-if (ret >= 0 && (q->orig_pix_fmt != 
ff_qsv_map_fourcc(param.mfx.FrameInfo.FourCC) ||
+if (q->reinit_flag || (ret >= 0 && (q->orig_pix_fmt != 
ff_qsv_map_fourcc(param.mfx.FrameInfo.FourCC) ||
 avctx->coded_width  != param.mfx.FrameInfo.Width ||
-avctx->coded_height != param.mfx.FrameInfo.Height)) {
+avctx->coded_height != param.mfx.FrameInfo.Height))) {
 AVPacket zero_pkt = {0};
 
 if (q->buffered_count) {
-- 
2.25.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH 2/3] libavcodec/qsvdec: remove redundant decodeHeader()

2021-04-25 Thread wenbin . chen
From: "Chen,Wenbin" 

Since ffmpeg-qsv uses return value to reinit decoder, it doesn't need to
decode header each time. Move qsv_decode_header's position so that
it will be called only if codec needed to be reinitialized.
Rearrange the code of flushing decoder and re-init decoder operation.
Remove the buffer_count and use the got_frame to decide whether the
decoder is drain.

Signed-off-by: Wenbin Chen 
Signed-off-by Guangxin Xu 
---
 libavcodec/qsvdec.c | 26 --
 1 file changed, 12 insertions(+), 14 deletions(-)

diff --git a/libavcodec/qsvdec.c b/libavcodec/qsvdec.c
index 88232f5d8d..fe416e74ca 100644
--- a/libavcodec/qsvdec.c
+++ b/libavcodec/qsvdec.c
@@ -63,7 +63,6 @@ typedef struct QSVContext {
 
 AVFifoBuffer *async_fifo;
 int zero_consume_run;
-int buffered_count;
 int reinit_flag;
 
 enum AVPixelFormat orig_pix_fmt;
@@ -504,8 +503,6 @@ static int qsv_decode(AVCodecContext *avctx, QSVContext *q,
 ++q->zero_consume_run;
 if (q->zero_consume_run > 1)
 ff_qsv_print_warning(avctx, ret, "A decode call did not consume 
any data");
-} else if (!*sync && bs.DataOffset) {
-++q->buffered_count;
 } else {
 q->zero_consume_run = 0;
 }
@@ -637,20 +634,21 @@ static int qsv_process_data(AVCodecContext *avctx, 
QSVContext *q,
 if (!avctx->coded_height)
 avctx->coded_height = 720;
 
-ret = qsv_decode_header(avctx, q, pkt, pix_fmt, ¶m);
-
-if (q->reinit_flag || (ret >= 0 && (q->orig_pix_fmt != 
ff_qsv_map_fourcc(param.mfx.FrameInfo.FourCC) ||
-avctx->coded_width  != param.mfx.FrameInfo.Width ||
-avctx->coded_height != param.mfx.FrameInfo.Height))) {
+/* decode zero-size pkt to flush the buffered pkt before reinit */
+if (q->reinit_flag) {
 AVPacket zero_pkt = {0};
+ret = qsv_decode(avctx, q, frame, got_frame, &zero_pkt);
+if (*got_frame)
+return ret;
+}
 
-if (q->buffered_count) {
-q->reinit_flag = 1;
-/* decode zero-size pkt to flush the buffered pkt before reinit */
-q->buffered_count--;
-return qsv_decode(avctx, q, frame, got_frame, &zero_pkt);
-}
+if (q->reinit_flag || !q->session) {
 q->reinit_flag = 0;
+ret = qsv_decode_header(avctx, q, pkt, pix_fmt, ¶m);
+if (ret < 0) {
+av_log(avctx, AV_LOG_ERROR, "Error decoding header\n");
+goto reinit_fail;
+}
 
 q->orig_pix_fmt = avctx->pix_fmt = pix_fmt = 
ff_qsv_map_fourcc(param.mfx.FrameInfo.FourCC);
 
-- 
2.25.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH 3/3] libavcodec/qsvdec: using suggested num to set init_pool_size

2021-04-25 Thread wenbin . chen
From: Wenbinc-Bin 

The init_pool_size is set to be 64 and it is too many.
Use IOSurfQuery to get NumFrameSuggest which is the suggested
number of frame that needed to be allocated when initializing the decoder.
Considering that the hevc_qsv encoder uses the  most frame buffer,
async is 4 (default) and max_b_frames is 8 (default) and decoder
may followed by VPP, use NumFrameSuggest + 16 to set init_pool_size.

Sigend-off-by Wenbin Chen 
Signed-off-by Guangxin Xu 
---
 fftools/ffmpeg_qsv.c |  9 -
 libavcodec/qsvdec.c  | 14 ++
 2 files changed, 22 insertions(+), 1 deletion(-)

diff --git a/fftools/ffmpeg_qsv.c b/fftools/ffmpeg_qsv.c
index 960c88b69d..3862dc1e7d 100644
--- a/fftools/ffmpeg_qsv.c
+++ b/fftools/ffmpeg_qsv.c
@@ -74,6 +74,7 @@ int qsv_init(AVCodecContext *s)
 InputStream *ist = s->opaque;
 AVHWFramesContext *frames_ctx;
 AVQSVFramesContext *frames_hwctx;
+int suggest_pool_size;
 int ret;
 
 if (!hw_device_ctx) {
@@ -82,6 +83,12 @@ int qsv_init(AVCodecContext *s)
 return ret;
 }
 
+suggest_pool_size = 0;
+if (ist->hw_frames_ctx) {
+frames_ctx = (AVHWFramesContext *)ist->hw_frames_ctx->data;
+suggest_pool_size = frames_ctx->initial_pool_size;
+}
+
 av_buffer_unref(&ist->hw_frames_ctx);
 ist->hw_frames_ctx = av_hwframe_ctx_alloc(hw_device_ctx);
 if (!ist->hw_frames_ctx)
@@ -94,7 +101,7 @@ int qsv_init(AVCodecContext *s)
 frames_ctx->height= FFALIGN(s->coded_height, 32);
 frames_ctx->format= AV_PIX_FMT_QSV;
 frames_ctx->sw_format = s->sw_pix_fmt;
-frames_ctx->initial_pool_size = 64 + s->extra_hw_frames;
+frames_ctx->initial_pool_size = suggest_pool_size + 16 + 
s->extra_hw_frames;
 frames_hwctx->frame_type  = MFX_MEMTYPE_VIDEO_MEMORY_DECODER_TARGET;
 
 ret = av_hwframe_ctx_init(ist->hw_frames_ctx);
diff --git a/libavcodec/qsvdec.c b/libavcodec/qsvdec.c
index fe416e74ca..f7cd33cc74 100644
--- a/libavcodec/qsvdec.c
+++ b/libavcodec/qsvdec.c
@@ -643,18 +643,32 @@ static int qsv_process_data(AVCodecContext *avctx, 
QSVContext *q,
 }
 
 if (q->reinit_flag || !q->session) {
+mfxFrameAllocRequest request;
+AVHWFramesContext *hw_frames_ctx;
+memset(&request, 0, sizeof(request));
+
 q->reinit_flag = 0;
 ret = qsv_decode_header(avctx, q, pkt, pix_fmt, ¶m);
 if (ret < 0) {
 av_log(avctx, AV_LOG_ERROR, "Error decoding header\n");
 goto reinit_fail;
 }
+param.IOPattern = q->iopattern;
 
 q->orig_pix_fmt = avctx->pix_fmt = pix_fmt = 
ff_qsv_map_fourcc(param.mfx.FrameInfo.FourCC);
 
 avctx->coded_width  = param.mfx.FrameInfo.Width;
 avctx->coded_height = param.mfx.FrameInfo.Height;
 
+ret = MFXVideoDECODE_QueryIOSurf(q->session, ¶m, &request);
+if (ret < 0)
+return ff_qsv_print_error(avctx, ret, "Error querying IO surface");
+
+if (avctx->hw_frames_ctx) {
+hw_frames_ctx = (AVHWFramesContext *)avctx->hw_frames_ctx->data;
+hw_frames_ctx->initial_pool_size = request.NumFrameSuggested;
+}
+
 ret = qsv_decode_preinit(avctx, q, pix_fmt, ¶m);
 if (ret < 0)
 goto reinit_fail;
-- 
2.25.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH v2 1/7] libavcodec/qsvenc: skip parameter resetting on mjpeg_qsv

2022-09-06 Thread Wenbin Chen
mjpeg_qsv don't support dynamic resetting, so skip it.

Signed-off-by: Wenbin Chen 
---
 libavcodec/qsvenc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libavcodec/qsvenc.c b/libavcodec/qsvenc.c
index 7ac5390f10..842cfb845e 100644
--- a/libavcodec/qsvenc.c
+++ b/libavcodec/qsvenc.c
@@ -1680,7 +1680,7 @@ static int update_parameters(AVCodecContext *avctx, 
QSVEncContext *q,
 {
 int needReset = 0, ret = 0;
 
-if (!frame)
+if (!frame || avctx->codec_id == AV_CODEC_ID_MJPEG)
 return 0;
 
 needReset = update_qp(avctx, q);
-- 
2.32.0

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH v2 2/7] libavcodec/qsvenc: Add max_frame_size reset support to qsv

2022-09-06 Thread Wenbin Chen
Signed-off-by: Wenbin Chen 
---
 doc/encoders.texi   |  4 
 libavcodec/qsvenc.c | 20 
 libavcodec/qsvenc.h |  2 ++
 3 files changed, 26 insertions(+)

diff --git a/doc/encoders.texi b/doc/encoders.texi
index d36464d629..aadb6ab9fd 100644
--- a/doc/encoders.texi
+++ b/doc/encoders.texi
@@ -3344,6 +3344,10 @@ Following options can be used durning qsv encoding.
 @item @var{b_quant_offset}
 Supported in h264_qsv and hevc_qsv.
 Change these value to reset qsv codec's qp configuration.
+
+@item @var{max_frame_size}
+Supported in h264_qsv and hevc_qsv.
+Change this value to reset qsv codec's MaxFrameSize configuration.
 @end table
 
 @subsection H264 options
diff --git a/libavcodec/qsvenc.c b/libavcodec/qsvenc.c
index 842cfb845e..915a1abd26 100644
--- a/libavcodec/qsvenc.c
+++ b/libavcodec/qsvenc.c
@@ -824,6 +824,7 @@ static int init_video_param(AVCodecContext *avctx, 
QSVEncContext *q)
 q->extco2.ExtBRC = q->extbrc ? MFX_CODINGOPTION_ON : 
MFX_CODINGOPTION_OFF;
 if (q->max_frame_size >= 0)
 q->extco2.MaxFrameSize = q->max_frame_size;
+q->old_max_frame_size = q->max_frame_size;
 if (q->int_ref_type >= 0)
 q->extco2.IntRefType = q->int_ref_type;
 if (q->int_ref_cycle_size >= 0)
@@ -1675,6 +1676,24 @@ static int update_qp(AVCodecContext *avctx, 
QSVEncContext *q)
 return updated;
 }
 
+static int update_max_frame_size(AVCodecContext *avctx, QSVEncContext *q)
+{
+int updated = 0;
+
+if (avctx->codec_id != AV_CODEC_ID_H264 && avctx->codec_id != 
AV_CODEC_ID_HEVC)
+return 0;
+
+UPDATE_PARAM(q->old_max_frame_size, q->max_frame_size);
+if (!updated)
+return 0;
+
+q->extco2.MaxFrameSize  = FFMAX(0, q->max_frame_size);
+av_log(avctx, AV_LOG_DEBUG,
+   "Reset MaxFrameSize: %d;\n", q->extco2.MaxFrameSize);
+
+return updated;
+}
+
 static int update_parameters(AVCodecContext *avctx, QSVEncContext *q,
  const AVFrame *frame)
 {
@@ -1684,6 +1703,7 @@ static int update_parameters(AVCodecContext *avctx, 
QSVEncContext *q,
 return 0;
 
 needReset = update_qp(avctx, q);
+needReset |= update_max_frame_size(avctx, q);
 if (!needReset)
 return 0;
 
diff --git a/libavcodec/qsvenc.h b/libavcodec/qsvenc.h
index a983651dda..3984ae7dd8 100644
--- a/libavcodec/qsvenc.h
+++ b/libavcodec/qsvenc.h
@@ -249,6 +249,8 @@ typedef struct QSVEncContext {
 float old_i_quant_offset;
 float old_b_quant_factor;
 float old_b_quant_offset;
+// This is used for max_frame_size reset
+int old_max_frame_size;
 } QSVEncContext;
 
 int ff_qsv_enc_init(AVCodecContext *avctx, QSVEncContext *q);
-- 
2.32.0

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH v2 3/7] libavcodec/qsvenc: Add gop_size reset support to qsvenc

2022-09-06 Thread Wenbin Chen
Signed-off-by: Wenbin Chen 
---
 doc/encoders.texi   |  3 +++
 libavcodec/qsvenc.c | 16 
 libavcodec/qsvenc.h |  2 ++
 3 files changed, 21 insertions(+)

diff --git a/doc/encoders.texi b/doc/encoders.texi
index aadb6ab9fd..bc1a4dae38 100644
--- a/doc/encoders.texi
+++ b/doc/encoders.texi
@@ -3348,6 +3348,9 @@ Change these value to reset qsv codec's qp configuration.
 @item @var{max_frame_size}
 Supported in h264_qsv and hevc_qsv.
 Change this value to reset qsv codec's MaxFrameSize configuration.
+
+@item @var{gop_size}
+Change this value to reset qsv codec's gop configuration.
 @end table
 
 @subsection H264 options
diff --git a/libavcodec/qsvenc.c b/libavcodec/qsvenc.c
index 915a1abd26..9a0431630a 100644
--- a/libavcodec/qsvenc.c
+++ b/libavcodec/qsvenc.c
@@ -636,6 +636,7 @@ static int init_video_param(AVCodecContext *avctx, 
QSVEncContext *q)
 q->param.mfx.CodecProfile   = q->profile;
 q->param.mfx.TargetUsage= avctx->compression_level;
 q->param.mfx.GopPicSize = FFMAX(0, avctx->gop_size);
+q->old_gop_size = avctx->gop_size;
 q->param.mfx.GopRefDist = FFMAX(-1, avctx->max_b_frames) + 1;
 q->param.mfx.GopOptFlag = avctx->flags & AV_CODEC_FLAG_CLOSED_GOP ?
   MFX_GOP_CLOSED : MFX_GOP_STRICT;
@@ -1694,6 +1695,20 @@ static int update_max_frame_size(AVCodecContext *avctx, 
QSVEncContext *q)
 return updated;
 }
 
+static int update_gop_size(AVCodecContext *avctx, QSVEncContext *q)
+{
+int updated = 0;
+UPDATE_PARAM(q->old_gop_size, avctx->gop_size);
+if (!updated)
+return 0;
+
+q->param.mfx.GopPicSize = FFMAX(0, avctx->gop_size);
+av_log(avctx, AV_LOG_DEBUG, "reset GopPicSize to %d\n",
+   q->param.mfx.GopPicSize);
+
+return updated;
+}
+
 static int update_parameters(AVCodecContext *avctx, QSVEncContext *q,
  const AVFrame *frame)
 {
@@ -1704,6 +1719,7 @@ static int update_parameters(AVCodecContext *avctx, 
QSVEncContext *q,
 
 needReset = update_qp(avctx, q);
 needReset |= update_max_frame_size(avctx, q);
+needReset |= update_gop_size(avctx, q);
 if (!needReset)
 return 0;
 
diff --git a/libavcodec/qsvenc.h b/libavcodec/qsvenc.h
index 3984ae7dd8..5f6955a3a7 100644
--- a/libavcodec/qsvenc.h
+++ b/libavcodec/qsvenc.h
@@ -251,6 +251,8 @@ typedef struct QSVEncContext {
 float old_b_quant_offset;
 // This is used for max_frame_size reset
 int old_max_frame_size;
+// This is used for gop reset
+int old_gop_size;
 } QSVEncContext;
 
 int ff_qsv_enc_init(AVCodecContext *avctx, QSVEncContext *q);
-- 
2.32.0

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH v2 4/7] libavcodec/qsvenc: Add "slice" intra refresh type to qsvenc

2022-09-06 Thread Wenbin Chen
Add "slice" intra refresh type to h264_qsv and hevc_qsv. This type means
horizontal refresh by slices without overlapping. Also update the doc.

Signed-off-by: Wenbin Chen 
---
 doc/encoders.texi| 12 
 libavcodec/qsvenc_h264.c |  1 +
 libavcodec/qsvenc_hevc.c |  1 +
 3 files changed, 10 insertions(+), 4 deletions(-)

diff --git a/doc/encoders.texi b/doc/encoders.texi
index bc1a4dae38..d5d695d39c 100644
--- a/doc/encoders.texi
+++ b/doc/encoders.texi
@@ -3454,8 +3454,10 @@ Specifies intra refresh type. The major goal of intra 
refresh is improvement of
 error resilience without significant impact on encoded bitstream size caused by
 I frames. The SDK encoder achieves this by encoding part of each frame in
 refresh cycle using intra MBs. @var{none} means no refresh. @var{vertical} 
means
-vertical refresh, by column of MBs. To enable intra refresh, B frame should be
-set to 0.
+vertical refresh, by column of MBs. @var{horizontal} means horizontal refresh,
+by rows of MBs. @var{slice} means horizontal refresh by slices without
+overlapping. In case of @var{slice}, in_ref_cycle_size is ignored. To enable
+intra refresh, B frame should be set to 0.
 
 @item @var{int_ref_cycle_size}
 Specifies number of pictures within refresh cycle starting from 2. 0 and 1 are
@@ -3641,8 +3643,10 @@ Specifies intra refresh type. The major goal of intra 
refresh is improvement of
 error resilience without significant impact on encoded bitstream size caused by
 I frames. The SDK encoder achieves this by encoding part of each frame in
 refresh cycle using intra MBs. @var{none} means no refresh. @var{vertical} 
means
-vertical refresh, by column of MBs. To enable intra refresh, B frame should be
-set to 0.
+vertical refresh, by column of MBs. @var{horizontal} means horizontal refresh,
+by rows of MBs. @var{slice} means horizontal refresh by slices without
+overlapping. In case of @var{slice}, in_ref_cycle_size is ignored. To enable
+intra refresh, B frame should be set to 0.
 
 @item @var{int_ref_cycle_size}
 Specifies number of pictures within refresh cycle starting from 2. 0 and 1 are
diff --git a/libavcodec/qsvenc_h264.c b/libavcodec/qsvenc_h264.c
index 1bbdc45203..8bc4ef95d2 100644
--- a/libavcodec/qsvenc_h264.c
+++ b/libavcodec/qsvenc_h264.c
@@ -139,6 +139,7 @@ static const AVOption options[] = {
 { "none", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 0 }, .flags = VE, 
"int_ref_type" },
 { "vertical", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 1 }, .flags = VE, 
"int_ref_type" },
 { "horizontal", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 2 }, .flags = VE, 
"int_ref_type" },
+{ "slice" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 3 }, .flags = VE, 
"int_ref_type" },
 { "int_ref_cycle_size", "Number of frames in the intra refresh cycle", 
  OFFSET(qsv.int_ref_cycle_size),  AV_OPT_TYPE_INT, { .i64 = -1 },  
 -1, UINT16_MAX, VE },
 { "int_ref_qp_delta",   "QP difference for the refresh MBs",   
  OFFSET(qsv.int_ref_qp_delta),AV_OPT_TYPE_INT, { .i64 = INT16_MIN }, 
INT16_MIN,  INT16_MAX, VE },
 { "recovery_point_sei", "Insert recovery point SEI messages",  
  OFFSET(qsv.recovery_point_sei),  AV_OPT_TYPE_INT, { .i64 = -1 },  
 -1,  1, VE },
diff --git a/libavcodec/qsvenc_hevc.c b/libavcodec/qsvenc_hevc.c
index 5986c3f1a6..ba7cb6fba6 100644
--- a/libavcodec/qsvenc_hevc.c
+++ b/libavcodec/qsvenc_hevc.c
@@ -270,6 +270,7 @@ static const AVOption options[] = {
 { "none", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 0 }, .flags = VE, 
"int_ref_type" },
 { "vertical", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 1 }, .flags = VE, 
"int_ref_type" },
 { "horizontal", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 2 }, .flags = VE, 
"int_ref_type" },
+{ "slice" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 3 }, .flags = VE, 
"int_ref_type" },
 { "int_ref_cycle_size", "Number of frames in the intra refresh cycle", 
  OFFSET(qsv.int_ref_cycle_size),  AV_OPT_TYPE_INT, { .i64 = -1 },  
 -1, UINT16_MAX, VE },
 { "int_ref_qp_delta",   "QP difference for the refresh MBs",   
  OFFSET(qsv.int_ref_qp_delta),AV_OPT_TYPE_INT, { .i64 = INT16_MIN }, 
INT16_MIN,  INT16_MAX, VE },
 { "int_ref_cycle_dist",   "Distance between the beginnings of the 
intra-refresh cycles in frames",  OFFSET(qsv.int_ref_cycle_dist),  
AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT16_MAX, VE },
-- 
2.32.0

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH v2 5/7] libavcodec/qsvenc: Add intra refresh reset support to qsvenc

2022-09-06 Thread Wenbin Chen
Signed-off-by: Wenbin Chen 
---
 doc/encoders.texi   |  7 +++
 libavcodec/qsvenc.c | 33 +
 libavcodec/qsvenc.h |  5 +
 3 files changed, 45 insertions(+)

diff --git a/doc/encoders.texi b/doc/encoders.texi
index d5d695d39c..da56159858 100644
--- a/doc/encoders.texi
+++ b/doc/encoders.texi
@@ -3351,6 +3351,13 @@ Change this value to reset qsv codec's MaxFrameSize 
configuration.
 
 @item @var{gop_size}
 Change this value to reset qsv codec's gop configuration.
+
+@item @var{int_ref_type}
+@item @var{int_ref_cycle_size}
+@item @var{int_ref_qp_delta}
+@item @var{int_ref_cycle_dist}
+Supported in h264_qsv and hevc_qsv.
+Change these value to reset qsv codec's Intra Refresh configuration.
 @end table
 
 @subsection H264 options
diff --git a/libavcodec/qsvenc.c b/libavcodec/qsvenc.c
index 9a0431630a..cd0549b249 100644
--- a/libavcodec/qsvenc.c
+++ b/libavcodec/qsvenc.c
@@ -828,10 +828,13 @@ static int init_video_param(AVCodecContext *avctx, 
QSVEncContext *q)
 q->old_max_frame_size = q->max_frame_size;
 if (q->int_ref_type >= 0)
 q->extco2.IntRefType = q->int_ref_type;
+q->old_int_ref_type = q->int_ref_type;
 if (q->int_ref_cycle_size >= 0)
 q->extco2.IntRefCycleSize = q->int_ref_cycle_size;
+q->old_int_ref_cycle_size = q->int_ref_cycle_size;
 if (q->int_ref_qp_delta != INT16_MIN)
 q->extco2.IntRefQPDelta = q->int_ref_qp_delta;
+q->old_int_ref_qp_delta = q->int_ref_qp_delta;
 if (q->max_slice_size >= 0)
 q->extco2.MaxSliceSize = q->max_slice_size;
 q->extco2.DisableDeblockingIdc = q->dblk_idc;
@@ -920,6 +923,7 @@ static int init_video_param(AVCodecContext *avctx, 
QSVEncContext *q)
 }
 if (q->int_ref_cycle_dist >= 0)
 q->extco3.IntRefCycleDist = q->int_ref_cycle_dist;
+q->old_int_ref_cycle_dist = q->int_ref_cycle_dist;
 if (q->low_delay_brc >= 0)
 q->extco3.LowDelayBRC = q->low_delay_brc ? MFX_CODINGOPTION_ON 
: MFX_CODINGOPTION_OFF;
 if (q->max_frame_size_i >= 0)
@@ -1709,6 +1713,34 @@ static int update_gop_size(AVCodecContext *avctx, 
QSVEncContext *q)
 return updated;
 }
 
+static int update_rir(AVCodecContext *avctx, QSVEncContext *q)
+{
+int updated = 0;
+
+if (avctx->codec_id != AV_CODEC_ID_H264 && avctx->codec_id != 
AV_CODEC_ID_HEVC)
+return 0;
+
+UPDATE_PARAM(q->old_int_ref_type, q->int_ref_type);
+UPDATE_PARAM(q->old_int_ref_cycle_size, q->int_ref_cycle_size);
+UPDATE_PARAM(q->old_int_ref_qp_delta, q->int_ref_qp_delta);
+UPDATE_PARAM(q->old_int_ref_cycle_dist, q->int_ref_cycle_dist);
+if (!updated)
+return 0;
+
+q->extco2.IntRefType  = FFMAX(0, q->int_ref_type);
+q->extco2.IntRefCycleSize = FFMAX(0, q->int_ref_cycle_size);
+q->extco2.IntRefQPDelta   =
+q->int_ref_qp_delta != INT16_MIN ? q->int_ref_qp_delta : 0;
+q->extco3.IntRefCycleDist = FFMAX(0, q->int_ref_cycle_dist);
+av_log(avctx, AV_LOG_DEBUG,
+   "Reset IntRefType: %d; IntRefCycleSize: %d; "
+   "IntRefQPDelta: %d; IntRefCycleDist: %d\n",
+   q->extco2.IntRefType, q->extco2.IntRefCycleSize,
+   q->extco2.IntRefQPDelta, q->extco3.IntRefCycleDist);
+
+return updated;
+}
+
 static int update_parameters(AVCodecContext *avctx, QSVEncContext *q,
  const AVFrame *frame)
 {
@@ -1720,6 +1752,7 @@ static int update_parameters(AVCodecContext *avctx, 
QSVEncContext *q,
 needReset = update_qp(avctx, q);
 needReset |= update_max_frame_size(avctx, q);
 needReset |= update_gop_size(avctx, q);
+needReset |= update_rir(avctx, q);
 if (!needReset)
 return 0;
 
diff --git a/libavcodec/qsvenc.h b/libavcodec/qsvenc.h
index 5f6955a3a7..2eada6ab26 100644
--- a/libavcodec/qsvenc.h
+++ b/libavcodec/qsvenc.h
@@ -253,6 +253,11 @@ typedef struct QSVEncContext {
 int old_max_frame_size;
 // This is used for gop reset
 int old_gop_size;
+// These are used for intra refresh reset
+int old_int_ref_type;
+int old_int_ref_cycle_size;
+int old_int_ref_qp_delta;
+int old_int_ref_cycle_dist;
 } QSVEncContext;
 
 int ff_qsv_enc_init(AVCodecContext *avctx, QSVEncContext *q);
-- 
2.32.0

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH v2 6/7] libavcodec/qsvenc: Add max/min qp reset support in qsvenc

2022-09-06 Thread Wenbin Chen
Signed-off-by: Wenbin Chen 
---
 doc/encoders.texi   | 11 +++
 libavcodec/qsvenc.c | 78 +
 libavcodec/qsvenc.h |  9 ++
 3 files changed, 98 insertions(+)

diff --git a/doc/encoders.texi b/doc/encoders.texi
index da56159858..850e3c261c 100644
--- a/doc/encoders.texi
+++ b/doc/encoders.texi
@@ -3358,6 +3358,17 @@ Change this value to reset qsv codec's gop configuration.
 @item @var{int_ref_cycle_dist}
 Supported in h264_qsv and hevc_qsv.
 Change these value to reset qsv codec's Intra Refresh configuration.
+
+@item @var{qmax}
+@item @var{qmin}
+@item @var{max_qp_i}
+@item @var{min_qp_i}
+@item @var{max_qp_p}
+@item @var{min_qp_p}
+@item @var{max_qp_b}
+@item @var{min_qp_b}
+Supported in h264_qsv.
+Change these value to reset qsv codec's max/min qp configuration.
 @end table
 
 @subsection H264 options
diff --git a/libavcodec/qsvenc.c b/libavcodec/qsvenc.c
index cd0549b249..215e5930ef 100644
--- a/libavcodec/qsvenc.c
+++ b/libavcodec/qsvenc.c
@@ -858,22 +858,30 @@ static int init_video_param(AVCodecContext *avctx, 
QSVEncContext *q)
 q->extco2.MinQPI = avctx->qmin > 51 ? 51 : avctx->qmin;
 q->extco2.MinQPP = q->extco2.MinQPB = q->extco2.MinQPI;
 }
+q->old_qmin = avctx->qmin;
 if (avctx->qmax >= 0) {
 q->extco2.MaxQPI = avctx->qmax > 51 ? 51 : avctx->qmax;
 q->extco2.MaxQPP = q->extco2.MaxQPB = q->extco2.MaxQPI;
 }
+q->old_qmax = avctx->qmax;
 if (q->min_qp_i >= 0)
 q->extco2.MinQPI = q->min_qp_i > 51 ? 51 : q->min_qp_i;
+q->old_min_qp_i = q->min_qp_i;
 if (q->max_qp_i >= 0)
 q->extco2.MaxQPI = q->max_qp_i > 51 ? 51 : q->max_qp_i;
+q->old_max_qp_i = q->max_qp_i;
 if (q->min_qp_p >= 0)
 q->extco2.MinQPP = q->min_qp_p > 51 ? 51 : q->min_qp_p;
+q->old_min_qp_p = q->min_qp_p;
 if (q->max_qp_p >= 0)
 q->extco2.MaxQPP = q->max_qp_p > 51 ? 51 : q->max_qp_p;
+q->old_max_qp_p = q->max_qp_p;
 if (q->min_qp_b >= 0)
 q->extco2.MinQPB = q->min_qp_b > 51 ? 51 : q->min_qp_b;
+q->old_min_qp_b = q->min_qp_b;
 if (q->max_qp_b >= 0)
 q->extco2.MaxQPB = q->max_qp_b > 51 ? 51 : q->max_qp_b;
+q->old_max_qp_b = q->max_qp_b;
 if (q->mbbrc >= 0)
 q->extco2.MBBRC = q->mbbrc ? MFX_CODINGOPTION_ON : 
MFX_CODINGOPTION_OFF;
 
@@ -1741,6 +1749,71 @@ static int update_rir(AVCodecContext *avctx, 
QSVEncContext *q)
 return updated;
 }
 
+static int update_min_max_qp(AVCodecContext *avctx, QSVEncContext *q)
+{
+int updated = 0;
+
+if (avctx->codec_id != AV_CODEC_ID_H264)
+return 0;
+
+UPDATE_PARAM(q->old_qmax, avctx->qmin);
+UPDATE_PARAM(q->old_qmax, avctx->qmin);
+UPDATE_PARAM(q->old_min_qp_i, q->min_qp_i);
+UPDATE_PARAM(q->old_max_qp_i, q->max_qp_i);
+UPDATE_PARAM(q->old_min_qp_p, q->min_qp_p);
+UPDATE_PARAM(q->old_max_qp_p, q->max_qp_p);
+UPDATE_PARAM(q->old_min_qp_b, q->min_qp_b);
+UPDATE_PARAM(q->old_max_qp_b, q->max_qp_b);
+if (!updated)
+return 0;
+
+if ((avctx->qmin >= 0 && avctx->qmax >= 0 && avctx->qmin > avctx->qmax) ||
+(q->max_qp_i >= 0 && q->min_qp_i >= 0 && q->min_qp_i > q->max_qp_i) ||
+(q->max_qp_p >= 0 && q->min_qp_p >= 0 && q->min_qp_p > q->max_qp_p) ||
+(q->max_qp_b >= 0 && q->min_qp_b >= 0 && q->min_qp_b > q->max_qp_b)) {
+av_log(avctx, AV_LOG_ERROR,
+"qmin and or qmax are set but invalid,"
+" please make sure min <= max\n");
+return AVERROR(EINVAL);
+}
+
+q->extco2.MinQPI = 0;
+q->extco2.MaxQPI = 0;
+q->extco2.MinQPP = 0;
+q->extco2.MaxQPP = 0;
+q->extco2.MinQPB = 0;
+q->extco2.MaxQPB = 0;
+if (avctx->qmin >= 0) {
+q->extco2.MinQPI = avctx->qmin > 51 ? 51 : avctx->qmin;
+q->extco2.MinQPB = q->extco2.MinQPP = q->extco2.MinQPI;
+}
+if (avctx->qmax >= 0) {
+q->extco2.MaxQPI = avctx->qmax > 51 ? 51 : avctx->qmax;
+q->extco2.MaxQPB = q->extco2.MaxQPP = q->extco2.MaxQPI;
+}
+if (q->min_qp_i >= 0)
+q->extco2.MinQPI = q->min_qp_i > 51 ? 51 : q->min_qp_i;
+if (q->max_qp_i >= 0)
+q->extco2.MaxQPI = q->max_qp_i > 5

[FFmpeg-devel] [PATCH v2 7/7] libavcodec/qsvenc: Add low_delay_brc reset support to qsvenc

2022-09-06 Thread Wenbin Chen
Signed-off-by: Wenbin Chen 
---
 doc/encoders.texi   |  4 
 libavcodec/qsvenc.c | 23 ++-
 libavcodec/qsvenc.h |  2 ++
 3 files changed, 28 insertions(+), 1 deletion(-)

diff --git a/doc/encoders.texi b/doc/encoders.texi
index 850e3c261c..453150f3e7 100644
--- a/doc/encoders.texi
+++ b/doc/encoders.texi
@@ -3369,6 +3369,10 @@ Change these value to reset qsv codec's Intra Refresh 
configuration.
 @item @var{min_qp_b}
 Supported in h264_qsv.
 Change these value to reset qsv codec's max/min qp configuration.
+
+@item @var{low_delay_brc}
+Supported in h264_qsv and hevc_qsv.
+Change this value to reset qsv codec's low_delay_brc configuration.
 @end table
 
 @subsection H264 options
diff --git a/libavcodec/qsvenc.c b/libavcodec/qsvenc.c
index 215e5930ef..58900d56a7 100644
--- a/libavcodec/qsvenc.c
+++ b/libavcodec/qsvenc.c
@@ -934,6 +934,7 @@ static int init_video_param(AVCodecContext *avctx, 
QSVEncContext *q)
 q->old_int_ref_cycle_dist = q->int_ref_cycle_dist;
 if (q->low_delay_brc >= 0)
 q->extco3.LowDelayBRC = q->low_delay_brc ? MFX_CODINGOPTION_ON 
: MFX_CODINGOPTION_OFF;
+q->old_low_delay_brc = q->low_delay_brc;
 if (q->max_frame_size_i >= 0)
 q->extco3.MaxFrameSizeI = q->max_frame_size_i;
 if (q->max_frame_size_p >= 0)
@@ -1814,6 +1815,26 @@ static int update_min_max_qp(AVCodecContext *avctx, 
QSVEncContext *q)
 return updated;
 }
 
+static int update_low_delay_brc(AVCodecContext *avctx, QSVEncContext *q)
+{
+int updated = 0;
+
+if (avctx->codec_id != AV_CODEC_ID_H264 && avctx->codec_id != 
AV_CODEC_ID_HEVC)
+return 0;
+
+UPDATE_PARAM(q->old_low_delay_brc, q->low_delay_brc);
+if (!updated)
+return 0;
+
+q->extco3.LowDelayBRC = MFX_CODINGOPTION_UNKNOWN;
+if (q->low_delay_brc >= 0)
+q->extco3.LowDelayBRC = q->low_delay_brc ? MFX_CODINGOPTION_ON : 
MFX_CODINGOPTION_OFF;
+av_log(avctx, AV_LOG_DEBUG, "Reset LowDelayBRC: %s\n",
+   print_threestate(q->extco3.LowDelayBRC));
+
+return updated;
+}
+
 static int update_parameters(AVCodecContext *avctx, QSVEncContext *q,
  const AVFrame *frame)
 {
@@ -1826,7 +1847,7 @@ static int update_parameters(AVCodecContext *avctx, 
QSVEncContext *q,
 needReset |= update_max_frame_size(avctx, q);
 needReset |= update_gop_size(avctx, q);
 needReset |= update_rir(avctx, q);
-
+needReset |= update_low_delay_brc(avctx, q);
 ret = update_min_max_qp(avctx, q);
 if (ret < 0)
 return ret;
diff --git a/libavcodec/qsvenc.h b/libavcodec/qsvenc.h
index 3ed20f757b..54e5cf89d3 100644
--- a/libavcodec/qsvenc.h
+++ b/libavcodec/qsvenc.h
@@ -267,6 +267,8 @@ typedef struct QSVEncContext {
 int old_min_qp_p;
 int old_max_qp_b;
 int old_min_qp_b;
+// This is used for low_delay_brc reset
+int old_low_delay_brc;
 } QSVEncContext;
 
 int ff_qsv_enc_init(AVCodecContext *avctx, QSVEncContext *q);
-- 
2.32.0

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH v4] libavcodec/cbs_av1: Add size check before parse obu

2022-09-21 Thread Wenbin Chen
cbs_av1_write_obu() check pbc size after parsing obu frame, and return
AVERROR(ENOSPC) if pbc is small. pbc will be reallocated and this obu
frame will be parsed again, but this may cause error because
CodedBitstreamAV1Context has already been updated, for example
ref_order_hint is updated and will not match the same obu frame. Now size
check is added before parsing obu frame to avoid this error.

Signed-off-by: Wenbin Chen 
---
 libavcodec/cbs_av1.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/libavcodec/cbs_av1.c b/libavcodec/cbs_av1.c
index 154d9156cf..9c51a8c7c8 100644
--- a/libavcodec/cbs_av1.c
+++ b/libavcodec/cbs_av1.c
@@ -1075,6 +1075,9 @@ static int cbs_av1_write_obu(CodedBitstreamContext *ctx,
 put_bits32(pbc, 0);
 }
 
+if (8 * (unit->data_size + obu->obu_size) > put_bits_left(pbc))
+return AVERROR(ENOSPC);
+
 td = NULL;
 start_pos = put_bits_count(pbc);
 
-- 
2.32.0

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH 1/3] libavcodec/qsvenc: Add framerate reset support to qsv

2022-09-22 Thread Wenbin Chen
Signed-off-by: Wenbin Chen 
---
 doc/encoders.texi   |  3 +++
 libavcodec/qsvenc.c | 26 ++
 libavcodec/qsvenc.h |  2 ++
 3 files changed, 31 insertions(+)

diff --git a/doc/encoders.texi b/doc/encoders.texi
index ac71f50ad2..4ed7ce1bb0 100644
--- a/doc/encoders.texi
+++ b/doc/encoders.texi
@@ -3360,6 +3360,9 @@ Change these value to reset qsv codec's max/min qp 
configuration.
 @item @var{low_delay_brc}
 Supported in h264_qsv and hevc_qsv.
 Change this value to reset qsv codec's low_delay_brc configuration.
+
+@item @var{framerate}
+Change this value to reset qsv codec's framerate configuration.
 @end table
 
 @subsection H264 options
diff --git a/libavcodec/qsvenc.c b/libavcodec/qsvenc.c
index 84c6e292aa..ce00cd302b 100644
--- a/libavcodec/qsvenc.c
+++ b/libavcodec/qsvenc.c
@@ -705,6 +705,7 @@ static int init_video_param(AVCodecContext *avctx, 
QSVEncContext *q)
 q->param.mfx.FrameInfo.FrameRateExtN  = avctx->time_base.den;
 q->param.mfx.FrameInfo.FrameRateExtD  = avctx->time_base.num;
 }
+q->old_framerate = avctx->framerate;
 
 ret = select_rc_mode(avctx, q);
 if (ret < 0)
@@ -1838,6 +1839,30 @@ static int update_low_delay_brc(AVCodecContext *avctx, 
QSVEncContext *q)
 return updated;
 }
 
+static int update_frame_rate(AVCodecContext *avctx, QSVEncContext *q)
+{
+int updated = 0;
+
+UPDATE_PARAM(q->old_framerate.num, avctx->framerate.num);
+UPDATE_PARAM(q->old_framerate.den, avctx->framerate.den);
+if (!updated)
+return 0;
+
+if (avctx->framerate.den > 0 && avctx->framerate.num > 0) {
+q->param.mfx.FrameInfo.FrameRateExtN = avctx->framerate.num;
+q->param.mfx.FrameInfo.FrameRateExtD = avctx->framerate.den;
+} else {
+q->param.mfx.FrameInfo.FrameRateExtN = avctx->time_base.den;
+q->param.mfx.FrameInfo.FrameRateExtD = avctx->time_base.num;
+}
+av_log(avctx, AV_LOG_DEBUG, "Reset framerate: %d/%d (%.2f fps).\n",
+   q->param.mfx.FrameInfo.FrameRateExtN,
+   q->param.mfx.FrameInfo.FrameRateExtD,
+   (double)q->param.mfx.FrameInfo.FrameRateExtN / 
q->param.mfx.FrameInfo.FrameRateExtD);
+
+return updated;
+}
+
 static int update_parameters(AVCodecContext *avctx, QSVEncContext *q,
  const AVFrame *frame)
 {
@@ -1851,6 +1876,7 @@ static int update_parameters(AVCodecContext *avctx, 
QSVEncContext *q,
 needReset |= update_gop_size(avctx, q);
 needReset |= update_rir(avctx, q);
 needReset |= update_low_delay_brc(avctx, q);
+needReset |= update_frame_rate(avctx, q);
 ret = update_min_max_qp(avctx, q);
 if (ret < 0)
 return ret;
diff --git a/libavcodec/qsvenc.h b/libavcodec/qsvenc.h
index f2b7ee361f..960197f159 100644
--- a/libavcodec/qsvenc.h
+++ b/libavcodec/qsvenc.h
@@ -271,6 +271,8 @@ typedef struct QSVEncContext {
 int old_min_qp_b;
 // This is used for low_delay_brc reset
 int old_low_delay_brc;
+// This is used for framerate reset
+AVRational old_framerate;
 } QSVEncContext;
 
 int ff_qsv_enc_init(AVCodecContext *avctx, QSVEncContext *q);
-- 
2.32.0

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH 2/3] libavcodec/qsvenc: Add bitrate reset support to qsvenc

2022-09-22 Thread Wenbin Chen
Signed-off-by: Wenbin Chen 
---
 doc/encoders.texi   |  6 ++
 libavcodec/qsvenc.c | 38 ++
 libavcodec/qsvenc.h |  5 +
 3 files changed, 49 insertions(+)

diff --git a/doc/encoders.texi b/doc/encoders.texi
index 4ed7ce1bb0..2b6412dbec 100644
--- a/doc/encoders.texi
+++ b/doc/encoders.texi
@@ -3363,6 +3363,12 @@ Change this value to reset qsv codec's low_delay_brc 
configuration.
 
 @item @var{framerate}
 Change this value to reset qsv codec's framerate configuration.
+
+@item @var{bit_rate}
+@item @var{rc_buffer_size}
+@item @var{rc_initial_buffer_occupancy}
+@item @var{rc_max_rate}
+Change these value to reset qsv codec's bitrate control configuration.
 @end table
 
 @subsection H264 options
diff --git a/libavcodec/qsvenc.c b/libavcodec/qsvenc.c
index ce00cd302b..3371711872 100644
--- a/libavcodec/qsvenc.c
+++ b/libavcodec/qsvenc.c
@@ -718,6 +718,10 @@ static int init_video_param(AVCodecContext *avctx, 
QSVEncContext *q)
 max_bitrate_kbps   = avctx->rc_max_rate / 1000;
 brc_param_multiplier   = (FFMAX(FFMAX3(target_bitrate_kbps, 
max_bitrate_kbps, buffer_size_in_kilobytes),
   initial_delay_in_kilobytes) + 0x1) / 
0x1;
+q->old_rc_buffer_size = avctx->rc_buffer_size;
+q->old_rc_initial_buffer_occupancy = avctx->rc_initial_buffer_occupancy;
+q->old_bit_rate = avctx->bit_rate;
+q->old_rc_max_rate = avctx->rc_max_rate;
 
 switch (q->param.mfx.RateControlMethod) {
 case MFX_RATECONTROL_CBR:
@@ -1863,6 +1867,39 @@ static int update_frame_rate(AVCodecContext *avctx, 
QSVEncContext *q)
 return updated;
 }
 
+static int update_bitrate(AVCodecContext *avctx, QSVEncContext *q)
+{
+int updated = 0;
+int target_bitrate_kbps, max_bitrate_kbps, brc_param_multiplier;
+int buffer_size_in_kilobytes, initial_delay_in_kilobytes;
+
+UPDATE_PARAM(q->old_rc_buffer_size, avctx->rc_buffer_size);
+UPDATE_PARAM(q->old_rc_initial_buffer_occupancy, 
avctx->rc_initial_buffer_occupancy);
+UPDATE_PARAM(q->old_bit_rate, avctx->bit_rate);
+UPDATE_PARAM(q->old_rc_max_rate, avctx->rc_max_rate);
+if (!updated)
+return 0;
+
+buffer_size_in_kilobytes   = avctx->rc_buffer_size / 8000;
+initial_delay_in_kilobytes = avctx->rc_initial_buffer_occupancy / 8000;
+target_bitrate_kbps= avctx->bit_rate / 1000;
+max_bitrate_kbps   = avctx->rc_max_rate / 1000;
+brc_param_multiplier   = (FFMAX(FFMAX3(target_bitrate_kbps, 
max_bitrate_kbps, buffer_size_in_kilobytes),
+initial_delay_in_kilobytes) + 0x1) / 
0x1;
+
+q->param.mfx.BufferSizeInKB = buffer_size_in_kilobytes / 
brc_param_multiplier;
+q->param.mfx.InitialDelayInKB = initial_delay_in_kilobytes / 
brc_param_multiplier;
+q->param.mfx.TargetKbps = target_bitrate_kbps / brc_param_multiplier;
+q->param.mfx.MaxKbps = max_bitrate_kbps / brc_param_multiplier;
+q->param.mfx.BRCParamMultiplier = brc_param_multiplier;
+av_log(avctx, AV_LOG_VERBOSE,
+"Reset BufferSizeInKB: %d; InitialDelayInKB: %d; "
+"TargetKbps: %d; MaxKbps: %d; BRCParamMultiplier: %d\n",
+q->param.mfx.BufferSizeInKB, q->param.mfx.InitialDelayInKB,
+q->param.mfx.TargetKbps, q->param.mfx.MaxKbps, 
q->param.mfx.BRCParamMultiplier);
+return updated;
+}
+
 static int update_parameters(AVCodecContext *avctx, QSVEncContext *q,
  const AVFrame *frame)
 {
@@ -1877,6 +1914,7 @@ static int update_parameters(AVCodecContext *avctx, 
QSVEncContext *q,
 needReset |= update_rir(avctx, q);
 needReset |= update_low_delay_brc(avctx, q);
 needReset |= update_frame_rate(avctx, q);
+needReset |= update_bitrate(avctx, q);
 ret = update_min_max_qp(avctx, q);
 if (ret < 0)
 return ret;
diff --git a/libavcodec/qsvenc.h b/libavcodec/qsvenc.h
index 960197f159..6e1132d2e3 100644
--- a/libavcodec/qsvenc.h
+++ b/libavcodec/qsvenc.h
@@ -273,6 +273,11 @@ typedef struct QSVEncContext {
 int old_low_delay_brc;
 // This is used for framerate reset
 AVRational old_framerate;
+// These are used for bitrate control reset
+int old_bit_rate;
+int old_rc_buffer_size;
+int old_rc_initial_buffer_occupancy;
+int old_rc_max_rate;
 } QSVEncContext;
 
 int ff_qsv_enc_init(AVCodecContext *avctx, QSVEncContext *q);
-- 
2.32.0

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH 3/3] libavcodec/qsvenc: Add pic_timing_sei reset support to qsv

2022-09-22 Thread Wenbin Chen
Signed-off-by: Wenbin Chen 
---
 doc/encoders.texi   |  4 
 libavcodec/qsvenc.c | 21 +
 libavcodec/qsvenc.h |  2 ++
 3 files changed, 27 insertions(+)

diff --git a/doc/encoders.texi b/doc/encoders.texi
index 2b6412dbec..741d545ea1 100644
--- a/doc/encoders.texi
+++ b/doc/encoders.texi
@@ -3369,6 +3369,10 @@ Change this value to reset qsv codec's framerate 
configuration.
 @item @var{rc_initial_buffer_occupancy}
 @item @var{rc_max_rate}
 Change these value to reset qsv codec's bitrate control configuration.
+
+@item @var{pic_timing_sei}
+Supported in h264_qsv and hevc_qsv.
+Change this value to reset qsv codec's pic_timing_sei configuration.
 @end table
 
 @subsection H264 options
diff --git a/libavcodec/qsvenc.c b/libavcodec/qsvenc.c
index 3371711872..c1a601f0b3 100644
--- a/libavcodec/qsvenc.c
+++ b/libavcodec/qsvenc.c
@@ -784,6 +784,7 @@ static int init_video_param(AVCodecContext *avctx, 
QSVEncContext *q)
 
 q->extco.PicTimingSEI = q->pic_timing_sei ?
 MFX_CODINGOPTION_ON : 
MFX_CODINGOPTION_UNKNOWN;
+q->old_pic_timing_sei = q->pic_timing_sei;
 
 if (q->rdo >= 0)
 q->extco.RateDistortionOpt = q->rdo > 0 ? MFX_CODINGOPTION_ON : 
MFX_CODINGOPTION_OFF;
@@ -1900,6 +1901,25 @@ static int update_bitrate(AVCodecContext *avctx, 
QSVEncContext *q)
 return updated;
 }
 
+static int update_pic_timing_sei(AVCodecContext *avctx, QSVEncContext *q)
+{
+int updated = 0;
+
+if (avctx->codec_id != AV_CODEC_ID_H264 && avctx->codec_id != 
AV_CODEC_ID_HEVC)
+return 0;
+
+UPDATE_PARAM(q->old_pic_timing_sei, q->pic_timing_sei);
+if (!updated)
+return 0;
+
+q->extco.PicTimingSEI = q->pic_timing_sei ?
+MFX_CODINGOPTION_ON : MFX_CODINGOPTION_UNKNOWN;
+av_log(avctx, AV_LOG_DEBUG, "Reset PicTimingSEI: %s\n",
+   print_threestate(q->extco.PicTimingSEI));
+
+return updated;
+}
+
 static int update_parameters(AVCodecContext *avctx, QSVEncContext *q,
  const AVFrame *frame)
 {
@@ -1915,6 +1935,7 @@ static int update_parameters(AVCodecContext *avctx, 
QSVEncContext *q,
 needReset |= update_low_delay_brc(avctx, q);
 needReset |= update_frame_rate(avctx, q);
 needReset |= update_bitrate(avctx, q);
+needReset |= update_pic_timing_sei(avctx, q);
 ret = update_min_max_qp(avctx, q);
 if (ret < 0)
 return ret;
diff --git a/libavcodec/qsvenc.h b/libavcodec/qsvenc.h
index 6e1132d2e3..486c996fc6 100644
--- a/libavcodec/qsvenc.h
+++ b/libavcodec/qsvenc.h
@@ -278,6 +278,8 @@ typedef struct QSVEncContext {
 int old_rc_buffer_size;
 int old_rc_initial_buffer_occupancy;
 int old_rc_max_rate;
+// This is used for SEI Timing reset
+int old_pic_timing_sei;
 } QSVEncContext;
 
 int ff_qsv_enc_init(AVCodecContext *avctx, QSVEncContext *q);
-- 
2.32.0

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH 1/2] libavcodec/qsvenc: Let runtime to set default parameter.

2022-09-26 Thread Wenbin Chen
Unset qsv_h264 and qsv_hevc's default settings. Let runtime to decide
these parameters, so that it can choose the best parameter and ffmpeg-qsv
can keep up with runtime's update.

Signed-off-by: Wenbin Chen 
---
 libavcodec/qsvenc_h264.c | 4 ++--
 libavcodec/qsvenc_hevc.c | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/libavcodec/qsvenc_h264.c b/libavcodec/qsvenc_h264.c
index 85826ae4be..fe777a6ae3 100644
--- a/libavcodec/qsvenc_h264.c
+++ b/libavcodec/qsvenc_h264.c
@@ -177,8 +177,8 @@ static const FFCodecDefault qsv_enc_defaults[] = {
 { "b", "1M"},
 { "refs",  "0" },
 // same as the x264 default
-{ "g", "250"   },
-{ "bf","3" },
+{ "g", "-1"},
+{ "bf","-1"},
 { "qmin",  "-1"},
 { "qmax",  "-1"},
 { "trellis",   "-1"},
diff --git a/libavcodec/qsvenc_hevc.c b/libavcodec/qsvenc_hevc.c
index 6ec6230999..0c5bec231d 100644
--- a/libavcodec/qsvenc_hevc.c
+++ b/libavcodec/qsvenc_hevc.c
@@ -290,7 +290,7 @@ static const FFCodecDefault qsv_enc_defaults[] = {
 { "b", "1M"},
 { "refs",  "0" },
 // same as the x264 default
-{ "g", "248"   },
+{ "g", "-1"},
 { "bf","-1"},
 { "qmin",  "-1"},
 { "qmax",  "-1"},
-- 
2.32.0

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH 2/2] libavcodec/qsvenc: Let runtime to decide targetUsage

2022-09-26 Thread Wenbin Chen
Set preset default value to MFX_TARGETUSAGE_UNKNOWN. Let runtime to
decide the targetUsage, so that ffmpeg-qsv can keep up with runtime's
update.

Signed-off-by: Wenbin Chen 
---
 libavcodec/qsvenc.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libavcodec/qsvenc.h b/libavcodec/qsvenc.h
index f2b7ee361f..4315463cd2 100644
--- a/libavcodec/qsvenc.h
+++ b/libavcodec/qsvenc.h
@@ -52,7 +52,7 @@
 
 #define QSV_COMMON_OPTS \
 { "async_depth", "Maximum processing parallelism", OFFSET(qsv.async_depth), 
AV_OPT_TYPE_INT, { .i64 = ASYNC_DEPTH_DEFAULT }, 1, INT_MAX, VE },  
\
-{ "preset", NULL, OFFSET(qsv.preset), AV_OPT_TYPE_INT, { .i64 = 
MFX_TARGETUSAGE_BALANCED }, MFX_TARGETUSAGE_BEST_QUALITY, 
MFX_TARGETUSAGE_BEST_SPEED,   VE, "preset" }, \
+{ "preset", NULL, OFFSET(qsv.preset), AV_OPT_TYPE_INT, { .i64 = 
MFX_TARGETUSAGE_UNKNOWN }, MFX_TARGETUSAGE_UNKNOWN, MFX_TARGETUSAGE_BEST_SPEED, 
  VE, "preset" },   \
 { "veryfast",NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 
MFX_TARGETUSAGE_BEST_SPEED  },   INT_MIN, INT_MAX, VE, "preset" },  
  \
 { "faster",  NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MFX_TARGETUSAGE_6  },
INT_MIN, INT_MAX, VE, "preset" },   
 \
 { "fast",NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MFX_TARGETUSAGE_5  },
INT_MIN, INT_MAX, VE, "preset" },   
 \
-- 
2.32.0

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH v2 2/2] libavcodec/qsvenc: Let runtime to decide targetUsage

2022-09-26 Thread Wenbin Chen
Set preset default value to MFX_TARGETUSAGE_UNKNOWN. Let runtime to
decide the targetUsage, so that ffmpeg-qsv can keep up with runtime's
update.

Signed-off-by: Wenbin Chen 
---
 libavcodec/qsvenc.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libavcodec/qsvenc.h b/libavcodec/qsvenc.h
index f2b7ee361f..4315463cd2 100644
--- a/libavcodec/qsvenc.h
+++ b/libavcodec/qsvenc.h
@@ -52,7 +52,7 @@
 
 #define QSV_COMMON_OPTS \
 { "async_depth", "Maximum processing parallelism", OFFSET(qsv.async_depth), 
AV_OPT_TYPE_INT, { .i64 = ASYNC_DEPTH_DEFAULT }, 1, INT_MAX, VE },  
\
-{ "preset", NULL, OFFSET(qsv.preset), AV_OPT_TYPE_INT, { .i64 = 
MFX_TARGETUSAGE_BALANCED }, MFX_TARGETUSAGE_BEST_QUALITY, 
MFX_TARGETUSAGE_BEST_SPEED,   VE, "preset" }, \
+{ "preset", NULL, OFFSET(qsv.preset), AV_OPT_TYPE_INT, { .i64 = 
MFX_TARGETUSAGE_UNKNOWN }, MFX_TARGETUSAGE_UNKNOWN, MFX_TARGETUSAGE_BEST_SPEED, 
  VE, "preset" },   \
 { "veryfast",NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 
MFX_TARGETUSAGE_BEST_SPEED  },   INT_MIN, INT_MAX, VE, "preset" },  
  \
 { "faster",  NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MFX_TARGETUSAGE_6  },
INT_MIN, INT_MAX, VE, "preset" },   
 \
 { "fast",NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MFX_TARGETUSAGE_5  },
INT_MIN, INT_MAX, VE, "preset" },   
 \
-- 
2.32.0

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH v2 1/2] libavcodec/qsvenc: Let runtime to set default parameter.

2022-09-26 Thread Wenbin Chen
Unset qsv_h264 and qsv_hevc's default settings. Let runtime to decide
these parameters, so that it can choose the best parameter and ffmpeg-qsv
can keep up with runtime's update.

Signed-off-by: Wenbin Chen 
---
 libavcodec/qsvenc_h264.c | 5 ++---
 libavcodec/qsvenc_hevc.c | 3 +--
 2 files changed, 3 insertions(+), 5 deletions(-)

diff --git a/libavcodec/qsvenc_h264.c b/libavcodec/qsvenc_h264.c
index 85826ae4be..11aaabbd1b 100644
--- a/libavcodec/qsvenc_h264.c
+++ b/libavcodec/qsvenc_h264.c
@@ -176,9 +176,8 @@ static const AVClass class = {
 static const FFCodecDefault qsv_enc_defaults[] = {
 { "b", "1M"},
 { "refs",  "0" },
-// same as the x264 default
-{ "g", "250"   },
-{ "bf","3" },
+{ "g", "-1"},
+{ "bf","-1"},
 { "qmin",  "-1"},
 { "qmax",  "-1"},
 { "trellis",   "-1"},
diff --git a/libavcodec/qsvenc_hevc.c b/libavcodec/qsvenc_hevc.c
index 6ec6230999..a5bf915954 100644
--- a/libavcodec/qsvenc_hevc.c
+++ b/libavcodec/qsvenc_hevc.c
@@ -289,8 +289,7 @@ static const AVClass class = {
 static const FFCodecDefault qsv_enc_defaults[] = {
 { "b", "1M"},
 { "refs",  "0" },
-// same as the x264 default
-{ "g", "248"   },
+{ "g", "-1"},
 { "bf","-1"},
 { "qmin",  "-1"},
 { "qmax",  "-1"},
-- 
2.32.0

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH] libavcodec/qsvenc.c: add max_frame_size support for hevc_qsv

2020-11-29 Thread wenbin . chen
From: Wenbinc-Bin 

The max_frame_size parameter is set only when codec is h264. Now I add hevc 
in that conditional statement.

Signed-off-by: Wenbin CHEN 
---
 libavcodec/qsvenc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libavcodec/qsvenc.c b/libavcodec/qsvenc.c
index 2bd2a56227..aba98dd689 100644
--- a/libavcodec/qsvenc.c
+++ b/libavcodec/qsvenc.c
@@ -691,7 +691,7 @@ FF_ENABLE_DEPRECATION_WARNINGS
 q->extparam_internal[q->nb_extparam_internal++] = (mfxExtBuffer 
*)&q->extco;
 
 #if QSV_HAVE_CO2
-if (avctx->codec_id == AV_CODEC_ID_H264) {
+if (avctx->codec_id == AV_CODEC_ID_H264 || avctx->codec_id == 
AV_CODEC_ID_HEVC) {
 if (q->int_ref_type >= 0)
 q->extco2.IntRefType = q->int_ref_type;
 if (q->int_ref_cycle_size >= 0)
-- 
2.25.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

[FFmpeg-devel] [PATCH] libavcodec/qsvenc: add max_frame_size support for hevc_qsv

2020-12-01 Thread wenbin . chen
From: Wenbinc-Bin 

The max_frame_size parameter is set only when codec is h264. Now I add
hevc in that conditional statement.

Signed-off-by: Wenbin CHEN 
---
 libavcodec/qsvenc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libavcodec/qsvenc.c b/libavcodec/qsvenc.c
index 2bd2a56227..aba98dd689 100644
--- a/libavcodec/qsvenc.c
+++ b/libavcodec/qsvenc.c
@@ -691,7 +691,7 @@ FF_ENABLE_DEPRECATION_WARNINGS
 q->extparam_internal[q->nb_extparam_internal++] = (mfxExtBuffer 
*)&q->extco;
 
 #if QSV_HAVE_CO2
-if (avctx->codec_id == AV_CODEC_ID_H264) {
+if (avctx->codec_id == AV_CODEC_ID_H264 || avctx->codec_id == 
AV_CODEC_ID_HEVC) {
 if (q->int_ref_type >= 0)
 q->extco2.IntRefType = q->int_ref_type;
 if (q->int_ref_cycle_size >= 0)
-- 
2.25.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

[FFmpeg-devel] [PATCH] libavcodec/qsvenc: add DisableDeblockingIdc support for qsv

2020-12-03 Thread wenbin . chen
From: Wenbinc-Bin 

MediaSDK already has a flag to control deblocking (DisableDeblockingIdc). Add 
dblk_idc parameter in ffmpeg to expose this flag to user.

Sigend-off-by: Wenbin Chen 
---
 libavcodec/qsvenc.c | 4 
 libavcodec/qsvenc.h | 3 +++
 2 files changed, 7 insertions(+)

diff --git a/libavcodec/qsvenc.c b/libavcodec/qsvenc.c
index aba98dd689..0d20d1968f 100644
--- a/libavcodec/qsvenc.c
+++ b/libavcodec/qsvenc.c
@@ -710,6 +710,10 @@ FF_ENABLE_DEPRECATION_WARNINGS
 if (q->max_slice_size >= 0)
 q->extco2.MaxSliceSize = q->max_slice_size;
 #endif
+#if QSV_HAVE_DISABLEDEBLOCKIDC
+if(q->dblk_idc >= 0)
+q->extco2.DisableDeblockingIdc = q->dblk_idc;
+#endif
 
 #if QSV_HAVE_TRELLIS
 if (avctx->trellis >= 0)
diff --git a/libavcodec/qsvenc.h b/libavcodec/qsvenc.h
index 6d305f87dd..3720320789 100644
--- a/libavcodec/qsvenc.h
+++ b/libavcodec/qsvenc.h
@@ -44,6 +44,7 @@
 
 #define QSV_HAVE_TRELLIS QSV_VERSION_ATLEAST(1, 8)
 #define QSV_HAVE_MAX_SLICE_SIZE QSV_VERSION_ATLEAST(1, 9)
+#define QSV_HAVE_DISABLEDEBLOCKIDC QSV_VERSION_ATLEAST(1, 9)
 #define QSV_HAVE_BREF_TYPE  QSV_VERSION_ATLEAST(1, 8)
 
 #define QSV_HAVE_LA QSV_VERSION_ATLEAST(1, 7)
@@ -97,6 +98,7 @@
 { "b_strategy", "Strategy to choose between I/P/B-frames", 
OFFSET(qsv.b_strategy),AV_OPT_TYPE_INT, { .i64 = -1 }, -1,  1, VE 
}, \
 { "forced_idr", "Forcing I frames as IDR frames", 
OFFSET(qsv.forced_idr), AV_OPT_TYPE_BOOL,{ .i64 = 0  },  0,  1, VE 
}, \
 { "low_power", "enable low power mode(experimental: many limitations by mfx 
version, BRC modes, etc.)", OFFSET(qsv.low_power), AV_OPT_TYPE_BOOL, { .i64 = 
0}, 0, 1, VE},\
+{ "dblk_idc", "value of DisableDeblockingIdc (default is 0), in range [0,2]",  
 OFFSET(qsv.dblk_idc),   AV_OPT_TYPE_INT,{ .i64 = 0 },   0,  2,  VE},\
 
 extern const AVCodecHWConfigInternal *const ff_qsv_enc_hw_configs[];
 
@@ -167,6 +169,7 @@ typedef struct QSVEncContext {
 int rdo;
 int max_frame_size;
 int max_slice_size;
+int dblk_idc;
 
 int tile_cols;
 int tile_rows;
-- 
2.25.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

[FFmpeg-devel] [PATCH] libavcodec/qsvenc: add low latency P-pyramid support for qsv

2020-12-09 Thread wenbin . chen
From: Wenbinc-Bin 

Add low latency P-pyramid support for qsv, and it relates to a new
command line parameter "-p_strategy". To enable this flag, user also
need to set "-bf" to -1 or 0.

Signed-off-by Wenbin Chen 
---
 libavcodec/qsvenc.c | 22 ++
 libavcodec/qsvenc.h |  2 ++
 2 files changed, 24 insertions(+)

diff --git a/libavcodec/qsvenc.c b/libavcodec/qsvenc.c
index 2bd2a56227..c3b41374e4 100644
--- a/libavcodec/qsvenc.c
+++ b/libavcodec/qsvenc.c
@@ -268,6 +268,13 @@ static void dump_video_param(AVCodecContext *avctx, 
QSVEncContext *q,
 case MFX_B_REF_PYRAMID: av_log(avctx, AV_LOG_VERBOSE, "pyramid");   break;
 default:av_log(avctx, AV_LOG_VERBOSE, "auto");  break;
 }
+av_log(avctx, AV_LOG_VERBOSE, "; PRefType: ");
+switch(co3->PRefType){
+case MFX_P_REF_DEFAULT: av_log(avctx, AV_LOG_VERBOSE, "default");   
break;
+case MFX_P_REF_SIMPLE:  av_log(avctx, AV_LOG_VERBOSE, "simple");   
break;
+case MFX_P_REF_PYRAMID: av_log(avctx, AV_LOG_VERBOSE, "pyramid");   
break;
+default:break;
+}
 av_log(avctx, AV_LOG_VERBOSE, "\n");
 #endif
 
@@ -777,6 +784,21 @@ FF_ENABLE_DEPRECATION_WARNINGS
 #if QSV_HAVE_CO3
 q->extco3.Header.BufferId  = MFX_EXTBUFF_CODING_OPTION3;
 q->extco3.Header.BufferSz  = sizeof(q->extco3);
+switch(q->p_strategy){
+case 0:
+q->extco3.PRefType = MFX_P_REF_DEFAULT;
+break;
+case 1:
+q->extco3.PRefType = MFX_P_REF_SIMPLE;
+break;
+case 2:
+q->extco3.PRefType = MFX_P_REF_PYRAMID;
+break;
+default:
+q->extco3.PRefType = MFX_P_REF_DEFAULT;
+av_log(avctx, AV_LOG_VERBOSE, "invalid p_strategy, set to 
default\n");
+break;
+}
 #if QSV_HAVE_GPB
 if (avctx->codec_id == AV_CODEC_ID_HEVC)
 q->extco3.GPB  = q->gpb ? MFX_CODINGOPTION_ON : 
MFX_CODINGOPTION_OFF;
diff --git a/libavcodec/qsvenc.h b/libavcodec/qsvenc.h
index 6d305f87dd..30aaf72ebd 100644
--- a/libavcodec/qsvenc.h
+++ b/libavcodec/qsvenc.h
@@ -95,6 +95,7 @@
 { "adaptive_i", "Adaptive I-frame placement", 
OFFSET(qsv.adaptive_i), AV_OPT_TYPE_INT, { .i64 = -1 }, -1,  1, VE 
}, \
 { "adaptive_b", "Adaptive B-frame placement", 
OFFSET(qsv.adaptive_b), AV_OPT_TYPE_INT, { .i64 = -1 }, -1,  1, VE 
}, \
 { "b_strategy", "Strategy to choose between I/P/B-frames", 
OFFSET(qsv.b_strategy),AV_OPT_TYPE_INT, { .i64 = -1 }, -1,  1, VE 
}, \
+{ "p_strategy", "enable P-pyramid 0-default 1-simple 2-pyramis",
OFFSET(qsv.p_strategy), AV_OPT_TYPE_INT,{ .i64 = 0}, 0,2, VE }, 
  \
 { "forced_idr", "Forcing I frames as IDR frames", 
OFFSET(qsv.forced_idr), AV_OPT_TYPE_BOOL,{ .i64 = 0  },  0,  1, VE 
}, \
 { "low_power", "enable low power mode(experimental: many limitations by mfx 
version, BRC modes, etc.)", OFFSET(qsv.low_power), AV_OPT_TYPE_BOOL, { .i64 = 
0}, 0, 1, VE},\
 
@@ -182,6 +183,7 @@ typedef struct QSVEncContext {
 int adaptive_i;
 int adaptive_b;
 int b_strategy;
+int p_strategy;
 int cavlc;
 
 int int_ref_type;
-- 
2.25.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

[FFmpeg-devel] [PATCH V2] libavcodec/qsvenc: add low latency P-pyramid support for qsv

2020-12-24 Thread wenbin . chen
From: Wenbinc-Bin 

Add low latency P-pyramid support for qsv, and it relates to a new
command line parameter "-p_strategy". To enable this flag, user also
need to set "-bf" to -1 or 0.

Signed-off-by Wenbin Chen 
---
 libavcodec/qsvenc.c | 23 +++
 libavcodec/qsvenc.h |  2 ++
 2 files changed, 25 insertions(+)

diff --git a/libavcodec/qsvenc.c b/libavcodec/qsvenc.c
index 0d20d1968f..8cb0ecff89 100644
--- a/libavcodec/qsvenc.c
+++ b/libavcodec/qsvenc.c
@@ -268,6 +268,14 @@ static void dump_video_param(AVCodecContext *avctx, 
QSVEncContext *q,
 case MFX_B_REF_PYRAMID: av_log(avctx, AV_LOG_VERBOSE, "pyramid");   break;
 default:av_log(avctx, AV_LOG_VERBOSE, "auto");  break;
 }
+
+av_log(avctx, AV_LOG_VERBOSE, "; PRefType: ");
+switch(co3->PRefType){
+case MFX_P_REF_DEFAULT: av_log(avctx, AV_LOG_VERBOSE, "default");   
break;
+case MFX_P_REF_SIMPLE:  av_log(avctx, AV_LOG_VERBOSE, "simple");   
break;
+case MFX_P_REF_PYRAMID: av_log(avctx, AV_LOG_VERBOSE, "pyramid");   
break;
+default:break;
+}
 av_log(avctx, AV_LOG_VERBOSE, "\n");
 #endif
 
@@ -781,6 +789,21 @@ FF_ENABLE_DEPRECATION_WARNINGS
 #if QSV_HAVE_CO3
 q->extco3.Header.BufferId  = MFX_EXTBUFF_CODING_OPTION3;
 q->extco3.Header.BufferSz  = sizeof(q->extco3);
+switch(q->p_strategy){
+case 0:
+q->extco3.PRefType = MFX_P_REF_DEFAULT;
+break;
+case 1:
+q->extco3.PRefType = MFX_P_REF_SIMPLE;
+break;
+case 2:
+q->extco3.PRefType = MFX_P_REF_PYRAMID;
+break;
+default:
+q->extco3.PRefType = MFX_P_REF_DEFAULT;
+av_log(avctx, AV_LOG_VERBOSE, "invalid p_strategy, set to 
default\n");
+break;
+}
 #if QSV_HAVE_GPB
 if (avctx->codec_id == AV_CODEC_ID_HEVC)
 q->extco3.GPB  = q->gpb ? MFX_CODINGOPTION_ON : 
MFX_CODINGOPTION_OFF;
diff --git a/libavcodec/qsvenc.h b/libavcodec/qsvenc.h
index 3720320789..a074561ca8 100644
--- a/libavcodec/qsvenc.h
+++ b/libavcodec/qsvenc.h
@@ -96,6 +96,7 @@
 { "adaptive_i", "Adaptive I-frame placement", 
OFFSET(qsv.adaptive_i), AV_OPT_TYPE_INT, { .i64 = -1 }, -1,  1, VE 
}, \
 { "adaptive_b", "Adaptive B-frame placement", 
OFFSET(qsv.adaptive_b), AV_OPT_TYPE_INT, { .i64 = -1 }, -1,  1, VE 
}, \
 { "b_strategy", "Strategy to choose between I/P/B-frames", 
OFFSET(qsv.b_strategy),AV_OPT_TYPE_INT, { .i64 = -1 }, -1,  1, VE 
}, \
+{ "p_strategy", "enable P-pyramid 0-default 1-simple 2-pyramid",
OFFSET(qsv.p_strategy), AV_OPT_TYPE_INT,{ .i64 = 0}, 0,2, VE }, 
\
 { "forced_idr", "Forcing I frames as IDR frames", 
OFFSET(qsv.forced_idr), AV_OPT_TYPE_BOOL,{ .i64 = 0  },  0,  1, VE 
}, \
 { "low_power", "enable low power mode(experimental: many limitations by mfx 
version, BRC modes, etc.)", OFFSET(qsv.low_power), AV_OPT_TYPE_BOOL, { .i64 = 
0}, 0, 1, VE},\
 { "dblk_idc", "value of DisableDeblockingIdc (default is 0), in range [0,2]",  
 OFFSET(qsv.dblk_idc),   AV_OPT_TYPE_INT,{ .i64 = 0 },   0,  2,  VE},\
@@ -185,6 +186,7 @@ typedef struct QSVEncContext {
 int adaptive_i;
 int adaptive_b;
 int b_strategy;
+int p_strategy;
 int cavlc;
 
 int int_ref_type;
-- 
2.25.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

[FFmpeg-devel] [PATCH V3] libavcodec/qsvenc: add low latency P-pyramid support for qsv

2020-12-28 Thread wenbin . chen
From: Wenbinc-Bin 

Add low latency P-pyramid support for qsv, and it relates to a new
command line parameter "-p_strategy". To enable this flag, user also
need to set "-bf" to 0.
P-strategy has two modes "simple" and "pyramid". The details of these
model refers to 
https://github.com/Intel-Media-SDK/MediaSDK/blob/master/doc/mediasdk-man.md#PRefType

Signed-off-by Wenbin Chen 
---
 libavcodec/qsvenc.c | 32 
 libavcodec/qsvenc.h |  2 ++
 2 files changed, 34 insertions(+)

diff --git a/libavcodec/qsvenc.c b/libavcodec/qsvenc.c
index 2bd2a56227..3b75a83432 100644
--- a/libavcodec/qsvenc.c
+++ b/libavcodec/qsvenc.c
@@ -268,6 +268,15 @@ static void dump_video_param(AVCodecContext *avctx, 
QSVEncContext *q,
 case MFX_B_REF_PYRAMID: av_log(avctx, AV_LOG_VERBOSE, "pyramid");   break;
 default:av_log(avctx, AV_LOG_VERBOSE, "auto");  break;
 }
+
+av_log(avctx, AV_LOG_VERBOSE, "; PRefType: ");
+switch(co3->PRefType){
+case MFX_P_REF_DEFAULT: av_log(avctx, AV_LOG_VERBOSE, "default");   break;
+case MFX_P_REF_SIMPLE:  av_log(avctx, AV_LOG_VERBOSE, "simple");break;
+case MFX_P_REF_PYRAMID: av_log(avctx, AV_LOG_VERBOSE, "pyramid");   break;
+default:av_log(avctx, AV_LOG_VERBOSE, "unknown");   break;
+}
+
 av_log(avctx, AV_LOG_VERBOSE, "\n");
 #endif
 
@@ -777,6 +786,29 @@ FF_ENABLE_DEPRECATION_WARNINGS
 #if QSV_HAVE_CO3
 q->extco3.Header.BufferId  = MFX_EXTBUFF_CODING_OPTION3;
 q->extco3.Header.BufferSz  = sizeof(q->extco3);
+
+switch(q->p_strategy){
+case 0:
+q->extco3.PRefType = MFX_P_REF_DEFAULT;
+break;
+case 1:
+q->extco3.PRefType = MFX_P_REF_SIMPLE;
+break;
+case 2:
+q->extco3.PRefType = MFX_P_REF_PYRAMID;
+break;
+default:
+q->extco3.PRefType = MFX_P_REF_DEFAULT;
+av_log(avctx, AV_LOG_WARNING, "invalid p_strategy, set to 
default\n");
+break;
+} 
+if((q->extco3.PRefType == MFX_P_REF_SIMPLE ||
+q->extco3.PRefType == MFX_P_REF_PYRAMID) && 
+avctx->max_b_frames != 0){
+av_log(avctx, AV_LOG_WARNING, "Please set max_b_frames(-bf) to 0 
to enable P-pyramid\n");
+}
+
+
 #if QSV_HAVE_GPB
 if (avctx->codec_id == AV_CODEC_ID_HEVC)
 q->extco3.GPB  = q->gpb ? MFX_CODINGOPTION_ON : 
MFX_CODINGOPTION_OFF;
diff --git a/libavcodec/qsvenc.h b/libavcodec/qsvenc.h
index 6d305f87dd..1b6149cccf 100644
--- a/libavcodec/qsvenc.h
+++ b/libavcodec/qsvenc.h
@@ -95,6 +95,7 @@
 { "adaptive_i", "Adaptive I-frame placement", 
OFFSET(qsv.adaptive_i), AV_OPT_TYPE_INT, { .i64 = -1 }, -1,  1, VE 
}, \
 { "adaptive_b", "Adaptive B-frame placement", 
OFFSET(qsv.adaptive_b), AV_OPT_TYPE_INT, { .i64 = -1 }, -1,  1, VE 
}, \
 { "b_strategy", "Strategy to choose between I/P/B-frames", 
OFFSET(qsv.b_strategy),AV_OPT_TYPE_INT, { .i64 = -1 }, -1,  1, VE 
}, \
+{ "p_strategy", "enable P-pyramid 0-default 1-simple 2-pyramid",
OFFSET(qsv.p_strategy), AV_OPT_TYPE_INT,{ .i64 = 0}, 0,2, VE }, 
\
 { "forced_idr", "Forcing I frames as IDR frames", 
OFFSET(qsv.forced_idr), AV_OPT_TYPE_BOOL,{ .i64 = 0  },  0,  1, VE 
}, \
 { "low_power", "enable low power mode(experimental: many limitations by mfx 
version, BRC modes, etc.)", OFFSET(qsv.low_power), AV_OPT_TYPE_BOOL, { .i64 = 
0}, 0, 1, VE},\
 
@@ -181,6 +182,7 @@ typedef struct QSVEncContext {
 int extbrc;
 int adaptive_i;
 int adaptive_b;
+int p_strategy;
 int b_strategy;
 int cavlc;
 
-- 
2.25.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

[FFmpeg-devel] [PATCH V4] libavcodec/qsvenc: add low latency P-pyramid support for qsv

2020-12-28 Thread wenbin . chen
From: Wenbinc-Bin 

Add low latency P-pyramid support for qsv, and it relates to a new
command line parameter "-p_strategy". To enable this flag, user also
need to set "-bf" to 0.
P-strategy has two modes "simple" and "pyramid". The details of these
model refers to 
https://github.com/Intel-Media-SDK/MediaSDK/blob/master/doc/mediasdk-man.md#PRefType
patch V4: modify the coding style problem.

Signed-off-by Wenbin Chen 
---
 libavcodec/qsvenc.c | 32 
 libavcodec/qsvenc.h |  2 ++
 2 files changed, 34 insertions(+)

diff --git a/libavcodec/qsvenc.c b/libavcodec/qsvenc.c
index 2bd2a56227..646b9f948e 100644
--- a/libavcodec/qsvenc.c
+++ b/libavcodec/qsvenc.c
@@ -268,6 +268,15 @@ static void dump_video_param(AVCodecContext *avctx, 
QSVEncContext *q,
 case MFX_B_REF_PYRAMID: av_log(avctx, AV_LOG_VERBOSE, "pyramid");   break;
 default:av_log(avctx, AV_LOG_VERBOSE, "auto");  break;
 }
+
+av_log(avctx, AV_LOG_VERBOSE, "; PRefType: ");
+switch (co3->PRefType) {
+case MFX_P_REF_DEFAULT: av_log(avctx, AV_LOG_VERBOSE, "default");   break;
+case MFX_P_REF_SIMPLE:  av_log(avctx, AV_LOG_VERBOSE, "simple");break;
+case MFX_P_REF_PYRAMID: av_log(avctx, AV_LOG_VERBOSE, "pyramid");   break;
+default:av_log(avctx, AV_LOG_VERBOSE, "unknown");   break;
+}
+
 av_log(avctx, AV_LOG_VERBOSE, "\n");
 #endif
 
@@ -777,6 +786,29 @@ FF_ENABLE_DEPRECATION_WARNINGS
 #if QSV_HAVE_CO3
 q->extco3.Header.BufferId  = MFX_EXTBUFF_CODING_OPTION3;
 q->extco3.Header.BufferSz  = sizeof(q->extco3);
+
+switch (q->p_strategy) {
+case 0:
+q->extco3.PRefType = MFX_P_REF_DEFAULT;
+break;
+case 1:
+q->extco3.PRefType = MFX_P_REF_SIMPLE;
+break;
+case 2:
+q->extco3.PRefType = MFX_P_REF_PYRAMID;
+break;
+default:
+q->extco3.PRefType = MFX_P_REF_DEFAULT;
+av_log(avctx, AV_LOG_WARNING, "invalid p_strategy, set to 
default\n");
+break;
+} 
+if((q->extco3.PRefType == MFX_P_REF_SIMPLE ||
+q->extco3.PRefType == MFX_P_REF_PYRAMID) && 
+avctx->max_b_frames != 0){
+av_log(avctx, AV_LOG_WARNING, "Please set max_b_frames(-bf) to 0 
to enable P-pyramid\n");
+}
+
+
 #if QSV_HAVE_GPB
 if (avctx->codec_id == AV_CODEC_ID_HEVC)
 q->extco3.GPB  = q->gpb ? MFX_CODINGOPTION_ON : 
MFX_CODINGOPTION_OFF;
diff --git a/libavcodec/qsvenc.h b/libavcodec/qsvenc.h
index 6d305f87dd..1b6149cccf 100644
--- a/libavcodec/qsvenc.h
+++ b/libavcodec/qsvenc.h
@@ -95,6 +95,7 @@
 { "adaptive_i", "Adaptive I-frame placement", 
OFFSET(qsv.adaptive_i), AV_OPT_TYPE_INT, { .i64 = -1 }, -1,  1, VE 
}, \
 { "adaptive_b", "Adaptive B-frame placement", 
OFFSET(qsv.adaptive_b), AV_OPT_TYPE_INT, { .i64 = -1 }, -1,  1, VE 
}, \
 { "b_strategy", "Strategy to choose between I/P/B-frames", 
OFFSET(qsv.b_strategy),AV_OPT_TYPE_INT, { .i64 = -1 }, -1,  1, VE 
}, \
+{ "p_strategy", "enable P-pyramid 0-default 1-simple 2-pyramid",
OFFSET(qsv.p_strategy), AV_OPT_TYPE_INT,{ .i64 = 0}, 0,2, VE }, 
\
 { "forced_idr", "Forcing I frames as IDR frames", 
OFFSET(qsv.forced_idr), AV_OPT_TYPE_BOOL,{ .i64 = 0  },  0,  1, VE 
}, \
 { "low_power", "enable low power mode(experimental: many limitations by mfx 
version, BRC modes, etc.)", OFFSET(qsv.low_power), AV_OPT_TYPE_BOOL, { .i64 = 
0}, 0, 1, VE},\
 
@@ -181,6 +182,7 @@ typedef struct QSVEncContext {
 int extbrc;
 int adaptive_i;
 int adaptive_b;
+int p_strategy;
 int b_strategy;
 int cavlc;
 
-- 
2.25.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

[FFmpeg-devel] [PATCH V5] libavcodec/qsvenc: add low latency P-pyramid support for qsv

2020-12-28 Thread wenbin . chen
From: Wenbinc-Bin 

Add low latency P-pyramid support for qsv, and it relates to a new
command line parameter "-p_strategy". To enable this flag, user also
need to set "-bf" to 0.
P-strategy has two modes "simple" and "pyramid". The details of these
model refers to 
https://github.com/Intel-Media-SDK/MediaSDK/blob/master/doc/mediasdk-man.md#PRefType
patch V2~V4: modify the coding style problem.
patch V5: forget to change "if" statement's coding style and fix it in V5.

Signed-off-by Wenbin Chen 
---
 libavcodec/qsvenc.c | 32 
 libavcodec/qsvenc.h |  2 ++
 2 files changed, 34 insertions(+)

diff --git a/libavcodec/qsvenc.c b/libavcodec/qsvenc.c
index 2bd2a56227..07df6f2364 100644
--- a/libavcodec/qsvenc.c
+++ b/libavcodec/qsvenc.c
@@ -268,6 +268,15 @@ static void dump_video_param(AVCodecContext *avctx, 
QSVEncContext *q,
 case MFX_B_REF_PYRAMID: av_log(avctx, AV_LOG_VERBOSE, "pyramid");   break;
 default:av_log(avctx, AV_LOG_VERBOSE, "auto");  break;
 }
+
+av_log(avctx, AV_LOG_VERBOSE, "; PRefType: ");
+switch (co3->PRefType) {
+case MFX_P_REF_DEFAULT: av_log(avctx, AV_LOG_VERBOSE, "default");   break;
+case MFX_P_REF_SIMPLE:  av_log(avctx, AV_LOG_VERBOSE, "simple");break;
+case MFX_P_REF_PYRAMID: av_log(avctx, AV_LOG_VERBOSE, "pyramid");   break;
+default:av_log(avctx, AV_LOG_VERBOSE, "unknown");   break;
+}
+
 av_log(avctx, AV_LOG_VERBOSE, "\n");
 #endif
 
@@ -777,6 +786,29 @@ FF_ENABLE_DEPRECATION_WARNINGS
 #if QSV_HAVE_CO3
 q->extco3.Header.BufferId  = MFX_EXTBUFF_CODING_OPTION3;
 q->extco3.Header.BufferSz  = sizeof(q->extco3);
+
+switch (q->p_strategy) {
+case 0:
+q->extco3.PRefType = MFX_P_REF_DEFAULT;
+break;
+case 1:
+q->extco3.PRefType = MFX_P_REF_SIMPLE;
+break;
+case 2:
+q->extco3.PRefType = MFX_P_REF_PYRAMID;
+break;
+default:
+q->extco3.PRefType = MFX_P_REF_DEFAULT;
+av_log(avctx, AV_LOG_WARNING, "invalid p_strategy, set to 
default\n");
+break;
+}
+if ((q->extco3.PRefType == MFX_P_REF_SIMPLE ||
+q->extco3.PRefType == MFX_P_REF_PYRAMID) &&
+avctx->max_b_frames != 0) {
+av_log(avctx, AV_LOG_WARNING, "Please set max_b_frames(-bf) to 0 
to enable P-pyramid\n");
+}
+
+
 #if QSV_HAVE_GPB
 if (avctx->codec_id == AV_CODEC_ID_HEVC)
 q->extco3.GPB  = q->gpb ? MFX_CODINGOPTION_ON : 
MFX_CODINGOPTION_OFF;
diff --git a/libavcodec/qsvenc.h b/libavcodec/qsvenc.h
index 6d305f87dd..1b6149cccf 100644
--- a/libavcodec/qsvenc.h
+++ b/libavcodec/qsvenc.h
@@ -95,6 +95,7 @@
 { "adaptive_i", "Adaptive I-frame placement", 
OFFSET(qsv.adaptive_i), AV_OPT_TYPE_INT, { .i64 = -1 }, -1,  1, VE 
}, \
 { "adaptive_b", "Adaptive B-frame placement", 
OFFSET(qsv.adaptive_b), AV_OPT_TYPE_INT, { .i64 = -1 }, -1,  1, VE 
}, \
 { "b_strategy", "Strategy to choose between I/P/B-frames", 
OFFSET(qsv.b_strategy),AV_OPT_TYPE_INT, { .i64 = -1 }, -1,  1, VE 
}, \
+{ "p_strategy", "enable P-pyramid 0-default 1-simple 2-pyramid",
OFFSET(qsv.p_strategy), AV_OPT_TYPE_INT,{ .i64 = 0}, 0,2, VE }, 
\
 { "forced_idr", "Forcing I frames as IDR frames", 
OFFSET(qsv.forced_idr), AV_OPT_TYPE_BOOL,{ .i64 = 0  },  0,  1, VE 
}, \
 { "low_power", "enable low power mode(experimental: many limitations by mfx 
version, BRC modes, etc.)", OFFSET(qsv.low_power), AV_OPT_TYPE_BOOL, { .i64 = 
0}, 0, 1, VE},\
 
@@ -181,6 +182,7 @@ typedef struct QSVEncContext {
 int extbrc;
 int adaptive_i;
 int adaptive_b;
+int p_strategy;
 int b_strategy;
 int cavlc;
 
-- 
2.25.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

[FFmpeg-devel] [PATCH V6] libavcodec/qsvenc: add low latency P-pyramid support for qsv

2020-12-29 Thread wenbin . chen
From: Wenbinc-Bin 

Add low latency P-pyramid support for qsv, and it relates to a new
command line parameter "-p_strategy". To enable this flag, user also
need to set "-bf" to 0. P-strategy has two modes "1-simple" and "2-pyramid".

Signed-off-by Wenbin Chen 
---
The details of the two models refer to
https://github.com/Intel-Media-SDK/MediaSDK/blob/master/doc/mediasdk-man.md#PRefType
patch V2~V4: modify the coding style problem.
patch V5: Forget to change "if" statement's coding style and fix it in V5.
patch V6: Change the patch description's position in patch.

 libavcodec/qsvenc.c | 32 
 libavcodec/qsvenc.h |  2 ++
 2 files changed, 34 insertions(+)

diff --git a/libavcodec/qsvenc.c b/libavcodec/qsvenc.c
index 2bd2a56227..07df6f2364 100644
--- a/libavcodec/qsvenc.c
+++ b/libavcodec/qsvenc.c
@@ -268,6 +268,15 @@ static void dump_video_param(AVCodecContext *avctx, 
QSVEncContext *q,
 case MFX_B_REF_PYRAMID: av_log(avctx, AV_LOG_VERBOSE, "pyramid");   break;
 default:av_log(avctx, AV_LOG_VERBOSE, "auto");  break;
 }
+
+av_log(avctx, AV_LOG_VERBOSE, "; PRefType: ");
+switch (co3->PRefType) {
+case MFX_P_REF_DEFAULT: av_log(avctx, AV_LOG_VERBOSE, "default");   break;
+case MFX_P_REF_SIMPLE:  av_log(avctx, AV_LOG_VERBOSE, "simple");break;
+case MFX_P_REF_PYRAMID: av_log(avctx, AV_LOG_VERBOSE, "pyramid");   break;
+default:av_log(avctx, AV_LOG_VERBOSE, "unknown");   break;
+}
+
 av_log(avctx, AV_LOG_VERBOSE, "\n");
 #endif
 
@@ -777,6 +786,29 @@ FF_ENABLE_DEPRECATION_WARNINGS
 #if QSV_HAVE_CO3
 q->extco3.Header.BufferId  = MFX_EXTBUFF_CODING_OPTION3;
 q->extco3.Header.BufferSz  = sizeof(q->extco3);
+
+switch (q->p_strategy) {
+case 0:
+q->extco3.PRefType = MFX_P_REF_DEFAULT;
+break;
+case 1:
+q->extco3.PRefType = MFX_P_REF_SIMPLE;
+break;
+case 2:
+q->extco3.PRefType = MFX_P_REF_PYRAMID;
+break;
+default:
+q->extco3.PRefType = MFX_P_REF_DEFAULT;
+av_log(avctx, AV_LOG_WARNING, "invalid p_strategy, set to 
default\n");
+break;
+}
+if ((q->extco3.PRefType == MFX_P_REF_SIMPLE ||
+q->extco3.PRefType == MFX_P_REF_PYRAMID) &&
+avctx->max_b_frames != 0) {
+av_log(avctx, AV_LOG_WARNING, "Please set max_b_frames(-bf) to 0 
to enable P-pyramid\n");
+}
+
+
 #if QSV_HAVE_GPB
 if (avctx->codec_id == AV_CODEC_ID_HEVC)
 q->extco3.GPB  = q->gpb ? MFX_CODINGOPTION_ON : 
MFX_CODINGOPTION_OFF;
diff --git a/libavcodec/qsvenc.h b/libavcodec/qsvenc.h
index 6d305f87dd..1b6149cccf 100644
--- a/libavcodec/qsvenc.h
+++ b/libavcodec/qsvenc.h
@@ -95,6 +95,7 @@
 { "adaptive_i", "Adaptive I-frame placement", 
OFFSET(qsv.adaptive_i), AV_OPT_TYPE_INT, { .i64 = -1 }, -1,  1, VE 
}, \
 { "adaptive_b", "Adaptive B-frame placement", 
OFFSET(qsv.adaptive_b), AV_OPT_TYPE_INT, { .i64 = -1 }, -1,  1, VE 
}, \
 { "b_strategy", "Strategy to choose between I/P/B-frames", 
OFFSET(qsv.b_strategy),AV_OPT_TYPE_INT, { .i64 = -1 }, -1,  1, VE 
}, \
+{ "p_strategy", "enable P-pyramid 0-default 1-simple 2-pyramid",
OFFSET(qsv.p_strategy), AV_OPT_TYPE_INT,{ .i64 = 0}, 0,2, VE }, 
\
 { "forced_idr", "Forcing I frames as IDR frames", 
OFFSET(qsv.forced_idr), AV_OPT_TYPE_BOOL,{ .i64 = 0  },  0,  1, VE 
}, \
 { "low_power", "enable low power mode(experimental: many limitations by mfx 
version, BRC modes, etc.)", OFFSET(qsv.low_power), AV_OPT_TYPE_BOOL, { .i64 = 
0}, 0, 1, VE},\
 
@@ -181,6 +182,7 @@ typedef struct QSVEncContext {
 int extbrc;
 int adaptive_i;
 int adaptive_b;
+int p_strategy;
 int b_strategy;
 int cavlc;
 
-- 
2.25.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

[FFmpeg-devel] [PATCH 01/10] libavcodec/qsvenc.c: add max_frame_size support for hevc_qsv

2021-01-25 Thread wenbin . chen
From: Wenbinc-Bin 

The max_frame_size parameter is set only when codec is h264. Now I add hevc in 
that conditional statement.

Signed-off-by: Wenbin Chen 
---
 libavcodec/qsvenc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libavcodec/qsvenc.c b/libavcodec/qsvenc.c
index 566a5c8552..0bca4f30e3 100644
--- a/libavcodec/qsvenc.c
+++ b/libavcodec/qsvenc.c
@@ -691,7 +691,7 @@ FF_ENABLE_DEPRECATION_WARNINGS
 q->extparam_internal[q->nb_extparam_internal++] = (mfxExtBuffer 
*)&q->extco;
 
 #if QSV_HAVE_CO2
-if (avctx->codec_id == AV_CODEC_ID_H264) {
+if (avctx->codec_id == AV_CODEC_ID_H264 || avctx->codec_id == 
AV_CODEC_ID_HEVC) {
 if (q->int_ref_type >= 0)
 q->extco2.IntRefType = q->int_ref_type;
 if (q->int_ref_cycle_size >= 0)
-- 
2.25.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

[FFmpeg-devel] [PATCH 02/10] libavcodec/qsvenc: add DisableDeblockingIdc support for qsv

2021-01-25 Thread wenbin . chen
From: Wenbinc-Bin 

MediaSDK already has a flag to control deblocking (DisableDeblockingIdc). Add 
dblk_idc parameter in ffmpeg to expose this flag to user.

Sigend-off-by: Wenbin Chen 
---
 libavcodec/qsvenc.c | 6 ++
 libavcodec/qsvenc.h | 3 +++
 2 files changed, 9 insertions(+)

diff --git a/libavcodec/qsvenc.c b/libavcodec/qsvenc.c
index 0bca4f30e3..2434feb660 100644
--- a/libavcodec/qsvenc.c
+++ b/libavcodec/qsvenc.c
@@ -295,6 +295,8 @@ static void dump_video_param(AVCodecContext *avctx, 
QSVEncContext *q,
 av_log(avctx, AV_LOG_VERBOSE, "FrameRateExtD: %"PRIu32"; FrameRateExtN: 
%"PRIu32" \n",
info->FrameInfo.FrameRateExtD, info->FrameInfo.FrameRateExtN);
 
+av_log(avctx, AV_LOG_VERBOSE, "DisableDeblockingIdc: %"PRIu32" \n", 
co2->DisableDeblockingIdc);
+
 }
 
 static int select_rc_mode(AVCodecContext *avctx, QSVEncContext *q)
@@ -710,6 +712,10 @@ FF_ENABLE_DEPRECATION_WARNINGS
 if (q->max_slice_size >= 0)
 q->extco2.MaxSliceSize = q->max_slice_size;
 #endif
+#if QSV_HAVE_DISABLEDEBLOCKIDC
+if(q->dblk_idc >= 0)
+q->extco2.DisableDeblockingIdc = q->dblk_idc;
+#endif
 
 #if QSV_HAVE_TRELLIS
 if (avctx->trellis >= 0)
diff --git a/libavcodec/qsvenc.h b/libavcodec/qsvenc.h
index 6d305f87dd..3720320789 100644
--- a/libavcodec/qsvenc.h
+++ b/libavcodec/qsvenc.h
@@ -44,6 +44,7 @@
 
 #define QSV_HAVE_TRELLIS QSV_VERSION_ATLEAST(1, 8)
 #define QSV_HAVE_MAX_SLICE_SIZE QSV_VERSION_ATLEAST(1, 9)
+#define QSV_HAVE_DISABLEDEBLOCKIDC QSV_VERSION_ATLEAST(1, 9)
 #define QSV_HAVE_BREF_TYPE  QSV_VERSION_ATLEAST(1, 8)
 
 #define QSV_HAVE_LA QSV_VERSION_ATLEAST(1, 7)
@@ -97,6 +98,7 @@
 { "b_strategy", "Strategy to choose between I/P/B-frames", 
OFFSET(qsv.b_strategy),AV_OPT_TYPE_INT, { .i64 = -1 }, -1,  1, VE 
}, \
 { "forced_idr", "Forcing I frames as IDR frames", 
OFFSET(qsv.forced_idr), AV_OPT_TYPE_BOOL,{ .i64 = 0  },  0,  1, VE 
}, \
 { "low_power", "enable low power mode(experimental: many limitations by mfx 
version, BRC modes, etc.)", OFFSET(qsv.low_power), AV_OPT_TYPE_BOOL, { .i64 = 
0}, 0, 1, VE},\
+{ "dblk_idc", "value of DisableDeblockingIdc (default is 0), in range [0,2]",  
 OFFSET(qsv.dblk_idc),   AV_OPT_TYPE_INT,{ .i64 = 0 },   0,  2,  VE},\
 
 extern const AVCodecHWConfigInternal *const ff_qsv_enc_hw_configs[];
 
@@ -167,6 +169,7 @@ typedef struct QSVEncContext {
 int rdo;
 int max_frame_size;
 int max_slice_size;
+int dblk_idc;
 
 int tile_cols;
 int tile_rows;
-- 
2.25.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

[FFmpeg-devel] [PATCH 03/10] libavcodec/qsvenc: add low latency P-pyramid support for qsv

2021-01-25 Thread wenbin . chen
From: Wenbinc-Bin 

Add low latency P-pyramid support for qsv, and it relates to a new
command line parameter "-p_strategy". To enable this flag, user also
need to set "-bf" to 0. P-strategy has two modes "1-simple" and "2-pyramid".
The details of the two models refer to
https://github.com/Intel-Media-SDK/MediaSDK/blob/master/doc/mediasdk-man.md#PRefType

Signed-off-by Wenbin Chen 
---
 libavcodec/qsvenc.c | 30 ++
 libavcodec/qsvenc.h |  2 ++
 2 files changed, 32 insertions(+)

diff --git a/libavcodec/qsvenc.c b/libavcodec/qsvenc.c
index 2434feb660..a811d06329 100644
--- a/libavcodec/qsvenc.c
+++ b/libavcodec/qsvenc.c
@@ -268,6 +268,14 @@ static void dump_video_param(AVCodecContext *avctx, 
QSVEncContext *q,
 case MFX_B_REF_PYRAMID: av_log(avctx, AV_LOG_VERBOSE, "pyramid");   break;
 default:av_log(avctx, AV_LOG_VERBOSE, "auto");  break;
 }
+
+av_log(avctx, AV_LOG_VERBOSE, "; PRefType: ");
+switch (co3->PRefType) {
+case MFX_P_REF_DEFAULT: av_log(avctx, AV_LOG_VERBOSE, "default");   break;
+case MFX_P_REF_SIMPLE:  av_log(avctx, AV_LOG_VERBOSE, "simple");break;
+case MFX_P_REF_PYRAMID: av_log(avctx, AV_LOG_VERBOSE, "pyramid");   break;
+default:av_log(avctx, AV_LOG_VERBOSE, "unknown");   break;
+}
 av_log(avctx, AV_LOG_VERBOSE, "\n");
 #endif
 
@@ -783,6 +791,28 @@ FF_ENABLE_DEPRECATION_WARNINGS
 #if QSV_HAVE_CO3
 q->extco3.Header.BufferId  = MFX_EXTBUFF_CODING_OPTION3;
 q->extco3.Header.BufferSz  = sizeof(q->extco3);
+
+switch (q->p_strategy) {
+case 0:
+q->extco3.PRefType = MFX_P_REF_DEFAULT;
+break;
+case 1:
+q->extco3.PRefType = MFX_P_REF_SIMPLE;
+break;
+case 2:
+q->extco3.PRefType = MFX_P_REF_PYRAMID;
+break;
+default:
+q->extco3.PRefType = MFX_P_REF_DEFAULT;
+av_log(avctx, AV_LOG_WARNING, "invalid p_strategy, set to 
default\n");
+break;
+}
+if ((q->extco3.PRefType == MFX_P_REF_SIMPLE ||
+q->extco3.PRefType == MFX_P_REF_PYRAMID) &&
+avctx->max_b_frames != 0) {
+av_log(avctx, AV_LOG_WARNING, "Please set max_b_frames(-bf) to 0 
to enable P-pyramid\n");
+}
+
 #if QSV_HAVE_GPB
 if (avctx->codec_id == AV_CODEC_ID_HEVC)
 q->extco3.GPB  = q->gpb ? MFX_CODINGOPTION_ON : 
MFX_CODINGOPTION_OFF;
diff --git a/libavcodec/qsvenc.h b/libavcodec/qsvenc.h
index 3720320789..7da6e0a50f 100644
--- a/libavcodec/qsvenc.h
+++ b/libavcodec/qsvenc.h
@@ -95,6 +95,7 @@
 { "extbrc", "Extended bitrate control",   
OFFSET(qsv.extbrc), AV_OPT_TYPE_INT, { .i64 = -1 }, -1,  1, VE 
}, \
 { "adaptive_i", "Adaptive I-frame placement", 
OFFSET(qsv.adaptive_i), AV_OPT_TYPE_INT, { .i64 = -1 }, -1,  1, VE 
}, \
 { "adaptive_b", "Adaptive B-frame placement", 
OFFSET(qsv.adaptive_b), AV_OPT_TYPE_INT, { .i64 = -1 }, -1,  1, VE 
}, \
+{ "p_strategy", "enable P-pyramid 0-default 1-simple 2-pyramid",
OFFSET(qsv.p_strategy), AV_OPT_TYPE_INT,{ .i64 = 0}, 0,2, VE }, 
\
 { "b_strategy", "Strategy to choose between I/P/B-frames", 
OFFSET(qsv.b_strategy),AV_OPT_TYPE_INT, { .i64 = -1 }, -1,  1, VE 
}, \
 { "forced_idr", "Forcing I frames as IDR frames", 
OFFSET(qsv.forced_idr), AV_OPT_TYPE_BOOL,{ .i64 = 0  },  0,  1, VE 
}, \
 { "low_power", "enable low power mode(experimental: many limitations by mfx 
version, BRC modes, etc.)", OFFSET(qsv.low_power), AV_OPT_TYPE_BOOL, { .i64 = 
0}, 0, 1, VE},\
@@ -185,6 +186,7 @@ typedef struct QSVEncContext {
 int adaptive_i;
 int adaptive_b;
 int b_strategy;
+int p_strategy;
 int cavlc;
 
 int int_ref_type;
-- 
2.25.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

[FFmpeg-devel] [PATCH 04/10] libavcodec/qsvdec.c: extract frame packing arrangement data

2021-01-25 Thread wenbin . chen
From: Wenbinc-Bin 

Use h264_sei to parse SEI data got from MediaSDK. Extract frame
packing arrangement information from SEI data and config AVStereo3D
side data for decoded frame.

Sigend-off-by: Wenbin Chen 
---
 libavcodec/qsv_internal.h |   2 +
 libavcodec/qsvdec.c   | 149 ++
 libavcodec/qsvdec.h   |   6 ++
 3 files changed, 157 insertions(+)

diff --git a/libavcodec/qsv_internal.h b/libavcodec/qsv_internal.h
index 6b2fbbe252..aa3da97c99 100644
--- a/libavcodec/qsv_internal.h
+++ b/libavcodec/qsv_internal.h
@@ -52,6 +52,8 @@
 
 #define QSV_MAX_ENC_PAYLOAD 2   // # of mfxEncodeCtrl payloads supported
 
+#define QSV_PAYLOAD_SIZE 1024
+
 #define QSV_VERSION_ATLEAST(MAJOR, MINOR)   \
 (MFX_VERSION_MAJOR > (MAJOR) || \
  MFX_VERSION_MAJOR == (MAJOR) && MFX_VERSION_MINOR >= (MINOR))
diff --git a/libavcodec/qsvdec.c b/libavcodec/qsvdec.c
index d10f90a0db..5cb49cfb4a 100644
--- a/libavcodec/qsvdec.c
+++ b/libavcodec/qsvdec.c
@@ -36,10 +36,12 @@
 #include "libavutil/pixfmt.h"
 #include "libavutil/time.h"
 #include "libavutil/imgutils.h"
+#include "libavutil/stereo3d.h"
 
 #include "avcodec.h"
 #include "internal.h"
 #include "decode.h"
+#include "get_bits.h"
 #include "qsv.h"
 #include "qsv_internal.h"
 #include "qsvdec.h"
@@ -398,6 +400,147 @@ static QSVFrame *find_frame(QSVContext *q, 
mfxFrameSurface1 *surf)
 return NULL;
 }
 
+static int h264_decode_fpa(H264SEIFramePacking *fpa, AVFrame *frame)
+{
+if (!fpa || !frame) {
+return AVERROR(EINVAL);
+}
+
+if (!fpa->arrangement_cancel_flag &&
+fpa->arrangement_type <= 6 &&
+fpa->content_interpretation_type > 0 &&
+fpa->content_interpretation_type < 3) {
+AVStereo3D *stereo = av_stereo3d_create_side_data(frame);
+if (stereo) {
+switch (fpa->arrangement_type) {
+case 0:
+stereo->type = AV_STEREO3D_CHECKERBOARD;
+break;
+case 1:
+stereo->type = AV_STEREO3D_COLUMNS;
+break;
+case 2:
+stereo->type = AV_STEREO3D_LINES;
+break;
+case 3:
+if (fpa->quincunx_sampling_flag)
+stereo->type = AV_STEREO3D_SIDEBYSIDE_QUINCUNX;
+else
+stereo->type = AV_STEREO3D_SIDEBYSIDE;
+break;
+case 4:
+stereo->type = AV_STEREO3D_TOPBOTTOM;
+break;
+case 5:
+stereo->type = AV_STEREO3D_FRAMESEQUENCE;
+if (fpa->current_frame_is_frame0_flag)
+stereo->view = AV_STEREO3D_VIEW_LEFT;
+else
+stereo->view = AV_STEREO3D_VIEW_RIGHT;
+break;
+case 6:
+stereo->type = AV_STEREO3D_2D;
+break;
+}
+
+if (fpa->content_interpretation_type == 2)
+stereo->flags = AV_STEREO3D_FLAG_INVERT;
+}
+}
+return 0;
+}
+
+static int h264_parse_side_data(AVCodecContext *avctx, QSVContext *q, AVFrame 
*frame)
+{
+GetBitContext gb_payload;
+uint8_t *sei_buffer;
+int sei_buffer_index;
+int ret;
+
+/* remove emulation prevention bytes */
+sei_buffer = (uint8_t *)av_mallocz(q->payload.NumBit / 8);
+if (!sei_buffer) {
+av_freep(&sei_buffer);
+return AVERROR(ENOMEM);
+}
+sei_buffer_index = 0;
+for (int i = 0; i < q->payload.NumBit / 8; i++) {
+if (q->payload.Data[i] == 3)
+i++;
+sei_buffer[sei_buffer_index] = q->payload.Data[i];
+sei_buffer_index += 1;
+}
+
+ret = init_get_bits8(&gb_payload, sei_buffer, sei_buffer_index+1);
+if (ret < 0) {
+av_freep(&sei_buffer);
+return ret;
+}
+
+ret = ff_h264_sei_decode(&q->sei, &gb_payload, &q->ps, avctx);
+if (ret < 0) {
+av_freep(&sei_buffer);
+return ret;
+}
+
+switch (q->payload.Type) {
+case SEI_TYPE_FRAME_PACKING_ARRANGEMENT:
+ret = h264_decode_fpa(&q->sei.frame_packing, frame);
+break;
+default:
+break;
+}
+
+av_freep(&sei_buffer);
+return ret;
+}
+
+static int extract_frame_side_data(AVCodecContext *avctx, QSVContext *q, 
AVFrame *frame)
+{
+mfxU64 ts;
+mfxStatus sts;
+int ret;
+
+if (q->payload.BufSize == 0) {
+q->payload.Data = av_mallocz(QSV_PAYLOAD_SIZE);
+if (!q->payload.Data) {
+av_freep(&q->payload.Data);
+return AVERROR(ENOMEM);
+}
+q->payload.BufSize = QSV_PAYLOAD_SIZE;
+}
+
+st

[FFmpeg-devel] [PATCH 05/10] libavcodec/qsvenc: Add transform skip for hevc_qsv

2021-01-25 Thread wenbin . chen
From: Wenbinc-Bin 

Add transform skip option for hevc_qsv. Command line option
is "transform_skip". By enabling this option, the
transform_skip_enabled_flag in PPS will be set to 1. This option
is only supported in the platform newer than ICL.

Signed-off-by Wenbin Chen 
---
 libavcodec/qsvenc.c  | 10 --
 libavcodec/qsvenc.h  |  1 +
 libavcodec/qsvenc_hevc.c |  3 +++
 3 files changed, 12 insertions(+), 2 deletions(-)

diff --git a/libavcodec/qsvenc.c b/libavcodec/qsvenc.c
index a811d06329..f2fcd09ae0 100644
--- a/libavcodec/qsvenc.c
+++ b/libavcodec/qsvenc.c
@@ -304,7 +304,9 @@ static void dump_video_param(AVCodecContext *avctx, 
QSVEncContext *q,
info->FrameInfo.FrameRateExtD, info->FrameInfo.FrameRateExtN);
 
 av_log(avctx, AV_LOG_VERBOSE, "DisableDeblockingIdc: %"PRIu32" \n", 
co2->DisableDeblockingIdc);
-
+#if QSV_VERSION_ATLEAST(1, 26)
+av_log(avctx, AV_LOG_VERBOSE, "TransformSkip: %s \n", 
print_threestate(co3->TransformSkip));
+#endif
 }
 
 static int select_rc_mode(AVCodecContext *avctx, QSVEncContext *q)
@@ -813,10 +815,14 @@ FF_ENABLE_DEPRECATION_WARNINGS
 av_log(avctx, AV_LOG_WARNING, "Please set max_b_frames(-bf) to 0 
to enable P-pyramid\n");
 }
 
+if (avctx->codec_id == AV_CODEC_ID_HEVC) {
+#if QSV_VERSION_ATLEAST(1, 26)
+q->extco3.TransformSkip  = q->transform_skip ? MFX_CODINGOPTION_ON 
: MFX_CODINGOPTION_OFF;
+#endif
 #if QSV_HAVE_GPB
-if (avctx->codec_id == AV_CODEC_ID_HEVC)
 q->extco3.GPB  = q->gpb ? MFX_CODINGOPTION_ON : 
MFX_CODINGOPTION_OFF;
 #endif
+}
 q->extparam_internal[q->nb_extparam_internal++] = (mfxExtBuffer 
*)&q->extco3;
 #endif
 }
diff --git a/libavcodec/qsvenc.h b/libavcodec/qsvenc.h
index 7da6e0a50f..d1de914724 100644
--- a/libavcodec/qsvenc.h
+++ b/libavcodec/qsvenc.h
@@ -197,6 +197,7 @@ typedef struct QSVEncContext {
 int repeat_pps;
 int low_power;
 int gpb;
+int transform_skip;
 
 int a53_cc;
 
diff --git a/libavcodec/qsvenc_hevc.c b/libavcodec/qsvenc_hevc.c
index 347f30655e..07a7e3b2be 100644
--- a/libavcodec/qsvenc_hevc.c
+++ b/libavcodec/qsvenc_hevc.c
@@ -246,6 +246,9 @@ static const AVOption options[] = {
 
 { "tile_cols",  "Number of columns for tiled encoding",   
OFFSET(qsv.tile_cols),AV_OPT_TYPE_INT, { .i64 = 0 }, 0, UINT16_MAX, VE },
 { "tile_rows",  "Number of rows for tiled encoding",  
OFFSET(qsv.tile_rows),AV_OPT_TYPE_INT, { .i64 = 0 }, 0, UINT16_MAX, VE },
+#if QSV_VERSION_ATLEAST(1, 26)
+{ "transform_skip", "Turn this option ON to enable transformskip",   
OFFSET(qsv.transform_skip),  AV_OPT_TYPE_INT,{ .i64 = -1},   -1, 1, 
 VE},
+#endif
 
 { NULL },
 };
-- 
2.25.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

[FFmpeg-devel] [PATCH 07/10] libavocdec/qsvenc_hevc: encode RGB format rawvideo

2021-01-25 Thread wenbin . chen
From: Wenbinc-Bin 

Add support for hevc_qsv to input RGB format frame. It will
transform frame to yuv inside MediaSDK instead of using auto
scale. Hevc_qsv supports directly encoding BGRA and X2RGB10Le format.
X2RGB10Le is only supported in VDENC (-low_power 1).
The X2RGB10Le correspond to the A2RGB20 format in MediaSDK, and for
A2RGB10 the two MSBs is A channels while this two bits in X2RGB10Le is
undefined. MediaSDK team is discussing about this, so I leave an interface
here.

Sigend-of-by: Wenbin Chen 
---
 libavcodec/qsv.c | 16 
 libavcodec/qsvenc.c  | 19 +--
 libavcodec/qsvenc_hevc.c |  6 ++
 3 files changed, 39 insertions(+), 2 deletions(-)

diff --git a/libavcodec/qsv.c b/libavcodec/qsv.c
index 6e3154e1a3..7ade53e278 100644
--- a/libavcodec/qsv.c
+++ b/libavcodec/qsv.c
@@ -196,6 +196,12 @@ int ff_qsv_print_warning(void *log_ctx, mfxStatus err,
 enum AVPixelFormat ff_qsv_map_fourcc(uint32_t fourcc)
 {
 switch (fourcc) {
+#if QSV_VERSION_ATLEAST(1, 9)
+case MFX_FOURCC_A2RGB10: return AV_PIX_FMT_X2RGB10LE;
+#endif
+#if QSV_VERSION_ATLEAST(1, 17)
+case MFX_FOURCC_RGB4: return AV_PIX_FMT_BGRA;
+#endif
 case MFX_FOURCC_NV12: return AV_PIX_FMT_NV12;
 case MFX_FOURCC_P010: return AV_PIX_FMT_P010;
 case MFX_FOURCC_P8:   return AV_PIX_FMT_PAL8;
@@ -222,6 +228,16 @@ int ff_qsv_map_pixfmt(enum AVPixelFormat format, uint32_t 
*fourcc)
 *fourcc = MFX_FOURCC_P010;
 return AV_PIX_FMT_P010;
 #if CONFIG_VAAPI
+#if QSV_VERSION_ATLEAST(1, 9)
+case AV_PIX_FMT_BGRA:
+*fourcc = MFX_FOURCC_RGB4;
+return AV_PIX_FMT_BGRA;
+#endif
+#if QSV_VERSION_ATLEAST(1, 17)
+case AV_PIX_FMT_X2RGB10LE:
+*fourcc = MFX_FOURCC_A2RGB10;
+return AV_PIX_FMT_X2RGB10LE;
+#endif
 case AV_PIX_FMT_YUV422P:
 case AV_PIX_FMT_YUYV422:
 *fourcc = MFX_FOURCC_YUY2;
diff --git a/libavcodec/qsvenc.c b/libavcodec/qsvenc.c
index addc61bf89..4b345aca0a 100644
--- a/libavcodec/qsvenc.c
+++ b/libavcodec/qsvenc.c
@@ -613,6 +613,13 @@ static int init_video_param(AVCodecContext *avctx, 
QSVEncContext *q)
 brc_param_multiplier   = (FFMAX(FFMAX3(target_bitrate_kbps, 
max_bitrate_kbps, buffer_size_in_kilobytes),
   initial_delay_in_kilobytes) + 0x1) / 
0x1;
 
+#if QSV_VERSION_ATLEAST(1, 9)
+if (sw_format == AV_PIX_FMT_X2RGB10LE && q->low_power != 1) {
+av_log(avctx, AV_LOG_ERROR, "Only VDENC support encoding x2rgb10\n");
+return AVERROR(EINVAL);
+}
+#endif
+
 switch (q->param.mfx.RateControlMethod) {
 case MFX_RATECONTROL_CBR:
 case MFX_RATECONTROL_VBR:
@@ -1422,8 +1429,16 @@ static int submit_frame(QSVEncContext *q, const AVFrame 
*frame,
 qf->surface.Info.PicStruct |= MFX_PICSTRUCT_FRAME_TRIPLING;
 
 qf->surface.Data.PitchLow  = qf->frame->linesize[0];
-qf->surface.Data.Y = qf->frame->data[0];
-qf->surface.Data.UV= qf->frame->data[1];
+if (frame->format == AV_PIX_FMT_X2RGB10LE ||
+frame->format == AV_PIX_FMT_BGRA) {
+qf->surface.Data.B = qf->frame->data[0];
+qf->surface.Data.G = qf->frame->data[0] + 1;
+qf->surface.Data.R = qf->frame->data[0] + 2;
+qf->surface.Data.A = qf->frame->data[0] + 3;
+} else {
+qf->surface.Data.Y = qf->frame->data[0];
+qf->surface.Data.UV= qf->frame->data[1];
+}
 }
 
 qf->surface.Data.TimeStamp = av_rescale_q(frame->pts, q->avctx->time_base, 
(AVRational){1, 9});
diff --git a/libavcodec/qsvenc_hevc.c b/libavcodec/qsvenc_hevc.c
index 07a7e3b2be..18e110d140 100644
--- a/libavcodec/qsvenc_hevc.c
+++ b/libavcodec/qsvenc_hevc.c
@@ -289,6 +289,12 @@ AVCodec ff_hevc_qsv_encoder = {
 .pix_fmts   = (const enum AVPixelFormat[]){ AV_PIX_FMT_NV12,
 AV_PIX_FMT_P010,
 AV_PIX_FMT_QSV,
+#if QSV_VERSION_ATLEAST(1, 17)
+AV_PIX_FMT_BGRA,
+#endif
+#if QSV_VERSION_ATLEAST(1, 9)
+AV_PIX_FMT_X2RGB10LE,
+#endif
 AV_PIX_FMT_NONE },
 .priv_class = &class,
 .defaults   = qsv_enc_defaults,
-- 
2.25.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

[FFmpeg-devel] [PATCH 06/10] libavcodec/qsvenc.c: add ROI support to qsv encoder

2021-01-25 Thread wenbin . chen
From: Wenbinc-Bin 

Use the mfxEncoderCtrl parameter to enable ROI. Get side data 
"AVRegionOfInterest"
from filter "addroi" and use it to configure "mfxExtEncoderROI" which is
the MediaSDK's ROI configuration.
It is the first time to use encoderCtrl feature in ffmpeg-qsv,
so add allocate and free process as well.

Sigend-off-by: Wenbin Chen 
---
 libavcodec/qsv_internal.h |  3 ++
 libavcodec/qsvenc.c   | 74 +++
 2 files changed, 77 insertions(+)

diff --git a/libavcodec/qsv_internal.h b/libavcodec/qsv_internal.h
index aa3da97c99..d846a2741a 100644
--- a/libavcodec/qsv_internal.h
+++ b/libavcodec/qsv_internal.h
@@ -51,6 +51,9 @@
 #define ASYNC_DEPTH_DEFAULT 4   // internal parallelism
 
 #define QSV_MAX_ENC_PAYLOAD 2   // # of mfxEncodeCtrl payloads supported
+#define QSV_MAX_ENC_EXTPARAM 2
+
+#define QSV_MAX_ROI_NUM 256
 
 #define QSV_PAYLOAD_SIZE 1024
 
diff --git a/libavcodec/qsvenc.c b/libavcodec/qsvenc.c
index f2fcd09ae0..addc61bf89 100644
--- a/libavcodec/qsvenc.c
+++ b/libavcodec/qsvenc.c
@@ -1291,6 +1291,13 @@ static void clear_unused_frames(QSVEncContext *q)
 QSVFrame *cur = q->work_frames;
 while (cur) {
 if (cur->used && !cur->surface.Data.Locked) {
+
+for (int i = 0; i < cur->enc_ctrl.NumExtParam; i++) {
+if (cur->enc_ctrl.ExtParam[i])
+av_freep(&(cur->enc_ctrl.ExtParam[i]));
+}
+cur->enc_ctrl.NumExtParam = 0;
+
 free_encoder_ctrl_payloads(&cur->enc_ctrl);
 if (cur->frame->format == AV_PIX_FMT_QSV) {
 av_frame_unref(cur->frame);
@@ -1333,6 +1340,12 @@ static int get_free_frame(QSVEncContext *q, QSVFrame **f)
 av_freep(&frame);
 return AVERROR(ENOMEM);
 }
+frame->enc_ctrl.ExtParam = av_mallocz(sizeof(mfxExtBuffer*) * 
QSV_MAX_ENC_EXTPARAM);
+if (!frame->enc_ctrl.ExtParam) {
+av_free(frame->enc_ctrl.Payload);
+av_freep(&frame);
+return AVERROR(ENOMEM);
+}
 *last = frame;
 
 *f = frame;
@@ -1436,6 +1449,7 @@ static int encode_frame(AVCodecContext *avctx, 
QSVEncContext *q,
 const AVFrame *frame)
 {
 AVPacket new_pkt = { 0 };
+AVFrameSideData *sd;
 mfxBitstream *bs;
 #if QSV_VERSION_ATLEAST(1, 26)
 mfxExtAVCEncodedFrameInfo *enc_info;
@@ -1446,6 +1460,7 @@ static int encode_frame(AVCodecContext *avctx, 
QSVEncContext *q,
 mfxSyncPoint *sync = NULL;
 QSVFrame *qsv_frame = NULL;
 mfxEncodeCtrl* enc_ctrl = NULL;
+mfxExtEncoderROI *enc_roi = NULL;
 int ret;
 
 if (frame) {
@@ -1480,6 +1495,8 @@ static int encode_frame(AVCodecContext *avctx, 
QSVEncContext *q,
 bs->Data  = new_pkt.data;
 bs->MaxLength = new_pkt.size;
 
+enc_info = NULL;
+enc_buf = NULL;
 #if QSV_VERSION_ATLEAST(1, 26)
 if (avctx->codec_id == AV_CODEC_ID_H264) {
 enc_info = av_mallocz(sizeof(*enc_info));
@@ -1502,6 +1519,62 @@ static int encode_frame(AVCodecContext *avctx, 
QSVEncContext *q,
 q->set_encode_ctrl_cb(avctx, frame, &qsv_frame->enc_ctrl);
 }
 
+#if QSV_VERSION_ATLEAST(1, 22)
+sd = NULL;
+if (frame) {
+sd = av_frame_get_side_data(frame,
+AV_FRAME_DATA_REGIONS_OF_INTEREST);
+}
+if (sd) {
+AVRegionOfInterest *roi;
+uint32_t roi_size;
+int nb_roi, i;
+
+enc_roi = (mfxExtEncoderROI *)av_mallocz(sizeof(*enc_roi));
+if (!enc_roi) {
+av_packet_unref(&new_pkt);
+if (bs)
+av_freep(bs);
+if (enc_info)
+av_freep(&enc_info);
+if (enc_buf)
+av_freep(&enc_buf);
+return AVERROR(ENOMEM);
+}
+roi = (AVRegionOfInterest *)sd->data;
+roi_size = roi->self_size;
+av_assert0(roi_size && sd->size % roi_size == 0);
+nb_roi = sd->size / roi_size;
+if (nb_roi > QSV_MAX_ROI_NUM) {
+av_log(avctx, AV_LOG_WARNING, "More ROIs set than "
+"supported by driver (%d > %d).\n",
+nb_roi, QSV_MAX_ROI_NUM);
+nb_roi = QSV_MAX_ROI_NUM;
+}
+enc_roi->Header.BufferId = MFX_EXTBUFF_ENCODER_ROI;
+enc_roi->Header.BufferSz = sizeof(*enc_roi);
+enc_roi->NumROI  = nb_roi;
+enc_roi->ROIMode = MFX_ROI_MODE_QP_DELTA;
+// For overlapping regions, the first in the array takes priority.
+for (i = 0; i < nb_roi; i++) {
+roi = (AVRegionOfInterest*)(sd->data + roi_size * i);
+av_assert0(roi->qoffset.den != 0);
+
+enc_roi->ROI[i].Top = roi->top & 0xfff0;
+enc_roi->ROI[i].Bottom = roi->bottom &am

[FFmpeg-devel] [PATCH 08/10] libavcodec/qsvenc: add horizontal intra refresh and refresh cycle dist

2021-01-25 Thread wenbin . chen
From: Wenbinc-Bin 

Add an new intra refresh type: "horizontal", and an new param
ref_cycle_dist. This param specify the distance between the
beginnings of the intra-refresh cycles in frames.

Signed-off-by: Wenbin Chen 
---
 libavcodec/qsvenc.c  | 13 +++--
 libavcodec/qsvenc.h  |  1 +
 libavcodec/qsvenc_h264.c |  5 -
 3 files changed, 16 insertions(+), 3 deletions(-)

diff --git a/libavcodec/qsvenc.c b/libavcodec/qsvenc.c
index 4b345aca0a..d16f1094c8 100644
--- a/libavcodec/qsvenc.c
+++ b/libavcodec/qsvenc.c
@@ -217,8 +217,10 @@ static void dump_video_param(AVCodecContext *avctx, 
QSVEncContext *q,
 
 #if QSV_HAVE_CO2
 av_log(avctx, AV_LOG_VERBOSE,
-   "RecoveryPointSEI: %s IntRefType: %"PRIu16"; IntRefCycleSize: 
%"PRIu16"; IntRefQPDelta: %"PRId16"\n",
-   print_threestate(co->RecoveryPointSEI), co2->IntRefType, 
co2->IntRefCycleSize, co2->IntRefQPDelta);
+   "RecoveryPointSEI: %s IntRefType: %"PRIu16"; IntRefCycleSize: 
%"PRIu16
+   "; IntRefQPDelta: %"PRId16"; IntRefCycleDist: %"PRId16"\n",
+   print_threestate(co->RecoveryPointSEI), co2->IntRefType, 
co2->IntRefCycleSize,
+   co2->IntRefQPDelta, co3->IntRefCycleDist);
 
 av_log(avctx, AV_LOG_VERBOSE, "MaxFrameSize: %d; ", co2->MaxFrameSize);
 #if QSV_HAVE_MAX_SLICE_SIZE
@@ -822,6 +824,13 @@ FF_ENABLE_DEPRECATION_WARNINGS
 av_log(avctx, AV_LOG_WARNING, "Please set max_b_frames(-bf) to 0 
to enable P-pyramid\n");
 }
 
+#if QSV_VERSION_ATLEAST(1, 16)
+if (avctx->codec_id == AV_CODEC_ID_H264) {
+if (q->int_ref_cycle_dist)
+q->extco3.IntRefCycleDist = q->int_ref_cycle_dist;
+}
+#endif
+
 if (avctx->codec_id == AV_CODEC_ID_HEVC) {
 #if QSV_VERSION_ATLEAST(1, 26)
 q->extco3.TransformSkip  = q->transform_skip ? MFX_CODINGOPTION_ON 
: MFX_CODINGOPTION_OFF;
diff --git a/libavcodec/qsvenc.h b/libavcodec/qsvenc.h
index d1de914724..99befefde1 100644
--- a/libavcodec/qsvenc.h
+++ b/libavcodec/qsvenc.h
@@ -192,6 +192,7 @@ typedef struct QSVEncContext {
 int int_ref_type;
 int int_ref_cycle_size;
 int int_ref_qp_delta;
+int int_ref_cycle_dist;
 int recovery_point_sei;
 
 int repeat_pps;
diff --git a/libavcodec/qsvenc_h264.c b/libavcodec/qsvenc_h264.c
index ddafc45ec3..47583621b4 100644
--- a/libavcodec/qsvenc_h264.c
+++ b/libavcodec/qsvenc_h264.c
@@ -129,10 +129,13 @@ static const AVOption options[] = {
 { "int_ref_type", "Intra refresh type",
  OFFSET(qsv.int_ref_type),AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 
UINT16_MAX, VE, "int_ref_type" },
 { "none", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 0 }, .flags = VE, 
"int_ref_type" },
 { "vertical", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 1 }, .flags = VE, 
"int_ref_type" },
+{ "horizontal", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 2 }, .flags = VE, 
"int_ref_type" },
 { "int_ref_cycle_size", "Number of frames in the intra refresh cycle", 
  OFFSET(qsv.int_ref_cycle_size),  AV_OPT_TYPE_INT, { .i64 = -1 },  
 -1, UINT16_MAX, VE },
 { "int_ref_qp_delta",   "QP difference for the refresh MBs",   
  OFFSET(qsv.int_ref_qp_delta),AV_OPT_TYPE_INT, { .i64 = INT16_MIN }, 
INT16_MIN,  INT16_MAX, VE },
 { "recovery_point_sei", "Insert recovery point SEI messages",  
  OFFSET(qsv.recovery_point_sei),  AV_OPT_TYPE_INT, { .i64 = -1 },  
 -1,  1, VE },
-
+#if QSV_VERSION_ATLEAST(1, 16)
+{ "int_ref_cycle_dist",   "Distance between the beginnings of the 
intra-refresh cycles in frames",  OFFSET(qsv.int_ref_cycle_dist),  
AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT16_MAX, VE },
+#endif
 { "profile", NULL, OFFSET(qsv.profile), AV_OPT_TYPE_INT, { .i64 = 
MFX_PROFILE_UNKNOWN }, 0, INT_MAX, VE, "profile" },
 { "unknown" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MFX_PROFILE_UNKNOWN 
 }, INT_MIN, INT_MAX, VE, "profile" },
 { "baseline", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 
MFX_PROFILE_AVC_BASELINE }, INT_MIN, INT_MAX, VE, "profile" },
-- 
2.25.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

[FFmpeg-devel] [PATCH 09/10] libavcodec/qsvdec: using suggested num to set init_pool_size

2021-01-25 Thread wenbin . chen
From: Wenbinc-Bin 

The init_pool_size is set to be 64 and it is too many.
Use IOSurfQuery to get NumFrameSuggest which is the suggested
number of frame that needed to be allocated when initial the decoder
Considering the hevc_qsv encoder's async is 4 (default)
and max_b_frames is 8 (default) and decoder may followed by VPP,
use NumFrameSuggest + 16 to set init_pool_size.

Sigend-off-by Wenbin Chen 
---
 fftools/ffmpeg_qsv.c |  9 -
 libavcodec/qsvdec.c  | 28 +++-
 2 files changed, 35 insertions(+), 2 deletions(-)

diff --git a/fftools/ffmpeg_qsv.c b/fftools/ffmpeg_qsv.c
index 960c88b69d..3862dc1e7d 100644
--- a/fftools/ffmpeg_qsv.c
+++ b/fftools/ffmpeg_qsv.c
@@ -74,6 +74,7 @@ int qsv_init(AVCodecContext *s)
 InputStream *ist = s->opaque;
 AVHWFramesContext *frames_ctx;
 AVQSVFramesContext *frames_hwctx;
+int suggest_pool_size;
 int ret;
 
 if (!hw_device_ctx) {
@@ -82,6 +83,12 @@ int qsv_init(AVCodecContext *s)
 return ret;
 }
 
+suggest_pool_size = 0;
+if (ist->hw_frames_ctx) {
+frames_ctx = (AVHWFramesContext *)ist->hw_frames_ctx->data;
+suggest_pool_size = frames_ctx->initial_pool_size;
+}
+
 av_buffer_unref(&ist->hw_frames_ctx);
 ist->hw_frames_ctx = av_hwframe_ctx_alloc(hw_device_ctx);
 if (!ist->hw_frames_ctx)
@@ -94,7 +101,7 @@ int qsv_init(AVCodecContext *s)
 frames_ctx->height= FFALIGN(s->coded_height, 32);
 frames_ctx->format= AV_PIX_FMT_QSV;
 frames_ctx->sw_format = s->sw_pix_fmt;
-frames_ctx->initial_pool_size = 64 + s->extra_hw_frames;
+frames_ctx->initial_pool_size = suggest_pool_size + 16 + 
s->extra_hw_frames;
 frames_hwctx->frame_type  = MFX_MEMTYPE_VIDEO_MEMORY_DECODER_TARGET;
 
 ret = av_hwframe_ctx_init(ist->hw_frames_ctx);
diff --git a/libavcodec/qsvdec.c b/libavcodec/qsvdec.c
index 5cb49cfb4a..fba7d9cee6 100644
--- a/libavcodec/qsvdec.c
+++ b/libavcodec/qsvdec.c
@@ -720,6 +720,7 @@ int ff_qsv_process_data(AVCodecContext *avctx, QSVContext 
*q,
 AVFrame *frame, int *got_frame, AVPacket *pkt)
 {
 int ret;
+int first_init;
 mfxVideoParam param = { 0 };
 enum AVPixelFormat pix_fmt = AV_PIX_FMT_NV12;
 
@@ -738,12 +739,20 @@ int ff_qsv_process_data(AVCodecContext *avctx, QSVContext 
*q,
 if (!avctx->coded_height)
 avctx->coded_height = 720;
 
+first_init = 0;
+if (!q->session)
+first_init = 1;
+
 ret = qsv_decode_header(avctx, q, pkt, pix_fmt, ¶m);
 
 if (ret >= 0 && (q->orig_pix_fmt != 
ff_qsv_map_fourcc(param.mfx.FrameInfo.FourCC) ||
 avctx->coded_width  != param.mfx.FrameInfo.Width ||
-avctx->coded_height != param.mfx.FrameInfo.Height)) {
+avctx->coded_height != param.mfx.FrameInfo.Height ||
+first_init == 1)) {
 AVPacket zero_pkt = {0};
+mfxFrameAllocRequest request;
+AVHWFramesContext *hw_frames_ctx;
+memset(&request, 0, sizeof(request));
 
 if (q->buffered_count) {
 q->reinit_flag = 1;
@@ -758,6 +767,23 @@ int ff_qsv_process_data(AVCodecContext *avctx, QSVContext 
*q,
 avctx->coded_width  = param.mfx.FrameInfo.Width;
 avctx->coded_height = param.mfx.FrameInfo.Height;
 
+if (first_init == 0) {
+hw_frames_ctx = (AVHWFramesContext *)avctx->hw_frames_ctx->data;
+hw_frames_ctx->initial_pool_size = 0;
+ret = qsv_decode_preinit(avctx, q, pix_fmt, ¶m);
+if (ret < 0)
+goto reinit_fail;
+}
+
+ret = MFXVideoDECODE_QueryIOSurf(q->session, ¶m, &request);
+if (ret < 0)
+return ff_qsv_print_error(avctx, ret, "Error querying IO surface");
+
+if (avctx->hw_frames_ctx) {
+hw_frames_ctx = (AVHWFramesContext *)avctx->hw_frames_ctx->data;
+hw_frames_ctx->initial_pool_size = request.NumFrameSuggested;
+}
+
 ret = qsv_decode_preinit(avctx, q, pix_fmt, ¶m);
 if (ret < 0)
 goto reinit_fail;
-- 
2.25.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

[FFmpeg-devel] [PATCH 10/10] libavcodec/qsvdec: move unref before get_format

2021-01-25 Thread wenbin . chen
From: Wenbinc-Bin 

Qsv decoder needs to call preinit() twice to get NumFrameSuggest
to config init_pool_size. The hw_frame_ctx is released at the
second time calling preinit(). The hw_frame_ctx is AVBufferRef, so
it release the source when the last unref is called. When the old
context is released, the new one is already created, and somehow the device
memory is stil be taken, even if the destory memory function is called.
Moving unref before creating new context can solve this problem.

Signed-off-by Wenbin Chen 
---
 libavcodec/qsvdec.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/libavcodec/qsvdec.c b/libavcodec/qsvdec.c
index fba7d9cee6..23494c217d 100644
--- a/libavcodec/qsvdec.c
+++ b/libavcodec/qsvdec.c
@@ -179,6 +179,8 @@ static int qsv_decode_preinit(AVCodecContext *avctx, 
QSVContext *q, enum AVPixel
 pix_fmt,/* system memory format obtained from bitstream parser 
*/
 AV_PIX_FMT_NONE };
 
+av_buffer_unref(&q->frames_ctx.mids_buf);
+av_buffer_unref(&q->frames_ctx.hw_frames_ctx);
 ret = ff_get_format(avctx, pix_fmts);
 if (ret < 0) {
 q->orig_pix_fmt = avctx->pix_fmt = AV_PIX_FMT_NONE;
-- 
2.25.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

[FFmpeg-devel] [PATCH V6 1/5] hwcontext_vaapi: Use PRIME_2 memory type for modifiers.

2021-12-07 Thread Wenbin Chen
From: Bas Nieuwenhuizen 

This way we can pass explicit modifiers in. Sometimes the
modifier matters for the number of memory planes that
libva accepts, in particular when dealing with
driver-compressed textures. Furthermore the driver might
not actually be able to determine the implicit modifier
if all the buffer-passing has used explicit modifier.
All these issues should be resolved by passing in the
modifier, and for that we switch to using the PRIME_2
memory type.

Tested with experimental radeonsi patches for modifiers
and kmsgrab. Also tested with radeonsi without the
patches to double-check it works without PRIME_2 support.

v2:
  Cache PRIME_2 support to avoid doing two calls every time on
  libva drivers that do not support it.

v3:
  Remove prime2_vas usage.

Signed-off-by: Bas Nieuwenhuizen 
---
 libavutil/hwcontext_vaapi.c | 158 ++--
 1 file changed, 114 insertions(+), 44 deletions(-)

diff --git a/libavutil/hwcontext_vaapi.c b/libavutil/hwcontext_vaapi.c
index 83e542876d..75acc851d6 100644
--- a/libavutil/hwcontext_vaapi.c
+++ b/libavutil/hwcontext_vaapi.c
@@ -79,6 +79,9 @@ typedef struct VAAPIFramesContext {
 unsigned int rt_format;
 // Whether vaDeriveImage works.
 int derive_works;
+// Caches whether VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_2 is unsupported for
+// surface imports.
+int prime_2_import_unsupported;
 } VAAPIFramesContext;
 
 typedef struct VAAPIMapping {
@@ -1022,32 +1025,17 @@ static void vaapi_unmap_from_drm(AVHWFramesContext 
*dst_fc,
 static int vaapi_map_from_drm(AVHWFramesContext *src_fc, AVFrame *dst,
   const AVFrame *src, int flags)
 {
+VAAPIFramesContext *src_vafc = src_fc->internal->priv;
 AVHWFramesContext  *dst_fc =
 (AVHWFramesContext*)dst->hw_frames_ctx->data;
 AVVAAPIDeviceContext  *dst_dev = dst_fc->device_ctx->hwctx;
 const AVDRMFrameDescriptor *desc;
 const VAAPIFormatDescriptor *format_desc;
 VASurfaceID surface_id;
-VAStatus vas;
+VAStatus vas = VA_STATUS_SUCCESS;
+int use_prime2;
 uint32_t va_fourcc;
-int err, i, j, k;
-
-unsigned long buffer_handle;
-VASurfaceAttribExternalBuffers buffer_desc;
-VASurfaceAttrib attrs[2] = {
-{
-.type  = VASurfaceAttribMemoryType,
-.flags = VA_SURFACE_ATTRIB_SETTABLE,
-.value.type= VAGenericValueTypeInteger,
-.value.value.i = VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME,
-},
-{
-.type  = VASurfaceAttribExternalBufferDescriptor,
-.flags = VA_SURFACE_ATTRIB_SETTABLE,
-.value.type= VAGenericValueTypePointer,
-.value.value.p = &buffer_desc,
-}
-};
+int err, i, j;
 
 desc = (AVDRMFrameDescriptor*)src->data[0];
 
@@ -1083,35 +1071,117 @@ static int vaapi_map_from_drm(AVHWFramesContext 
*src_fc, AVFrame *dst,
 format_desc = vaapi_format_from_fourcc(va_fourcc);
 av_assert0(format_desc);
 
-buffer_handle = desc->objects[0].fd;
-buffer_desc.pixel_format = va_fourcc;
-buffer_desc.width= src_fc->width;
-buffer_desc.height   = src_fc->height;
-buffer_desc.data_size= desc->objects[0].size;
-buffer_desc.buffers  = &buffer_handle;
-buffer_desc.num_buffers  = 1;
-buffer_desc.flags= 0;
-
-k = 0;
-for (i = 0; i < desc->nb_layers; i++) {
-for (j = 0; j < desc->layers[i].nb_planes; j++) {
-buffer_desc.pitches[k] = desc->layers[i].planes[j].pitch;
-buffer_desc.offsets[k] = desc->layers[i].planes[j].offset;
-++k;
+use_prime2 = !src_vafc->prime_2_import_unsupported &&
+ desc->objects[0].format_modifier != DRM_FORMAT_MOD_INVALID;
+if (use_prime2) {
+VADRMPRIMESurfaceDescriptor prime_desc;
+VASurfaceAttrib prime_attrs[2] = {
+{
+.type  = VASurfaceAttribMemoryType,
+.flags = VA_SURFACE_ATTRIB_SETTABLE,
+.value.type= VAGenericValueTypeInteger,
+.value.value.i = VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_2,
+},
+{
+.type  = VASurfaceAttribExternalBufferDescriptor,
+.flags = VA_SURFACE_ATTRIB_SETTABLE,
+.value.type= VAGenericValueTypePointer,
+.value.value.p = &prime_desc,
+}
+};
+prime_desc.fourcc = va_fourcc;
+prime_desc.width = src_fc->width;
+prime_desc.height = src_fc->height;
+prime_desc.num_objects = desc->nb_objects;
+for (i = 0; i < desc->nb_objects; ++i) {
+prime_desc.objects[i].fd = desc->objects[i].fd;
+prime_desc.objects[i].size = desc->objects[i].size;
+prime_desc.objects[i].drm_format_modifier =
+desc->objects[i].format_modifier;
 }
-}
-buffer_desc.num_planes = k;
 
-if (format_desc->chroma_planes

[FFmpeg-devel] [PATCH V6 2/5] libavutil/hwcontext_vaapi: Add a new nv12 format map to support vulkan frame

2021-12-07 Thread Wenbin Chen
Vulkan will map nv12 to R8 and GR88, so add this map to vaapi to support
vulkan frame.

Signed-off-by: Wenbin Chen 
---
 libavutil/hwcontext_vaapi.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/libavutil/hwcontext_vaapi.c b/libavutil/hwcontext_vaapi.c
index 75acc851d6..994b744e4d 100644
--- a/libavutil/hwcontext_vaapi.c
+++ b/libavutil/hwcontext_vaapi.c
@@ -992,6 +992,7 @@ static const struct {
 } vaapi_drm_format_map[] = {
 #ifdef DRM_FORMAT_R8
 DRM_MAP(NV12, 2, DRM_FORMAT_R8,  DRM_FORMAT_RG88),
+DRM_MAP(NV12, 2, DRM_FORMAT_R8,  DRM_FORMAT_GR88),
 #endif
 DRM_MAP(NV12, 1, DRM_FORMAT_NV12),
 #if defined(VA_FOURCC_P010) && defined(DRM_FORMAT_R16)
-- 
2.25.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH V6 3/5] libavutil/hwcontext_vulkan: Allocate vkFrame in one memory

2021-12-07 Thread Wenbin Chen
The vaapi can import external frame, but the planes of the external
frames should be in the same drm object. A new option "contiguous_planes"
is added to device. This flag tells device to allocate places in one
memory. When device is derived from vaapi this flag will be enabled.
A new flag frame_flag is also added to AVVulkanFramesContext. User
can use this flag to force enable or disable this behaviour.
A new variable "offset "is added to AVVKFrame. It describe describe the
offset from the memory currently bound to the VkImage.

Signed-off-by: Wenbin Chen 
---
 libavutil/hwcontext_vulkan.c | 68 +++-
 libavutil/hwcontext_vulkan.h | 24 +
 2 files changed, 91 insertions(+), 1 deletion(-)

diff --git a/libavutil/hwcontext_vulkan.c b/libavutil/hwcontext_vulkan.c
index a0437c9661..eef9009ae1 100644
--- a/libavutil/hwcontext_vulkan.c
+++ b/libavutil/hwcontext_vulkan.c
@@ -103,8 +103,14 @@ typedef struct VulkanDevicePriv {
 /* Settings */
 int use_linear_images;
 
+/* allocate planes in a contiguous memory */
+int contiguous_planes;
+
 /* Nvidia */
 int dev_is_nvidia;
+
+/* Intel */
+int dev_is_intel;
 } VulkanDevicePriv;
 
 typedef struct VulkanFramesPriv {
@@ -153,6 +159,8 @@ typedef struct AVVkFrameInternal {
 av_free((void *)props);
\
 }
 
+#define VKF_FLAG(x, f) (((x) & (~AV_VK_FRAME_FLAG_NONE)) & (f))
+
 static const struct {
 enum AVPixelFormat pixfmt;
 const VkFormat vkfmts[4];
@@ -1374,6 +1382,13 @@ static int 
vulkan_device_create_internal(AVHWDeviceContext *ctx,
 if (opt_d)
 p->use_linear_images = strtol(opt_d->value, NULL, 10);
 
+opt_d = av_dict_get(opts, "contiguous_planes", NULL, 0);
+if (opt_d)
+p->contiguous_planes = strtol(opt_d->value, NULL, 10);
+else
+p->contiguous_planes = -1;
+
+
 hwctx->enabled_dev_extensions = dev_info.ppEnabledExtensionNames;
 hwctx->nb_enabled_dev_extensions = dev_info.enabledExtensionCount;
 
@@ -1425,6 +1440,8 @@ static int vulkan_device_init(AVHWDeviceContext *ctx)
 
 p->dev_is_nvidia = (p->props.properties.vendorID == 0x10de);
 
+p->dev_is_intel = (p->props.properties.vendorID == 0x8086);
+
 vk->GetPhysicalDeviceQueueFamilyProperties(hwctx->phys_dev, &queue_num, 
NULL);
 if (!queue_num) {
 av_log(ctx, AV_LOG_ERROR, "Failed to get queues!\n");
@@ -1742,8 +1759,12 @@ static int alloc_bind_mem(AVHWFramesContext *hwfc, 
AVVkFrame *f,
 AVHWDeviceContext *ctx = hwfc->device_ctx;
 VulkanDevicePriv *p = ctx->internal->priv;
 FFVulkanFunctions *vk = &p->vkfn;
+AVVulkanFramesContext *hwfctx = hwfc->hwctx;
 const int planes = av_pix_fmt_count_planes(hwfc->sw_format);
 VkBindImageMemoryInfo bind_info[AV_NUM_DATA_POINTERS] = { { 0 } };
+VkMemoryRequirements memory_requirements = { 0 };
+int mem_size = 0;
+int mem_size_list[AV_NUM_DATA_POINTERS] = { 0 };
 
 AVVulkanDeviceContext *hwctx = ctx->hwctx;
 
@@ -1771,6 +1792,19 @@ static int alloc_bind_mem(AVHWFramesContext *hwfc, 
AVVkFrame *f,
 req.memoryRequirements.size = FFALIGN(req.memoryRequirements.size,
   
p->props.properties.limits.minMemoryMapAlignment);
 
+if (VKF_FLAG(hwfctx->flags, AV_VK_FRAME_FLAG_CONTIGUOUS_MEMORY)) {
+if (memory_requirements.size == 0) {
+memory_requirements = req.memoryRequirements;
+} else if (memory_requirements.memoryTypeBits != 
req.memoryRequirements.memoryTypeBits) {
+av_log(hwfc, AV_LOG_ERROR, "the param for each planes are not 
the same\n");
+return AVERROR(EINVAL);
+}
+
+mem_size_list[i] = req.memoryRequirements.size;
+mem_size += mem_size_list[i];
+continue;
+}
+
 /* In case the implementation prefers/requires dedicated allocation */
 use_ded_mem = ded_req.prefersDedicatedAllocation |
   ded_req.requiresDedicatedAllocation;
@@ -1792,6 +1826,29 @@ static int alloc_bind_mem(AVHWFramesContext *hwfc, 
AVVkFrame *f,
 bind_info[i].memory = f->mem[i];
 }
 
+if (VKF_FLAG(hwfctx->flags, AV_VK_FRAME_FLAG_CONTIGUOUS_MEMORY)) {
+memory_requirements.size = mem_size;
+
+/* Allocate memory */
+if ((err = alloc_mem(ctx, &memory_requirements,
+f->tiling == VK_IMAGE_TILING_LINEAR ?
+VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT :
+VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
+(void *)(((uint8_t *)alloc_pnext)),
+&f->flags, &f->mem[0])))
+return err;
+
+f

[FFmpeg-devel] [PATCH V6 4/5] libavutil/hwcontext_vulkan: Add support to hwmap to software frame when using contiguous_planes flag.

2021-12-07 Thread Wenbin Chen
Add support to map vulkan frames to software frames when
using contiguous_planes flag.

Signed-off-by: Wenbin Chen 
---
 libavutil/hwcontext_vulkan.c | 11 +--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/libavutil/hwcontext_vulkan.c b/libavutil/hwcontext_vulkan.c
index eef9009ae1..f980b72720 100644
--- a/libavutil/hwcontext_vulkan.c
+++ b/libavutil/hwcontext_vulkan.c
@@ -2327,9 +2327,10 @@ static int vulkan_map_frame_to_mem(AVHWFramesContext 
*hwfc, AVFrame *dst,
const AVFrame *src, int flags)
 {
 VkResult ret;
-int err, mapped_mem_count = 0;
+int err, mapped_mem_count = 0, loop = 0;
 AVVkFrame *f = (AVVkFrame *)src->data[0];
 AVVulkanDeviceContext *hwctx = hwfc->device_ctx->hwctx;
+AVVulkanFramesContext *hwfctx = hwfc->hwctx;
 const int planes = av_pix_fmt_count_planes(hwfc->sw_format);
 VulkanDevicePriv *p = hwfc->device_ctx->internal->priv;
 FFVulkanFunctions *vk = &p->vkfn;
@@ -2356,7 +2357,9 @@ static int vulkan_map_frame_to_mem(AVHWFramesContext 
*hwfc, AVFrame *dst,
 dst->width  = src->width;
 dst->height = src->height;
 
-for (int i = 0; i < planes; i++) {
+loop = VKF_FLAG(hwfctx->flags, AV_VK_FRAME_FLAG_CONTIGUOUS_MEMORY) ?
+   1 : planes;
+for (int i = 0; i < loop; i++) {
 ret = vk->MapMemory(hwctx->act_dev, f->mem[i], 0,
 VK_WHOLE_SIZE, 0, (void **)&dst->data[i]);
 if (ret != VK_SUCCESS) {
@@ -2367,6 +2370,10 @@ static int vulkan_map_frame_to_mem(AVHWFramesContext 
*hwfc, AVFrame *dst,
 }
 mapped_mem_count++;
 }
+if (VKF_FLAG(hwfctx->flags, AV_VK_FRAME_FLAG_CONTIGUOUS_MEMORY)) {
+for (int i = 0; i < planes; i++)
+dst->data[i] = dst->data[0] + f->offset[i];
+}
 
 /* Check if the memory contents matter */
 if (((flags & AV_HWFRAME_MAP_READ) || !(flags & AV_HWFRAME_MAP_OVERWRITE)) 
&&
-- 
2.25.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH V6 5/5] libavutil/hwcontext_vulkan: specify the modifier to create VKImage

2021-12-07 Thread Wenbin Chen
When vulkan image exports to drm, the tilling need to be
VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT. Now add code to create vulkan
image using this format.

Now the following command line works:

ffmpeg -hwaccel vaapi -hwaccel_device /dev/dri/renderD128 
-hwaccel_output_format \
vaapi -i input_1080p.264 -vf "hwmap=derive_device=vulkan,format=vulkan, \
scale_vulkan=1920:1080,hwmap=derive_device=vaapi,format=vaapi" -c:v h264_vaapi 
output.264

Signed-off-by: Wenbin Chen 
---
 libavutil/hwcontext_vulkan.c | 133 +--
 1 file changed, 127 insertions(+), 6 deletions(-)

diff --git a/libavutil/hwcontext_vulkan.c b/libavutil/hwcontext_vulkan.c
index f980b72720..11c4260e86 100644
--- a/libavutil/hwcontext_vulkan.c
+++ b/libavutil/hwcontext_vulkan.c
@@ -120,6 +120,9 @@ typedef struct VulkanFramesPriv {
 /* Image transfers */
 VulkanExecCtx upload_ctx;
 VulkanExecCtx download_ctx;
+
+/*modifier info*/
+VkImageDrmFormatModifierListCreateInfoEXT *modifier_info;
 } VulkanFramesPriv;
 
 typedef struct AVVkFrameInternal {
@@ -242,6 +245,31 @@ const VkFormat *av_vkfmt_from_pixfmt(enum AVPixelFormat p)
 return NULL;
 }
 
+static const void *vk_find_struct(const void *chain, VkStructureType stype)
+{
+const VkBaseInStructure *in = chain;
+while (in) {
+if (in->sType == stype)
+return in;
+
+in = in->pNext;
+}
+
+return NULL;
+}
+
+static void vk_link_struct(void *chain, void *in)
+{
+VkBaseOutStructure *out = chain;
+if (!in)
+return;
+
+while (out->pNext)
+out = out->pNext;
+
+out->pNext = in;
+}
+
 static int pixfmt_is_supported(AVHWDeviceContext *dev_ctx, enum AVPixelFormat 
p,
int linear)
 {
@@ -2094,6 +2122,10 @@ static void try_export_flags(AVHWFramesContext *hwfc,
 AVVulkanDeviceContext *dev_hwctx = hwfc->device_ctx->hwctx;
 VulkanDevicePriv *p = hwfc->device_ctx->internal->priv;
 FFVulkanFunctions *vk = &p->vkfn;
+const int has_modifiers = hwctx->tiling == 
VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT;
+int loop_count;
+const VkImageDrmFormatModifierListCreateInfoEXT *modifier_info = 
vk_find_struct(hwctx->create_pnext,
+
VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_LIST_CREATE_INFO_EXT);
 VkExternalImageFormatProperties eprops = {
 .sType = VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES_KHR,
 };
@@ -2101,9 +2133,18 @@ static void try_export_flags(AVHWFramesContext *hwfc,
 .sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2,
 .pNext = &eprops,
 };
+VkPhysicalDeviceImageDrmFormatModifierInfoEXT phy_dev_mod_info = {
+.sType = 
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_DRM_FORMAT_MODIFIER_INFO_EXT,
+.pNext = NULL,
+.pQueueFamilyIndices   = p->qfs,
+.queueFamilyIndexCount = p->num_qfs,
+.sharingMode   = p->num_qfs > 1 ? VK_SHARING_MODE_CONCURRENT :
+  VK_SHARING_MODE_EXCLUSIVE,
+};
 VkPhysicalDeviceExternalImageFormatInfo enext = {
 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO,
 .handleType = exp,
+.pNext = has_modifiers && modifier_info ? &phy_dev_mod_info : NULL,
 };
 VkPhysicalDeviceImageFormatInfo2 pinfo = {
 .sType  = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2,
@@ -2115,11 +2156,16 @@ static void try_export_flags(AVHWFramesContext *hwfc,
 .flags  = VK_IMAGE_CREATE_ALIAS_BIT,
 };
 
-ret = vk->GetPhysicalDeviceImageFormatProperties2(dev_hwctx->phys_dev,
-  &pinfo, &props);
-if (ret == VK_SUCCESS) {
-*iexp |= exp;
-*comp_handle_types |= 
eprops.externalMemoryProperties.compatibleHandleTypes;
+loop_count = has_modifiers && modifier_info ? 
modifier_info->drmFormatModifierCount : 1;
+for (int i = 0; i < loop_count; i++) {
+if (has_modifiers && modifier_info)
+phy_dev_mod_info.drmFormatModifier = 
modifier_info->pDrmFormatModifiers[i];
+ret = vk->GetPhysicalDeviceImageFormatProperties2(dev_hwctx->phys_dev,
+&pinfo, &props);
+if (ret == VK_SUCCESS) {
+*iexp |= exp;
+*comp_handle_types |= 
eprops.externalMemoryProperties.compatibleHandleTypes;
+}
 }
 }
 
@@ -2190,6 +2236,12 @@ static void vulkan_frames_uninit(AVHWFramesContext *hwfc)
 {
 VulkanFramesPriv *fp = hwfc->internal->priv;
 
+if (fp->modifier_info) {
+if (fp->modifier_info->pDrmFormatModifiers)
+av_freep(&fp->modifier_info->pDrmFormatModifiers);
+av_freep(&fp->modifier_info);
+}
+
 free_exec_

[FFmpeg-devel] [PATCH] libavfilter/vf_overlay_qsv: Use format of first input to set output format for overlay_qsv

2021-12-09 Thread Wenbin Chen
overlay_qsv hard coded to use nv12 as output format. Now use the format
of the first input to set output format. Now the following command
works:

ffmpeg -hwaccel qsv -c:v hevc_qsv -i input_p010.265 -hwaccel qsv -c:v hevc_qsv \
-i input2_p010.265 -filter_complex "[0:v][1:v]overlay_qsv=x=0:y=0:alpha=255, \
hwdownload,format=p010le" -f rawvideo -y output_p010.yuv

Signed-off-by: Wenbin Chen 
---
 libavfilter/vf_overlay_qsv.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/libavfilter/vf_overlay_qsv.c b/libavfilter/vf_overlay_qsv.c
index 7e76b39aa9..d947a1faa1 100644
--- a/libavfilter/vf_overlay_qsv.c
+++ b/libavfilter/vf_overlay_qsv.c
@@ -276,6 +276,7 @@ static int config_output(AVFilterLink *outlink)
 int ret;
 
 av_log(ctx, AV_LOG_DEBUG, "Output is of %s.\n", 
av_get_pix_fmt_name(outlink->format));
+vpp->qsv_param.out_sw_format = in0->format;
 if ((in0->format == AV_PIX_FMT_QSV && in1->format != AV_PIX_FMT_QSV) ||
 (in0->format != AV_PIX_FMT_QSV && in1->format == AV_PIX_FMT_QSV)) {
 av_log(ctx, AV_LOG_ERROR, "Mixing hardware and software pixel formats 
is not supported.\n");
@@ -288,6 +289,7 @@ static int config_output(AVFilterLink *outlink)
 av_log(ctx, AV_LOG_ERROR, "Inputs with different underlying QSV 
devices are forbidden.\n");
 return AVERROR(EINVAL);
 }
+vpp->qsv_param.out_sw_format = hw_frame0->sw_format;
 }
 
 outlink->w  = vpp->var_values[VAR_MW];
-- 
2.25.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH V3 1/2] libavcodec/vaapi_decode: fix the problem that init_pool_size < nb_surface

2021-12-09 Thread Wenbin Chen
For vaapi if the init_pool_size is not zero, the pool size is fixed.
This means max surfaces is init_pool_size, but when mapping vaapi
frame to qsv frame, the init_pool_size < nb_surface. The cause is that
vaapi_decode_make_config() config the init_pool_size and it is called
twice. The first time is to init frame_context and the second time is to
init codec. On the second time the init_pool_size is changed to original
value so the init_pool_size is lower than the reall size because
pool_size used to initialize frame_context need to plus thread_count and
3 (guarantee 4 base work surfaces). Now add code to make sure
init_pool_size is only set once. Now the following commandline works:

ffmpeg -hwaccel vaapi -hwaccel_device /dev/dri/renderD128 \
-hwaccel_output_format vaapi -i input.264 \
-vf "hwmap=derive_device=qsv,format=qsv" \
-c:v h264_qsv output.264

Signed-off-by: Wenbin Chen 
---
 libavcodec/vaapi_decode.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libavcodec/vaapi_decode.c b/libavcodec/vaapi_decode.c
index 665af370ed..da0e72b10b 100644
--- a/libavcodec/vaapi_decode.c
+++ b/libavcodec/vaapi_decode.c
@@ -650,7 +650,7 @@ int ff_vaapi_decode_init(AVCodecContext *avctx)
 ctx->hwctx  = ctx->device->hwctx;
 
 err = vaapi_decode_make_config(avctx, ctx->frames->device_ref,
-   &ctx->va_config, avctx->hw_frames_ctx);
+   &ctx->va_config, NULL);
 if (err)
 goto fail;
 
-- 
2.25.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH V3 2/2] libavutil/hwcontext_opencl: fix a bug for mapping qsv frame to opencl

2021-12-09 Thread Wenbin Chen
From: nyanmisaka 

mfxHDLPair was added to qsv, so modify qsv->opencl map function as well.
Now the following commandline works:

ffmpeg -v verbose -init_hw_device vaapi=va:/dev/dri/renderD128 \
-init_hw_device qsv=qs@va -init_hw_device opencl=ocl@va -filter_hw_device ocl \
-hwaccel qsv -hwaccel_output_format qsv -hwaccel_device qs -c:v h264_qsv \
-i input.264 -vf "hwmap=derive_device=opencl,format=opencl,avgblur_opencl, \
hwmap=derive_device=qsv:reverse=1:extra_hw_frames=32,format=qsv" \
-c:v h264_qsv output.264

Signed-off-by: nyanmisaka 
Signed-off-by: Wenbin Chen 
---
 libavutil/hwcontext_opencl.c | 3 ++-
 libavutil/hwcontext_qsv.h| 5 +
 2 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/libavutil/hwcontext_opencl.c b/libavutil/hwcontext_opencl.c
index 26a3a24593..ab812999cd 100644
--- a/libavutil/hwcontext_opencl.c
+++ b/libavutil/hwcontext_opencl.c
@@ -48,6 +48,7 @@
 #if HAVE_OPENCL_VAAPI_INTEL_MEDIA
 #if CONFIG_LIBMFX
 #include 
+#include "hwcontext_qsv.h"
 #endif
 #include 
 #include 
@@ -2249,7 +2250,7 @@ static int opencl_map_from_qsv(AVHWFramesContext *dst_fc, 
AVFrame *dst,
 #if CONFIG_LIBMFX
 if (src->format == AV_PIX_FMT_QSV) {
 mfxFrameSurface1 *mfx_surface = (mfxFrameSurface1*)src->data[3];
-va_surface = *(VASurfaceID*)mfx_surface->Data.MemId;
+va_surface = *MFXSURFACEP_TO_VASURFACEP(mfx_surface);
 } else
 #endif
 if (src->format == AV_PIX_FMT_VAAPI) {
diff --git a/libavutil/hwcontext_qsv.h b/libavutil/hwcontext_qsv.h
index b98d611cfc..957df01ef1 100644
--- a/libavutil/hwcontext_qsv.h
+++ b/libavutil/hwcontext_qsv.h
@@ -29,6 +29,11 @@
  * contain AVBufferRefs whose data pointer points to an mfxFrameSurface1 
struct.
  */
 
+#if CONFIG_VAAPI
+#define MFXSURFACEP_TO_VASURFACEP(surf) \
+(VASurfaceID*)(((mfxHDLPair*)surf->Data.MemId)->first)
+#endif
+
 /**
  * This struct is allocated as AVHWDeviceContext.hwctx
  */
-- 
2.25.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH V2] libavutil/hwcontext_qsv: clean padding when upload qsv frames

2021-12-22 Thread Wenbin Chen
Fix #7830
When we upload a frame that is not padded as MSDK requires, we create a
new AVFrame to copy data. The frame's padding data is uninitialized so
it brings run to run problem. For example, If we run the following
command serveral times we will get different outputs.

ffmpeg -init_hw_device qsv=qsv:hw -qsv_device /dev/dri/renderD128 \
-filter_hw_device qsv -f rawvideo -s 192x200 -pix_fmt p010 \
-i 192x200_P010.yuv -vf "format=nv12,hwupload=extra_hw_frames=16" \
-c:v hevc_qsv output.265

According to 
https://github.com/Intel-Media-SDK/MediaSDK/blob/master/doc/mediasdk-man.md#encoding-procedures
"Note: It is the application's responsibility to fill pixels outside
of crop window when it is smaller than frame to be encoded. Especially
in cases when crops are not aligned to minimum coding block size (16
for AVC, 8 for HEVC and VP9)"

I add a function to fill padding area with border pixel to fix this
run2run problem, and also move the new AVFrame to global structure
to reduce redundant allocation operation to increase preformance.

Signed-off-by: Wenbin Chen 
---
 libavutil/hwcontext_qsv.c | 96 +--
 1 file changed, 83 insertions(+), 13 deletions(-)

diff --git a/libavutil/hwcontext_qsv.c b/libavutil/hwcontext_qsv.c
index a5d154a24d..853fb7f60d 100644
--- a/libavutil/hwcontext_qsv.c
+++ b/libavutil/hwcontext_qsv.c
@@ -47,6 +47,7 @@
 #include "pixfmt.h"
 #include "pixdesc.h"
 #include "time.h"
+#include "imgutils.h"
 
 #define QSV_VERSION_ATLEAST(MAJOR, MINOR)   \
 (MFX_VERSION_MAJOR > (MAJOR) || \
@@ -90,6 +91,7 @@ typedef struct QSVFramesContext {
 
 mfxExtOpaqueSurfaceAlloc opaque_alloc;
 mfxExtBuffer *ext_buffers[1];
+AVFrame realigned_tmp_frame;
 } QSVFramesContext;
 
 static const struct {
@@ -137,6 +139,54 @@ static uint32_t qsv_get_d3d11va_bind_flags(int mem_type)
 }
 #endif
 
+static int qsv_fill_border(AVFrame *dst, const AVFrame *src)
+{
+const AVPixFmtDescriptor *desc;
+int i, planes_nb = 0;
+if (dst->format != src->format)
+return AVERROR(EINVAL);
+
+desc = av_pix_fmt_desc_get(dst->format);
+
+for (i = 0; i < desc->nb_components; i++)
+planes_nb = FFMAX(planes_nb, desc->comp[i].plane + 1);
+
+for (i = 0; i < planes_nb; i++) {
+int sheight, dheight, y;
+ptrdiff_t swidth = av_image_get_linesize(src->format,
+ src->width,
+ i);
+ptrdiff_t dwidth = av_image_get_linesize(dst->format,
+ dst->width,
+ i);
+const AVComponentDescriptor comp = desc->comp[i];
+if (swidth < 0 || dwidth < 0) {
+av_log(NULL, AV_LOG_ERROR, "av_image_get_linesize failed\n");
+return AVERROR(EINVAL);
+}
+sheight = src->height;
+dheight = dst->height;
+if (i) {
+sheight = AV_CEIL_RSHIFT(src->height, desc->log2_chroma_h);
+dheight = AV_CEIL_RSHIFT(dst->height, desc->log2_chroma_h);
+}
+//fill right padding
+for (y = 0; y < sheight; y++) {
+void *line_ptr = dst->data[i] + y*dst->linesize[i] + swidth;
+av_memcpy_backptr(line_ptr,
+   comp.depth > 8 ? 2 : 1,
+   dwidth - swidth);
+}
+//fill bottom padding
+for (y = sheight; y < dheight; y++) {
+memcpy(dst->data[i]+y*dst->linesize[i],
+   dst->data[i]+(sheight-1)*dst->linesize[i],
+   dwidth);
+}
+}
+return 0;
+}
+
 static int qsv_device_init(AVHWDeviceContext *ctx)
 {
 AVQSVDeviceContext *hwctx = ctx->hwctx;
@@ -220,6 +270,7 @@ static void qsv_frames_uninit(AVHWFramesContext *ctx)
 av_freep(&s->surface_ptrs);
 av_freep(&s->surfaces_internal);
 av_freep(&s->handle_pairs_internal);
+av_frame_unref(&s->realigned_tmp_frame);
 av_buffer_unref(&s->child_frames_ref);
 }
 
@@ -1014,12 +1065,13 @@ static int qsv_transfer_data_to(AVHWFramesContext *ctx, 
AVFrame *dst,
 QSVFramesContext   *s = ctx->internal->priv;
 mfxFrameSurface1   in = {{ 0 }};
 mfxFrameSurface1 *out = (mfxFrameSurface1*)dst->data[3];
+mfxFrameInfo tmp_info;
 
 mfxSyncPoint sync = NULL;
 mfxStatus err;
 int ret = 0;
 /* make a copy if the input is not padded as libmfx requires */
-AVFrame tmp_frame;
+AVFrame *tmp_frame = &s->realigned_tmp_frame;
 const AVFrame *src_frame;
 int realigned = 0;
 
@@ -1048,24 +1100,40 @@ static int qsv_transfer_data_to(AVHWFramesContext *ctx, 
AVFrame *dst,
 if (ret < 0)
 return ret;
 
+/* Accor

[FFmpeg-devel] [PATCH] doc/encoders.texi Add doc for qsv

2022-01-04 Thread Wenbin Chen
Add doc for qsv decoder.
Add more option's introduction to qsv encoder.

Signed-off-by: Wenbin Chen 
---
 doc/decoders.texi |  42 
 doc/encoders.texi | 253 +-
 2 files changed, 292 insertions(+), 3 deletions(-)

diff --git a/doc/decoders.texi b/doc/decoders.texi
index 49ab735dce..de2429abba 100644
--- a/doc/decoders.texi
+++ b/doc/decoders.texi
@@ -126,6 +126,48 @@ Set amount of frame threads to use during decoding. The 
default value is 0 (auto
 
 @end table
 
+@section QSV Decoders
+
+The family of Intel QuickSync Video decoders (VC1, MPEG-2, H.264, HEVC,
+JPEG/MJPEG, VP8, VP9, AV1).
+
+@subsection Common Options
+
+The following options are supported by all qsv decoders.
+
+@table @option
+
+@item @var{async_depth}
+Internal parallelization depth, the higher the value the higher the latency.
+
+@item @var{gpu_copy}
+A GPU-accelerated copy between video and system memory
+@table @samp
+@item default
+@item on
+@item off
+@end table
+
+@end table
+
+@subsection HEVC Options
+Extra options for hevc_qsv.
+
+@table @option
+
+@item @var{load_plugin}
+A user plugin to load in an internal session
+@table @samp
+@item none
+@item hevc_sw
+@item hevc_hw
+@end table
+
+@item @var{load_plugins}
+A :-separate list of hexadecimal plugin UIDs to load in an internal session
+
+@end table
+
 @c man end VIDEO DECODERS
 
 @chapter Audio Decoders
diff --git a/doc/encoders.texi b/doc/encoders.texi
index e3b61de5a1..7cc8be1209 100644
--- a/doc/encoders.texi
+++ b/doc/encoders.texi
@@ -3123,12 +3123,13 @@ Setting a higher @option{bits_per_mb} limit will 
improve the speed.
 For the fastest encoding speed set the @option{qscale} parameter (4 is the
 recommended value) and do not set a size constraint.
 
-@section QSV encoders
+@section QSV Encoders
 
-The family of Intel QuickSync Video encoders (MPEG-2, H.264, HEVC, JPEG/MJPEG 
and VP9)
+The family of Intel QuickSync Video encoders (MPEG-2, H.264, HEVC, JPEG/MJPEG
+and VP9)
 
+@subsection Ratecontrol Method
 The ratecontrol method is selected as follows:
-
 @itemize @bullet
 @item
 When @option{global_quality} is specified, a quality-based mode is used.
@@ -3176,6 +3177,7 @@ Note that depending on your system, a different mode than 
the one you specified
 may be selected by the encoder. Set the verbosity level to @var{verbose} or
 higher to see the actual settings used by the QSV runtime.
 
+@subsection Global Options -> MSDK Options
 Additional libavcodec global options are mapped to MSDK options as follows:
 
 @itemize
@@ -3212,6 +3214,251 @@ encoder use CAVLC instead of CABAC.
 
 @end itemize
 
+@subsection Common Options
+Following options are used by all qsv encoders.
+
+@table @option
+@item @var{async_depth}
+Specifies how many asynchronous operations an application performs
+before the application explicitly synchronizes the result. If zero,
+the value is not specified.
+
+@item @var{avbr_accuracy}
+Accuracy of the AVBR ratecontrol (unit of tenth of percent).
+
+@item @var{avbr_convergence}
+Convergence of the AVBR ratecontrol (unit of 100 frames)
+
+The parameters @var{avbr_accuracy} and @var{avbr_convergence} are for the
+average variable bitrate control (AVBR) algorithm.
+The algorithm focuses on overall encoding quality while meeting the specified
+bitrate, @var{target_bitrate}, within the accuracy range @var{avbr_accuracy},
+after a @var{avbr_Convergence} period. This method does not follow HRD and the
+instant bitrate is not capped or padded.
+
+@item @var{preset}
+This option itemizes a range of choices from veryfast (best speed) to veryslow
+(best quality).
+@table @samp
+@item veryfast
+@item faster
+@item fast
+@item medium
+@item slow
+@item slower
+@item veryslow
+@end table
+
+@item @var{forced_idr}
+Forcing I frames as IDR frames.
+
+@item @var{low_power}
+For encoders set this flag to ON to reduce power consumption and GPU usage.
+@end table
+
+@subsection H264 options
+These options are used by h264_qsv
+
+@table @option
+@item @var{extbrc}
+Extended bitrate control.
+
+@item @var{recovery_point_sei}
+Set this flag to insert the recovery point SEI message at the beginning of 
every
+intra refresh cycle.
+
+@item @var{rdo}
+Enable rate distortion optimization.
+
+@item @var{max_frame_size}
+Maximum encoded frame size in bytes.
+
+@item @var{max_slice_size}
+Maximum encoded slice size in bytes.
+
+@item @var{bitrate_limit}
+Toggle bitrate limitations.
+Modifies bitrate to be in the range imposed by the QSV encoder. Setting this
+flag off may lead to violation of HRD conformance. Mind that specifying bitrate
+below the QSV encoder range might significantly affect quality. If on this
+option takes effect in non CQP modes: if bitrate is not in the range imposed
+by the QSV encoder, it will be changed to be in the range.
+
+@item @var{mbbrc}
+Setting this flag enables macroblock level bitrate control that generally
+improves subjective visual quality. Enabling this flag may have negative im

  1   2   3   >