[FFmpeg-devel] [PATCH] libavcodec/hevc_mp4toannexb_bsf: update the extradata in codec par if change detected

2021-12-03 Thread Linjie Fu
From: Linjie Fu 

Container may support multiple sample descriptions in a single
bitstream, like multiple stsd in mov, which introduces different
sequence header(e.g.profile/bit_depth) in the middle of the bitstream.

Update the extradata field in context parameter once packet with
different extradata is got.

Signed-off-by: Linjie Fu 
---
 libavcodec/hevc_mp4toannexb_bsf.c | 23 +++
 1 file changed, 23 insertions(+)

diff --git a/libavcodec/hevc_mp4toannexb_bsf.c 
b/libavcodec/hevc_mp4toannexb_bsf.c
index 790dfb0394..36a83d0c95 100644
--- a/libavcodec/hevc_mp4toannexb_bsf.c
+++ b/libavcodec/hevc_mp4toannexb_bsf.c
@@ -125,6 +125,9 @@ static int hevc_mp4toannexb_filter(AVBSFContext *ctx, 
AVPacket *out)
 int got_irap = 0;
 int i, ret = 0;
 
+uint8_t *extradata;
+size_t extradata_size = 0;
+
 ret = ff_bsf_get_packet(ctx, &in);
 if (ret < 0)
 return ret;
@@ -135,6 +138,26 @@ static int hevc_mp4toannexb_filter(AVBSFContext *ctx, 
AVPacket *out)
 return 0;
 }
 
+extradata = av_packet_get_side_data(in, AV_PKT_DATA_NEW_EXTRADATA, 
&extradata_size);
+if (extradata && extradata_size &&
+(ctx->par_in->extradata_size != extradata_size ||
+ memcmp(ctx->par_in->extradata, extradata, extradata_size))) {
+av_log(ctx, AV_LOG_VERBOSE, "Update extradata, size = %zu\n", 
extradata_size);
+/* Update extradata */
+av_freep(&ctx->par_in->extradata);
+ctx->par_in->extradata_size = extradata_size;
+ctx->par_in->extradata  = av_mallocz(extradata_size + 
AV_INPUT_BUFFER_PADDING_SIZE);
+if (!ctx->par_in->extradata)
+return AVERROR(ENOMEM);
+memcpy(ctx->par_in->extradata, extradata, extradata_size);
+/* Reinit */
+ret = hevc_extradata_to_annexb(ctx);
+if (ret < 0)
+return ret;
+s->length_size  = ret;
+s->extradata_parsed = 1;
+}
+
 bytestream2_init(&gb, in->data, in->size);
 
 while (bytestream2_get_bytes_left(&gb)) {
-- 
2.31.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] lavc/qsvdec: add support for gpu_copy

2019-03-25 Thread Linjie Fu
Add support for GPU copy when QSV decoders works in system memory mode.
However, memory must be sequent and aligned with 128x64 to enable this
feature.(first introduced in FFmpeg 3.3.1)

GPUCopy = MFX_GPUCOPY_ON leads to performance improvement up to x10.

CMD:
ffmpeg -init_hw_device qsv=hw -filter_hw_device hw -c:v h264_qsv
-gpu_copy on -i input.h264 -pix_fmt yuv420p out.yuv


Signed-off-by: Linjie Fu 
Signed-off-by: ChaoX A Liu 
---
 libavcodec/qsv.c  | 27 +---
 libavcodec/qsv_internal.h |  6 ++---
 libavcodec/qsvdec.c   | 53 ++-
 libavcodec/qsvdec.h   |  2 ++
 libavcodec/qsvdec_h2645.c | 10 
 libavcodec/qsvdec_other.c |  5 
 libavcodec/qsvenc.c   |  7 +++---
 7 files changed, 89 insertions(+), 21 deletions(-)

diff --git a/libavcodec/qsv.c b/libavcodec/qsv.c
index bb0d79588c..40e6c677cb 100644
--- a/libavcodec/qsv.c
+++ b/libavcodec/qsv.c
@@ -277,15 +277,19 @@ load_plugin_fail:
 }
 
 int ff_qsv_init_internal_session(AVCodecContext *avctx, mfxSession *session,
- const char *load_plugins)
+ const char *load_plugins, int gpu_copy)
 {
-mfxIMPL impl   = MFX_IMPL_AUTO_ANY;
-mfxVersion ver = { { QSV_VERSION_MINOR, QSV_VERSION_MAJOR } };
+mfxIMPL  impl = MFX_IMPL_AUTO_ANY;
+mfxVersionver = { { QSV_VERSION_MINOR, QSV_VERSION_MAJOR } };
+mfxInitParam init_par = { MFX_IMPL_AUTO_ANY };
 
 const char *desc;
 int ret;
 
-ret = MFXInit(impl, &ver, session);
+init_par.GPUCopy= gpu_copy;
+init_par.Implementation = impl;
+init_par.Version= ver;
+ret = MFXInitEx(init_par, session);
 if (ret < 0)
 return ff_qsv_print_error(avctx, ret,
   "Error initializing an internal MFX 
session");
@@ -571,7 +575,8 @@ static mfxStatus qsv_frame_get_hdl(mfxHDL pthis, mfxMemId 
mid, mfxHDL *hdl)
 }
 
 int ff_qsv_init_session_device(AVCodecContext *avctx, mfxSession *psession,
-   AVBufferRef *device_ref, const char 
*load_plugins)
+   AVBufferRef *device_ref, const char 
*load_plugins,
+   int gpu_copy)
 {
 static const mfxHandleType handle_types[] = {
 MFX_HANDLE_VA_DISPLAY,
@@ -581,11 +586,12 @@ int ff_qsv_init_session_device(AVCodecContext *avctx, 
mfxSession *psession,
 AVHWDeviceContext*device_ctx = (AVHWDeviceContext*)device_ref->data;
 AVQSVDeviceContext *device_hwctx = device_ctx->hwctx;
 mfxSessionparent_session = device_hwctx->session;
+mfxInitParaminit_par = { MFX_IMPL_AUTO_ANY };
+mfxHDLhandle = NULL;
 
 mfxSessionsession;
 mfxVersionver;
 mfxIMPL   impl;
-mfxHDLhandle = NULL;
 mfxHandleType handle_type;
 mfxStatus err;
 
@@ -611,7 +617,10 @@ int ff_qsv_init_session_device(AVCodecContext *avctx, 
mfxSession *psession,
"from the session\n");
 }
 
-err = MFXInit(impl, &ver, &session);
+init_par.GPUCopy= gpu_copy;
+init_par.Implementation = impl;
+init_par.Version= ver;
+err = MFXInitEx(init_par, &session);
 if (err != MFX_ERR_NONE)
 return ff_qsv_print_error(avctx, err,
   "Error initializing a child MFX session");
@@ -642,7 +651,7 @@ int ff_qsv_init_session_device(AVCodecContext *avctx, 
mfxSession *psession,
 
 int ff_qsv_init_session_frames(AVCodecContext *avctx, mfxSession *psession,
QSVFramesContext *qsv_frames_ctx,
-   const char *load_plugins, int opaque)
+   const char *load_plugins, int opaque, int 
gpu_copy)
 {
 mfxFrameAllocator frame_allocator = {
 .pthis  = qsv_frames_ctx,
@@ -662,7 +671,7 @@ int ff_qsv_init_session_frames(AVCodecContext *avctx, 
mfxSession *psession,
 int ret;
 
 ret = ff_qsv_init_session_device(avctx, &session,
- frames_ctx->device_ref, load_plugins);
+ frames_ctx->device_ref, load_plugins, 
gpu_copy);
 if (ret < 0)
 return ret;
 
diff --git a/libavcodec/qsv_internal.h b/libavcodec/qsv_internal.h
index 394c558883..8be6c3757c 100644
--- a/libavcodec/qsv_internal.h
+++ b/libavcodec/qsv_internal.h
@@ -95,14 +95,14 @@ int ff_qsv_map_pixfmt(enum AVPixelFormat format, uint32_t 
*fourcc);
 enum AVPictureType ff_qsv_map_pictype(int mfx_pic_type);
 
 int ff_qsv_init_internal_session(AVCodecContext *avctx, mfxSession *session,
- const char *load_plugins);
+ const char *load_plugins, int gpu_copy);
 
 int ff_qsv_init_session_device(AVCodecContext *avctx, mfxSession *psession,
-  

[FFmpeg-devel] [PATCH, RFC 2/3] lavc/qsvdec: add support for system memory mode

2019-03-25 Thread Linjie Fu
Copy from video to system memory, so output in sysmem memory mode is needed.

Signed-off-by: Linjie Fu 
---
Previously discussed in:
https://patchwork.ffmpeg.org/patch/7009/
This mode is needed in gpu_copy, is this feature implemented in
current lavc now?
 libavcodec/qsvdec.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/libavcodec/qsvdec.c b/libavcodec/qsvdec.c
index 5dd2b3834b..604effbd51 100644
--- a/libavcodec/qsvdec.c
+++ b/libavcodec/qsvdec.c
@@ -47,7 +47,8 @@ const AVCodecHWConfigInternal *ff_qsv_hw_configs[] = {
 &(const AVCodecHWConfigInternal) {
 .public = {
 .pix_fmt = AV_PIX_FMT_QSV,
-.methods = AV_CODEC_HW_CONFIG_METHOD_HW_FRAMES_CTX |
+.methods = AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX |
+   AV_CODEC_HW_CONFIG_METHOD_HW_FRAMES_CTX |
AV_CODEC_HW_CONFIG_METHOD_AD_HOC,
 .device_type = AV_HWDEVICE_TYPE_QSV,
 },
-- 
2.17.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] doc/examples: add QSV decode GPU copy sample

2019-03-25 Thread Linjie Fu
Usage is:
  ./qsvdec_gpucopy on/off input_stream output_stream

For example:
 - enable/disable gpu copy:
  ./qsvdec_gpucopy on input.h264 output.yuv
  ./qsvdec_gpucopy off input.h264 output.yuv

Generate fps per second.

Signed-off-by: Linjie Fu 
---
 configure |   2 +
 doc/examples/Makefile |   1 +
 doc/examples/qsvdec_gpucopy.c | 276 ++
 3 files changed, 279 insertions(+)
 create mode 100644 doc/examples/qsvdec_gpucopy.c

diff --git a/configure b/configure
index 331393f8d5..579ab9ea4a 100755
--- a/configure
+++ b/configure
@@ -1667,6 +1667,7 @@ EXAMPLE_LIST="
 metadata_example
 muxing_example
 qsvdec_example
+qsvdec_gpucopy_example
 remuxing_example
 resampling_audio_example
 scaling_video_example
@@ -3550,6 +3551,7 @@ hw_decode_example_deps="avcodec avformat avutil"
 metadata_example_deps="avformat avutil"
 muxing_example_deps="avcodec avformat avutil swscale"
 qsvdec_example_deps="avcodec avutil libmfx h264_qsv_decoder"
+qsvdec_gpucopy_example_deps="avcodec avutil avformat"
 remuxing_example_deps="avcodec avformat avutil"
 resampling_audio_example_deps="avutil swresample"
 scaling_video_example_deps="avutil swscale"
diff --git a/doc/examples/Makefile b/doc/examples/Makefile
index 2935424e54..188ef0abf1 100644
--- a/doc/examples/Makefile
+++ b/doc/examples/Makefile
@@ -14,6 +14,7 @@ EXAMPLES-$(CONFIG_HW_DECODE_EXAMPLE) += hw_decode
 EXAMPLES-$(CONFIG_METADATA_EXAMPLE)  += metadata
 EXAMPLES-$(CONFIG_MUXING_EXAMPLE)+= muxing
 EXAMPLES-$(CONFIG_QSVDEC_EXAMPLE)+= qsvdec
+EXAMPLES-$(CONFIG_QSVDEC_GPUCOPY_EXAMPLE)+= qsvdec_gpucopy
 EXAMPLES-$(CONFIG_REMUXING_EXAMPLE)  += remuxing
 EXAMPLES-$(CONFIG_RESAMPLING_AUDIO_EXAMPLE)  += resampling_audio
 EXAMPLES-$(CONFIG_SCALING_VIDEO_EXAMPLE) += scaling_video
diff --git a/doc/examples/qsvdec_gpucopy.c b/doc/examples/qsvdec_gpucopy.c
new file mode 100644
index 00..244cf6c6a0
--- /dev/null
+++ b/doc/examples/qsvdec_gpucopy.c
@@ -0,0 +1,276 @@
+/*
+ * Copyright (c) 2019 Linjie Fu
+ *
+ * HW Acceleration API (video decoding) decode sample
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+/**
+ * @file
+ * QSV-Accelerated H264 decoding GPU Copy example.
+ *
+ * @example qsvdec_gpucopy.c
+ * This example shows how to do QSV decode with GPU Copy
+ */
+
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "libavcodec/qsv.h"
+#include 
+
+static AVBufferRef *hw_device_ctx = NULL;
+static enum AVPixelFormat hw_pix_fmt;
+static FILE *output_file = NULL;
+static int g_frame_count = 0;
+int g_avg_fps = 0;
+struct timeval pre_timestamp, cur_timestamp;
+
+static int hw_decoder_init(AVCodecContext *ctx,
+   const enum AVHWDeviceType type) {
+int err = 0;
+
+if ((err = av_hwdevice_ctx_create(&hw_device_ctx, type, NULL, NULL, 0)) <
+0) {
+fprintf(stderr, "Failed to create specified HW device.\n");
+return err;
+}
+ctx->hw_device_ctx = av_buffer_ref(hw_device_ctx);
+
+return err;
+}
+
+static enum AVPixelFormat get_hw_format(AVCodecContext *ctx,
+const enum AVPixelFormat *pix_fmts) {
+const enum AVPixelFormat *p;
+
+for (p = pix_fmts; *p != -1; p++) {
+if (*p == hw_pix_fmt) return *p;
+}
+
+fprintf(stderr, "Failed to get HW surface format.\n");
+return AV_PIX_FMT_NONE;
+}
+
+static int decode_write(AVCodecContext *avctx, AVPacket *packet) {
+AVFrame *frame = NULL;
+
+uint8_t *buffer = NULL;
+int size;
+int ret = 0;
+
+ret = avcodec_send_packet(avctx, packet);
+if (ret < 0) {
+fprintf(stderr, "Error during decoding\n");
+retur

[FFmpeg-devel] [PATCH, v2] lavc/qsvenc: expose low_power option in H264 QSV

2019-03-25 Thread Linjie Fu
Always exposes low_power option for h264 qsv, and reports a warning
if VDENC is not supported with current version of MSDK.

Signed-off-by: Linjie Fu 
---
[v2]: repalce "VDENC" with "low_power" to be more understandable.

 libavcodec/qsvenc.c  | 11 ++-
 libavcodec/qsvenc_h264.c |  2 --
 2 files changed, 10 insertions(+), 3 deletions(-)

diff --git a/libavcodec/qsvenc.c b/libavcodec/qsvenc.c
index 5aa020d47b..8264d0a413 100644
--- a/libavcodec/qsvenc.c
+++ b/libavcodec/qsvenc.c
@@ -495,9 +495,18 @@ static int init_video_param(AVCodecContext *avctx, 
QSVEncContext *q)
 }
 }
 
+if (q->low_power) {
 #if QSV_HAVE_VDENC
-q->param.mfx.LowPower   = q->low_power ? MFX_CODINGOPTION_ON : 
MFX_CODINGOPTION_OFF;
+q->param.mfx.LowPower = MFX_CODINGOPTION_ON;
+#else
+av_log(avctx, AV_LOG_WARNING, "The low_power option is "
+"not supported with this MSDK version.\n");
+q->low_power = 0;
+q->param.mfx.LowPower = MFX_CODINGOPTION_OFF;
 #endif
+} else
+q->param.mfx.LowPower = MFX_CODINGOPTION_OFF;
+
 q->param.mfx.CodecProfile   = q->profile;
 q->param.mfx.TargetUsage= avctx->compression_level;
 q->param.mfx.GopPicSize = FFMAX(0, avctx->gop_size);
diff --git a/libavcodec/qsvenc_h264.c b/libavcodec/qsvenc_h264.c
index f458137848..93044a58c9 100644
--- a/libavcodec/qsvenc_h264.c
+++ b/libavcodec/qsvenc_h264.c
@@ -154,9 +154,7 @@ static const AVOption options[] = {
 { "auto"   , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MFX_MF_AUTO }, 
INT_MIN, INT_MAX, VE, "mfmode" },
 #endif
 
-#if QSV_HAVE_VDENC
 { "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},
-#endif
 
 { "repeat_pps", "repeat pps for every frame", OFFSET(qsv.repeat_pps), 
AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE },
 
-- 
2.17.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] lavc/vaapi_decode: add va_profile format map support for HEVC_REXT

2019-03-27 Thread Linjie Fu
HEVC_REXT will be map to {VAProfileHEVCMain422_10, VAProfileHEVCMain444,
VAProfileHEVCMain444_10} in vaapi_profile_map[], since need to be distinguished
to select the exact va_profile.

Add va_profile -> AV_PIX_FMT map for FF_PROFILE_HEVC_REXT to match the
exact va_profile.

Signed-off-by: Linjie Fu 
---
 libavcodec/vaapi_decode.c | 29 +
 1 file changed, 25 insertions(+), 4 deletions(-)

diff --git a/libavcodec/vaapi_decode.c b/libavcodec/vaapi_decode.c
index 015154b879..1cb8683b7c 100644
--- a/libavcodec/vaapi_decode.c
+++ b/libavcodec/vaapi_decode.c
@@ -414,6 +414,18 @@ static const struct {
 #undef MAP
 };
 
+static const struct {
+VAProfile va_profile;
+enum AVPixelFormat pix_fmt;
+} rext_format_map[] = {
+#define MAP(vp, av) { VAProfileHEVCMain ## vp, AV_PIX_FMT_ ## av }
+MAP(422_10,  YUYV422),
+MAP(422_10,  YUV422P10LE),
+MAP(444, YUV444P),
+MAP(444_10,  YUV444P10LE),
+#undef MAP
+};
+
 /*
  * Set *va_config and the frames_ref fields from the current codec parameters
  * in avctx.
@@ -426,7 +438,7 @@ static int vaapi_decode_make_config(AVCodecContext *avctx,
 AVVAAPIHWConfig   *hwconfig= NULL;
 AVHWFramesConstraints *constraints = NULL;
 VAStatus vas;
-int err, i, j;
+int err, i, j, k;
 const AVCodecDescriptor *codec_desc;
 VAProfile *profile_list = NULL, matched_va_profile;
 int profile_count, exact_match, matched_ff_profile;
@@ -467,13 +479,22 @@ static int vaapi_decode_make_config(AVCodecContext *avctx,
 if (avctx->profile == vaapi_profile_map[i].codec_profile ||
 vaapi_profile_map[i].codec_profile == FF_PROFILE_UNKNOWN)
 profile_match = 1;
-for (j = 0; j < profile_count; j++) {
-if (vaapi_profile_map[i].va_profile == profile_list[j]) {
+if (avctx->profile == FF_PROFILE_HEVC_REXT) {
+/* find the exact va_profile for HEVC_REXT */
+for (j = 0; j < FF_ARRAY_ELEMS(rext_format_map); j++) {
+if (avctx->pix_fmt == rext_format_map[j].pix_fmt)
+   break;
+}
+if (vaapi_profile_map[i].va_profile != 
rext_format_map[j].va_profile)
+continue;
+}
+for (k = 0; k < profile_count; k++) {
+if (vaapi_profile_map[i].va_profile == profile_list[k]) {
 exact_match = profile_match;
 break;
 }
 }
-if (j < profile_count) {
+if (k < profile_count) {
 matched_va_profile = vaapi_profile_map[i].va_profile;
 matched_ff_profile = vaapi_profile_map[i].codec_profile;
 if (exact_match)
-- 
2.17.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] lavc/qsvenc: expose low_power as a common option for QSV encoder

2019-03-28 Thread Linjie Fu
Always exposes low_power option for all qsv encoder, and reports a warning
if VDENC is not supported in current version of MSDK.

Signed-off-by: Linjie Fu 
---
 libavcodec/qsvenc.c  | 11 ++-
 libavcodec/qsvenc.h  |  1 +
 libavcodec/qsvenc_h264.c |  4 
 3 files changed, 11 insertions(+), 5 deletions(-)

diff --git a/libavcodec/qsvenc.c b/libavcodec/qsvenc.c
index 5aa020d47b..751b3028bf 100644
--- a/libavcodec/qsvenc.c
+++ b/libavcodec/qsvenc.c
@@ -495,9 +495,18 @@ static int init_video_param(AVCodecContext *avctx, 
QSVEncContext *q)
 }
 }
 
+if (q->low_power) {
 #if QSV_HAVE_VDENC
-q->param.mfx.LowPower   = q->low_power ? MFX_CODINGOPTION_ON : 
MFX_CODINGOPTION_OFF;
+q->param.mfx.LowPower = MFX_CODINGOPTION_ON;
+#else
+av_log(avctx, AV_LOG_WARNING, "The low_power option is "
+"not supported with this MSDK version.\n");
+q->low_power = 0;
+q->param.mfx.LowPower = MFX_CODINGOPTION_OFF;
 #endif
+} else
+q->param.mfx.LowPower = MFX_CODINGOPTION_OFF;
+
 q->param.mfx.CodecProfile   = q->profile;
 q->param.mfx.TargetUsage= avctx->compression_level;
 q->param.mfx.GopPicSize = FFMAX(0, avctx->gop_size);
diff --git a/libavcodec/qsvenc.h b/libavcodec/qsvenc.h
index 00afbd80aa..0c9887753c 100644
--- a/libavcodec/qsvenc.h
+++ b/libavcodec/qsvenc.h
@@ -89,6 +89,7 @@
 { "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 
}, \
 { "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},\
 
 typedef int SetEncodeCtrlCB (AVCodecContext *avctx,
  const AVFrame *frame, mfxEncodeCtrl* enc_ctrl);
diff --git a/libavcodec/qsvenc_h264.c b/libavcodec/qsvenc_h264.c
index f458137848..8e61826eef 100644
--- a/libavcodec/qsvenc_h264.c
+++ b/libavcodec/qsvenc_h264.c
@@ -154,10 +154,6 @@ static const AVOption options[] = {
 { "auto"   , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MFX_MF_AUTO }, 
INT_MIN, INT_MAX, VE, "mfmode" },
 #endif
 
-#if QSV_HAVE_VDENC
-{ "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},
-#endif
-
 { "repeat_pps", "repeat pps for every frame", OFFSET(qsv.repeat_pps), 
AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE },
 
 { NULL },
-- 
2.17.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] lavc/hevc_ps: parse constraint flags for HEVC REXT

2019-04-01 Thread Linjie Fu
Parse all the constraint flags.

It can be passed to hw decoders to detemine the exact profile for Range
Extension HEVC.

Signed-off-by: Linjie Fu 
---
 libavcodec/hevc_ps.c | 18 +++---
 libavcodec/hevc_ps.h | 10 ++
 2 files changed, 25 insertions(+), 3 deletions(-)

diff --git a/libavcodec/hevc_ps.c b/libavcodec/hevc_ps.c
index 80df417e4f..1365a9d640 100644
--- a/libavcodec/hevc_ps.c
+++ b/libavcodec/hevc_ps.c
@@ -295,9 +295,21 @@ static int decode_profile_tier_level(GetBitContext *gb, 
AVCodecContext *avctx,
 ptl->non_packed_constraint_flag = get_bits1(gb);
 ptl->frame_only_constraint_flag = get_bits1(gb);
 
-skip_bits(gb, 16); // XXX_reserved_zero_44bits[0..15]
-skip_bits(gb, 16); // XXX_reserved_zero_44bits[16..31]
-skip_bits(gb, 12); // XXX_reserved_zero_44bits[32..43]
+ptl->max_12bit_constraint_flag= get_bits1(gb);
+ptl->max_10bit_constraint_flag= get_bits1(gb);
+ptl->max_8bit_constraint_flag = get_bits1(gb);
+ptl->max_422chroma_constraint_flag= get_bits1(gb);
+ptl->max_420chroma_constraint_flag= get_bits1(gb);
+ptl->max_monochrome_constraint_flag   = get_bits1(gb);
+ptl->intra_constraint_flag= get_bits1(gb);
+ptl->one_picture_only_constraint_flag = get_bits1(gb);
+ptl->lower_bit_rate_constraint_flag   = get_bits1(gb);
+
+skip_bits(gb, 16); // XXX_reserved_zero_34bits[0..15]
+skip_bits(gb, 16); // XXX_reserved_zero_34bits[16..31]
+skip_bits(gb, 2);  // XXX_reserved_zero_34bits[32..33]
+
+ptl->inbld_flag = get_bits1(gb);
 
 return 0;
 }
diff --git a/libavcodec/hevc_ps.h b/libavcodec/hevc_ps.h
index bbaa9205ef..1c95a1848b 100644
--- a/libavcodec/hevc_ps.h
+++ b/libavcodec/hevc_ps.h
@@ -182,6 +182,16 @@ typedef struct PTLCommon {
 uint8_t interlaced_source_flag;
 uint8_t non_packed_constraint_flag;
 uint8_t frame_only_constraint_flag;
+uint8_t max_12bit_constraint_flag;
+uint8_t max_10bit_constraint_flag;
+uint8_t max_8bit_constraint_flag;
+uint8_t max_422chroma_constraint_flag;
+uint8_t max_420chroma_constraint_flag;
+uint8_t max_monochrome_constraint_flag;
+uint8_t intra_constraint_flag;
+uint8_t one_picture_only_constraint_flag;
+uint8_t lower_bit_rate_constraint_flag;
+uint8_t inbld_flag;
 } PTLCommon;
 
 typedef struct PTL {
-- 
2.17.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] lavc/hevc_ps: parse constraint flags for HEVC REXT

2019-04-02 Thread Linjie Fu
Parse all the constraint flags according to ITU-T Rec. H.265 (02/2018).

It can be passed to hw decoders to detemine the exact profile for Range
Extension HEVC.

Signed-off-by: Linjie Fu 
---
 libavcodec/hevc_ps.c | 44 
 libavcodec/hevc_ps.h | 11 +++
 2 files changed, 51 insertions(+), 4 deletions(-)

diff --git a/libavcodec/hevc_ps.c b/libavcodec/hevc_ps.c
index 80df417e4f..53822173b8 100644
--- a/libavcodec/hevc_ps.c
+++ b/libavcodec/hevc_ps.c
@@ -267,7 +267,7 @@ static int decode_profile_tier_level(GetBitContext *gb, 
AVCodecContext *avctx,
 {
 int i;
 
-if (get_bits_left(gb) < 2+1+5 + 32 + 4 + 16 + 16 + 12)
+if (get_bits_left(gb) < 2+1+5 + 32 + 4 + 43 + 1)
 return -1;
 
 ptl->profile_space = get_bits(gb, 2);
@@ -295,9 +295,45 @@ static int decode_profile_tier_level(GetBitContext *gb, 
AVCodecContext *avctx,
 ptl->non_packed_constraint_flag = get_bits1(gb);
 ptl->frame_only_constraint_flag = get_bits1(gb);
 
-skip_bits(gb, 16); // XXX_reserved_zero_44bits[0..15]
-skip_bits(gb, 16); // XXX_reserved_zero_44bits[16..31]
-skip_bits(gb, 12); // XXX_reserved_zero_44bits[32..43]
+#define check_profile_idc(idc) \
+ptl->profile_idc == idc || ptl->profile_compatibility_flag[idc]
+
+if (check_profile_idc(4) || check_profile_idc(5) || check_profile_idc(6) ||
+check_profile_idc(7) || check_profile_idc(8) || check_profile_idc(9) ||
+check_profile_idc(10)) {
+
+ptl->max_12bit_constraint_flag= get_bits1(gb);
+ptl->max_10bit_constraint_flag= get_bits1(gb);
+ptl->max_8bit_constraint_flag = get_bits1(gb);
+ptl->max_422chroma_constraint_flag= get_bits1(gb);
+ptl->max_420chroma_constraint_flag= get_bits1(gb);
+ptl->max_monochrome_constraint_flag   = get_bits1(gb);
+ptl->intra_constraint_flag= get_bits1(gb);
+ptl->one_picture_only_constraint_flag = get_bits1(gb);
+ptl->lower_bit_rate_constraint_flag   = get_bits1(gb);
+
+if (check_profile_idc(5) || check_profile_idc(9) || 
check_profile_idc(10)) {
+ptl->max_14bit_constraint_flag= get_bits1(gb);
+skip_bits_long(gb, 33); // XXX_reserved_zero_33bits[0..32]
+} else {
+skip_bits_long(gb, 34); // XXX_reserved_zero_34bits[0..33]
+}
+} else if (check_profile_idc(2)) {
+skip_bits(gb, 7);
+ptl->one_picture_only_constraint_flag = get_bits1(gb);
+skip_bits_long(gb, 35); // XXX_reserved_zero_35bits[0..34]
+} else {
+skip_bits_long(gb, 43); // XXX_reserved_zero_43bits[0..42]
+}
+
+if ((ptl->profile_idc >=1 && ptl->profile_idc <= 5) || ptl->profile_idc == 
9 ||
+ptl->profile_compatibility_flag[1] || 
ptl->profile_compatibility_flag[2] ||
+ptl->profile_compatibility_flag[3] || 
ptl->profile_compatibility_flag[4] ||
+ptl->profile_compatibility_flag[5] || 
ptl->profile_compatibility_flag[9])
+ptl->inbld_flag = get_bits1(gb);
+else
+skip_bits1(gb);
+#undef check_profile_idc
 
 return 0;
 }
diff --git a/libavcodec/hevc_ps.h b/libavcodec/hevc_ps.h
index bbaa9205ef..a7861b090e 100644
--- a/libavcodec/hevc_ps.h
+++ b/libavcodec/hevc_ps.h
@@ -182,6 +182,17 @@ typedef struct PTLCommon {
 uint8_t interlaced_source_flag;
 uint8_t non_packed_constraint_flag;
 uint8_t frame_only_constraint_flag;
+uint8_t max_12bit_constraint_flag;
+uint8_t max_10bit_constraint_flag;
+uint8_t max_8bit_constraint_flag;
+uint8_t max_422chroma_constraint_flag;
+uint8_t max_420chroma_constraint_flag;
+uint8_t max_monochrome_constraint_flag;
+uint8_t intra_constraint_flag;
+uint8_t one_picture_only_constraint_flag;
+uint8_t lower_bit_rate_constraint_flag;
+uint8_t max_14bit_constraint_flag;
+uint8_t inbld_flag;
 } PTLCommon;
 
 typedef struct PTL {
-- 
2.17.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, RFC 2/2] lavc/vaapi_decode: find exact va_profile for HEVC_REXT

2019-04-02 Thread Linjie Fu
Use the profile constraint flags to determine the exact va_profile for
HEVC_REXT.

Directly cast PTLCommon to H265RawProfileTierLevel, and use ff_h265_get_profile
to get the exact profile.

Signed-off-by: Linjie Fu 
---
[v2]: use constraint flags to determine the exact profile, expose the
codec-specific stuff at the beginning.
[RFC]: is it acceptable to cast PTLCommon to H265RawProfileTierLevel for
convenience? The members in PTLCommon should be strictly matched in
H265RawProfileTierLevel.

 libavcodec/vaapi_decode.c | 74 +++
 1 file changed, 59 insertions(+), 15 deletions(-)

diff --git a/libavcodec/vaapi_decode.c b/libavcodec/vaapi_decode.c
index 69512e1d45..6967a63186 100644
--- a/libavcodec/vaapi_decode.c
+++ b/libavcodec/vaapi_decode.c
@@ -24,6 +24,8 @@
 #include "decode.h"
 #include "internal.h"
 #include "vaapi_decode.h"
+#include "hevcdec.h"
+#include "h265_profile_level.h"
 
 
 int ff_vaapi_decode_make_param_buffer(AVCodecContext *avctx,
@@ -401,6 +403,29 @@ static const struct {
 #undef MAP
 };
 
+/*
+ * Find exact va_profile for HEVC Range Extension
+ */
+static VAProfile vaapi_decode_find_exact_profile(AVCodecContext *avctx)
+{
+const HEVCContext *h = avctx->priv_data;
+const HEVCSPS *sps = h->ps.sps;
+const PTL *ptl = &(sps->ptl);
+const PTLCommon *general_ptl = &(ptl->general_ptl);
+const H265ProfileDescriptor *profile;
+
+/* PTLCommon should match the member sequence in H265RawProfileTierLevel*/
+profile = ff_h265_get_profile((H265RawProfileTierLevel *)general_ptl);
+
+if (!strcmp(profile->name, "Main 4:2:2 10"))
+return VAProfileHEVCMain422_10;
+else if (!strcmp(profile->name, "Main 4:4:4"))
+return VAProfileHEVCMain444;
+else if (!strcmp(profile->name, "Main 4:4:4 10"))
+return VAProfileHEVCMain444_10;
+
+return VAProfileNone;
+}
 /*
  * Set *va_config and the frames_ref fields from the current codec parameters
  * in avctx.
@@ -447,24 +472,43 @@ static int vaapi_decode_make_config(AVCodecContext *avctx,
 matched_va_profile = VAProfileNone;
 exact_match = 0;
 
-for (i = 0; i < FF_ARRAY_ELEMS(vaapi_profile_map); i++) {
-int profile_match = 0;
-if (avctx->codec_id != vaapi_profile_map[i].codec_id)
-continue;
-if (avctx->profile == vaapi_profile_map[i].codec_profile ||
-vaapi_profile_map[i].codec_profile == FF_PROFILE_UNKNOWN)
-profile_match = 1;
-for (j = 0; j < profile_count; j++) {
-if (vaapi_profile_map[i].va_profile == profile_list[j]) {
-exact_match = profile_match;
+if (avctx->profile == FF_PROFILE_HEVC_REXT) {
+/* find the exact va_profile for HEVC_REXT */
+#if VA_CHECK_VERSION(1, 2, 0)
+VAProfile va_profile = vaapi_decode_find_exact_profile(avctx);
+for (i = 0; i < profile_count; i++) {
+if (va_profile == profile_list[i]) {
+exact_match = 1;
+matched_va_profile = va_profile;
+matched_ff_profile = FF_PROFILE_HEVC_REXT;
 break;
 }
 }
-if (j < profile_count) {
-matched_va_profile = vaapi_profile_map[i].va_profile;
-matched_ff_profile = vaapi_profile_map[i].codec_profile;
-if (exact_match)
-break;
+#else
+av_log(avctx, AV_LOG_WARNING, "The profile is "
+"not supported with this VA version.\n");
+#endif
+} else {
+/* find the exact va_profile according to codec_id and profile */
+for (i = 0; i < FF_ARRAY_ELEMS(vaapi_profile_map); i++) {
+int profile_match = 0;
+if (avctx->codec_id != vaapi_profile_map[i].codec_id)
+continue;
+if (avctx->profile == vaapi_profile_map[i].codec_profile ||
+vaapi_profile_map[i].codec_profile == FF_PROFILE_UNKNOWN)
+profile_match = 1;
+for (j = 0; j < profile_count; j++) {
+if (vaapi_profile_map[i].va_profile == profile_list[j]) {
+exact_match = profile_match;
+break;
+}
+}
+if (j < profile_count) {
+matched_va_profile = vaapi_profile_map[i].va_profile;
+matched_ff_profile = vaapi_profile_map[i].codec_profile;
+if (exact_match)
+break;
+}
 }
 }
 av_freep(&profile_list);
-- 
2.17.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] lavc/hevc_ps: parse constraint flags for HEVC REXT

2019-04-02 Thread Linjie Fu
Parse all the constraint flags according to ITU-T Rec. H.265 (02/2018).

It can be passed to hw decoders to detemine the exact profile for Range
Extension HEVC.

Adjust the sequence of members in PTLCommon to match H265RawProfileTierLevel.

Signed-off-by: Linjie Fu 
---
 libavcodec/hevc_ps.c | 44 
 libavcodec/hevc_ps.h | 13 -
 2 files changed, 52 insertions(+), 5 deletions(-)

diff --git a/libavcodec/hevc_ps.c b/libavcodec/hevc_ps.c
index 80df417e4f..53822173b8 100644
--- a/libavcodec/hevc_ps.c
+++ b/libavcodec/hevc_ps.c
@@ -267,7 +267,7 @@ static int decode_profile_tier_level(GetBitContext *gb, 
AVCodecContext *avctx,
 {
 int i;
 
-if (get_bits_left(gb) < 2+1+5 + 32 + 4 + 16 + 16 + 12)
+if (get_bits_left(gb) < 2+1+5 + 32 + 4 + 43 + 1)
 return -1;
 
 ptl->profile_space = get_bits(gb, 2);
@@ -295,9 +295,45 @@ static int decode_profile_tier_level(GetBitContext *gb, 
AVCodecContext *avctx,
 ptl->non_packed_constraint_flag = get_bits1(gb);
 ptl->frame_only_constraint_flag = get_bits1(gb);
 
-skip_bits(gb, 16); // XXX_reserved_zero_44bits[0..15]
-skip_bits(gb, 16); // XXX_reserved_zero_44bits[16..31]
-skip_bits(gb, 12); // XXX_reserved_zero_44bits[32..43]
+#define check_profile_idc(idc) \
+ptl->profile_idc == idc || ptl->profile_compatibility_flag[idc]
+
+if (check_profile_idc(4) || check_profile_idc(5) || check_profile_idc(6) ||
+check_profile_idc(7) || check_profile_idc(8) || check_profile_idc(9) ||
+check_profile_idc(10)) {
+
+ptl->max_12bit_constraint_flag= get_bits1(gb);
+ptl->max_10bit_constraint_flag= get_bits1(gb);
+ptl->max_8bit_constraint_flag = get_bits1(gb);
+ptl->max_422chroma_constraint_flag= get_bits1(gb);
+ptl->max_420chroma_constraint_flag= get_bits1(gb);
+ptl->max_monochrome_constraint_flag   = get_bits1(gb);
+ptl->intra_constraint_flag= get_bits1(gb);
+ptl->one_picture_only_constraint_flag = get_bits1(gb);
+ptl->lower_bit_rate_constraint_flag   = get_bits1(gb);
+
+if (check_profile_idc(5) || check_profile_idc(9) || 
check_profile_idc(10)) {
+ptl->max_14bit_constraint_flag= get_bits1(gb);
+skip_bits_long(gb, 33); // XXX_reserved_zero_33bits[0..32]
+} else {
+skip_bits_long(gb, 34); // XXX_reserved_zero_34bits[0..33]
+}
+} else if (check_profile_idc(2)) {
+skip_bits(gb, 7);
+ptl->one_picture_only_constraint_flag = get_bits1(gb);
+skip_bits_long(gb, 35); // XXX_reserved_zero_35bits[0..34]
+} else {
+skip_bits_long(gb, 43); // XXX_reserved_zero_43bits[0..42]
+}
+
+if ((ptl->profile_idc >=1 && ptl->profile_idc <= 5) || ptl->profile_idc == 
9 ||
+ptl->profile_compatibility_flag[1] || 
ptl->profile_compatibility_flag[2] ||
+ptl->profile_compatibility_flag[3] || 
ptl->profile_compatibility_flag[4] ||
+ptl->profile_compatibility_flag[5] || 
ptl->profile_compatibility_flag[9])
+ptl->inbld_flag = get_bits1(gb);
+else
+skip_bits1(gb);
+#undef check_profile_idc
 
 return 0;
 }
diff --git a/libavcodec/hevc_ps.h b/libavcodec/hevc_ps.h
index bbaa9205ef..64f1a1e209 100644
--- a/libavcodec/hevc_ps.h
+++ b/libavcodec/hevc_ps.h
@@ -177,11 +177,22 @@ typedef struct PTLCommon {
 uint8_t tier_flag;
 uint8_t profile_idc;
 uint8_t profile_compatibility_flag[32];
-uint8_t level_idc;
 uint8_t progressive_source_flag;
 uint8_t interlaced_source_flag;
 uint8_t non_packed_constraint_flag;
 uint8_t frame_only_constraint_flag;
+uint8_t max_12bit_constraint_flag;
+uint8_t max_10bit_constraint_flag;
+uint8_t max_8bit_constraint_flag;
+uint8_t max_422chroma_constraint_flag;
+uint8_t max_420chroma_constraint_flag;
+uint8_t max_monochrome_constraint_flag;
+uint8_t intra_constraint_flag;
+uint8_t one_picture_only_constraint_flag;
+uint8_t lower_bit_rate_constraint_flag;
+uint8_t max_14bit_constraint_flag;
+uint8_t inbld_flag;
+uint8_t level_idc;
 } PTLCommon;
 
 typedef struct PTL {
-- 
2.17.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 RFC 2/2] lavc/vaapi_decode: find exact va_profile for HEVC_REXT

2019-04-04 Thread Linjie Fu
Use the profile constraint flags to determine the exact va_profile for
HEVC_REXT.

Directly cast PTLCommon to H265RawProfileTierLevel, and use ff_h265_get_profile
to get the exact profile.

Signed-off-by: Linjie Fu 
---
[v2]: use constraint flags to determine the exact profile, expose the
codec-specific stuff at the beginning.
[v3]: move the VA version check to fix the compile issue.
[RFC]: is it acceptable to cast PTLCommon to H265RawProfileTierLevel for
convenience? The members in PTLCommon should be strictly matched in
H265RawProfileTierLevel.

 libavcodec/vaapi_decode.c | 73 +++
 1 file changed, 58 insertions(+), 15 deletions(-)

diff --git a/libavcodec/vaapi_decode.c b/libavcodec/vaapi_decode.c
index 69512e1d45..47db6c874a 100644
--- a/libavcodec/vaapi_decode.c
+++ b/libavcodec/vaapi_decode.c
@@ -24,6 +24,8 @@
 #include "decode.h"
 #include "internal.h"
 #include "vaapi_decode.h"
+#include "hevcdec.h"
+#include "h265_profile_level.h"
 
 
 int ff_vaapi_decode_make_param_buffer(AVCodecContext *avctx,
@@ -401,6 +403,33 @@ static const struct {
 #undef MAP
 };
 
+/*
+ * Find exact va_profile for HEVC Range Extension
+ */
+static VAProfile vaapi_decode_find_exact_profile(AVCodecContext *avctx)
+{
+const HEVCContext *h = avctx->priv_data;
+const HEVCSPS *sps = h->ps.sps;
+const PTL *ptl = &(sps->ptl);
+const PTLCommon *general_ptl = &(ptl->general_ptl);
+const H265ProfileDescriptor *profile;
+
+/* PTLCommon should match the member sequence in H265RawProfileTierLevel*/
+profile = ff_h265_get_profile((H265RawProfileTierLevel *)general_ptl);
+
+#if VA_CHECK_VERSION(1, 2, 0)
+if (!strcmp(profile->name, "Main 4:2:2 10"))
+return VAProfileHEVCMain422_10;
+else if (!strcmp(profile->name, "Main 4:4:4"))
+return VAProfileHEVCMain444;
+else if (!strcmp(profile->name, "Main 4:4:4 10"))
+return VAProfileHEVCMain444_10;
+#else
+av_log(avctx, AV_LOG_WARNING, "HEVC profile %s is "
+"not supported with this VA version.\n", 
profile->name);
+#endif
+return VAProfileNone;
+}
 /*
  * Set *va_config and the frames_ref fields from the current codec parameters
  * in avctx.
@@ -447,24 +476,38 @@ static int vaapi_decode_make_config(AVCodecContext *avctx,
 matched_va_profile = VAProfileNone;
 exact_match = 0;
 
-for (i = 0; i < FF_ARRAY_ELEMS(vaapi_profile_map); i++) {
-int profile_match = 0;
-if (avctx->codec_id != vaapi_profile_map[i].codec_id)
-continue;
-if (avctx->profile == vaapi_profile_map[i].codec_profile ||
-vaapi_profile_map[i].codec_profile == FF_PROFILE_UNKNOWN)
-profile_match = 1;
-for (j = 0; j < profile_count; j++) {
-if (vaapi_profile_map[i].va_profile == profile_list[j]) {
-exact_match = profile_match;
+if (avctx->profile == FF_PROFILE_HEVC_REXT) {
+/* find the exact va_profile for HEVC_REXT */
+VAProfile va_profile = vaapi_decode_find_exact_profile(avctx);
+for (i = 0; i < profile_count; i++) {
+if (va_profile == profile_list[i]) {
+exact_match = 1;
+matched_va_profile = va_profile;
+matched_ff_profile = FF_PROFILE_HEVC_REXT;
 break;
 }
 }
-if (j < profile_count) {
-matched_va_profile = vaapi_profile_map[i].va_profile;
-matched_ff_profile = vaapi_profile_map[i].codec_profile;
-if (exact_match)
-break;
+} else {
+/* find the exact va_profile according to codec_id and profile */
+for (i = 0; i < FF_ARRAY_ELEMS(vaapi_profile_map); i++) {
+int profile_match = 0;
+if (avctx->codec_id != vaapi_profile_map[i].codec_id)
+continue;
+if (avctx->profile == vaapi_profile_map[i].codec_profile ||
+vaapi_profile_map[i].codec_profile == FF_PROFILE_UNKNOWN)
+profile_match = 1;
+for (j = 0; j < profile_count; j++) {
+if (vaapi_profile_map[i].va_profile == profile_list[j]) {
+exact_match = profile_match;
+break;
+}
+}
+if (j < profile_count) {
+matched_va_profile = vaapi_profile_map[i].va_profile;
+matched_ff_profile = vaapi_profile_map[i].codec_profile;
+if (exact_match)
+break;
+}
 }
 }
 av_freep(&profile_list);
-- 
2.17.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] lavc/vaapi_decode: find exact va_profile for HEVC_REXT

2019-04-08 Thread Linjie Fu
Use the profile constraint flags to determine the exact va_profile for
HEVC_REXT.

Directly cast PTLCommon to H265RawProfileTierLevel, and use ff_h265_get_profile
to get the exact profile.

Add h265_profile_level.o to build objects for vaapi_decode to fix the compile
dependency issue.

Signed-off-by: Linjie Fu 
---
[v2]: use constraint flags to determine the exact profile, expose the
codec-specific stuff at the beginning.
[v3]: move the VA version check to fix the compile issue.
[v4]: fix the build issue.

 libavcodec/Makefile   |  2 +-
 libavcodec/vaapi_decode.c | 73 +++
 2 files changed, 59 insertions(+), 16 deletions(-)

diff --git a/libavcodec/Makefile b/libavcodec/Makefile
index 15c43a8a6a..c0df0ad90a 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -857,7 +857,7 @@ OBJS-$(CONFIG_ADPCM_YAMAHA_ENCODER)   += adpcmenc.o 
adpcm_data.o
 OBJS-$(CONFIG_D3D11VA)+= dxva2.o
 OBJS-$(CONFIG_DXVA2)  += dxva2.o
 OBJS-$(CONFIG_NVDEC)  += nvdec.o
-OBJS-$(CONFIG_VAAPI)  += vaapi_decode.o
+OBJS-$(CONFIG_VAAPI)  += vaapi_decode.o 
h265_profile_level.o
 OBJS-$(CONFIG_VIDEOTOOLBOX)   += videotoolbox.o
 OBJS-$(CONFIG_VDPAU)  += vdpau.o
 
diff --git a/libavcodec/vaapi_decode.c b/libavcodec/vaapi_decode.c
index 69512e1d45..47db6c874a 100644
--- a/libavcodec/vaapi_decode.c
+++ b/libavcodec/vaapi_decode.c
@@ -24,6 +24,8 @@
 #include "decode.h"
 #include "internal.h"
 #include "vaapi_decode.h"
+#include "hevcdec.h"
+#include "h265_profile_level.h"
 
 
 int ff_vaapi_decode_make_param_buffer(AVCodecContext *avctx,
@@ -401,6 +403,33 @@ static const struct {
 #undef MAP
 };
 
+/*
+ * Find exact va_profile for HEVC Range Extension
+ */
+static VAProfile vaapi_decode_find_exact_profile(AVCodecContext *avctx)
+{
+const HEVCContext *h = avctx->priv_data;
+const HEVCSPS *sps = h->ps.sps;
+const PTL *ptl = &(sps->ptl);
+const PTLCommon *general_ptl = &(ptl->general_ptl);
+const H265ProfileDescriptor *profile;
+
+/* PTLCommon should match the member sequence in H265RawProfileTierLevel*/
+profile = ff_h265_get_profile((H265RawProfileTierLevel *)general_ptl);
+
+#if VA_CHECK_VERSION(1, 2, 0)
+if (!strcmp(profile->name, "Main 4:2:2 10"))
+return VAProfileHEVCMain422_10;
+else if (!strcmp(profile->name, "Main 4:4:4"))
+return VAProfileHEVCMain444;
+else if (!strcmp(profile->name, "Main 4:4:4 10"))
+return VAProfileHEVCMain444_10;
+#else
+av_log(avctx, AV_LOG_WARNING, "HEVC profile %s is "
+"not supported with this VA version.\n", 
profile->name);
+#endif
+return VAProfileNone;
+}
 /*
  * Set *va_config and the frames_ref fields from the current codec parameters
  * in avctx.
@@ -447,24 +476,38 @@ static int vaapi_decode_make_config(AVCodecContext *avctx,
 matched_va_profile = VAProfileNone;
 exact_match = 0;
 
-for (i = 0; i < FF_ARRAY_ELEMS(vaapi_profile_map); i++) {
-int profile_match = 0;
-if (avctx->codec_id != vaapi_profile_map[i].codec_id)
-continue;
-if (avctx->profile == vaapi_profile_map[i].codec_profile ||
-vaapi_profile_map[i].codec_profile == FF_PROFILE_UNKNOWN)
-profile_match = 1;
-for (j = 0; j < profile_count; j++) {
-if (vaapi_profile_map[i].va_profile == profile_list[j]) {
-exact_match = profile_match;
+if (avctx->profile == FF_PROFILE_HEVC_REXT) {
+/* find the exact va_profile for HEVC_REXT */
+VAProfile va_profile = vaapi_decode_find_exact_profile(avctx);
+for (i = 0; i < profile_count; i++) {
+if (va_profile == profile_list[i]) {
+exact_match = 1;
+matched_va_profile = va_profile;
+matched_ff_profile = FF_PROFILE_HEVC_REXT;
 break;
 }
 }
-if (j < profile_count) {
-matched_va_profile = vaapi_profile_map[i].va_profile;
-matched_ff_profile = vaapi_profile_map[i].codec_profile;
-if (exact_match)
-break;
+} else {
+/* find the exact va_profile according to codec_id and profile */
+for (i = 0; i < FF_ARRAY_ELEMS(vaapi_profile_map); i++) {
+int profile_match = 0;
+if (avctx->codec_id != vaapi_profile_map[i].codec_id)
+continue;
+if (avctx->profile == vaapi_profile_map[i].codec_profile ||
+vaapi_profile_map[i].codec_profile == FF_PROFILE_UNKNOWN)
+profile_match = 1;
+for (j = 0; j < profile_count; j++) {
+if (vaapi_profile_map[i].va_profile == 

[FFmpeg-devel] [PATCH] lavu/hwcontext_qsv: Fix the realign check for hwupload

2019-04-10 Thread Linjie Fu
Fix the aligned check in hwupload, input surface should be 16 aligned
too.

Fix #7830.

Signed-off-by: Linjie Fu 
---
 libavutil/hwcontext_qsv.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/libavutil/hwcontext_qsv.c b/libavutil/hwcontext_qsv.c
index b6d8bfe2bf..bc6236f25d 100644
--- a/libavutil/hwcontext_qsv.c
+++ b/libavutil/hwcontext_qsv.c
@@ -892,7 +892,8 @@ static int qsv_transfer_data_to(AVHWFramesContext *ctx, 
AVFrame *dst,
 return ret;
 
 
-if (src->height & 16 || src->linesize[0] & 16) {
+if (src->height % 16 || src->width % 16 ||
+src->linesize[0] % 16) {
 realigned = 1;
 memset(&tmp_frame, 0, sizeof(tmp_frame));
 tmp_frame.format = src->format;
-- 
2.17.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/2] lavc/qsvenc: Fix the memory leak for enc_ctrl.Payload

2019-04-10 Thread Linjie Fu
frame->enc_ctrl.Payload is malloced in get_free_frame, directly memset
the whole structure of enc_ctrl to zero will cause the memory leak for
enc_ctrl.Payload.

Fix the memory leak issue and reset other members in mfxEncodeCtrl.

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

diff --git a/libavcodec/qsvenc.c b/libavcodec/qsvenc.c
index 5aa020d47b..029bb562d6 100644
--- a/libavcodec/qsvenc.c
+++ b/libavcodec/qsvenc.c
@@ -1254,7 +1254,7 @@ static int encode_frame(AVCodecContext *avctx, 
QSVEncContext *q,
 if (qsv_frame) {
 surf = &qsv_frame->surface;
 enc_ctrl = &qsv_frame->enc_ctrl;
-memset(enc_ctrl, 0, sizeof(mfxEncodeCtrl));
+memset(enc_ctrl, 0, sizeof(mfxEncodeCtrl) - sizeof(mfxPayload **));
 
 if (frame->pict_type == AV_PICTURE_TYPE_I) {
 enc_ctrl->FrameType = MFX_FRAMETYPE_I | MFX_FRAMETYPE_REF;
-- 
2.17.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] lavu/hwcontext_qsv: Fix the realign check for hwupload

2019-04-10 Thread Linjie Fu
Fix the aligned check in hwupload, input surface should be 16 aligned
too.

Fix #7830.

Signed-off-by: Linjie Fu 
---

 libavutil/hwcontext_qsv.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/libavutil/hwcontext_qsv.c b/libavutil/hwcontext_qsv.c
index b6d8bfe2bf..8b000fe636 100644
--- a/libavutil/hwcontext_qsv.c
+++ b/libavutil/hwcontext_qsv.c
@@ -892,7 +892,8 @@ static int qsv_transfer_data_to(AVHWFramesContext *ctx, 
AVFrame *dst,
 return ret;
 
 
-if (src->height & 16 || src->linesize[0] & 16) {
+if (src->height & 15 || src->width & 15 ||
+src->linesize[0] & 15) {
 realigned = 1;
 memset(&tmp_frame, 0, sizeof(tmp_frame));
 tmp_frame.format = src->format;
-- 
2.17.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] lavf/qsvvpp: avoid the double-free when working in sys memory mode

2019-04-14 Thread Linjie Fu
Currently, picref will be freed by calling av_frame_free(&picref) in
submit_frame() in qsvvpp.c when working in system memory mode,and normally it 
is freed in filter_frame() in vf_vpp_qsv.c when working in other modes.

Double free happens when working in system memory mode, remove to
fix the memory issue.

Signed-off-by: Linjie Fu 
---
Can be reproduced by applying the system memory patch and qsvdec+vpp:
ffmpeg -init_hw_device qsv=hw -filter_hw_device hw -c:v h264_qsv -i 
input.mp4 \
-vf "vpp_qsv=w=960:h=540,format=rgb32" -f null -
 libavfilter/qsvvpp.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/libavfilter/qsvvpp.c b/libavfilter/qsvvpp.c
index 06efdf5089..5cd1d5d345 100644
--- a/libavfilter/qsvvpp.c
+++ b/libavfilter/qsvvpp.c
@@ -316,7 +316,6 @@ static QSVFrame *submit_frame(QSVVPPContext *s, 
AVFilterLink *inlink, AVFrame *p
 }
 
 av_frame_copy_props(qsv_frame->frame, picref);
-av_frame_free(&picref);
 } else
 qsv_frame->frame = av_frame_clone(picref);
 
-- 
2.17.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] lavu/hwcontext_qsv: Fix the realign check for hwupload

2019-04-14 Thread Linjie Fu
Fix the aligned check in hwupload, input surface should be 16 aligned
too.

Fix #7830.

Signed-off-by: Linjie Fu 
---
 libavutil/hwcontext_qsv.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/libavutil/hwcontext_qsv.c b/libavutil/hwcontext_qsv.c
index b6d8bfe2bf..197dd8002a 100644
--- a/libavutil/hwcontext_qsv.c
+++ b/libavutil/hwcontext_qsv.c
@@ -891,8 +891,7 @@ static int qsv_transfer_data_to(AVHWFramesContext *ctx, 
AVFrame *dst,
 if (ret < 0)
 return ret;
 
-
-if (src->height & 16 || src->linesize[0] & 16) {
+if (src->height & 15 || src->linesize[0] & 15) {
 realigned = 1;
 memset(&tmp_frame, 0, sizeof(tmp_frame));
 tmp_frame.format = src->format;
-- 
2.17.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] lavc/qsvenc: Fix the memory leak for enc_ctrl.Payload

2019-04-14 Thread Linjie Fu
frame->enc_ctrl.Payload is malloced in get_free_frame, directly memset
the whole structure of enc_ctrl to zero will cause the memory leak for
enc_ctrl.Payload.

frame->enc_ctrl as a structure will be malloc and init to zero by calling
frame = av_mallocz(sizeof(*frame)), so the memset is redundant and can
be removed.

Can be reproduced by #7830.

Signed-off-by: Linjie Fu 
---
 libavcodec/qsvenc.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/libavcodec/qsvenc.c b/libavcodec/qsvenc.c
index 5aa020d47b..19953bd4ea 100644
--- a/libavcodec/qsvenc.c
+++ b/libavcodec/qsvenc.c
@@ -1254,7 +1254,6 @@ static int encode_frame(AVCodecContext *avctx, 
QSVEncContext *q,
 if (qsv_frame) {
 surf = &qsv_frame->surface;
 enc_ctrl = &qsv_frame->enc_ctrl;
-memset(enc_ctrl, 0, sizeof(mfxEncodeCtrl));
 
 if (frame->pict_type == AV_PICTURE_TYPE_I) {
 enc_ctrl->FrameType = MFX_FRAMETYPE_I | MFX_FRAMETYPE_REF;
-- 
2.17.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] lavc/vaapi_encode_h264: add support for maxframesize

2019-04-22 Thread Linjie Fu
Add support for max frame size:
- max_frame_size (bytes) to indicate the allowed max frame size.
- pass_num to indicate number of passes.
- delta_qp to indicate adjust qp value.

Currently only AVC encoder can support this settings in multiple pass case.
If the frame size exceeds, the encoder will do more pak passes to adjust the
QP value to control the frame size.

Set Default num_passes to 4 (1~4), set delta_qp[4] = {1, 1, 1, 1}, use
new_qp for encoder if frame size exceeds the limitation:
new_qp = base_qp + delta_qp[0] + delta_qp[1] + ...

ffmpeg -hwaccel vaapi -vaapi_device /dev/dri/renderD128 -f rawvideo \
-v verbose -s:v 352x288 -i ./input.yuv -vf format=nv12,hwupload \
-c:v h264_vaapi -profile:v main -g 30 -bf 3 -max_frame_size 4 \
-pass_num 2 -delta_qp 2 -vframes 100 -y ./max_frame_size.h264

Signed-off-by: Linjie Fu 
---
 libavcodec/vaapi_encode.c  | 46 ++
 libavcodec/vaapi_encode.h  | 11 
 libavcodec/vaapi_encode_h264.c | 15 +++
 3 files changed, 72 insertions(+)

diff --git a/libavcodec/vaapi_encode.c b/libavcodec/vaapi_encode.c
index 2dda451882..762c42ef13 100644
--- a/libavcodec/vaapi_encode.c
+++ b/libavcodec/vaapi_encode.c
@@ -236,6 +236,14 @@ static int vaapi_encode_issue(AVCodecContext *avctx,
 goto fail;
 }
 
+if (ctx->max_frame_size) {
+err = vaapi_encode_make_param_buffer(avctx, pic, 
VAEncMiscParameterBufferType,
+(char*) &ctx->mfs_params.misc,
+sizeof(ctx->mfs_params));
+if (err < 0)
+goto fail;
+}
+
 if (pic->type == PICTURE_TYPE_IDR) {
 if (ctx->va_packed_headers & VA_ENC_PACKED_HEADER_SEQUENCE &&
 ctx->codec->write_sequence_header) {
@@ -1630,6 +1638,38 @@ rc_mode_found:
 return 0;
 }
 
+static av_cold int vaapi_encode_init_max_frame_size(AVCodecContext *avctx)
+{
+VAAPIEncodeContext *ctx = avctx->priv_data;
+
+uint32_t max_frame_size = ctx->max_frame_size;
+uint8_t num_passes = ctx->pass_num;
+uint8_t *delta_qp = av_mallocz_array(num_passes, sizeof(uint8_t));
+int err = 0;
+int i = 0;
+
+if (!delta_qp) {
+err = AVERROR(ENOMEM);
+return err;
+}
+for (i = 0; i delta_qp;
+}
+
+
+ctx->mfs_params.misc.type = VAEncMiscParameterTypeMultiPassFrameSize;
+ctx->mfs_params.mfs.type = VAEncMiscParameterTypeMultiPassFrameSize;
+ctx->mfs_params.mfs.max_frame_size = max_frame_size;
+ctx->mfs_params.mfs.num_passes = num_passes;
+ctx->mfs_params.mfs.delta_qp = delta_qp;
+
+av_log(avctx, AV_LOG_VERBOSE, "Max Frame Size: %d bytes, "
+  "num_passes: %d, delta_qp = %d.\n",
+ctx->max_frame_size, num_passes, 
ctx->delta_qp);
+
+return 0;
+}
+
 static av_cold int vaapi_encode_init_gop_structure(AVCodecContext *avctx)
 {
 VAAPIEncodeContext *ctx = avctx->priv_data;
@@ -2095,6 +2135,12 @@ av_cold int ff_vaapi_encode_init(AVCodecContext *avctx)
 goto fail;
 }
 
+if (ctx->max_frame_size) {
+err = vaapi_encode_init_max_frame_size(avctx);
+if (err < 0)
+goto fail;
+}
+
 vas = vaCreateConfig(ctx->hwctx->display,
  ctx->va_profile, ctx->va_entrypoint,
  ctx->config_attributes, ctx->nb_config_attributes,
diff --git a/libavcodec/vaapi_encode.h b/libavcodec/vaapi_encode.h
index 44a8db566e..557476d226 100644
--- a/libavcodec/vaapi_encode.h
+++ b/libavcodec/vaapi_encode.h
@@ -176,6 +176,13 @@ typedef struct VAAPIEncodeContext {
 // Desired B frame reference depth.
 int desired_b_depth;
 
+// Max Frame Size
+int max_frame_size;
+// Number Of Passes
+int pass_num;
+// Delta_qp For Each Pass
+int delta_qp;
+
 // Explicitly set RC mode (otherwise attempt to pick from
 // available modes).
 int explicit_rc_mode;
@@ -268,6 +275,10 @@ typedef struct VAAPIEncodeContext {
 } quality_params;
 #endif
 
+struct {
+VAEncMiscParameterBuffer misc;
+VAEncMiscParameterBufferMultiPassFrameSize mfs;
+} __attribute__((packed)) mfs_params;
 // Per-sequence parameter structure (VAEncSequenceParameterBuffer*).
 void   *codec_sequence_params;
 
diff --git a/libavcodec/vaapi_encode_h264.c b/libavcodec/vaapi_encode_h264.c
index 4cf99d7c78..4d55dc2bac 100644
--- a/libavcodec/vaapi_encode_h264.c
+++ b/libavcodec/vaapi_encode_h264.c
@@ -72,6 +72,9 @@ typedef struct VAAPIEncodeH264Context {
 int sei;
 int profile;
 int level;
+int max_frame_size;
+int pass_num;
+int delta_qp;
 
 // Derived settings.
 int mb_width;
@@ -1233,6 +1236,12 

[FFmpeg-devel] [PATCH 2/2] doc/encoder: add documentations for max_frame_size

2019-04-28 Thread Linjie Fu
add docs.

Signed-off-by: Linjie Fu 
---
 doc/encoders.texi | 11 +++
 1 file changed, 11 insertions(+)

diff --git a/doc/encoders.texi b/doc/encoders.texi
index ef12c73ed5..e9887e13a6 100644
--- a/doc/encoders.texi
+++ b/doc/encoders.texi
@@ -2940,6 +2940,17 @@ Use CAVLC.
 @item aud
 Include access unit delimiters in the stream (not included by default).
 
+@item max_frame_size
+Set the allowed max size in bytes for each frame. If the frame size exceeds 
the limitation,
+encoder will adjust the QP value by delta_qp for each pass to control the 
frame size.
+
+@item pass_num
+Set number of passes, currently can support up to 4 passes.
+
+@item delta_qp
+Set delta QP for every pass. Every pass can have different QP, currently set 
equal delta_qp for
+each pass.
+
 @item sei
 Set SEI message types to include.
 Some combination of the following values:
-- 
2.17.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/2, v2] lavc/vaapi_encode_h264: add support for maxframesize

2019-04-28 Thread Linjie Fu
Add support for max frame size:
- max_frame_size (bytes) to indicate the allowed max frame size, set
with default 4 passes and delata_qp = 1 per pass;

Customized pass_num and delta_qp per pass is also available:
- pass_num to indicate number of passes.
- delta_qp to indicate qp value added to base_qp for each pass.

Currently only AVC encoder can support this settings in multiple pass case.
If the frame size exceeds the limitation, encoder will adjust the QP value
set by bit rate control methods, add delta_qp for each pass to control the
frame size.
new_qp = base_qp + delta_qp[0];
new_qp = base_qp + delta_qp[0] + delta_qp[1] + ...

Set max frame size with default params:
ffmpeg -hwaccel vaapi -vaapi_device /dev/dri/renderD128 -f rawvideo \
-v verbose -s:v 352x288 -i ./input.yuv -vf format=nv12,hwupload \
-c:v h264_vaapi -profile:v main -g 30 -bf 3 -max_frame_size 4 \
-vframes 100 -y ./max_frame_size.h264

Set max frame size with expected params:
ffmpeg -hwaccel vaapi -vaapi_device /dev/dri/renderD128 -f rawvideo \
-v verbose -s:v 352x288 -i ./input.yuv -vf format=nv12,hwupload \
-c:v h264_vaapi -profile:v main -g 30 -bf 3 -max_frame_size 4 \
-pass_num 2 -delta_qp 2 -vframes 100 -y ./max_frame_size.h264

Signed-off-by: Linjie Fu 
---
 libavcodec/vaapi_encode.c  | 56 +-
 libavcodec/vaapi_encode.h  | 16 +-
 libavcodec/vaapi_encode_h264.c | 15 +
 3 files changed, 85 insertions(+), 2 deletions(-)

diff --git a/libavcodec/vaapi_encode.c b/libavcodec/vaapi_encode.c
index 2dda451882..c807957b23 100644
--- a/libavcodec/vaapi_encode.c
+++ b/libavcodec/vaapi_encode.c
@@ -235,7 +235,15 @@ static int vaapi_encode_issue(AVCodecContext *avctx,
 if (err < 0)
 goto fail;
 }
-
+#if VA_CHECK_VERSION(1, 3, 0)
+if (ctx->max_frame_size) {
+err = vaapi_encode_make_param_buffer(avctx, pic, 
VAEncMiscParameterBufferType,
+(char*) &ctx->mfs_params.misc,
+sizeof(ctx->mfs_params));
+if (err < 0)
+goto fail;
+}
+#endif
 if (pic->type == PICTURE_TYPE_IDR) {
 if (ctx->va_packed_headers & VA_ENC_PACKED_HEADER_SEQUENCE &&
 ctx->codec->write_sequence_header) {
@@ -1630,6 +1638,43 @@ rc_mode_found:
 return 0;
 }
 
+static av_cold int vaapi_encode_init_max_frame_size(AVCodecContext *avctx)
+{
+VAAPIEncodeContext *ctx = avctx->priv_data;
+
+uint32_t max_frame_size = ctx->max_frame_size;
+uint8_t num_passes = ctx->pass_num;
+int err = 0;
+int i = 0;
+
+ctx->delta_qp_array = av_mallocz_array(num_passes, sizeof(uint8_t));
+if (!ctx->delta_qp_array) {
+err = AVERROR(ENOMEM);
+return err;
+}
+for (i = 0; i delta_qp_array[i] = ctx->delta_qp;
+}
+
+
+#if VA_CHECK_VERSION(1, 3, 0)
+ctx->mfs_params.misc.type = VAEncMiscParameterTypeMultiPassFrameSize;
+ctx->mfs_params.mfs.type = VAEncMiscParameterTypeMultiPassFrameSize;
+ctx->mfs_params.mfs.max_frame_size = max_frame_size;
+ctx->mfs_params.mfs.num_passes = num_passes;
+ctx->mfs_params.mfs.delta_qp = ctx->delta_qp_array;
+
+av_log(avctx, AV_LOG_VERBOSE, "Max Frame Size: %d bytes, "
+  "num_passes: %d, delta_qp = %d.\n",
+ctx->max_frame_size, num_passes, 
ctx->delta_qp);
+#else
+av_log(avctx, AV_LOG_WARNING, "Max Frame Size is "
+"not supported with this VA version.\n");
+#endif
+
+return 0;
+}
+
 static av_cold int vaapi_encode_init_gop_structure(AVCodecContext *avctx)
 {
 VAAPIEncodeContext *ctx = avctx->priv_data;
@@ -2095,6 +2140,12 @@ av_cold int ff_vaapi_encode_init(AVCodecContext *avctx)
 goto fail;
 }
 
+if (ctx->max_frame_size) {
+err = vaapi_encode_init_max_frame_size(avctx);
+if (err < 0)
+goto fail;
+}
+
 vas = vaCreateConfig(ctx->hwctx->display,
  ctx->va_profile, ctx->va_entrypoint,
  ctx->config_attributes, ctx->nb_config_attributes,
@@ -2219,6 +2270,9 @@ av_cold int ff_vaapi_encode_close(AVCodecContext *avctx)
 ctx->va_config = VA_INVALID_ID;
 }
 
+if (ctx->delta_qp_array)
+av_freep(&ctx->delta_qp_array);
+
 av_freep(&ctx->codec_sequence_params);
 av_freep(&ctx->codec_picture_params);
 
diff --git a/libavcodec/vaapi_encode.h b/libavcodec/vaapi_encode.h
index 44a8db566e..92b1ebd3f0 100644
--- a/libavcodec/vaapi_encode.h
+++ b/libavcodec/vaapi_encode.h
@@ -176,6 +176,15 @@ typedef struct VAAPIEncodeContext {
 // Desired B frame reference depth.
 int

[FFmpeg-devel] [PATCH 1/3] lavc/hevc_ps: parse constraint flags for HEVC REXT

2019-04-28 Thread Linjie Fu
Parse all the constraint flags according to ITU-T Rec. H.265 (02/2018).

It can be passed to hw decoders to determine the exact profile for Range
Extension HEVC.

Signed-off-by: Linjie Fu 
---
This is the same patch with previous one, send again to be wrapped in
the patch set.
 libavcodec/hevc_ps.c | 44 
 libavcodec/hevc_ps.h | 13 -
 2 files changed, 52 insertions(+), 5 deletions(-)

diff --git a/libavcodec/hevc_ps.c b/libavcodec/hevc_ps.c
index 80df417e4f..53822173b8 100644
--- a/libavcodec/hevc_ps.c
+++ b/libavcodec/hevc_ps.c
@@ -267,7 +267,7 @@ static int decode_profile_tier_level(GetBitContext *gb, 
AVCodecContext *avctx,
 {
 int i;
 
-if (get_bits_left(gb) < 2+1+5 + 32 + 4 + 16 + 16 + 12)
+if (get_bits_left(gb) < 2+1+5 + 32 + 4 + 43 + 1)
 return -1;
 
 ptl->profile_space = get_bits(gb, 2);
@@ -295,9 +295,45 @@ static int decode_profile_tier_level(GetBitContext *gb, 
AVCodecContext *avctx,
 ptl->non_packed_constraint_flag = get_bits1(gb);
 ptl->frame_only_constraint_flag = get_bits1(gb);
 
-skip_bits(gb, 16); // XXX_reserved_zero_44bits[0..15]
-skip_bits(gb, 16); // XXX_reserved_zero_44bits[16..31]
-skip_bits(gb, 12); // XXX_reserved_zero_44bits[32..43]
+#define check_profile_idc(idc) \
+ptl->profile_idc == idc || ptl->profile_compatibility_flag[idc]
+
+if (check_profile_idc(4) || check_profile_idc(5) || check_profile_idc(6) ||
+check_profile_idc(7) || check_profile_idc(8) || check_profile_idc(9) ||
+check_profile_idc(10)) {
+
+ptl->max_12bit_constraint_flag= get_bits1(gb);
+ptl->max_10bit_constraint_flag= get_bits1(gb);
+ptl->max_8bit_constraint_flag = get_bits1(gb);
+ptl->max_422chroma_constraint_flag= get_bits1(gb);
+ptl->max_420chroma_constraint_flag= get_bits1(gb);
+ptl->max_monochrome_constraint_flag   = get_bits1(gb);
+ptl->intra_constraint_flag= get_bits1(gb);
+ptl->one_picture_only_constraint_flag = get_bits1(gb);
+ptl->lower_bit_rate_constraint_flag   = get_bits1(gb);
+
+if (check_profile_idc(5) || check_profile_idc(9) || 
check_profile_idc(10)) {
+ptl->max_14bit_constraint_flag= get_bits1(gb);
+skip_bits_long(gb, 33); // XXX_reserved_zero_33bits[0..32]
+} else {
+skip_bits_long(gb, 34); // XXX_reserved_zero_34bits[0..33]
+}
+} else if (check_profile_idc(2)) {
+skip_bits(gb, 7);
+ptl->one_picture_only_constraint_flag = get_bits1(gb);
+skip_bits_long(gb, 35); // XXX_reserved_zero_35bits[0..34]
+} else {
+skip_bits_long(gb, 43); // XXX_reserved_zero_43bits[0..42]
+}
+
+if ((ptl->profile_idc >=1 && ptl->profile_idc <= 5) || ptl->profile_idc == 
9 ||
+ptl->profile_compatibility_flag[1] || 
ptl->profile_compatibility_flag[2] ||
+ptl->profile_compatibility_flag[3] || 
ptl->profile_compatibility_flag[4] ||
+ptl->profile_compatibility_flag[5] || 
ptl->profile_compatibility_flag[9])
+ptl->inbld_flag = get_bits1(gb);
+else
+skip_bits1(gb);
+#undef check_profile_idc
 
 return 0;
 }
diff --git a/libavcodec/hevc_ps.h b/libavcodec/hevc_ps.h
index bbaa9205ef..64f1a1e209 100644
--- a/libavcodec/hevc_ps.h
+++ b/libavcodec/hevc_ps.h
@@ -177,11 +177,22 @@ typedef struct PTLCommon {
 uint8_t tier_flag;
 uint8_t profile_idc;
 uint8_t profile_compatibility_flag[32];
-uint8_t level_idc;
 uint8_t progressive_source_flag;
 uint8_t interlaced_source_flag;
 uint8_t non_packed_constraint_flag;
 uint8_t frame_only_constraint_flag;
+uint8_t max_12bit_constraint_flag;
+uint8_t max_10bit_constraint_flag;
+uint8_t max_8bit_constraint_flag;
+uint8_t max_422chroma_constraint_flag;
+uint8_t max_420chroma_constraint_flag;
+uint8_t max_monochrome_constraint_flag;
+uint8_t intra_constraint_flag;
+uint8_t one_picture_only_constraint_flag;
+uint8_t lower_bit_rate_constraint_flag;
+uint8_t max_14bit_constraint_flag;
+uint8_t inbld_flag;
+uint8_t level_idc;
 } PTLCommon;
 
 typedef struct PTL {
-- 
2.17.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] lavc/vaapi_hevc: add vaapi_parse_rext_profile to find exact va_profile

2019-04-28 Thread Linjie Fu
Add vaapi_parse_rext_profile and use profile constraint flags to
determine the exact va_profile for HEVC_REXT.

Add build object in Makefile for h265_profile_level dependency.

Signed-off-by: Linjie Fu 
---
 libavcodec/Makefile |  2 +-
 libavcodec/vaapi_hevc.c | 69 +
 libavcodec/vaapi_hevc.h | 24 ++
 3 files changed, 94 insertions(+), 1 deletion(-)
 create mode 100644 libavcodec/vaapi_hevc.h

diff --git a/libavcodec/Makefile b/libavcodec/Makefile
index f37135fc07..4f6a7acb92 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -878,7 +878,7 @@ OBJS-$(CONFIG_HEVC_D3D11VA_HWACCEL)   += dxva2_hevc.o
 OBJS-$(CONFIG_HEVC_DXVA2_HWACCEL) += dxva2_hevc.o
 OBJS-$(CONFIG_HEVC_NVDEC_HWACCEL) += nvdec_hevc.o
 OBJS-$(CONFIG_HEVC_QSV_HWACCEL)   += qsvdec_h2645.o
-OBJS-$(CONFIG_HEVC_VAAPI_HWACCEL) += vaapi_hevc.o
+OBJS-$(CONFIG_HEVC_VAAPI_HWACCEL) += vaapi_hevc.o h265_profile_level.o
 OBJS-$(CONFIG_HEVC_VDPAU_HWACCEL) += vdpau_hevc.o
 OBJS-$(CONFIG_MJPEG_NVDEC_HWACCEL)+= nvdec_mjpeg.o
 OBJS-$(CONFIG_MJPEG_VAAPI_HWACCEL)+= vaapi_mjpeg.o
diff --git a/libavcodec/vaapi_hevc.c b/libavcodec/vaapi_hevc.c
index c69d63d8ec..dd48747787 100644
--- a/libavcodec/vaapi_hevc.c
+++ b/libavcodec/vaapi_hevc.c
@@ -27,6 +27,8 @@
 #include "hevcdec.h"
 #include "hwaccel.h"
 #include "vaapi_decode.h"
+#include "vaapi_hevc.h"
+#include "h265_profile_level.h"
 
 typedef struct VAAPIDecodePictureHEVC {
 VAPictureParameterBufferHEVC pic_param;
@@ -421,6 +423,73 @@ static int vaapi_hevc_decode_slice(AVCodecContext *avctx,
 return 0;
 }
 
+static int ptl_convert(const PTLCommon *general_ptl, H265RawProfileTierLevel 
*h265_raw_ptl)
+{
+h265_raw_ptl->general_profile_space = general_ptl->profile_space;
+h265_raw_ptl->general_tier_flag = general_ptl->tier_flag;
+h265_raw_ptl->general_profile_idc   = general_ptl->profile_idc;
+
+memcpy(h265_raw_ptl->general_profile_compatibility_flag,
+  general_ptl->profile_compatibility_flag, 32 
* sizeof(int));
+
+h265_raw_ptl->general_progressive_source_flag  = 
general_ptl->progressive_source_flag;
+h265_raw_ptl->general_interlaced_source_flag   = 
general_ptl->interlaced_source_flag;
+h265_raw_ptl->general_non_packed_constraint_flag   = 
general_ptl->non_packed_constraint_flag;
+h265_raw_ptl->general_frame_only_constraint_flag   = 
general_ptl->frame_only_constraint_flag;
+h265_raw_ptl->general_max_12bit_constraint_flag= 
general_ptl->max_12bit_constraint_flag;
+h265_raw_ptl->general_max_10bit_constraint_flag= 
general_ptl->max_10bit_constraint_flag;
+h265_raw_ptl->general_max_8bit_constraint_flag = 
general_ptl->max_8bit_constraint_flag;
+h265_raw_ptl->general_max_422chroma_constraint_flag= 
general_ptl->max_422chroma_constraint_flag;
+h265_raw_ptl->general_max_420chroma_constraint_flag= 
general_ptl->max_420chroma_constraint_flag;
+h265_raw_ptl->general_max_monochrome_constraint_flag   = 
general_ptl->max_monochrome_constraint_flag;
+h265_raw_ptl->general_intra_constraint_flag= 
general_ptl->intra_constraint_flag;
+h265_raw_ptl->general_one_picture_only_constraint_flag = 
general_ptl->one_picture_only_constraint_flag;
+h265_raw_ptl->general_lower_bit_rate_constraint_flag   = 
general_ptl->lower_bit_rate_constraint_flag;
+h265_raw_ptl->general_max_14bit_constraint_flag= 
general_ptl->max_14bit_constraint_flag;
+h265_raw_ptl->general_inbld_flag   = 
general_ptl->inbld_flag;
+h265_raw_ptl->general_level_idc= 
general_ptl->level_idc;
+
+return 0;
+}
+
+/*
+ * Find exact va_profile for HEVC Range Extension
+ */
+VAProfile ff_vaapi_parse_rext_profile(AVCodecContext *avctx)
+{
+const HEVCContext *h = avctx->priv_data;
+const HEVCSPS *sps = h->ps.sps;
+const PTL *ptl = &(sps->ptl);
+const PTLCommon *general_ptl = &(ptl->general_ptl);
+const H265ProfileDescriptor *profile = NULL;
+
+H265RawProfileTierLevel *h265_raw_ptl = 
av_mallocz(sizeof(H265RawProfileTierLevel));
+/* convert PTLCommon to H265RawProfileTierLevel */
+ptl_convert(general_ptl, h265_raw_ptl);
+
+profile = ff_h265_get_profile(h265_raw_ptl);
+av_freep(&h265_raw_ptl);
+
+if (!profile)
+return VAProfileNone;
+
+#if VA_CHECK_VERSION(1, 2, 0)
+if (!strcmp(profile->name, "Main 4:2:2 10") ||
+!strcmp(profile->name, "Main 4:2:2 10 Intra"))
+return VAProfileHEVCMain422_10;
+else if (!strcmp(profile->name, "Main 4:4:4") ||
+ !strcmp(profile->name, "Main 4:4:4 Intra

[FFmpeg-devel] [PATCH 3/3, v5] lavc/vaapi_decode: add profile_parser to find the exact va_profile

2019-04-28 Thread Linjie Fu
Add function pointer field in vaapi_profile_map[], set profile_parser
for HEVC_REXT to find the exact va_profile.

Signed-off-by: Linjie Fu 
---
SPS range extension fields should be passed to decoder, will use
VAPictureParameterBufferHEVCExtension consist of base and rext.

 libavcodec/vaapi_decode.c | 71 ++-
 1 file changed, 41 insertions(+), 30 deletions(-)

diff --git a/libavcodec/vaapi_decode.c b/libavcodec/vaapi_decode.c
index 69512e1d45..7c9cfbc0ed 100644
--- a/libavcodec/vaapi_decode.c
+++ b/libavcodec/vaapi_decode.c
@@ -24,7 +24,7 @@
 #include "decode.h"
 #include "internal.h"
 #include "vaapi_decode.h"
-
+#include "vaapi_hevc.h"
 
 int ff_vaapi_decode_make_param_buffer(AVCodecContext *avctx,
   VAAPIDecodePicture *pic,
@@ -364,39 +364,44 @@ static const struct {
 enum AVCodecID codec_id;
 int codec_profile;
 VAProfile va_profile;
+VAProfile (*profile_parser)(AVCodecContext *avctx);
 } vaapi_profile_map[] = {
-#define MAP(c, p, v) { AV_CODEC_ID_ ## c, FF_PROFILE_ ## p, VAProfile ## v }
-MAP(MPEG2VIDEO,  MPEG2_SIMPLE,MPEG2Simple ),
-MAP(MPEG2VIDEO,  MPEG2_MAIN,  MPEG2Main   ),
-MAP(H263,UNKNOWN, H263Baseline),
-MAP(MPEG4,   MPEG4_SIMPLE,MPEG4Simple ),
+#define MAP(c, p, v, f) { AV_CODEC_ID_ ## c, FF_PROFILE_ ## p, VAProfile ## v, 
f}
+MAP(MPEG2VIDEO,  MPEG2_SIMPLE,MPEG2Simple , NULL ),
+MAP(MPEG2VIDEO,  MPEG2_MAIN,  MPEG2Main   , NULL ),
+MAP(H263,UNKNOWN, H263Baseline, NULL ),
+MAP(MPEG4,   MPEG4_SIMPLE,MPEG4Simple , NULL ),
 MAP(MPEG4,   MPEG4_ADVANCED_SIMPLE,
-   MPEG4AdvancedSimple),
-MAP(MPEG4,   MPEG4_MAIN,  MPEG4Main   ),
+   MPEG4AdvancedSimple, NULL ),
+MAP(MPEG4,   MPEG4_MAIN,  MPEG4Main   , NULL ),
 MAP(H264,H264_CONSTRAINED_BASELINE,
-   H264ConstrainedBaseline),
-MAP(H264,H264_MAIN,   H264Main),
-MAP(H264,H264_HIGH,   H264High),
+   H264ConstrainedBaseline, NULL ),
+MAP(H264,H264_MAIN,   H264Main, NULL ),
+MAP(H264,H264_HIGH,   H264High, NULL ),
 #if VA_CHECK_VERSION(0, 37, 0)
-MAP(HEVC,HEVC_MAIN,   HEVCMain),
-MAP(HEVC,HEVC_MAIN_10,HEVCMain10  ),
+MAP(HEVC,HEVC_MAIN,   HEVCMain, NULL ),
+MAP(HEVC,HEVC_MAIN_10,HEVCMain10  , NULL ),
+#endif
+#if VA_CHECK_VERSION(1, 2, 0)
+MAP(HEVC,HEVC_REXT,   None,
+  ff_vaapi_parse_rext_profile),
 #endif
 MAP(MJPEG,   MJPEG_HUFFMAN_BASELINE_DCT,
-  JPEGBaseline),
-MAP(WMV3,VC1_SIMPLE,  VC1Simple   ),
-MAP(WMV3,VC1_MAIN,VC1Main ),
-MAP(WMV3,VC1_COMPLEX, VC1Advanced ),
-MAP(WMV3,VC1_ADVANCED,VC1Advanced ),
-MAP(VC1, VC1_SIMPLE,  VC1Simple   ),
-MAP(VC1, VC1_MAIN,VC1Main ),
-MAP(VC1, VC1_COMPLEX, VC1Advanced ),
-MAP(VC1, VC1_ADVANCED,VC1Advanced ),
-MAP(VP8, UNKNOWN,   VP8Version0_3 ),
+  JPEGBaseline, NULL ),
+MAP(WMV3,VC1_SIMPLE,  VC1Simple   , NULL ),
+MAP(WMV3,VC1_MAIN,VC1Main , NULL ),
+MAP(WMV3,VC1_COMPLEX, VC1Advanced , NULL ),
+MAP(WMV3,VC1_ADVANCED,VC1Advanced , NULL ),
+MAP(VC1, VC1_SIMPLE,  VC1Simple   , NULL ),
+MAP(VC1, VC1_MAIN,VC1Main , NULL ),
+MAP(VC1, VC1_COMPLEX, VC1Advanced , NULL ),
+MAP(VC1, VC1_ADVANCED,VC1Advanced , NULL ),
+MAP(VP8, UNKNOWN,   VP8Version0_3 , NULL ),
 #if VA_CHECK_VERSION(0, 38, 0)
-MAP(VP9, VP9_0,   VP9Profile0 ),
+MAP(VP9, VP9_0,   VP9Profile0 , NULL ),
 #endif
 #if VA_CHECK_VERSION(0, 39, 0)
-MAP(VP9, VP9_2,   VP9Profile2 ),
+MAP(VP9, VP9_2,   VP9Profile2 , NULL ),
 #endif
 #undef MAP
 };
@@ -415,8 +420,8 @@ static int vaapi_decode_make_config(AVCodecContext *avctx,
 VAStatus vas;
 int err, i, j;
 const AVCodecDescriptor *codec_desc;
-VAProfile *profile_list = NULL, matched_va_profile;
-int profile_count, exact_match, matched_ff_profile;
+VAProfile *profile_list = NULL, matched_va_profile, tmp_va_profile;
+int profile_count, exact_match, matched_ff_profile, tmp_codec_profile;
 
 AVHWDeviceContext*device = (AVHWDeviceContext*)device_ref->data;
 AVVAAPIDeviceContext *hwctx = device->hwctx;
@@ -454,15 +459,21 @@ static int vaapi_decode_make_config(AVCodecContext *avctx,
 if (avctx->profile == vaapi_profile_map[i].codec_profile |

[FFmpeg-devel] [PATCH] lavc/vaapi_encode: disable ICQ mode when enabling low power

2019-05-21 Thread Linjie Fu
ICQ mode is not supported in low power mode and should be disabled.

For H264, Driver supports RC modes CQP, CBR, VBR, QVBR.
For HEVC, Driver supports RC modes CQP, CBR, VBR, ICQ, QVBR.

ICQ is not exposed while working on low power mode for h264_vaapi, but
will trigger issues for hevc_vaapi.

Signed-off-by: Linjie Fu 
---
See https://github.com/intel/media-driver/issues/618 for details.
And patch for HEVC low power(ICL+): 
https://github.com/intel-media-ci/ffmpeg/pull/42

 libavcodec/vaapi_encode.c | 7 +--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/libavcodec/vaapi_encode.c b/libavcodec/vaapi_encode.c
index 2dda451..55ab919 100644
--- a/libavcodec/vaapi_encode.c
+++ b/libavcodec/vaapi_encode.c
@@ -1371,6 +1371,7 @@ static av_cold int 
vaapi_encode_init_rate_control(AVCodecContext *avctx)
 // * If bitrate and maxrate are set and have the same value, try CBR.
 // * If a bitrate is set, try AVBR, then VBR, then CBR.
 // * If no bitrate is set, try ICQ, then CQP.
+// * If low power is set, ICQ is not supported.
 
 #define TRY_RC_MODE(mode, fail) do { \
 rc_mode = &vaapi_encode_rc_modes[mode]; \
@@ -1405,7 +1406,8 @@ static av_cold int 
vaapi_encode_init_rate_control(AVCodecContext *avctx)
 TRY_RC_MODE(RC_MODE_QVBR, 0);
 
 if (avctx->global_quality > 0) {
-TRY_RC_MODE(RC_MODE_ICQ, 0);
+if (!ctx->low_power)
+TRY_RC_MODE(RC_MODE_ICQ, 0);
 TRY_RC_MODE(RC_MODE_CQP, 0);
 }
 
@@ -1417,7 +1419,8 @@ static av_cold int 
vaapi_encode_init_rate_control(AVCodecContext *avctx)
 TRY_RC_MODE(RC_MODE_VBR, 0);
 TRY_RC_MODE(RC_MODE_CBR, 0);
 } else {
-TRY_RC_MODE(RC_MODE_ICQ, 0);
+if (!ctx->low_power)
+TRY_RC_MODE(RC_MODE_ICQ, 0);
 TRY_RC_MODE(RC_MODE_CQP, 0);
 }
 
-- 
2.7.4

___
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] lavc/vaapi_encode: grow packet if vaMapBuffer returns multiple buffers

2019-05-29 Thread Linjie Fu
It seems that VA_CODED_BUF_STATUS_SINGLE_NALU allows driver to map
buffer for each slice.

Currently, assigning new buffer for pkt when multiple buffer returns
from vaMapBuffer will cover the previous encoded pkt data and lead
to encode issues.

Using av_grow_packet to expand pkt if several buffers are returned.

Signed-off-by: Linjie Fu 
---
 libavcodec/vaapi_encode.c | 12 ++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/libavcodec/vaapi_encode.c b/libavcodec/vaapi_encode.c
index 2dda451..2812237 100644
--- a/libavcodec/vaapi_encode.c
+++ b/libavcodec/vaapi_encode.c
@@ -490,6 +490,7 @@ static int vaapi_encode_output(AVCodecContext *avctx,
 VACodedBufferSegment *buf_list, *buf;
 VAStatus vas;
 int err;
+uint8_t *ptr;
 
 err = vaapi_encode_wait(avctx, pic);
 if (err < 0)
@@ -509,11 +510,18 @@ static int vaapi_encode_output(AVCodecContext *avctx,
 av_log(avctx, AV_LOG_DEBUG, "Output buffer: %u bytes "
"(status %08x).\n", buf->size, buf->status);
 
-err = av_new_packet(pkt, buf->size);
+if (pkt->size)
+err = av_grow_packet(pkt, buf->size);
+else {
+err = av_new_packet(pkt, buf->size);
+ptr = pkt->data;
+}
+
 if (err < 0)
 goto fail_mapped;
 
-memcpy(pkt->data, buf->buf, buf->size);
+memcpy(ptr, buf->buf, buf->size);
+ptr += buf->size;
 }
 
 if (pic->type == PICTURE_TYPE_IDR)
-- 
2.7.4

___
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] lavf/qsvvpp: allocate continuous memory

2019-05-29 Thread Linjie Fu
Mediasdk calls CMRT to copy from video to system memory and requires
memory to be continuously allocated across Y and UV.

Add a new path to allocate continuous memory when using system out.
Use av_image_fill_pointers to arrange data according to pixfmt.

Signed-off-by: Linjie Fu 
---
[v2]: use av_image_fill_pointers

 libavfilter/qsvvpp.c | 32 +++-
 1 file changed, 27 insertions(+), 5 deletions(-)

diff --git a/libavfilter/qsvvpp.c b/libavfilter/qsvvpp.c
index 06efdf5089..6eeed7e632 100644
--- a/libavfilter/qsvvpp.c
+++ b/libavfilter/qsvvpp.c
@@ -27,6 +27,7 @@
 #include "libavutil/hwcontext_qsv.h"
 #include "libavutil/time.h"
 #include "libavutil/pixdesc.h"
+#include "libavutil/imgutils.h"
 
 #include "internal.h"
 #include "qsvvpp.h"
@@ -51,6 +52,7 @@ struct QSVVPPContext {
 enum AVPixelFormat  out_sw_format;   /* Real output format */
 mfxVideoParam   vpp_param;
 mfxFrameInfo   *frame_infos; /* frame info for each input */
+AVBufferPool   *pool;
 
 /* members related to the input/output surface */
 int in_mem_mode;
@@ -375,10 +377,24 @@ static QSVFrame *query_frame(QSVVPPContext *s, 
AVFilterLink *outlink)
 out_frame->surface = (mfxFrameSurface1 *)out_frame->frame->data[3];
 } else {
 /* Get a frame with aligned dimensions.
- * Libmfx need system memory being 128x64 aligned */
-out_frame->frame = ff_get_video_buffer(outlink,
-   FFALIGN(outlink->w, 128),
-   FFALIGN(outlink->h, 64));
+ * Libmfx need system memory being 128x64 aligned
+ * and continuously allocated across Y and UV */
+out_frame->frame = av_frame_alloc();
+if (!out_frame->frame) {
+return NULL;
+}
+
+out_frame->frame->linesize[0] = FFALIGN(outlink->w, 128);
+out_frame->frame->linesize[1] = out_frame->frame->linesize[0];
+out_frame->frame->buf[0]  = av_buffer_pool_get(s->pool);
+out_frame->frame->format  = outlink->format;
+
+if (!out_frame->frame->buf[0])
+return NULL;
+
+av_image_fill_pointers(out_frame->frame->data, 
out_frame->frame->format,
+FFALIGN(outlink->h, 64), 
out_frame->frame->buf[0]->data,
+
out_frame->frame->linesize);
 if (!out_frame->frame)
 return NULL;
 
@@ -483,8 +499,13 @@ static int init_vpp_session(AVFilterContext *avctx, 
QSVVPPContext *s)
 
 av_buffer_unref(&outlink->hw_frames_ctx);
 outlink->hw_frames_ctx = out_frames_ref;
-} else
+} else {
 s->out_mem_mode = MFX_MEMTYPE_SYSTEM_MEMORY;
+s->pool = av_buffer_pool_init(av_image_get_buffer_size(outlink->format,
+FFALIGN(outlink->w, 
128),
+FFALIGN(outlink->h, 
64), 1),
+av_buffer_allocz);
+}
 
 /* extract the properties of the "master" session given to us */
 ret = MFXQueryIMPL(device_hwctx->session, &impl);
@@ -674,6 +695,7 @@ int ff_qsvvpp_free(QSVVPPContext **vpp)
 /* release all the resources */
 clear_frame_list(&s->in_frame_list);
 clear_frame_list(&s->out_frame_list);
+av_buffer_pool_uninit(&s->pool);
 av_freep(&s->surface_ptrs_in);
 av_freep(&s->surface_ptrs_out);
 av_freep(&s->ext_buffers);
-- 
2.17.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] lavc/vaapi_encode: grow packet if vaMapBuffer returns multiple buffers

2019-05-30 Thread Linjie Fu
It seems that VA_CODED_BUF_STATUS_SINGLE_NALU allows driver to map
buffer for each slice.

Currently, assigning new buffer for pkt when multiple buffer returns
from vaMapBuffer will cover the previous encoded pkt data and lead
to encode issues.

Iterate through the buf_list first to find out the total buffer size
needed for the pkt, allocate the whole pkt to avoid repeated reallocation
and memcpy, then copy data from each buf to pkt.

Signed-off-by: Linjie Fu 
---
[v2]: allocate the whole pkt to avoid repeated reallocation
and memcpy

 libavcodec/vaapi_encode.c | 18 +-
 1 file changed, 13 insertions(+), 5 deletions(-)

diff --git a/libavcodec/vaapi_encode.c b/libavcodec/vaapi_encode.c
index 2dda451..9c9e5dd 100644
--- a/libavcodec/vaapi_encode.c
+++ b/libavcodec/vaapi_encode.c
@@ -489,6 +489,8 @@ static int vaapi_encode_output(AVCodecContext *avctx,
 VAAPIEncodeContext *ctx = avctx->priv_data;
 VACodedBufferSegment *buf_list, *buf;
 VAStatus vas;
+int total_size = 0;
+uint8_t *ptr;
 int err;
 
 err = vaapi_encode_wait(avctx, pic);
@@ -505,15 +507,21 @@ static int vaapi_encode_output(AVCodecContext *avctx,
 goto fail;
 }
 
+for (buf = buf_list; buf; buf = buf->next)
+total_size += buf->size;
+
+err = av_new_packet(pkt, total_size);
+ptr = pkt->data;
+
+if (err < 0)
+goto fail_mapped;
+
 for (buf = buf_list; buf; buf = buf->next) {
 av_log(avctx, AV_LOG_DEBUG, "Output buffer: %u bytes "
"(status %08x).\n", buf->size, buf->status);
 
-err = av_new_packet(pkt, buf->size);
-if (err < 0)
-goto fail_mapped;
-
-memcpy(pkt->data, buf->buf, buf->size);
+memcpy(ptr, buf->buf, buf->size);
+ptr += buf->size;
 }
 
 if (pic->type == PICTURE_TYPE_IDR)
-- 
2.7.4

___
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] lavf/qsvvpp:allocate continuous memory

2019-06-04 Thread Linjie Fu
Mediasdk calls CMRT to copy from video to system memory and requires
memory to be continuously allocated across Y and UV.

Add a new path to allocate continuous memory when using system out.
Use av_frame_get_buffer to arrange data according to pixfmt, and remove
the introduced plane_padding.

Signed-off-by: Linjie Fu 
---
 libavfilter/qsvvpp.c | 26 --
 1 file changed, 20 insertions(+), 6 deletions(-)

diff --git a/libavfilter/qsvvpp.c b/libavfilter/qsvvpp.c
index 5cd1d5d345..c06171444f 100644
--- a/libavfilter/qsvvpp.c
+++ b/libavfilter/qsvvpp.c
@@ -350,7 +350,7 @@ static QSVFrame *query_frame(QSVVPPContext *s, AVFilterLink 
*outlink)
 {
 AVFilterContext *ctx = outlink->src;
 QSVFrame*out_frame;
-int  ret;
+int  i, ret;
 
 clear_unused_frames(s->out_frame_list);
 
@@ -374,12 +374,26 @@ static QSVFrame *query_frame(QSVVPPContext *s, 
AVFilterLink *outlink)
 out_frame->surface = (mfxFrameSurface1 *)out_frame->frame->data[3];
 } else {
 /* Get a frame with aligned dimensions.
- * Libmfx need system memory being 128x64 aligned */
-out_frame->frame = ff_get_video_buffer(outlink,
-   FFALIGN(outlink->w, 128),
-   FFALIGN(outlink->h, 64));
-if (!out_frame->frame)
+ * Libmfx need system memory being 128x64 aligned
+ * and continuously allocated across Y and UV */
+out_frame->frame = av_frame_alloc();
+if (!out_frame->frame) {
 return NULL;
+}
+
+out_frame->frame->width  = FFALIGN(outlink->w, 128);
+out_frame->frame->height = FFALIGN(outlink->h, 64);
+out_frame->frame->format = outlink->format;
+
+ret = av_frame_get_buffer(out_frame->frame, 128);
+if (ret < 0)
+return NULL;
+
+/* remove plane_padding introduced by av_frame_get_buffer */
+for (i = 1; i < 4; i++) {
+if (out_frame->frame->data[i])
+out_frame->frame->data[i] -= i * 128;
+}
 
 out_frame->frame->width  = outlink->w;
 out_frame->frame->height = outlink->h;
-- 
2.17.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, RFC] lavc/vp9dec: fix the multi-thread HWAccel decode error

2019-06-11 Thread Linjie Fu
Fix the multi-thread HWAccel decode error for vp9.

VP9 supports the resolution changing. In multi-thread mode, worker-threads
destroy and free the first created VAAPIDecodeContext if resolution change
happens and create new one. Other threads still request to destroy previous
and demand for new context. This leads to decode failures and memory issue.

Modify to call hwaccel_uninit/hwaccel_init by ff_thread_get_format only
when the first-come thread detected the resolution changing.

Signed-off-by: Linjie Fu 
---
Fix the same issue vaapi_vp8 decoding meets:
https://patchwork.ffmpeg.org/patch/12507/

 libavcodec/vp9.c| 18 ++
 libavcodec/vp9dec.h |  2 ++
 2 files changed, 16 insertions(+), 4 deletions(-)

diff --git a/libavcodec/vp9.c b/libavcodec/vp9.c
index acf3ffc..e2fad9d 100644
--- a/libavcodec/vp9.c
+++ b/libavcodec/vp9.c
@@ -179,6 +179,7 @@ static int update_size(AVCodecContext *avctx, int w, int h)
 uint8_t *p;
 int bytesperpixel = s->bytesperpixel, ret, cols, rows;
 int lflvl_len, i;
+int dim_reset = 0;
 
 av_assert0(w > 0 && h > 0);
 
@@ -186,6 +187,10 @@ static int update_size(AVCodecContext *avctx, int w, int h)
 if ((ret = ff_set_dimensions(avctx, w, h)) < 0)
 return ret;
 
+if (!avctx->internal->hwaccel_priv_data ||
+s->context == avctx->internal->hwaccel_priv_data)
+dim_reset = 1;
+
 switch (s->pix_fmt) {
 case AV_PIX_FMT_YUV420P:
 case AV_PIX_FMT_YUV420P10:
@@ -216,16 +221,21 @@ static int update_size(AVCodecContext *avctx, int w, int 
h)
 *fmtp++ = s->pix_fmt;
 *fmtp = AV_PIX_FMT_NONE;
 
-ret = ff_thread_get_format(avctx, pix_fmts);
-if (ret < 0)
-return ret;
+if (dim_reset) {
+ret = ff_thread_get_format(avctx, pix_fmts);
+if (ret < 0)
+return ret;
+
+avctx->pix_fmt = ret;
+}
 
-avctx->pix_fmt = ret;
 s->gf_fmt  = s->pix_fmt;
 s->w = w;
 s->h = h;
 }
 
+s->context = avctx->internal->hwaccel_priv_data;
+
 cols = (w + 7) >> 3;
 rows = (h + 7) >> 3;
 
diff --git a/libavcodec/vp9dec.h b/libavcodec/vp9dec.h
index 66573ed..bc3f36c 100644
--- a/libavcodec/vp9dec.h
+++ b/libavcodec/vp9dec.h
@@ -152,6 +152,8 @@ typedef struct VP9Context {
 int block_alloc_using_2pass;
 uint16_t mvscale[3][2];
 uint8_t mvstep[3][2];
+
+void *context;
 } VP9Context;
 
 struct VP9TileData {
-- 
2.7.4

___
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] lavc/vaapi_encode: add support for AVC Trellis

2019-06-12 Thread Linjie Fu
Add support for VAAPI AVC Trellis Quantization with limitation:
- VA-API version >= (1, 0, 0)

Use option "-trellis off/I/P/B" to disable or enable Trellis
quantization for I/P/B frames.

Signed-off-by: Linjie Fu 
---
[v2]: Since nonstandard struct for VAEncMiscParameterQuantization is
fixed: https://github.com/intel/libva/issues/265
update patch based on:
http://git.ffmpeg.org/gitweb/ffmpeg.git/commit/2880a32c668023bfee4745095c885450d547ae45
 libavcodec/vaapi_encode.c  | 48 ++
 libavcodec/vaapi_encode.h  |  9 +--
 libavcodec/vaapi_encode_h264.c |  9 +++
 3 files changed, 64 insertions(+), 2 deletions(-)

diff --git a/libavcodec/vaapi_encode.c b/libavcodec/vaapi_encode.c
index dd2a24de04..fbfbe78c6b 100644
--- a/libavcodec/vaapi_encode.c
+++ b/libavcodec/vaapi_encode.c
@@ -1671,6 +1671,48 @@ rc_mode_found:
 return 0;
 }
 
+static av_cold int vaapi_encode_init_quantization(AVCodecContext *avctx)
+{
+#if VA_CHECK_VERSION(1, 0, 0)
+VAAPIEncodeContext *ctx = avctx->priv_data;
+VAStatus vas;
+VAConfigAttrib attr = { VAConfigAttribEncQuantization };
+int trellis = ctx->trellis;
+
+vas = vaGetConfigAttributes(ctx->hwctx->display,
+ctx->va_profile,
+ctx->va_entrypoint,
+&attr, 1);
+if (vas != VA_STATUS_SUCCESS) {
+av_log(avctx, AV_LOG_ERROR, "Failed to query quantization "
+   "config attribute: %d (%s).\n", vas, vaErrorStr(vas));
+return AVERROR_EXTERNAL;
+}
+
+if (attr.value == VA_ATTRIB_NOT_SUPPORTED ||
+attr.value == VA_ENC_QUANTIZATION_NONE) {
+av_log(avctx, AV_LOG_WARNING, "Special Quantization attribute is not "
+"supported: will use default quantization.\n");
+} else if (attr.value == VA_ENC_QUANTIZATION_TRELLIS_SUPPORTED){
+av_log(avctx, AV_LOG_VERBOSE, "Quantization Trellis supported.\n");
+
+ctx->quantization_params = (VAEncMiscParameterQuantization) {
+.quantization_flags.value = trellis,
+};
+
+vaapi_encode_add_global_param(avctx,
+  VAEncMiscParameterTypeQuantization,
+  &ctx->quantization_params,
+  sizeof(ctx->quantization_params));
+}
+#else
+av_log(avctx, AV_LOG_WARNING, "The encode quantization option (Trellis) is 
"
+   "not supported with this VAAPI version.\n");
+#endif
+
+return 0;
+}
+
 static av_cold int vaapi_encode_init_gop_structure(AVCodecContext *avctx)
 {
 VAAPIEncodeContext *ctx = avctx->priv_data;
@@ -2132,6 +2174,12 @@ av_cold int ff_vaapi_encode_init(AVCodecContext *avctx)
 if (err < 0)
 goto fail;
 
+if (ctx->trellis) {
+err = vaapi_encode_init_quantization(avctx);
+if (err < 0)
+goto fail;
+}
+
 if (avctx->compression_level >= 0) {
 err = vaapi_encode_init_quality(avctx);
 if (err < 0)
diff --git a/libavcodec/vaapi_encode.h b/libavcodec/vaapi_encode.h
index eeec06036b..b24735da59 100644
--- a/libavcodec/vaapi_encode.h
+++ b/libavcodec/vaapi_encode.h
@@ -37,7 +37,7 @@ struct VAAPIEncodePicture;
 
 enum {
 MAX_CONFIG_ATTRIBUTES  = 4,
-MAX_GLOBAL_PARAMS  = 4,
+MAX_GLOBAL_PARAMS  = 5,
 MAX_DPB_SIZE   = 16,
 MAX_PICTURE_REFERENCES = 2,
 MAX_REORDER_DELAY  = 16,
@@ -220,6 +220,9 @@ typedef struct VAAPIEncodeContext {
 // Packed headers which will actually be sent.
 unsigned intva_packed_headers;
 
+// Quantization mode
+int trellis;
+
 // Configuration attributes to use when creating va_config.
 VAConfigAttrib  config_attributes[MAX_CONFIG_ATTRIBUTES];
 int  nb_config_attributes;
@@ -256,7 +259,9 @@ typedef struct VAAPIEncodeContext {
 #if VA_CHECK_VERSION(0, 36, 0)
 VAEncMiscParameterBufferQualityLevel quality_params;
 #endif
-
+#if VA_CHECK_VERSION(1, 0, 0)
+VAEncMiscParameterQuantization quantization_params;
+#endif
 // Per-sequence parameter structure (VAEncSequenceParameterBuffer*).
 void   *codec_sequence_params;
 
diff --git a/libavcodec/vaapi_encode_h264.c b/libavcodec/vaapi_encode_h264.c
index d1427112ea..427fb6320e 100644
--- a/libavcodec/vaapi_encode_h264.c
+++ b/libavcodec/vaapi_encode_h264.c
@@ -72,6 +72,7 @@ typedef struct VAAPIEncodeH264Context {
 int sei;
 int profile;
 int level;
+int trellis;
 
 // Derived settings.
 int mb_width;
@@ -1233,6 +1234,8 @@ static av_cold int vaapi_encode_h264_init(AVCodecContext 
*avctx)
 if (priv->qp > 0)
 ctx->explicit_qp = priv->qp;
 
+ctx->trellis = priv->trellis;
+
 return ff_vaapi_encode_init(avctx);
 }
 
@@ -1263,6 +1266,12 @@ static cons

[FFmpeg-devel] [PATCH v3, 1/2] lavc/vaapi_encode: add support for AVC Trellis

2019-06-16 Thread Linjie Fu
Trellis quantization is an algorithm that can improve data compression
in DCT-based encoding methods. It reduces the size of some DCT
coefficients while recovering others to take their place.

Trellis quantization effectively finds the optimal quantization for
each block to maximize the PSNR relative to bitrate.

Add support for VAAPI AVC Trellis Quantization with limitation:
- VA-API version >= (1, 5, 0)

Use option "-trellis off/I/P/B" to disable or enable Trellis
quantization for I/P/B frames.

Signed-off-by: Linjie Fu 
---
 libavcodec/vaapi_encode.c | 47 +++
 libavcodec/vaapi_encode.h | 19 +---
 2 files changed, 63 insertions(+), 3 deletions(-)

diff --git a/libavcodec/vaapi_encode.c b/libavcodec/vaapi_encode.c
index dd2a24de04..394c824069 100644
--- a/libavcodec/vaapi_encode.c
+++ b/libavcodec/vaapi_encode.c
@@ -1671,6 +1671,47 @@ rc_mode_found:
 return 0;
 }
 
+static av_cold int vaapi_encode_init_quantization(AVCodecContext *avctx)
+{
+#if VA_CHECK_VERSION(1, 5, 0)
+VAAPIEncodeContext *ctx = avctx->priv_data;
+VAStatus vas;
+VAConfigAttrib attr = { VAConfigAttribEncQuantization };
+
+vas = vaGetConfigAttributes(ctx->hwctx->display,
+ctx->va_profile,
+ctx->va_entrypoint,
+&attr, 1);
+if (vas != VA_STATUS_SUCCESS) {
+av_log(avctx, AV_LOG_ERROR, "Failed to query quantization "
+   "config attribute: %d (%s).\n", vas, vaErrorStr(vas));
+return AVERROR_EXTERNAL;
+}
+
+if (attr.value == VA_ATTRIB_NOT_SUPPORTED ||
+attr.value == VA_ENC_QUANTIZATION_NONE) {
+av_log(avctx, AV_LOG_WARNING, "Special Quantization attribute is not "
+"supported: will use default quantization.\n");
+} else if (attr.value == VA_ENC_QUANTIZATION_TRELLIS_SUPPORTED){
+av_log(avctx, AV_LOG_VERBOSE, "Quantization Trellis supported.\n");
+
+ctx->quantization_params = (VAEncMiscParameterQuantization) {
+.quantization_flags.value = ctx->trellis,
+};
+
+vaapi_encode_add_global_param(avctx,
+  VAEncMiscParameterTypeQuantization,
+  &ctx->quantization_params,
+  sizeof(ctx->quantization_params));
+}
+#else
+av_log(avctx, AV_LOG_WARNING, "The encode quantization option (Trellis) is 
"
+   "not supported with this VAAPI version.\n");
+#endif
+
+return 0;
+}
+
 static av_cold int vaapi_encode_init_gop_structure(AVCodecContext *avctx)
 {
 VAAPIEncodeContext *ctx = avctx->priv_data;
@@ -2132,6 +2173,12 @@ av_cold int ff_vaapi_encode_init(AVCodecContext *avctx)
 if (err < 0)
 goto fail;
 
+if (ctx->trellis) {
+err = vaapi_encode_init_quantization(avctx);
+if (err < 0)
+goto fail;
+}
+
 if (avctx->compression_level >= 0) {
 err = vaapi_encode_init_quality(avctx);
 if (err < 0)
diff --git a/libavcodec/vaapi_encode.h b/libavcodec/vaapi_encode.h
index eeec06036b..9b7f29a2d2 100644
--- a/libavcodec/vaapi_encode.h
+++ b/libavcodec/vaapi_encode.h
@@ -37,7 +37,7 @@ struct VAAPIEncodePicture;
 
 enum {
 MAX_CONFIG_ATTRIBUTES  = 4,
-MAX_GLOBAL_PARAMS  = 4,
+MAX_GLOBAL_PARAMS  = 5,
 MAX_DPB_SIZE   = 16,
 MAX_PICTURE_REFERENCES = 2,
 MAX_REORDER_DELAY  = 16,
@@ -176,6 +176,9 @@ typedef struct VAAPIEncodeContext {
 // Desired B frame reference depth.
 int desired_b_depth;
 
+// Quantization mode
+int trellis;
+
 // Explicitly set RC mode (otherwise attempt to pick from
 // available modes).
 int explicit_rc_mode;
@@ -256,7 +259,9 @@ typedef struct VAAPIEncodeContext {
 #if VA_CHECK_VERSION(0, 36, 0)
 VAEncMiscParameterBufferQualityLevel quality_params;
 #endif
-
+#if VA_CHECK_VERSION(1, 5, 0)
+VAEncMiscParameterQuantization quantization_params;
+#endif
 // Per-sequence parameter structure (VAEncSequenceParameterBuffer*).
 void   *codec_sequence_params;
 
@@ -418,7 +423,15 @@ 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 }, \
+{ "trellis", \
+  "Trellis Quantization", \
+  OFFSET(common.trellis), AV_OPT_TYPE_FLAGS, \
+  { .i64 = 0}, 0, INT_MAX, FLAGS, "trellis"}, \
+  { "off",   NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 1 }, INT_MIN, INT_MAX, 
FLAGS, "trellis"}, \
+  { "I", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 2 

[FFmpeg-devel] [PATCH 2/2] doc/encoders.texi: add docs for trellis

2019-06-16 Thread Linjie Fu
Signed-off-by: Linjie Fu 
---
 doc/encoders.texi | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/doc/encoders.texi b/doc/encoders.texi
index eefd124751..2e54dcc15f 100644
--- a/doc/encoders.texi
+++ b/doc/encoders.texi
@@ -2899,6 +2899,13 @@ will refer only to P- or I-frames.  When set to greater 
values multiple layers
 of B-frames will be present, frames in each layer only referring to frames in
 higher layers.
 
+@item trellis
+Trellis quantization can improve data compression in DCT-based encoding 
methods.
+It reduces the size of some DCT coefficients while recovering others to take 
their
+place. This process can increase quality by effectively finding the optimal
+quantization for each block to maximize the PSNR relative to bitrate.
+Set to off/I/P/B to disable or enable trellis quantization for I/P/B frames.
+
 @item rc_mode
 Set the rate control mode to use.  A given driver may only support a subset of
 modes.
-- 
2.17.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 1/2] lavf/qsvvpp:allocate continuous memory

2019-06-17 Thread Linjie Fu
Mediasdk calls CMRT to copy from video to system memory and requires
memory to be continuously allocated across Y and UV.

Add a new path to allocate continuous memory when using system out.
Use get_continuous_buffer to arrange data according to pixfmt.

Signed-off-by: Linjie Fu 
---
 libavfilter/qsvvpp.c | 67 
 1 file changed, 62 insertions(+), 5 deletions(-)

diff --git a/libavfilter/qsvvpp.c b/libavfilter/qsvvpp.c
index 8d5ff2eb65..07fe53573d 100644
--- a/libavfilter/qsvvpp.c
+++ b/libavfilter/qsvvpp.c
@@ -27,6 +27,7 @@
 #include "libavutil/hwcontext_qsv.h"
 #include "libavutil/time.h"
 #include "libavutil/pixdesc.h"
+#include "libavutil/imgutils.h"
 
 #include "internal.h"
 #include "qsvvpp.h"
@@ -346,6 +347,57 @@ static QSVFrame *submit_frame(QSVVPPContext *s, 
AVFilterLink *inlink, AVFrame *p
 return qsv_frame;
 }
 
+static int get_continuous_buffer(AVFrame *frame, int align)
+{
+const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(frame->format);
+int ret, i, padded_height;
+
+if (!desc)
+return AVERROR(EINVAL);
+
+if ((ret = av_image_check_size(frame->width, frame->height, 0, NULL)) < 0)
+return ret;
+
+if (!frame->linesize[0]) {
+if (align <= 0)
+align = 32; /* STRIDE_ALIGN. Should be av_cpu_max_align() */
+
+for (i=1; i<=align; i+=i) {
+ret = av_image_fill_linesizes(frame->linesize, frame->format,
+  FFALIGN(frame->width, i));
+if (ret < 0)
+return ret;
+if (!(frame->linesize[0] & (align-1)))
+break;
+}
+
+for (i = 0; i < 4 && frame->linesize[i]; i++)
+frame->linesize[i] = FFALIGN(frame->linesize[i], align);
+}
+
+padded_height = FFALIGN(frame->height, 64);
+if ((ret = av_image_fill_pointers(frame->data, frame->format, 
padded_height,
+  NULL, frame->linesize)) < 0)
+return ret;
+
+frame->buf[0] = av_buffer_alloc(ret);
+if (!frame->buf[0]) {
+ret = AVERROR(ENOMEM);
+goto fail;
+}
+
+if ((ret = av_image_fill_pointers(frame->data, frame->format, 
padded_height,
+  frame->buf[0]->data, frame->linesize)) < 
0)
+goto fail;
+
+frame->extended_data = frame->data;
+
+return 0;
+fail:
+av_frame_unref(frame);
+return ret;
+}
+
 /* get the output surface */
 static QSVFrame *query_frame(QSVVPPContext *s, AVFilterLink *outlink)
 {
@@ -375,15 +427,20 @@ static QSVFrame *query_frame(QSVVPPContext *s, 
AVFilterLink *outlink)
 out_frame->surface = (mfxFrameSurface1 *)out_frame->frame->data[3];
 } else {
 /* Get a frame with aligned dimensions.
- * Libmfx need system memory being 128x64 aligned */
-out_frame->frame = ff_get_video_buffer(outlink,
-   FFALIGN(outlink->w, 128),
-   FFALIGN(outlink->h, 64));
-if (!out_frame->frame)
+ * Libmfx need system memory being 128x64 aligned
+ * and continuously allocated across Y and UV */
+out_frame->frame = av_frame_alloc();
+if (!out_frame->frame) {
 return NULL;
+}
 
 out_frame->frame->width  = outlink->w;
 out_frame->frame->height = outlink->h;
+out_frame->frame->format = outlink->format;
+
+ret = get_continuous_buffer(out_frame->frame, 128);
+if (ret < 0)
+return NULL;
 
 ret = map_frame_to_surface(out_frame->frame,
   &out_frame->surface_internal);
-- 
2.17.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/2] lavf/vf_vpp_qsv: add support for QSV transpose filter

2019-06-17 Thread Linjie Fu
Add transpose support for qsv_vpp with rotate and hflip:
- rotate: [0, 3] support clockwise rotation of 0, 90, 180, 270;
- hflip:  [0, 1] support horizontal flip;

Configure with:
{"cclock_hflip","clock","cclock","clock_hflip","reversal","hflip","vflip"}

Limitation:
If pipeline contains resize, mirroring and other, VPP skips other filters
in MSDK when IOPattern equals d3d->d3d. So "cclock_hflip, clock_hflip, vflip"
will not work in d3d->d3d condition.

CMD:
ffmpeg -hwaccel qsv -c:v h264_qsv -i input.h264
-vf 'format=qsv,vpp_qsv=transpose=clock' -c:v h264_qsv output.h264

ffmpeg -init_hw_device qsv=foo -filter_hw_device foo -f rawvideo
-pix_fmt nv12 -s:v 1920x1080 -i input.nv12 -vf
'hwupload=extra_hw_frames=64,format=qsv,vpp_qsv=transpose=cclock_hflip'
-f rawvideo -pix_fmt nv12 -y ./transpose.yuv

Signed-off-by: Linjie Fu 
---
 libavfilter/vf_vpp_qsv.c | 95 +++-
 1 file changed, 93 insertions(+), 2 deletions(-)

diff --git a/libavfilter/vf_vpp_qsv.c b/libavfilter/vf_vpp_qsv.c
index dd05e8baff..974fc7a255 100644
--- a/libavfilter/vf_vpp_qsv.c
+++ b/libavfilter/vf_vpp_qsv.c
@@ -36,12 +36,15 @@
 #include "libavformat/avformat.h"
 
 #include "qsvvpp.h"
+#include "transpose.h"
 
 #define OFFSET(x) offsetof(VPPContext, x)
 #define FLAGS (AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_FILTERING_PARAM)
 
 /* number of video enhancement filters */
-#define ENH_FILTERS_COUNT (5)
+#define ENH_FILTERS_COUNT (7)
+#define QSV_HAVE_ROTATION  QSV_VERSION_ATLEAST(1, 17)
+#define QSV_HAVE_MIRRORING QSV_VERSION_ATLEAST(1, 19)
 
 typedef struct VPPContext{
 const AVClass *class;
@@ -54,6 +57,8 @@ typedef struct VPPContext{
 mfxExtVPPDenoise denoise_conf;
 mfxExtVPPDetail detail_conf;
 mfxExtVPPProcAmp procamp_conf;
+mfxExtVPPRotation rotation_conf;
+mfxExtVPPMirroring mirroring_conf;
 
 int out_width;
 int out_height;
@@ -70,6 +75,10 @@ typedef struct VPPContext{
 int crop_x;
 int crop_y;
 
+int transpose;
+int rotate; /* rotate angle : [0, 90, 180, 270] */
+int hflip;  /* flip mode : 0 = off, 1 = HORIZONTAL flip */
+
 /* param for the procamp */
 intprocamp;/* enable procamp */
 float  hue;
@@ -95,6 +104,15 @@ static const AVOption options[] = {
 { "contrast","ProcAmp contrast", OFFSET(contrast),
AV_OPT_TYPE_FLOAT,{ .dbl = 1.0 }, 0.0, 10.0, .flags = FLAGS},
 { "brightness",  "ProcAmp brightness",   OFFSET(brightness),  
AV_OPT_TYPE_FLOAT,{ .dbl = 0.0 }, -100.0, 100.0, .flags = FLAGS},
 
+{ "transpose",  "set transpose direction",   OFFSET(transpose),   
AV_OPT_TYPE_INT,  { .i64 = -1 }, -1, 6, FLAGS, "transpose"},
+{ "cclock_hflip",  "rotate counter-clockwise with horizontal flip",  
0, AV_OPT_TYPE_CONST, { .i64 = TRANSPOSE_CCLOCK_FLIP }, .flags=FLAGS, .unit = 
"transpose" },
+{ "clock", "rotate clockwise",   
0, AV_OPT_TYPE_CONST, { .i64 = TRANSPOSE_CLOCK   }, .flags=FLAGS, .unit = 
"transpose" },
+{ "cclock","rotate counter-clockwise",   
0, AV_OPT_TYPE_CONST, { .i64 = TRANSPOSE_CCLOCK  }, .flags=FLAGS, .unit = 
"transpose" },
+{ "clock_hflip",   "rotate clockwise with horizontal flip",  
0, AV_OPT_TYPE_CONST, { .i64 = TRANSPOSE_CLOCK_FLIP  }, .flags=FLAGS, .unit = 
"transpose" },
+{ "reversal",  "rotate by half-turn",
0, AV_OPT_TYPE_CONST, { .i64 = TRANSPOSE_REVERSAL}, .flags=FLAGS, .unit = 
"transpose" },
+{ "hflip", "flip horizontally",  
0, AV_OPT_TYPE_CONST, { .i64 = TRANSPOSE_HFLIP   }, .flags=FLAGS, .unit = 
"transpose" },
+{ "vflip", "flip vertically",
0, AV_OPT_TYPE_CONST, { .i64 = TRANSPOSE_VFLIP   }, .flags=FLAGS, .unit = 
"transpose" },
+
 { "cw",   "set the width crop area expression",   OFFSET(cw), 
AV_OPT_TYPE_STRING, { .str = "iw" }, CHAR_MIN, CHAR_MAX, FLAGS },
 { "ch",   "set the height crop area expression",  OFFSET(ch), 
AV_OPT_TYPE_STRING, { .str = "ih" }, CHAR_MIN, CHAR_MAX, FLAGS },
 { "cx",   "set the x crop area expression",   OFFSET(cx), 
AV_OPT_TYPE_STRING, { .str = "(in_w-out_w)/2" }, CHAR_MIN, CHAR_MAX, FLAGS },
@@ -322,8 +340,81 @@ static int config_output(AVFilterLink *outlink)
 param.ext

[FFmpeg-devel] [PATCH, RFC] lavc/phtread_frame: update context in child thread in multi-thread mode

2019-06-26 Thread Linjie Fu
Currently in ff_thread_decode_frame, context is updated from child thread
to main thread, and main thread releases the context in avcodec_close()
when decode finishes.

However, when resolution/format change in vp9, ff_get_format was called,
and hwaccel_uninit() and hwaccel_init will be used to destroy and re-create
the context. Due to the async between main-thread and child-thread,
main-thread updated its context from child earlier than the context was
refreshed in child-thread. And it will lead to:
1. memory leak in child-thread.
2. double free in main-thread while calling avcodec_close().

Can be reproduced with a resolution change case in vp9, and use -vframes
to terminate the decode between the dynamic resolution change frames:

ffmpeg -hwaccel vaapi -hwaccel_device /dev/dri/renderD128 -v
verbose -i ./test2360_1672_4980.ivf -pix_fmt p010le -f rawvideo -vsync
passthrough -vframes 6 -y out.yuv

Move update_context_from_thread from ff_thread_decode_frame(main thread)
to frame_worker_thread(child thread), update the context in child thread
right after the context was updated to avoid the async issue.

Signed-off-by: Linjie Fu 
---
Request for Comments, not quite familiar with the constraints.
Thanks in advance.

 libavcodec/internal.h  |   5 ++
 libavcodec/pthread_frame.c | 164 -
 2 files changed, 91 insertions(+), 78 deletions(-)

diff --git a/libavcodec/internal.h b/libavcodec/internal.h
index 5096ffa..9f4ed0b 100644
--- a/libavcodec/internal.h
+++ b/libavcodec/internal.h
@@ -162,6 +162,11 @@ typedef struct AVCodecInternal {
 
 void *thread_ctx;
 
+/**
+ * Main thread AVCodecContext pointer
+ */
+void *main_thread;
+
 DecodeSimpleContext ds;
 DecodeFilterContext filter;
 
diff --git a/libavcodec/pthread_frame.c b/libavcodec/pthread_frame.c
index 36ac0ac..be42e98 100644
--- a/libavcodec/pthread_frame.c
+++ b/libavcodec/pthread_frame.c
@@ -159,82 +159,6 @@ static void async_unlock(FrameThreadContext *fctx)
 }
 
 /**
- * Codec worker thread.
- *
- * Automatically calls ff_thread_finish_setup() if the codec does
- * not provide an update_thread_context method, or if the codec returns
- * before calling it.
- */
-static attribute_align_arg void *frame_worker_thread(void *arg)
-{
-PerThreadContext *p = arg;
-AVCodecContext *avctx = p->avctx;
-const AVCodec *codec = avctx->codec;
-
-pthread_mutex_lock(&p->mutex);
-while (1) {
-while (atomic_load(&p->state) == STATE_INPUT_READY && !p->die)
-pthread_cond_wait(&p->input_cond, &p->mutex);
-
-if (p->die) break;
-
-if (!codec->update_thread_context && THREAD_SAFE_CALLBACKS(avctx))
-ff_thread_finish_setup(avctx);
-
-/* If a decoder supports hwaccel, then it must call ff_get_format().
- * Since that call must happen before ff_thread_finish_setup(), the
- * decoder is required to implement update_thread_context() and call
- * ff_thread_finish_setup() manually. Therefore the above
- * ff_thread_finish_setup() call did not happen and hwaccel_serializing
- * cannot be true here. */
-av_assert0(!p->hwaccel_serializing);
-
-/* if the previous thread uses hwaccel then we take the lock to ensure
- * the threads don't run concurrently */
-if (avctx->hwaccel) {
-pthread_mutex_lock(&p->parent->hwaccel_mutex);
-p->hwaccel_serializing = 1;
-}
-
-av_frame_unref(p->frame);
-p->got_frame = 0;
-p->result = codec->decode(avctx, p->frame, &p->got_frame, &p->avpkt);
-
-if ((p->result < 0 || !p->got_frame) && p->frame->buf[0]) {
-if (avctx->internal->allocate_progress)
-av_log(avctx, AV_LOG_ERROR, "A frame threaded decoder did not "
-   "free the frame on failure. This is a bug, please 
report it.\n");
-av_frame_unref(p->frame);
-}
-
-if (atomic_load(&p->state) == STATE_SETTING_UP)
-ff_thread_finish_setup(avctx);
-
-if (p->hwaccel_serializing) {
-p->hwaccel_serializing = 0;
-pthread_mutex_unlock(&p->parent->hwaccel_mutex);
-}
-
-if (p->async_serializing) {
-p->async_serializing = 0;
-
-async_unlock(p->parent);
-}
-
-pthread_mutex_lock(&p->progress_mutex);
-
-atomic_store(&p->state, STATE_INPUT_READY);
-
-pthread_cond_broadcast(&p->progress_cond);
-pthread_cond_signal(&p->output_cond);
-pthread_mutex_unlock(&p->progress_mutex);
-}
-pthread_mutex_unlock(&p->mutex);
-
-return NULL;
-}
-
-/**
  * Update the next thread's AVCodecContext with valu

[FFmpeg-devel] [PATCH, RFC, v2] lavc/phtread_frame: update context in child thread in multi-thread mode

2019-06-26 Thread Linjie Fu
Currently in ff_thread_decode_frame, context is updated from child thread
to main thread, and main thread releases the context in avcodec_close()
when decode finishes.

However, when resolution/format change in vp9, ff_get_format was called,
and hwaccel_uninit() and hwaccel_init will be used to destroy and re-create
the context. Due to the async between main-thread and child-thread,
main-thread updated its context from child earlier than the context was
refreshed in child-thread. And it will lead to:
1. memory leak in child-thread.
2. double free in main-thread while calling avcodec_close().

Can be reproduced with a resolution change case in vp9, and use -vframes
to terminate the decode between the dynamic resolution change frames:

ffmpeg -hwaccel vaapi -hwaccel_device /dev/dri/renderD128 -v
verbose -i ./test2360_1672_4980.ivf -pix_fmt p010le -f rawvideo -vsync
passthrough -vframes 6 -y out.yuv

Move update_context_from_thread from ff_thread_decode_frame(main thread)
to frame_worker_thread(child thread), update the context in child thread
right after the context was updated to avoid the async issue.

Signed-off-by: Linjie Fu 
---
Request for Comments, not quite familiar with the constraints.
Thanks in advance.

 libavcodec/internal.h  |  5 +
 libavcodec/pthread_frame.c | 12 +---
 2 files changed, 14 insertions(+), 3 deletions(-)

diff --git a/libavcodec/internal.h b/libavcodec/internal.h
index 5096ffa..9f4ed0b 100644
--- a/libavcodec/internal.h
+++ b/libavcodec/internal.h
@@ -162,6 +162,11 @@ typedef struct AVCodecInternal {
 
 void *thread_ctx;
 
+/**
+ * Main thread AVCodecContext pointer
+ */
+void *main_thread;
+
 DecodeSimpleContext ds;
 DecodeFilterContext filter;
 
diff --git a/libavcodec/pthread_frame.c b/libavcodec/pthread_frame.c
index 36ac0ac..2730a8c 100644
--- a/libavcodec/pthread_frame.c
+++ b/libavcodec/pthread_frame.c
@@ -140,6 +140,8 @@ typedef struct FrameThreadContext {
 #define THREAD_SAFE_CALLBACKS(avctx) \
 ((avctx)->thread_safe_callbacks || (avctx)->get_buffer2 == 
avcodec_default_get_buffer2)
 
+static int update_context_from_thread(AVCodecContext *dst, AVCodecContext 
*src, int for_user);
+
 static void async_lock(FrameThreadContext *fctx)
 {
 pthread_mutex_lock(&fctx->async_mutex);
@@ -157,7 +159,6 @@ static void async_unlock(FrameThreadContext *fctx)
 pthread_cond_broadcast(&fctx->async_cond);
 pthread_mutex_unlock(&fctx->async_mutex);
 }
-
 /**
  * Codec worker thread.
  *
@@ -200,6 +201,10 @@ static attribute_align_arg void *frame_worker_thread(void 
*arg)
 p->got_frame = 0;
 p->result = codec->decode(avctx, p->frame, &p->got_frame, &p->avpkt);
 
+if (p->avctx->internal->main_thread)
+update_context_from_thread((AVCodecContext 
*)p->avctx->internal->main_thread,
+
p->avctx, 1);
+
 if ((p->result < 0 || !p->got_frame) && p->frame->buf[0]) {
 if (avctx->internal->allocate_progress)
 av_log(avctx, AV_LOG_ERROR, "A frame threaded decoder did not "
@@ -540,8 +545,6 @@ int ff_thread_decode_frame(AVCodecContext *avctx,
 if (finished >= avctx->thread_count) finished = 0;
 } while (!avpkt->size && !*got_picture_ptr && err >= 0 && finished != 
fctx->next_finished);
 
-update_context_from_thread(avctx, p->avctx, 1);
-
 if (fctx->next_decoding >= avctx->thread_count) fctx->next_decoding = 0;
 
 fctx->next_finished = finished;
@@ -728,6 +731,8 @@ int ff_frame_thread_init(AVCodecContext *avctx)
 FrameThreadContext *fctx;
 int i, err = 0;
 
+avctx->internal->main_thread = avctx;
+
 if (!thread_count) {
 int nb_cpus = av_cpu_count();
 #if FF_API_DEBUG_MV
@@ -800,6 +805,7 @@ int ff_frame_thread_init(AVCodecContext *avctx)
 *copy->internal = *src->internal;
 copy->internal->thread_ctx = p;
 copy->internal->last_pkt_props = &p->avpkt;
+copy->internal->main_thread = avctx;
 
 if (!i) {
 src = copy;
-- 
2.7.4

___
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] lavc/pthread_frame: update context in child thread in multi-thread mode

2019-06-27 Thread Linjie Fu
Currently in ff_thread_decode_frame, context is updated from child thread
to user thread, and user thread releases the context in avcodec_close()
when decode finishes.

However, when resolution/format changes, ff_get_format is called, and
hwaccel_uninit() and hwaccel_init will be used to destroy and re-create
the context. Due to the async between user-thread and child-thread,
user-thread updates its context from child earlier than the context
is refreshed in child-thread. And it will lead to:
1. memory leak in child-thread.
2. double free in user-thread while calling avcodec_close().

Can be reproduced with a resolution change case, and use -vframes
to terminate the decode between the dynamic resolution changing frames:

ffmpeg -hwaccel vaapi -hwaccel_device /dev/dri/renderD128 -v
verbose -i ./test2360_1672_4980.ivf -pix_fmt p010le -f rawvideo -vsync
passthrough -vframes 6 -y out.yuv

ffmpeg -hwaccel vaapi -hwaccel_device /dev/dri/renderD128 -v verbose -i
./reinit-large_420_8-to-small_420_8.h264 -pix_fmt nv12 -f rawvideo
-vsync passthrough -vframes 45 -y out.yuv

Move update_context_from_thread from ff_thread_decode_frame(user thread)
to frame_worker_thread(child thread), update the context in child thread
right after the context is refreshed to avoid the async issue.

Signed-off-by: Linjie Fu 
---
 libavcodec/internal.h  |  7 +++
 libavcodec/pthread_frame.c | 21 ++---
 2 files changed, 25 insertions(+), 3 deletions(-)

diff --git a/libavcodec/internal.h b/libavcodec/internal.h
index 5096ffa..a85 100644
--- a/libavcodec/internal.h
+++ b/libavcodec/internal.h
@@ -162,6 +162,13 @@ typedef struct AVCodecInternal {
 
 void *thread_ctx;
 
+/**
+ * User thread AVCodecContext pointer and
+ * context mutex
+ */
+void *user_avctx;
+pthread_mutex_t context_mutex;
+
 DecodeSimpleContext ds;
 DecodeFilterContext filter;
 
diff --git a/libavcodec/pthread_frame.c b/libavcodec/pthread_frame.c
index 36ac0ac..60110f2 100644
--- a/libavcodec/pthread_frame.c
+++ b/libavcodec/pthread_frame.c
@@ -140,6 +140,8 @@ typedef struct FrameThreadContext {
 #define THREAD_SAFE_CALLBACKS(avctx) \
 ((avctx)->thread_safe_callbacks || (avctx)->get_buffer2 == 
avcodec_default_get_buffer2)
 
+static int update_context_from_thread(AVCodecContext *dst, AVCodecContext 
*src, int for_user);
+
 static void async_lock(FrameThreadContext *fctx)
 {
 pthread_mutex_lock(&fctx->async_mutex);
@@ -157,7 +159,6 @@ static void async_unlock(FrameThreadContext *fctx)
 pthread_cond_broadcast(&fctx->async_cond);
 pthread_mutex_unlock(&fctx->async_mutex);
 }
-
 /**
  * Codec worker thread.
  *
@@ -169,6 +170,7 @@ static attribute_align_arg void *frame_worker_thread(void 
*arg)
 {
 PerThreadContext *p = arg;
 AVCodecContext *avctx = p->avctx;
+AVCodecContext *user_avctx = p->avctx->internal->user_avctx;
 const AVCodec *codec = avctx->codec;
 
 pthread_mutex_lock(&p->mutex);
@@ -200,6 +202,12 @@ static attribute_align_arg void *frame_worker_thread(void 
*arg)
 p->got_frame = 0;
 p->result = codec->decode(avctx, p->frame, &p->got_frame, &p->avpkt);
 
+if (user_avctx) {
+pthread_mutex_lock(&user_avctx->internal->context_mutex);
+update_context_from_thread(user_avctx, p->avctx, 1);
+pthread_mutex_unlock(&user_avctx->internal->context_mutex);
+}
+
 if ((p->result < 0 || !p->got_frame) && p->frame->buf[0]) {
 if (avctx->internal->allocate_progress)
 av_log(avctx, AV_LOG_ERROR, "A frame threaded decoder did not "
@@ -390,7 +398,9 @@ static int submit_packet(PerThreadContext *p, 
AVCodecContext *user_avctx,
 
 pthread_mutex_lock(&p->mutex);
 
+pthread_mutex_lock(&user_avctx->internal->context_mutex);
 ret = update_context_from_user(p->avctx, user_avctx);
+pthread_mutex_unlock(&user_avctx->internal->context_mutex);
 if (ret) {
 pthread_mutex_unlock(&p->mutex);
 return ret;
@@ -540,8 +550,6 @@ int ff_thread_decode_frame(AVCodecContext *avctx,
 if (finished >= avctx->thread_count) finished = 0;
 } while (!avpkt->size && !*got_picture_ptr && err >= 0 && finished != 
fctx->next_finished);
 
-update_context_from_thread(avctx, p->avctx, 1);
-
 if (fctx->next_decoding >= avctx->thread_count) fctx->next_decoding = 0;
 
 fctx->next_finished = finished;
@@ -713,6 +721,8 @@ void ff_frame_thread_free(AVCodecContext *avctx, int 
thread_count)
 pthread_mutex_destroy(&fctx->async_mutex);
 pthread_cond_destroy(&fctx->async_cond);
 
+pthread_mutex_destroy(&avctx->internal->context_mutex);
+
 av_freep(&avctx->internal->thread_ctx);
 
 if (a

[FFmpeg-devel] [PATCH 1/5] lavu/pixfmt: add Y210/AYUV/Y410 pixel formats

2019-06-27 Thread Linjie Fu
Previously, media driver provided planar format(like 420 8 bit), but
for HEVC Range Extension (422/444 8/10 bit), the decoded image is
produced in packed format.

Y210/AYUV/Y410 are packed formats which are needed in HEVC Rext decoding
for both VAAPI and QSV:
- Y210: 422 10 BIT
- AYUV: 444  8 BIT
- Y410: 444 10 BIT

Signed-off-by: Linjie Fu 
---
 libavutil/pixdesc.c | 62 +
 libavutil/pixfmt.h  |  6 ++
 libavutil/version.h |  2 +-
 3 files changed, 69 insertions(+), 1 deletion(-)

diff --git a/libavutil/pixdesc.c b/libavutil/pixdesc.c
index b97b066..bde49f9 100644
--- a/libavutil/pixdesc.c
+++ b/libavutil/pixdesc.c
@@ -205,6 +205,68 @@ static const AVPixFmtDescriptor 
av_pix_fmt_descriptors[AV_PIX_FMT_NB] = {
 { 0, 4, 1, 0, 8, 3, 7, 2 },/* V */
 },
 },
+[AV_PIX_FMT_Y210LE] = {
+.name = "y210le",
+.nb_components = 3,
+.log2_chroma_w = 1,
+.log2_chroma_h = 0,
+.comp = {
+{ 0, 4, 0, 6, 10, 1, 9, 1 },/* Y */
+{ 0, 8, 1, 6, 10, 3, 9, 2 },/* U */
+{ 0, 8, 3, 6, 10, 3, 9, 4 },/* V */
+},
+.flags = AV_PIX_FMT_FLAG_ALPHA,
+},
+[AV_PIX_FMT_Y210BE] = {
+.name = "y210be",
+.nb_components = 3,
+.log2_chroma_w = 1,
+.log2_chroma_h = 0,
+.comp = {
+{ 0, 4, 0, 6, 10, 1, 9, 1 },/* Y */
+{ 0, 8, 1, 6, 10, 3, 9, 2 },/* U */
+{ 0, 8, 3, 6, 10, 3, 9, 4 },/* V */
+},
+.flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_ALPHA,
+},
+[AV_PIX_FMT_AYUV] = {
+.name = "ayuv",
+.nb_components = 4,
+.log2_chroma_w = 0,
+.log2_chroma_h = 0,
+.comp = {
+{ 0, 4, 1, 0, 8, 3, 7, 2 },/* Y */
+{ 0, 4, 2, 0, 8, 3, 7, 1 },/* U */
+{ 0, 4, 3, 0, 8, 3, 7, 3 },/* V */
+{ 0, 4, 0, 0, 8, 3, 7, 4 },/* A */
+},
+},
+[AV_PIX_FMT_Y410LE] = {
+.name = "y410le",
+.nb_components = 4,
+.log2_chroma_w = 0,
+.log2_chroma_h = 0,
+.comp = {
+{ 0, 4, 1, 0, 10, 3, 9, 2 },/* Y */
+{ 0, 4, 0, 0, 10, 3, 9, 1 },/* U */
+{ 0, 4, 2, 0, 10, 3, 9, 3 },/* V */
+{ 0, 4, 3, 0,  2, 3, 1, 4 },/* A */
+},
+.flags = AV_PIX_FMT_FLAG_ALPHA,
+},
+[AV_PIX_FMT_Y410BE] = {
+.name = "y410be",
+.nb_components = 4,
+.log2_chroma_w = 0,
+.log2_chroma_h = 0,
+.comp = {
+{ 0, 4, 1, 0, 10, 3, 9, 2 },/* Y */
+{ 0, 4, 0, 0, 10, 3, 9, 1 },/* U */
+{ 0, 4, 2, 0, 10, 3, 9, 3 },/* V */
+{ 0, 4, 3, 0,  2, 3, 1, 4 },/* A */
+},
+.flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_ALPHA,
+},
 [AV_PIX_FMT_RGB24] = {
 .name = "rgb24",
 .nb_components = 3,
diff --git a/libavutil/pixfmt.h b/libavutil/pixfmt.h
index 8b54c94..6a6a36a 100644
--- a/libavutil/pixfmt.h
+++ b/libavutil/pixfmt.h
@@ -209,6 +209,12 @@ enum AVPixelFormat {
 
 AV_PIX_FMT_YVYU422,   ///< packed YUV 4:2:2, 16bpp, Y0 Cr Y1 Cb
 
+AV_PIX_FMT_Y210LE,///< packed YUV 4:2:2, 32bpp, Y0 Cb Y1 Cr, 
little-endian
+AV_PIX_FMT_Y210BE,///< packed YUV 4:2:2, 32bpp, Y0 Cb Y1 Cr, big-endian
+AV_PIX_FMT_AYUV,  ///< packed YUV 4:4:4, 32bpp,  A Y Cb Cr
+AV_PIX_FMT_Y410LE,///< packed YUV 4:4:4, 32bpp, Cr Y Cb A, 
little-endian
+AV_PIX_FMT_Y410BE,///< packed YUV 4:4:4, 32bpp, Cr Y Cb A, big-endian
+
 AV_PIX_FMT_YA16BE,   ///< 16 bits gray, 16 bits alpha (big-endian)
 AV_PIX_FMT_YA16LE,   ///< 16 bits gray, 16 bits alpha (little-endian)
 
diff --git a/libavutil/version.h b/libavutil/version.h
index dccbb38..e16b93e 100644
--- a/libavutil/version.h
+++ b/libavutil/version.h
@@ -79,7 +79,7 @@
  */
 
 #define LIBAVUTIL_VERSION_MAJOR  56
-#define LIBAVUTIL_VERSION_MINOR  29
+#define LIBAVUTIL_VERSION_MINOR  30
 #define LIBAVUTIL_VERSION_MICRO 100
 
 #define LIBAVUTIL_VERSION_INT   AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \
-- 
2.7.4

___
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/5] lavu/hwcontext_vaapi: add vaapi_format_map for Y210/AYUV/Y410

2019-06-27 Thread Linjie Fu
Signed-off-by: Linjie Fu 
---
 libavutil/hwcontext_vaapi.c | 8 
 1 file changed, 8 insertions(+)

diff --git a/libavutil/hwcontext_vaapi.c b/libavutil/hwcontext_vaapi.c
index 4227c3c..6378d0e 100644
--- a/libavutil/hwcontext_vaapi.c
+++ b/libavutil/hwcontext_vaapi.c
@@ -116,6 +116,14 @@ static const VAAPIFormatDescriptor vaapi_format_map[] = {
 #endif
 MAP(UYVY, YUV422,  UYVY422, 0),
 MAP(YUY2, YUV422,  YUYV422, 0),
+#ifdef VA_FOURCC_Y210
+MAP(Y210, YUV422_10,Y210LE, 0),
+#endif
+#define VA_RT_FORMAT_AYUV VA_FOURCC_AYUV
+MAP(AYUV,   AYUV, AYUV, 0),
+#ifdef VA_FOURCC_Y410
+MAP(Y410, YUV444_10,Y410LE, 0),
+#endif
 MAP(411P, YUV411,  YUV411P, 0),
 MAP(422V, YUV422,  YUV440P, 0),
 MAP(444P, YUV444,  YUV444P, 0),
-- 
2.7.4

___
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/5] lavc/qsv: add decode support for HEVC Rext

2019-06-27 Thread Linjie Fu
Add support for YUV422P/YUV422P10, YUV444P/YUV444P10 in qsv_map_pixfmt.
Allow qsv to choose correct fourc from format.

Add support for YUYV422/Y210/AYUV/Y410 to map frame to surface and
allowed hwdownload.

HEVC Rext decode is supported on ICL+ platform.

Cmdline for 444 8 bit decode:
ffmpeg -hwaccel qsv -hwaccel_device /dev/dri/renderD128 -c:v
hevc_qsv -load_plugin hevc_hw -i HEVCRext_444_8bit.bin -vf
hwdownload,format=ayuv -pix_fmt ayuv -vsync passthrough out.yuv

Signed-off-by: Linjie Fu 
---
 libavcodec/qsv.c  | 12 
 libavutil/hwcontext_qsv.c | 25 ++---
 2 files changed, 34 insertions(+), 3 deletions(-)

diff --git a/libavcodec/qsv.c b/libavcodec/qsv.c
index 986d4f6..87f4aae 100644
--- a/libavcodec/qsv.c
+++ b/libavcodec/qsv.c
@@ -225,6 +225,18 @@ int ff_qsv_map_pixfmt(enum AVPixelFormat format, uint32_t 
*fourcc)
 case AV_PIX_FMT_NV12:
 *fourcc = MFX_FOURCC_NV12;
 return AV_PIX_FMT_NV12;
+case AV_PIX_FMT_YUV422P:
+*fourcc = MFX_FOURCC_YUY2;
+return AV_PIX_FMT_YUYV422;
+case AV_PIX_FMT_YUV422P10:
+*fourcc = MFX_FOURCC_Y210;
+return AV_PIX_FMT_Y210LE;
+case AV_PIX_FMT_YUV444P:
+*fourcc = MFX_FOURCC_AYUV;
+return AV_PIX_FMT_AYUV;
+case AV_PIX_FMT_YUV444P10:
+*fourcc = MFX_FOURCC_Y410;
+return AV_PIX_FMT_Y410LE;
 case AV_PIX_FMT_YUV420P10:
 case AV_PIX_FMT_P010:
 *fourcc = MFX_FOURCC_P010;
diff --git a/libavutil/hwcontext_qsv.c b/libavutil/hwcontext_qsv.c
index 59e4ed9..f0be4bb 100644
--- a/libavutil/hwcontext_qsv.c
+++ b/libavutil/hwcontext_qsv.c
@@ -103,6 +103,14 @@ static const struct {
 { AV_PIX_FMT_BGRA, MFX_FOURCC_RGB4 },
 { AV_PIX_FMT_P010, MFX_FOURCC_P010 },
 { AV_PIX_FMT_PAL8, MFX_FOURCC_P8   },
+{ AV_PIX_FMT_YUYV422,
+   MFX_FOURCC_YUY2 },
+{ AV_PIX_FMT_Y210LE,
+   MFX_FOURCC_Y210 },
+{ AV_PIX_FMT_AYUV,
+   MFX_FOURCC_AYUV },
+{ AV_PIX_FMT_Y410LE,
+   MFX_FOURCC_Y410 },
 };
 
 static uint32_t qsv_fourcc_from_pix_fmt(enum AVPixelFormat pix_fmt)
@@ -760,20 +768,31 @@ static int map_frame_to_surface(const AVFrame *frame, 
mfxFrameSurface1 *surface)
 surface->Data.Y  = frame->data[0];
 surface->Data.UV = frame->data[1];
 break;
-
 case AV_PIX_FMT_YUV420P:
 surface->Data.Y = frame->data[0];
 surface->Data.U = frame->data[1];
 surface->Data.V = frame->data[2];
 break;
-
 case AV_PIX_FMT_BGRA:
+case AV_PIX_FMT_AYUV:
 surface->Data.B = frame->data[0];
 surface->Data.G = frame->data[0] + 1;
 surface->Data.R = frame->data[0] + 2;
 surface->Data.A = frame->data[0] + 3;
 break;
-
+case AV_PIX_FMT_YUYV422:
+surface->Data.Y = frame->data[0];
+surface->Data.U = frame->data[0] + 1;
+surface->Data.V = frame->data[0] + 3;
+break;
+case AV_PIX_FMT_Y210LE:
+surface->Data.Y16 = frame->data[0];
+surface->Data.U16 = frame->data[0] + 2;
+surface->Data.V16 = frame->data[0] + 6;
+break;
+case AV_PIX_FMT_Y410LE:
+surface->Data.U = frame->data[0];
+break;
 default:
 return MFX_ERR_UNSUPPORTED;
 }
-- 
2.7.4

___
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/5] lavc/qsvdec: add ChromaFormat support for YUV422/YUV444

2019-06-27 Thread Linjie Fu
Currently, ChromaFormat passed to libmfx is set to YUV42O by default.

Modify to choose ChromaFormat according to fourCC.

Signed-off-by: Linjie Fu 
---
 libavcodec/qsvdec.c | 20 +++-
 1 file changed, 19 insertions(+), 1 deletion(-)

diff --git a/libavcodec/qsvdec.c b/libavcodec/qsvdec.c
index 46aa2d6..7650325 100644
--- a/libavcodec/qsvdec.c
+++ b/libavcodec/qsvdec.c
@@ -40,6 +40,7 @@
 #include "qsv.h"
 #include "qsv_internal.h"
 #include "qsvdec.h"
+#include 
 
 const AVCodecHWConfigInternal *ff_qsv_hw_configs[] = {
 &(const AVCodecHWConfigInternal) {
@@ -211,7 +212,24 @@ static int qsv_decode_init(AVCodecContext *avctx, 
QSVContext *q)
 param.mfx.FrameInfo.FourCC = q->fourcc;
 param.mfx.FrameInfo.Width  = frame_width;
 param.mfx.FrameInfo.Height = frame_height;
-param.mfx.FrameInfo.ChromaFormat   = MFX_CHROMAFORMAT_YUV420;
+
+switch (q->fourcc) {
+case VA_FOURCC_YUY2:
+#ifdef VA_FOURCC_Y210
+case VA_FOURCC_Y210:
+#endif
+param.mfx.FrameInfo.ChromaFormat   = MFX_CHROMAFORMAT_YUV422;
+break;
+case VA_FOURCC_AYUV:
+#ifdef VA_FOURCC_Y410
+case VA_FOURCC_Y410:
+#endif
+param.mfx.FrameInfo.ChromaFormat   = MFX_CHROMAFORMAT_YUV444;
+break;
+default:
+param.mfx.FrameInfo.ChromaFormat   = MFX_CHROMAFORMAT_YUV420;
+break;
+}
 
 switch (avctx->field_order) {
 case AV_FIELD_PROGRESSIVE:
-- 
2.7.4

___
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/5] libav/qsv: set Info.Shift according to the setting in desc

2019-06-27 Thread Linjie Fu
Currently, Info.Shift in libmfx is set according to the depth of the
pixfmt. As QSV now supports Y410 (depth > 8 but shift = 0), it doesn't
work any more.

Modify to set Info.Shift according to the setting in desc.

Signed-off-by: Linjie Fu 
---
 libavcodec/qsvdec.c   | 2 +-
 libavutil/hwcontext_qsv.c | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/libavcodec/qsvdec.c b/libavcodec/qsvdec.c
index 7650325..0f45a34 100644
--- a/libavcodec/qsvdec.c
+++ b/libavcodec/qsvdec.c
@@ -208,7 +208,7 @@ static int qsv_decode_init(AVCodecContext *avctx, 
QSVContext *q)
 
 param.mfx.FrameInfo.BitDepthLuma   = desc->comp[0].depth;
 param.mfx.FrameInfo.BitDepthChroma = desc->comp[0].depth;
-param.mfx.FrameInfo.Shift  = desc->comp[0].depth > 8;
+param.mfx.FrameInfo.Shift  = desc->comp[0].shift > 0;
 param.mfx.FrameInfo.FourCC = q->fourcc;
 param.mfx.FrameInfo.Width  = frame_width;
 param.mfx.FrameInfo.Height = frame_height;
diff --git a/libavutil/hwcontext_qsv.c b/libavutil/hwcontext_qsv.c
index f0be4bb..ab484b6 100644
--- a/libavutil/hwcontext_qsv.c
+++ b/libavutil/hwcontext_qsv.c
@@ -323,7 +323,7 @@ static int qsv_init_surface(AVHWFramesContext *ctx, 
mfxFrameSurface1 *surf)
 
 surf->Info.BitDepthLuma   = desc->comp[0].depth;
 surf->Info.BitDepthChroma = desc->comp[0].depth;
-surf->Info.Shift  = desc->comp[0].depth > 8;
+surf->Info.Shift  = desc->comp[0].shift > 0;
 
 if (desc->log2_chroma_w && desc->log2_chroma_h)
 surf->Info.ChromaFormat   = MFX_CHROMAFORMAT_YUV420;
-- 
2.7.4

___
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] lavc/vaapi_decode: recreate hw_frames_ctx without destroy va_context

2019-07-06 Thread Linjie Fu
VP9 allows resolution changes per frame. Currently in VAAPI, resolution
changes leads to va context destroy and reinit. This will cause
reference frame surface lost and produce garbage.

As libva allows re-create surface separately without changing the
context, this issue could be handled by only recreating hw_frames_ctx.

Could be verified by:
ffmpeg -hwaccel vaapi -hwaccel_device /dev/dri/renderD128 -i
./resolutions.ivf
-pix_fmt p010le -f rawvideo -vframes 20 -y vaapi.yuv

Signed-off-by: Linjie Fu 
---
 libavcodec/decode.c   |  8 
 libavcodec/vaapi_decode.c | 40 ++--
 2 files changed, 26 insertions(+), 22 deletions(-)

diff --git a/libavcodec/decode.c b/libavcodec/decode.c
index 0863b82..a81b857 100644
--- a/libavcodec/decode.c
+++ b/libavcodec/decode.c
@@ -1254,7 +1254,6 @@ int ff_decode_get_hw_frames_ctx(AVCodecContext *avctx,
 
 frames_ctx = (AVHWFramesContext*)avctx->hw_frames_ctx->data;
 
-
 if (frames_ctx->initial_pool_size) {
 // We guarantee 4 base work surfaces. The function above guarantees 1
 // (the absolute minimum), so add the missing count.
@@ -1333,7 +1332,7 @@ static int hwaccel_init(AVCodecContext *avctx,
 return AVERROR_PATCHWELCOME;
 }
 
-if (hwaccel->priv_data_size) {
+if (hwaccel->priv_data_size && !avctx->internal->hwaccel_priv_data) {
 avctx->internal->hwaccel_priv_data =
 av_mallocz(hwaccel->priv_data_size);
 if (!avctx->internal->hwaccel_priv_data)
@@ -1397,8 +1396,9 @@ int ff_get_format(AVCodecContext *avctx, const enum 
AVPixelFormat *fmt)
 
 for (;;) {
 // Remove the previous hwaccel, if there was one.
-hwaccel_uninit(avctx);
-
+// VAAPI allows reinit hw_frames_ctx only
+if (choices[0] != AV_PIX_FMT_VAAPI_VLD)
+hwaccel_uninit(avctx);
 user_choice = avctx->get_format(avctx, choices);
 if (user_choice == AV_PIX_FMT_NONE) {
 // Explicitly chose nothing, give up.
diff --git a/libavcodec/vaapi_decode.c b/libavcodec/vaapi_decode.c
index 69512e1..13f0cf0 100644
--- a/libavcodec/vaapi_decode.c
+++ b/libavcodec/vaapi_decode.c
@@ -613,8 +613,10 @@ int ff_vaapi_decode_init(AVCodecContext *avctx)
 VAStatus vas;
 int err;
 
-ctx->va_config  = VA_INVALID_ID;
-ctx->va_context = VA_INVALID_ID;
+if (!ctx->va_config && !ctx->va_context){
+ctx->va_config  = VA_INVALID_ID;
+ctx->va_context = VA_INVALID_ID;
+}
 
 #if FF_API_STRUCT_VAAPI_CONTEXT
 if (avctx->hwaccel_context) {
@@ -642,7 +644,6 @@ int ff_vaapi_decode_init(AVCodecContext *avctx)
 // present, so set it here to avoid the behaviour changing.
 ctx->hwctx->driver_quirks =
 AV_VAAPI_DRIVER_QUIRK_RENDER_PARAM_BUFFERS;
-
 }
 #endif
 
@@ -655,7 +656,8 @@ int ff_vaapi_decode_init(AVCodecContext *avctx)
"context: %#x/%#x.\n", ctx->va_config, ctx->va_context);
 } else {
 #endif
-
+// Get a new hw_frames_ctx even if there is already one
+// recreate surface without reconstuct va_context
 err = ff_decode_get_hw_frames_ctx(avctx, AV_HWDEVICE_TYPE_VAAPI);
 if (err < 0)
 goto fail;
@@ -670,21 +672,23 @@ int ff_vaapi_decode_init(AVCodecContext *avctx)
 if (err)
 goto fail;
 
-vas = vaCreateContext(ctx->hwctx->display, ctx->va_config,
-  avctx->coded_width, avctx->coded_height,
-  VA_PROGRESSIVE,
-  ctx->hwfc->surface_ids,
-  ctx->hwfc->nb_surfaces,
-  &ctx->va_context);
-if (vas != VA_STATUS_SUCCESS) {
-av_log(avctx, AV_LOG_ERROR, "Failed to create decode "
-   "context: %d (%s).\n", vas, vaErrorStr(vas));
-err = AVERROR(EIO);
-goto fail;
-}
+if (ctx->va_context == VA_INVALID_ID) {
+vas = vaCreateContext(ctx->hwctx->display, ctx->va_config,
+  avctx->coded_width, avctx->coded_height,
+  VA_PROGRESSIVE,
+  ctx->hwfc->surface_ids,
+  ctx->hwfc->nb_surfaces,
+  &ctx->va_context);
+if (vas != VA_STATUS_SUCCESS) {
+av_log(avctx, AV_LOG_ERROR, "Failed to create decode "
+   "context: %d (%s).\n", vas, vaErrorStr(vas));
+err = AVERROR(EIO);
+goto fail;
+}
 
-av_log(avctx, AV_LOG_DEBUG, "Decode context initialised: "
-   "%#x/%#x.\n", ctx->va_config, ctx->va_context);
+av_log(avctx, AV_LOG_DEBUG, "Decode context initialised: "
+   "%#x/%#x.\n", ctx->va_config, ctx->

[FFmpeg-devel] [PATCH 1/2] lavc/decode: recreate hw_frames_ctx instead of return if already exists

2019-07-06 Thread Linjie Fu
If hw_frames_ctx exists when calling ff_decode_get_hw_frames_ctx, it
is allowed to be recreated instead of just return.

Move hw_frames_ctx check outside ff_decode_get_hw_frames_ctx, and check
in relevant code.

Signed-off-by: Linjie Fu 
---
 libavcodec/decode.c | 2 +-
 libavcodec/dxva2.c  | 8 +---
 libavcodec/vdpau.c  | 9 +
 3 files changed, 11 insertions(+), 8 deletions(-)

diff --git a/libavcodec/decode.c b/libavcodec/decode.c
index 6c31166..0863b82 100644
--- a/libavcodec/decode.c
+++ b/libavcodec/decode.c
@@ -1230,7 +1230,7 @@ int ff_decode_get_hw_frames_ctx(AVCodecContext *avctx,
 return AVERROR(ENOSYS);
 
 if (avctx->hw_frames_ctx)
-return 0;
+av_buffer_unref(&avctx->hw_frames_ctx);
 if (!avctx->hw_device_ctx) {
 av_log(avctx, AV_LOG_ERROR, "A hardware frames or device context is "
 "required for hardware accelerated decoding.\n");
diff --git a/libavcodec/dxva2.c b/libavcodec/dxva2.c
index 3241611..0404064 100644
--- a/libavcodec/dxva2.c
+++ b/libavcodec/dxva2.c
@@ -661,9 +661,11 @@ int ff_dxva2_decode_init(AVCodecContext *avctx)
 // (avctx->pix_fmt is not updated yet at this point)
 sctx->pix_fmt = avctx->hwaccel->pix_fmt;
 
-ret = ff_decode_get_hw_frames_ctx(avctx, dev_type);
-if (ret < 0)
-return ret;
+if (!avctx->hw_frames_ctx) {
+ret = ff_decode_get_hw_frames_ctx(avctx, dev_type);
+if (ret < 0)
+return ret;
+}
 
 frames_ctx = (AVHWFramesContext*)avctx->hw_frames_ctx->data;
 sctx->device_ctx = frames_ctx->device_ctx;
diff --git a/libavcodec/vdpau.c b/libavcodec/vdpau.c
index 167f06d..b7a4e9c 100644
--- a/libavcodec/vdpau.c
+++ b/libavcodec/vdpau.c
@@ -178,10 +178,11 @@ int ff_vdpau_common_init(AVCodecContext *avctx, 
VdpDecoderProfile profile,
 AVHWFramesContext *frames_ctx;
 AVVDPAUDeviceContext *dev_ctx;
 
-ret = ff_decode_get_hw_frames_ctx(avctx, AV_HWDEVICE_TYPE_VDPAU);
-if (ret < 0)
-return ret;
-
+if (!avctx->hw_frames_ctx) {
+ret = ff_decode_get_hw_frames_ctx(avctx, AV_HWDEVICE_TYPE_VDPAU);
+if (ret < 0)
+return ret;
+}
 frames_ctx = (AVHWFramesContext*)avctx->hw_frames_ctx->data;
 dev_ctx = frames_ctx->device_ctx->hwctx;
 
-- 
2.7.4

___
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] lavf/vf_vpp_qsv: add support for QSV transpose filter

2019-07-10 Thread Linjie Fu
Add transpose support for qsv_vpp with rotate and hflip:
- rotate: [0, 3] support clockwise rotation of 0, 90, 180, 270;
- hflip:  [0, 1] support horizontal flip;

Configure with:
{"cclock_hflip","clock","cclock","clock_hflip","reversal","hflip","vflip"}

Limitation:
If pipeline contains resize, mirroring and other, VPP skips other filters
in MSDK when IOPattern equals d3d->d3d. So "cclock_hflip, clock_hflip, vflip"
will not work in d3d->d3d condition.

This pr is fixing this:
https://github.com/Intel-Media-SDK/MediaSDK/pull/1491

CMD:
ffmpeg -hwaccel qsv -c:v h264_qsv -i input.h264
-vf 'format=qsv,vpp_qsv=transpose=clock' -c:v h264_qsv output.h264

ffmpeg -init_hw_device qsv=hw -filter_hw_device hw -c:v h264_qsv -i input.h264
-vf 'hwupload=extra_hw_frames=64,format=qsv,vpp_qsv=transpose=cclock_hflip'
-f rawvideo -pix_fmt nv12 ./transpose.yuv

Signed-off-by: Linjie Fu 
---
 libavfilter/vf_vpp_qsv.c | 101 ++-
 1 file changed, 99 insertions(+), 2 deletions(-)

diff --git a/libavfilter/vf_vpp_qsv.c b/libavfilter/vf_vpp_qsv.c
index dd05e8baff..01ff42a677 100644
--- a/libavfilter/vf_vpp_qsv.c
+++ b/libavfilter/vf_vpp_qsv.c
@@ -36,12 +36,15 @@
 #include "libavformat/avformat.h"
 
 #include "qsvvpp.h"
+#include "transpose.h"
 
 #define OFFSET(x) offsetof(VPPContext, x)
 #define FLAGS (AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_FILTERING_PARAM)
 
 /* number of video enhancement filters */
-#define ENH_FILTERS_COUNT (5)
+#define ENH_FILTERS_COUNT (7)
+#define QSV_HAVE_ROTATION  QSV_VERSION_ATLEAST(1, 17)
+#define QSV_HAVE_MIRRORING QSV_VERSION_ATLEAST(1, 19)
 
 typedef struct VPPContext{
 const AVClass *class;
@@ -54,6 +57,8 @@ typedef struct VPPContext{
 mfxExtVPPDenoise denoise_conf;
 mfxExtVPPDetail detail_conf;
 mfxExtVPPProcAmp procamp_conf;
+mfxExtVPPRotation rotation_conf;
+mfxExtVPPMirroring mirroring_conf;
 
 int out_width;
 int out_height;
@@ -70,6 +75,10 @@ typedef struct VPPContext{
 int crop_x;
 int crop_y;
 
+int transpose;
+int rotate; /* rotate angle : [0, 90, 180, 270] */
+int hflip;  /* flip mode : 0 = off, 1 = HORIZONTAL flip */
+
 /* param for the procamp */
 intprocamp;/* enable procamp */
 float  hue;
@@ -95,6 +104,15 @@ static const AVOption options[] = {
 { "contrast","ProcAmp contrast", OFFSET(contrast),
AV_OPT_TYPE_FLOAT,{ .dbl = 1.0 }, 0.0, 10.0, .flags = FLAGS},
 { "brightness",  "ProcAmp brightness",   OFFSET(brightness),  
AV_OPT_TYPE_FLOAT,{ .dbl = 0.0 }, -100.0, 100.0, .flags = FLAGS},
 
+{ "transpose",  "set transpose direction",   OFFSET(transpose),   
AV_OPT_TYPE_INT,  { .i64 = -1 }, -1, 6, FLAGS, "transpose"},
+{ "cclock_hflip",  "rotate counter-clockwise with horizontal flip",  
0, AV_OPT_TYPE_CONST, { .i64 = TRANSPOSE_CCLOCK_FLIP }, .flags=FLAGS, .unit = 
"transpose" },
+{ "clock", "rotate clockwise",   
0, AV_OPT_TYPE_CONST, { .i64 = TRANSPOSE_CLOCK   }, .flags=FLAGS, .unit = 
"transpose" },
+{ "cclock","rotate counter-clockwise",   
0, AV_OPT_TYPE_CONST, { .i64 = TRANSPOSE_CCLOCK  }, .flags=FLAGS, .unit = 
"transpose" },
+{ "clock_hflip",   "rotate clockwise with horizontal flip",  
0, AV_OPT_TYPE_CONST, { .i64 = TRANSPOSE_CLOCK_FLIP  }, .flags=FLAGS, .unit = 
"transpose" },
+{ "reversal",  "rotate by half-turn",
0, AV_OPT_TYPE_CONST, { .i64 = TRANSPOSE_REVERSAL}, .flags=FLAGS, .unit = 
"transpose" },
+{ "hflip", "flip horizontally",  
0, AV_OPT_TYPE_CONST, { .i64 = TRANSPOSE_HFLIP   }, .flags=FLAGS, .unit = 
"transpose" },
+{ "vflip", "flip vertically",
0, AV_OPT_TYPE_CONST, { .i64 = TRANSPOSE_VFLIP   }, .flags=FLAGS, .unit = 
"transpose" },
+
 { "cw",   "set the width crop area expression",   OFFSET(cw), 
AV_OPT_TYPE_STRING, { .str = "iw" }, CHAR_MIN, CHAR_MAX, FLAGS },
 { "ch",   "set the height crop area expression",  OFFSET(ch), 
AV_OPT_TYPE_STRING, { .str = "ih" }, CHAR_MIN, CHAR_MAX, FLAGS },
 { "cx",   "set the x crop area expression",   OFFSET(cx), 
AV_OPT_TYPE_STRING, { .str = "(in_w-out_w)/2" }, CHAR_MIN, CHAR_MAX, FLAGS },
@@ -322,8 +340,87 @

[FFmpeg-devel] [PATCH 1/2] lavc/decode: recreate hw_frames_ctx instead of return if already exists

2019-07-11 Thread Linjie Fu
If hw_frames_ctx exists when calling ff_decode_get_hw_frames_ctx, it
is allowed to be recreated instead of just return.

Move hw_frames_ctx check outside ff_decode_get_hw_frames_ctx, and check
in relevant code.

Signed-off-by: Linjie Fu 
---
 libavcodec/decode.c | 2 +-
 libavcodec/dxva2.c  | 8 +---
 libavcodec/vdpau.c  | 9 +
 3 files changed, 11 insertions(+), 8 deletions(-)

diff --git a/libavcodec/decode.c b/libavcodec/decode.c
index 6c31166..0863b82 100644
--- a/libavcodec/decode.c
+++ b/libavcodec/decode.c
@@ -1230,7 +1230,7 @@ int ff_decode_get_hw_frames_ctx(AVCodecContext *avctx,
 return AVERROR(ENOSYS);
 
 if (avctx->hw_frames_ctx)
-return 0;
+av_buffer_unref(&avctx->hw_frames_ctx);
 if (!avctx->hw_device_ctx) {
 av_log(avctx, AV_LOG_ERROR, "A hardware frames or device context is "
 "required for hardware accelerated decoding.\n");
diff --git a/libavcodec/dxva2.c b/libavcodec/dxva2.c
index 3241611..0404064 100644
--- a/libavcodec/dxva2.c
+++ b/libavcodec/dxva2.c
@@ -661,9 +661,11 @@ int ff_dxva2_decode_init(AVCodecContext *avctx)
 // (avctx->pix_fmt is not updated yet at this point)
 sctx->pix_fmt = avctx->hwaccel->pix_fmt;
 
-ret = ff_decode_get_hw_frames_ctx(avctx, dev_type);
-if (ret < 0)
-return ret;
+if (!avctx->hw_frames_ctx) {
+ret = ff_decode_get_hw_frames_ctx(avctx, dev_type);
+if (ret < 0)
+return ret;
+}
 
 frames_ctx = (AVHWFramesContext*)avctx->hw_frames_ctx->data;
 sctx->device_ctx = frames_ctx->device_ctx;
diff --git a/libavcodec/vdpau.c b/libavcodec/vdpau.c
index 167f06d..b7a4e9c 100644
--- a/libavcodec/vdpau.c
+++ b/libavcodec/vdpau.c
@@ -178,10 +178,11 @@ int ff_vdpau_common_init(AVCodecContext *avctx, 
VdpDecoderProfile profile,
 AVHWFramesContext *frames_ctx;
 AVVDPAUDeviceContext *dev_ctx;
 
-ret = ff_decode_get_hw_frames_ctx(avctx, AV_HWDEVICE_TYPE_VDPAU);
-if (ret < 0)
-return ret;
-
+if (!avctx->hw_frames_ctx) {
+ret = ff_decode_get_hw_frames_ctx(avctx, AV_HWDEVICE_TYPE_VDPAU);
+if (ret < 0)
+return ret;
+}
 frames_ctx = (AVHWFramesContext*)avctx->hw_frames_ctx->data;
 dev_ctx = frames_ctx->device_ctx->hwctx;
 
-- 
2.7.4

___
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] lavc/vaapi_decode: recreate hw_frames_ctx for vp9 without destroy va_context

2019-07-11 Thread Linjie Fu
VP9 allows resolution changes per frame. Currently in VAAPI, resolution
changes leads to va context destroy and reinit. This will cause
reference frame surface lost and produce garbage.

Though refs surface id could be passed to media driver and found in
RTtbl, vp9RefList[] in hal layer has already been destroyed. Thus the
new created VaContext could only got an empty RefList.

As libva allows re-create surface separately without changing the
context, this issue could be handled by only recreating hw_frames_ctx.

Set hwaccel_priv_data_keeping flag for vp9 to only recreating
hw_frame_ctx when dynamic resolution changing happens.

Could be verified by:
ffmpeg -hwaccel vaapi -hwaccel_device /dev/dri/renderD128 -i
  ./resolutions.ivf -pix_fmt p010le -f rawvideo -vframes 20 -y vaapi.yuv

Signed-off-by: Linjie Fu 
---
 libavcodec/decode.c| 10 +-
 libavcodec/internal.h  |  1 +
 libavcodec/pthread_frame.c |  2 ++
 libavcodec/vaapi_decode.c  | 40 ++--
 libavcodec/vaapi_vp9.c |  4 
 5 files changed, 34 insertions(+), 23 deletions(-)

diff --git a/libavcodec/decode.c b/libavcodec/decode.c
index 0863b82..7b15fa5 100644
--- a/libavcodec/decode.c
+++ b/libavcodec/decode.c
@@ -1254,7 +1254,6 @@ int ff_decode_get_hw_frames_ctx(AVCodecContext *avctx,
 
 frames_ctx = (AVHWFramesContext*)avctx->hw_frames_ctx->data;
 
-
 if (frames_ctx->initial_pool_size) {
 // We guarantee 4 base work surfaces. The function above guarantees 1
 // (the absolute minimum), so add the missing count.
@@ -1333,7 +1332,7 @@ static int hwaccel_init(AVCodecContext *avctx,
 return AVERROR_PATCHWELCOME;
 }
 
-if (hwaccel->priv_data_size) {
+if (hwaccel->priv_data_size && !avctx->internal->hwaccel_priv_data) {
 avctx->internal->hwaccel_priv_data =
 av_mallocz(hwaccel->priv_data_size);
 if (!avctx->internal->hwaccel_priv_data)
@@ -1396,9 +1395,10 @@ int ff_get_format(AVCodecContext *avctx, const enum 
AVPixelFormat *fmt)
 memcpy(choices, fmt, (n + 1) * sizeof(*choices));
 
 for (;;) {
-// Remove the previous hwaccel, if there was one.
-hwaccel_uninit(avctx);
-
+// Remove the previous hwaccel, if there was one,
+// and no need for keeping.
+if (!avctx->internal->hwaccel_priv_data_keeping)
+hwaccel_uninit(avctx);
 user_choice = avctx->get_format(avctx, choices);
 if (user_choice == AV_PIX_FMT_NONE) {
 // Explicitly chose nothing, give up.
diff --git a/libavcodec/internal.h b/libavcodec/internal.h
index 5096ffa..7adef08 100644
--- a/libavcodec/internal.h
+++ b/libavcodec/internal.h
@@ -188,6 +188,7 @@ typedef struct AVCodecInternal {
  * hwaccel-specific private data
  */
 void *hwaccel_priv_data;
+int hwaccel_priv_data_keeping;
 
 /**
  * checks API usage: after codec draining, flush is required to resume 
operation
diff --git a/libavcodec/pthread_frame.c b/libavcodec/pthread_frame.c
index 36ac0ac..6032818 100644
--- a/libavcodec/pthread_frame.c
+++ b/libavcodec/pthread_frame.c
@@ -283,6 +283,7 @@ static int update_context_from_thread(AVCodecContext *dst, 
AVCodecContext *src,
 dst->sample_fmt = src->sample_fmt;
 dst->channel_layout = src->channel_layout;
 dst->internal->hwaccel_priv_data = src->internal->hwaccel_priv_data;
+dst->internal->hwaccel_priv_data_keeping = 
src->internal->hwaccel_priv_data_keeping;
 
 if (!!dst->hw_frames_ctx != !!src->hw_frames_ctx ||
 (dst->hw_frames_ctx && dst->hw_frames_ctx->data != 
src->hw_frames_ctx->data)) {
@@ -340,6 +341,7 @@ static int update_context_from_user(AVCodecContext *dst, 
AVCodecContext *src)
 dst->frame_number = src->frame_number;
 dst->reordered_opaque = src->reordered_opaque;
 dst->thread_safe_callbacks = src->thread_safe_callbacks;
+dst->internal->hwaccel_priv_data_keeping = 
src->internal->hwaccel_priv_data_keeping;
 
 if (src->slice_count && src->slice_offset) {
 if (dst->slice_count < src->slice_count) {
diff --git a/libavcodec/vaapi_decode.c b/libavcodec/vaapi_decode.c
index 69512e1..13f0cf0 100644
--- a/libavcodec/vaapi_decode.c
+++ b/libavcodec/vaapi_decode.c
@@ -613,8 +613,10 @@ int ff_vaapi_decode_init(AVCodecContext *avctx)
 VAStatus vas;
 int err;
 
-ctx->va_config  = VA_INVALID_ID;
-ctx->va_context = VA_INVALID_ID;
+if (!ctx->va_config && !ctx->va_context){
+ctx->va_config  = VA_INVALID_ID;
+ctx->va_context = VA_INVALID_ID;
+}
 
 #if FF_API_STRUCT_VAAPI_CONTEXT
 if (avctx->hwaccel_context) {
@@ -642,7 +644,6 @@ int ff_vaapi_decode_init(AVCodecContext *avctx)
 // present, so set it here to avoid the

[FFmpeg-devel] [PATCH] fftools/ffmpeg_filter: use -reinit_filter to disable/enable auto scale

2019-07-11 Thread Linjie Fu
Currently, ffmpeg inserts scale filter in the filter graph to force
the whole decoded stream to scale into the same size with the first
frame. It's not quite make sense in resolution changing cases if user
wants the rawvideo without any scale.

Option -reinit_filter 0 could be used to realize similar function, but
it fails when ifilter has hw_frame_ctx.

Add auto_scale flag set by -reinit_filter to indicate whether auto
inserting the scale filter in the filter graph.

Signed-off-by: Linjie Fu 
---
Request for comments.
As we have discussed in the rawdump filter patch, here is a simpler
solution based on -reinit_filter, and reuse this option.(maybe it's not
easy to be accepted to add a separate option)

 fftools/ffmpeg.c| 2 +-
 fftools/ffmpeg.h| 1 +
 fftools/ffmpeg_filter.c | 2 +-
 3 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c
index 01f04103cf..5305b87bd4 100644
--- a/fftools/ffmpeg.c
+++ b/fftools/ffmpeg.c
@@ -2133,6 +2133,7 @@ static int ifilter_send_frame(InputFilter *ifilter, 
AVFrame *frame)
 
 /* determine if the parameters for this input changed */
 need_reinit = ifilter->format != frame->format;
+fg->auto_scale = ifilter->ist->reinit_filters;
 
 switch (ifilter->ist->st->codecpar->codec_type) {
 case AVMEDIA_TYPE_AUDIO:
@@ -2145,7 +2146,6 @@ static int ifilter_send_frame(InputFilter *ifilter, 
AVFrame *frame)
ifilter->height != frame->height;
 break;
 }
-
 if (!ifilter->ist->reinit_filters && fg->graph)
 need_reinit = 0;
 
diff --git a/fftools/ffmpeg.h b/fftools/ffmpeg.h
index 7b6f802082..0c289b439f 100644
--- a/fftools/ffmpeg.h
+++ b/fftools/ffmpeg.h
@@ -285,6 +285,7 @@ typedef struct FilterGraph {
 
 AVFilterGraph *graph;
 int reconfiguration;
+int auto_scale;
 
 InputFilter   **inputs;
 int  nb_inputs;
diff --git a/fftools/ffmpeg_filter.c b/fftools/ffmpeg_filter.c
index 72838de1e2..856ba48de7 100644
--- a/fftools/ffmpeg_filter.c
+++ b/fftools/ffmpeg_filter.c
@@ -469,7 +469,7 @@ static int configure_output_video_filter(FilterGraph *fg, 
OutputFilter *ofilter,
 if (ret < 0)
 return ret;
 
-if (ofilter->width || ofilter->height) {
+if ((ofilter->width || ofilter->height) && fg->auto_scale) {
 char args[255];
 AVFilterContext *filter;
 AVDictionaryEntry *e = NULL;
-- 
2.17.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/2] fftools/ffmpeg_filter: add -autoscale to disable/enable the default scale

2019-07-15 Thread Linjie Fu
Currently, ffmpeg inserts scale filter by default in the filter graph
to force the whole decoded stream to scale into the same size with the
first frame. It's not quite make sense in resolution changing cases if
user wants the rawvideo without any scale.

Using autoscale/noautoscale to indicate whether auto inserting the scale
filter in the filter graph:
-noautoscale or -autoscale 0:
disable the default auto scale filter inserting.

Signed-off-by: Linjie Fu 
---
 fftools/ffmpeg.c| 1 +
 fftools/ffmpeg.h| 4 
 fftools/ffmpeg_filter.c | 2 +-
 fftools/ffmpeg_opt.c| 5 +
 4 files changed, 11 insertions(+), 1 deletion(-)

diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c
index 01f04103cf..5d52430b1e 100644
--- a/fftools/ffmpeg.c
+++ b/fftools/ffmpeg.c
@@ -2133,6 +2133,7 @@ static int ifilter_send_frame(InputFilter *ifilter, 
AVFrame *frame)
 
 /* determine if the parameters for this input changed */
 need_reinit = ifilter->format != frame->format;
+fg->autoscale = ifilter->ist->autoscale;
 
 switch (ifilter->ist->st->codecpar->codec_type) {
 case AVMEDIA_TYPE_AUDIO:
diff --git a/fftools/ffmpeg.h b/fftools/ffmpeg.h
index 7b6f802082..1602406581 100644
--- a/fftools/ffmpeg.h
+++ b/fftools/ffmpeg.h
@@ -133,6 +133,8 @@ typedef struct OptionsContext {
 intnb_hwaccel_output_formats;
 SpecifierOpt *autorotate;
 intnb_autorotate;
+SpecifierOpt *autoscale;
+intnb_autoscale;
 
 /* output options */
 StreamMap *stream_maps;
@@ -285,6 +287,7 @@ typedef struct FilterGraph {
 
 AVFilterGraph *graph;
 int reconfiguration;
+int autoscale;
 
 InputFilter   **inputs;
 int  nb_inputs;
@@ -335,6 +338,7 @@ typedef struct InputStream {
 int guess_layout_max;
 
 int autorotate;
+int autoscale;
 
 int fix_sub_duration;
 struct { /* previous decoded subtitle and related variables */
diff --git a/fftools/ffmpeg_filter.c b/fftools/ffmpeg_filter.c
index 72838de1e2..2a2eb080eb 100644
--- a/fftools/ffmpeg_filter.c
+++ b/fftools/ffmpeg_filter.c
@@ -469,7 +469,7 @@ static int configure_output_video_filter(FilterGraph *fg, 
OutputFilter *ofilter,
 if (ret < 0)
 return ret;
 
-if (ofilter->width || ofilter->height) {
+if ((ofilter->width || ofilter->height) && fg->autoscale) {
 char args[255];
 AVFilterContext *filter;
 AVDictionaryEntry *e = NULL;
diff --git a/fftools/ffmpeg_opt.c b/fftools/ffmpeg_opt.c
index f5ca18aa64..47f90c22aa 100644
--- a/fftools/ffmpeg_opt.c
+++ b/fftools/ffmpeg_opt.c
@@ -742,7 +742,9 @@ static void add_input_streams(OptionsContext *o, 
AVFormatContext *ic)
 MATCH_PER_STREAM_OPT(ts_scale, dbl, ist->ts_scale, ic, st);
 
 ist->autorotate = 1;
+ist->autoscale  = 1;
 MATCH_PER_STREAM_OPT(autorotate, i, ist->autorotate, ic, st);
+MATCH_PER_STREAM_OPT(autoscale, i, ist->autoscale, ic, st);
 
 MATCH_PER_STREAM_OPT(codec_tags, str, codec_tag, ic, st);
 if (codec_tag) {
@@ -3640,6 +3642,9 @@ const OptionDef options[] = {
 { "autorotate",   HAS_ARG | OPT_BOOL | OPT_SPEC |
   OPT_EXPERT | OPT_INPUT,  
  { .off = OFFSET(autorotate) },
 "automatically insert correct rotate filters" },
+{ "autoscale",HAS_ARG | OPT_BOOL | OPT_SPEC |
+  OPT_EXPERT | OPT_INPUT,  
  { .off = OFFSET(autoscale) },
+"automatically insert correct scale filters" },
 
 /* audio options */
 { "aframes",OPT_AUDIO | HAS_ARG  | OPT_PERFILE | OPT_OUTPUT,   
{ .func_arg = opt_audio_frames },
-- 
2.17.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/2] doc/ffmpeg.texi: update docs for autoscale/autorotate

2019-07-15 Thread Linjie Fu
Add docs for autoscale/noautoscale.

Update information for autorotate according to ffplay.

Signed-off-by: Linjie Fu 
---
 doc/ffmpeg.texi | 11 +++
 1 file changed, 11 insertions(+)

diff --git a/doc/ffmpeg.texi b/doc/ffmpeg.texi
index cd35eb49c8..040a2b53cf 100644
--- a/doc/ffmpeg.texi
+++ b/doc/ffmpeg.texi
@@ -735,9 +735,20 @@ Technical note -- attachments are implemented as codec 
extradata, so this
 option can actually be used to extract extradata from any stream, not just
 attachments.
 
+@item -autorotate
+Automatically rotate the video according to file metadata. Enabled by
+default, use @option{-noautorotate} to disable it.
+
+@item -autoscale
+Automatically scale the video according to the resolution of first frame.
+Enabled by default, use @option{-noautoscale} to disable it.
+
 @item -noautorotate
 Disable automatically rotating video based on file metadata.
 
+@item -noautoscale
+Disable automatically scale video based on first frame resolution.
+
 @end table
 
 @section Video Options
-- 
2.17.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] lavc/vaapi_encode: add support for maxframesize

2019-07-15 Thread Linjie Fu
Add support for max frame size:
- max_frame_size (bytes) to indicate the max allowed size for frame.

If the frame size exceeds the limitation, encoder will to control the frame
size by adjusting QP value.
- MFS_NUM_PASSES to indicate number of passes for QP adjust.
- MFS_DELTA_QP to indicate adjust qp value per pass.

To simplify the usage, default QP adjust is set to delta_qp[4] = {1, 1, 1, 1}.
Use new_qp for encoder if frame size exceeds the limitation:
new_qp = base_qp + delta_qp[0] + delta_qp[1] + ...

ffmpeg -hwaccel vaapi -vaapi_device /dev/dri/renderD128 -f rawvideo \
-v verbose -s:v 352x288 -i ./input.yuv -vf format=nv12,hwupload \
-c:v h264_vaapi -profile:v main -g 30 -bf 3 -max_frame_size 4 \
-vframes 100 -y ./max_frame_size.h264

Max frame size was enabled since VA-API version (1, 3, 0), but query is 
available
since (1, 5, 0). It will be passed as a parameter in picParam and should be set
for each frame.

Signed-off-by: Linjie Fu 
---
Since the Attribute query for maxframesize is merged in media driver,
it's more robust now for vaapi to make use of this feature.
https://github.com/intel/media-driver/pull/656

 libavcodec/vaapi_encode.c | 68 ++-
 libavcodec/vaapi_encode.h | 19 +--
 2 files changed, 84 insertions(+), 3 deletions(-)

diff --git a/libavcodec/vaapi_encode.c b/libavcodec/vaapi_encode.c
index dd2a24de04..fdc1cec178 100644
--- a/libavcodec/vaapi_encode.c
+++ b/libavcodec/vaapi_encode.c
@@ -258,7 +258,16 @@ static int vaapi_encode_issue(AVCodecContext *avctx,
 if (err < 0)
 goto fail;
 }
-
+#if VA_CHECK_VERSION(1, 5, 0)
+if (ctx->max_frame_size) {
+err = vaapi_encode_make_misc_param_buffer(avctx, pic,
+
VAEncMiscParameterTypeMultiPassFrameSize,
+&ctx->mfs_params,
+sizeof(ctx->mfs_params));
+if (err < 0)
+goto fail;
+}
+#endif
 if (pic->type == PICTURE_TYPE_IDR) {
 if (ctx->va_packed_headers & VA_ENC_PACKED_HEADER_SEQUENCE &&
 ctx->codec->write_sequence_header) {
@@ -1671,6 +1680,54 @@ rc_mode_found:
 return 0;
 }
 
+static av_cold int vaapi_encode_init_max_frame_size(AVCodecContext *avctx)
+{
+#if VA_CHECK_VERSION(1, 5, 0)
+VAAPIEncodeContext  *ctx = avctx->priv_data;
+VAConfigAttrib  attr = { VAConfigAttribMaxFrameSize };
+VAStatus vas;
+int i;
+
+vas = vaGetConfigAttributes(ctx->hwctx->display,
+ctx->va_profile,
+ctx->va_entrypoint,
+&attr, 1);
+if (vas != VA_STATUS_SUCCESS) {
+ctx->max_frame_size = 0;
+av_log(avctx, AV_LOG_ERROR, "Failed to query max frame size "
+   "config attribute: %d (%s).\n", vas, vaErrorStr(vas));
+return AVERROR_EXTERNAL;
+}
+
+if (attr.value == VA_ATTRIB_NOT_SUPPORTED) {
+ctx->max_frame_size = 0;
+av_log(avctx, AV_LOG_WARNING, "Max frame size attribute "
+"is not supported.\n");
+} else {
+ctx->delta_qp = av_mallocz_array(MFS_NUM_PASSES, sizeof(uint8_t));
+if (!ctx->delta_qp) {
+return AVERROR(ENOMEM);
+}
+for (i = 0; i delta_qp[i] = MFS_DELTA_QP;
+
+ctx->mfs_params = (VAEncMiscParameterBufferMultiPassFrameSize){
+.max_frame_size = ctx->max_frame_size,
+.num_passes = MFS_NUM_PASSES,
+.delta_qp   = ctx->delta_qp,
+};
+
+av_log(avctx, AV_LOG_VERBOSE, "Max Frame Size: %d bytes.\n ",
+ctx->max_frame_size);
+}
+#else
+av_log(avctx, AV_LOG_WARNING, "Max Frame Size is "
+"not supported with this VA version.\n");
+#endif
+
+return 0;
+}
+
 static av_cold int vaapi_encode_init_gop_structure(AVCodecContext *avctx)
 {
 VAAPIEncodeContext *ctx = avctx->priv_data;
@@ -2138,6 +2195,12 @@ av_cold int ff_vaapi_encode_init(AVCodecContext *avctx)
 goto fail;
 }
 
+if (ctx->max_frame_size) {
+err = vaapi_encode_init_max_frame_size(avctx);
+if (err < 0)
+goto fail;
+}
+
 vas = vaCreateConfig(ctx->hwctx->display,
  ctx->va_profile, ctx->va_entrypoint,
  ctx->config_attributes, ctx->nb_config_attributes,
@@ -2262,6 +2325,9 @@ av_cold int ff_vaapi_encode_close(AVCodecContext *avctx)
 ctx->va_config = VA_INVALID_ID;
 }
 
+if (ctx->delta_qp)
+av_freep(&ctx->delta_qp);
+
 av

[FFmpeg-devel] [PATCH 2/2] doc/vaapi_encode: add documentations for max_frame_size

2019-07-15 Thread Linjie Fu
Add docs for max_frame_size option.

Signed-off-by: Linjie Fu 
---
 doc/encoders.texi | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/doc/encoders.texi b/doc/encoders.texi
index eefd124751..ea43900e91 100644
--- a/doc/encoders.texi
+++ b/doc/encoders.texi
@@ -2899,6 +2899,12 @@ will refer only to P- or I-frames.  When set to greater 
values multiple layers
 of B-frames will be present, frames in each layer only referring to frames in
 higher layers.
 
+@item max_frame_size
+Set the allowed max size in bytes for each frame. If the frame size exceeds
+the limitation, encoder will adjust the QP value by adding delta_qp for each 
+pass to control the frame size. To simplify the usage, delta_qp is set to
+default.
+
 @item rc_mode
 Set the rate control mode to use.  A given driver may only support a subset of
 modes.
-- 
2.17.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/2] doc/ffmpeg.texi: update docs for autoscale/autorotate

2019-07-16 Thread Linjie Fu
Add docs for autoscale.

Update information for autorotate according to ffplay.

Signed-off-by: Linjie Fu 
---
 doc/ffmpeg.texi | 14 ++
 1 file changed, 10 insertions(+), 4 deletions(-)

diff --git a/doc/ffmpeg.texi b/doc/ffmpeg.texi
index cd35eb49c8..b91da2b2b4 100644
--- a/doc/ffmpeg.texi
+++ b/doc/ffmpeg.texi
@@ -734,10 +734,6 @@ ffmpeg -dump_attachment:t "" -i INPUT
 Technical note -- attachments are implemented as codec extradata, so this
 option can actually be used to extract extradata from any stream, not just
 attachments.
-
-@item -noautorotate
-Disable automatically rotating video based on file metadata.
-
 @end table
 
 @section Video Options
@@ -819,6 +815,16 @@ Create the filtergraph specified by @var{filtergraph} and 
use it to
 filter the stream.
 
 This is an alias for @code{-filter:v}, see the @ref{filter_option,,-filter 
option}.
+
+@item -autorotate
+Automatically rotate the video according to file metadata. Enabled by
+default, use @option{-noautorotate} to disable it.
+
+@item -autoscale
+Automatically scale the video according to the resolution of first frame.
+Enabled by default, use @option{-noautoscale} to disable it. Each frame of
+the output raw video can be in different resolutions and is in need to be
+handled next.
 @end table
 
 @section Advanced Video options
-- 
2.17.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] lavc/phtread_frame: update hwaccel_priv_data in time for multithread

2019-07-18 Thread Linjie Fu
When resolution/format changes, hwaccel_uninit/hwaccel_init will
be called to destroy and re-create the hwaccel_priv_data. When output
frame number meets the constraints for vframes, the hwaccel_priv_data
modified in decoding thread won't be update to user-thread due to the
delay mechanism. It will lead to:
1. memory leak in child-thread.
2. double free in user-thread while calling avcodec_close().

Can be reproduced with a resolution change case, and use -vframes
to terminate the decode during dynamic resolution changing:

ffmpeg -hwaccel vaapi -hwaccel_device /dev/dri/renderD128 -v verbose
-i ./reinit-large_420_8-to-small_420_8.h264 -pix_fmt nv12 -f rawvideo
-vsync passthrough -vframes 45 -y out.yuv

The root cause is the conflict between delay mechanism and -vframes.
FFmpeg won't output a frame if it's still receiving the initial packets,
so there is async between decode process and output. hwaccel_priv_data
in user thread won't be updated until the resolution changing
frame is output.

As user context should reflect the state of the last frame that
was output to the user, hwaccel_priv_data should be updated
separately from decoding thread in time.

Signed-off-by: Linjie Fu 
---
 libavcodec/pthread_frame.c | 11 +--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/libavcodec/pthread_frame.c b/libavcodec/pthread_frame.c
index 36ac0ac..cf7a575 100644
--- a/libavcodec/pthread_frame.c
+++ b/libavcodec/pthread_frame.c
@@ -282,7 +282,6 @@ static int update_context_from_thread(AVCodecContext *dst, 
AVCodecContext *src,
 dst->sample_rate= src->sample_rate;
 dst->sample_fmt = src->sample_fmt;
 dst->channel_layout = src->channel_layout;
-dst->internal->hwaccel_priv_data = src->internal->hwaccel_priv_data;
 
 if (!!dst->hw_frames_ctx != !!src->hw_frames_ctx ||
 (dst->hw_frames_ctx && dst->hw_frames_ctx->data != 
src->hw_frames_ctx->data)) {
@@ -410,6 +409,7 @@ static int submit_packet(PerThreadContext *p, 
AVCodecContext *user_avctx,
 pthread_mutex_unlock(&prev_thread->progress_mutex);
 }
 
+p->avctx->internal->hwaccel_priv_data = 
prev_thread->avctx->internal->hwaccel_priv_data;
 err = update_context_from_thread(p->avctx, prev_thread->avctx, 0);
 if (err) {
 pthread_mutex_unlock(&p->mutex);
@@ -476,7 +476,7 @@ int ff_thread_decode_frame(AVCodecContext *avctx,
 FrameThreadContext *fctx = avctx->internal->thread_ctx;
 int finished = fctx->next_finished;
 PerThreadContext *p;
-int err;
+int err, cur_decoding;
 
 /* release the async lock, permitting blocked hwaccel threads to
  * go forward while we are in this function */
@@ -544,6 +544,13 @@ int ff_thread_decode_frame(AVCodecContext *avctx,
 
 if (fctx->next_decoding >= avctx->thread_count) fctx->next_decoding = 0;
 
+/* update hwaccel_priv_data from decoding thread */
+cur_decoding = fctx->next_decoding - 1;
+if (cur_decoding < 0) cur_decoding += avctx->thread_count;
+
+p = &fctx->threads[cur_decoding];
+avctx->internal->hwaccel_priv_data = p->avctx->internal->hwaccel_priv_data;
+
 fctx->next_finished = finished;
 
 /* return the size of the consumed packet if no error occurred */
-- 
2.7.4

___
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] fftools/ffmpeg_filter: add -autoscale to disable/enable the default scale

2019-07-19 Thread Linjie Fu
Currently, ffmpeg inserts scale filter by default in the filter graph
to force the whole decoded stream to scale into the same size with the
first frame. It's not quite make sense in resolution changing cases if
user wants the rawvideo without any scale.

Using autoscale/noautoscale to indicate whether auto inserting the scale
filter in the filter graph:
-noautoscale or -autoscale 0:
disable the default auto scale filter inserting.

Signed-off-by: U. Artie Eoff 
Signed-off-by: Linjie Fu 
---
 fftools/ffmpeg.c| 1 +
 fftools/ffmpeg.h| 4 
 fftools/ffmpeg_filter.c | 2 +-
 fftools/ffmpeg_opt.c| 8 
 4 files changed, 14 insertions(+), 1 deletion(-)

diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c
index 01f04103cf..5d52430b1e 100644
--- a/fftools/ffmpeg.c
+++ b/fftools/ffmpeg.c
@@ -2133,6 +2133,7 @@ static int ifilter_send_frame(InputFilter *ifilter, 
AVFrame *frame)
 
 /* determine if the parameters for this input changed */
 need_reinit = ifilter->format != frame->format;
+fg->autoscale = ifilter->ist->autoscale;
 
 switch (ifilter->ist->st->codecpar->codec_type) {
 case AVMEDIA_TYPE_AUDIO:
diff --git a/fftools/ffmpeg.h b/fftools/ffmpeg.h
index 7b6f802082..1602406581 100644
--- a/fftools/ffmpeg.h
+++ b/fftools/ffmpeg.h
@@ -133,6 +133,8 @@ typedef struct OptionsContext {
 intnb_hwaccel_output_formats;
 SpecifierOpt *autorotate;
 intnb_autorotate;
+SpecifierOpt *autoscale;
+intnb_autoscale;
 
 /* output options */
 StreamMap *stream_maps;
@@ -285,6 +287,7 @@ typedef struct FilterGraph {
 
 AVFilterGraph *graph;
 int reconfiguration;
+int autoscale;
 
 InputFilter   **inputs;
 int  nb_inputs;
@@ -335,6 +338,7 @@ typedef struct InputStream {
 int guess_layout_max;
 
 int autorotate;
+int autoscale;
 
 int fix_sub_duration;
 struct { /* previous decoded subtitle and related variables */
diff --git a/fftools/ffmpeg_filter.c b/fftools/ffmpeg_filter.c
index 72838de1e2..2a2eb080eb 100644
--- a/fftools/ffmpeg_filter.c
+++ b/fftools/ffmpeg_filter.c
@@ -469,7 +469,7 @@ static int configure_output_video_filter(FilterGraph *fg, 
OutputFilter *ofilter,
 if (ret < 0)
 return ret;
 
-if (ofilter->width || ofilter->height) {
+if ((ofilter->width || ofilter->height) && fg->autoscale) {
 char args[255];
 AVFilterContext *filter;
 AVDictionaryEntry *e = NULL;
diff --git a/fftools/ffmpeg_opt.c b/fftools/ffmpeg_opt.c
index f5ca18aa64..41cb676dad 100644
--- a/fftools/ffmpeg_opt.c
+++ b/fftools/ffmpeg_opt.c
@@ -742,7 +742,9 @@ static void add_input_streams(OptionsContext *o, 
AVFormatContext *ic)
 MATCH_PER_STREAM_OPT(ts_scale, dbl, ist->ts_scale, ic, st);
 
 ist->autorotate = 1;
+ist->autoscale  = 1;
 MATCH_PER_STREAM_OPT(autorotate, i, ist->autorotate, ic, st);
+MATCH_PER_STREAM_OPT(autoscale, i, ist->autoscale, ic, st);
 
 MATCH_PER_STREAM_OPT(codec_tags, str, codec_tag, ic, st);
 if (codec_tag) {
@@ -3640,6 +3642,12 @@ const OptionDef options[] = {
 { "autorotate",   HAS_ARG | OPT_BOOL | OPT_SPEC |
   OPT_EXPERT | OPT_INPUT,  
  { .off = OFFSET(autorotate) },
 "automatically insert correct rotate filters" },
+{ "autoscale",HAS_ARG | OPT_BOOL | OPT_SPEC |
+  OPT_EXPERT | OPT_INPUT,  
  { .off = OFFSET(autoscale) },
+"automatically insert a scale filter at the end of the filter graph if 
a resolution"
+"change is detected. This ensures all frames are the same resolution 
as the first frame"
+"when they leave the filter chain (this option is enabled by default)."
+"If disabled, some encoders/muxers may not support this mode."},
 
 /* audio options */
 { "aframes",OPT_AUDIO | HAS_ARG  | OPT_PERFILE | OPT_OUTPUT,   
{ .func_arg = opt_audio_frames },
-- 
2.17.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] doc/ffmpeg.texi: update docs for autoscale/autorotate

2019-07-19 Thread Linjie Fu
Add docs for autoscale.

Update information for autorotate according to ffplay.

Signed-off-by: U. Artie Eoff 
Signed-off-by: Linjie Fu 
---
 doc/ffmpeg.texi | 17 +
 1 file changed, 13 insertions(+), 4 deletions(-)

diff --git a/doc/ffmpeg.texi b/doc/ffmpeg.texi
index cd35eb49c8..99121b6981 100644
--- a/doc/ffmpeg.texi
+++ b/doc/ffmpeg.texi
@@ -734,10 +734,6 @@ ffmpeg -dump_attachment:t "" -i INPUT
 Technical note -- attachments are implemented as codec extradata, so this
 option can actually be used to extract extradata from any stream, not just
 attachments.
-
-@item -noautorotate
-Disable automatically rotating video based on file metadata.
-
 @end table
 
 @section Video Options
@@ -819,6 +815,19 @@ Create the filtergraph specified by @var{filtergraph} and 
use it to
 filter the stream.
 
 This is an alias for @code{-filter:v}, see the @ref{filter_option,,-filter 
option}.
+
+@item -autorotate
+Automatically rotate the video according to file metadata. Enabled by
+default, use @option{-noautorotate} to disable it.
+
+@item -autoscale
+Automatically scale the video according to the resolution of first frame.
+Enabled by default, use @option{-noautoscale} to disable it. When autoscale is
+disabled, all output frames might not be in the same resolution and may require
+some additional explicit processing according to your final rendering/output
+destination. Disabling autoscale may not work in all situations. Therefore, it
+is not recommended to disable it unless you really know what you are doing.
+Disable autoscale at your own risk.
 @end table
 
 @section Advanced Video options
-- 
2.17.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] fftools/ffmpeg_filter: add -autoscale to disable/enable the default scale

2019-07-19 Thread Linjie Fu
Currently, ffmpeg inserts scale filter by default in the filter graph
to force the whole decoded stream to scale into the same size with the
first frame. It's not quite make sense in resolution changing cases if
user wants the rawvideo without any scale.

Using autoscale/noautoscale to indicate whether auto inserting the scale
filter in the filter graph:
-noautoscale or -autoscale 0:
disable the default auto scale filter inserting.

Update docs.

Signed-off-by: U. Artie Eoff 
Signed-off-by: Linjie Fu 
---
 doc/ffmpeg.texi | 17 +
 fftools/ffmpeg.c|  1 +
 fftools/ffmpeg.h|  4 
 fftools/ffmpeg_filter.c |  2 +-
 fftools/ffmpeg_opt.c|  8 
 5 files changed, 27 insertions(+), 5 deletions(-)

diff --git a/doc/ffmpeg.texi b/doc/ffmpeg.texi
index cd35eb49c8..99121b6981 100644
--- a/doc/ffmpeg.texi
+++ b/doc/ffmpeg.texi
@@ -734,10 +734,6 @@ ffmpeg -dump_attachment:t "" -i INPUT
 Technical note -- attachments are implemented as codec extradata, so this
 option can actually be used to extract extradata from any stream, not just
 attachments.
-
-@item -noautorotate
-Disable automatically rotating video based on file metadata.
-
 @end table
 
 @section Video Options
@@ -819,6 +815,19 @@ Create the filtergraph specified by @var{filtergraph} and 
use it to
 filter the stream.
 
 This is an alias for @code{-filter:v}, see the @ref{filter_option,,-filter 
option}.
+
+@item -autorotate
+Automatically rotate the video according to file metadata. Enabled by
+default, use @option{-noautorotate} to disable it.
+
+@item -autoscale
+Automatically scale the video according to the resolution of first frame.
+Enabled by default, use @option{-noautoscale} to disable it. When autoscale is
+disabled, all output frames might not be in the same resolution and may require
+some additional explicit processing according to your final rendering/output
+destination. Disabling autoscale may not work in all situations. Therefore, it
+is not recommended to disable it unless you really know what you are doing.
+Disable autoscale at your own risk.
 @end table
 
 @section Advanced Video options
diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c
index 01f04103cf..5d52430b1e 100644
--- a/fftools/ffmpeg.c
+++ b/fftools/ffmpeg.c
@@ -2133,6 +2133,7 @@ static int ifilter_send_frame(InputFilter *ifilter, 
AVFrame *frame)
 
 /* determine if the parameters for this input changed */
 need_reinit = ifilter->format != frame->format;
+fg->autoscale = ifilter->ist->autoscale;
 
 switch (ifilter->ist->st->codecpar->codec_type) {
 case AVMEDIA_TYPE_AUDIO:
diff --git a/fftools/ffmpeg.h b/fftools/ffmpeg.h
index 7b6f802082..1602406581 100644
--- a/fftools/ffmpeg.h
+++ b/fftools/ffmpeg.h
@@ -133,6 +133,8 @@ typedef struct OptionsContext {
 intnb_hwaccel_output_formats;
 SpecifierOpt *autorotate;
 intnb_autorotate;
+SpecifierOpt *autoscale;
+intnb_autoscale;
 
 /* output options */
 StreamMap *stream_maps;
@@ -285,6 +287,7 @@ typedef struct FilterGraph {
 
 AVFilterGraph *graph;
 int reconfiguration;
+int autoscale;
 
 InputFilter   **inputs;
 int  nb_inputs;
@@ -335,6 +338,7 @@ typedef struct InputStream {
 int guess_layout_max;
 
 int autorotate;
+int autoscale;
 
 int fix_sub_duration;
 struct { /* previous decoded subtitle and related variables */
diff --git a/fftools/ffmpeg_filter.c b/fftools/ffmpeg_filter.c
index 72838de1e2..2a2eb080eb 100644
--- a/fftools/ffmpeg_filter.c
+++ b/fftools/ffmpeg_filter.c
@@ -469,7 +469,7 @@ static int configure_output_video_filter(FilterGraph *fg, 
OutputFilter *ofilter,
 if (ret < 0)
 return ret;
 
-if (ofilter->width || ofilter->height) {
+if ((ofilter->width || ofilter->height) && fg->autoscale) {
 char args[255];
 AVFilterContext *filter;
 AVDictionaryEntry *e = NULL;
diff --git a/fftools/ffmpeg_opt.c b/fftools/ffmpeg_opt.c
index f5ca18aa64..41cb676dad 100644
--- a/fftools/ffmpeg_opt.c
+++ b/fftools/ffmpeg_opt.c
@@ -742,7 +742,9 @@ static void add_input_streams(OptionsContext *o, 
AVFormatContext *ic)
 MATCH_PER_STREAM_OPT(ts_scale, dbl, ist->ts_scale, ic, st);
 
 ist->autorotate = 1;
+ist->autoscale  = 1;
 MATCH_PER_STREAM_OPT(autorotate, i, ist->autorotate, ic, st);
+MATCH_PER_STREAM_OPT(autoscale, i, ist->autoscale, ic, st);
 
 MATCH_PER_STREAM_OPT(codec_tags, str, codec_tag, ic, st);
 if (codec_tag) {
@@ -3640,6 +3642,12 @@ const OptionDef options[] = {
 { "autorotate",   HAS_ARG | OPT_BOOL | OPT_SPEC |
   OPT_EXPERT | OPT_INPUT,  
  { .off = OFFSET(autorotate) },
 "automatically insert correct rotate filters" },
+{ "autoscale",HAS_ARG | OPT_BOOL | OPT_SP

[FFmpeg-devel] [PATCH] lavu/hwcontext_qsv: fix the memory leak

2019-07-26 Thread Linjie Fu
av_dict_free child_device_opts to fix the memory leak.

Signed-off-by: Linjie Fu 
---
 libavutil/hwcontext_qsv.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/libavutil/hwcontext_qsv.c b/libavutil/hwcontext_qsv.c
index 59e4ed9157..0329a81ec3 100644
--- a/libavutil/hwcontext_qsv.c
+++ b/libavutil/hwcontext_qsv.c
@@ -1240,6 +1240,8 @@ static int qsv_device_create(AVHWDeviceContext *ctx, 
const char *device,
 
 ret = av_hwdevice_ctx_create(&priv->child_device_ctx, child_device_type,
  e ? e->value : NULL, child_device_opts, 0);
+
+av_dict_free(&child_device_opts);
 if (ret < 0)
 return ret;
 
-- 
2.17.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 1/2] fftools/ffmpeg_filter: add -autoscale to disable/enable the default scale

2019-07-28 Thread Linjie Fu
Currently, ffmpeg inserts scale filter by default in the filter graph
to force the whole decoded stream to scale into the same size with the
first frame. It's not quite make sense in resolution changing cases if
user wants the rawvideo without any scale.

Using autoscale/noautoscale to indicate whether auto inserting the scale
filter in the filter graph:
-noautoscale or -autoscale 0:
disable the default auto scale filter inserting.

Update docs.

Signed-off-by: U. Artie Eoff 
Signed-off-by: Linjie Fu 
---
 doc/ffmpeg.texi | 16 
 fftools/ffmpeg.c|  1 +
 fftools/ffmpeg.h|  4 
 fftools/ffmpeg_filter.c |  2 +-
 fftools/ffmpeg_opt.c|  8 
 5 files changed, 26 insertions(+), 5 deletions(-)

diff --git a/doc/ffmpeg.texi b/doc/ffmpeg.texi
index cd35eb4..29da951 100644
--- a/doc/ffmpeg.texi
+++ b/doc/ffmpeg.texi
@@ -734,10 +734,6 @@ ffmpeg -dump_attachment:t "" -i INPUT
 Technical note -- attachments are implemented as codec extradata, so this
 option can actually be used to extract extradata from any stream, not just
 attachments.
-
-@item -noautorotate
-Disable automatically rotating video based on file metadata.
-
 @end table
 
 @section Video Options
@@ -819,6 +815,18 @@ Create the filtergraph specified by @var{filtergraph} and 
use it to
 filter the stream.
 
 This is an alias for @code{-filter:v}, see the @ref{filter_option,,-filter 
option}.
+
+@item -autorotate
+Automatically rotate the video according to file metadata. Enabled by
+default, use @option{-noautorotate} to disable it.
+
+@item -autoscale
+Automatically scale the video according to the resolution of first frame.
+Enabled by default, use @option{-noautoscale} to disable it. When autoscale is
+disabled, all output frames of filter graph might not be in the same resolution
+and may be inadequate for some encoder/muxer. Therefore, it is not recommended
+to disable it unless you really know what you are doing.
+Disable autoscale at your own risk.
 @end table
 
 @section Advanced Video options
diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c
index 01f0410..5d52430 100644
--- a/fftools/ffmpeg.c
+++ b/fftools/ffmpeg.c
@@ -2133,6 +2133,7 @@ static int ifilter_send_frame(InputFilter *ifilter, 
AVFrame *frame)
 
 /* determine if the parameters for this input changed */
 need_reinit = ifilter->format != frame->format;
+fg->autoscale = ifilter->ist->autoscale;
 
 switch (ifilter->ist->st->codecpar->codec_type) {
 case AVMEDIA_TYPE_AUDIO:
diff --git a/fftools/ffmpeg.h b/fftools/ffmpeg.h
index 7b6f802..1602406 100644
--- a/fftools/ffmpeg.h
+++ b/fftools/ffmpeg.h
@@ -133,6 +133,8 @@ typedef struct OptionsContext {
 intnb_hwaccel_output_formats;
 SpecifierOpt *autorotate;
 intnb_autorotate;
+SpecifierOpt *autoscale;
+intnb_autoscale;
 
 /* output options */
 StreamMap *stream_maps;
@@ -285,6 +287,7 @@ typedef struct FilterGraph {
 
 AVFilterGraph *graph;
 int reconfiguration;
+int autoscale;
 
 InputFilter   **inputs;
 int  nb_inputs;
@@ -335,6 +338,7 @@ typedef struct InputStream {
 int guess_layout_max;
 
 int autorotate;
+int autoscale;
 
 int fix_sub_duration;
 struct { /* previous decoded subtitle and related variables */
diff --git a/fftools/ffmpeg_filter.c b/fftools/ffmpeg_filter.c
index 72838de..2a2eb08 100644
--- a/fftools/ffmpeg_filter.c
+++ b/fftools/ffmpeg_filter.c
@@ -469,7 +469,7 @@ static int configure_output_video_filter(FilterGraph *fg, 
OutputFilter *ofilter,
 if (ret < 0)
 return ret;
 
-if (ofilter->width || ofilter->height) {
+if ((ofilter->width || ofilter->height) && fg->autoscale) {
 char args[255];
 AVFilterContext *filter;
 AVDictionaryEntry *e = NULL;
diff --git a/fftools/ffmpeg_opt.c b/fftools/ffmpeg_opt.c
index f5ca18a..41cb676 100644
--- a/fftools/ffmpeg_opt.c
+++ b/fftools/ffmpeg_opt.c
@@ -742,7 +742,9 @@ static void add_input_streams(OptionsContext *o, 
AVFormatContext *ic)
 MATCH_PER_STREAM_OPT(ts_scale, dbl, ist->ts_scale, ic, st);
 
 ist->autorotate = 1;
+ist->autoscale  = 1;
 MATCH_PER_STREAM_OPT(autorotate, i, ist->autorotate, ic, st);
+MATCH_PER_STREAM_OPT(autoscale, i, ist->autoscale, ic, st);
 
 MATCH_PER_STREAM_OPT(codec_tags, str, codec_tag, ic, st);
 if (codec_tag) {
@@ -3640,6 +3642,12 @@ const OptionDef options[] = {
 { "autorotate",   HAS_ARG | OPT_BOOL | OPT_SPEC |
   OPT_EXPERT | OPT_INPUT,  
  { .off = OFFSET(autorotate) },
 "automatically insert correct rotate filters" },
+{ "autoscale",HAS_ARG | OPT_BOOL | OPT_SPEC |
+  OPT_EXPERT | OPT_INPUT,  
  { .off = OFFSET(autoscale) },
+

[FFmpeg-devel] [PATCH, RFC 2/2] fftools/ffmpeg: add dynamic resolution encode support for libvpx-vp9

2019-07-28 Thread Linjie Fu
According to spec, vp9 should support dynamic resolution changes.

Add dynamic resolution encoding support in libvpx-vp9, and flush
encoders when resolution change happens.

Format change should also be supported, but I didn't test it so just
leave it open.

cmdline:
ffmpeg -noautoscale -y -i ./reinit-large_420_8-to-small_420_8.h264
 -pix_fmt yuv420p -c:v libvpx-vp9 lena.ivf

Signed-off-by: Linjie Fu 
---
 fftools/ffmpeg.c   | 9 +
 libavcodec/libvpxenc.c | 9 +
 2 files changed, 18 insertions(+)

diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c
index 5d52430..e091117 100644
--- a/fftools/ffmpeg.c
+++ b/fftools/ffmpeg.c
@@ -64,6 +64,7 @@
 #include "libavutil/thread.h"
 #include "libavutil/threadmessage.h"
 #include "libavcodec/mathops.h"
+#include "libavcodec/internal.h"
 #include "libavformat/os_support.h"
 
 # include "libavfilter/avfilter.h"
@@ -130,6 +131,7 @@ static void do_video_stats(OutputStream *ost, int 
frame_size);
 static BenchmarkTimeStamps get_benchmark_time_stamps(void);
 static int64_t getmaxrss(void);
 static int ifilter_has_all_input_formats(FilterGraph *fg);
+static void flush_encoders(void);
 
 static int run_as_daemon  = 0;
 static int nb_frames_dup = 0;
@@ -1067,6 +1069,13 @@ static void do_video_out(OutputFile *of,
 InputStream *ist = NULL;
 AVFilterContext *filter = ost->filter->filter;
 
+/* flush encoders in dynamic resolution encode */
+if (next_picture && (enc->width != next_picture->width ||
+ enc->height != next_picture->height)) {
+flush_encoders();
+enc->internal->draining = 0;
+}
+
 if (ost->source_index >= 0)
 ist = input_streams[ost->source_index];
 
diff --git a/libavcodec/libvpxenc.c b/libavcodec/libvpxenc.c
index feb52ea..54ac365 100644
--- a/libavcodec/libvpxenc.c
+++ b/libavcodec/libvpxenc.c
@@ -1067,6 +1067,15 @@ static int vpx_encode(AVCodecContext *avctx, AVPacket 
*pkt,
 int res, coded_size;
 vpx_enc_frame_flags_t flags = 0;
 
+if (frame && (avctx->width != frame->width ||
+  avctx->height != frame->height)) {
+avctx->width  = frame->width;
+avctx->height = frame->height;
+
+avctx->codec->close(avctx);
+avctx->codec->init(avctx);
+}
+
 if (frame) {
 rawimg  = &ctx->rawimg;
 rawimg->planes[VPX_PLANE_Y] = frame->data[0];
-- 
2.7.4

___
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 1/4] fftools/ffmpeg_filter: add -autoscale to disable/enable the default scale

2019-07-29 Thread Linjie Fu
Currently, ffmpeg inserts scale filter by default in the filter graph
to force the whole decoded stream to scale into the same size with the
first frame. It's not quite make sense in resolution changing cases if
user wants the rawvideo without any scale.

Using autoscale/noautoscale to indicate whether auto inserting the scale
filter in the filter graph:
-noautoscale or -autoscale 0:
disable the default auto scale filter inserting.

Update docs.

Signed-off-by: U. Artie Eoff 
Signed-off-by: Linjie Fu 
---
[no update]
 doc/ffmpeg.texi | 16 
 fftools/ffmpeg.c|  1 +
 fftools/ffmpeg.h|  4 
 fftools/ffmpeg_filter.c |  2 +-
 fftools/ffmpeg_opt.c|  8 
 5 files changed, 26 insertions(+), 5 deletions(-)

diff --git a/doc/ffmpeg.texi b/doc/ffmpeg.texi
index cd35eb4..29da951 100644
--- a/doc/ffmpeg.texi
+++ b/doc/ffmpeg.texi
@@ -734,10 +734,6 @@ ffmpeg -dump_attachment:t "" -i INPUT
 Technical note -- attachments are implemented as codec extradata, so this
 option can actually be used to extract extradata from any stream, not just
 attachments.
-
-@item -noautorotate
-Disable automatically rotating video based on file metadata.
-
 @end table
 
 @section Video Options
@@ -819,6 +815,18 @@ Create the filtergraph specified by @var{filtergraph} and 
use it to
 filter the stream.
 
 This is an alias for @code{-filter:v}, see the @ref{filter_option,,-filter 
option}.
+
+@item -autorotate
+Automatically rotate the video according to file metadata. Enabled by
+default, use @option{-noautorotate} to disable it.
+
+@item -autoscale
+Automatically scale the video according to the resolution of first frame.
+Enabled by default, use @option{-noautoscale} to disable it. When autoscale is
+disabled, all output frames of filter graph might not be in the same resolution
+and may be inadequate for some encoder/muxer. Therefore, it is not recommended
+to disable it unless you really know what you are doing.
+Disable autoscale at your own risk.
 @end table
 
 @section Advanced Video options
diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c
index 01f0410..5d52430 100644
--- a/fftools/ffmpeg.c
+++ b/fftools/ffmpeg.c
@@ -2133,6 +2133,7 @@ static int ifilter_send_frame(InputFilter *ifilter, 
AVFrame *frame)
 
 /* determine if the parameters for this input changed */
 need_reinit = ifilter->format != frame->format;
+fg->autoscale = ifilter->ist->autoscale;
 
 switch (ifilter->ist->st->codecpar->codec_type) {
 case AVMEDIA_TYPE_AUDIO:
diff --git a/fftools/ffmpeg.h b/fftools/ffmpeg.h
index 7b6f802..1602406 100644
--- a/fftools/ffmpeg.h
+++ b/fftools/ffmpeg.h
@@ -133,6 +133,8 @@ typedef struct OptionsContext {
 intnb_hwaccel_output_formats;
 SpecifierOpt *autorotate;
 intnb_autorotate;
+SpecifierOpt *autoscale;
+intnb_autoscale;
 
 /* output options */
 StreamMap *stream_maps;
@@ -285,6 +287,7 @@ typedef struct FilterGraph {
 
 AVFilterGraph *graph;
 int reconfiguration;
+int autoscale;
 
 InputFilter   **inputs;
 int  nb_inputs;
@@ -335,6 +338,7 @@ typedef struct InputStream {
 int guess_layout_max;
 
 int autorotate;
+int autoscale;
 
 int fix_sub_duration;
 struct { /* previous decoded subtitle and related variables */
diff --git a/fftools/ffmpeg_filter.c b/fftools/ffmpeg_filter.c
index 72838de..2a2eb08 100644
--- a/fftools/ffmpeg_filter.c
+++ b/fftools/ffmpeg_filter.c
@@ -469,7 +469,7 @@ static int configure_output_video_filter(FilterGraph *fg, 
OutputFilter *ofilter,
 if (ret < 0)
 return ret;
 
-if (ofilter->width || ofilter->height) {
+if ((ofilter->width || ofilter->height) && fg->autoscale) {
 char args[255];
 AVFilterContext *filter;
 AVDictionaryEntry *e = NULL;
diff --git a/fftools/ffmpeg_opt.c b/fftools/ffmpeg_opt.c
index f5ca18a..41cb676 100644
--- a/fftools/ffmpeg_opt.c
+++ b/fftools/ffmpeg_opt.c
@@ -742,7 +742,9 @@ static void add_input_streams(OptionsContext *o, 
AVFormatContext *ic)
 MATCH_PER_STREAM_OPT(ts_scale, dbl, ist->ts_scale, ic, st);
 
 ist->autorotate = 1;
+ist->autoscale  = 1;
 MATCH_PER_STREAM_OPT(autorotate, i, ist->autorotate, ic, st);
+MATCH_PER_STREAM_OPT(autoscale, i, ist->autoscale, ic, st);
 
 MATCH_PER_STREAM_OPT(codec_tags, str, codec_tag, ic, st);
 if (codec_tag) {
@@ -3640,6 +3642,12 @@ const OptionDef options[] = {
 { "autorotate",   HAS_ARG | OPT_BOOL | OPT_SPEC |
   OPT_EXPERT | OPT_INPUT,  
  { .off = OFFSET(autorotate) },
 "automatically insert correct rotate filters" },
+{ "autoscale",HAS_ARG | OPT_BOOL | OPT_SPEC |
+  OPT_EXPERT | OPT_INPUT,  
  { .off = OFFSET(autoscale) },
+

[FFmpeg-devel] [PATCH 2/4] avc/avcodec: add AV_CODEC_CAP_VARIABLE_DIMENSIONS flag

2019-07-29 Thread Linjie Fu
Add AV_CODEC_CAP_VARIABLE_DIMENSIONS flag to indicate whether encoder
supports variable dimension encoding.

Signed-off-by: Linjie Fu 
---
 fftools/cmdutils.c   | 2 ++
 libavcodec/avcodec.h | 5 +
 libavcodec/rawenc.c  | 1 +
 libavcodec/version.h | 2 +-
 4 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/fftools/cmdutils.c b/fftools/cmdutils.c
index 9cfbc45..25ea1c6 100644
--- a/fftools/cmdutils.c
+++ b/fftools/cmdutils.c
@@ -1424,6 +1424,8 @@ static void print_codec(const AVCodec *c)
 printf("hardware ");
 if (c->capabilities & AV_CODEC_CAP_HYBRID)
 printf("hybrid ");
+if (c->capabilities & AV_CODEC_CAP_VARIABLE_DIMENSIONS)
+printf("multidimension ");
 if (!c->capabilities)
 printf("none");
 printf("\n");
diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
index d234271..a7704ea 100644
--- a/libavcodec/avcodec.h
+++ b/libavcodec/avcodec.h
@@ -1092,6 +1092,11 @@ typedef struct RcOverride{
 #define AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE (1 << 20)
 
 /**
+ * Codec supports variable dimensions in encoding.
+ */
+#define AV_CODEC_CAP_VARIABLE_DIMENSIONS (1 << 21)
+
+/**
  * Pan Scan area.
  * This specifies the area which should be displayed.
  * Note there may be multiple such areas for one frame.
diff --git a/libavcodec/rawenc.c b/libavcodec/rawenc.c
index d181b74..486c0d7 100644
--- a/libavcodec/rawenc.c
+++ b/libavcodec/rawenc.c
@@ -92,4 +92,5 @@ AVCodec ff_rawvideo_encoder = {
 .id = AV_CODEC_ID_RAWVIDEO,
 .init   = raw_encode_init,
 .encode2= raw_encode,
+.capabilities   = AV_CODEC_CAP_VARIABLE_DIMENSIONS,
 };
diff --git a/libavcodec/version.h b/libavcodec/version.h
index 43c8cdb..e70ebc0 100644
--- a/libavcodec/version.h
+++ b/libavcodec/version.h
@@ -29,7 +29,7 @@
 
 #define LIBAVCODEC_VERSION_MAJOR  58
 #define LIBAVCODEC_VERSION_MINOR  55
-#define LIBAVCODEC_VERSION_MICRO 100
+#define LIBAVCODEC_VERSION_MICRO 101
 
 #define LIBAVCODEC_VERSION_INT  AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
LIBAVCODEC_VERSION_MINOR, \
-- 
2.7.4

___
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] fftools/ffmpeg: support variable dimension encode

2019-07-29 Thread Linjie Fu
Flush encoders when dimension change happens, reset draining to resume
encode.

If encoder doesn't support variable dimension, stop encoding and
report errors.

Signed-off-by: Linjie Fu 
---
 fftools/ffmpeg.c| 13 +
 libavcodec/encode.c |  4 
 2 files changed, 17 insertions(+)

diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c
index 5d52430..8ceeaaa 100644
--- a/fftools/ffmpeg.c
+++ b/fftools/ffmpeg.c
@@ -130,6 +130,7 @@ static void do_video_stats(OutputStream *ost, int 
frame_size);
 static BenchmarkTimeStamps get_benchmark_time_stamps(void);
 static int64_t getmaxrss(void);
 static int ifilter_has_all_input_formats(FilterGraph *fg);
+static void flush_encoders(void);
 
 static int run_as_daemon  = 0;
 static int nb_frames_dup = 0;
@@ -1067,6 +1068,18 @@ static void do_video_out(OutputFile *of,
 InputStream *ist = NULL;
 AVFilterContext *filter = ost->filter->filter;
 
+/* flush encoders in dynamic resolution encode */
+if (next_picture && (enc->width != next_picture->width ||
+ enc->height != next_picture->height)) {
+flush_encoders();
+
+if (!(enc->codec->capabilities & AV_CODEC_CAP_VARIABLE_DIMENSIONS)) {
+av_log(NULL, AV_LOG_ERROR, "Dynamic resolution encode "
+"is not supported by %s.\n", enc->codec->name);
+goto error;
+}
+}
+
 if (ost->source_index >= 0)
 ist = input_streams[ost->source_index];
 
diff --git a/libavcodec/encode.c b/libavcodec/encode.c
index d12c425..9303bc9 100644
--- a/libavcodec/encode.c
+++ b/libavcodec/encode.c
@@ -389,6 +389,10 @@ int attribute_align_arg avcodec_send_frame(AVCodecContext 
*avctx, const AVFrame
 if (!avcodec_is_open(avctx) || !av_codec_is_encoder(avctx->codec))
 return AVERROR(EINVAL);
 
+/* reset draining when encoder is flushed in variable dimensions encoding 
*/
+if (frame)
+avctx->internal->draining = 0;
+
 if (avctx->internal->draining)
 return AVERROR_EOF;
 
-- 
2.7.4

___
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] lavc/libvpxenc: add dynamic resolution encode support for libvpx

2019-07-29 Thread Linjie Fu
According to spec, libvpx should support dynamic resolution changes.

Add dynamic resolution encoding support in libvpx.

Format change should also be supported, but I didn't test it so just
leave it open.

cmdline:
ffmpeg -noautoscale -y -i ./reinit-large_420_8-to-small_420_8.h264
 -pix_fmt yuv420p -c:v libvpx-vp9 lena.ivf

Signed-off-by: Linjie Fu 
---
 libavcodec/libvpxenc.c | 13 +++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/libavcodec/libvpxenc.c b/libavcodec/libvpxenc.c
index feb52ea..6af6c50 100644
--- a/libavcodec/libvpxenc.c
+++ b/libavcodec/libvpxenc.c
@@ -1067,6 +1067,15 @@ static int vpx_encode(AVCodecContext *avctx, AVPacket 
*pkt,
 int res, coded_size;
 vpx_enc_frame_flags_t flags = 0;
 
+if (frame && (avctx->width != frame->width ||
+  avctx->height != frame->height)) {
+avctx->width  = frame->width;
+avctx->height = frame->height;
+
+avctx->codec->close(avctx);
+avctx->codec->init(avctx);
+}
+
 if (frame) {
 rawimg  = &ctx->rawimg;
 rawimg->planes[VPX_PLANE_Y] = frame->data[0];
@@ -1295,7 +1304,7 @@ AVCodec ff_libvpx_vp8_encoder = {
 .init   = vp8_init,
 .encode2= vpx_encode,
 .close  = vpx_free,
-.capabilities   = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_AUTO_THREADS,
+.capabilities   = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_AUTO_THREADS | 
AV_CODEC_CAP_VARIABLE_DIMENSIONS,
 .pix_fmts   = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUV420P, 
AV_PIX_FMT_YUVA420P, AV_PIX_FMT_NONE },
 .priv_class = &class_vp8,
 .defaults   = defaults,
@@ -1325,7 +1334,7 @@ AVCodec ff_libvpx_vp9_encoder = {
 .init   = vp9_init,
 .encode2= vpx_encode,
 .close  = vpx_free,
-.capabilities   = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_AUTO_THREADS,
+.capabilities   = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_AUTO_THREADS | 
AV_CODEC_CAP_VARIABLE_DIMENSIONS,
 .profiles   = NULL_IF_CONFIG_SMALL(ff_vp9_profiles),
 .priv_class = &class_vp9,
 .defaults   = defaults,
-- 
2.7.4

___
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/4] avc/avcodec: add AV_CODEC_CAP_VARIABLE_DIMENSIONS flag

2019-07-29 Thread Linjie Fu
Add AV_CODEC_CAP_VARIABLE_DIMENSIONS flag to indicate whether encoder
supports variable dimension encoding.

Signed-off-by: Linjie Fu 
---
[v2]: update API changes.
 doc/APIchanges   | 3 +++
 fftools/cmdutils.c   | 2 ++
 libavcodec/avcodec.h | 5 +
 libavcodec/rawenc.c  | 1 +
 libavcodec/version.h | 2 +-
 5 files changed, 12 insertions(+), 1 deletion(-)

diff --git a/doc/APIchanges b/doc/APIchanges
index 07331b1..2e855f2 100644
--- a/doc/APIchanges
+++ b/doc/APIchanges
@@ -15,6 +15,9 @@ libavutil: 2017-10-21
 
 API changes, most recent first:
 
+2019-07-xx - xx - lavc 58.55.101 - avcodec.h
+  Add AV_CODEC_CAP_VARIABLE_DIMENSIONS
+
  8< - FFmpeg 4.2 was cut here  8< -
 
 2019-06-21 - a30e44098a - lavu 56.30.100 - frame.h
diff --git a/fftools/cmdutils.c b/fftools/cmdutils.c
index 9cfbc45..25ea1c6 100644
--- a/fftools/cmdutils.c
+++ b/fftools/cmdutils.c
@@ -1424,6 +1424,8 @@ static void print_codec(const AVCodec *c)
 printf("hardware ");
 if (c->capabilities & AV_CODEC_CAP_HYBRID)
 printf("hybrid ");
+if (c->capabilities & AV_CODEC_CAP_VARIABLE_DIMENSIONS)
+printf("multidimension ");
 if (!c->capabilities)
 printf("none");
 printf("\n");
diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
index d234271..a7704ea 100644
--- a/libavcodec/avcodec.h
+++ b/libavcodec/avcodec.h
@@ -1092,6 +1092,11 @@ typedef struct RcOverride{
 #define AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE (1 << 20)
 
 /**
+ * Codec supports variable dimensions in encoding.
+ */
+#define AV_CODEC_CAP_VARIABLE_DIMENSIONS (1 << 21)
+
+/**
  * Pan Scan area.
  * This specifies the area which should be displayed.
  * Note there may be multiple such areas for one frame.
diff --git a/libavcodec/rawenc.c b/libavcodec/rawenc.c
index d181b74..486c0d7 100644
--- a/libavcodec/rawenc.c
+++ b/libavcodec/rawenc.c
@@ -92,4 +92,5 @@ AVCodec ff_rawvideo_encoder = {
 .id = AV_CODEC_ID_RAWVIDEO,
 .init   = raw_encode_init,
 .encode2= raw_encode,
+.capabilities   = AV_CODEC_CAP_VARIABLE_DIMENSIONS,
 };
diff --git a/libavcodec/version.h b/libavcodec/version.h
index 43c8cdb..e70ebc0 100644
--- a/libavcodec/version.h
+++ b/libavcodec/version.h
@@ -29,7 +29,7 @@
 
 #define LIBAVCODEC_VERSION_MAJOR  58
 #define LIBAVCODEC_VERSION_MINOR  55
-#define LIBAVCODEC_VERSION_MICRO 100
+#define LIBAVCODEC_VERSION_MICRO 101
 
 #define LIBAVCODEC_VERSION_INT  AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
LIBAVCODEC_VERSION_MINOR, \
-- 
2.7.4

___
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/4] fftools/ffmpeg: support variable dimension encode

2019-07-29 Thread Linjie Fu
Flush encoders when dimension change happens.

Signed-off-by: Linjie Fu 
---
 fftools/ffmpeg.c | 14 ++
 1 file changed, 14 insertions(+)

diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c
index 5d52430..cb3adb2 100644
--- a/fftools/ffmpeg.c
+++ b/fftools/ffmpeg.c
@@ -130,6 +130,7 @@ static void do_video_stats(OutputStream *ost, int 
frame_size);
 static BenchmarkTimeStamps get_benchmark_time_stamps(void);
 static int64_t getmaxrss(void);
 static int ifilter_has_all_input_formats(FilterGraph *fg);
+static void flush_encoders(void);
 
 static int run_as_daemon  = 0;
 static int nb_frames_dup = 0;
@@ -1067,6 +1068,19 @@ static void do_video_out(OutputFile *of,
 InputStream *ist = NULL;
 AVFilterContext *filter = ost->filter->filter;
 
+/* flush encoders in dynamic resolution encode */
+if (next_picture && (enc->width != next_picture->width ||
+ enc->height != next_picture->height)) {
+flush_encoders();
+avcodec_flush_buffers(enc);
+
+if (!(enc->codec->capabilities & AV_CODEC_CAP_VARIABLE_DIMENSIONS)) {
+av_log(NULL, AV_LOG_ERROR, "Dynamic resolution encode "
+"is not supported by %s.\n", enc->codec->name);
+goto error;
+}
+}
+
 if (ost->source_index >= 0)
 ist = input_streams[ost->source_index];
 
-- 
2.7.4

___
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 1/3] fftools/ffmpeg_filter: add -autoscale to disable/enable the default scale

2019-07-30 Thread Linjie Fu
Currently, ffmpeg inserts scale filter by default in the filter graph
to force the whole decoded stream to scale into the same size with the
first frame. It's not quite make sense in resolution changing cases if
user wants the rawvideo without any scale.

Using autoscale/noautoscale to indicate whether auto inserting the scale
filter in the filter graph:
-noautoscale or -autoscale 0:
disable the default auto scale filter inserting.

Update docs.

Signed-off-by: U. Artie Eoff 
Signed-off-by: Linjie Fu 
---
[no updates]
 doc/ffmpeg.texi | 16 
 fftools/ffmpeg.c|  1 +
 fftools/ffmpeg.h|  4 
 fftools/ffmpeg_filter.c |  2 +-
 fftools/ffmpeg_opt.c|  8 
 5 files changed, 26 insertions(+), 5 deletions(-)

diff --git a/doc/ffmpeg.texi b/doc/ffmpeg.texi
index cd35eb4..29da951 100644
--- a/doc/ffmpeg.texi
+++ b/doc/ffmpeg.texi
@@ -734,10 +734,6 @@ ffmpeg -dump_attachment:t "" -i INPUT
 Technical note -- attachments are implemented as codec extradata, so this
 option can actually be used to extract extradata from any stream, not just
 attachments.
-
-@item -noautorotate
-Disable automatically rotating video based on file metadata.
-
 @end table
 
 @section Video Options
@@ -819,6 +815,18 @@ Create the filtergraph specified by @var{filtergraph} and 
use it to
 filter the stream.
 
 This is an alias for @code{-filter:v}, see the @ref{filter_option,,-filter 
option}.
+
+@item -autorotate
+Automatically rotate the video according to file metadata. Enabled by
+default, use @option{-noautorotate} to disable it.
+
+@item -autoscale
+Automatically scale the video according to the resolution of first frame.
+Enabled by default, use @option{-noautoscale} to disable it. When autoscale is
+disabled, all output frames of filter graph might not be in the same resolution
+and may be inadequate for some encoder/muxer. Therefore, it is not recommended
+to disable it unless you really know what you are doing.
+Disable autoscale at your own risk.
 @end table
 
 @section Advanced Video options
diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c
index 01f0410..5d52430 100644
--- a/fftools/ffmpeg.c
+++ b/fftools/ffmpeg.c
@@ -2133,6 +2133,7 @@ static int ifilter_send_frame(InputFilter *ifilter, 
AVFrame *frame)
 
 /* determine if the parameters for this input changed */
 need_reinit = ifilter->format != frame->format;
+fg->autoscale = ifilter->ist->autoscale;
 
 switch (ifilter->ist->st->codecpar->codec_type) {
 case AVMEDIA_TYPE_AUDIO:
diff --git a/fftools/ffmpeg.h b/fftools/ffmpeg.h
index 7b6f802..1602406 100644
--- a/fftools/ffmpeg.h
+++ b/fftools/ffmpeg.h
@@ -133,6 +133,8 @@ typedef struct OptionsContext {
 intnb_hwaccel_output_formats;
 SpecifierOpt *autorotate;
 intnb_autorotate;
+SpecifierOpt *autoscale;
+intnb_autoscale;
 
 /* output options */
 StreamMap *stream_maps;
@@ -285,6 +287,7 @@ typedef struct FilterGraph {
 
 AVFilterGraph *graph;
 int reconfiguration;
+int autoscale;
 
 InputFilter   **inputs;
 int  nb_inputs;
@@ -335,6 +338,7 @@ typedef struct InputStream {
 int guess_layout_max;
 
 int autorotate;
+int autoscale;
 
 int fix_sub_duration;
 struct { /* previous decoded subtitle and related variables */
diff --git a/fftools/ffmpeg_filter.c b/fftools/ffmpeg_filter.c
index 72838de..2a2eb08 100644
--- a/fftools/ffmpeg_filter.c
+++ b/fftools/ffmpeg_filter.c
@@ -469,7 +469,7 @@ static int configure_output_video_filter(FilterGraph *fg, 
OutputFilter *ofilter,
 if (ret < 0)
 return ret;
 
-if (ofilter->width || ofilter->height) {
+if ((ofilter->width || ofilter->height) && fg->autoscale) {
 char args[255];
 AVFilterContext *filter;
 AVDictionaryEntry *e = NULL;
diff --git a/fftools/ffmpeg_opt.c b/fftools/ffmpeg_opt.c
index f5ca18a..41cb676 100644
--- a/fftools/ffmpeg_opt.c
+++ b/fftools/ffmpeg_opt.c
@@ -742,7 +742,9 @@ static void add_input_streams(OptionsContext *o, 
AVFormatContext *ic)
 MATCH_PER_STREAM_OPT(ts_scale, dbl, ist->ts_scale, ic, st);
 
 ist->autorotate = 1;
+ist->autoscale  = 1;
 MATCH_PER_STREAM_OPT(autorotate, i, ist->autorotate, ic, st);
+MATCH_PER_STREAM_OPT(autoscale, i, ist->autoscale, ic, st);
 
 MATCH_PER_STREAM_OPT(codec_tags, str, codec_tag, ic, st);
 if (codec_tag) {
@@ -3640,6 +3642,12 @@ const OptionDef options[] = {
 { "autorotate",   HAS_ARG | OPT_BOOL | OPT_SPEC |
   OPT_EXPERT | OPT_INPUT,  
  { .off = OFFSET(autorotate) },
 "automatically insert correct rotate filters" },
+{ "autoscale",HAS_ARG | OPT_BOOL | OPT_SPEC |
+  OPT_EXPERT | OPT_INPUT,  
  { .off = OFFSET(autoscale) },
+

[FFmpeg-devel] [PATCH, v2 3/3] lavc/libvpxenc: add dynamic resolution encode support for libvpx

2019-07-30 Thread Linjie Fu
According to spec, libvpx should support dynamic resolution changes.

Add dynamic resolution encoding support in libvpx.

Format change should also be supported, but I didn't test it so just
leave it open.

cmdline:
ffmpeg -noautoscale -y -i ./reinit-large_420_8-to-small_420_8.h264
 -pix_fmt yuv420p -c:v libvpx-vp9 lena.ivf

Signed-off-by: Linjie Fu 
---
[v2]: use AV_CODEC_CAP_PARAM_CHANGE flag.

 libavcodec/libvpxenc.c | 13 +++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/libavcodec/libvpxenc.c b/libavcodec/libvpxenc.c
index feb52ea..800ba18 100644
--- a/libavcodec/libvpxenc.c
+++ b/libavcodec/libvpxenc.c
@@ -1067,6 +1067,15 @@ static int vpx_encode(AVCodecContext *avctx, AVPacket 
*pkt,
 int res, coded_size;
 vpx_enc_frame_flags_t flags = 0;
 
+if (frame && (avctx->width != frame->width ||
+  avctx->height != frame->height)) {
+avctx->width  = frame->width;
+avctx->height = frame->height;
+
+avctx->codec->close(avctx);
+avctx->codec->init(avctx);
+}
+
 if (frame) {
 rawimg  = &ctx->rawimg;
 rawimg->planes[VPX_PLANE_Y] = frame->data[0];
@@ -1295,7 +1304,7 @@ AVCodec ff_libvpx_vp8_encoder = {
 .init   = vp8_init,
 .encode2= vpx_encode,
 .close  = vpx_free,
-.capabilities   = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_AUTO_THREADS,
+.capabilities   = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_AUTO_THREADS | 
AV_CODEC_CAP_PARAM_CHANGE,
 .pix_fmts   = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUV420P, 
AV_PIX_FMT_YUVA420P, AV_PIX_FMT_NONE },
 .priv_class = &class_vp8,
 .defaults   = defaults,
@@ -1325,7 +1334,7 @@ AVCodec ff_libvpx_vp9_encoder = {
 .init   = vp9_init,
 .encode2= vpx_encode,
 .close  = vpx_free,
-.capabilities   = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_AUTO_THREADS,
+.capabilities   = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_AUTO_THREADS | 
AV_CODEC_CAP_PARAM_CHANGE,
 .profiles   = NULL_IF_CONFIG_SMALL(ff_vp9_profiles),
 .priv_class = &class_vp9,
 .defaults   = defaults,
-- 
2.7.4

___
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/3] fftools/ffmpeg: support variable resolution encode

2019-07-30 Thread Linjie Fu
Flush encoders when resolution change happens.

Use AV_CODEC_CAP_PARAM_CHANGE flag for encoder to indicate whether
it supports variable/dynamic resolution encoding.

Signed-off-by: Linjie Fu 
---
[v3]: use AV_CODEC_CAP_PARAM_CHANGE flag
 fftools/ffmpeg.c| 14 ++
 libavcodec/rawenc.c |  1 +
 2 files changed, 15 insertions(+)

diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c
index 5d52430..35b0f89 100644
--- a/fftools/ffmpeg.c
+++ b/fftools/ffmpeg.c
@@ -130,6 +130,7 @@ static void do_video_stats(OutputStream *ost, int 
frame_size);
 static BenchmarkTimeStamps get_benchmark_time_stamps(void);
 static int64_t getmaxrss(void);
 static int ifilter_has_all_input_formats(FilterGraph *fg);
+static void flush_encoders(void);
 
 static int run_as_daemon  = 0;
 static int nb_frames_dup = 0;
@@ -1067,6 +1068,19 @@ static void do_video_out(OutputFile *of,
 InputStream *ist = NULL;
 AVFilterContext *filter = ost->filter->filter;
 
+/* flush encoders in dynamic resolution encode */
+if (next_picture && (enc->width != next_picture->width ||
+ enc->height != next_picture->height)) {
+flush_encoders();
+avcodec_flush_buffers(enc);
+
+if (!(enc->codec->capabilities & AV_CODEC_CAP_PARAM_CHANGE)) {
+av_log(NULL, AV_LOG_ERROR, "Dynamic resolution encode "
+"is not supported by %s.\n", enc->codec->name);
+goto error;
+}
+}
+
 if (ost->source_index >= 0)
 ist = input_streams[ost->source_index];
 
diff --git a/libavcodec/rawenc.c b/libavcodec/rawenc.c
index d181b74..9e8cb57 100644
--- a/libavcodec/rawenc.c
+++ b/libavcodec/rawenc.c
@@ -92,4 +92,5 @@ AVCodec ff_rawvideo_encoder = {
 .id = AV_CODEC_ID_RAWVIDEO,
 .init   = raw_encode_init,
 .encode2= raw_encode,
+.capabilities   = AV_CODEC_CAP_PARAM_CHANGE,
 };
-- 
2.7.4

___
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] lavu/hwcontext_vaapi: cope with race map for YUV420P

2019-07-31 Thread Linjie Fu
There is a race condition for AV_PIX_FMT_YUV420P when mapping from pix_fmt
to fourcc, both VA_FOURCC_I420 and VA_FOURCC_YV12 could be find by pix_fmt.

Currently, vaapi_get_image_format will go through the query results of
pix_fmt and returned the first matched result according to the declared
order in driver.This may leads to a wrong image_format.

Modify to find image_format via fourcc.

Fix vaapi CSC to I420:
ffmpeg -hwaccel vaapi -vaapi_device /dev/dri/renderD128 -f rawvideo
-pix_fmt nv12 -s:v 1280x720 -i NV12.yuv -vf
'format=nv12,hwupload,scale_vaapi=format=yuv420p,hwdownload,format=yuv420p'
-f rawvideo -vsync passthrough -vframes 10 -y aa.yuv

Signed-off-by: Linjie Fu 
---
 libavutil/hwcontext_vaapi.c | 14 +++---
 1 file changed, 11 insertions(+), 3 deletions(-)

diff --git a/libavutil/hwcontext_vaapi.c b/libavutil/hwcontext_vaapi.c
index cf11764..64f14de 100644
--- a/libavutil/hwcontext_vaapi.c
+++ b/libavutil/hwcontext_vaapi.c
@@ -63,6 +63,7 @@ typedef struct VAAPIDevicePriv {
 typedef struct VAAPISurfaceFormat {
 enum AVPixelFormat pix_fmt;
 VAImageFormat image_format;
+unsigned int fourcc;
 } VAAPISurfaceFormat;
 
 typedef struct VAAPIDeviceContext {
@@ -171,15 +172,21 @@ static int vaapi_get_image_format(AVHWDeviceContext 
*hwdev,
   VAImageFormat **image_format)
 {
 VAAPIDeviceContext *ctx = hwdev->internal->priv;
+VAAPIFormatDescriptor *desc;
 int i;
 
+desc = vaapi_format_from_pix_fmt(pix_fmt);
+if (!desc || !image_format)
+goto fail;
+
 for (i = 0; i < ctx->nb_formats; i++) {
-if (ctx->formats[i].pix_fmt == pix_fmt) {
-if (image_format)
-*image_format = &ctx->formats[i].image_format;
+if (ctx->formats[i].fourcc == desc->fourcc) {
+*image_format = &ctx->formats[i].image_format;
 return 0;
 }
 }
+
+fail:
 return AVERROR(EINVAL);
 }
 
@@ -368,6 +375,7 @@ static int vaapi_device_init(AVHWDeviceContext *hwdev)
 av_log(hwdev, AV_LOG_DEBUG, "Format %#x -> %s.\n",
fourcc, av_get_pix_fmt_name(pix_fmt));
 ctx->formats[ctx->nb_formats].pix_fmt  = pix_fmt;
+ctx->formats[ctx->nb_formats].fourcc   = fourcc;
 ctx->formats[ctx->nb_formats].image_format = image_list[i];
 ++ctx->nb_formats;
 }
-- 
2.7.4

___
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] lavf/vf_deinterlace_vaapi: flush queued frame in field mode

2019-08-02 Thread Linjie Fu
Add deint_vaapi_request_frame for deinterlace_vaapi, send NULL frame
to flush the queued frame.

Fix the frame drop issue in field mode:

ffmpeg -hwaccel vaapi -vaapi_device /dev/dri/renderD128 -v verbose -c:v
h264 -i ./input.h264 -vf 'format=nv12|vaapi,hwupload,
deinterlace_vaapi=mode=bob:rate=field,hwdownload,format=nv12'
-pix_fmt yuv420p -f rawvideo -vsync passthrough -y dump.yuv

Signed-off-by: Linjie Fu 
---
 libavfilter/vf_deinterlace_vaapi.c | 46 --
 1 file changed, 39 insertions(+), 7 deletions(-)

diff --git a/libavfilter/vf_deinterlace_vaapi.c 
b/libavfilter/vf_deinterlace_vaapi.c
index 72d0349..c811327 100644
--- a/libavfilter/vf_deinterlace_vaapi.c
+++ b/libavfilter/vf_deinterlace_vaapi.c
@@ -48,6 +48,9 @@ typedef struct DeintVAAPIContext {
 intqueue_count;
 AVFrame   *frame_queue[MAX_REFERENCES];
 intextra_delay_for_timestamps;
+
+inteof;
+intprev_pts;
 } DeintVAAPIContext;
 
 static const char *deint_vaapi_mode_name(int mode)
@@ -190,11 +193,16 @@ static int deint_vaapi_filter_frame(AVFilterLink *inlink, 
AVFrame *input_frame)
 void *filter_params_addr = NULL;
 int err, i, field, current_frame_index;
 
-av_log(avctx, AV_LOG_DEBUG, "Filter input: %s, %ux%u (%"PRId64").\n",
-   av_get_pix_fmt_name(input_frame->format),
-   input_frame->width, input_frame->height, input_frame->pts);
+// NULL frame is used to flush the queue in field mode
+if (input_frame)
+av_log(avctx, AV_LOG_DEBUG, "Filter input: %s, %ux%u (%"PRId64").\n",
+av_get_pix_fmt_name(input_frame->format),
+input_frame->width, input_frame->height, input_frame->pts);
+else if (ctx->field_rate == 1) {
+return 0;
+}
 
-if (ctx->queue_count < ctx->queue_depth) {
+if (input_frame && ctx->queue_count < ctx->queue_depth) {
 ctx->frame_queue[ctx->queue_count++] = input_frame;
 if (ctx->queue_count < ctx->queue_depth) {
 // Need more reference surfaces before we can continue.
@@ -291,6 +299,8 @@ static int deint_vaapi_filter_frame(AVFilterLink *inlink, 
AVFrame *input_frame)
 if (ctx->field_rate == 2) {
 if (field == 0)
 output_frame->pts = 2 * input_frame->pts;
+else if (ctx->eof)
+output_frame->pts = 3 * input_frame->pts - ctx->prev_pts;
 else
 output_frame->pts = input_frame->pts +
 ctx->frame_queue[current_frame_index + 1]->pts;
@@ -306,6 +316,8 @@ static int deint_vaapi_filter_frame(AVFilterLink *inlink, 
AVFrame *input_frame)
 break;
 }
 
+ctx->prev_pts = input_frame->pts;
+
 return err;
 
 fail:
@@ -315,6 +327,25 @@ fail:
 return err;
 }
 
+static int deint_vaapi_request_frame(AVFilterLink *link)
+{
+AVFilterContext *avctx = link->src;
+DeintVAAPIContext *ctx   = avctx->priv;
+int ret;
+
+if (ctx->eof)
+return AVERROR_EOF;
+
+ret = ff_request_frame(link->src->inputs[0]);
+if (ret == AVERROR_EOF) {
+ctx->eof = 1;
+deint_vaapi_filter_frame(link->src->inputs[0], NULL);
+} else if (ret < 0)
+return ret;
+
+return 0;
+}
+
 static av_cold int deint_vaapi_init(AVFilterContext *avctx)
 {
 VAAPIVPPContext *vpp_ctx = avctx->priv;
@@ -376,9 +407,10 @@ static const AVFilterPad deint_vaapi_inputs[] = {
 
 static const AVFilterPad deint_vaapi_outputs[] = {
 {
-.name = "default",
-.type = AVMEDIA_TYPE_VIDEO,
-.config_props = &deint_vaapi_config_output,
+.name   = "default",
+.type   = AVMEDIA_TYPE_VIDEO,
+.request_frame  = &deint_vaapi_request_frame,
+.config_props   = &deint_vaapi_config_output,
 },
 { NULL }
 };
-- 
2.7.4

___
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, RFC, v2 3/3] lavc/libvpxenc: add dynamic resolution encode support for libvpx

2019-08-13 Thread Linjie Fu
According to spec, libvpx should support dynamic resolution changes.

Add dynamic resolution encoding support in libvpx.

Only single pass mode with no look ahead is supported for variable
resolution encoding without initialization.

cmdline:
ffmpeg -noautoscale -y -i ./reinit-large_420_8-to-small_420_8.h264
 -pix_fmt yuv420p -c:v libvpx-vp9 lena.ivf

Filed an issue in https://bugs.chromium.org/p/webm/issues/detail?id=1642
to fix some memory problem.

Signed-off-by: Linjie Fu 
---
 libavcodec/libvpxenc.c | 24 
 1 file changed, 24 insertions(+)

diff --git a/libavcodec/libvpxenc.c b/libavcodec/libvpxenc.c
index feb52ea..3d2295d 100644
--- a/libavcodec/libvpxenc.c
+++ b/libavcodec/libvpxenc.c
@@ -1067,6 +1067,28 @@ static int vpx_encode(AVCodecContext *avctx, AVPacket 
*pkt,
 int res, coded_size;
 vpx_enc_frame_flags_t flags = 0;
 
+if (frame && (avctx->width != frame->width ||
+  avctx->height != frame->height)) {
+avctx->width  = frame->width;
+avctx->height = frame->height;
+
+struct vpx_codec_enc_cfg new_cfg = { 0 };
+memcpy(&new_cfg, ctx->encoder.config.enc,
+sizeof(struct vpx_codec_enc_cfg));
+
+new_cfg.g_w = frame->width;
+new_cfg.g_h = frame->height;
+if (new_cfg.g_lag_in_frames > 1 ||
+new_cfg.g_pass != VPX_RC_ONE_PASS) {
+av_log(avctx, AV_LOG_WARNING, "Only single pass mode "
+   "with no look ahead is supported for variable "
+   "resolution encoding without initialization.\n");
+new_cfg.g_pass  = VPX_RC_ONE_PASS;
+new_cfg.g_lag_in_frames = 0;
+}
+vpx_codec_enc_config_set(&ctx->encoder, &new_cfg);
+}
+
 if (frame) {
 rawimg  = &ctx->rawimg;
 rawimg->planes[VPX_PLANE_Y] = frame->data[0];
@@ -1075,6 +1097,8 @@ static int vpx_encode(AVCodecContext *avctx, AVPacket 
*pkt,
 rawimg->stride[VPX_PLANE_Y] = frame->linesize[0];
 rawimg->stride[VPX_PLANE_U] = frame->linesize[1];
 rawimg->stride[VPX_PLANE_V] = frame->linesize[2];
+rawimg->d_w = frame->width;
+rawimg->d_h = frame->height;
 if (ctx->is_alpha) {
 uint8_t *u_plane, *v_plane;
 rawimg_alpha = &ctx->rawimg_alpha;
-- 
2.7.4

___
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] lavu/hwcontext_vaapi: provide detailed warning if directly mapping fails

2019-08-14 Thread Linjie Fu
Detailed message could be helpful when using hwmap=mode=direct,format=xxx
for both qsv and vaapi.

Signed-off-by: Linjie Fu 
---
 libavutil/hwcontext_vaapi.c | 9 ++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/libavutil/hwcontext_vaapi.c b/libavutil/hwcontext_vaapi.c
index cf117640f2..30c42e4385 100644
--- a/libavutil/hwcontext_vaapi.c
+++ b/libavutil/hwcontext_vaapi.c
@@ -747,19 +747,22 @@ static int vaapi_map_frame(AVHWFramesContext *hwfc,
 av_log(hwfc, AV_LOG_DEBUG, "Map surface %#x.\n", surface_id);
 
 if (!ctx->derive_works && (flags & AV_HWFRAME_MAP_DIRECT)) {
-// Requested direct mapping but it is not possible.
+av_log(hwfc, AV_LOG_WARNING, "Requested direct mapping but "
+"it is not possible.\n");
 return AVERROR(EINVAL);
 }
 if (dst->format == AV_PIX_FMT_NONE)
 dst->format = hwfc->sw_format;
 if (dst->format != hwfc->sw_format && (flags & AV_HWFRAME_MAP_DIRECT)) {
-// Requested direct mapping but the formats do not match.
+av_log(hwfc, AV_LOG_WARNING, "Requested direct mapping but "
+"the formats do not match.\n");
 return AVERROR(EINVAL);
 }
 
 err = vaapi_get_image_format(hwfc->device_ctx, dst->format, &image_format);
 if (err < 0) {
-// Requested format is not a valid output format.
+av_log(hwfc, AV_LOG_WARNING, "Requested format is "
+"not a valid output format.\n");
 return AVERROR(EINVAL);
 }
 
-- 
2.17.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] lavu/hwcontext_vaapi: provide detailed error msg if directly mapping fails

2019-08-14 Thread Linjie Fu
Detailed message could be helpful when using hwmap=mode=direct,format=xxx
for both qsv and vaapi.

Signed-off-by: Linjie Fu 
---
 libavutil/hwcontext_vaapi.c | 9 ++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/libavutil/hwcontext_vaapi.c b/libavutil/hwcontext_vaapi.c
index cf117640f2..3fbeb4954e 100644
--- a/libavutil/hwcontext_vaapi.c
+++ b/libavutil/hwcontext_vaapi.c
@@ -747,19 +747,22 @@ static int vaapi_map_frame(AVHWFramesContext *hwfc,
 av_log(hwfc, AV_LOG_DEBUG, "Map surface %#x.\n", surface_id);
 
 if (!ctx->derive_works && (flags & AV_HWFRAME_MAP_DIRECT)) {
-// Requested direct mapping but it is not possible.
+av_log(hwfc, AV_LOG_ERROR, "Requested direct mapping but "
+"it is not possible.\n");
 return AVERROR(EINVAL);
 }
 if (dst->format == AV_PIX_FMT_NONE)
 dst->format = hwfc->sw_format;
 if (dst->format != hwfc->sw_format && (flags & AV_HWFRAME_MAP_DIRECT)) {
-// Requested direct mapping but the formats do not match.
+av_log(hwfc, AV_LOG_ERROR, "Requested direct mapping but "
+"the formats do not match.\n");
 return AVERROR(EINVAL);
 }
 
 err = vaapi_get_image_format(hwfc->device_ctx, dst->format, &image_format);
 if (err < 0) {
-// Requested format is not a valid output format.
+av_log(hwfc, AV_LOG_ERROR, "Requested format is "
+"not a valid output format.\n");
 return AVERROR(EINVAL);
 }
 
-- 
2.17.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/2] lavu/hwcontext_vaapi: cope with race map for YUV420P

2019-08-14 Thread Linjie Fu
There is a race condition for AV_PIX_FMT_YUV420P when mapping from pix_fmt
to fourcc, both VA_FOURCC_I420 and VA_FOURCC_YV12 could be found by pix_fmt.

Currently, vaapi_get_image_format will go through the query results of
pix_fmt and returned the first matched result according to the declared
order in driver.This may leads to a wrong image_format.

Modify to find image_format via fourcc.

Fix vaapi CSC to I420:
ffmpeg -hwaccel vaapi -vaapi_device /dev/dri/renderD128 -f rawvideo
-pix_fmt nv12 -s:v 1280x720 -i NV12.yuv -vf
'format=nv12,hwupload,scale_vaapi=format=yuv420p,hwdownload,format=yuv420p'
-f rawvideo -vsync passthrough -vframes 10 -y aa.yuv

Reviewed-by: Zhong Li 
Signed-off-by: Linjie Fu 
---
 libavutil/hwcontext_vaapi.c | 14 +++---
 1 file changed, 11 insertions(+), 3 deletions(-)

diff --git a/libavutil/hwcontext_vaapi.c b/libavutil/hwcontext_vaapi.c
index cf11764..64f14de 100644
--- a/libavutil/hwcontext_vaapi.c
+++ b/libavutil/hwcontext_vaapi.c
@@ -63,6 +63,7 @@ typedef struct VAAPIDevicePriv {
 typedef struct VAAPISurfaceFormat {
 enum AVPixelFormat pix_fmt;
 VAImageFormat image_format;
+unsigned int fourcc;
 } VAAPISurfaceFormat;
 
 typedef struct VAAPIDeviceContext {
@@ -171,15 +172,21 @@ static int vaapi_get_image_format(AVHWDeviceContext 
*hwdev,
   VAImageFormat **image_format)
 {
 VAAPIDeviceContext *ctx = hwdev->internal->priv;
+VAAPIFormatDescriptor *desc;
 int i;
 
+desc = vaapi_format_from_pix_fmt(pix_fmt);
+if (!desc || !image_format)
+goto fail;
+
 for (i = 0; i < ctx->nb_formats; i++) {
-if (ctx->formats[i].pix_fmt == pix_fmt) {
-if (image_format)
-*image_format = &ctx->formats[i].image_format;
+if (ctx->formats[i].fourcc == desc->fourcc) {
+*image_format = &ctx->formats[i].image_format;
 return 0;
 }
 }
+
+fail:
 return AVERROR(EINVAL);
 }
 
@@ -368,6 +375,7 @@ static int vaapi_device_init(AVHWDeviceContext *hwdev)
 av_log(hwdev, AV_LOG_DEBUG, "Format %#x -> %s.\n",
fourcc, av_get_pix_fmt_name(pix_fmt));
 ctx->formats[ctx->nb_formats].pix_fmt  = pix_fmt;
+ctx->formats[ctx->nb_formats].fourcc   = fourcc;
 ctx->formats[ctx->nb_formats].image_format = image_list[i];
 ++ctx->nb_formats;
 }
-- 
2.7.4

___
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] lavu/hwcontext_vaapi: remove redundant check in vaapi_map_to_memory

2019-08-14 Thread Linjie Fu
vaapi_get_image_format() will be called in vaapi_map_frame(), so it's
redundant here. Also, NULL for VAImageFormat **image_format could be
a bit improper since the function is supposed to be used to get the
image format.

Remove vaapi_get_image_format() in vaapi_map_to_memory().

Signed-off-by: Linjie Fu 
---
 libavutil/hwcontext_vaapi.c | 6 --
 1 file changed, 6 deletions(-)

diff --git a/libavutil/hwcontext_vaapi.c b/libavutil/hwcontext_vaapi.c
index 64f14de..3b0f671 100644
--- a/libavutil/hwcontext_vaapi.c
+++ b/libavutil/hwcontext_vaapi.c
@@ -940,12 +940,6 @@ static int vaapi_map_to_memory(AVHWFramesContext *hwfc, 
AVFrame *dst,
 {
 int err;
 
-if (dst->format != AV_PIX_FMT_NONE) {
-err = vaapi_get_image_format(hwfc->device_ctx, dst->format, NULL);
-if (err < 0)
-return AVERROR(ENOSYS);
-}
-
 err = vaapi_map_frame(hwfc, dst, src, flags);
 if (err)
 return err;
-- 
2.7.4

___
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] lavu/pixfmt: add AYUV pixel format

2019-08-27 Thread Linjie Fu
Add support for packed 4:4:4 pixel format AYUV.

It is the format that VAAPI/QSV uses when coping with 4:4:4
surfaces. Alpha channel will be set to default value for HEVC REXT
hw decode.

Signed-off-by: Linjie Fu 
---
 libavutil/pixdesc.c   | 13 +
 libavutil/pixfmt.h|  2 ++
 libavutil/tests/pixfmt_best.c |  1 +
 libavutil/version.h   |  2 +-
 4 files changed, 17 insertions(+), 1 deletion(-)

diff --git a/libavutil/pixdesc.c b/libavutil/pixdesc.c
index b97b066..d217000 100644
--- a/libavutil/pixdesc.c
+++ b/libavutil/pixdesc.c
@@ -205,6 +205,19 @@ static const AVPixFmtDescriptor 
av_pix_fmt_descriptors[AV_PIX_FMT_NB] = {
 { 0, 4, 1, 0, 8, 3, 7, 2 },/* V */
 },
 },
+[AV_PIX_FMT_AYUV] = {
+.name = "ayuv",
+.nb_components = 4,
+.log2_chroma_w = 0,
+.log2_chroma_h = 0,
+.comp = {
+{ 0, 4, 1, 0, 8, 3, 7, 2 },/* Y */
+{ 0, 4, 2, 0, 8, 3, 7, 3 },/* U */
+{ 0, 4, 3, 0, 8, 3, 7, 4 },/* V */
+{ 0, 4, 0, 0, 8, 3, 7, 1 },/* A */
+},
+.flags = AV_PIX_FMT_FLAG_ALPHA,
+},
 [AV_PIX_FMT_RGB24] = {
 .name = "rgb24",
 .nb_components = 3,
diff --git a/libavutil/pixfmt.h b/libavutil/pixfmt.h
index 8b54c94..adbaec8 100644
--- a/libavutil/pixfmt.h
+++ b/libavutil/pixfmt.h
@@ -348,6 +348,8 @@ enum AVPixelFormat {
 AV_PIX_FMT_NV24,  ///< planar YUV 4:4:4, 24bpp, 1 plane for Y and 1 
plane for the UV components, which are interleaved (first byte U and the 
following byte V)
 AV_PIX_FMT_NV42,  ///< as above, but U and V bytes are swapped
 
+AV_PIX_FMT_AYUV,  ///< packed YUV 4:4:4, 32bpp,  A  Y Cb Cr,
+
 AV_PIX_FMT_NB ///< number of pixel formats, DO NOT USE THIS if you 
want to link with shared libav* because the number of formats might differ 
between versions
 };
 
diff --git a/libavutil/tests/pixfmt_best.c b/libavutil/tests/pixfmt_best.c
index 53f7264..2939e48 100644
--- a/libavutil/tests/pixfmt_best.c
+++ b/libavutil/tests/pixfmt_best.c
@@ -91,6 +91,7 @@ int main(void)
 TEST(AV_PIX_FMT_YUVA420P,  AV_PIX_FMT_YUV420P);
 TEST(AV_PIX_FMT_YUVA422P,  AV_PIX_FMT_YUV422P);
 TEST(AV_PIX_FMT_YUVA444P,  AV_PIX_FMT_YUV444P);
+TEST(AV_PIX_FMT_AYUV,  AV_PIX_FMT_YUV444P);
 TEST(AV_PIX_FMT_AYUV64,AV_PIX_FMT_YUV444P16);
 TEST(AV_PIX_FMT_RGBA,  AV_PIX_FMT_RGB24);
 TEST(AV_PIX_FMT_ABGR,  AV_PIX_FMT_RGB24);
diff --git a/libavutil/version.h b/libavutil/version.h
index ecc6a7c..658a508 100644
--- a/libavutil/version.h
+++ b/libavutil/version.h
@@ -79,7 +79,7 @@
  */
 
 #define LIBAVUTIL_VERSION_MAJOR  56
-#define LIBAVUTIL_VERSION_MINOR  33
+#define LIBAVUTIL_VERSION_MINOR  34
 #define LIBAVUTIL_VERSION_MICRO 100
 
 #define LIBAVUTIL_VERSION_INT   AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \
-- 
2.7.4

___
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] swscale: Add swscale and fate support for AYUV

2019-08-27 Thread Linjie Fu
Add swscale support for AYUV and make it more robust.

Also update the reference in fate.

Signed-off-by: Linjie Fu 
---
 libswscale/input.c   | 26 +
 libswscale/output.c  | 50 
 libswscale/utils.c   |  1 +
 libswscale/version.h |  2 +-
 tests/ref/fate/filter-pixdesc-ayuv   |  1 +
 tests/ref/fate/filter-pixfmts-copy   |  1 +
 tests/ref/fate/filter-pixfmts-crop   |  1 +
 tests/ref/fate/filter-pixfmts-field  |  1 +
 tests/ref/fate/filter-pixfmts-fieldorder |  1 +
 tests/ref/fate/filter-pixfmts-hflip  |  1 +
 tests/ref/fate/filter-pixfmts-il |  1 +
 tests/ref/fate/filter-pixfmts-null   |  1 +
 tests/ref/fate/filter-pixfmts-pad|  1 +
 tests/ref/fate/filter-pixfmts-scale  |  1 +
 tests/ref/fate/filter-pixfmts-transpose  |  1 +
 tests/ref/fate/filter-pixfmts-vflip  |  1 +
 tests/ref/fate/pixfmt_best   |  2 +-
 tests/ref/fate/sws-pixdesc-query |  3 ++
 18 files changed, 94 insertions(+), 2 deletions(-)
 create mode 100644 tests/ref/fate/filter-pixdesc-ayuv

diff --git a/libswscale/input.c b/libswscale/input.c
index 064f8da..73d1aa9 100644
--- a/libswscale/input.c
+++ b/libswscale/input.c
@@ -552,6 +552,25 @@ static void yvy2ToUV_c(uint8_t *dstU, uint8_t *dstV, const 
uint8_t *unused0, con
 av_assert1(src1 == src2);
 }
 
+static void ayuvToY_c(uint8_t *dst, const uint8_t *src, const uint8_t 
*unused1, const uint8_t *unused2,  int width,
+  uint32_t *unused)
+{
+int i;
+for (i = 0; i < width; i++)
+dst[i] = src[4 * i + 2];
+}
+
+static void ayuvToUV_c(uint8_t *dstU, uint8_t *dstV, const uint8_t *unused0, 
const uint8_t *src1,
+   const uint8_t *src2, int width, uint32_t *unused)
+{
+int i;
+for (i = 0; i < width; i++) {
+dstV[i] = src1[4 * i];
+dstU[i] = src1[4 * i + 1];
+}
+av_assert1(src1 == src2);
+}
+
 static void bswap16Y_c(uint8_t *_dst, const uint8_t *_src, const uint8_t 
*unused1, const uint8_t *unused2, int width,
uint32_t *unused)
 {
@@ -1154,6 +1173,9 @@ av_cold void ff_sws_init_input_funcs(SwsContext *c)
 case AV_PIX_FMT_P016BE:
 c->chrToYV12 = p016BEToUV_c;
 break;
+case AV_PIX_FMT_AYUV:
+c->chrToYV12 = ayuvToUV_c;
+break;
 }
 if (c->chrSrcHSubSample) {
 switch (srcFormat) {
@@ -1586,6 +1608,9 @@ av_cold void ff_sws_init_input_funcs(SwsContext *c)
 c->lumToYV12 = grayf32ToY16_bswap_c;
 #endif
 break;
+case AV_PIX_FMT_AYUV:
+c->lumToYV12 = ayuvToY_c;
+break;
 }
 if (c->needAlpha) {
 if (is16BPS(srcFormat) || isNBPS(srcFormat)) {
@@ -1599,6 +1624,7 @@ av_cold void ff_sws_init_input_funcs(SwsContext *c)
 case AV_PIX_FMT_RGBA64BE:  c->alpToYV12 = rgba64beToA_c; break;
 case AV_PIX_FMT_BGRA:
 case AV_PIX_FMT_RGBA:
+case AV_PIX_FMT_AYUV:
 c->alpToYV12 = rgbaToA_c;
 break;
 case AV_PIX_FMT_ABGR:
diff --git a/libswscale/output.c b/libswscale/output.c
index 26b0ff3..d7c0818 100644
--- a/libswscale/output.c
+++ b/libswscale/output.c
@@ -2403,6 +2403,53 @@ yuv2ya8_X_c(SwsContext *c, const int16_t *lumFilter,
 }
 
 static void
+yuv2ayuv_X_c(SwsContext *c, const int16_t *lumFilter,
+ const int16_t **lumSrc, int lumFilterSize,
+ const int16_t *chrFilter, const int16_t **chrUSrc,
+ const int16_t **chrVSrc, int chrFilterSize,
+ const int16_t **alpSrc, uint8_t *dest, int dstW, int y)
+{
+int hasAlpha = !!alpSrc;
+int i;
+
+for (i = 0; i < dstW; i++) {
+int j;
+int A = 1 << 18;
+int Y = 1 << 18;
+int U = 1 << 18;
+int V = 1 << 18;
+
+for (j = 0; j < lumFilterSize; j++) {
+Y += lumSrc[j][i]  * lumFilter[j];
+}
+for (j = 0; j < chrFilterSize; j++) {
+U += chrUSrc[j][i] * chrFilter[j];
+V += chrVSrc[j][i] * chrFilter[j];
+}
+if (hasAlpha)
+for (j = 0; j < lumFilterSize; j++)
+A += alpSrc[j][i] * lumFilter[j];
+A >>= 19;
+Y >>= 19;
+U >>= 19;
+V >>= 19;
+A = hasAlpha ? A : 255;
+
+if ((A | Y | U | V) & 0x100) {
+A = av_clip_uint8(A);
+Y = av_clip_uint8(Y);
+U = av_clip_uint8(U);
+V = av_clip_uint8(V);
+}
+
+dest[4*i] = V;
+dest[4*i + 1] = U;
+dest[4*i + 2] = Y;
+dest[4*i + 3] = A;
+}
+}
+
+static void
 yuv2ayuv64le_X_c(SwsContext *c, const int16_t *lumFilter,
  const int16_t **_lumSrc, int lumFilterSize,
  const int16_t *chrFilter, const int16_t **_chrUSrc,
@@

[FFmpeg-devel] [PATCH] avcodec/vaapi:free slice_buffers when decoding failed

2018-09-14 Thread Linjie Fu
If vaEndPicture failed in ff_vaapi_decode_issue, free
the pic->slice_buffer.

Fix the memory leak issue in ticket #7385

Signed-off-by: Linjie Fu 
---
 libavcodec/vaapi_decode.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/libavcodec/vaapi_decode.c b/libavcodec/vaapi_decode.c
index d0a6b5817d..700cd5c681 100644
--- a/libavcodec/vaapi_decode.c
+++ b/libavcodec/vaapi_decode.c
@@ -216,6 +216,11 @@ fail_with_picture:
 fail:
 ff_vaapi_decode_destroy_buffers(avctx, pic);
 fail_at_end:
+pic->nb_param_buffers = 0;
+pic->nb_slices= 0;
+pic->slices_allocated = 0;
+av_freep(&pic->slice_buffers);
+
 return err;
 }
 
-- 
2.17.1

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


[FFmpeg-devel] [PATCH V2] avcodec/vaapi:free slice_buffers when decoding failed

2018-09-18 Thread Linjie Fu
If vaEndPicture failed in ff_vaapi_decode_issue, free
the pic->slice_buffer.

Fix the memory leak issue in ticket #7385

[V2] unit the return paths under the "exit" tag at
the end of the function.

Signed-off-by: Linjie Fu 
---
 libavcodec/vaapi_decode.c | 15 ---
 1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/libavcodec/vaapi_decode.c b/libavcodec/vaapi_decode.c
index d0a6b5817d..3ee9c6be51 100644
--- a/libavcodec/vaapi_decode.c
+++ b/libavcodec/vaapi_decode.c
@@ -152,7 +152,7 @@ int ff_vaapi_decode_issue(AVCodecContext *avctx,
 {
 VAAPIDecodeContext *ctx = avctx->internal->hwaccel_priv_data;
 VAStatus vas;
-int err;
+int err = 0;
 
 av_log(avctx, AV_LOG_DEBUG, "Decode to surface %#x.\n",
pic->output_surface);
@@ -200,12 +200,7 @@ int ff_vaapi_decode_issue(AVCodecContext *avctx,
 AV_VAAPI_DRIVER_QUIRK_RENDER_PARAM_BUFFERS)
 ff_vaapi_decode_destroy_buffers(avctx, pic);
 
-pic->nb_param_buffers = 0;
-pic->nb_slices= 0;
-pic->slices_allocated = 0;
-av_freep(&pic->slice_buffers);
-
-return 0;
+goto exit;
 
 fail_with_picture:
 vas = vaEndPicture(ctx->hwctx->display, ctx->va_context);
@@ -216,6 +211,12 @@ fail_with_picture:
 fail:
 ff_vaapi_decode_destroy_buffers(avctx, pic);
 fail_at_end:
+exit:
+pic->nb_param_buffers = 0;
+pic->nb_slices= 0;
+pic->slices_allocated = 0;
+av_freep(&pic->slice_buffers);
+
 return err;
 }
 
-- 
2.17.1

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


[FFmpeg-devel] [PATCH V3] avcodec/h264_mp4toannexb_bsf: extract extradata for first coming frame

2018-09-29 Thread Linjie Fu
Add "new_nal_slice" to indicate the first coming nal_slice (including
H264_NAL_IDR_SLICE and H264_NAL_SLICE)

Extract extradata of streams when the first nal_slice comes, not only
H264_NAL_IDR_SLICE but also H264_NAL_SLICE.

This patch aims at the following issues:
1. the IDR frame is missing in the  first GOP of a stream
(common in live stream, IDR.No.Inband.SPPS.mkv in ticket #6418)
2. there is no IDR frame in the input stream.
(No.Inband.SPPS.No.IDR.mkv in ticket #6418)

Both clips could be decoded successfully using software decoding
but had problems in hwaccel using qsv before applying the patch.

V3: modified the commit message and the code duplication.

Signed-off-by: Linjie Fu 
---
 libavcodec/h264_mp4toannexb_bsf.c | 9 +++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/libavcodec/h264_mp4toannexb_bsf.c 
b/libavcodec/h264_mp4toannexb_bsf.c
index fb3f24ea40..8dd9159b22 100644
--- a/libavcodec/h264_mp4toannexb_bsf.c
+++ b/libavcodec/h264_mp4toannexb_bsf.c
@@ -33,6 +33,7 @@ typedef struct H264BSFContext {
 int32_t  pps_offset;
 uint8_t  length_size;
 uint8_t  new_idr;
+uint8_t  new_nal_slice;
 uint8_t  idr_sps_seen;
 uint8_t  idr_pps_seen;
 int  extradata_parsed;
@@ -236,13 +237,17 @@ static int h264_mp4toannexb_filter(AVBSFContext *ctx, 
AVPacket *out)
 if (!s->new_idr && unit_type == H264_NAL_IDR_SLICE && (buf[1] & 0x80))
 s->new_idr = 1;
 
-/* prepend only to the first type 5 NAL unit of an IDR picture, if no 
sps/pps are already present */
-if (s->new_idr && unit_type == H264_NAL_IDR_SLICE && !s->idr_sps_seen 
&& !s->idr_pps_seen) {
+/* prepend to the first type 5 NAL unit of an IDR picture,
+ * or the first type 1 NAL unit of an IDR missing picture, 
+ * if no sps/pps are already present */
+if (s->new_idr && !s->idr_sps_seen && !s->idr_pps_seen
+&& (unit_type == H264_NAL_IDR_SLICE || (!s->new_nal_slice 
&& H264_NAL_SLICE == unit_type))) {
 if ((ret=alloc_and_copy(out,
ctx->par_out->extradata, 
ctx->par_out->extradata_size,
buf, nal_size, 1)) < 0)
 goto fail;
 s->new_idr = 0;
+s->new_nal_slice = 1;
 /* if only SPS has been seen, also insert PPS */
 } else if (s->new_idr && unit_type == H264_NAL_IDR_SLICE && 
s->idr_sps_seen && !s->idr_pps_seen) {
 if (s->pps_offset == -1) {
-- 
2.17.1

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


[FFmpeg-devel] [PATCH] avcodec/qsvdec:flush the buffered data before reinit

2018-09-29 Thread Linjie Fu
Flush the buffered data in libmfx before video param reinit
in case the frames drop.

Cache the first frame causing the reinit and decode zero-size
pkt to flush the buffered pkt before reinit. After all the
buffered pkts being flushed, resume to reinit and decode.

Fix the issue in ticket #7399.

Modified in qsvdec_other.c as well.

Signed-off-by: Linjie Fu 
Signed-off-by: Zhong  Li 
---
 libavcodec/qsvdec.c   | 12 
 libavcodec/qsvdec.h   |  2 ++
 libavcodec/qsvdec_h2645.c | 11 +++
 libavcodec/qsvdec_other.c | 10 +++---
 4 files changed, 28 insertions(+), 7 deletions(-)

diff --git a/libavcodec/qsvdec.c b/libavcodec/qsvdec.c
index 22e7a46a85..ca4500b456 100644
--- a/libavcodec/qsvdec.c
+++ b/libavcodec/qsvdec.c
@@ -372,6 +372,8 @@ 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;
 }
@@ -493,6 +495,7 @@ int ff_qsv_process_data(AVCodecContext *avctx, QSVContext 
*q,
 int dummy_size;
 int ret;
 const AVPixFmtDescriptor *desc;
+AVPacket zero_pkt = {0};
 
 if (!q->avctx_internal) {
 q->avctx_internal = avcodec_alloc_context3(NULL);
@@ -527,6 +530,15 @@ int ff_qsv_process_data(AVCodecContext *avctx, QSVContext 
*q,
AV_PIX_FMT_NONE };
 enum AVPixelFormat qsv_format;
 
+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);
+}
+
+q->reinit_flag = 0;
+
 qsv_format = ff_qsv_map_pixfmt(q->parser->format, &q->fourcc);
 if (qsv_format < 0) {
 av_log(avctx, AV_LOG_ERROR,
diff --git a/libavcodec/qsvdec.h b/libavcodec/qsvdec.h
index 5b7b03a48b..111536caba 100644
--- a/libavcodec/qsvdec.h
+++ b/libavcodec/qsvdec.h
@@ -53,6 +53,8 @@ typedef struct QSVContext {
 
 AVFifoBuffer *async_fifo;
 int zero_consume_run;
+int buffered_count;
+int reinit_flag;
 
 // the internal parser and codec context for parsing the data
 AVCodecParserContext *parser;
diff --git a/libavcodec/qsvdec_h2645.c b/libavcodec/qsvdec_h2645.c
index d9d2318d1a..b8a78aa81b 100644
--- a/libavcodec/qsvdec_h2645.c
+++ b/libavcodec/qsvdec_h2645.c
@@ -146,10 +146,11 @@ static int qsv_decode_frame(AVCodecContext *avctx, void 
*data,
 /* no more data */
 if (av_fifo_size(s->packet_fifo) < sizeof(AVPacket))
 return avpkt->size ? avpkt->size : ff_qsv_process_data(avctx, 
&s->qsv, frame, got_frame, avpkt);
-
-av_packet_unref(&s->buffer_pkt);
-
-av_fifo_generic_read(s->packet_fifo, &s->buffer_pkt, 
sizeof(s->buffer_pkt), NULL);
+/* in progress of reinit, no read from fifo and keep the 
buffer_pkt */
+if (!s->qsv.reinit_flag) {
+av_packet_unref(&s->buffer_pkt);
+av_fifo_generic_read(s->packet_fifo, &s->buffer_pkt, 
sizeof(s->buffer_pkt), NULL);
+}
 }
 
 ret = ff_qsv_process_data(avctx, &s->qsv, frame, got_frame, 
&s->buffer_pkt);
@@ -159,6 +160,8 @@ static int qsv_decode_frame(AVCodecContext *avctx, void 
*data,
 av_packet_unref(&s->buffer_pkt);
 return ret;
 }
+if (s->qsv.reinit_flag)
+continue;
 
 s->buffer_pkt.size -= ret;
 s->buffer_pkt.data += ret;
diff --git a/libavcodec/qsvdec_other.c b/libavcodec/qsvdec_other.c
index 993c7a8e80..b449bb21b7 100644
--- a/libavcodec/qsvdec_other.c
+++ b/libavcodec/qsvdec_other.c
@@ -132,9 +132,11 @@ static int qsv_decode_frame(AVCodecContext *avctx, void 
*data,
 /* no more data */
 if (av_fifo_size(s->packet_fifo) < sizeof(AVPacket))
 return avpkt->size ? avpkt->size : ff_qsv_process_data(avctx, 
&s->qsv, frame, got_frame, avpkt);
-
-av_packet_unref(&s->input_ref);
-av_fifo_generic_read(s->packet_fifo, &s->input_ref, 
sizeof(s->input_ref), NULL);
+/* in progress of reinit, no read from fifo and keep the 
buffer_pkt */ 
+if (!s->qsv.reinit_flag) {
+av_packet_unref(&s->input_ref);
+av_fifo_generic_read(s->packet_fifo, &s->input_ref, 
sizeof(s->input_ref), NULL);
+}
 }
 
 ret = ff_qsv_process_data(avctx, &s->qsv, frame, got_frame, 
&s->input_ref);
@@ -145,6 +147,8 @@ s

[FFmpeg-devel] [PATCH V2] avcodec-qsvdec-flush-the-buffered-data-before-reinit

2018-10-15 Thread Linjie Fu
Flush the buffered data in libmfx before video param reinit
in case the frames drop.

Cache the first frame causing the reinit and decode zero-size
pkt to flush the buffered pkt before reinit. After all the
buffered pkts being flushed, resume to reinit and decode.

Fix the issue in ticket #7399.

Modified in qsvdec_other.c as well.

[V2]: Move the definition of zero_pkt to where it is exactly
used.

Signed-off-by: Linjie Fu 
Signed-off-by: Zhong  Li 
---
 libavcodec/qsvdec.c   | 12 
 libavcodec/qsvdec.h   |  2 ++
 libavcodec/qsvdec_h2645.c | 11 +++
 libavcodec/qsvdec_other.c | 10 +++---
 4 files changed, 28 insertions(+), 7 deletions(-)

diff --git a/libavcodec/qsvdec.c b/libavcodec/qsvdec.c
index 22e7a46a85..6753e596a1 100644
--- a/libavcodec/qsvdec.c
+++ b/libavcodec/qsvdec.c
@@ -372,6 +372,8 @@ 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;
 }
@@ -526,6 +528,16 @@ int ff_qsv_process_data(AVCodecContext *avctx, QSVContext 
*q,
AV_PIX_FMT_NONE,
AV_PIX_FMT_NONE };
 enum AVPixelFormat qsv_format;
+AVPacket zero_pkt = {0};
+
+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);
+}
+
+q->reinit_flag = 0;
 
 qsv_format = ff_qsv_map_pixfmt(q->parser->format, &q->fourcc);
 if (qsv_format < 0) {
diff --git a/libavcodec/qsvdec.h b/libavcodec/qsvdec.h
index 5b7b03a48b..111536caba 100644
--- a/libavcodec/qsvdec.h
+++ b/libavcodec/qsvdec.h
@@ -53,6 +53,8 @@ typedef struct QSVContext {
 
 AVFifoBuffer *async_fifo;
 int zero_consume_run;
+int buffered_count;
+int reinit_flag;
 
 // the internal parser and codec context for parsing the data
 AVCodecParserContext *parser;
diff --git a/libavcodec/qsvdec_h2645.c b/libavcodec/qsvdec_h2645.c
index d9d2318d1a..b8a78aa81b 100644
--- a/libavcodec/qsvdec_h2645.c
+++ b/libavcodec/qsvdec_h2645.c
@@ -146,10 +146,11 @@ static int qsv_decode_frame(AVCodecContext *avctx, void 
*data,
 /* no more data */
 if (av_fifo_size(s->packet_fifo) < sizeof(AVPacket))
 return avpkt->size ? avpkt->size : ff_qsv_process_data(avctx, 
&s->qsv, frame, got_frame, avpkt);
-
-av_packet_unref(&s->buffer_pkt);
-
-av_fifo_generic_read(s->packet_fifo, &s->buffer_pkt, 
sizeof(s->buffer_pkt), NULL);
+/* in progress of reinit, no read from fifo and keep the 
buffer_pkt */
+if (!s->qsv.reinit_flag) {
+av_packet_unref(&s->buffer_pkt);
+av_fifo_generic_read(s->packet_fifo, &s->buffer_pkt, 
sizeof(s->buffer_pkt), NULL);
+}
 }
 
 ret = ff_qsv_process_data(avctx, &s->qsv, frame, got_frame, 
&s->buffer_pkt);
@@ -159,6 +160,8 @@ static int qsv_decode_frame(AVCodecContext *avctx, void 
*data,
 av_packet_unref(&s->buffer_pkt);
 return ret;
 }
+if (s->qsv.reinit_flag)
+continue;
 
 s->buffer_pkt.size -= ret;
 s->buffer_pkt.data += ret;
diff --git a/libavcodec/qsvdec_other.c b/libavcodec/qsvdec_other.c
index 993c7a8e80..b449bb21b7 100644
--- a/libavcodec/qsvdec_other.c
+++ b/libavcodec/qsvdec_other.c
@@ -132,9 +132,11 @@ static int qsv_decode_frame(AVCodecContext *avctx, void 
*data,
 /* no more data */
 if (av_fifo_size(s->packet_fifo) < sizeof(AVPacket))
 return avpkt->size ? avpkt->size : ff_qsv_process_data(avctx, 
&s->qsv, frame, got_frame, avpkt);
-
-av_packet_unref(&s->input_ref);
-av_fifo_generic_read(s->packet_fifo, &s->input_ref, 
sizeof(s->input_ref), NULL);
+/* in progress of reinit, no read from fifo and keep the 
buffer_pkt */ 
+if (!s->qsv.reinit_flag) {
+av_packet_unref(&s->input_ref);
+av_fifo_generic_read(s->packet_fifo, &s->input_ref, 
sizeof(s->input_ref), NULL);
+}
 }
 
 ret = ff_qsv_process_data(avctx, &s->qsv, frame, got_frame, 
&s->input_ref);
@@ -145,6 +147,8 @@ static int qsv_decode_frame(AVCodecContext *avctx, void 
*data,
 
 return ret;
 }
+if (s->qsv.reinit_flag)
+continue;
 
 s->input_ref.size -= ret;
 s->input_ref.data += ret;
-- 
2.17.1

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


[FFmpeg-devel] [PATCH] avcodec/h264_parser: Skip Redundant Slice Info Attached Behind Frames.

2018-10-24 Thread Linjie Fu
Skip redundant slice info attached behind frames (PPS for eaxmple) to
parse timestamp correctly and produce the segment format successfully.

When PPS info is attached behind frame data whin one PES packet,
h264_find_frame_end for PPS slice returns END_NOT_FOUND,and causes the
following IDR frame to returning END_NOT_FOUND too. And this leads to
the failure of parsing pts and operation of segment.

Skip redundant slice info to ensure the h264_parser to find the correct
frame_end of following frame, and make sure parse_packet could parse the
pts and dts.

Fix the pts issue for single segment.ts and the segment format
failure issue for http live stream in ticket #7207.

Signed-off-by: Linjie Fu 
---
 libavcodec/h264_parser.c | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/libavcodec/h264_parser.c b/libavcodec/h264_parser.c
index 5f9a9c46ef..bcc97d6260 100644
--- a/libavcodec/h264_parser.c
+++ b/libavcodec/h264_parser.c
@@ -577,6 +577,7 @@ static int h264_parse(AVCodecParserContext *s,
 H264ParseContext *p = s->priv_data;
 ParseContext *pc = &p->pc;
 int next;
+int input_bufsize = buf_size;
 
 if (!p->got_first) {
 p->got_first = 1;
@@ -644,7 +645,10 @@ static int h264_parse(AVCodecParserContext *s,
 
 *poutbuf  = buf;
 *poutbuf_size = buf_size;
-return next;
+if (next > 0 && next http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


[FFmpeg-devel] [PATCH] add an option to forbid the fallback to sw when hardware init fails

2018-10-30 Thread Linjie Fu
Currently ff_get_format will go through all usable choices if the
chosen format was not supported. It will fallback to software if
the hardware init fails.

According to the comment in ticket #7519, provided an option
"-fallback_forbid 1" to return directly if hardware init fails
and forbid the fallback to software.

Signed-off-by: Linjie Fu 
---
 libavcodec/avcodec.h   |  8 
 libavcodec/decode.c| 11 +--
 libavcodec/options_table.h |  1 +
 3 files changed, 18 insertions(+), 2 deletions(-)

diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
index 705a3ce4f3..fac3c6acb2 100644
--- a/libavcodec/avcodec.h
+++ b/libavcodec/avcodec.h
@@ -3312,6 +3312,14 @@ typedef struct AVCodecContext {
  * used as reference pictures).
  */
 int extra_hw_frames;
+
+/**
+ * - forbid the fallback to software path in ff_get_format
+ * - when the hardware init fails. (0 -> disabled)
+ * - encoding: unused.
+ * - decoding: Set by user.
+ */
+int fallback_forbid;
 } AVCodecContext;
 
 #if FF_API_CODEC_GET_SET
diff --git a/libavcodec/decode.c b/libavcodec/decode.c
index 4607e9f318..edadbd7e03 100644
--- a/libavcodec/decode.c
+++ b/libavcodec/decode.c
@@ -1441,8 +1441,15 @@ int ff_get_format(AVCodecContext *avctx, const enum 
AVPixelFormat *fmt)
 av_log(avctx, AV_LOG_DEBUG, "Format %s requires hwaccel "
"initialisation.\n", desc->name);
 err = hwaccel_init(avctx, hw_config);
-if (err < 0)
-goto try_again;
+if (err < 0) {
+if (avctx->fallback_forbid) {
+av_log(avctx, AV_LOG_ERROR, "Format %s not usable, 
fallback "
+"was forbidden.\n", desc->name);
+ret = AV_PIX_FMT_NONE;
+break;
+} else
+goto try_again;
+}
 }
 ret = user_choice;
 break;
diff --git a/libavcodec/options_table.h b/libavcodec/options_table.h
index 099261e168..73f0333eeb 100644
--- a/libavcodec/options_table.h
+++ b/libavcodec/options_table.h
@@ -479,6 +479,7 @@ static const AVOption avcodec_options[] = {
 {"allow_high_depth", "allow to output YUV pixel formats with a different 
chroma sampling than 4:2:0 and/or other than 8 bits per component", 0, 
AV_OPT_TYPE_CONST, {.i64 = AV_HWACCEL_FLAG_ALLOW_HIGH_DEPTH }, INT_MIN, 
INT_MAX, V | D, "hwaccel_flags"},
 {"allow_profile_mismatch", "attempt to decode anyway if HW accelerated 
decoder's supported profiles do not exactly match the stream", 0, 
AV_OPT_TYPE_CONST, {.i64 = AV_HWACCEL_FLAG_ALLOW_PROFILE_MISMATCH }, INT_MIN, 
INT_MAX, V | D, "hwaccel_flags"},
 {"extra_hw_frames", "Number of extra hardware frames to allocate for the 
user", OFFSET(extra_hw_frames), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, 
V|D },
+{"fallback_forbid", "forbid the fallback to software path when hardware init 
fails", OFFSET(fallback_forbid), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, V|D },
 {NULL},
 };
 
-- 
2.17.1

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


[FFmpeg-devel] [PATCH] avcodec/qsvenc: add VDENC support for H264 and HEVC

2018-10-31 Thread Linjie Fu
Add VDENC(lowpower mode) support for QSV h264 and HEVC
with the limitation of MSDK API verion greater than 1.15.

It's an experimental function(like lowpower in vaapi) with
some limitations:
- CBR/VBR require HuC which should be explicitly loaded via i915
module parameter(i915.enable_guc=2 for >=4.16)
- HEVC VDENC was supported >= ICE LAKE

use option "-low_power 1" to enable VDENC.

Signed-off-by: Linjie Fu 
---
 libavcodec/qsvenc.c  | 3 +++
 libavcodec/qsvenc.h  | 2 ++
 libavcodec/qsvenc_h264.c | 3 +++
 libavcodec/qsvenc_hevc.c | 3 +++
 4 files changed, 11 insertions(+)

diff --git a/libavcodec/qsvenc.c b/libavcodec/qsvenc.c
index 948751daf4..7a031297fe 100644
--- a/libavcodec/qsvenc.c
+++ b/libavcodec/qsvenc.c
@@ -464,6 +464,9 @@ static int init_video_param(AVCodecContext *avctx, 
QSVEncContext *q)
 }
 }
 
+#if QSV_HAVE_VDENC
+q->param.mfx.LowPower   = q->low_power ? 
MFX_CODINGOPTION_ON:MFX_CODINGOPTION_OFF;
+#endif
 q->param.mfx.CodecProfile   = q->profile;
 q->param.mfx.TargetUsage= avctx->compression_level;
 q->param.mfx.GopPicSize = FFMAX(0, avctx->gop_size);
diff --git a/libavcodec/qsvenc.h b/libavcodec/qsvenc.h
index 50cc4267e7..a396aa7d3f 100644
--- a/libavcodec/qsvenc.h
+++ b/libavcodec/qsvenc.h
@@ -44,6 +44,7 @@
 #define QSV_HAVE_LA QSV_VERSION_ATLEAST(1, 7)
 #define QSV_HAVE_LA_DS  QSV_VERSION_ATLEAST(1, 8)
 #define QSV_HAVE_LA_HRD QSV_VERSION_ATLEAST(1, 11)
+#define QSV_HAVE_VDENC  QSV_VERSION_ATLEAST(1, 15)
 
 #if defined(_WIN32) || defined(__CYGWIN__)
 #define QSV_HAVE_AVBR   QSV_VERSION_ATLEAST(1, 3)
@@ -162,6 +163,7 @@ typedef struct QSVEncContext {
 int recovery_point_sei;
 
 int a53_cc;
+int low_power;
 
 #if QSV_HAVE_MF
 int mfmode;
diff --git a/libavcodec/qsvenc_h264.c b/libavcodec/qsvenc_h264.c
index 07c9d64e6b..483faf832b 100644
--- a/libavcodec/qsvenc_h264.c
+++ b/libavcodec/qsvenc_h264.c
@@ -153,6 +153,9 @@ static const AVOption options[] = {
 { "off", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MFX_MF_DISABLED }, 
INT_MIN, INT_MAX, VE, "mfmode" },
 { "auto"   , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MFX_MF_AUTO }, 
INT_MIN, INT_MAX, VE, "mfmode" },
 #endif
+#if QSV_HAVE_VDENC
+{ "low_power",  "low power mode for encoder h264_qsv",   
OFFSET(qsv.low_power),  AV_OPT_TYPE_INT, { .i64 =  0 }, 0,   1, VE 
},
+#endif
 
 { NULL },
 };
diff --git a/libavcodec/qsvenc_hevc.c b/libavcodec/qsvenc_hevc.c
index 4339b316a3..cfe3674f0f 100644
--- a/libavcodec/qsvenc_hevc.c
+++ b/libavcodec/qsvenc_hevc.c
@@ -243,6 +243,9 @@ static const AVOption options[] = {
 { "main",NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MFX_PROFILE_HEVC_MAIN
}, INT_MIN, INT_MAX, VE, "profile" },
 { "main10",  NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MFX_PROFILE_HEVC_MAIN10  
}, INT_MIN, INT_MAX, VE, "profile" },
 { "mainsp",  NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MFX_PROFILE_HEVC_MAINSP  
}, INT_MIN, INT_MAX, VE, "profile" },
+#if QSV_HAVE_VDENC
+{ "low_power", "low power mode for encoder hevc_qsv", 
OFFSET(qsv.low_power), AV_OPT_TYPE_INT, { .i64 =  0 },  0,  1, VE },
+#endif
 
 { NULL },
 };
-- 
2.17.1

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


[FFmpeg-devel] [PATCH] [V2] avcodec/qsvenc: add VDENC support for H264 and HEVC

2018-11-04 Thread Linjie Fu
Add VDENC(lowpower mode) support for QSV h264 and HEVC

It's an experimental function(like lowpower in vaapi) with
some limitations:
- CBR/VBR require HuC which should be explicitly loaded via i915
module parameter(i915.enable_guc=2 for linux kerner version >= 4.16)
- HEVC VDENC was supported >= ICE LAKE

use option "-low_power 1" to enable VDENC.

[V2]: modified the commit message and option comments, use AV_OPT_TYPE_BOOL
to replace AV_OPT_TYPE_INT.

Signed-off-by: Linjie Fu 
---
 libavcodec/qsvenc.c  | 3 +++
 libavcodec/qsvenc.h  | 2 ++
 libavcodec/qsvenc_h264.c | 3 +++
 libavcodec/qsvenc_hevc.c | 3 +++
 4 files changed, 11 insertions(+)

diff --git a/libavcodec/qsvenc.c b/libavcodec/qsvenc.c
index 948751daf4..7a031297fe 100644
--- a/libavcodec/qsvenc.c
+++ b/libavcodec/qsvenc.c
@@ -464,6 +464,9 @@ static int init_video_param(AVCodecContext *avctx, 
QSVEncContext *q)
 }
 }
 
+#if QSV_HAVE_VDENC
+q->param.mfx.LowPower   = q->low_power ? 
MFX_CODINGOPTION_ON:MFX_CODINGOPTION_OFF;
+#endif
 q->param.mfx.CodecProfile   = q->profile;
 q->param.mfx.TargetUsage= avctx->compression_level;
 q->param.mfx.GopPicSize = FFMAX(0, avctx->gop_size);
diff --git a/libavcodec/qsvenc.h b/libavcodec/qsvenc.h
index 50cc4267e7..a396aa7d3f 100644
--- a/libavcodec/qsvenc.h
+++ b/libavcodec/qsvenc.h
@@ -44,6 +44,7 @@
 #define QSV_HAVE_LA QSV_VERSION_ATLEAST(1, 7)
 #define QSV_HAVE_LA_DS  QSV_VERSION_ATLEAST(1, 8)
 #define QSV_HAVE_LA_HRD QSV_VERSION_ATLEAST(1, 11)
+#define QSV_HAVE_VDENC  QSV_VERSION_ATLEAST(1, 15)
 
 #if defined(_WIN32) || defined(__CYGWIN__)
 #define QSV_HAVE_AVBR   QSV_VERSION_ATLEAST(1, 3)
@@ -162,6 +163,7 @@ typedef struct QSVEncContext {
 int recovery_point_sei;
 
 int a53_cc;
+int low_power;
 
 #if QSV_HAVE_MF
 int mfmode;
diff --git a/libavcodec/qsvenc_h264.c b/libavcodec/qsvenc_h264.c
index 07c9d64e6b..e538e0ad52 100644
--- a/libavcodec/qsvenc_h264.c
+++ b/libavcodec/qsvenc_h264.c
@@ -153,6 +153,9 @@ static const AVOption options[] = {
 { "off", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MFX_MF_DISABLED }, 
INT_MIN, INT_MAX, VE, "mfmode" },
 { "auto"   , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MFX_MF_AUTO }, 
INT_MIN, INT_MAX, VE, "mfmode" },
 #endif
+#if QSV_HAVE_VDENC
+{ "low_power", "enable low power mode (experimental, many limitations by 
mfx version, HW platform, BRC modes, etc.", OFFSET(qsv.low_power), 
AV_OPT_TYPE_BOOL, { .i64 =  0 }, 0, 1, VE},
+#endif
 
 { NULL },
 };
diff --git a/libavcodec/qsvenc_hevc.c b/libavcodec/qsvenc_hevc.c
index 4339b316a3..f038f79b94 100644
--- a/libavcodec/qsvenc_hevc.c
+++ b/libavcodec/qsvenc_hevc.c
@@ -243,6 +243,9 @@ static const AVOption options[] = {
 { "main",NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MFX_PROFILE_HEVC_MAIN
}, INT_MIN, INT_MAX, VE, "profile" },
 { "main10",  NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MFX_PROFILE_HEVC_MAIN10  
}, INT_MIN, INT_MAX, VE, "profile" },
 { "mainsp",  NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MFX_PROFILE_HEVC_MAINSP  
}, INT_MIN, INT_MAX, VE, "profile" },
+#if QSV_HAVE_VDENC
+{ "low_power", "enable low power mode (experimental, many limitations by 
mfx version, HW platform, BRC modes, etc.", OFFSET(qsv.low_power), 
AV_OPT_TYPE_BOOL, { .i64 =  0 },  0,  1, VE },
+#endif
 
 { NULL },
 };
-- 
2.17.1

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


[FFmpeg-devel] [PATCH] avfilter/vf_overlay_qsv: initialize default pix_fmt

2018-11-05 Thread Linjie Fu
add default initiaization for pix_fmt in function have_alpha_panar
to avoid using uninitialized value.

Signed-off-by: Linjie Fu 
---
 libavfilter/vf_overlay_qsv.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/libavfilter/vf_overlay_qsv.c b/libavfilter/vf_overlay_qsv.c
index 20871786ee..79d6a58ec3 100644
--- a/libavfilter/vf_overlay_qsv.c
+++ b/libavfilter/vf_overlay_qsv.c
@@ -167,7 +167,8 @@ static int have_alpha_planar(AVFilterLink *link)
 if (link->format == AV_PIX_FMT_QSV) {
 fctx= (AVHWFramesContext *)link->hw_frames_ctx->data;
 pix_fmt = fctx->sw_format;
-}
+} else
+pix_fmt = AV_PIX_FMT_NONE;
 
 desc = av_pix_fmt_desc_get(pix_fmt);
 if (!desc)
-- 
2.17.1

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


[FFmpeg-devel] [PATCH] avcodec/vaapi_encode: modify the initialization postion of profile_string

2018-11-05 Thread Linjie Fu
Currently, profile_string was initialized in the "for" loop. If
it didn't enter this loop or accidently break, profile_string may be
uninitialized.

Modify to initialize the profile_string after the loop to avoid
using the uninitialized value when calling av_log.

Signed-off-by: Linjie Fu 
---
 libavcodec/vaapi_encode.c | 12 ++--
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/libavcodec/vaapi_encode.c b/libavcodec/vaapi_encode.c
index 2c34cdce2c..b43b52f0e5 100644
--- a/libavcodec/vaapi_encode.c
+++ b/libavcodec/vaapi_encode.c
@@ -1066,6 +1066,7 @@ static av_cold int 
vaapi_encode_profile_entrypoint(AVCodecContext *avctx)
 }
 
 av_assert0(ctx->codec->profiles);
+
 for (i = 0; (ctx->codec->profiles[i].av_profile !=
  FF_PROFILE_UNKNOWN); i++) {
 profile = &ctx->codec->profiles[i];
@@ -1080,12 +1081,6 @@ static av_cold int 
vaapi_encode_profile_entrypoint(AVCodecContext *avctx)
 avctx->profile != FF_PROFILE_UNKNOWN)
 continue;
 
-#if VA_CHECK_VERSION(1, 0, 0)
-profile_string = vaProfileStr(profile->va_profile);
-#else
-profile_string = "(no profile names)";
-#endif
-
 for (j = 0; j < n; j++) {
 if (va_profiles[j] == profile->va_profile)
 break;
@@ -1107,6 +1102,11 @@ static av_cold int 
vaapi_encode_profile_entrypoint(AVCodecContext *avctx)
 
 avctx->profile  = profile->av_profile;
 ctx->va_profile = profile->va_profile;
+#if VA_CHECK_VERSION(1, 0, 0)
+profile_string = vaProfileStr(profile->va_profile);
+#else
+profile_string = "(no profile names)";
+#endif
 av_log(avctx, AV_LOG_VERBOSE, "Using VAAPI profile %s (%d).\n",
profile_string, ctx->va_profile);
 
-- 
2.17.1

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


[FFmpeg-devel] [PATCH] avcodec/qsvenc: add default initiaize for pict_type

2018-11-05 Thread Linjie Fu
add default initiaize for pict_type in function ff_qsv_encode
to avoid using uninitialized value:

FF_DISABLE_DEPRECATION_WARNINGS
avctx->coded_frame->pict_type = pict_type;
FF_ENABLE_DEPRECATION_WARNINGS

Signed-off-by: Linjie Fu 
---
 libavcodec/qsvenc.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/libavcodec/qsvenc.c b/libavcodec/qsvenc.c
index 7a031297fe..564222ca10 100644
--- a/libavcodec/qsvenc.c
+++ b/libavcodec/qsvenc.c
@@ -1333,6 +1333,8 @@ int ff_qsv_encode(AVCodecContext *avctx, QSVEncContext *q,
 pict_type = AV_PICTURE_TYPE_P;
 else if (bs->FrameType & MFX_FRAMETYPE_B || bs->FrameType & 
MFX_FRAMETYPE_xB)
 pict_type = AV_PICTURE_TYPE_B;
+else
+pict_type = AV_PICTURE_TYPE_NONE;
 
 #if FF_API_CODED_FRAME
 FF_DISABLE_DEPRECATION_WARNINGS
-- 
2.17.1

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


[FFmpeg-devel] [PATCH v2] fftools/ffmpeg: add an option to forbid the fallback to software path when hardware init fails

2018-11-08 Thread Linjie Fu
Currently ff_get_format will go through all usable choices if the chosen
format was not supported. It will fallback to software path if the hardware
init fails.

Provided an option "-fallback_forbid 1" in user-code to detect frame->format and
hwaccel_get_buffer in get_buffer. If hardware init fails, returns an error.

Signed-off-by: Linjie Fu 
---

[v2] detect hardware init failures in get_buffer and modify in user-code

 fftools/ffmpeg.c | 2 ++
 fftools/ffmpeg.h | 1 +
 fftools/ffmpeg_opt.c | 3 +++
 3 files changed, 6 insertions(+)

diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c
index da4259a9a8..45694fef57 100644
--- a/fftools/ffmpeg.c
+++ b/fftools/ffmpeg.c
@@ -2890,6 +2890,8 @@ static int get_buffer(AVCodecContext *s, AVFrame *frame, 
int flags)
 
 if (ist->hwaccel_get_buffer && frame->format == ist->hwaccel_pix_fmt)
 return ist->hwaccel_get_buffer(s, frame, flags);
+else if (ist->fallback_forbid)
+return AVERROR(EINVAL);
 
 return avcodec_default_get_buffer2(s, frame, flags);
 }
diff --git a/fftools/ffmpeg.h b/fftools/ffmpeg.h
index eb1eaf6363..67ddaeaaee 100644
--- a/fftools/ffmpeg.h
+++ b/fftools/ffmpeg.h
@@ -365,6 +365,7 @@ typedef struct InputStream {
 enum AVHWDeviceType hwaccel_device_type;
 char  *hwaccel_device;
 enum AVPixelFormat hwaccel_output_format;
+int fallback_forbid;
 
 /* hwaccel context */
 void  *hwaccel_ctx;
diff --git a/fftools/ffmpeg_opt.c b/fftools/ffmpeg_opt.c
index d4851a2cd8..314e25565c 100644
--- a/fftools/ffmpeg_opt.c
+++ b/fftools/ffmpeg_opt.c
@@ -3600,6 +3600,9 @@ const OptionDef options[] = {
 { "autorotate",   HAS_ARG | OPT_BOOL | OPT_SPEC |
   OPT_EXPERT | OPT_INPUT,  
  { .off = OFFSET(autorotate) },
 "automatically insert correct rotate filters" },
+{ "fallback_forbid",  HAS_ARG | OPT_BOOL | OPT_SPEC |
+  OPT_EXPERT | OPT_INPUT,  
  { .off = OFFSET(fallback_forbid)},
+  "forbid the fallback to default software path when hardware init fails"},
 
 /* audio options */
 { "aframes",OPT_AUDIO | HAS_ARG  | OPT_PERFILE | OPT_OUTPUT,   
{ .func_arg = opt_audio_frames },
-- 
2.17.1

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


[FFmpeg-devel] [PATCH v3] fftools/ffmpeg: add an option to forbid the fallback to software path when hardware init fails

2018-11-09 Thread Linjie Fu
Currently ff_get_format will go through all usable choices if the chosen
format was not supported. It will fallback to software path if the hardware
init fails.

Provided an option "-require_hwaccel 1" in user-code to detect frame->format and
hwaccel_get_buffer in get_buffer. If hardware init fails, returns an error.

Signed-off-by: Linjie Fu 
---
[v2] detect hardware init failures in get_buffer and modify in user-code
[v3] changed the option name, add error message

 fftools/ffmpeg.c | 4 
 fftools/ffmpeg.h | 3 +++
 fftools/ffmpeg_opt.c | 4 
 3 files changed, 11 insertions(+)

diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c
index da4259a9a8..113ab6312a 100644
--- a/fftools/ffmpeg.c
+++ b/fftools/ffmpeg.c
@@ -2890,6 +2890,10 @@ static int get_buffer(AVCodecContext *s, AVFrame *frame, 
int flags)
 
 if (ist->hwaccel_get_buffer && frame->format == ist->hwaccel_pix_fmt)
 return ist->hwaccel_get_buffer(s, frame, flags);
+else if (ist->require_hwaccel) {
+av_log(s, AV_LOG_ERROR, "Hardware acceleration is required and will 
not fallback to try software path.\n");
+return AVERROR(EINVAL);
+}
 
 return avcodec_default_get_buffer2(s, frame, flags);
 }
diff --git a/fftools/ffmpeg.h b/fftools/ffmpeg.h
index eb1eaf6363..a5c85daa67 100644
--- a/fftools/ffmpeg.h
+++ b/fftools/ffmpeg.h
@@ -133,6 +133,8 @@ typedef struct OptionsContext {
 intnb_hwaccel_output_formats;
 SpecifierOpt *autorotate;
 intnb_autorotate;
+SpecifierOpt *require_hwaccel;
+intnb_require_hwaccel;
 
 /* output options */
 StreamMap *stream_maps;
@@ -365,6 +367,7 @@ typedef struct InputStream {
 enum AVHWDeviceType hwaccel_device_type;
 char  *hwaccel_device;
 enum AVPixelFormat hwaccel_output_format;
+int require_hwaccel;
 
 /* hwaccel context */
 void  *hwaccel_ctx;
diff --git a/fftools/ffmpeg_opt.c b/fftools/ffmpeg_opt.c
index d4851a2cd8..6890bb7fcf 100644
--- a/fftools/ffmpeg_opt.c
+++ b/fftools/ffmpeg_opt.c
@@ -730,6 +730,7 @@ static void add_input_streams(OptionsContext *o, 
AVFormatContext *ic)
 ist->autorotate = 1;
 MATCH_PER_STREAM_OPT(autorotate, i, ist->autorotate, ic, st);
 
+MATCH_PER_STREAM_OPT(require_hwaccel, i, ist->require_hwaccel, ic, st);
 MATCH_PER_STREAM_OPT(codec_tags, str, codec_tag, ic, st);
 if (codec_tag) {
 uint32_t tag = strtol(codec_tag, &next, 0);
@@ -3600,6 +3601,9 @@ const OptionDef options[] = {
 { "autorotate",   HAS_ARG | OPT_BOOL | OPT_SPEC |
   OPT_EXPERT | OPT_INPUT,  
  { .off = OFFSET(autorotate) },
 "automatically insert correct rotate filters" },
+{ "require_hwaccel",  HAS_ARG | OPT_BOOL | OPT_SPEC |
+  OPT_EXPERT | OPT_INPUT,  
  { .off = OFFSET(require_hwaccel)},
+  "forbid the fallback to default software path when hardware init fails"},
 
 /* audio options */
 { "aframes",OPT_AUDIO | HAS_ARG  | OPT_PERFILE | OPT_OUTPUT,   
{ .func_arg = opt_audio_frames },
-- 
2.17.1

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


[FFmpeg-devel] [PATCH,v3] lavc/qsvenc: add VDENC support for H264

2018-11-26 Thread Linjie Fu
Add VDENC(lowpower mode) support for QSV H264.

It's an experimental function(like lowpower in vaapi) with
some limitations:
- CBR/VBR require HuC which should be explicitly loaded via i915
module parameter(i915.enable_guc=2 for linux kernel version >= 4.16)

use option "-low_power 1" to enable VDENC.

Signed-off-by: Linjie Fu 
---
[v2]: modified the commit message and option comments, use AV_OPT_TYPE_BOOL
to replace AV_OPT_TYPE_INT.
[v3]: enable H264 VDENC separately.

 libavcodec/qsvenc.c  | 3 +++
 libavcodec/qsvenc.h  | 2 ++
 libavcodec/qsvenc_h264.c | 3 +++
 3 files changed, 8 insertions(+)

diff --git a/libavcodec/qsvenc.c b/libavcodec/qsvenc.c
index 948751daf4..7a031297fe 100644
--- a/libavcodec/qsvenc.c
+++ b/libavcodec/qsvenc.c
@@ -464,6 +464,9 @@ static int init_video_param(AVCodecContext *avctx, 
QSVEncContext *q)
 }
 }
 
+#if QSV_HAVE_VDENC
+q->param.mfx.LowPower   = q->low_power ? 
MFX_CODINGOPTION_ON:MFX_CODINGOPTION_OFF;
+#endif
 q->param.mfx.CodecProfile   = q->profile;
 q->param.mfx.TargetUsage= avctx->compression_level;
 q->param.mfx.GopPicSize = FFMAX(0, avctx->gop_size);
diff --git a/libavcodec/qsvenc.h b/libavcodec/qsvenc.h
index 50cc4267e7..a396aa7d3f 100644
--- a/libavcodec/qsvenc.h
+++ b/libavcodec/qsvenc.h
@@ -44,6 +44,7 @@
 #define QSV_HAVE_LA QSV_VERSION_ATLEAST(1, 7)
 #define QSV_HAVE_LA_DS  QSV_VERSION_ATLEAST(1, 8)
 #define QSV_HAVE_LA_HRD QSV_VERSION_ATLEAST(1, 11)
+#define QSV_HAVE_VDENC  QSV_VERSION_ATLEAST(1, 15)
 
 #if defined(_WIN32) || defined(__CYGWIN__)
 #define QSV_HAVE_AVBR   QSV_VERSION_ATLEAST(1, 3)
@@ -162,6 +163,7 @@ typedef struct QSVEncContext {
 int recovery_point_sei;
 
 int a53_cc;
+int low_power;
 
 #if QSV_HAVE_MF
 int mfmode;
diff --git a/libavcodec/qsvenc_h264.c b/libavcodec/qsvenc_h264.c
index 07c9d64e6b..8857959d39 100644
--- a/libavcodec/qsvenc_h264.c
+++ b/libavcodec/qsvenc_h264.c
@@ -153,6 +153,9 @@ static const AVOption options[] = {
 { "off", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MFX_MF_DISABLED }, 
INT_MIN, INT_MAX, VE, "mfmode" },
 { "auto"   , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MFX_MF_AUTO }, 
INT_MIN, INT_MAX, VE, "mfmode" },
 #endif
+#if QSV_HAVE_VDENC
+{ "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},
+#endif
 
 { NULL },
 };
-- 
2.17.1

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


[FFmpeg-devel] [PATCH] lavc/hevc_parser: add 4 bytes startcode condition in hevc_find_frame_end

2018-11-27 Thread Linjie Fu
The startcode before VPS,SPS,PPS and the first NALU in an AU is 4 bytes.
Blindly taking the startcode as 3 bytes will leave 0x00 in last packet
and may lead to some warnings in parse_nal_units when s->flags is set to
PARSER_FLAG_COMPLETE_FRAMES.

Add 4 bytes startcode condition in hevc_find_frame_end.
Modify the code to print the buf_size like in H264 and reduce the duplication.

Signed-off-by: Linjie Fu 
---
 libavcodec/hevc_parser.c | 15 ++-
 1 file changed, 10 insertions(+), 5 deletions(-)

diff --git a/libavcodec/hevc_parser.c b/libavcodec/hevc_parser.c
index 369d1338d0..aa216e3c8d 100644
--- a/libavcodec/hevc_parser.c
+++ b/libavcodec/hevc_parser.c
@@ -32,6 +32,7 @@
 #include "parser.h"
 
 #define START_CODE 0x01 ///< start_code_prefix_one_3bytes
+#define START_CODE_4 0x0001 ///< start_code_4bytes
 
 #define IS_IRAP_NAL(nal) (nal->type >= 16 && nal->type <= 23)
 #define IS_IDR_NAL(nal) (nal->type == HEVC_NAL_IDR_W_RADL || nal->type == 
HEVC_NAL_IDR_N_LP)
@@ -239,7 +240,7 @@ static int parse_nal_units(AVCodecParserContext *s, const 
uint8_t *buf,
 }
 }
 /* didn't find a picture! */
-av_log(avctx, AV_LOG_ERROR, "missing picture in access unit\n");
+av_log(avctx, AV_LOG_ERROR, "missing picture in access unit with size 
%d\n", buf_size);
 return -1;
 }
 
@@ -267,8 +268,7 @@ static int hevc_find_frame_end(AVCodecParserContext *s, 
const uint8_t *buf,
 if ((nut >= HEVC_NAL_VPS && nut <= HEVC_NAL_EOB_NUT) || nut == 
HEVC_NAL_SEI_PREFIX ||
 (nut >= 41 && nut <= 44) || (nut >= 48 && nut <= 55)) {
 if (pc->frame_start_found) {
-pc->frame_start_found = 0;
-return i - 5;
+goto found;
 }
 } else if (nut <= HEVC_NAL_RASL_R ||
(nut >= HEVC_NAL_BLA_W_LP && nut <= HEVC_NAL_CRA_NUT)) {
@@ -277,14 +277,19 @@ static int hevc_find_frame_end(AVCodecParserContext *s, 
const uint8_t *buf,
 if (!pc->frame_start_found) {
 pc->frame_start_found = 1;
 } else { // First slice of next frame found
-pc->frame_start_found = 0;
-return i - 5;
+goto found;
 }
 }
 }
 }
 
 return END_NOT_FOUND;
+
+found:
+pc->frame_start_found = 0;
+if (((pc->state64 >> 3 * 8) & 0x) == START_CODE_4)
+return i - 6;
+return i - 5;
 }
 
 static int hevc_parse(AVCodecParserContext *s, AVCodecContext *avctx,
-- 
2.17.1

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


[FFmpeg-devel] [PATCH, v2] lavc/qsvenc: assert uninitialized pict_type

2018-11-27 Thread Linjie Fu
Assert in function ff_qsv_encode to avoid using uninitialized value:

FF_DISABLE_DEPRECATION_WARNINGS
avctx->coded_frame->pict_type = pict_type;
FF_ENABLE_DEPRECATION_WARNINGS

Signed-off-by: Linjie Fu 
---
[v2] assert instead of setting the pict_type to AV_PICTURE_TYPE_NONE;

 libavcodec/qsvenc.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/libavcodec/qsvenc.c b/libavcodec/qsvenc.c
index 7a031297fe..fd9f4f0934 100644
--- a/libavcodec/qsvenc.c
+++ b/libavcodec/qsvenc.c
@@ -1333,6 +1333,8 @@ int ff_qsv_encode(AVCodecContext *avctx, QSVEncContext *q,
 pict_type = AV_PICTURE_TYPE_P;
 else if (bs->FrameType & MFX_FRAMETYPE_B || bs->FrameType & 
MFX_FRAMETYPE_xB)
 pict_type = AV_PICTURE_TYPE_B;
+else
+av_assert0(!"Uninitialized pict_type!");
 
 #if FF_API_CODED_FRAME
 FF_DISABLE_DEPRECATION_WARNINGS
-- 
2.17.1

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


[FFmpeg-devel] [PATCH,v4] lavc/qsvenc: add VDENC support for H264

2018-11-27 Thread Linjie Fu
Add VDENC(lowpower mode) support for QSV H264

It's an experimental function(like lowpower in vaapi) with
some limitations:
- CBR/VBR require HuC which should be explicitly loaded via i915
module parameter(i915.enable_guc=2 for linux kernel version >= 4.16)

Use option "-low_power 1" to enable VDENC.
Add in dump_video_param() to show the status of VDENC in runtime log.

Signed-off-by: Linjie Fu 
---
[v2]: modified the commit message and option comments, use AV_OPT_TYPE_BOOL
to replace AV_OPT_TYPE_INT.
[v3]: enable H264 VDENC separately.
[v4]: Add in dump_video_param to show the status of VDENC in runtime
log.

 libavcodec/qsvenc.c  | 11 +++
 libavcodec/qsvenc.h  |  2 ++
 libavcodec/qsvenc_h264.c |  3 +++
 3 files changed, 16 insertions(+)

diff --git a/libavcodec/qsvenc.c b/libavcodec/qsvenc.c
index 948751daf4..42804e68af 100644
--- a/libavcodec/qsvenc.c
+++ b/libavcodec/qsvenc.c
@@ -226,6 +226,14 @@ static void dump_video_param(AVCodecContext *avctx, 
QSVEncContext *q,
 av_log(avctx, AV_LOG_VERBOSE, "\n");
 #endif
 
+#if QSV_HAVE_VDENC
+av_log(avctx, AV_LOG_VERBOSE, "VDENC: ");
+if (info->LowPower == MFX_CODINGOPTION_ON)
+av_log(avctx, AV_LOG_VERBOSE, "ON\n");
+else
+av_log(avctx, AV_LOG_VERBOSE, "OFF\n");
+#endif
+
 #if QSV_VERSION_ATLEAST(1, 8)
 av_log(avctx, AV_LOG_VERBOSE,
"RepeatPPS: %s; NumMbPerSlice: %"PRIu16"; LookAheadDS: ",
@@ -464,6 +472,9 @@ static int init_video_param(AVCodecContext *avctx, 
QSVEncContext *q)
 }
 }
 
+#if QSV_HAVE_VDENC
+q->param.mfx.LowPower   = q->low_power ? 
MFX_CODINGOPTION_ON:MFX_CODINGOPTION_OFF;
+#endif
 q->param.mfx.CodecProfile   = q->profile;
 q->param.mfx.TargetUsage= avctx->compression_level;
 q->param.mfx.GopPicSize = FFMAX(0, avctx->gop_size);
diff --git a/libavcodec/qsvenc.h b/libavcodec/qsvenc.h
index 50cc4267e7..a396aa7d3f 100644
--- a/libavcodec/qsvenc.h
+++ b/libavcodec/qsvenc.h
@@ -44,6 +44,7 @@
 #define QSV_HAVE_LA QSV_VERSION_ATLEAST(1, 7)
 #define QSV_HAVE_LA_DS  QSV_VERSION_ATLEAST(1, 8)
 #define QSV_HAVE_LA_HRD QSV_VERSION_ATLEAST(1, 11)
+#define QSV_HAVE_VDENC  QSV_VERSION_ATLEAST(1, 15)
 
 #if defined(_WIN32) || defined(__CYGWIN__)
 #define QSV_HAVE_AVBR   QSV_VERSION_ATLEAST(1, 3)
@@ -162,6 +163,7 @@ typedef struct QSVEncContext {
 int recovery_point_sei;
 
 int a53_cc;
+int low_power;
 
 #if QSV_HAVE_MF
 int mfmode;
diff --git a/libavcodec/qsvenc_h264.c b/libavcodec/qsvenc_h264.c
index 07c9d64e6b..40071d805a 100644
--- a/libavcodec/qsvenc_h264.c
+++ b/libavcodec/qsvenc_h264.c
@@ -153,6 +153,9 @@ static const AVOption options[] = {
 { "off", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MFX_MF_DISABLED }, 
INT_MIN, INT_MAX, VE, "mfmode" },
 { "auto"   , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MFX_MF_AUTO }, 
INT_MIN, INT_MAX, VE, "mfmode" },
 #endif
+#if QSV_HAVE_VDENC
+{ "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},
+#endif
 
 { NULL },
 };
-- 
2.17.1

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


[FFmpeg-devel] [PATCH,v5] lavc/qsvenc: add VDENC support for H264

2018-11-28 Thread Linjie Fu
Add VDENC(lowpower mode) support for QSV H264

It's an experimental function(like lowpower in vaapi) with
some limitations:
- CBR/VBR require HuC which should be explicitly loaded via i915
module parameter(i915.enable_guc=2 for linux kernel version >= 4.16)

Use option "-low_power 1" to enable VDENC.
Add in dump_video_param() to show the status of VDENC in runtime log.

Signed-off-by: Linjie Fu 
---
[v2]: Modify the commit message and option comments, use AV_OPT_TYPE_BOOL
to replace AV_OPT_TYPE_INT.
[v3]: Enable H264 VDENC separately.
[v4]: Add in dump_video_param to show the status of VDENC in runtime
log.
[v5]: Use print_threestate.

 libavcodec/qsvenc.c  | 7 +++
 libavcodec/qsvenc.h  | 2 ++
 libavcodec/qsvenc_h264.c | 3 +++
 3 files changed, 12 insertions(+)

diff --git a/libavcodec/qsvenc.c b/libavcodec/qsvenc.c
index 948751daf4..b1ec90c6c6 100644
--- a/libavcodec/qsvenc.c
+++ b/libavcodec/qsvenc.c
@@ -226,6 +226,10 @@ static void dump_video_param(AVCodecContext *avctx, 
QSVEncContext *q,
 av_log(avctx, AV_LOG_VERBOSE, "\n");
 #endif
 
+#if QSV_HAVE_VDENC
+av_log(avctx, AV_LOG_VERBOSE, "VDENC: %s\n", 
print_threestate(info->LowPower));
+#endif
+
 #if QSV_VERSION_ATLEAST(1, 8)
 av_log(avctx, AV_LOG_VERBOSE,
"RepeatPPS: %s; NumMbPerSlice: %"PRIu16"; LookAheadDS: ",
@@ -464,6 +468,9 @@ static int init_video_param(AVCodecContext *avctx, 
QSVEncContext *q)
 }
 }
 
+#if QSV_HAVE_VDENC
+q->param.mfx.LowPower   = q->low_power ? MFX_CODINGOPTION_ON : 
MFX_CODINGOPTION_OFF;
+#endif
 q->param.mfx.CodecProfile   = q->profile;
 q->param.mfx.TargetUsage= avctx->compression_level;
 q->param.mfx.GopPicSize = FFMAX(0, avctx->gop_size);
diff --git a/libavcodec/qsvenc.h b/libavcodec/qsvenc.h
index 50cc4267e7..a396aa7d3f 100644
--- a/libavcodec/qsvenc.h
+++ b/libavcodec/qsvenc.h
@@ -44,6 +44,7 @@
 #define QSV_HAVE_LA QSV_VERSION_ATLEAST(1, 7)
 #define QSV_HAVE_LA_DS  QSV_VERSION_ATLEAST(1, 8)
 #define QSV_HAVE_LA_HRD QSV_VERSION_ATLEAST(1, 11)
+#define QSV_HAVE_VDENC  QSV_VERSION_ATLEAST(1, 15)
 
 #if defined(_WIN32) || defined(__CYGWIN__)
 #define QSV_HAVE_AVBR   QSV_VERSION_ATLEAST(1, 3)
@@ -162,6 +163,7 @@ typedef struct QSVEncContext {
 int recovery_point_sei;
 
 int a53_cc;
+int low_power;
 
 #if QSV_HAVE_MF
 int mfmode;
diff --git a/libavcodec/qsvenc_h264.c b/libavcodec/qsvenc_h264.c
index 07c9d64e6b..40071d805a 100644
--- a/libavcodec/qsvenc_h264.c
+++ b/libavcodec/qsvenc_h264.c
@@ -153,6 +153,9 @@ static const AVOption options[] = {
 { "off", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MFX_MF_DISABLED }, 
INT_MIN, INT_MAX, VE, "mfmode" },
 { "auto"   , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MFX_MF_AUTO }, 
INT_MIN, INT_MAX, VE, "mfmode" },
 #endif
+#if QSV_HAVE_VDENC
+{ "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},
+#endif
 
 { NULL },
 };
-- 
2.17.1

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


[FFmpeg-devel] [PATCH] lavc/opusenc: add frame_alloc and frame_count check to quit encode

2018-11-29 Thread Linjie Fu
Add frame_alloc and frame_count check in opus_encode_frame to avoid
the infinite loop issue.

Fix #7578.

Signed-off-by: Linjie Fu 
---
 libavcodec/opusenc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libavcodec/opusenc.c b/libavcodec/opusenc.c
index 578785f4b4..7146968fc8 100644
--- a/libavcodec/opusenc.c
+++ b/libavcodec/opusenc.c
@@ -543,7 +543,7 @@ static int opus_encode_frame(AVCodecContext *avctx, 
AVPacket *avpkt,
 ff_bufqueue_add(avctx, &s->bufqueue, av_frame_clone(frame));
 } else {
 ff_opus_psy_signal_eof(&s->psyctx);
-if (!s->afq.remaining_samples)
+if (!s->afq.remaining_samples || (!s->afq.frame_alloc && 
!s->afq.frame_count))
 return 0; /* We've been flushed and there's nothing left to encode 
*/
 }
 
-- 
2.17.1

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


  1   2   3   4   5   >