From 046a23892770accf32776bd16a2bf6ad534f42eb Mon Sep 17 00:00:00 2001 From: Gijs Peskens Date: Wed, 4 Feb 2026 09:49:02 +0100 Subject: [PATCH] rpidistro-ffmpeg: upgrade to latest upstream, 7.1.13 Upgrade rpidistro-ffmpeg to the latest upstream, some changes were made in the recipe to better match the OE recipe of the same version, x264 disabled by default due to cyclic dependency Signed-off-by: Gijs Peskens --- ...01-configure-setup-for-OE-core-usage.patch | 21 +- ...omx-replace-opt-vc-path-with-usr-lib.patch | 9 +- .../2024-fix-compile-newer-binutils.patch | 33 - ...rpi_24.patch => ffmpeg-7.1.2-rpi_28.patch} | 6521 +++++++++-------- ...eg_5.1.4.bb => rpidistro-ffmpeg_7.1.13.bb} | 125 +- 5 files changed, 3349 insertions(+), 3360 deletions(-) delete mode 100644 recipes-multimedia/rpidistro-ffmpeg/files/2024-fix-compile-newer-binutils.patch rename recipes-multimedia/rpidistro-ffmpeg/files/{0001-ffmpeg-5.1.4-rpi_24.patch => ffmpeg-7.1.2-rpi_28.patch} (87%) rename recipes-multimedia/rpidistro-ffmpeg/{rpidistro-ffmpeg_5.1.4.bb => rpidistro-ffmpeg_7.1.13.bb} (68%) diff --git a/recipes-multimedia/rpidistro-ffmpeg/files/2001-configure-setup-for-OE-core-usage.patch b/recipes-multimedia/rpidistro-ffmpeg/files/2001-configure-setup-for-OE-core-usage.patch index 5a064b8..0988eb2 100644 --- a/recipes-multimedia/rpidistro-ffmpeg/files/2001-configure-setup-for-OE-core-usage.patch +++ b/recipes-multimedia/rpidistro-ffmpeg/files/2001-configure-setup-for-OE-core-usage.patch @@ -1,4 +1,4 @@ -From 702742f9575c87ac8c496d76daf51af7d4aaebd7 Mon Sep 17 00:00:00 2001 +From 465e6fd630f406f662b344f4092ceeb402b26bcb Mon Sep 17 00:00:00 2001 From: Vincent Davis Jr Date: Sun, 9 Jun 2024 18:09:25 -0400 Subject: [PATCH] configure: setup for OE-core usage @@ -25,10 +25,10 @@ Signed-off-by: Vincent Davis Jr 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/configure b/configure -index 7214c221..7a541e63 100755 +index e4b48ee1..664b31fb 100755 --- a/configure +++ b/configure -@@ -5898,6 +5898,9 @@ enable_weak_pic() { +@@ -6178,6 +6178,9 @@ enable_weak_pic() { } enabled pic && enable_weak_pic @@ -38,7 +38,7 @@ index 7214c221..7a541e63 100755 test_cc < /dev/null 2>&1; then sdl2_cflags=$("${SDL2_CONFIG}" --cflags) sdl2_extralibs=$("${SDL2_CONFIG}" --libs) --- -2.34.1 - diff --git a/recipes-multimedia/rpidistro-ffmpeg/files/2004-libavcodec-omx-replace-opt-vc-path-with-usr-lib.patch b/recipes-multimedia/rpidistro-ffmpeg/files/2004-libavcodec-omx-replace-opt-vc-path-with-usr-lib.patch index 02c07de..2445223 100644 --- a/recipes-multimedia/rpidistro-ffmpeg/files/2004-libavcodec-omx-replace-opt-vc-path-with-usr-lib.patch +++ b/recipes-multimedia/rpidistro-ffmpeg/files/2004-libavcodec-omx-replace-opt-vc-path-with-usr-lib.patch @@ -1,4 +1,4 @@ -From 0dfb56e12fa709794525cda1471091f6699905d5 Mon Sep 17 00:00:00 2001 +From 53f736cdb4d85633286287594675e5f3c7fa8df9 Mon Sep 17 00:00:00 2001 From: Vincent Davis Jr Date: Thu, 8 Dec 2022 10:49:03 -0600 Subject: [PATCH] libavcodec: omx replace /opt/vc path with /usr/lib @@ -18,10 +18,10 @@ Signed-off-by: Vincent Davis Jr 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/omx.c b/libavcodec/omx.c -index 0a6a3083..8c6e9193 100644 +index 2c386550..f0e75216 100644 --- a/libavcodec/omx.c +++ b/libavcodec/omx.c -@@ -141,7 +141,7 @@ static av_cold OMXContext *omx_init(void *logctx, const char *libname, const cha +@@ -143,7 +143,7 @@ static av_cold OMXContext *omx_init(void *logctx, const char *libname, const cha { static const char * const libnames[] = { #if CONFIG_OMX_RPI @@ -30,6 +30,3 @@ index 0a6a3083..8c6e9193 100644 #else "libOMX_Core.so", NULL, "libOmxCore.so", NULL, --- -2.38.1 - diff --git a/recipes-multimedia/rpidistro-ffmpeg/files/2024-fix-compile-newer-binutils.patch b/recipes-multimedia/rpidistro-ffmpeg/files/2024-fix-compile-newer-binutils.patch deleted file mode 100644 index 89235ec..0000000 --- a/recipes-multimedia/rpidistro-ffmpeg/files/2024-fix-compile-newer-binutils.patch +++ /dev/null @@ -1,33 +0,0 @@ -Upstream-Status: Pending - -diff --git a/libavcodec/arm/mlpdsp_armv5te.S b/libavcodec/arm/mlpdsp_armv5te.S -index 4f9aa485fd21aabff582423703197dc0d05173dc..d31568611c30f67145e89332240dc6a5246e68c7 100644 (file) ---- a/libavcodec/arm/mlpdsp_armv5te.S -+++ b/libavcodec/arm/mlpdsp_armv5te.S -@@ -229,7 +229,7 @@ A .endif - .endif - - // Begin loop --01: -+1: - .if TOTAL_TAPS == 0 - // Things simplify a lot in this case - // In fact this could be pipelined further if it's worth it... -@@ -241,7 +241,7 @@ A .endif - str ST0, [PST, #-4]! - str ST0, [PST, #4 * (MAX_BLOCKSIZE + MAX_FIR_ORDER)] - str ST0, [PSAMP], #4 * MAX_CHANNELS -- bne 01b -+ bne 1b - .else - .if \fir_taps & 1 - .set LOAD_REG, 1 -@@ -333,7 +333,7 @@ T orr AC0, AC0, AC1 - str ST3, [PST, #-4]! - str ST2, [PST, #4 * (MAX_BLOCKSIZE + MAX_FIR_ORDER)] - str ST3, [PSAMP], #4 * MAX_CHANNELS -- bne 01b -+ bne 1b - .endif - b 99f - diff --git a/recipes-multimedia/rpidistro-ffmpeg/files/0001-ffmpeg-5.1.4-rpi_24.patch b/recipes-multimedia/rpidistro-ffmpeg/files/ffmpeg-7.1.2-rpi_28.patch similarity index 87% rename from recipes-multimedia/rpidistro-ffmpeg/files/0001-ffmpeg-5.1.4-rpi_24.patch rename to recipes-multimedia/rpidistro-ffmpeg/files/ffmpeg-7.1.2-rpi_28.patch index 016cf40..020d75e 100644 --- a/recipes-multimedia/rpidistro-ffmpeg/files/0001-ffmpeg-5.1.4-rpi_24.patch +++ b/recipes-multimedia/rpidistro-ffmpeg/files/ffmpeg-7.1.2-rpi_28.patch @@ -6,7 +6,7 @@ raspiberry pi support. --- a/configure +++ b/configure -@@ -205,6 +205,7 @@ External library support: +@@ -202,6 +202,7 @@ External library support: --disable-bzlib disable bzlib [autodetect] --disable-coreimage disable Apple CoreImage framework [autodetect] --enable-chromaprint enable audio fingerprinting with chromaprint [no] @@ -14,16 +14,16 @@ raspiberry pi support. --enable-frei0r enable frei0r video filtering [no] --enable-gcrypt enable gcrypt, needed for rtmp(t)e support if openssl, librtmp or gmp is not used [no] -@@ -281,6 +282,7 @@ External library support: - if openssl, gnutls or mbedtls is not used [no] +@@ -287,6 +288,7 @@ External library support: + --enable-libtorch enable Torch as one DNN backend [no] --enable-libtwolame enable MP2 encoding via libtwolame [no] --enable-libuavs3d enable AVS3 decoding via libuavs3d [no] + --disable-libudev disable libudev [autodetect] --enable-libv4l2 enable libv4l2/v4l-utils [no] --enable-libvidstab enable video stabilization using vid.stab [no] --enable-libvmaf enable vmaf filter via libvmaf [no] -@@ -343,12 +345,16 @@ External library support: - --enable-libmfx enable Intel MediaSDK (AKA Quick Sync Video) code via libmfx [no] +@@ -353,12 +355,16 @@ External library support: + --enable-libvpl enable Intel oneVPL code via libvpl if libmfx is not used [no] --enable-libnpp enable Nvidia Performance Primitives-based code [no] --enable-mmal enable Broadcom Multi-Media Abstraction Layer (Raspberry Pi) via MMAL [no] + --enable-sand enable sand video formats [rpi] @@ -39,7 +39,7 @@ raspiberry pi support. --disable-vaapi disable Video Acceleration API (mainly Unix/Intel) code [autodetect] --disable-vdpau disable Nvidia Video Decode and Presentation API for Unix code [autodetect] --disable-videotoolbox disable VideoToolbox code [autodetect] -@@ -1754,7 +1760,9 @@ EXTERNAL_AUTODETECT_LIBRARY_LIST=" +@@ -1844,7 +1850,9 @@ EXTERNAL_AUTODETECT_LIBRARY_LIST=" avfoundation bzlib coreimage @@ -49,7 +49,15 @@ raspiberry pi support. libxcb libxcb_shm libxcb_shape -@@ -1924,6 +1932,7 @@ HWACCEL_LIBRARY_LIST=" +@@ -1918,6 +1926,7 @@ EXTERNAL_LIBRARY_LIST=" + libcodec2 + libdav1d + libdc1394 ++ libdrm + libflite + libfontconfig + libfreetype +@@ -2027,6 +2036,7 @@ HWACCEL_LIBRARY_LIST=" mmal omx opencl @@ -57,7 +65,7 @@ raspiberry pi support. " DOCUMENT_LIST=" -@@ -1941,10 +1950,14 @@ FEATURE_LIST=" +@@ -2044,10 +2054,14 @@ FEATURE_LIST=" omx_rpi runtime_cpudetect safe_bitstream_reader @@ -66,13 +74,13 @@ raspiberry pi support. small static swscale_alpha ++ v4l2_req_hevc_vx + vout_drm + vout_egl -+ v4l2_req_hevc_vx " # this list should be kept in linking order -@@ -2501,6 +2514,7 @@ CONFIG_EXTRA=" +@@ -2624,6 +2638,7 @@ CONFIG_EXTRA=" rtpdec rtpenc_chain rv34dsp @@ -80,15 +88,15 @@ raspiberry pi support. scene_sad sinewin snappy -@@ -3011,6 +3025,7 @@ d3d11va_deps="dxva_h ID3D11VideoDecoder - dxva2_deps="dxva2api_h DXVA2_ConfigPictureDecode ole32 user32" +@@ -3150,6 +3165,7 @@ dxva2_deps="dxva2api_h DXVA2_ConfigPictu ffnvcodec_deps_any="libdl LoadLibrary" + mediacodec_deps="android mediandk" nvdec_deps="ffnvcodec" +v4l2_request_deps="linux_videodev2_h linux_media_h v4l2_timeval_to_ns libdrm libudev" vaapi_x11_deps="xlib_x11" videotoolbox_hwaccel_deps="videotoolbox pthreads" videotoolbox_hwaccel_extralibs="-framework QuartzCore" -@@ -3054,6 +3069,8 @@ hevc_dxva2_hwaccel_deps="dxva2 DXVA_PicP +@@ -3204,6 +3220,8 @@ hevc_dxva2_hwaccel_deps="dxva2 DXVA_PicP hevc_dxva2_hwaccel_select="hevc_decoder" hevc_nvdec_hwaccel_deps="nvdec" hevc_nvdec_hwaccel_select="hevc_decoder" @@ -97,7 +105,7 @@ raspiberry pi support. hevc_vaapi_hwaccel_deps="vaapi VAPictureParameterBufferHEVC" hevc_vaapi_hwaccel_select="hevc_decoder" hevc_vdpau_hwaccel_deps="vdpau VdpPictureInfoHEVC" -@@ -3539,8 +3556,11 @@ sndio_indev_deps="sndio" +@@ -3750,8 +3768,11 @@ sndio_indev_deps="sndio" sndio_outdev_deps="sndio" v4l2_indev_deps_any="linux_videodev2_h sys_videoio_h" v4l2_indev_suggest="libv4l2" @@ -109,15 +117,31 @@ raspiberry pi support. vfwcap_indev_deps="vfw32 vfwcap_defines" xcbgrab_indev_deps="libxcb" xcbgrab_indev_suggest="libxcb_shm libxcb_shape libxcb_xfixes" -@@ -3745,6 +3765,7 @@ tonemap_opencl_filter_deps="opencl const - transpose_opencl_filter_deps="opencl" +@@ -3858,6 +3879,7 @@ cropdetect_filter_deps="gpl" + deinterlace_qsv_filter_deps="libmfx" + deinterlace_qsv_filter_select="qsvvpp" + deinterlace_vaapi_filter_deps="vaapi" ++deinterlace_v4l2m2m_filter_deps="libdrm v4l2_m2m" + delogo_filter_deps="gpl" + denoise_vaapi_filter_deps="vaapi" + derain_filter_select="dnn" +@@ -3966,6 +3988,7 @@ transpose_opencl_filter_deps="opencl" transpose_vaapi_filter_deps="vaapi VAProcPipelineCaps_rotation_flags" + transpose_vt_filter_deps="videotoolbox VTPixelRotationSessionCreate" transpose_vulkan_filter_deps="vulkan spirv_compiler" +unsand_filter_select="sand" unsharp_opencl_filter_deps="opencl" uspp_filter_deps="gpl avcodec" vaguedenoiser_filter_deps="gpl" -@@ -6296,6 +6317,12 @@ if enabled xlib; then +@@ -3977,6 +4000,7 @@ libvmaf_cuda_filter_deps="libvmaf libvma + zmq_filter_deps="libzmq" + zoompan_filter_deps="swscale" + zscale_filter_deps="libzimg const_nan" ++scale_v4l2m2m_filter_deps="libdrm v4l2_m2m" + scale_vaapi_filter_deps="vaapi" + scale_vt_filter_deps="videotoolbox VTPixelTransferSessionCreate" + scale_vulkan_filter_deps="vulkan spirv_compiler" +@@ -6644,6 +6668,12 @@ if enabled xlib; then disable xlib fi @@ -130,7 +154,7 @@ raspiberry pi support. check_headers direct.h check_headers dirent.h check_headers dxgidebug.h -@@ -6735,8 +6762,16 @@ enabled rkmpp && { require_p +@@ -7134,8 +7164,16 @@ enabled rkmpp && { require_p { enabled libdrm || die "ERROR: rkmpp requires --enable-libdrm"; } } @@ -138,7 +162,7 @@ raspiberry pi support. + die "ERROR: v4l2-request requires --enable-libdrm"; } && + { enabled libudev || + die "ERROR: v4l2-request requires libudev"; } - enabled vapoursynth && require_pkg_config vapoursynth "vapoursynth-script >= 42" VSScript.h vsscript_init + enabled vapoursynth && require_headers "vapoursynth/VSScript4.h vapoursynth/VapourSynth4.h" +enabled vout_drm && { enabled libdrm || die "ERROR: vout_drm requires --enable-libdrm"; } + @@ -147,7 +171,7 @@ raspiberry pi support. if enabled gcrypt; then GCRYPT_CONFIG="${cross_prefix}libgcrypt-config" -@@ -6817,6 +6852,10 @@ if enabled v4l2_m2m; then +@@ -7218,6 +7256,10 @@ if enabled v4l2_m2m; then check_cc vp9_v4l2_m2m linux/videodev2.h "int i = V4L2_PIX_FMT_VP9;" fi @@ -158,9 +182,9 @@ raspiberry pi support. check_headers sys/videoio.h test_code cc sys/videoio.h "struct v4l2_frmsizeenum vfse; vfse.discrete.width = 0;" && enable_sanitized struct_v4l2_frmivalenum_discrete -@@ -7305,6 +7344,9 @@ check_deps $CONFIG_LIST \ - - enabled threads && ! enabled pthreads && ! enabled atomics_native && die "non pthread threading without atomics not supported, try adding --enable-pthreads or --cpu=i486 or higher if you are on x86" +@@ -7730,6 +7772,9 @@ enabled threads || warn \ + "that the libraries from this build MUST NOT be used in a multi-threaded"\ + "environment." +# Sub-feature of hevc_v4l2request_hwaccel - can only be set once deps are done +enabled hevc_v4l2request_hwaccel && disabled hevc_v4l2_request && enable v4l2_req_hevc_vx @@ -168,61 +192,36 @@ raspiberry pi support. case $target_os in haiku) disable memalign ---- a/fftools/ffmpeg.c -+++ b/fftools/ffmpeg.c -@@ -1953,8 +1953,8 @@ static int ifilter_send_frame(InputFilte - av_channel_layout_compare(&ifilter->ch_layout, &frame->ch_layout); - break; - case AVMEDIA_TYPE_VIDEO: -- need_reinit |= ifilter->width != frame->width || -- ifilter->height != frame->height; -+ need_reinit |= ifilter->width != av_frame_cropped_width(frame) || -+ ifilter->height != av_frame_cropped_height(frame); - break; +--- a/fftools/ffmpeg.h ++++ b/fftools/ffmpeg.h +@@ -715,6 +715,8 @@ extern enum VideoSyncMethod video_sync_m + extern float frame_drop_threshold; + extern int do_benchmark; + extern int do_benchmark_all; ++extern int no_cvt_hw; ++extern int do_deinterlace; + extern int do_hex_dump; + extern int do_pkt_dump; + extern int copy_ts; +--- a/fftools/ffmpeg_dec.c ++++ b/fftools/ffmpeg_dec.c +@@ -392,7 +392,7 @@ static int video_frame_process(DecoderPr } + #endif -@@ -1965,6 +1965,9 @@ static int ifilter_send_frame(InputFilte - (ifilter->hw_frames_ctx && ifilter->hw_frames_ctx->data != frame->hw_frames_ctx->data)) - need_reinit = 1; - -+ if (no_cvt_hw && fg->graph) -+ need_reinit = 0; -+ - if (sd = av_frame_get_side_data(frame, AV_FRAME_DATA_DISPLAYMATRIX)) { - if (!ifilter->displaymatrix || memcmp(sd->data, ifilter->displaymatrix, sizeof(int32_t) * 9)) - need_reinit = 1; -@@ -2220,8 +2223,7 @@ static int decode_video(InputStream *ist - decoded_frame->top_field_first = ist->top_field_first; - - ist->frames_decoded++; -- -- if (ist->hwaccel_retrieve_data && decoded_frame->format == ist->hwaccel_pix_fmt) { -+ if (!no_cvt_hw && ist->hwaccel_retrieve_data && decoded_frame->format == ist->hwaccel_pix_fmt) { - err = ist->hwaccel_retrieve_data(ist->dec_ctx, decoded_frame); +- if (frame->format == dp->hwaccel_pix_fmt) { ++ if (!no_cvt_hw && frame->format == dp->hwaccel_pix_fmt) { + int err = hwaccel_retrieve_data(dp->dec_ctx, frame); if (err < 0) - goto fail; -@@ -2418,7 +2420,12 @@ static int process_input_packet(InputStr - case AVMEDIA_TYPE_VIDEO: - ret = decode_video (ist, repeating ? NULL : avpkt, &got_output, &duration_pts, !pkt, - &decode_failed); -- if (!repeating || !pkt || got_output) { -+ // Pi: Do not inc dts if no_cvt_hw set -+ // V4L2 H264 decode has long latency and sometimes spits out a long -+ // stream of output without input. In this case incrementing DTS is wrong. -+ // There may be cases where the condition as written is correct so only -+ // "fix" in the cases which cause problems -+ if (!repeating || !pkt || (got_output && !no_cvt_hw)) { - if (pkt && pkt->duration) { - duration_dts = av_rescale_q(pkt->duration, ist->st->time_base, AV_TIME_BASE_Q); - } else if(ist->dec_ctx->framerate.num != 0 && ist->dec_ctx->framerate.den != 0) { -@@ -2564,12 +2571,15 @@ static enum AVPixelFormat get_format(AVC + return err; +@@ -1333,12 +1333,15 @@ static enum AVPixelFormat get_format(AVC break; - if (ist->hwaccel_id == HWACCEL_GENERIC || -- ist->hwaccel_id == HWACCEL_AUTO) { -+ ist->hwaccel_id == HWACCEL_AUTO || -+ no_cvt_hw) { - for (i = 0;; i++) { + if (dp->hwaccel_id == HWACCEL_GENERIC || +- dp->hwaccel_id == HWACCEL_AUTO) { ++ dp->hwaccel_id == HWACCEL_AUTO || ++ no_cvt_hw) { + for (int i = 0;; i++) { config = avcodec_get_hw_config(s->codec, i); if (!config) break; @@ -233,32 +232,32 @@ raspiberry pi support. AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX)) continue; if (config->pix_fmt == *p) ---- a/fftools/ffmpeg.h -+++ b/fftools/ffmpeg.h -@@ -626,6 +626,7 @@ extern enum VideoSyncMethod video_sync_m - extern float frame_drop_threshold; - extern int do_benchmark; - extern int do_benchmark_all; -+extern int no_cvt_hw; - extern int do_deinterlace; - extern int do_hex_dump; - extern int do_pkt_dump; --- a/fftools/ffmpeg_filter.c +++ b/fftools/ffmpeg_filter.c -@@ -1175,8 +1175,8 @@ int ifilter_parameters_from_frame(InputF +@@ -2791,8 +2791,8 @@ static int send_frame(FilterGraph *fg, F + break; + case AVMEDIA_TYPE_VIDEO: + if (ifp->format != frame->format || +- ifp->width != frame->width || +- ifp->height != frame->height || ++ ifp->width != av_frame_cropped_width(frame) || ++ ifp->height != av_frame_cropped_height(frame) || + ifp->color_space != frame->colorspace || + ifp->color_range != frame->color_range) + need_reinit |= VIDEO_CHANGED; +@@ -2813,6 +2813,9 @@ static int send_frame(FilterGraph *fg, F + (ifp->hw_frames_ctx && ifp->hw_frames_ctx->data != frame->hw_frames_ctx->data)) + need_reinit |= HWACCEL_CHANGED; - ifilter->format = frame->format; - -- ifilter->width = frame->width; -- ifilter->height = frame->height; -+ ifilter->width = av_frame_cropped_width(frame); -+ ifilter->height = av_frame_cropped_height(frame); - ifilter->sample_aspect_ratio = frame->sample_aspect_ratio; - - ifilter->sample_rate = frame->sample_rate; ++ if (no_cvt_hw && fgt->graph) ++ need_reinit = 0; ++ + if (need_reinit) { + ret = ifilter_parameters_from_frame(ifilter, frame); + if (ret < 0) --- a/fftools/ffmpeg_hw.c +++ b/fftools/ffmpeg_hw.c -@@ -75,6 +75,8 @@ static char *hw_device_default_name(enum +@@ -73,6 +73,8 @@ static char *hw_device_default_name(enum char *name; size_t index_pos; int index, index_limit = 1000; @@ -269,7 +268,7 @@ raspiberry pi support. if (!name) --- a/fftools/ffmpeg_opt.c +++ b/fftools/ffmpeg_opt.c -@@ -162,6 +162,7 @@ enum VideoSyncMethod video_sync_method = +@@ -62,6 +62,7 @@ enum VideoSyncMethod video_sync_method = float frame_drop_threshold = 0; int do_benchmark = 0; int do_benchmark_all = 0; @@ -277,18 +276,23 @@ raspiberry pi support. int do_hex_dump = 0; int do_pkt_dump = 0; int copy_ts = 0; -@@ -3724,6 +3725,8 @@ const OptionDef options[] = { - "add timings for benchmarking" }, - { "benchmark_all", OPT_BOOL | OPT_EXPERT, { &do_benchmark_all }, +@@ -1574,8 +1575,11 @@ const OptionDef options[] = { + { "benchmark_all", OPT_TYPE_BOOL, OPT_EXPERT, + { &do_benchmark_all }, "add timings for each task" }, -+ { "no_cvt_hw", OPT_BOOL | OPT_EXPERT, { &no_cvt_hw }, +- { "progress", OPT_TYPE_FUNC, OPT_FUNC_ARG | OPT_EXPERT, +- { .func_arg = opt_progress }, ++ { "no_cvt_hw", OPT_TYPE_BOOL, OPT_EXPERT, ++ { &no_cvt_hw }, + "do not auto-convert hw frames to sw" }, - { "progress", HAS_ARG | OPT_EXPERT, { .func_arg = opt_progress }, ++ { "progress", OPT_TYPE_FUNC, OPT_FUNC_ARG | OPT_EXPERT, ++ { .func_arg = opt_progress }, "write program-readable progress information", "url" }, - { "stdin", OPT_BOOL | OPT_EXPERT, { &stdin_interaction }, + { "stdin", OPT_TYPE_BOOL, OPT_EXPERT, + { &stdin_interaction }, --- a/libavcodec/Makefile +++ b/libavcodec/Makefile -@@ -161,7 +161,10 @@ OBJS-$(CONFIG_VIDEODSP) + +@@ -175,7 +175,10 @@ OBJS-$(CONFIG_VIDEODSP) + OBJS-$(CONFIG_VP3DSP) += vp3dsp.o OBJS-$(CONFIG_VP56DSP) += vp56dsp.o OBJS-$(CONFIG_VP8DSP) += vp8dsp.o @@ -300,35 +304,15 @@ raspiberry pi support. OBJS-$(CONFIG_WMA_FREQS) += wma_freqs.o OBJS-$(CONFIG_WMV2DSP) += wmv2dsp.o -@@ -972,6 +975,8 @@ OBJS-$(CONFIG_HEVC_D3D11VA_HWACCEL) - OBJS-$(CONFIG_HEVC_DXVA2_HWACCEL) += dxva2_hevc.o +@@ -1025,6 +1028,8 @@ OBJS-$(CONFIG_HEVC_DXVA2_HWACCEL) + OBJS-$(CONFIG_HEVC_D3D12VA_HWACCEL) += dxva2_hevc.o d3d12va_hevc.o OBJS-$(CONFIG_HEVC_NVDEC_HWACCEL) += nvdec_hevc.o OBJS-$(CONFIG_HEVC_QSV_HWACCEL) += qsvdec.o +OBJS-$(CONFIG_HEVC_V4L2REQUEST_HWACCEL) += v4l2_request_hevc.o v4l2_req_decode_q.o v4l2_req_hevc_v4.o +OBJS-$(CONFIG_V4L2_REQ_HEVC_VX) += v4l2_req_hevc_v1.o v4l2_req_hevc_v2.o v4l2_req_hevc_v3.o OBJS-$(CONFIG_HEVC_VAAPI_HWACCEL) += vaapi_hevc.o h265_profile_level.o OBJS-$(CONFIG_HEVC_VDPAU_HWACCEL) += vdpau_hevc.o h265_profile_level.o - OBJS-$(CONFIG_MJPEG_NVDEC_HWACCEL) += nvdec_mjpeg.o ---- a/libavcodec/avcodec.h -+++ b/libavcodec/avcodec.h -@@ -2212,6 +2212,17 @@ typedef struct AVHWAccel { - * that avctx->hwaccel_priv_data is invalid. - */ - int (*frame_params)(AVCodecContext *avctx, AVBufferRef *hw_frames_ctx); -+ -+ /** -+ * Called if parsing fails -+ * -+ * An error has occured, end_frame will not be called -+ * start_frame & decode_slice may or may not have been called -+ * Optional -+ * -+ * @param avctx the codec context -+ */ -+ void (*abort_frame)(AVCodecContext *avctx); - } AVHWAccel; - - /** + OBJS-$(CONFIG_HEVC_VULKAN_HWACCEL) += vulkan_decode.o vulkan_hevc.o --- /dev/null +++ b/libavcodec/hevc-ctrls-v1.h @@ -0,0 +1,229 @@ @@ -1606,94 +1590,15 @@ raspiberry pi support. +}; + +#endif ---- a/libavcodec/hevc_parser.c -+++ b/libavcodec/hevc_parser.c -@@ -97,6 +97,19 @@ static int hevc_parse_slice_header(AVCod - avctx->profile = ps->sps->ptl.general_ptl.profile_idc; - avctx->level = ps->sps->ptl.general_ptl.level_idc; - -+ if (ps->sps->chroma_format_idc == 1) { -+ avctx->chroma_sample_location = ps->sps->vui.chroma_loc_info_present_flag ? -+ ps->sps->vui.chroma_sample_loc_type_top_field + 1 : -+ AVCHROMA_LOC_LEFT; -+ } -+ else if (ps->sps->chroma_format_idc == 2 || -+ ps->sps->chroma_format_idc == 3) { -+ avctx->chroma_sample_location = AVCHROMA_LOC_TOPLEFT;; -+ } -+ else { -+ avctx->chroma_sample_location = AVCHROMA_LOC_UNSPECIFIED; -+ } -+ - if (ps->vps->vps_timing_info_present_flag) { - num = ps->vps->vps_num_units_in_tick; - den = ps->vps->vps_time_scale; ---- a/libavcodec/hevc_refs.c -+++ b/libavcodec/hevc_refs.c -@@ -98,18 +98,22 @@ static HEVCFrame *alloc_frame(HEVCContex - if (!frame->rpl_buf) - goto fail; - -- frame->tab_mvf_buf = av_buffer_pool_get(s->tab_mvf_pool); -- if (!frame->tab_mvf_buf) -- goto fail; -- frame->tab_mvf = (MvField *)frame->tab_mvf_buf->data; -+ if (s->tab_mvf_pool) { -+ frame->tab_mvf_buf = av_buffer_pool_get(s->tab_mvf_pool); -+ if (!frame->tab_mvf_buf) -+ goto fail; -+ frame->tab_mvf = (MvField *)frame->tab_mvf_buf->data; -+ } - -- frame->rpl_tab_buf = av_buffer_pool_get(s->rpl_tab_pool); -- if (!frame->rpl_tab_buf) -- goto fail; -- frame->rpl_tab = (RefPicListTab **)frame->rpl_tab_buf->data; -- frame->ctb_count = s->ps.sps->ctb_width * s->ps.sps->ctb_height; -- for (j = 0; j < frame->ctb_count; j++) -- frame->rpl_tab[j] = (RefPicListTab *)frame->rpl_buf->data; -+ if (s->rpl_tab_pool) { -+ frame->rpl_tab_buf = av_buffer_pool_get(s->rpl_tab_pool); -+ if (!frame->rpl_tab_buf) -+ goto fail; -+ frame->rpl_tab = (RefPicListTab **)frame->rpl_tab_buf->data; -+ frame->ctb_count = s->ps.sps->ctb_width * s->ps.sps->ctb_height; -+ for (j = 0; j < frame->ctb_count; j++) -+ frame->rpl_tab[j] = (RefPicListTab *)frame->rpl_buf->data; -+ } - - frame->frame->top_field_first = s->sei.picture_timing.picture_struct == AV_PICTURE_STRUCTURE_TOP_FIELD; - frame->frame->interlaced_frame = (s->sei.picture_timing.picture_struct == AV_PICTURE_STRUCTURE_TOP_FIELD) || (s->sei.picture_timing.picture_struct == AV_PICTURE_STRUCTURE_BOTTOM_FIELD); -@@ -284,14 +288,17 @@ static int init_slice_rpl(HEVCContext *s - int ctb_count = frame->ctb_count; - int ctb_addr_ts = s->ps.pps->ctb_addr_rs_to_ts[s->sh.slice_segment_addr]; - int i; -+ RefPicListTab * const tab = (RefPicListTab *)frame->rpl_buf->data + s->slice_idx; - - if (s->slice_idx >= frame->rpl_buf->size / sizeof(RefPicListTab)) - return AVERROR_INVALIDDATA; - -- for (i = ctb_addr_ts; i < ctb_count; i++) -- frame->rpl_tab[i] = (RefPicListTab *)frame->rpl_buf->data + s->slice_idx; -+ if (frame->rpl_tab) { -+ for (i = ctb_addr_ts; i < ctb_count; i++) -+ frame->rpl_tab[i] = tab; -+ } - -- frame->refPicList = (RefPicList *)frame->rpl_tab[ctb_addr_ts]; -+ frame->refPicList = tab->refPicList; - - return 0; - } ---- a/libavcodec/hevcdec.c -+++ b/libavcodec/hevcdec.c -@@ -340,6 +340,19 @@ static void export_stream_params(HEVCCon - - ff_set_sar(avctx, sps->vui.sar); +--- a/libavcodec/hevc/hevcdec.c ++++ b/libavcodec/hevc/hevcdec.c +@@ -367,6 +367,19 @@ static void export_stream_params(HEVCCon + else + avctx->color_range = AVCOL_RANGE_MPEG; + if (sps->chroma_format_idc == 1) { -+ avctx->chroma_sample_location = sps->vui.chroma_loc_info_present_flag ? -+ sps->vui.chroma_sample_loc_type_top_field + 1 : ++ avctx->chroma_sample_location = sps->vui.common.chroma_loc_info_present_flag ? ++ sps->vui.common.chroma_sample_loc_type_top_field + 1 : + AVCHROMA_LOC_LEFT; + } + else if (sps->chroma_format_idc == 2 || @@ -1704,20 +1609,20 @@ raspiberry pi support. + avctx->chroma_sample_location = AVCHROMA_LOC_UNSPECIFIED; + } + - if (sps->vui.video_signal_type_present_flag) - avctx->color_range = sps->vui.video_full_range_flag ? AVCOL_RANGE_JPEG - : AVCOL_RANGE_MPEG; -@@ -402,6 +415,7 @@ static enum AVPixelFormat get_format(HEV - #define HWACCEL_MAX (CONFIG_HEVC_DXVA2_HWACCEL + \ + if (sps->vui.common.colour_description_present_flag) { + avctx->color_primaries = sps->vui.common.colour_primaries; + avctx->color_trc = sps->vui.common.transfer_characteristics; +@@ -528,6 +541,7 @@ static enum AVPixelFormat get_format(HEV CONFIG_HEVC_D3D11VA_HWACCEL * 2 + \ + CONFIG_HEVC_D3D12VA_HWACCEL + \ CONFIG_HEVC_NVDEC_HWACCEL + \ + CONFIG_HEVC_V4L2REQUEST_HWACCEL + \ CONFIG_HEVC_VAAPI_HWACCEL + \ CONFIG_HEVC_VIDEOTOOLBOX_HWACCEL + \ - CONFIG_HEVC_VDPAU_HWACCEL) -@@ -429,6 +443,9 @@ static enum AVPixelFormat get_format(HEV - #if CONFIG_HEVC_VIDEOTOOLBOX_HWACCEL - *fmt++ = AV_PIX_FMT_VIDEOTOOLBOX; + CONFIG_HEVC_VDPAU_HWACCEL + \ +@@ -563,6 +577,9 @@ static enum AVPixelFormat get_format(HEV + #if CONFIG_HEVC_VULKAN_HWACCEL + *fmt++ = AV_PIX_FMT_VULKAN; #endif +#if CONFIG_HEVC_V4L2REQUEST_HWACCEL + *fmt++ = AV_PIX_FMT_DRM_PRIME; @@ -1725,7 +1630,7 @@ raspiberry pi support. break; case AV_PIX_FMT_YUV420P10: #if CONFIG_HEVC_DXVA2_HWACCEL -@@ -450,6 +467,9 @@ static enum AVPixelFormat get_format(HEV +@@ -590,6 +607,9 @@ static enum AVPixelFormat get_format(HEV #if CONFIG_HEVC_NVDEC_HWACCEL *fmt++ = AV_PIX_FMT_CUDA; #endif @@ -1734,87 +1639,78 @@ raspiberry pi support. +#endif break; case AV_PIX_FMT_YUV444P: - #if CONFIG_HEVC_VDPAU_HWACCEL -@@ -504,6 +524,16 @@ static int set_sps(HEVCContext *s, const + #if CONFIG_HEVC_VAAPI_HWACCEL +@@ -683,13 +703,16 @@ static int set_sps(HEVCContext *s, HEVCL if (!sps) return 0; +- ret = pic_arrays_init(l, sps); +- if (ret < 0) +- goto fail; + // If hwaccel then we don't need all the s/w decode helper arrays -+ if (s->avctx->hwaccel) { -+ export_stream_params(s, sps); -+ -+ s->avctx->pix_fmt = pix_fmt; -+ s->ps.sps = sps; -+ s->ps.vps = (HEVCVPS*) s->ps.vps_list[s->ps.sps->vps_id]->data; -+ return 0; -+ } -+ - ret = pic_arrays_init(s, sps); - if (ret < 0) - goto fail; -@@ -3011,11 +3041,13 @@ static int hevc_frame_start(HEVCContext - ((s->ps.sps->height >> s->ps.sps->log2_min_cb_size) + 1); - int ret; ++ if (!s->avctx->hwaccel) { ++ ret = pic_arrays_init(l, sps); ++ if (ret < 0) ++ goto fail; -- memset(s->horizontal_bs, 0, s->bs_width * s->bs_height); -- memset(s->vertical_bs, 0, s->bs_width * s->bs_height); -- memset(s->cbf_luma, 0, s->ps.sps->min_tb_width * s->ps.sps->min_tb_height); -- memset(s->is_pcm, 0, (s->ps.sps->min_pu_width + 1) * (s->ps.sps->min_pu_height + 1)); -- memset(s->tab_slice_address, -1, pic_size_in_ctb * sizeof(*s->tab_slice_address)); -+ if (s->horizontal_bs) { -+ memset(s->horizontal_bs, 0, s->bs_width * s->bs_height); -+ memset(s->vertical_bs, 0, s->bs_width * s->bs_height); -+ memset(s->cbf_luma, 0, s->ps.sps->min_tb_width * s->ps.sps->min_tb_height); -+ memset(s->is_pcm, 0, (s->ps.sps->min_pu_width + 1) * (s->ps.sps->min_pu_height + 1)); -+ memset(s->tab_slice_address, -1, pic_size_in_ctb * sizeof(*s->tab_slice_address)); +- ff_hevc_pred_init(&s->hpc, sps->bit_depth); +- ff_hevc_dsp_init (&s->hevcdsp, sps->bit_depth); +- ff_videodsp_init (&s->vdsp, sps->bit_depth); ++ ff_hevc_pred_init(&s->hpc, sps->bit_depth); ++ ff_hevc_dsp_init (&s->hevcdsp, sps->bit_depth); ++ ff_videodsp_init (&s->vdsp, sps->bit_depth); + } - s->is_decoded = 0; - s->first_nal_type = s->nal_unit_type; -@@ -3507,8 +3539,13 @@ static int hevc_decode_frame(AVCodecCont + l->sps = ff_refstruct_ref_c(sps); + s->vps = ff_refstruct_ref_c(sps->vps); +@@ -3210,11 +3233,13 @@ static int hevc_frame_start(HEVCContext + } + } + +- memset(l->horizontal_bs, 0, l->bs_width * l->bs_height); +- memset(l->vertical_bs, 0, l->bs_width * l->bs_height); +- memset(l->cbf_luma, 0, sps->min_tb_width * sps->min_tb_height); +- memset(l->is_pcm, 0, (sps->min_pu_width + 1) * (sps->min_pu_height + 1)); +- memset(l->tab_slice_address, -1, pic_size_in_ctb * sizeof(*l->tab_slice_address)); ++ if (l->horizontal_bs) { ++ memset(l->horizontal_bs, 0, l->bs_width * l->bs_height); ++ memset(l->vertical_bs, 0, l->bs_width * l->bs_height); ++ memset(l->cbf_luma, 0, sps->min_tb_width * sps->min_tb_height); ++ memset(l->is_pcm, 0, (sps->min_pu_width + 1) * (sps->min_pu_height + 1)); ++ memset(l->tab_slice_address, -1, pic_size_in_ctb * sizeof(*l->tab_slice_address)); ++ } + + if (IS_IDR(s)) + ff_hevc_clear_refs(l); +@@ -3782,8 +3807,13 @@ static int hevc_receive_frame(AVCodecCon + } - s->ref = NULL; ret = decode_nal_units(s, avpkt->data, avpkt->size); - if (ret < 0) + if (ret < 0) { + // Ensure that hwaccel knows this frame is over -+ if (s->avctx->hwaccel && s->avctx->hwaccel->abort_frame) -+ s->avctx->hwaccel->abort_frame(s->avctx); ++ if (FF_HW_HAS_CB(avctx, abort_frame)) ++ FF_HW_SIMPLE_CALL(avctx, abort_frame); + return ret; + } - if (avctx->hwaccel) { - if (s->ref && (ret = avctx->hwaccel->end_frame(avctx)) < 0) { -@@ -3558,15 +3595,19 @@ static int hevc_ref_frame(HEVCContext *s - dst->needs_fg = 1; + do_output: + if (ff_container_fifo_read(s->output_fifo, frame) >= 0) { +@@ -3812,8 +3842,10 @@ static int hevc_ref_frame(HEVCFrame *dst } -- dst->tab_mvf_buf = av_buffer_ref(src->tab_mvf_buf); -- if (!dst->tab_mvf_buf) -- goto fail; -- dst->tab_mvf = src->tab_mvf; -+ if (src->tab_mvf_buf) { -+ dst->tab_mvf_buf = av_buffer_ref(src->tab_mvf_buf); -+ if (!dst->tab_mvf_buf) -+ goto fail; -+ dst->tab_mvf = src->tab_mvf; -+ } + dst->pps = ff_refstruct_ref_c(src->pps); +- dst->tab_mvf = ff_refstruct_ref(src->tab_mvf); +- dst->rpl_tab = ff_refstruct_ref(src->rpl_tab); ++ if (src->tab_mvf) ++ dst->tab_mvf = ff_refstruct_ref(src->tab_mvf); ++ if (src->rpl_tab) ++ dst->rpl_tab = ff_refstruct_ref(src->rpl_tab); + dst->rpl = ff_refstruct_ref(src->rpl); + dst->nb_rpl_elems = src->nb_rpl_elems; -- dst->rpl_tab_buf = av_buffer_ref(src->rpl_tab_buf); -- if (!dst->rpl_tab_buf) -- goto fail; -- dst->rpl_tab = src->rpl_tab; -+ if (src->rpl_tab_buf) { -+ dst->rpl_tab_buf = av_buffer_ref(src->rpl_tab_buf); -+ if (!dst->rpl_tab_buf) -+ goto fail; -+ dst->rpl_tab = src->rpl_tab; -+ } - - dst->rpl_buf = av_buffer_ref(src->rpl_buf); - if (!dst->rpl_buf) -@@ -3900,6 +3941,9 @@ const FFCodec ff_hevc_decoder = { +@@ -4125,6 +4157,9 @@ const FFCodec ff_hevc_decoder = { #if CONFIG_HEVC_NVDEC_HWACCEL HWACCEL_NVDEC(hevc), #endif @@ -1824,27 +1720,114 @@ raspiberry pi support. #if CONFIG_HEVC_VAAPI_HWACCEL HWACCEL_VAAPI(hevc), #endif +--- a/libavcodec/hevc/parser.c ++++ b/libavcodec/hevc/parser.c +@@ -93,6 +93,19 @@ static int hevc_parse_slice_header(AVCod + avctx->profile = sps->ptl.general_ptl.profile_idc; + avctx->level = sps->ptl.general_ptl.level_idc; + ++ if (sps->chroma_format_idc == 1) { ++ avctx->chroma_sample_location = sps->vui.common.chroma_loc_info_present_flag ? ++ sps->vui.common.chroma_sample_loc_type_top_field + 1 : ++ AVCHROMA_LOC_LEFT; ++ } ++ else if (sps->chroma_format_idc == 2 || ++ sps->chroma_format_idc == 3) { ++ avctx->chroma_sample_location = AVCHROMA_LOC_TOPLEFT;; ++ } ++ else { ++ avctx->chroma_sample_location = AVCHROMA_LOC_UNSPECIFIED; ++ } ++ + if (sps->vps->vps_timing_info_present_flag) { + num = sps->vps->vps_num_units_in_tick; + den = sps->vps->vps_time_scale; +--- a/libavcodec/hevc/refs.c ++++ b/libavcodec/hevc/refs.c +@@ -140,16 +140,19 @@ static HEVCFrame *alloc_frame(HEVCContex + goto fail; + frame->nb_rpl_elems = s->pkt.nb_nals; + +- frame->tab_mvf = ff_refstruct_pool_get(l->tab_mvf_pool); +- if (!frame->tab_mvf) +- goto fail; +- +- frame->rpl_tab = ff_refstruct_pool_get(l->rpl_tab_pool); +- if (!frame->rpl_tab) +- goto fail; +- frame->ctb_count = l->sps->ctb_width * l->sps->ctb_height; +- for (j = 0; j < frame->ctb_count; j++) +- frame->rpl_tab[j] = frame->rpl; ++ if (l->tab_mvf_pool) { ++ frame->tab_mvf = ff_refstruct_pool_get(l->tab_mvf_pool); ++ if (!frame->tab_mvf) ++ goto fail; ++ } ++ if (l->rpl_tab_pool) { ++ frame->rpl_tab = ff_refstruct_pool_get(l->rpl_tab_pool); ++ if (!frame->rpl_tab) ++ goto fail; ++ frame->ctb_count = l->sps->ctb_width * l->sps->ctb_height; ++ for (j = 0; j < frame->ctb_count; j++) ++ frame->rpl_tab[j] = frame->rpl; ++ } + + if (s->sei.picture_timing.picture_struct == AV_PICTURE_STRUCTURE_TOP_FIELD) + frame->f->flags |= AV_FRAME_FLAG_TOP_FIELD_FIRST; +@@ -287,14 +290,17 @@ static int init_slice_rpl(HEVCContext *s + int ctb_count = frame->ctb_count; + int ctb_addr_ts = s->pps->ctb_addr_rs_to_ts[s->sh.slice_segment_addr]; + int i; ++ RefPicListTab * const rpl = frame->rpl + s->slice_idx; + + if (s->slice_idx >= frame->nb_rpl_elems) + return AVERROR_INVALIDDATA; + +- for (i = ctb_addr_ts; i < ctb_count; i++) +- frame->rpl_tab[i] = frame->rpl + s->slice_idx; ++ if (frame->rpl_tab) { ++ for (i = ctb_addr_ts; i < ctb_count; i++) ++ frame->rpl_tab[i] = rpl; ++ } + +- frame->refPicList = (RefPicList *)frame->rpl_tab[ctb_addr_ts]; ++ frame->refPicList = (RefPicList *)rpl; + + return 0; + } +--- a/libavcodec/hwaccel_internal.h ++++ b/libavcodec/hwaccel_internal.h +@@ -161,6 +161,17 @@ typedef struct FFHWAccel { + * Callback to flush the hwaccel state. + */ + void (*flush)(AVCodecContext *avctx); ++ ++ /** ++ * Called if parsing fails ++ * ++ * An error has occured, end_frame will not be called ++ * start_frame & decode_slice may or may not have been called ++ * Optional ++ * ++ * @param avctx the codec context ++ */ ++ void (*abort_frame)(AVCodecContext *avctx); + } FFHWAccel; + + static inline const FFHWAccel *ffhwaccel(const AVHWAccel *codec) --- a/libavcodec/hwaccels.h +++ b/libavcodec/hwaccels.h -@@ -40,6 +40,7 @@ extern const AVHWAccel ff_hevc_d3d11va_h - extern const AVHWAccel ff_hevc_d3d11va2_hwaccel; - extern const AVHWAccel ff_hevc_dxva2_hwaccel; - extern const AVHWAccel ff_hevc_nvdec_hwaccel; -+extern const AVHWAccel ff_hevc_v4l2request_hwaccel; - extern const AVHWAccel ff_hevc_vaapi_hwaccel; - extern const AVHWAccel ff_hevc_vdpau_hwaccel; - extern const AVHWAccel ff_hevc_videotoolbox_hwaccel; +@@ -43,6 +43,7 @@ extern const struct FFHWAccel ff_hevc_d3 + extern const struct FFHWAccel ff_hevc_d3d12va_hwaccel; + extern const struct FFHWAccel ff_hevc_dxva2_hwaccel; + extern const struct FFHWAccel ff_hevc_nvdec_hwaccel; ++extern const struct FFHWAccel ff_hevc_v4l2request_hwaccel; + extern const struct FFHWAccel ff_hevc_vaapi_hwaccel; + extern const struct FFHWAccel ff_hevc_vdpau_hwaccel; + extern const struct FFHWAccel ff_hevc_videotoolbox_hwaccel; --- a/libavcodec/hwconfig.h +++ b/libavcodec/hwconfig.h -@@ -24,6 +24,7 @@ - - - #define HWACCEL_CAP_ASYNC_SAFE (1 << 0) -+#define HWACCEL_CAP_MT_SAFE (1 << 1) - - - typedef struct AVCodecHWConfigInternal { -@@ -70,6 +71,8 @@ typedef struct AVCodecHWConfigInternal { +@@ -67,6 +67,8 @@ void ff_hwaccel_uninit(AVCodecContext *a HW_CONFIG_HWACCEL(1, 1, 0, D3D11, D3D11VA, ff_ ## codec ## _d3d11va2_hwaccel) #define HWACCEL_NVDEC(codec) \ HW_CONFIG_HWACCEL(1, 1, 0, CUDA, CUDA, ff_ ## codec ## _nvdec_hwaccel) @@ -1873,122 +1856,9 @@ raspiberry pi support. #include #include "avcodec.h" ---- a/libavcodec/pthread_frame.c -+++ b/libavcodec/pthread_frame.c -@@ -217,7 +217,8 @@ FF_ENABLE_DEPRECATION_WARNINGS - - /* if the previous thread uses hwaccel then we take the lock to ensure - * the threads don't run concurrently */ -- if (avctx->hwaccel) { -+ if (avctx->hwaccel && -+ !(avctx->hwaccel->caps_internal & HWACCEL_CAP_MT_SAFE)) { - pthread_mutex_lock(&p->parent->hwaccel_mutex); - p->hwaccel_serializing = 1; - } -@@ -243,7 +244,7 @@ FF_ENABLE_DEPRECATION_WARNINGS - p->hwaccel_serializing = 0; - pthread_mutex_unlock(&p->parent->hwaccel_mutex); - } -- av_assert0(!avctx->hwaccel); -+ av_assert0(!avctx->hwaccel || (avctx->hwaccel->caps_internal & HWACCEL_CAP_MT_SAFE)); - - if (p->async_serializing) { - p->async_serializing = 0; -@@ -331,6 +332,12 @@ FF_ENABLE_DEPRECATION_WARNINGS - } - - dst->hwaccel_flags = src->hwaccel_flags; -+ if (src->hwaccel && -+ (src->hwaccel->caps_internal & HWACCEL_CAP_MT_SAFE)) { -+ dst->hwaccel = src->hwaccel; -+ dst->hwaccel_context = src->hwaccel_context; -+ dst->internal->hwaccel_priv_data = src->internal->hwaccel_priv_data; -+ } - - err = av_buffer_replace(&dst->internal->pool, src->internal->pool); - if (err < 0) -@@ -461,10 +468,13 @@ static int submit_packet(PerThreadContex - } - - /* transfer the stashed hwaccel state, if any */ -- av_assert0(!p->avctx->hwaccel); -- FFSWAP(const AVHWAccel*, p->avctx->hwaccel, fctx->stash_hwaccel); -- FFSWAP(void*, p->avctx->hwaccel_context, fctx->stash_hwaccel_context); -- FFSWAP(void*, p->avctx->internal->hwaccel_priv_data, fctx->stash_hwaccel_priv); -+ av_assert0(!p->avctx->hwaccel || (p->avctx->hwaccel->caps_internal & HWACCEL_CAP_MT_SAFE)); -+ if (p->avctx->hwaccel && -+ !(p->avctx->hwaccel->caps_internal & HWACCEL_CAP_MT_SAFE)) { -+ FFSWAP(const AVHWAccel*, p->avctx->hwaccel, fctx->stash_hwaccel); -+ FFSWAP(void*, p->avctx->hwaccel_context, fctx->stash_hwaccel_context); -+ FFSWAP(void*, p->avctx->internal->hwaccel_priv_data, fctx->stash_hwaccel_priv); -+ } - - av_packet_unref(p->avpkt); - ret = av_packet_ref(p->avpkt, avpkt); -@@ -656,7 +666,9 @@ void ff_thread_finish_setup(AVCodecConte - - if (!(avctx->active_thread_type&FF_THREAD_FRAME)) return; - -- if (avctx->hwaccel && !p->hwaccel_serializing) { -+ if (avctx->hwaccel && -+ !(avctx->hwaccel->caps_internal & HWACCEL_CAP_MT_SAFE) && -+ !p->hwaccel_serializing) { - pthread_mutex_lock(&p->parent->hwaccel_mutex); - p->hwaccel_serializing = 1; - } -@@ -673,9 +685,12 @@ void ff_thread_finish_setup(AVCodecConte - * this is done here so that this worker thread can wipe its own hwaccel - * state after decoding, without requiring synchronization */ - av_assert0(!p->parent->stash_hwaccel); -- p->parent->stash_hwaccel = avctx->hwaccel; -- p->parent->stash_hwaccel_context = avctx->hwaccel_context; -- p->parent->stash_hwaccel_priv = avctx->internal->hwaccel_priv_data; -+ if (avctx->hwaccel && -+ !(avctx->hwaccel->caps_internal & HWACCEL_CAP_MT_SAFE)) { -+ p->parent->stash_hwaccel = avctx->hwaccel; -+ p->parent->stash_hwaccel_context = avctx->hwaccel_context; -+ p->parent->stash_hwaccel_priv = avctx->internal->hwaccel_priv_data; -+ } - - pthread_mutex_lock(&p->progress_mutex); - if(atomic_load(&p->state) == STATE_SETUP_FINISHED){ -@@ -730,6 +745,15 @@ void ff_frame_thread_free(AVCodecContext - - park_frame_worker_threads(fctx, thread_count); - -+ if (fctx->prev_thread && -+ avctx->hwaccel && (avctx->hwaccel->caps_internal & HWACCEL_CAP_MT_SAFE) && -+ avctx->internal->hwaccel_priv_data != -+ fctx->prev_thread->avctx->internal->hwaccel_priv_data) { -+ if (update_context_from_thread(avctx, fctx->prev_thread->avctx, 1) < 0) { -+ av_log(avctx, AV_LOG_ERROR, "Failed to update user thread.\n"); -+ } -+ } -+ - for (i = 0; i < thread_count; i++) { - PerThreadContext *p = &fctx->threads[i]; - AVCodecContext *ctx = p->avctx; -@@ -778,10 +802,13 @@ void ff_frame_thread_free(AVCodecContext - - /* if we have stashed hwaccel state, move it to the user-facing context, - * so it will be freed in avcodec_close() */ -- av_assert0(!avctx->hwaccel); -- FFSWAP(const AVHWAccel*, avctx->hwaccel, fctx->stash_hwaccel); -- FFSWAP(void*, avctx->hwaccel_context, fctx->stash_hwaccel_context); -- FFSWAP(void*, avctx->internal->hwaccel_priv_data, fctx->stash_hwaccel_priv); -+ av_assert0(!avctx->hwaccel || (avctx->hwaccel->caps_internal & HWACCEL_CAP_MT_SAFE)); -+ if (avctx->hwaccel && -+ !(avctx->hwaccel->caps_internal & HWACCEL_CAP_MT_SAFE)) { -+ FFSWAP(const AVHWAccel*, avctx->hwaccel, fctx->stash_hwaccel); -+ FFSWAP(void*, avctx->hwaccel_context, fctx->stash_hwaccel_context); -+ FFSWAP(void*, avctx->internal->hwaccel_priv_data, fctx->stash_hwaccel_priv); -+ } - - av_freep(&avctx->internal->thread_ctx); - } --- a/libavcodec/raw.c +++ b/libavcodec/raw.c -@@ -294,6 +294,12 @@ static const PixelFormatTag raw_pix_fmt_ +@@ -297,6 +297,12 @@ static const PixelFormatTag raw_pix_fmt_ { AV_PIX_FMT_RGB565LE,MKTAG( 3 , 0 , 0 , 0 ) }, /* flipped RGB565LE */ { AV_PIX_FMT_YUV444P, MKTAG('Y', 'V', '2', '4') }, /* YUV444P, swapped UV */ @@ -2043,10 +1913,10 @@ raspiberry pi support. + + dst = pkt->data; + -+ av_rpi_sand_to_planar_y8(dst, width, frame->data[0], frame->linesize[0], frame->linesize[3], x0, y0, width, height); ++ av_rpi_sand_to_planar_y8(dst, width, frame->data[0], frame->linesize[0], av_rpi_sand_frame_stride2_y(frame), x0, y0, width, height); + dst += width * height; + av_rpi_sand_to_planar_c8(dst, width / 2, dst + width * height / 4, width / 2, -+ frame->data[1], frame->linesize[1], av_rpi_sand_frame_stride2(frame), x0 / 2, y0 / 2, width / 2, height / 2); ++ frame->data[1], frame->linesize[1], av_rpi_sand_frame_stride2_c(frame), x0 / 2, y0 / 2, width / 2, height / 2); + return 0; +} + @@ -2066,10 +1936,10 @@ raspiberry pi support. + + dst = pkt->data; + -+ av_rpi_sand_to_planar_y16(dst, width * 2, frame->data[0], frame->linesize[0], frame->linesize[3], x0 * 2, y0, width * 2, height); ++ av_rpi_sand_to_planar_y16(dst, width * 2, frame->data[0], frame->linesize[0], av_rpi_sand_frame_stride2_y(frame), x0 * 2, y0, width * 2, height); + dst += width * height * 2; + av_rpi_sand_to_planar_c16(dst, width, dst + width * height / 2, width, -+ frame->data[1], frame->linesize[1], av_rpi_sand_frame_stride2(frame), x0, y0 / 2, width, height / 2); ++ frame->data[1], frame->linesize[1], av_rpi_sand_frame_stride2_c(frame), x0, y0 / 2, width, height / 2); + return 0; +} + @@ -2089,10 +1959,10 @@ raspiberry pi support. + + dst = pkt->data; + -+ av_rpi_sand30_to_planar_y16(dst, width * 2, frame->data[0], frame->linesize[0], frame->linesize[3], x0, y0, width, height); ++ av_rpi_sand30_to_planar_y16(dst, width * 2, frame->data[0], frame->linesize[0], av_rpi_sand_frame_stride2_y(frame), x0, y0, width, height); + dst += width * height * 2; + av_rpi_sand30_to_planar_c16(dst, width, dst + width * height / 2, width, -+ frame->data[1], frame->linesize[1], av_rpi_sand_frame_stride2(frame), x0/2, y0 / 2, width/2, height / 2); ++ frame->data[1], frame->linesize[1], av_rpi_sand_frame_stride2_c(frame), x0/2, y0 / 2, width/2, height / 2); + return 0; +} +#endif @@ -2165,23 +2035,29 @@ raspiberry pi support. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -+#include ++#include "config.h" #include #include #include -@@ -28,57 +29,89 @@ +@@ -28,58 +29,94 @@ #include #include #include "libavcodec/avcodec.h" +#include "libavcodec/internal.h" +#include "libavutil/avassert.h" ++#include "libavutil/mem.h" #include "libavutil/pixdesc.h" +-#include "refstruct.h" +#include "libavutil/hwcontext.h" #include "v4l2_context.h" #include "v4l2_buffers.h" #include "v4l2_m2m.h" +#include "v4l2_req_dmabufs.h" +#include "weak_link.h" ++ ++#if CONFIG_LIBDRM ++#include ++#endif #define USEC_PER_SEC 1000000 -static AVRational v4l2_timebase = { 1, USEC_PER_SEC }; @@ -2284,7 +2160,7 @@ raspiberry pi support. } static enum AVColorPrimaries v4l2_get_color_primaries(V4L2Buffer *buf) -@@ -115,6 +148,105 @@ static enum AVColorPrimaries v4l2_get_co +@@ -116,6 +153,105 @@ static enum AVColorPrimaries v4l2_get_co return AVCOL_PRI_UNSPECIFIED; } @@ -2390,7 +2266,7 @@ raspiberry pi support. static enum AVColorRange v4l2_get_color_range(V4L2Buffer *buf) { enum v4l2_quantization qt; -@@ -133,6 +265,20 @@ static enum AVColorRange v4l2_get_color_ +@@ -134,6 +270,20 @@ static enum AVColorRange v4l2_get_color_ return AVCOL_RANGE_UNSPECIFIED; } @@ -2411,7 +2287,7 @@ raspiberry pi support. static enum AVColorSpace v4l2_get_color_space(V4L2Buffer *buf) { enum v4l2_ycbcr_encoding ycbcr; -@@ -209,73 +355,218 @@ static enum AVColorTransferCharacteristi +@@ -210,71 +360,294 @@ static enum AVColorTransferCharacteristi return AVCOL_TRC_UNSPECIFIED; } @@ -2447,7 +2323,84 @@ raspiberry pi support. + is_tff ? V4L2_FIELD_INTERLACED_TB : V4L2_FIELD_INTERLACED_BT; +} -- av_buffer_unref(&avbuf->context_ref); +- ff_refstruct_unref(&avbuf->context_ref); ++static inline void frame_set_interlace(AVFrame* frame, const int is_interlaced, const int is_tff) ++{ ++ if (!is_interlaced) { ++#if FF_API_INTERLACED_FRAME ++FF_DISABLE_DEPRECATION_WARNINGS ++ frame->interlaced_frame = 0; ++ frame->top_field_first = 0; ++FF_ENABLE_DEPRECATION_WARNINGS ++#endif ++ frame->flags &= ~(AV_FRAME_FLAG_TOP_FIELD_FIRST | AV_FRAME_FLAG_INTERLACED); ++ } ++ else { ++#if FF_API_INTERLACED_FRAME ++FF_DISABLE_DEPRECATION_WARNINGS ++ frame->interlaced_frame = 1; ++ frame->top_field_first = !!is_tff; ++FF_ENABLE_DEPRECATION_WARNINGS ++#endif ++ if (is_tff) ++ frame->flags |= AV_FRAME_FLAG_TOP_FIELD_FIRST | AV_FRAME_FLAG_INTERLACED; ++ else ++ frame->flags = (frame->flags & ~AV_FRAME_FLAG_TOP_FIELD_FIRST) | AV_FRAME_FLAG_INTERLACED; + } + } + +-static int v4l2_buf_increase_ref(V4L2Buffer *in) ++static inline int frame_is_interlaced(const AVFrame* const frame) + { +- V4L2m2mContext *s = buf_to_m2mctx(in); ++#if FF_API_INTERLACED_FRAME ++FF_DISABLE_DEPRECATION_WARNINGS ++ return frame->interlaced_frame || (frame->flags & AV_FRAME_FLAG_INTERLACED) != 0; ++FF_ENABLE_DEPRECATION_WARNINGS ++#else ++ return (frame->flags & AV_FRAME_FLAG_INTERLACED) != 0; ++#endif ++} + +- if (in->context_ref) +- atomic_fetch_add(&in->context_refcount, 1); +- else { +- in->context_ref = ff_refstruct_ref(s->self_ref); ++static inline int frame_is_tff(const AVFrame* const frame) ++{ ++#if FF_API_INTERLACED_FRAME ++FF_DISABLE_DEPRECATION_WARNINGS ++ return frame->top_field_first || (frame->flags & AV_FRAME_FLAG_TOP_FIELD_FIRST) != 0; ++FF_ENABLE_DEPRECATION_WARNINGS ++#else ++ return (frame->flags & AV_FRAME_FLAG_TOP_FIELD_FIRST) != 0; ++#endif ++} ++ ++static inline int frame_is_key(const AVFrame* const frame) ++{ ++#if FF_API_FRAME_KEY ++FF_DISABLE_DEPRECATION_WARNINGS ++ return frame->key_frame || (frame->flags & AV_FRAME_FLAG_KEY) != 0; ++FF_ENABLE_DEPRECATION_WARNINGS ++#else ++ return (frame->flags & AV_FRAME_FLAG_KEY) != 0; ++#endif ++} ++ ++static inline void frame_set_key(AVFrame* const frame, const int is_key) ++{ ++#if FF_API_FRAME_KEY ++FF_DISABLE_DEPRECATION_WARNINGS ++ frame->key_frame = !!is_key; ++FF_ENABLE_DEPRECATION_WARNINGS ++#endif ++ frame->flags = is_key ? ++ frame->flags | AV_FRAME_FLAG_KEY : ++ frame->flags & ~AV_FRAME_FLAG_KEY; ++} ++ ++#if CONFIG_LIBDRM +static uint8_t * v4l2_get_drm_frame(V4L2Buffer *avbuf) +{ + AVDRMFrameDescriptor *drm_desc = &avbuf->drm_frame; @@ -2459,13 +2412,16 @@ raspiberry pi support. + + layer = &drm_desc->layers[0]; + layer->nb_planes = avbuf->num_planes; -+ + +- in->context_refcount = 1; + for (int i = 0; i < avbuf->num_planes; i++) { + layer->planes[i].object_index = i; + layer->planes[i].offset = avbuf->plane_info[i].offset; + layer->planes[i].pitch = avbuf->plane_info[i].bytesperline; -+ } -+ + } + +- in->status = V4L2BUF_RET_USER; +- atomic_fetch_add_explicit(&s->refcount, 1, memory_order_relaxed); + switch (avbuf->context->av_pix_fmt) { + case AV_PIX_FMT_0BGR: + layer->format = DRM_FORMAT_RGBX8888; @@ -2479,7 +2435,8 @@ raspiberry pi support. + case AV_PIX_FMT_BGR0: + layer->format = DRM_FORMAT_XRGB8888; + break; -+ + +- return 0; + case AV_PIX_FMT_ABGR: + layer->format = DRM_FORMAT_RGBA8888; + break; @@ -2548,25 +2505,20 @@ raspiberry pi support. + default: + drm_desc->nb_layers = 0; + break; - } ++ } + + return (uint8_t *) drm_desc; } ++#endif --static int v4l2_buf_increase_ref(V4L2Buffer *in) +-static int v4l2_buf_to_bufref(V4L2Buffer *in, int plane, AVBufferRef **buf) +static void v4l2_free_bufref(void *opaque, uint8_t *data) { -- V4L2m2mContext *s = buf_to_m2mctx(in); +- int ret; + AVBufferRef * bufref = (AVBufferRef *)data; + V4L2Buffer *avbuf = (V4L2Buffer *)bufref->data; + struct V4L2Context *ctx = ff_weak_link_lock(&avbuf->context_wl); - -- if (in->context_ref) -- atomic_fetch_add(&in->context_refcount, 1); -- else { -- in->context_ref = av_buffer_ref(s->self_ref); -- if (!in->context_ref) -- return AVERROR(ENOMEM); ++ + if (ctx != NULL) { + // Buffer still attached to context + V4L2m2mContext * const s = ctx_to_m2mctx(ctx); @@ -2575,13 +2527,23 @@ raspiberry pi support. + for (unsigned int i = 0; i != avbuf->num_planes; ++i) + dmabuf_read_end(avbuf->dmabuf[i]); + } -+ + +- if (plane >= in->num_planes) +- return AVERROR(EINVAL); + ff_mutex_lock(&ctx->lock); -+ + +- /* even though most encoders return 0 in data_offset encoding vp8 does require this value */ +- *buf = av_buffer_create((char *)in->plane_info[plane].mm_addr + in->planes[plane].data_offset, +- in->plane_info[plane].length, v4l2_free_buffer, in, 0); +- if (!*buf) +- return AVERROR(ENOMEM); + ff_v4l2_buffer_set_avail(avbuf); + avbuf->buf.timestamp.tv_sec = 0; + avbuf->buf.timestamp.tv_usec = 0; -+ + +- ret = v4l2_buf_increase_ref(in); +- if (ret) +- av_buffer_unref(buf); + if (V4L2_TYPE_IS_OUTPUT(ctx->type)) { + av_log(logger(avbuf), AV_LOG_DEBUG, "%s: Buffer avail\n", ctx->name); + } @@ -2593,40 +2555,28 @@ raspiberry pi support. + av_log(logger(avbuf), AV_LOG_DEBUG, "%s: Buffer freed but streamoff\n", ctx->name); + } -- in->context_refcount = 1; +- return ret; + ff_mutex_unlock(&ctx->lock); - } - -- in->status = V4L2BUF_RET_USER; -- atomic_fetch_add_explicit(&s->refcount, 1, memory_order_relaxed); ++ } ++ + ff_weak_link_unlock(avbuf->context_wl); + av_buffer_unref(&bufref); +} - -- return 0; ++ +static inline uint32_t ff_v4l2_buf_len(const struct v4l2_buffer * b, unsigned int i) +{ + return V4L2_TYPE_IS_MULTIPLANAR(b->type) ? b->m.planes[i].length : b->length; - } - --static int v4l2_buf_to_bufref(V4L2Buffer *in, int plane, AVBufferRef **buf) ++} ++ +static int v4l2_buffer_export_drm(V4L2Buffer* avbuf) - { -- int ret; ++{ + int i, ret; + const V4L2m2mContext * const s = buf_to_m2mctx(avbuf); - -- if (plane >= in->num_planes) -- return AVERROR(EINVAL); ++ + for (i = 0; i < avbuf->num_planes; i++) { + int dma_fd = -1; + const uint32_t blen = ff_v4l2_buf_len(&avbuf->buf, i); - -- /* even though most encoders return 0 in data_offset encoding vp8 does require this value */ -- *buf = av_buffer_create((char *)in->plane_info[plane].mm_addr + in->planes[plane].data_offset, -- in->plane_info[plane].length, v4l2_free_buffer, in, 0); -- if (!*buf) -- return AVERROR(ENOMEM); ++ + if (s->db_ctl != NULL) { + if ((avbuf->dmabuf[i] = dmabuf_alloc(s->db_ctl, blen)) == NULL) + return AVERROR(ENOMEM); @@ -2635,10 +2585,7 @@ raspiberry pi support. + avbuf->buf.m.planes[i].m.fd = dma_fd; + else + avbuf->buf.m.fd = dma_fd; - -- ret = v4l2_buf_increase_ref(in); -- if (ret) -- av_buffer_unref(buf); ++ + if (!s->output_drm) + avbuf->plane_info[i].mm_addr = dmabuf_map(avbuf->dmabuf[i]); + } @@ -2655,11 +2602,14 @@ raspiberry pi support. + return AVERROR(errno); + dma_fd = expbuf.fd; + } - -- return ret; ++ + avbuf->drm_frame.objects[i].size = blen; + avbuf->drm_frame.objects[i].fd = dma_fd; ++#if !CONFIG_LIBDRM ++ avbuf->drm_frame.objects[i].format_modifier = 0; ++#else + avbuf->drm_frame.objects[i].format_modifier = DRM_FORMAT_MOD_LINEAR; ++#endif + } + + return 0; @@ -2672,7 +2622,7 @@ raspiberry pi support. if (plane >= out->num_planes) return AVERROR(EINVAL); -@@ -283,32 +574,61 @@ static int v4l2_bufref_to_buf(V4L2Buffer +@@ -282,32 +655,65 @@ static int v4l2_bufref_to_buf(V4L2Buffer length = out->plane_info[plane].length; bytesused = FFMIN(size+offset, length); @@ -2727,8 +2677,11 @@ raspiberry pi support. + frame->buf[0] = wrap_avbuf(avbuf); + if (frame->buf[0] == NULL) + return AVERROR(ENOMEM); -+ + + if (buf_to_m2mctx(avbuf)->output_drm) { ++#if !CONFIG_LIBDRM ++ return AVERROR_OPTION_NOT_FOUND; ++#else + /* 1. get references to the actual data */ + const int rv = ff_v4l2_context_frames_set(avbuf->context); + if (rv != 0) @@ -2738,9 +2691,10 @@ raspiberry pi support. + frame->format = AV_PIX_FMT_DRM_PRIME; + frame->hw_frames_ctx = av_buffer_ref(avbuf->context->frames_ref); + return 0; ++#endif + } + - ++ + /* 1. get references to the actual data */ + for (i = 0; i < avbuf->num_planes; i++) { + frame->data[i] = (uint8_t *)avbuf->plane_info[i].mm_addr + avbuf->planes[i].data_offset; @@ -2749,7 +2703,7 @@ raspiberry pi support. } /* fixup special cases */ -@@ -317,88 +637,152 @@ static int v4l2_buffer_buf_to_swframe(AV +@@ -316,88 +722,152 @@ static int v4l2_buffer_buf_to_swframe(AV case AV_PIX_FMT_NV21: if (avbuf->num_planes > 1) break; @@ -2962,7 +2916,7 @@ raspiberry pi support. return 0; } -@@ -408,16 +792,31 @@ static int v4l2_buffer_swframe_to_buf(co +@@ -407,16 +877,31 @@ static int v4l2_buffer_swframe_to_buf(co * ******************************************************************************/ @@ -2972,7 +2926,7 @@ raspiberry pi support. - v4l2_set_pts(out, frame->pts); - - return v4l2_buffer_swframe_to_buf(frame, out); -+ out->buf.flags = frame->key_frame ? ++ out->buf.flags = frame_is_key(frame) ? + (out->buf.flags | V4L2_BUF_FLAG_KEYFRAME) : + (out->buf.flags & ~V4L2_BUF_FLAG_KEYFRAME); + // Beware that colour info is held in format rather than the actual @@ -2984,7 +2938,7 @@ raspiberry pi support. + out->buf.timestamp = tv_from_int(track_ts); + else + v4l2_set_pts(out, frame->pts); -+ v4l2_set_interlace(out, frame->interlaced_frame, frame->top_field_first); ++ v4l2_set_interlace(out, frame_is_interlaced(frame), frame_is_tff(frame)); + + return frame->format == AV_PIX_FMT_DRM_PRIME ? + v4l2_buffer_primeframe_to_buf(frame, out) : @@ -2998,11 +2952,14 @@ raspiberry pi support. av_frame_unref(frame); -@@ -428,17 +827,32 @@ int ff_v4l2_buffer_buf_to_avframe(AVFram +@@ -426,19 +911,32 @@ int ff_v4l2_buffer_buf_to_avframe(AVFram + return ret; /* 2. get frame information */ - frame->key_frame = !!(avbuf->buf.flags & V4L2_BUF_FLAG_KEYFRAME); -+ frame->pict_type = frame->key_frame ? AV_PICTURE_TYPE_I : +- if (avbuf->buf.flags & V4L2_BUF_FLAG_KEYFRAME) +- frame->flags |= AV_FRAME_FLAG_KEY; ++ frame_set_key(frame, avbuf->buf.flags & V4L2_BUF_FLAG_KEYFRAME); ++ frame->pict_type = (avbuf->buf.flags & V4L2_BUF_FLAG_KEYFRAME) != 0 ? AV_PICTURE_TYPE_I : + (avbuf->buf.flags & V4L2_BUF_FLAG_PFRAME) != 0 ? AV_PICTURE_TYPE_P : + (avbuf->buf.flags & V4L2_BUF_FLAG_BFRAME) != 0 ? AV_PICTURE_TYPE_B : + AV_PICTURE_TYPE_NONE; @@ -3012,8 +2969,7 @@ raspiberry pi support. frame->color_trc = v4l2_get_color_trc(avbuf); frame->pts = v4l2_get_pts(avbuf); frame->pkt_dts = AV_NOPTS_VALUE; -+ frame->interlaced_frame = v4l2_buf_is_interlaced(avbuf); -+ frame->top_field_first = v4l2_buf_is_top_first(avbuf); ++ frame_set_interlace(frame, v4l2_buf_is_interlaced(avbuf), v4l2_buf_is_top_first(avbuf)); /* these values are updated also during re-init in v4l2_process_driver_event */ - frame->height = avbuf->context->height; @@ -3034,7 +2990,7 @@ raspiberry pi support. /* 3. report errors upstream */ if (avbuf->buf.flags & V4L2_BUF_FLAG_ERROR) { -@@ -451,15 +865,15 @@ int ff_v4l2_buffer_buf_to_avframe(AVFram +@@ -451,15 +949,15 @@ int ff_v4l2_buffer_buf_to_avframe(AVFram int ff_v4l2_buffer_buf_to_avpkt(AVPacket *pkt, V4L2Buffer *avbuf) { @@ -3056,7 +3012,7 @@ raspiberry pi support. if (avbuf->buf.flags & V4L2_BUF_FLAG_KEYFRAME) pkt->flags |= AV_PKT_FLAG_KEY; -@@ -474,39 +888,108 @@ int ff_v4l2_buffer_buf_to_avpkt(AVPacket +@@ -474,39 +972,108 @@ int ff_v4l2_buffer_buf_to_avpkt(AVPacket return 0; } @@ -3177,7 +3133,7 @@ raspiberry pi support. if (V4L2_TYPE_IS_MULTIPLANAR(ctx->type)) { avbuf->num_planes = 0; -@@ -518,33 +1001,41 @@ int ff_v4l2_buffer_initialize(V4L2Buffer +@@ -518,33 +1085,41 @@ int ff_v4l2_buffer_initialize(V4L2Buffer } else avbuf->num_planes = 1; @@ -3231,7 +3187,7 @@ raspiberry pi support. if (V4L2_TYPE_IS_MULTIPLANAR(ctx->type)) { avbuf->buf.m.planes = avbuf->planes; avbuf->buf.length = avbuf->num_planes; -@@ -554,20 +1045,52 @@ int ff_v4l2_buffer_initialize(V4L2Buffer +@@ -554,20 +1129,52 @@ int ff_v4l2_buffer_initialize(V4L2Buffer avbuf->buf.length = avbuf->planes[0].length; } @@ -3295,7 +3251,7 @@ raspiberry pi support. #include +#include "avcodec.h" - #include "libavutil/buffer.h" ++#include "libavutil/buffer.h" #include "libavutil/frame.h" +#include "libavutil/hwcontext_drm.h" #include "packet.h" @@ -3326,8 +3282,9 @@ raspiberry pi support. + struct ff_weak_link_client *context_wl; - /* This object is refcounted per-plane, so we need to keep track -- * of how many context-refs we are holding. */ -- AVBufferRef *context_ref; +- * of how many context-refs we are holding. +- * This pointer is a RefStruct reference. */ +- const struct V4L2m2mContext *context_ref; - atomic_uint context_refcount; + /* DRM descriptor */ + AVDRMFrameDescriptor drm_frame; @@ -3399,14 +3356,14 @@ raspiberry pi support. #endif // AVCODEC_V4L2_BUFFERS_H --- a/libavcodec/v4l2_context.c +++ b/libavcodec/v4l2_context.c -@@ -27,11 +27,14 @@ - #include +@@ -28,11 +28,14 @@ #include #include + #include "libavutil/mem.h" +#include "libavutil/avassert.h" +#include "libavutil/pixdesc.h" #include "libavcodec/avcodec.h" - #include "libavcodec/internal.h" + #include "decode.h" #include "v4l2_buffers.h" #include "v4l2_fmt.h" #include "v4l2_m2m.h" @@ -3414,7 +3371,7 @@ raspiberry pi support. struct v4l2_format_update { uint32_t v4l2_fmt; -@@ -41,26 +44,168 @@ struct v4l2_format_update { +@@ -42,26 +45,173 @@ struct v4l2_format_update { int update_avfmt; }; @@ -3433,8 +3390,9 @@ raspiberry pi support. { - return ctx_to_m2mctx(ctx)->avctx; + return (unsigned int)pts; -+} -+ + } + +-static inline unsigned int v4l2_get_width(struct v4l2_format *fmt) +// FFmpeg requires us to propagate a number of vars from the coded pkt into +// the decoded frame. The only thing that tracks like that in V4L2 stateful +// is timestamp. PTS maps to timestamp for this decode. FFmpeg makes no @@ -3444,7 +3402,8 @@ raspiberry pi support. +// indexed by the tracking no. +static int64_t +xlat_pts_pkt_in(AVCodecContext *const avctx, xlat_track_t *const x, const AVPacket *const avpkt) -+{ + { +- return V4L2_TYPE_IS_MULTIPLANAR(fmt->type) ? fmt->fmt.pix_mp.width : fmt->fmt.pix.width; + int64_t track_pts; + + // Avoid 0 @@ -3460,9 +3419,8 @@ raspiberry pi support. + .pkt_size = avpkt->size, + .pts = avpkt->pts, + .dts = avpkt->dts, -+ .reordered_opaque = avctx->reordered_opaque, + .pkt_pos = avpkt->pos, -+ .pkt_duration = avpkt->duration, ++ .duration = avpkt->duration, + .track_pts = track_pts + }; + return track_pts; @@ -3483,14 +3441,16 @@ raspiberry pi support. + x->track_els[x->track_no % FF_V4L2_M2M_TRACK_SIZE] = (V4L2m2mTrackEl){ + .discard = 0, + .pending = 1, -+ .pkt_size = 0, + .pts = frame->pts, + .dts = AV_NOPTS_VALUE, -+ .reordered_opaque = frame->reordered_opaque, -+ .pkt_pos = frame->pkt_pos, -+ .pkt_duration = frame->pkt_duration, ++ .duration = frame->duration, + .track_pts = track_pts + }; ++#if FF_API_FRAME_PKT ++FF_DISABLE_DEPRECATION_WARNINGS ++ x->track_els[x->track_no % FF_V4L2_M2M_TRACK_SIZE].pkt_pos = frame->pkt_pos; ++FF_ENABLE_DEPRECATION_WARNINGS ++#endif + return track_pts; +} + @@ -3509,21 +3469,26 @@ raspiberry pi support. + "Frame tracking failure: pts=%" PRId64 ", track[%d]=%" PRId64 "\n", frame->pts, n, t->track_pts); + frame->pts = AV_NOPTS_VALUE; + frame->pkt_dts = AV_NOPTS_VALUE; -+ frame->reordered_opaque = x->last_opaque; -+ frame->pkt_pos = -1; -+ frame->pkt_duration = 0; ++ frame->duration = 0; ++#if FF_API_FRAME_PKT ++FF_DISABLE_DEPRECATION_WARNINGS + frame->pkt_size = -1; ++ frame->pkt_pos = -1; ++FF_ENABLE_DEPRECATION_WARNINGS ++#endif + } + else if (!t->discard) + { + frame->pts = t->pending ? t->pts : AV_NOPTS_VALUE; + frame->pkt_dts = t->dts; -+ frame->reordered_opaque = t->reordered_opaque; ++ frame->duration = t->duration; ++#if FF_API_FRAME_PKT ++FF_DISABLE_DEPRECATION_WARNINGS + frame->pkt_pos = t->pkt_pos; -+ frame->pkt_duration = t->pkt_duration; + frame->pkt_size = t->pkt_size; ++FF_ENABLE_DEPRECATION_WARNINGS ++#endif + -+ x->last_opaque = x->track_els[n].reordered_opaque; + if (frame->pts != AV_NOPTS_VALUE) + x->last_pts = frame->pts; + t->pending = 0; @@ -3557,7 +3522,6 @@ raspiberry pi support. + { + pkt->pts = t->pending ? t->pts : AV_NOPTS_VALUE; + -+ x->last_opaque = x->track_els[n].reordered_opaque; + if (pkt->pts != AV_NOPTS_VALUE) + x->last_pts = pkt->pts; + t->pending = 0; @@ -3573,13 +3537,11 @@ raspiberry pi support. + av_log(avctx, AV_LOG_TRACE, "Out pkt PTS=%" PRId64 ", track=%"PRId64", n=%d\n", + pkt->pts, t->track_pts, n); + return 0; - } - --static inline unsigned int v4l2_get_width(struct v4l2_format *fmt) ++} ++ + +static inline V4L2m2mContext *ctx_to_m2mctx(const V4L2Context *ctx) - { -- return V4L2_TYPE_IS_MULTIPLANAR(fmt->type) ? fmt->fmt.pix_mp.width : fmt->fmt.pix.width; ++{ + return V4L2_TYPE_IS_OUTPUT(ctx->type) ? + container_of(ctx, V4L2m2mContext, output) : + container_of(ctx, V4L2m2mContext, capture); @@ -3593,7 +3555,7 @@ raspiberry pi support. } static AVRational v4l2_get_sar(V4L2Context *ctx) -@@ -81,21 +226,29 @@ static AVRational v4l2_get_sar(V4L2Conte +@@ -82,21 +232,29 @@ static AVRational v4l2_get_sar(V4L2Conte return sar; } @@ -3634,7 +3596,7 @@ raspiberry pi support. return ret; } -@@ -153,76 +306,100 @@ static inline void v4l2_save_to_context( +@@ -154,76 +312,100 @@ static inline void v4l2_save_to_context( } } @@ -3781,7 +3743,7 @@ raspiberry pi support. return 1; } -@@ -266,171 +443,293 @@ static int v4l2_stop_encode(V4L2Context +@@ -267,175 +449,293 @@ static int v4l2_stop_encode(V4L2Context return 0; } @@ -3855,12 +3817,12 @@ raspiberry pi support. + if (err != EINTR) { + av_log(avctx, AV_LOG_DEBUG, "%s VIDIOC_DQBUF, errno (%s)\n", + ctx->name, av_err2str(AVERROR(err))); -+ -+ if (err == EPIPE) -+ ctx->flag_last = 1; - if (ctx->buffers[i].status == V4L2BUF_IN_DRIVER) - goto start; ++ if (err == EPIPE) ++ ctx->flag_last = 1; ++ + return AVERROR(err); } - ctx->done = 1; @@ -3944,9 +3906,13 @@ raspiberry pi support. - /* 0. handle errors */ - if (pfd.revents & POLLERR) { -- /* if we are trying to get free buffers but none have been queued yet -- no need to raise a warning */ +- /* if we are trying to get free buffers but none have been queued yet, +- * or if no buffers have been allocated yet, no need to raise a warning +- */ - if (timeout == 0) { +- if (!ctx->buffers) +- return NULL; +- - for (i = 0; i < ctx->num_buffers; i++) { - if (ctx->buffers[i].status != V4L2BUF_AVAILABLE) - av_log(logger(ctx), AV_LOG_WARNING, "%s POLLERR\n", ctx->name); @@ -4044,26 +4010,34 @@ raspiberry pi support. + ret = AVERROR(errno); // Remember errno before logging etc. + av_assert0(ret < 0); + } -+ -+ av_log(avctx, AV_LOG_TRACE, "V4L2 poll %s ret=%d, timeout=%d, events=%#x, revents=%#x\n", -+ ctx->name, ret, timeout, pfd.events, pfd.revents); - if (!V4L2_TYPE_IS_OUTPUT(ctx->type)) { - /* there is a capture buffer ready */ - if (pfd.revents & (POLLIN | POLLRDNORM)) - goto dequeue; -+ if (ret < 0) { -+ if (ret == AVERROR(EINTR)) -+ continue; -+ av_log(avctx, AV_LOG_ERROR, "V4L2 %s poll error %d (%s)\n", ctx->name, AVUNERROR(ret), av_err2str(ret)); -+ return ret; -+ } ++ av_log(avctx, AV_LOG_TRACE, "V4L2 poll %s ret=%d, timeout=%d, events=%#x, revents=%#x\n", ++ ctx->name, ret, timeout, pfd.events, pfd.revents); - /* the driver is ready to accept more input; instead of waiting for the capture - * buffer to complete we return NULL so input can proceed (we are single threaded) - */ - if (pfd.revents & (POLLOUT | POLLWRNORM)) - return NULL; ++ if (ret < 0) { ++ if (ret == AVERROR(EINTR)) ++ continue; ++ av_log(avctx, AV_LOG_ERROR, "V4L2 %s poll error %d (%s)\n", ctx->name, AVUNERROR(ret), av_err2str(ret)); ++ return ret; + } + +-dequeue: +- memset(&buf, 0, sizeof(buf)); +- buf.memory = V4L2_MEMORY_MMAP; +- buf.type = ctx->type; +- if (V4L2_TYPE_IS_MULTIPLANAR(ctx->type)) { +- memset(planes, 0, sizeof(planes)); +- buf.length = VIDEO_MAX_PLANES; +- buf.m.planes = planes; + if (ret == 0) { + if (timeout == -1) + av_log(avctx, AV_LOG_ERROR, "V4L2 %s poll unexpected timeout: events=%#x\n", ctx->name, pfd.events); @@ -4078,51 +4052,36 @@ raspiberry pi support. + return AVERROR(EAGAIN); } --dequeue: -- memset(&buf, 0, sizeof(buf)); -- buf.memory = V4L2_MEMORY_MMAP; -- buf.type = ctx->type; -- if (V4L2_TYPE_IS_MULTIPLANAR(ctx->type)) { -- memset(planes, 0, sizeof(planes)); -- buf.length = VIDEO_MAX_PLANES; -- buf.m.planes = planes; -+ if ((pfd.revents & POLLERR) != 0) { -+ av_log(avctx, AV_LOG_WARNING, "V4L2 %s POLLERR\n", ctx->name); -+ return AVERROR_UNKNOWN; - } - - ret = ioctl(ctx_to_m2mctx(ctx)->fd, VIDIOC_DQBUF, &buf); - if (ret) { - if (errno != EAGAIN) { -+ if ((pfd.revents & poll_event) != 0) { -+ ret = get_event(m); -+ if (ret < 0) { - ctx->done = 1; +- ctx->done = 1; - if (errno != EPIPE) - av_log(logger(ctx), AV_LOG_DEBUG, "%s VIDIOC_DQBUF, errno (%s)\n", - ctx->name, av_err2str(AVERROR(errno))); -+ return ret; - } +- } - return NULL; -+ continue; ++ if ((pfd.revents & POLLERR) != 0) { ++ av_log(avctx, AV_LOG_WARNING, "V4L2 %s POLLERR\n", ctx->name); ++ return AVERROR_UNKNOWN; } - if (ctx_to_m2mctx(ctx)->draining && !V4L2_TYPE_IS_OUTPUT(ctx->type)) { - int bytesused = V4L2_TYPE_IS_MULTIPLANAR(buf.type) ? - buf.m.planes[0].bytesused : buf.bytesused; - if (bytesused == 0) { -- ctx->done = 1; ++ if ((pfd.revents & poll_event) != 0) { ++ ret = get_event(m); ++ if (ret < 0) { + ctx->done = 1; - return NULL; -- } ++ return ret; + } -#ifdef V4L2_BUF_FLAG_LAST - if (buf.flags & V4L2_BUF_FLAG_LAST) - ctx->done = 1; -#endif -+ if ((pfd.revents & poll_cap) != 0) { -+ ret = dq_buf(ctx, ppavbuf); -+ if (ret == AVERROR(EPIPE)) -+ continue; -+ return ret; ++ continue; } - avbuf = &ctx->buffers[buf.index]; @@ -4131,6 +4090,13 @@ raspiberry pi support. - if (V4L2_TYPE_IS_MULTIPLANAR(ctx->type)) { - memcpy(avbuf->planes, planes, sizeof(planes)); - avbuf->buf.m.planes = avbuf->planes; ++ if ((pfd.revents & poll_cap) != 0) { ++ ret = dq_buf(ctx, ppavbuf); ++ if (ret == AVERROR(EPIPE)) ++ continue; ++ return ret; ++ } ++ + if ((pfd.revents & poll_out) != 0) { + if (is_cap) + return AVERROR(EAGAIN); @@ -4197,7 +4163,7 @@ raspiberry pi support. } return NULL; -@@ -438,25 +737,45 @@ static V4L2Buffer* v4l2_getfree_v4l2buf( +@@ -443,25 +743,45 @@ static V4L2Buffer* v4l2_getfree_v4l2buf( static int v4l2_release_buffers(V4L2Context* ctx) { @@ -4257,7 +4223,7 @@ raspiberry pi support. } static inline int v4l2_try_raw_format(V4L2Context* ctx, enum AVPixelFormat pixfmt) -@@ -485,6 +804,8 @@ static inline int v4l2_try_raw_format(V4 +@@ -490,6 +810,8 @@ static inline int v4l2_try_raw_format(V4 static int v4l2_get_raw_format(V4L2Context* ctx, enum AVPixelFormat *p) { @@ -4266,7 +4232,7 @@ raspiberry pi support. enum AVPixelFormat pixfmt = ctx->av_pix_fmt; struct v4l2_fmtdesc fdesc; int ret; -@@ -498,21 +819,22 @@ static int v4l2_get_raw_format(V4L2Conte +@@ -503,21 +825,22 @@ static int v4l2_get_raw_format(V4L2Conte return 0; } @@ -4297,7 +4263,7 @@ raspiberry pi support. } return AVERROR(EINVAL); -@@ -555,30 +877,131 @@ static int v4l2_get_coded_format(V4L2Con +@@ -560,30 +883,131 @@ static int v4l2_get_coded_format(V4L2Con * *****************************************************************************/ @@ -4438,7 +4404,7 @@ raspiberry pi support. s->draining= 1; return 0; } -@@ -587,23 +1010,29 @@ int ff_v4l2_context_enqueue_frame(V4L2Co +@@ -592,23 +1016,29 @@ int ff_v4l2_context_enqueue_frame(V4L2Co if (!avbuf) return AVERROR(EAGAIN); @@ -4471,7 +4437,7 @@ raspiberry pi support. s->draining = 1; return 0; } -@@ -612,8 +1041,13 @@ int ff_v4l2_context_enqueue_packet(V4L2C +@@ -617,8 +1047,13 @@ int ff_v4l2_context_enqueue_packet(V4L2C if (!avbuf) return AVERROR(EAGAIN); @@ -4487,7 +4453,7 @@ raspiberry pi support. return ret; return ff_v4l2_buffer_enqueue(avbuf); -@@ -621,42 +1055,77 @@ int ff_v4l2_context_enqueue_packet(V4L2C +@@ -626,42 +1061,77 @@ int ff_v4l2_context_enqueue_packet(V4L2C int ff_v4l2_context_dequeue_frame(V4L2Context* ctx, AVFrame* frame, int timeout) { @@ -4590,7 +4556,7 @@ raspiberry pi support. } int ff_v4l2_context_get_format(V4L2Context* ctx, int probe) -@@ -688,78 +1157,194 @@ int ff_v4l2_context_get_format(V4L2Conte +@@ -693,78 +1163,194 @@ int ff_v4l2_context_get_format(V4L2Conte int ff_v4l2_context_set_format(V4L2Context* ctx) { @@ -5000,7 +4966,7 @@ raspiberry pi support. { AV_FMT(YUYV422), AV_CODEC(RAWVIDEO), V4L2_FMT(YUYV) }, --- a/libavcodec/v4l2_m2m.c +++ b/libavcodec/v4l2_m2m.c -@@ -34,6 +34,15 @@ +@@ -36,6 +36,15 @@ #include "v4l2_context.h" #include "v4l2_fmt.h" #include "v4l2_m2m.h" @@ -5016,7 +4982,7 @@ raspiberry pi support. static inline int v4l2_splane_video(struct v4l2_capability *cap) { -@@ -67,7 +76,9 @@ static int v4l2_prepare_contexts(V4L2m2m +@@ -69,7 +78,9 @@ static int v4l2_prepare_contexts(V4L2m2m s->capture.done = s->output.done = 0; s->capture.name = "capture"; @@ -5026,7 +4992,7 @@ raspiberry pi support. atomic_init(&s->refcount, 0); sem_init(&s->refsync, 0, 0); -@@ -84,18 +95,58 @@ static int v4l2_prepare_contexts(V4L2m2m +@@ -86,18 +97,58 @@ static int v4l2_prepare_contexts(V4L2m2m if (v4l2_mplane_video(&cap)) { s->capture.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; s->output.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; @@ -5085,7 +5051,7 @@ raspiberry pi support. static int v4l2_probe_driver(V4L2m2mContext *s) { void *log_ctx = s->avctx; -@@ -115,6 +166,11 @@ static int v4l2_probe_driver(V4L2m2mCont +@@ -117,6 +168,11 @@ static int v4l2_probe_driver(V4L2m2mCont goto done; } @@ -5097,7 +5063,7 @@ raspiberry pi support. ret = ff_v4l2_context_get_format(&s->capture, 1); if (ret) { av_log(log_ctx, AV_LOG_DEBUG, "v4l2 capture format not supported\n"); -@@ -214,13 +270,7 @@ int ff_v4l2_m2m_codec_reinit(V4L2m2mCont +@@ -218,13 +274,7 @@ int ff_v4l2_m2m_codec_reinit(V4L2m2mCont av_log(log_ctx, AV_LOG_ERROR, "capture VIDIOC_STREAMOFF\n"); /* 2. unmap the capture buffers (v4l2 and ffmpeg): @@ -5111,7 +5077,7 @@ raspiberry pi support. ff_v4l2_context_release(&s->capture); /* 3. get the new capture format */ -@@ -239,7 +289,6 @@ int ff_v4l2_m2m_codec_reinit(V4L2m2mCont +@@ -243,7 +293,6 @@ int ff_v4l2_m2m_codec_reinit(V4L2m2mCont /* 5. complete reinit */ s->draining = 0; @@ -5119,17 +5085,17 @@ raspiberry pi support. return 0; } -@@ -256,6 +305,9 @@ static void v4l2_m2m_destroy_context(voi - av_frame_unref(s->frame); +@@ -259,6 +308,9 @@ static void v4l2_m2m_destroy_context(FFR + close(s->fd); av_frame_free(&s->frame); av_packet_unref(&s->buf_pkt); + av_freep(&s->extdata_data); + + av_log(s->avctx, AV_LOG_DEBUG, "V4L2 Context destroyed\n"); - - av_free(s); } -@@ -268,6 +320,11 @@ int ff_v4l2_m2m_codec_end(V4L2m2mPriv *p + + int ff_v4l2_m2m_codec_end(V4L2m2mPriv *priv) +@@ -269,6 +321,11 @@ int ff_v4l2_m2m_codec_end(V4L2m2mPriv *p if (!s) return 0; @@ -5141,7 +5107,7 @@ raspiberry pi support. if (s->fd >= 0) { ret = ff_v4l2_context_set_status(&s->output, VIDIOC_STREAMOFF); if (ret) -@@ -279,8 +336,20 @@ int ff_v4l2_m2m_codec_end(V4L2m2mPriv *p +@@ -280,6 +337,14 @@ int ff_v4l2_m2m_codec_end(V4L2m2mPriv *p } ff_v4l2_context_release(&s->output); @@ -5155,64 +5121,15 @@ raspiberry pi support. + } s->self_ref = NULL; -+ // This is only called on avctx close so after this point we don't have that -+ // Crash sooner if we find we are using it (can still log with avctx = NULL) -+ s->avctx = NULL; -+ priv->context = NULL; - av_buffer_unref(&priv->context_ref); - - return 0; -@@ -324,35 +393,38 @@ int ff_v4l2_m2m_codec_init(V4L2m2mPriv * - return v4l2_configure_contexts(s); - } - --int ff_v4l2_m2m_create_context(V4L2m2mPriv *priv, V4L2m2mContext **s) -+int ff_v4l2_m2m_create_context(V4L2m2mPriv *priv, V4L2m2mContext **pps) - { -- *s = av_mallocz(sizeof(V4L2m2mContext)); -- if (!*s) -+ V4L2m2mContext * const s = av_mallocz(sizeof(V4L2m2mContext)); -+ -+ *pps = NULL; -+ if (!s) - return AVERROR(ENOMEM); - -- priv->context_ref = av_buffer_create((uint8_t *) *s, sizeof(V4L2m2mContext), -+ priv->context_ref = av_buffer_create((uint8_t *)s, sizeof(*s), - &v4l2_m2m_destroy_context, NULL, 0); - if (!priv->context_ref) { -- av_freep(s); -+ av_free(s); - return AVERROR(ENOMEM); - } - - /* assign the context */ -- priv->context = *s; -- (*s)->priv = priv; -+ priv->context = s; -+ s->priv = priv; - - /* populate it */ -- priv->context->capture.num_buffers = priv->num_capture_buffers; -- priv->context->output.num_buffers = priv->num_output_buffers; -- priv->context->self_ref = priv->context_ref; -- priv->context->fd = -1; -+ s->capture.num_buffers = priv->num_capture_buffers; -+ s->output.num_buffers = priv->num_output_buffers; -+ s->self_ref = priv->context_ref; -+ s->fd = -1; -+ xlat_init(&s->xlat); + ff_refstruct_unref(&priv->context); +@@ -341,6 +406,7 @@ int ff_v4l2_m2m_create_context(V4L2m2mPr + priv->context->output.num_buffers = priv->num_output_buffers; + priv->context->self_ref = priv->context; + priv->context->fd = -1; ++ xlat_init(&priv->context->xlat); priv->context->frame = av_frame_alloc(); if (!priv->context->frame) { - av_buffer_unref(&priv->context_ref); -- *s = NULL; /* freed when unreferencing context_ref */ - return AVERROR(ENOMEM); - } - -+ *pps = s; - return 0; - } --- a/libavcodec/v4l2_m2m.h +++ b/libavcodec/v4l2_m2m.h @@ -30,6 +30,7 @@ @@ -5223,23 +5140,21 @@ raspiberry pi support. #include "v4l2_context.h" #define container_of(ptr, type, member) ({ \ -@@ -38,7 +39,39 @@ - - #define V4L_M2M_DEFAULT_OPTS \ +@@ -40,6 +41,38 @@ { "num_output_buffers", "Number of buffers in the output context",\ -- OFFSET(num_output_buffers), AV_OPT_TYPE_INT, { .i64 = 16 }, 6, INT_MAX, FLAGS } -+ OFFSET(num_output_buffers), AV_OPT_TYPE_INT, { .i64 = 16 }, 2, INT_MAX, FLAGS } -+ + OFFSET(num_output_buffers), AV_OPT_TYPE_INT, { .i64 = 16 }, 2, INT_MAX, FLAGS } + +#define FF_V4L2_M2M_TRACK_SIZE 128 +typedef struct V4L2m2mTrackEl { + int discard; // If we see this buffer its been flushed, so discard + int pending; -+ int pkt_size; + int64_t pts; + int64_t dts; -+ int64_t reordered_opaque; ++#if FF_API_FRAME_PKT + int64_t pkt_pos; -+ int64_t pkt_duration; ++ int pkt_size; ++#endif ++ int64_t duration; + int64_t track_pts; +} V4L2m2mTrackEl; + @@ -5256,14 +5171,14 @@ raspiberry pi support. +typedef struct xlat_track_s { + unsigned int track_no; + int64_t last_pts; // Last valid PTS decoded -+ int64_t last_opaque; + V4L2m2mTrackEl track_els[FF_V4L2_M2M_TRACK_SIZE]; +} xlat_track_t; + +struct dmabufs_ctl; - ++ typedef struct V4L2m2mContext { char devname[PATH_MAX]; + int fd; @@ -52,10 +85,10 @@ typedef struct V4L2m2mContext { AVCodecContext *avctx; sem_t refsync; @@ -5276,7 +5191,7 @@ raspiberry pi support. AVPacket buf_pkt; /* Reference to a frame. Only used during encoding */ -@@ -66,6 +99,36 @@ typedef struct V4L2m2mContext { +@@ -66,6 +99,37 @@ typedef struct V4L2m2mContext { /* reference back to V4L2m2mPriv */ void *priv; @@ -5306,6 +5221,7 @@ raspiberry pi support. + +#define FF_V4L2_QUIRK_REINIT_ALWAYS 1 +#define FF_V4L2_QUIRK_ENUM_FRAMESIZES_BROKEN 2 ++#define FF_V4L2_QUIRK_8192_MACRO_MAX 4 // Size limited to 8192 macroblocks + /* Quirks */ + unsigned int quirks; + @@ -5313,7 +5229,7 @@ raspiberry pi support. } V4L2m2mContext; typedef struct V4L2m2mPriv { -@@ -76,6 +139,8 @@ typedef struct V4L2m2mPriv { +@@ -75,6 +139,8 @@ typedef struct V4L2m2mPriv { int num_output_buffers; int num_capture_buffers; @@ -5322,7 +5238,7 @@ raspiberry pi support. } V4L2m2mPriv; /** -@@ -129,4 +194,26 @@ int ff_v4l2_m2m_codec_reinit(V4L2m2mCont +@@ -128,4 +194,26 @@ int ff_v4l2_m2m_codec_reinit(V4L2m2mCont */ int ff_v4l2_m2m_codec_full_reinit(V4L2m2mContext *ctx); @@ -5351,7 +5267,7 @@ raspiberry pi support. #endif /* AVCODEC_V4L2_M2M_H */ --- a/libavcodec/v4l2_m2m_dec.c +++ b/libavcodec/v4l2_m2m_dec.c -@@ -21,8 +21,14 @@ +@@ -21,8 +21,15 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -5363,10 +5279,11 @@ raspiberry pi support. +#include "libavutil/avassert.h" +#include "libavutil/hwcontext.h" +#include "libavutil/hwcontext_drm.h" ++#include "libavutil/mem.h" #include "libavutil/pixfmt.h" #include "libavutil/pixdesc.h" #include "libavutil/opt.h" -@@ -30,75 +36,279 @@ +@@ -30,75 +37,279 @@ #include "codec_internal.h" #include "libavcodec/decode.h" @@ -5384,7 +5301,7 @@ raspiberry pi support. +#include "h264_parse.h" +#endif +#if CONFIG_HEVC_DECODER -+#include "hevc_parse.h" ++#include "hevc/parse.h" +#endif + +// Pick 64 for max last count - that is >1sec at 60fps @@ -5446,13 +5363,13 @@ raspiberry pi support. + for (i = 0; i != 8; ++i) { + *s++ = ' '; + s = len > i + offset ? hex2(s, *m++) : dash2(s); - } ++ } + *s++ = ' '; + *s++ = ':'; + for (; i != 16; ++i) { + *s++ = ' '; + s = len > i + offset ? hex2(s, *m++) : dash2(s); -+ } + } + *s++ = 0; +} @@ -5694,7 +5611,7 @@ raspiberry pi support. return 0; } -@@ -133,51 +343,823 @@ static int v4l2_prepare_decoder(V4L2m2mC +@@ -133,51 +344,887 @@ static int v4l2_prepare_decoder(V4L2m2mC return 0; } @@ -5726,7 +5643,6 @@ raspiberry pi support. + // that turn up later get discarded. + + x->last_pts = AV_NOPTS_VALUE; -+ x->last_opaque = 0; + for (i = 0; i != FF_V4L2_M2M_TRACK_SIZE; ++i) { + x->track_els[i].pending = 0; + x->track_els[i].discard = 1; @@ -5919,18 +5835,18 @@ raspiberry pi support. + } + return NQ_DRAINING; + } -+ -+ if (!s->buf_pkt.size) -+ return NQ_NONE; - ret = ff_v4l2_context_enqueue_packet(output, &s->buf_pkt); - if (ret < 0 && ret != AVERROR(EAGAIN)) - goto fail; -+ if ((ret = check_output_streamon(avctx, s)) != 0) -+ return ret; ++ if (!s->buf_pkt.size) ++ return NQ_NONE; - /* if EAGAIN don't unref packet and try to enqueue in the next iteration */ - if (ret != AVERROR(EAGAIN)) ++ if ((ret = check_output_streamon(avctx, s)) != 0) ++ return ret; ++ + if (s->extdata_sent) + ret = ff_v4l2_context_enqueue_packet(&s->output, &s->buf_pkt, NULL, 0); + else @@ -6265,6 +6181,68 @@ raspiberry pi support. + av_log(avctx, AV_LOG_TRACE, "%s: Size %dx%d or fcc %s empty\n", __func__, w, h, av_fourcc2str(fcc)); + return 0; + } ++ ++ if ((s->quirks & FF_V4L2_QUIRK_8192_MACRO_MAX) != 0 && ++ ((w + 15) >> 4) * ((h + 15) >> 4) > 8192) ++ { ++ av_log(avctx, AV_LOG_DEBUG, "%s: %d x %d > 8192 macroblocks (quirk)\n", __func__, w, h); ++ return AVERROR(-EINVAL); ++ } ++ ++ // Test with TRY_FMT ++ { ++ struct v4l2_format fmt = { ++ .type = s->capture.format.type, ++ }; ++ int rv; ++ ++ if (V4L2_TYPE_IS_MULTIPLANAR(s->capture.format.type)) ++ { ++ fmt.fmt.pix.width = w; ++ fmt.fmt.pix.height = h; ++ fmt.fmt.pix.pixelformat = fcc; ++ } ++ else ++ { ++ fmt.fmt.pix_mp.width = w; ++ fmt.fmt.pix_mp.height = h; ++ fmt.fmt.pix_mp.pixelformat = fcc; ++ } ++ ++ while ((rv = ioctl(s->fd, VIDIOC_TRY_FMT, &fmt)) != 0 && errno == EINTR) ++ /* Loop */; ++ ++ if (rv != 0) { ++ rv = AVERROR(errno); ++ if (rv != AVERROR(ENOTTY)) { ++ av_log(avctx, AV_LOG_WARNING, "%s: Try FMT failed\n", __func__); ++ return rv; ++ } ++ av_log(avctx, AV_LOG_DEBUG, "%s: Try FMT not supported\n", __func__); ++ // Just continue hopefully ++ } ++ else if (V4L2_TYPE_IS_MULTIPLANAR(s->capture.format.type)) ++ { ++ av_log(avctx, AV_LOG_TRACE, "%s: requested %s %dx%d TRY_FMT %s %dx%d\n", __func__, ++ av_fourcc2str(fcc), w, h, ++ av_fourcc2str(fmt.fmt.pix.pixelformat), fmt.fmt.pix.width, fmt.fmt.pix.height); ++ if (fmt.fmt.pix.width < w || fmt.fmt.pix.height < h || fmt.fmt.pix.pixelformat != fcc) { ++ av_log(avctx, AV_LOG_DEBUG, "%s: TRY_FMT returned incompatible size\n", __func__); ++ return AVERROR(EINVAL); ++ } ++ } ++ else ++ { ++ av_log(avctx, AV_LOG_TRACE, "%s: requested %s %dx%d TRY_FMT %s %dx%d\n", __func__, ++ av_fourcc2str(fcc), w, h, ++ av_fourcc2str(fmt.fmt.pix_mp.pixelformat), fmt.fmt.pix_mp.width, fmt.fmt.pix_mp.height); ++ if (fmt.fmt.pix_mp.width < w || fmt.fmt.pix_mp.height < h || fmt.fmt.pix_mp.pixelformat != fcc) { ++ av_log(avctx, AV_LOG_DEBUG, "%s: TRY_FMT returned incompatible size\n", __func__); ++ return AVERROR(EINVAL); ++ } ++ } ++ } ++ + if ((s->quirks & FF_V4L2_QUIRK_ENUM_FRAMESIZES_BROKEN) != 0) { + av_log(avctx, AV_LOG_TRACE, "%s: Skipped (quirk): Size %dx%d, fcc %s\n", __func__, w, h, av_fourcc2str(fcc)); + return 0; @@ -6350,6 +6328,9 @@ raspiberry pi support. + // size in the first place. + if (strcmp(cap.driver, "meson-vdec") == 0) + s->quirks |= FF_V4L2_QUIRK_REINIT_ALWAYS | FF_V4L2_QUIRK_ENUM_FRAMESIZES_BROKEN; ++ // RPI has a max 8192 macroblock limit but no way of signaling it ++ if (strcmp(cap.driver, "bcm2835-codec") == 0) ++ s->quirks |= FF_V4L2_QUIRK_8192_MACRO_MAX; + + av_log(avctx, AV_LOG_DEBUG, "Driver '%s': Quirks=%#x\n", cap.driver, s->quirks); + return 0; @@ -6400,7 +6381,7 @@ raspiberry pi support. + unsigned int i; + for (i = 0; i != MAX_SPS_COUNT; ++i) { + if (ps.sps_list[i]) { -+ sps = (const SPS *)ps.sps_list[i]->data; ++ sps = ps.sps_list[i]; + break; + } + } @@ -6434,7 +6415,7 @@ raspiberry pi support. + unsigned int i; + for (i = 0; i != HEVC_MAX_SPS_COUNT; ++i) { + if (ps.sps_list[i]) { -+ sps = (const HEVCSPS *)ps.sps_list[i]->data; ++ sps = ps.sps_list[i]; + break; + } + } @@ -6545,12 +6526,14 @@ raspiberry pi support. static av_cold int v4l2_decode_init(AVCodecContext *avctx) { V4L2Context *capture, *output; -@@ -185,10 +1167,27 @@ static av_cold int v4l2_decode_init(AVCo +@@ -185,10 +1232,31 @@ static av_cold int v4l2_decode_init(AVCo V4L2m2mPriv *priv = avctx->priv_data; int ret; + av_log(avctx, AV_LOG_TRACE, "<<< %s\n", __func__); + ++#if FF_API_FRAME_PKT ++FF_DISABLE_DEPRECATION_WARNINGS + if (avctx->codec_id == AV_CODEC_ID_H264) { + if (avctx->ticks_per_frame == 1) { + if(avctx->time_base.den < INT_MAX/2) { @@ -6560,6 +6543,8 @@ raspiberry pi support. + } + avctx->ticks_per_frame = 2; + } ++FF_ENABLE_DEPRECATION_WARNINGS ++#endif + ret = ff_v4l2_m2m_create_context(priv, &s); if (ret < 0) @@ -6573,7 +6558,7 @@ raspiberry pi support. capture = &s->capture; output = &s->output; -@@ -196,14 +1195,45 @@ static av_cold int v4l2_decode_init(AVCo +@@ -196,14 +1264,45 @@ static av_cold int v4l2_decode_init(AVCo * by the v4l2 driver; this event will trigger a full pipeline reconfig and * the proper values will be retrieved from the kernel driver. */ @@ -6621,7 +6606,7 @@ raspiberry pi support. s->avctx = avctx; ret = ff_v4l2_m2m_codec_init(priv); -@@ -212,12 +1242,90 @@ static av_cold int v4l2_decode_init(AVCo +@@ -212,12 +1311,90 @@ static av_cold int v4l2_decode_init(AVCo return ret; } @@ -6714,12 +6699,10 @@ raspiberry pi support. } #define OFFSET(x) offsetof(V4L2m2mPriv, x) -@@ -226,10 +1334,17 @@ static av_cold int v4l2_decode_close(AVC - static const AVOption options[] = { +@@ -227,9 +1404,16 @@ static const AVOption options[] = { V4L_M2M_DEFAULT_OPTS, { "num_capture_buffers", "Number of buffers in the capture context", -- OFFSET(num_capture_buffers), AV_OPT_TYPE_INT, {.i64 = 20}, 20, INT_MAX, FLAGS }, -+ OFFSET(num_capture_buffers), AV_OPT_TYPE_INT, {.i64 = 20}, 2, INT_MAX, FLAGS }, + OFFSET(num_capture_buffers), AV_OPT_TYPE_INT, {.i64 = 20}, 2, INT_MAX, FLAGS }, + { "pixel_format", "Pixel format to be used by the decoder", OFFSET(pix_fmt), AV_OPT_TYPE_PIXEL_FMT, {.i64 = AV_PIX_FMT_NONE}, AV_PIX_FMT_NONE, AV_PIX_FMT_NB, FLAGS }, + { "dmabuf_alloc", "Dmabuf alloc method", OFFSET(dmabuf_alloc), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, FLAGS }, { NULL}, @@ -6733,14 +6716,15 @@ raspiberry pi support. #define M2MDEC_CLASS(NAME) \ static const AVClass v4l2_m2m_ ## NAME ## _dec_class = { \ .class_name = #NAME "_v4l2m2m_decoder", \ -@@ -250,10 +1365,16 @@ static const AVOption options[] = { +@@ -250,11 +1434,17 @@ static const AVOption options[] = { .init = v4l2_decode_init, \ FF_CODEC_RECEIVE_FRAME_CB(v4l2_receive_frame), \ .close = v4l2_decode_close, \ + .flush = v4l2_decode_flush, \ .bsfs = bsf_name, \ .p.capabilities = AV_CODEC_CAP_HARDWARE | AV_CODEC_CAP_DELAY | AV_CODEC_CAP_AVOID_PROBING, \ - .caps_internal = FF_CODEC_CAP_SETS_PKT_DTS | FF_CODEC_CAP_INIT_CLEANUP, \ + .caps_internal = FF_CODEC_CAP_NOT_INIT_THREADSAFE | \ + FF_CODEC_CAP_INIT_CLEANUP, \ .p.wrapper_name = "v4l2m2m", \ + .p.pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_DRM_PRIME, \ + AV_PIX_FMT_NV12, \ @@ -6752,19 +6736,31 @@ raspiberry pi support. M2MDEC(h264, "H.264", AV_CODEC_ID_H264, "h264_mp4toannexb"); --- a/libavcodec/v4l2_m2m_enc.c +++ b/libavcodec/v4l2_m2m_enc.c -@@ -24,6 +24,8 @@ +@@ -21,13 +21,17 @@ + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + ++#include "config.h" ++ #include #include #include -+#include + #include "encode.h" #include "libavcodec/avcodec.h" #include "libavutil/pixdesc.h" -@@ -38,6 +40,34 @@ + #include "libavutil/pixfmt.h" ++#include "libavutil/mem.h" + #include "libavutil/opt.h" + #include "codec_internal.h" + #include "profiles.h" +@@ -38,6 +42,39 @@ #define MPEG_CID(x) V4L2_CID_MPEG_VIDEO_##x #define MPEG_VIDEO(x) V4L2_MPEG_VIDEO_##x ++#if CONFIG_LIBDRM ++#include ++ +// P030 should be defined in drm_fourcc.h and hopefully will be sometime +// in the future but until then... +#ifndef DRM_FORMAT_P030 @@ -6779,6 +6775,8 @@ raspiberry pi support. +#define DRM_FORMAT_NV20 fourcc_code('N', 'V', '2', '0') +#endif + ++#endif ++ +#ifndef V4L2_CID_CODEC_BASE +#define V4L2_CID_CODEC_BASE V4L2_CID_MPEG_BASE +#endif @@ -6796,7 +6794,7 @@ raspiberry pi support. static inline void v4l2_set_timeperframe(V4L2m2mContext *s, unsigned int num, unsigned int den) { struct v4l2_streamparm parm = { 0 }; -@@ -148,15 +178,14 @@ static inline int v4l2_mpeg4_profile_fro +@@ -148,15 +185,14 @@ static inline int v4l2_mpeg4_profile_fro static int v4l2_check_b_frame_support(V4L2m2mContext *s) { if (s->avctx->max_b_frames) @@ -6814,12 +6812,15 @@ raspiberry pi support. return AVERROR_PATCHWELCOME; } -@@ -271,17 +300,208 @@ static int v4l2_prepare_encoder(V4L2m2mC +@@ -271,17 +307,212 @@ static int v4l2_prepare_encoder(V4L2m2mC return 0; } +static int avdrm_to_v4l2(struct v4l2_format * const format, const AVFrame * const frame) +{ ++#if !CONFIG_LIBDRM ++ return AVERROR_OPTION_NOT_FOUND; ++#else + const AVDRMFrameDescriptor *const src = (const AVDRMFrameDescriptor *)frame->data[0]; + + const uint32_t drm_fmt = src->layers[0].format; @@ -6903,6 +6904,7 @@ raspiberry pi support. + } + + return 0; ++#endif +} + +// Do we have similar enough formats to be usable? @@ -7025,7 +7027,7 @@ raspiberry pi support. } static int v4l2_receive_packet(AVCodecContext *avctx, AVPacket *avpkt) -@@ -292,6 +512,11 @@ static int v4l2_receive_packet(AVCodecCo +@@ -292,6 +523,11 @@ static int v4l2_receive_packet(AVCodecCo AVFrame *frame = s->frame; int ret; @@ -7037,7 +7039,7 @@ raspiberry pi support. if (s->draining) goto dequeue; -@@ -328,7 +553,115 @@ static int v4l2_receive_packet(AVCodecCo +@@ -328,7 +564,115 @@ static int v4l2_receive_packet(AVCodecCo } dequeue: @@ -7154,7 +7156,7 @@ raspiberry pi support. } static av_cold int v4l2_encode_init(AVCodecContext *avctx) -@@ -340,6 +673,8 @@ static av_cold int v4l2_encode_init(AVCo +@@ -340,6 +684,8 @@ static av_cold int v4l2_encode_init(AVCo uint32_t v4l2_fmt_output; int ret; @@ -7163,7 +7165,7 @@ raspiberry pi support. ret = ff_v4l2_m2m_create_context(priv, &s); if (ret < 0) return ret; -@@ -347,13 +682,17 @@ static av_cold int v4l2_encode_init(AVCo +@@ -347,13 +693,17 @@ static av_cold int v4l2_encode_init(AVCo capture = &s->capture; output = &s->output; @@ -7182,7 +7184,7 @@ raspiberry pi support. /* capture context */ capture->av_codec_id = avctx->codec_id; -@@ -372,7 +711,7 @@ static av_cold int v4l2_encode_init(AVCo +@@ -372,7 +722,7 @@ static av_cold int v4l2_encode_init(AVCo v4l2_fmt_output = output->format.fmt.pix.pixelformat; pix_fmt_output = ff_v4l2_format_v4l2_to_avfmt(v4l2_fmt_output, AV_CODEC_ID_RAWVIDEO); @@ -7191,7 +7193,7 @@ raspiberry pi support. const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt_output); av_log(avctx, AV_LOG_ERROR, "Encoder requires %s pixel format.\n", desc->name); return AVERROR(EINVAL); -@@ -390,9 +729,10 @@ static av_cold int v4l2_encode_close(AVC +@@ -390,9 +740,10 @@ static av_cold int v4l2_encode_close(AVC #define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM #define V4L_M2M_CAPTURE_OPTS \ @@ -7206,7 +7208,31 @@ raspiberry pi support. V4L_M2M_CAPTURE_OPTS, --- /dev/null +++ b/libavcodec/v4l2_req_decode_q.c -@@ -0,0 +1,84 @@ +@@ -0,0 +1,108 @@ ++/* ++ Copyright (C) 2024 John Cox john.cox@raspberrypi.com ++ ++ 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. ++ */ ++ +#include +#include +#include @@ -7293,7 +7319,31 @@ raspiberry pi support. + --- /dev/null +++ b/libavcodec/v4l2_req_decode_q.h -@@ -0,0 +1,27 @@ +@@ -0,0 +1,51 @@ ++/* ++ Copyright (C) 2024 John Cox john.cox@raspberrypi.com ++ ++ 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. ++ */ ++ +#ifndef AVCODEC_V4L2_REQ_DECODE_Q_H +#define AVCODEC_V4L2_REQ_DECODE_Q_H + @@ -7323,7 +7373,31 @@ raspiberry pi support. + --- /dev/null +++ b/libavcodec/v4l2_req_devscan.c -@@ -0,0 +1,451 @@ +@@ -0,0 +1,474 @@ ++/* ++ Copyright (C) 2024 John Cox john.cox@raspberrypi.com ++ ++ 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. ++ */ ++ +#include +#include +#include @@ -7462,9 +7536,8 @@ raspiberry pi support. +} + +#define REQ_BUF_CAPS (\ -+ V4L2_BUF_CAP_SUPPORTS_DMABUF |\ + V4L2_BUF_CAP_SUPPORTS_REQUESTS |\ -+ V4L2_BUF_CAP_SUPPORTS_M2M_HOLD_CAPTURE_BUF) ++ 0) + +static void probe_formats(void * const dc, + struct devscan *const scan, @@ -7777,9 +7850,33 @@ raspiberry pi support. + --- /dev/null +++ b/libavcodec/v4l2_req_devscan.h -@@ -0,0 +1,23 @@ -+#ifndef _DEVSCAN_H_ -+#define _DEVSCAN_H_ +@@ -0,0 +1,47 @@ ++/* ++ Copyright (C) 2024 John Cox john.cox@raspberrypi.com ++ ++ 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. ++ */ ++ ++#ifndef AVCODEC_V4L2_REQ_DEVSCAN_H ++#define AVCODEC_V4L2_REQ_DEVSCAN_H + +#include + @@ -7803,7 +7900,31 @@ raspiberry pi support. +#endif --- /dev/null +++ b/libavcodec/v4l2_req_dmabufs.c -@@ -0,0 +1,409 @@ +@@ -0,0 +1,433 @@ ++/* ++ Copyright (C) 2024 John Cox john.cox@raspberrypi.com ++ ++ 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. ++ */ ++ +#include +#include +#include @@ -8215,9 +8336,33 @@ raspiberry pi support. + --- /dev/null +++ b/libavcodec/v4l2_req_dmabufs.h -@@ -0,0 +1,45 @@ -+#ifndef DMABUFS_H -+#define DMABUFS_H +@@ -0,0 +1,69 @@ ++/* ++ Copyright (C) 2024 John Cox john.cox@raspberrypi.com ++ ++ 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. ++ */ ++ ++#ifndef AVCODEC_V4L2_REQ_DMABUFS_H ++#define AVCODEC_V4L2_REQ_DMABUFS_H + +#include + @@ -8263,38 +8408,161 @@ raspiberry pi support. +#endif --- /dev/null +++ b/libavcodec/v4l2_req_hevc_v1.c -@@ -0,0 +1,3 @@ +@@ -0,0 +1,27 @@ ++/* ++ Copyright (C) 2024 John Cox john.cox@raspberrypi.com ++ ++ 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. ++ */ ++ +#define HEVC_CTRLS_VERSION 1 +#include "v4l2_req_hevc_vx.c" + --- /dev/null +++ b/libavcodec/v4l2_req_hevc_v2.c -@@ -0,0 +1,3 @@ +@@ -0,0 +1,27 @@ ++/* ++ Copyright (C) 2024 John Cox john.cox@raspberrypi.com ++ ++ 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. ++ */ ++ +#define HEVC_CTRLS_VERSION 2 +#include "v4l2_req_hevc_vx.c" + --- /dev/null +++ b/libavcodec/v4l2_req_hevc_v3.c -@@ -0,0 +1,3 @@ +@@ -0,0 +1,27 @@ ++/* ++ Copyright (C) 2024 John Cox john.cox@raspberrypi.com ++ ++ 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. ++ */ ++ +#define HEVC_CTRLS_VERSION 3 +#include "v4l2_req_hevc_vx.c" + --- /dev/null +++ b/libavcodec/v4l2_req_hevc_v4.c -@@ -0,0 +1,3 @@ +@@ -0,0 +1,27 @@ ++/* ++ Copyright (C) 2024 John Cox john.cox@raspberrypi.com ++ ++ 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. ++ */ ++ +#define HEVC_CTRLS_VERSION 4 +#include "v4l2_req_hevc_vx.c" + --- /dev/null +++ b/libavcodec/v4l2_req_hevc_vx.c -@@ -0,0 +1,1362 @@ +@@ -0,0 +1,1479 @@ ++/* ++ Copyright (C) 2024 John Cox john.cox@raspberrypi.com ++ ++ 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 included by v4l2_req_hevc_v* - not compiled on its own + +#include "decode.h" -+#include "hevcdec.h" ++#include "hevc/hevcdec.h" +#include "hwconfig.h" +#include "internal.h" +#include "thread.h" ++#include "v4l2_fmt.h" ++ ++#include "libavutil/mem.h" + +#if HEVC_CTRLS_VERSION == 1 +#include "hevc-ctrls-v1.h" @@ -8352,12 +8620,12 @@ raspiberry pi support. + uint64_t timestamp; + struct qent_dst * qe_dst; + ++ // Refs to source frames ++ AVBufferRef * refs[18]; // 16 + 1 + 1 ++ + // Decode only - should be NULL by the time we emit the frame + struct req_decode_ent decode_ent; + -+ struct media_request *req; -+ struct qent_src *qe_src; -+ +#if HEVC_CTRLS_VERSION >= 2 + struct v4l2_ctrl_hevc_decode_params dec; +#endif @@ -8390,26 +8658,29 @@ raspiberry pi support. + +//static uint8_t nalu_slice_start_code[] = { 0x00, 0x00, 0x01 }; + ++static inline uint32_t vpixfmt(const struct v4l2_format *const format) ++{ ++ return V4L2_TYPE_IS_MULTIPLANAR(format->type) ? ++ format->fmt.pix_mp.pixelformat : format->fmt.pix.pixelformat; ++} + +// Get an FFmpeg format from the v4l2 format +static enum AVPixelFormat pixel_format_from_format(const struct v4l2_format *const format) +{ -+ switch (V4L2_TYPE_IS_MULTIPLANAR(format->type) ? -+ format->fmt.pix_mp.pixelformat : format->fmt.pix.pixelformat) { -+ case V4L2_PIX_FMT_YUV420: -+ return AV_PIX_FMT_YUV420P; -+ case V4L2_PIX_FMT_NV12: -+ return AV_PIX_FMT_NV12; ++ const uint32_t vfmt = vpixfmt(format); ++ switch (vfmt) { +#if CONFIG_SAND + case V4L2_PIX_FMT_NV12_COL128: ++ case V4L2_PIX_FMT_NV12_COL128M: + return AV_PIX_FMT_RPI4_8; + case V4L2_PIX_FMT_NV12_10_COL128: ++ case V4L2_PIX_FMT_NV12_10_COL128M: + return AV_PIX_FMT_RPI4_10; +#endif + default: + break; + } -+ return AV_PIX_FMT_NONE; ++ return ff_v4l2_format_v4l2_to_avfmt(vfmt, AV_CODEC_ID_RAWVIDEO); +} + +static inline uint64_t frame_capture_dpb(const AVFrame * const frame) @@ -8427,16 +8698,18 @@ raspiberry pi support. +static void fill_pred_table(const HEVCContext *h, struct v4l2_hevc_pred_weight_table *table) +{ + int32_t luma_weight_denom, chroma_weight_denom; -+ const SliceHeader *sh = &h->sh; ++ const SliceHeader * const sh = &h->sh; ++ const HEVCPPS * const pps = h->pps; ++ const HEVCSPS * const sps = pps->sps; + + if (sh->slice_type == HEVC_SLICE_I || -+ (sh->slice_type == HEVC_SLICE_P && !h->ps.pps->weighted_pred_flag) || -+ (sh->slice_type == HEVC_SLICE_B && !h->ps.pps->weighted_bipred_flag)) ++ (sh->slice_type == HEVC_SLICE_P && !pps->weighted_pred_flag) || ++ (sh->slice_type == HEVC_SLICE_B && !pps->weighted_bipred_flag)) + return; + + table->luma_log2_weight_denom = sh->luma_log2_weight_denom; + -+ if (h->ps.sps->chroma_format_idc) ++ if (sps->chroma_format_idc) + table->delta_chroma_log2_weight_denom = sh->chroma_log2_weight_denom - sh->luma_log2_weight_denom; + + luma_weight_denom = (1 << sh->luma_log2_weight_denom); @@ -8472,19 +8745,19 @@ raspiberry pi support. + + for (i = 0; i < h->rps[ST_CURR_BEF].nb_refs; i++) { + frame = h->rps[ST_CURR_BEF].ref[i]; -+ if (frame && timestamp == frame_capture_dpb(frame->frame)) ++ if (frame && timestamp == frame_capture_dpb(frame->f)) + return V4L2_HEVC_DPB_ENTRY_RPS_ST_CURR_BEFORE; + } + + for (i = 0; i < h->rps[ST_CURR_AFT].nb_refs; i++) { + frame = h->rps[ST_CURR_AFT].ref[i]; -+ if (frame && timestamp == frame_capture_dpb(frame->frame)) ++ if (frame && timestamp == frame_capture_dpb(frame->f)) + return V4L2_HEVC_DPB_ENTRY_RPS_ST_CURR_AFTER; + } + + for (i = 0; i < h->rps[LT_CURR].nb_refs; i++) { + frame = h->rps[LT_CURR].ref[i]; -+ if (frame && timestamp == frame_capture_dpb(frame->frame)) ++ if (frame && timestamp == frame_capture_dpb(frame->f)) + return V4L2_HEVC_DPB_ENTRY_RPS_LT_CURR; + } + @@ -8502,7 +8775,7 @@ raspiberry pi support. + if (!frame) + return 0; + -+ timestamp = frame_capture_dpb(frame->frame); ++ timestamp = frame_capture_dpb(frame->f); + + for (unsigned int i = 0; i < num_entries; i++) { + if (entries[i].timestamp == timestamp) @@ -8530,27 +8803,42 @@ raspiberry pi support. + return b; +} + ++static uint32_t trimmed_bits(const uint8_t * b, unsigned int byte_len) ++{ ++ const uint8_t * p = b + byte_len - 1; ++ unsigned int i; ++ // Strip simple trailing zeros ++ while (p > b && p[0] == 0) ++ --p; ++ // Strip cabac zero words ++ while (p > b + 2 && p[0] == 3 && p[-1] == 0 && p[-2] == 0) ++ p -= 3; ++ // We expect this byte to be non zero for a legal stream ++ for (i = 0; i != 7; ++i) ++ if (((1 << i) & p[0]) != 0) ++ break; ++ return (p - b) * 8 + 7 - i; ++} ++ +static int slice_add(V4L2MediaReqDescriptor * const rd) +{ + if (rd->num_slices >= rd->alloced_slices) { -+ struct v4l2_ctrl_hevc_slice_params * p2; -+ struct slice_info * s2; + size_t n2 = rd->alloced_slices == 0 ? 8 : rd->alloced_slices * 2; + -+ p2 = av_realloc_array(rd->slice_params, n2, sizeof(*p2)); -+ if (p2 == NULL) -+ return AVERROR(ENOMEM); -+ rd->slice_params = p2; -+ -+ s2 = av_realloc_array(rd->slices, n2, sizeof(*s2)); -+ if (s2 == NULL) -+ return AVERROR(ENOMEM); -+ rd->slices = s2; -+ ++ if (av_reallocp_array(&rd->slice_params, n2, sizeof(*rd->slice_params))) ++ goto fail; ++ if (av_reallocp_array(&rd->slices, n2, sizeof(*rd->slices))) ++ goto fail; + rd->alloced_slices = n2; + } + ++rd->num_slices; + return 0; ++ ++fail: ++ av_freep(&rd->slices); ++ rd->alloced_slices = 0; ++ rd->num_slices = 0; ++ return AVERROR(ENOMEM); +} + +static int offsets_add(V4L2MediaReqDescriptor *const rd, const size_t n, const unsigned * const offsets) @@ -8560,8 +8848,11 @@ raspiberry pi support. + void * p2; + while (rd->num_offsets + n > n2) + n2 *= 2; -+ if ((p2 = av_realloc_array(rd->offsets, n2, sizeof(*rd->offsets))) == NULL) ++ if (av_reallocp_array(&rd->offsets, n2, sizeof(*rd->offsets))) { ++ rd->alloced_offsets = 0; ++ rd->num_offsets = 0; + return AVERROR(ENOMEM); ++ } + rd->offsets = p2; + rd->alloced_offsets = n2; + } @@ -8575,21 +8866,22 @@ raspiberry pi support. +{ + unsigned int i; + unsigned int n = 0; -+ const HEVCFrame * const pic = h->ref; ++ const HEVCFrame * const pic = h->cur_frame; ++ const HEVCLayerContext * const layer = &h->layers[h->cur_layer]; + -+ for (i = 0; i < FF_ARRAY_ELEMS(h->DPB); i++) { -+ const HEVCFrame * const frame = &h->DPB[i]; ++ for (i = 0; i < FF_ARRAY_ELEMS(layer->DPB); i++) { ++ const HEVCFrame * const frame = &layer->DPB[i]; + if (frame != pic && (frame->flags & (HEVC_FRAME_FLAG_LONG_REF | HEVC_FRAME_FLAG_SHORT_REF))) { + struct v4l2_hevc_dpb_entry * const entry = entries + n++; + -+ entry->timestamp = frame_capture_dpb(frame->frame); ++ entry->timestamp = frame_capture_dpb(frame->f); +#if HEVC_CTRLS_VERSION <= 2 + entry->rps = find_frame_rps_type(h, entry->timestamp); +#else + entry->flags = (frame->flags & HEVC_FRAME_FLAG_LONG_REF) == 0 ? 0 : + V4L2_HEVC_DPB_ENTRY_LONG_TERM_REFERENCE; +#endif -+ entry->field_pic = frame->frame->interlaced_frame; ++ entry->field_pic = (frame->f->flags & AV_FRAME_FLAG_INTERLACED) != 0; + +#if HEVC_CTRLS_VERSION <= 3 + /* TODO: Interleaved: Get the POC for each field. */ @@ -8608,7 +8900,7 @@ raspiberry pi support. + const struct v4l2_ctrl_hevc_decode_params * const dec, +#endif + struct v4l2_ctrl_hevc_slice_params *slice_params, -+ uint32_t bit_size, uint32_t bit_offset) ++ const uint32_t data_offset, const uint32_t bit_size) +{ + const SliceHeader * const sh = &h->sh; +#if HEVC_CTRLS_VERSION >= 2 @@ -8624,9 +8916,9 @@ raspiberry pi support. + *slice_params = (struct v4l2_ctrl_hevc_slice_params) { + .bit_size = bit_size, +#if HEVC_CTRLS_VERSION <= 3 -+ .data_bit_offset = bit_offset, ++ .data_bit_offset = data_offset * 8 - 1, +#else -+ .data_byte_offset = bit_offset / 8 + 1, ++ .data_byte_offset = data_offset, +#endif + /* ISO/IEC 23008-2, ITU-T Rec. H.265: General slice segment header */ + .slice_segment_addr = sh->slice_segment_addr, @@ -8638,7 +8930,7 @@ raspiberry pi support. + /* ISO/IEC 23008-2, ITU-T Rec. H.265: General slice segment header */ + .slice_type = sh->slice_type, + .colour_plane_id = sh->colour_plane_id, -+ .slice_pic_order_cnt = h->ref->poc, ++ .slice_pic_order_cnt = h->cur_frame->poc, + .num_ref_idx_l0_active_minus1 = sh->nb_refs[L0] ? sh->nb_refs[L0] - 1 : 0, + .num_ref_idx_l1_active_minus1 = sh->nb_refs[L1] ? sh->nb_refs[L1] - 1 : 0, + .collocated_ref_idx = sh->slice_temporal_mvp_enabled_flag ? sh->collocated_ref_idx : 0, @@ -8696,13 +8988,13 @@ raspiberry pi support. +#endif + + if (sh->slice_type != HEVC_SLICE_I) { -+ rpl = &h->ref->refPicList[0]; ++ rpl = &h->cur_frame->refPicList[0]; + for (i = 0; i < rpl->nb_refs; i++) + slice_params->ref_idx_l0[i] = get_ref_pic_index(h, rpl->ref[i], dpb, dpb_n); + } + + if (sh->slice_type == HEVC_SLICE_B) { -+ rpl = &h->ref->refPicList[1]; ++ rpl = &h->cur_frame->refPicList[1]; + for (i = 0; i < rpl->nb_refs; i++) + slice_params->ref_idx_l1[i] = get_ref_pic_index(h, rpl->ref[i], dpb, dpb_n); + } @@ -8786,31 +9078,31 @@ raspiberry pi support. + .sps_max_sub_layers_minus1 = sps->max_sub_layers - 1, + }; + -+ if (sps->separate_colour_plane_flag) ++ if (sps->separate_colour_plane) + ctrl->flags |= V4L2_HEVC_SPS_FLAG_SEPARATE_COLOUR_PLANE; + -+ if (sps->scaling_list_enable_flag) ++ if (sps->scaling_list_enabled) + ctrl->flags |= V4L2_HEVC_SPS_FLAG_SCALING_LIST_ENABLED; + -+ if (sps->amp_enabled_flag) ++ if (sps->amp_enabled) + ctrl->flags |= V4L2_HEVC_SPS_FLAG_AMP_ENABLED; + + if (sps->sao_enabled) + ctrl->flags |= V4L2_HEVC_SPS_FLAG_SAMPLE_ADAPTIVE_OFFSET; + -+ if (sps->pcm_enabled_flag) ++ if (sps->pcm_enabled) + ctrl->flags |= V4L2_HEVC_SPS_FLAG_PCM_ENABLED; + -+ if (sps->pcm.loop_filter_disable_flag) ++ if (sps->pcm_loop_filter_disabled) + ctrl->flags |= V4L2_HEVC_SPS_FLAG_PCM_LOOP_FILTER_DISABLED; + -+ if (sps->long_term_ref_pics_present_flag) ++ if (sps->long_term_ref_pics_present) + ctrl->flags |= V4L2_HEVC_SPS_FLAG_LONG_TERM_REF_PICS_PRESENT; + -+ if (sps->sps_temporal_mvp_enabled_flag) ++ if (sps->temporal_mvp_enabled) + ctrl->flags |= V4L2_HEVC_SPS_FLAG_SPS_TEMPORAL_MVP_ENABLED; + -+ if (sps->sps_strong_intra_smoothing_enable_flag) ++ if (sps->strong_intra_smoothing_enabled) + ctrl->flags |= V4L2_HEVC_SPS_FLAG_STRONG_INTRA_SMOOTHING_ENABLED; +} + @@ -8923,6 +9215,25 @@ raspiberry pi support. + } +} + ++static int frame_finish(V4L2MediaReqDescriptor * const rd) ++{ ++ int rv = 0; ++ ++ if (rd->qe_dst) { ++ MediaBufsStatus stat = qent_dst_wait(rd->qe_dst); ++ if (stat != MEDIABUFS_STATUS_SUCCESS) ++ rv = -1; ++ } ++ ++ { ++ AVBufferRef **p = rd->refs; ++ for (; *p != NULL; ++p) ++ av_buffer_unref(p); ++ } ++ ++ return rv; ++} ++ +// Called before finally returning the frame to the user +// Set corrupt flag here as this is actually the frame structure that +// is going to the user (in MT land each thread has its own pool) @@ -8932,14 +9243,11 @@ raspiberry pi support. + +// av_log(NULL, AV_LOG_INFO, "%s\n", __func__); + frame->flags &= ~AV_FRAME_FLAG_CORRUPT; -+ if (rd->qe_dst) { -+ MediaBufsStatus stat = qent_dst_wait(rd->qe_dst); -+ if (stat != MEDIABUFS_STATUS_SUCCESS) { -+ av_log(logctx, AV_LOG_ERROR, "%s: Decode fail\n", __func__); -+ frame->flags |= AV_FRAME_FLAG_CORRUPT; -+ } ++ if (frame_finish(rd) != 0) { ++ av_log(logctx, AV_LOG_ERROR, "%s: Decode fail\n", __func__); ++ frame->flags |= AV_FRAME_FLAG_CORRUPT; + } -+ ++ av_dict_set_int(&frame->metadata, "v4l2_ts", rd->timestamp, 0); + return 0; +} + @@ -8958,12 +9266,12 @@ raspiberry pi support. +} + +static int v4l2_request_hevc_start_frame(AVCodecContext *avctx, ++ V4L2RequestContextHEVC *const ctx, + av_unused const uint8_t *buffer, + av_unused uint32_t size) +{ + const HEVCContext *h = avctx->priv_data; -+ V4L2MediaReqDescriptor *const rd = (V4L2MediaReqDescriptor *)h->ref->frame->data[0]; -+ V4L2RequestContextHEVC * const ctx = avctx->internal->hwaccel_priv_data; ++ V4L2MediaReqDescriptor *const rd = (V4L2MediaReqDescriptor *)h->cur_frame->f->data[0]; + +// av_log(NULL, AV_LOG_INFO, "%s\n", __func__); + decode_q_add(&ctx->decode_q, &rd->decode_ent); @@ -8973,7 +9281,7 @@ raspiberry pi support. + rd->timestamp = cvt_timestamp_to_dpb(ctx->timestamp); + + { -+ FrameDecodeData * const fdd = (FrameDecodeData*)h->ref->frame->private_ref->data; ++ FrameDecodeData * const fdd = (FrameDecodeData*)h->cur_frame->f->private_ref->data; + fdd->post_process = frame_post_process; + } + @@ -8986,7 +9294,7 @@ raspiberry pi support. + } + } + -+ ff_thread_finish_setup(avctx); // Allow next thread to enter rpi_hevc_start_frame ++ // ff_thread_finish_setup by caller + + return 0; +} @@ -8998,7 +9306,10 @@ raspiberry pi support. + unsigned int width; + unsigned int height; + unsigned int bpl; ++ unsigned int bpl2; + uint32_t pixelformat; ++ uint64_t mod = DRM_FORMAT_MOD_LINEAR; ++ unsigned int object_count = 1; + + if (V4L2_TYPE_IS_MULTIPLANAR(format->type)) { + width = format->fmt.pix_mp.width; @@ -9012,51 +9323,68 @@ raspiberry pi support. + pixelformat = format->fmt.pix.pixelformat; + bpl = format->fmt.pix.bytesperline; + } ++ bpl2 = bpl; + + switch (pixelformat) { + case V4L2_PIX_FMT_NV12: + layer->format = DRM_FORMAT_NV12; -+ desc->objects[0].format_modifier = DRM_FORMAT_MOD_LINEAR; ++ break; ++ case V4L2_PIX_FMT_P010: ++ layer->format = DRM_FORMAT_P010; + break; +#if CONFIG_SAND + case V4L2_PIX_FMT_NV12_COL128: + layer->format = DRM_FORMAT_NV12; -+ desc->objects[0].format_modifier = DRM_FORMAT_MOD_BROADCOM_SAND128_COL_HEIGHT(bpl); ++ mod = DRM_FORMAT_MOD_BROADCOM_SAND128_COL_HEIGHT(bpl); + break; + case V4L2_PIX_FMT_NV12_10_COL128: + layer->format = DRM_FORMAT_P030; -+ desc->objects[0].format_modifier = DRM_FORMAT_MOD_BROADCOM_SAND128_COL_HEIGHT(bpl); ++ mod = DRM_FORMAT_MOD_BROADCOM_SAND128_COL_HEIGHT(bpl); ++ break; ++ case V4L2_PIX_FMT_NV12_COL128M: ++ layer->format = DRM_FORMAT_NV12; ++ mod = DRM_FORMAT_MOD_BROADCOM_SAND128_COL_HEIGHT(0); ++ bpl = height; ++ bpl2 = height / 2; ++ object_count = 2; ++ break; ++ case V4L2_PIX_FMT_NV12_10_COL128M: ++ layer->format = DRM_FORMAT_P030; ++ mod = DRM_FORMAT_MOD_BROADCOM_SAND128_COL_HEIGHT(0); ++ bpl = height; ++ bpl2 = height / 2; ++ object_count = 2; + break; +#endif +#ifdef DRM_FORMAT_MOD_ALLWINNER_TILED + case V4L2_PIX_FMT_SUNXI_TILED_NV12: + layer->format = DRM_FORMAT_NV12; -+ desc->objects[0].format_modifier = DRM_FORMAT_MOD_ALLWINNER_TILED; ++ mod = DRM_FORMAT_MOD_ALLWINNER_TILED; + break; +#endif +#if defined(V4L2_PIX_FMT_NV15) && defined(DRM_FORMAT_NV15) + case V4L2_PIX_FMT_NV15: + layer->format = DRM_FORMAT_NV15; -+ desc->objects[0].format_modifier = DRM_FORMAT_MOD_LINEAR; + break; +#endif + case V4L2_PIX_FMT_NV16: + layer->format = DRM_FORMAT_NV16; -+ desc->objects[0].format_modifier = DRM_FORMAT_MOD_LINEAR; + break; +#if defined(V4L2_PIX_FMT_NV20) && defined(DRM_FORMAT_NV20) + case V4L2_PIX_FMT_NV20: + layer->format = DRM_FORMAT_NV20; -+ desc->objects[0].format_modifier = DRM_FORMAT_MOD_LINEAR; + break; +#endif + default: + return -1; + } + -+ desc->nb_objects = 1; -+ desc->objects[0].fd = -1; -+ desc->objects[0].size = 0; ++ desc->nb_objects = object_count; ++ for (unsigned int i = 0; i != AV_DRM_MAX_PLANES; ++i) { ++ desc->objects[i].fd = -1; ++ desc->objects[i].size = 0; ++ desc->objects[i].format_modifier = (i >= object_count) ? DRM_FORMAT_MOD_INVALID : mod; ++ } + + desc->nb_layers = 1; + layer->nb_planes = 2; @@ -9080,9 +9408,9 @@ raspiberry pi support. + else +#endif + { -+ layer->planes[1].object_index = 0; -+ layer->planes[1].offset = layer->planes[0].pitch * height; -+ layer->planes[1].pitch = layer->planes[0].pitch; ++ layer->planes[1].object_index = (object_count > 1) ? 1 : 0; ++ layer->planes[1].offset = (object_count > 1) ? 0 : layer->planes[0].pitch * height; ++ layer->planes[1].pitch = bpl2; + } + + return 0; @@ -9152,16 +9480,32 @@ raspiberry pi support. + return rv; +} + ++static void ++add_ref_once(V4L2MediaReqDescriptor * const rd, struct HEVCFrame * const ref) ++{ ++ AVBufferRef **p = rd->refs; ++ int i = 0; ++ while (*p != NULL) { ++ if (ref->f->buf[0]->data == (*p)->data) ++ return; ++ ++p; ++ av_assert0(++i < 16); ++ } ++ *p = av_buffer_ref(ref->f->buf[0]); ++} ++ +// This only works because we started out from a single coded frame buffer +// that will remain intact until after end_frame -+static int v4l2_request_hevc_decode_slice(AVCodecContext *avctx, const uint8_t *buffer, uint32_t size) ++static int v4l2_request_hevc_decode_slice(AVCodecContext *avctx, V4L2RequestContextHEVC *const ctx, ++ const uint8_t *buffer, uint32_t buffer_size) +{ ++ uint32_t size = buffer_size; + const HEVCContext * const h = avctx->priv_data; -+ V4L2RequestContextHEVC * const ctx = avctx->internal->hwaccel_priv_data; -+ V4L2MediaReqDescriptor * const rd = (V4L2MediaReqDescriptor*)h->ref->frame->data[0]; -+ int bcount = get_bits_count(&h->HEVClc->gb); -+ uint32_t boff = (ptr_from_index(buffer, bcount/8 + 1) - (buffer + bcount/8 + 1)) * 8 + bcount; -+ ++ const SliceHeader * const sh = &h->sh; ++ V4L2MediaReqDescriptor * const rd = (V4L2MediaReqDescriptor*)h->cur_frame->f->data[0]; ++ uint32_t data_offset = (ptr_from_index(buffer, sh->data_offset) - buffer); ++ uint32_t block_offset = 0; ++ uint32_t bsize; + const unsigned int n = rd->num_slices; + const unsigned int block_start = (n / ctx->max_slices) * ctx->max_slices; + @@ -9173,24 +9517,13 @@ raspiberry pi support. + if (ctx->start_code == V4L2_STATELESS_HEVC_START_CODE_ANNEX_B) { + buffer -= 3; + size += 3; -+ boff += 24; ++ data_offset += 3; + if (buffer[0] != 0 || buffer[1] != 0 || buffer[2] != 1) { + av_log(avctx, AV_LOG_ERROR, "Start code requested but missing %02x:%02x:%02x\n", + buffer[0], buffer[1], buffer[2]); + } + } + -+ if (ctx->decode_mode == V4L2_STATELESS_HEVC_DECODE_MODE_FRAME_BASED) { -+ if (rd->slices == NULL) { -+ if ((rd->slices = av_mallocz(sizeof(*rd->slices))) == NULL) -+ return AVERROR(ENOMEM); -+ rd->slices->ptr = buffer; -+ rd->num_slices = 1; -+ } -+ rd->slices->len = buffer - rd->slices->ptr + size; -+ return 0; -+ } -+ + if ((rv = slice_add(rd)) != 0) + return rv; + @@ -9201,19 +9534,38 @@ raspiberry pi support. + + if (n != block_start) { + struct slice_info *const si0 = rd->slices + block_start; -+ const size_t offset = (buffer - si0->ptr); -+ boff += offset * 8; -+ size += offset; -+ si0->len = si->len + offset; ++ block_offset = (buffer - si0->ptr); ++ si0->len = si->len + block_offset; + } + ++ bsize = ctx->bit_size_is_offset ? ++ (size + block_offset) * 8 : ++ trimmed_bits(buffer + data_offset, size - data_offset); +#if HEVC_CTRLS_VERSION >= 2 + if (n == 0) + fill_decode_params(h, &rd->dec); -+ fill_slice_params(h, &rd->dec, rd->slice_params + n, size * 8, boff); ++ fill_slice_params(h, &rd->dec, rd->slice_params + n, data_offset + block_offset, bsize); +#else -+ fill_slice_params(h, rd->slice_params + n, size * 8, boff); ++ fill_slice_params(h, rd->slice_params + n, data_offset + block_offset, bsize); +#endif ++ ++ { ++ RefPicList *rpl; ++ int i; ++ ++ if (sh->slice_type != HEVC_SLICE_I) { ++ rpl = &h->cur_frame->refPicList[0]; ++ for (i = 0; i < rpl->nb_refs; i++) ++ add_ref_once(rd, rpl->ref[i]); ++ } ++ ++ if (sh->slice_type == HEVC_SLICE_B) { ++ rpl = &h->cur_frame->refPicList[1]; ++ for (i = 0; i < rpl->nb_refs; i++) ++ add_ref_once(rd, rpl->ref[i]); ++ } ++ } ++ + if (ctx->max_offsets != 0 && + (rv = offsets_add(rd, h->sh.num_entry_point_offsets, h->sh.entry_point_offset)) != 0) + return rv; @@ -9221,27 +9573,22 @@ raspiberry pi support. + return 0; +} + -+static void v4l2_request_hevc_abort_frame(AVCodecContext * const avctx) ++static void v4l2_request_hevc_abort_frame(AVCodecContext * const avctx, V4L2RequestContextHEVC *const ctx) +{ + const HEVCContext * const h = avctx->priv_data; -+ if (h->ref != NULL) { -+ V4L2MediaReqDescriptor *const rd = (V4L2MediaReqDescriptor *)h->ref->frame->data[0]; -+ V4L2RequestContextHEVC * const ctx = avctx->internal->hwaccel_priv_data; -+ -+ media_request_abort(&rd->req); -+ mediabufs_src_qent_abort(ctx->mbufs, &rd->qe_src); ++ if (h->cur_frame != NULL) { ++ V4L2MediaReqDescriptor *const rd = (V4L2MediaReqDescriptor *)h->cur_frame->f->data[0]; + + decode_q_remove(&ctx->decode_q, &rd->decode_ent); + } +} + +static int send_slice(AVCodecContext * const avctx, ++ V4L2RequestContextHEVC * const ctx, + V4L2MediaReqDescriptor * const rd, + struct req_controls *const controls, + const unsigned int i, const unsigned int j) +{ -+ V4L2RequestContextHEVC * const ctx = avctx->internal->hwaccel_priv_data; -+ + const int is_last = (j == rd->num_slices); + struct slice_info *const si = rd->slices + i; + struct media_request * req = NULL; @@ -9298,11 +9645,10 @@ raspiberry pi support. + return AVERROR_UNKNOWN; +} + -+static int v4l2_request_hevc_end_frame(AVCodecContext *avctx) ++static int v4l2_request_hevc_end_frame(AVCodecContext *avctx, V4L2RequestContextHEVC *const ctx) +{ + const HEVCContext * const h = avctx->priv_data; -+ V4L2MediaReqDescriptor *rd = (V4L2MediaReqDescriptor*)h->ref->frame->data[0]; -+ V4L2RequestContextHEVC *ctx = avctx->internal->hwaccel_priv_data; ++ V4L2MediaReqDescriptor *rd = (V4L2MediaReqDescriptor*)h->cur_frame->f->data[0]; + struct req_controls rc; + unsigned int i; + int rv; @@ -9315,16 +9661,18 @@ raspiberry pi support. + } + + { -+ const ScalingList *sl = h->ps.pps->scaling_list_data_present_flag ? -+ &h->ps.pps->scaling_list : -+ h->ps.sps->scaling_list_enable_flag ? -+ &h->ps.sps->scaling_list : NULL; ++ const HEVCPPS *pps = h->pps; ++ const HEVCSPS *sps = pps->sps; ++ const ScalingList *sl = pps->scaling_list_data_present_flag ? ++ &pps->scaling_list : ++ sps->scaling_list_enabled ? ++ &sps->scaling_list : NULL; + + + memset(&rc, 0, sizeof(rc)); + rc.tv = cvt_dpb_to_tv(rd->timestamp); -+ fill_sps(&rc.sps, h->ps.sps); -+ fill_pps(&rc.pps, h->ps.pps); ++ fill_sps(&rc.sps, sps); ++ fill_pps(&rc.pps, pps); + if (sl) { + rc.has_scaling = 1; + fill_scaling_matrix(sl, &rc.scaling_matrix); @@ -9350,14 +9698,16 @@ raspiberry pi support. + // Send as slices + for (i = 0; i < rd->num_slices; i += ctx->max_slices) { + const unsigned int e = FFMIN(rd->num_slices, i + ctx->max_slices); -+ if ((rv = send_slice(avctx, rd, &rc, i, e)) != 0) ++ if ((rv = send_slice(avctx, ctx, rd, &rc, i, e)) != 0) + goto fail; + } + + // Set the drm_prime desriptor + drm_from_format(&rd->drm, mediabufs_dst_fmt(ctx->mbufs)); -+ rd->drm.objects[0].fd = dmabuf_fd(qent_dst_dmabuf(rd->qe_dst, 0)); -+ rd->drm.objects[0].size = dmabuf_size(qent_dst_dmabuf(rd->qe_dst, 0)); ++ for (i = 0; i != rd->drm.nb_objects; ++i) { ++ rd->drm.objects[i].fd = dmabuf_fd(qent_dst_dmabuf(rd->qe_dst, i)); ++ rd->drm.objects[i].size = dmabuf_size(qent_dst_dmabuf(rd->qe_dst, i)); ++ } + + decode_q_remove(&ctx->decode_q, &rd->decode_ent); + return 0; @@ -9378,7 +9728,7 @@ raspiberry pi support. +probe(AVCodecContext * const avctx, V4L2RequestContextHEVC * const ctx) +{ + const HEVCContext *h = avctx->priv_data; -+ const HEVCSPS * const sps = h->ps.sps; ++ const HEVCSPS * const sps = h->pps->sps; + struct v4l2_ctrl_hevc_sps ctrl_sps; + unsigned int i; + @@ -9416,11 +9766,7 @@ raspiberry pi support. + + mediabufs_ctl_query_ext_ctrls(ctx->mbufs, qc, noof_ctrls); + i = 0; -+#if HEVC_CTRLS_VERSION >= 4 -+ // Skip slice check if no slice mode -+ if (qc[1].type != 0 && !ctrl_valid(qc + 1, V4L2_STATELESS_HEVC_DECODE_MODE_SLICE_BASED)) -+ i = 1; -+#else ++#if HEVC_CTRLS_VERSION < 4 + // Fail frame mode silently for anything prior to V4 + if (qc[1].type == 0 || !ctrl_valid(qc + 1, V4L2_STATELESS_HEVC_DECODE_MODE_SLICE_BASED)) + return AVERROR(EINVAL); @@ -9467,6 +9813,17 @@ raspiberry pi support. + { .id = V4L2_CID_STATELESS_HEVC_START_CODE, }, + }; + ++ // Fix RPi Quirk ++ switch (vpixfmt(mediabufs_dst_fmt(ctx->mbufs))) { ++ case V4L2_PIX_FMT_NV12_COL128: ++ case V4L2_PIX_FMT_NV12_10_COL128: ++ ctx->bit_size_is_offset = 1; ++ break; ++ default: ++ ctx->bit_size_is_offset = 0; ++ break; ++ } ++ + mediabufs_ctl_query_ext_ctrls(ctx->mbufs, querys, FF_ARRAY_ELEMS(querys)); + + ctx->max_slices = (!(querys[2].flags & V4L2_CTRL_FLAG_DYNAMIC_ARRAY) || @@ -9526,11 +9883,9 @@ raspiberry pi support. + + av_log(NULL, AV_LOG_DEBUG, "%s: avctx=%p data=%p\n", __func__, avctx, data); + -+ qent_dst_unref(&rd->qe_dst); ++ frame_finish(rd); + -+ // We don't expect req or qe_src to be set -+ if (rd->req || rd->qe_src) -+ av_log(NULL, AV_LOG_ERROR, "%s: qe_src %p or req %p not NULL\n", __func__, rd->req, rd->qe_src); ++ qent_dst_unref(&rd->qe_dst); + + av_freep(&rd->slices); + av_freep(&rd->slice_params); @@ -9575,9 +9930,8 @@ raspiberry pi support. +} +#endif + -+static int frame_params(AVCodecContext *avctx, AVBufferRef *hw_frames_ctx) ++static int frame_params(AVCodecContext *avctx, V4L2RequestContextHEVC *const ctx, AVBufferRef *hw_frames_ctx) +{ -+ V4L2RequestContextHEVC *ctx = avctx->internal->hwaccel_priv_data; + AVHWFramesContext *hwfc = (AVHWFramesContext*)hw_frames_ctx->data; + const struct v4l2_format *vfmt = mediabufs_dst_fmt(ctx->mbufs); + @@ -9615,7 +9969,7 @@ raspiberry pi support. + return 0; +} + -+static int alloc_frame(AVCodecContext * avctx, AVFrame *frame) ++static int alloc_frame(AVCodecContext * avctx, V4L2RequestContextHEVC *const ctx, AVFrame *frame) +{ + int rv; + @@ -9626,6 +9980,10 @@ raspiberry pi support. + frame->data[0] = frame->buf[0]->data; + + frame->hw_frames_ctx = av_buffer_ref(avctx->hw_frames_ctx); ++ // Cropping will be applied by hevc_refs.c:ff_hevc_set_new_ref ++ // Mirrors hwaccel path in avcodec_default_get_buffer2 ++ frame->width = avctx->coded_width; ++ frame->height = avctx->coded_height; + + if ((rv = ff_attach_decode_data(frame)) != 0) { + av_log(avctx, AV_LOG_ERROR, "Failed to attach decode data to frame\n"); @@ -9652,7 +10010,7 @@ raspiberry pi support. + --- /dev/null +++ b/libavcodec/v4l2_req_media.c -@@ -0,0 +1,1808 @@ +@@ -0,0 +1,1835 @@ +/* + * Copyright (C) 2018 Paul Kocialkowski + * @@ -10038,7 +10396,7 @@ raspiberry pi support. +struct buf_pool { + enum mediabufs_memory memtype; + pthread_mutex_t lock; -+ sem_t free_sem; ++ pthread_cond_t cond; + struct qe_list_head free; + struct qe_list_head inuse; +}; @@ -10199,8 +10557,8 @@ raspiberry pi support. + for (i = 0; i < VIDEO_MAX_PLANES && be->dh[i]; ++i) + dmabuf_len_set(be->dh[i], 0); + bq_put_free(bp, be); ++ pthread_cond_broadcast(&bp->cond); + pthread_mutex_unlock(&bp->lock); -+ sem_post(&bp->free_sem); +} + +static bool queue_is_inuse(const struct buf_pool *const bp) @@ -10222,10 +10580,9 @@ raspiberry pi support. +{ + struct qent_base *buf; + -+ if (do_wait(&bp->free_sem)) -+ return NULL; + pthread_mutex_lock(&bp->lock); -+ buf = bq_get_free(bp); ++ while ((buf = bq_get_free(bp)) == NULL && pthread_cond_wait(&bp->cond, &bp->lock) == 0) ++ /* Loop */; + pthread_mutex_unlock(&bp->lock); + return buf; +} @@ -10234,8 +10591,6 @@ raspiberry pi support. +{ + struct qent_base *buf; + -+ if (do_trywait(&bp->free_sem)) -+ return NULL; + pthread_mutex_lock(&bp->lock); + buf = bq_get_free(bp); + pthread_mutex_unlock(&bp->lock); @@ -10261,7 +10616,7 @@ raspiberry pi support. + +static void queue_delete(struct buf_pool *const bp) +{ -+ sem_destroy(&bp->free_sem); ++ pthread_cond_destroy(&bp->cond); + pthread_mutex_destroy(&bp->lock); + free(bp); +} @@ -10272,7 +10627,7 @@ raspiberry pi support. + if (!bp) + return NULL; + pthread_mutex_init(&bp->lock, NULL); -+ sem_init(&bp->free_sem, 0, 0); ++ pthread_cond_init(&bp->cond, NULL); + return bp; +} + @@ -10478,7 +10833,7 @@ raspiberry pi support. +{ + if (!be->dh[0] || len > dmabuf_size(be->dh[0])) { + size_t newsize = round_up_size(len); -+ request_log("%s: Overrun %zd > %zd; trying %zd\n", __func__, len, dmabuf_size(be->dh[0]), newsize); ++ request_debug(NULL, "%s: Overrun %zd > %zd; trying %zd\n", __func__, len, dmabuf_size(be->dh[0]), newsize); + if (!dbsc) { + request_log("%s: No dmbabuf_ctrl for realloc\n", __func__); + return -ENOMEM; @@ -10519,7 +10874,7 @@ raspiberry pi support. + return 0; +} + -+const struct dmabuf_h * qent_dst_dmabuf(const struct qent_dst *const be_dst, unsigned int plane) ++struct dmabuf_h * qent_dst_dmabuf(const struct qent_dst *const be_dst, unsigned int plane) +{ + const struct qent_base *const be = &be_dst->base; + @@ -10828,6 +11183,32 @@ raspiberry pi support. + return cbuf.count; +} + ++static void queue_dst_wait_no_waiting(struct buf_pool *const bp) ++{ ++ // This is O(n^2), but n is not very big & shoudl only happen on shutdown ++ // so it isn't worth adding any processing to anything else to make this ++ // more efficient ++ for (;;) { ++ struct qent_base *be; ++ struct qent_dst *be_dst = NULL; ++ ++ pthread_mutex_lock(&bp->lock); ++ for (be = bp->inuse.head; be != NULL; be = be->next) { ++ be_dst = base_to_dst(be); ++ if (be_dst->waiting) { ++ qent_dst_ref(be_dst); ++ break; ++ } ++ } ++ pthread_mutex_unlock(&bp->lock); ++ ++ if (be == NULL) ++ break; ++ ++ qent_dst_wait(be_dst); ++ } ++} ++ +static MediaBufsStatus +qe_import_from_buf(struct mediabufs_ctl *const mbc, struct qent_base * const be, const struct v4l2_format *const fmt, + const unsigned int n, const bool x_dmabuf) @@ -10940,7 +11321,9 @@ raspiberry pi support. + + if (create_dst_bufs(mbc, 1, &be_dst) != 1) { + qe_dst_free(be_dst); -+ return NULL; ++ // We can't extend any more - try again but wait ++ mbc->dst_fixed = true; ++ return mediabufs_dst_qent_alloc(mbc, dbsc); + } + } + } @@ -11222,7 +11605,13 @@ raspiberry pi support. + return status; +} + -+int mediabufs_ctl_set_ext_ctrls(struct mediabufs_ctl * mbc, struct media_request * const mreq, struct v4l2_ext_control control_array[], unsigned int n) ++MediaBufsStatus mediabufs_stream_wait_dst_done(struct mediabufs_ctl *const mbc) ++{ ++ queue_dst_wait_no_waiting(mbc->dst); ++ return MEDIABUFS_STATUS_SUCCESS; ++} ++ ++int mediabufs_ctl_set_ext_ctrls(struct mediabufs_ctl * mbc, struct media_request * const mreq, struct v4l2_ext_control * const control_array, unsigned int n) +{ + struct v4l2_ext_controls controls = { + .controls = control_array, @@ -11274,7 +11663,7 @@ raspiberry pi support. + return rv; +} + -+int mediabufs_ctl_query_ext_ctrls(struct mediabufs_ctl * mbc, struct v4l2_query_ext_ctrl ctrls[], unsigned int n) ++int mediabufs_ctl_query_ext_ctrls(struct mediabufs_ctl * mbc, struct v4l2_query_ext_ctrl * ctrls, unsigned int n) +{ + int rv = 0; + while (n--) { @@ -11295,13 +11684,9 @@ raspiberry pi support. + +int mediabufs_src_resizable(const struct mediabufs_ctl *const mbc) +{ -+#if 1 -+ return 0; -+#else + // Single planar OUTPUT can only take exact size buffers + // Multiplanar will take larger than negotiated + return V4L2_TYPE_IS_MULTIPLANAR(mbc->src_fmt.type); -+#endif +} + +static void mediabufs_ctl_delete(struct mediabufs_ctl *const mbc) @@ -11463,7 +11848,7 @@ raspiberry pi support. + --- /dev/null +++ b/libavcodec/v4l2_req_media.h -@@ -0,0 +1,171 @@ +@@ -0,0 +1,179 @@ +/* +e.h +* @@ -11488,8 +11873,8 @@ raspiberry pi support. + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + -+#ifndef _MEDIA_H_ -+#define _MEDIA_H_ ++#ifndef AVCODEC_V4L2_REQ_MEDIA_H ++#define AVCODEC_V4L2_REQ_MEDIA_H + +#include +#include @@ -11537,6 +11922,11 @@ raspiberry pi support. +struct dmabuf_h; +struct dmabufs_ctl; + ++struct timeval; ++enum v4l2_buf_type; ++struct v4l2_ext_control; ++struct v4l2_query_ext_ctrl; ++ +// 1-1 mammping to V4L2 type - just defined separetely to avoid some include versioning difficulties +enum mediabufs_memory { + MEDIABUFS_MEMORY_UNSET = 0, @@ -11553,7 +11943,7 @@ raspiberry pi support. +int qent_src_alloc(struct qent_src *const be_src, const size_t len, struct dmabufs_ctl * dbsc); +// dbsc may be NULL if realloc not required +int qent_src_data_copy(struct qent_src *const be_src, const size_t offset, const void *const src, const size_t len, struct dmabufs_ctl * dbsc); -+const struct dmabuf_h * qent_dst_dmabuf(const struct qent_dst *const be, unsigned int plane); ++struct dmabuf_h * qent_dst_dmabuf(const struct qent_dst *const be, unsigned int plane); +int qent_dst_dup_fd(const struct qent_dst *const be, unsigned int plane); +MediaBufsStatus qent_dst_wait(struct qent_dst *const be); +void qent_dst_delete(struct qent_dst *const be); @@ -11588,6 +11978,9 @@ raspiberry pi support. + +MediaBufsStatus mediabufs_stream_on(struct mediabufs_ctl *const mbc); +MediaBufsStatus mediabufs_stream_off(struct mediabufs_ctl *const mbc); ++ ++MediaBufsStatus mediabufs_stream_wait_dst_done(struct mediabufs_ctl *const mbc); ++ +const struct v4l2_format *mediabufs_dst_fmt(struct mediabufs_ctl *const mbc); + +typedef int mediabufs_dst_fmt_accept_fn(void * v, const struct v4l2_fmtdesc *fmtdesc); @@ -11601,12 +11994,12 @@ raspiberry pi support. +void mediabufs_src_qent_abort(struct mediabufs_ctl *const mbc, struct qent_src **const pqe_src); + +int mediabufs_ctl_set_ext_ctrls(struct mediabufs_ctl * mbc, struct media_request * const mreq, -+ struct v4l2_ext_control control_array[], unsigned int n); ++ struct v4l2_ext_control * const control_array, unsigned int n); +MediaBufsStatus mediabufs_set_ext_ctrl(struct mediabufs_ctl *const mbc, + struct media_request * const mreq, + unsigned int id, void *data, + unsigned int size); -+int mediabufs_ctl_query_ext_ctrls(struct mediabufs_ctl * mbc, struct v4l2_query_ext_ctrl ctrls[], unsigned int n); ++int mediabufs_ctl_query_ext_ctrls(struct mediabufs_ctl * mbc, struct v4l2_query_ext_ctrl * ctrls, unsigned int n); + +int mediabufs_src_resizable(const struct mediabufs_ctl *const mbc); + @@ -11637,7 +12030,31 @@ raspiberry pi support. +#endif --- /dev/null +++ b/libavcodec/v4l2_req_pollqueue.c -@@ -0,0 +1,361 @@ +@@ -0,0 +1,385 @@ ++/* ++ Copyright (C) 2024 John Cox john.cox@raspberrypi.com ++ ++ 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. ++ */ ++ +#include +#include +#include @@ -12001,9 +12418,33 @@ raspiberry pi support. + --- /dev/null +++ b/libavcodec/v4l2_req_pollqueue.h -@@ -0,0 +1,18 @@ -+#ifndef POLLQUEUE_H_ -+#define POLLQUEUE_H_ +@@ -0,0 +1,42 @@ ++/* ++ Copyright (C) 2024 John Cox john.cox@raspberrypi.com ++ ++ 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. ++ */ ++ ++#ifndef AVCODEC_V4L2_REQ_POLLQUEUE_H ++#define AVCODEC_V4L2_REQ_POLLQUEUE_H + +struct polltask; +struct pollqueue; @@ -12019,10 +12460,34 @@ raspiberry pi support. +void pollqueue_unref(struct pollqueue **const ppq); +struct pollqueue * pollqueue_ref(struct pollqueue *const pq); + -+#endif /* POLLQUEUE_H_ */ ++#endif /* AVCODEC_V4L2_REQ_POLLQUEUE_H_ */ --- /dev/null +++ b/libavcodec/v4l2_req_utils.h -@@ -0,0 +1,27 @@ +@@ -0,0 +1,51 @@ ++/* ++ Copyright (C) 2024 John Cox john.cox@raspberrypi.com ++ ++ 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. ++ */ ++ +#ifndef AVCODEC_V4L2_REQ_UTILS_H +#define AVCODEC_V4L2_REQ_UTILS_H + @@ -12052,7 +12517,7 @@ raspiberry pi support. +#endif --- /dev/null +++ b/libavcodec/v4l2_request_hevc.c -@@ -0,0 +1,351 @@ +@@ -0,0 +1,436 @@ +/* + * This file is part of FFmpeg. + * @@ -12074,13 +12539,16 @@ raspiberry pi support. + +#include "config.h" +#include "decode.h" -+#include "hevcdec.h" ++#include "hevc/hevcdec.h" ++#include "hwaccel_internal.h" +#include "hwconfig.h" +#include "internal.h" + ++#include "v4l2_fmt.h" +#include "v4l2_request_hevc.h" + +#include "libavutil/hwcontext_drm.h" ++#include "libavutil/mem.h" +#include "libavutil/pixdesc.h" + +#include "v4l2_req_devscan.h" @@ -12110,52 +12578,58 @@ raspiberry pi support. + return bits_alloc; +} + -+static int v4l2_req_hevc_start_frame(AVCodecContext *avctx, ++int ff_v4l2_request_start_frame(AVCodecContext *avctx, + av_unused const uint8_t *buffer, + av_unused uint32_t size) +{ -+ const V4L2RequestContextHEVC * const ctx = avctx->internal->hwaccel_priv_data; -+ return ctx->fns->start_frame(avctx, buffer, size); ++ V4L2RequestPrivHEVC * const priv = avctx->internal->hwaccel_priv_data; ++ V4L2RequestContextHEVC *const ctx = priv->cctx; ++ return ctx->fns->start_frame(avctx, ctx, buffer, size); +} + -+static int v4l2_req_hevc_decode_slice(AVCodecContext *avctx, const uint8_t *buffer, uint32_t size) ++int ff_v4l2_request_decode_slice(AVCodecContext *avctx, const uint8_t *buffer, uint32_t size) +{ -+ V4L2RequestContextHEVC * const ctx = avctx->internal->hwaccel_priv_data; -+ return ctx->fns->decode_slice(avctx, buffer, size); ++ V4L2RequestPrivHEVC * const priv = avctx->internal->hwaccel_priv_data; ++ V4L2RequestContextHEVC *const ctx = priv->cctx; ++ return ctx->fns->decode_slice(avctx, ctx, buffer, size); +} + -+static int v4l2_req_hevc_end_frame(AVCodecContext *avctx) ++int ff_v4l2_request_end_frame(AVCodecContext *avctx) +{ -+ V4L2RequestContextHEVC *ctx = avctx->internal->hwaccel_priv_data; -+ return ctx->fns->end_frame(avctx); ++ V4L2RequestPrivHEVC * const priv = avctx->internal->hwaccel_priv_data; ++ V4L2RequestContextHEVC *const ctx = priv->cctx; ++ return ctx->fns->end_frame(avctx, ctx); +} + -+static void v4l2_req_hevc_abort_frame(AVCodecContext * const avctx) ++void ff_v4l2_request_abort_frame(AVCodecContext * const avctx) +{ -+ V4L2RequestContextHEVC * const ctx = avctx->internal->hwaccel_priv_data; -+ ctx->fns->abort_frame(avctx); ++ V4L2RequestPrivHEVC * const priv = avctx->internal->hwaccel_priv_data; ++ V4L2RequestContextHEVC *const ctx = priv->cctx; ++ ctx->fns->abort_frame(avctx, ctx); +} + -+static int v4l2_req_hevc_frame_params(AVCodecContext *avctx, AVBufferRef *hw_frames_ctx) ++int ff_v4l2_request_frame_params(AVCodecContext *avctx, AVBufferRef *hw_frames_ctx) +{ -+ V4L2RequestContextHEVC * const ctx = avctx->internal->hwaccel_priv_data; -+ return ctx->fns->frame_params(avctx, hw_frames_ctx); ++ V4L2RequestPrivHEVC * const priv = avctx->internal->hwaccel_priv_data; ++ V4L2RequestContextHEVC *const ctx = priv->cctx; ++ return ctx->fns->frame_params(avctx, ctx, hw_frames_ctx); +} + -+static int v4l2_req_hevc_alloc_frame(AVCodecContext * avctx, AVFrame *frame) ++int ff_v4l2_request_alloc_frame(AVCodecContext * avctx, AVFrame *frame) +{ -+ V4L2RequestContextHEVC * const ctx = avctx->internal->hwaccel_priv_data; -+ return ctx->fns->alloc_frame(avctx, frame); ++ V4L2RequestPrivHEVC * const priv = avctx->internal->hwaccel_priv_data; ++ V4L2RequestContextHEVC *const ctx = priv->cctx; ++ return ctx->fns->alloc_frame(avctx, ctx, frame); +} + + -+static int v4l2_request_hevc_uninit(AVCodecContext *avctx) ++static void ++cctx_free(void * v, uint8_t * data) +{ -+ V4L2RequestContextHEVC * const ctx = avctx->internal->hwaccel_priv_data; ++ V4L2RequestContextHEVC *const ctx = (V4L2RequestContextHEVC *)data; + -+ av_log(avctx, AV_LOG_DEBUG, "<<< %s\n", __func__); -+ -+ decode_q_wait(&ctx->decode_q, NULL); // Wait for all other threads to be out of decode ++ if (ctx->fns && ctx->fns->uninit) ++ ctx->fns->uninit(ctx); + + mediabufs_ctl_unref(&ctx->mbufs); + media_pool_delete(&ctx->mpool); @@ -12165,6 +12639,25 @@ raspiberry pi support. + + decode_q_uninit(&ctx->decode_q); + ++ av_free(ctx); ++} ++ ++int ff_v4l2_request_uninit(AVCodecContext *avctx) ++{ ++ V4L2RequestPrivHEVC * const priv = avctx->internal->hwaccel_priv_data; ++ ++ av_log(avctx, AV_LOG_DEBUG, "<<< %s\n", __func__); ++ ++ if (priv->cctx != NULL) { ++ V4L2RequestContextHEVC *const ctx = priv->cctx; ++ ++ decode_q_wait(&ctx->decode_q, NULL); // Wait for all other threads to be out of decode ++ mediabufs_stream_wait_dst_done(ctx->mbufs); // Now wait for processing to finish ++ ++ priv->cctx = NULL; ++ av_buffer_unref(&priv->cctx_buf); ++ } ++ +// if (avctx->hw_frames_ctx) { +// AVHWFramesContext *hwfc = (AVHWFramesContext*)avctx->hw_frames_ctx->data; +// av_buffer_pool_flush(hwfc->pool); @@ -12174,57 +12667,70 @@ raspiberry pi support. + +static int dst_fmt_accept_cb(void * v, const struct v4l2_fmtdesc *fmtdesc) +{ -+ AVCodecContext *const avctx = v; -+ const HEVCContext *const h = avctx->priv_data; ++ const int bit_depth = *(int *)v; + -+ if (h->ps.sps->bit_depth == 8) { -+ if (fmtdesc->pixelformat == V4L2_PIX_FMT_NV12_COL128 || -+ fmtdesc->pixelformat == V4L2_PIX_FMT_NV12) { -+ return 1; -+ } ++ // SAND is currently confised as to whether it is s/w or hardware ++ // *** Current usage is probably wrong - it shouldn't be a h/w fmt ++ if (fmtdesc->pixelformat == V4L2_PIX_FMT_NV12_COL128 || ++ fmtdesc->pixelformat == V4L2_PIX_FMT_NV12_COL128M) { ++ return bit_depth == 8; + } -+ else if (h->ps.sps->bit_depth == 10) { -+ if (fmtdesc->pixelformat == V4L2_PIX_FMT_NV12_10_COL128) { -+ return 1; -+ } ++ if (fmtdesc->pixelformat == V4L2_PIX_FMT_NV12_10_COL128 || ++ fmtdesc->pixelformat == V4L2_PIX_FMT_NV12_10_COL128M) { ++ return bit_depth == 10; ++ } ++ else { ++ const enum AVPixelFormat fmt = ff_v4l2_format_v4l2_to_avfmt(fmtdesc->pixelformat, AV_CODEC_ID_RAWVIDEO); ++ const AVPixFmtDescriptor * const desc = av_pix_fmt_desc_get(fmt); ++ ++ if (fmt == AV_PIX_FMT_NONE || desc == NULL) ++ return 0; ++ ++ return bit_depth == desc->comp[0].depth; + } -+ return 0; +} + -+static int v4l2_request_hevc_init(AVCodecContext *avctx) ++int ff_v4l2_request_init(AVCodecContext *avctx, ++ const struct v4l2_req_decode_fns * const * const try_fns, ++ const int width, const int height, const int bit_depth, ++ const size_t src_bufsize, ++ const int dst_buffers) +{ -+ const HEVCContext *h = avctx->priv_data; -+ V4L2RequestContextHEVC * const ctx = avctx->internal->hwaccel_priv_data; -+ const HEVCSPS * const sps = h->ps.sps; ++ V4L2RequestPrivHEVC * const priv = avctx->internal->hwaccel_priv_data; ++ V4L2RequestContextHEVC * ctx; + int ret; + const struct decdev * decdev; -+ const uint32_t src_pix_fmt = V2(ff_v4l2_req_hevc, 4).src_pix_fmt_v4l2; // Assuming constant for all APIs but avoiding V4L2 includes ++ const uint32_t src_pix_fmt = try_fns[0]->src_pix_fmt_v4l2; // Assuming constant for all APIs but avoiding V4L2 includes + size_t src_size; + enum mediabufs_memory src_memtype; + enum mediabufs_memory dst_memtype; + -+ av_log(avctx, AV_LOG_DEBUG, "<<< %s\n", __func__); ++ av_log(avctx, AV_LOG_DEBUG, "<<< %s (%dx%d %d bits src_size %zd dst_bufs %d\n", __func__, ++ width, height, bit_depth, src_bufsize, dst_buffers); + -+ // Give up immediately if this is something that we have no code to deal with -+ if (h->ps.sps->chroma_format_idc != 1) { -+ av_log(avctx, AV_LOG_WARNING, "chroma_format_idc(%d) != 1: Not implemented\n", h->ps.sps->chroma_format_idc); -+ return AVERROR_PATCHWELCOME; ++ if ((ctx = av_mallocz(sizeof(*ctx))) == NULL) { ++ av_log(avctx, AV_LOG_ERROR, "Unable to allocate context"); ++ return AVERROR(ENOMEM); + } -+ if (!(h->ps.sps->bit_depth == 10 || h->ps.sps->bit_depth == 8) || -+ h->ps.sps->bit_depth != h->ps.sps->bit_depth_chroma) { -+ av_log(avctx, AV_LOG_WARNING, "Bit depth Y:%d C:%d: Not implemented\n", h->ps.sps->bit_depth, h->ps.sps->bit_depth_chroma); -+ return AVERROR_PATCHWELCOME; ++ if ((priv->cctx_buf = av_buffer_create((uint8_t*)ctx, sizeof(*ctx), cctx_free, NULL, 0)) == NULL) { ++ av_log(avctx, AV_LOG_ERROR, "Unable to allocate context buffer"); ++ av_free(ctx); ++ return AVERROR(ENOMEM); + } ++ priv->cctx = ctx; ++ ++ decode_q_init(&ctx->decode_q); + + if ((ret = devscan_build(avctx, &ctx->devscan)) != 0) { + av_log(avctx, AV_LOG_WARNING, "Failed to find any V4L2 devices\n"); -+ return (AVERROR(-ret)); ++ ret = AVERROR(-ret); ++ goto fail0; + } + ret = AVERROR(ENOMEM); // Assume mem fail by default for these + + if ((decdev = devscan_find(ctx->devscan, src_pix_fmt)) == NULL) + { -+ av_log(avctx, AV_LOG_WARNING, "Failed to find a V4L2 device for H265\n"); ++ av_log(avctx, AV_LOG_WARNING, "Failed to find a device for %s\n", try_fns[0]->name); + ret = AVERROR(ENODEV); + goto fail0; + } @@ -12269,7 +12775,7 @@ raspiberry pi support. + // We will realloc if we need more + // Must use sps->h/w as avctx contains cropped size +retry_src_memtype: -+ src_size = bit_buf_size(sps->width, sps->height, sps->bit_depth - 8); ++ src_size = src_bufsize; + if (src_memtype == MEDIABUFS_MEMORY_DMABUF && mediabufs_src_resizable(ctx->mbufs)) + src_size /= 4; + // Kludge for conformance tests which break Annex A limits @@ -12277,9 +12783,9 @@ raspiberry pi support. + src_size = 0x40000; + + if (mediabufs_src_fmt_set(ctx->mbufs, decdev_src_type(decdev), src_pix_fmt, -+ sps->width, sps->height, src_size)) { ++ width, height, src_size)) { + char tbuf1[5]; -+ av_log(avctx, AV_LOG_ERROR, "Failed to set source format: %s %dx%d\n", strfourcc(tbuf1, src_pix_fmt), sps->width, sps->height); ++ av_log(avctx, AV_LOG_ERROR, "Failed to set source format: %s %dx%d\n", strfourcc(tbuf1, src_pix_fmt), width, height); + goto fail4; + } + @@ -12292,28 +12798,19 @@ raspiberry pi support. + goto fail4; + } + -+ if (V2(ff_v4l2_req_hevc, 4).probe(avctx, ctx) == 0) -+ ctx->fns = &V2(ff_v4l2_req_hevc, 4); -+#if CONFIG_V4L2_REQ_HEVC_VX -+ else if (V2(ff_v4l2_req_hevc, 3).probe(avctx, ctx) == 0) -+ ctx->fns = &V2(ff_v4l2_req_hevc, 3); -+ else if (V2(ff_v4l2_req_hevc, 2).probe(avctx, ctx) == 0) -+ ctx->fns = &V2(ff_v4l2_req_hevc, 2); -+ else if (V2(ff_v4l2_req_hevc, 1).probe(avctx, ctx) == 0) -+ ctx->fns = &V2(ff_v4l2_req_hevc, 1); -+#endif -+ else { -+ av_log(avctx, AV_LOG_ERROR, "No HEVC version probed successfully\n"); ++ for (const struct v4l2_req_decode_fns * const * tf = try_fns; (ctx->fns = *tf) != NULL; ++tf) ++ if (ctx->fns->probe(avctx, ctx) == 0) ++ break; ++ if (ctx->fns == NULL) { ++ av_log(avctx, AV_LOG_ERROR, "No %s version probed successfully\n", try_fns[0]->name); + ret = AVERROR(EINVAL); + goto fail4; + } -+ + av_log(avctx, AV_LOG_DEBUG, "%s probed successfully: driver v %#x\n", + ctx->fns->name, mediabufs_ctl_driver_version(ctx->mbufs)); + -+ if (mediabufs_dst_fmt_set(ctx->mbufs, sps->width, sps->height, dst_fmt_accept_cb, avctx)) { -+ char tbuf1[5]; -+ av_log(avctx, AV_LOG_ERROR, "Failed to set destination format: %s %dx%d\n", strfourcc(tbuf1, src_pix_fmt), sps->width, sps->height); ++ if (mediabufs_dst_fmt_set(ctx->mbufs, width, height, dst_fmt_accept_cb, (void*)&bit_depth)) { ++ av_log(avctx, AV_LOG_ERROR, "Failed to set destination format: %dx%d %dbit\n", width, height, bit_depth); + goto fail4; + } + @@ -12323,10 +12820,10 @@ raspiberry pi support. + } + + { -+ unsigned int dst_slots = sps->temporal_layer[sps->max_sub_layers - 1].max_dec_pic_buffering + ++ unsigned int dst_slots = dst_buffers + + avctx->thread_count + (avctx->extra_hw_frames > 0 ? avctx->extra_hw_frames : 6); + av_log(avctx, AV_LOG_DEBUG, "Slots=%d: Reordering=%d, threads=%d, hw+=%d\n", dst_slots, -+ sps->temporal_layer[sps->max_sub_layers - 1].max_dec_pic_buffering, ++ dst_buffers, + avctx->thread_count, avctx->extra_hw_frames); + + if (mediabufs_dst_chk_memtype(ctx->mbufs, dst_memtype)) { @@ -12360,8 +12857,6 @@ raspiberry pi support. + goto fail5; + } + -+ decode_q_init(&ctx->decode_q); -+ + // Set our s/w format + avctx->sw_pix_fmt = ((AVHWFramesContext *)avctx->hw_frames_ctx->data)->sw_format; + @@ -12376,42 +12871,123 @@ raspiberry pi support. +fail5: + av_buffer_unref(&avctx->hw_frames_ctx); +fail4: -+ mediabufs_ctl_unref(&ctx->mbufs); +fail3: -+ media_pool_delete(&ctx->mpool); +fail2: -+ pollqueue_unref(&ctx->pq); +fail1: -+ dmabufs_ctl_unref(&ctx->dbufs); +fail0: -+ devscan_delete(&ctx->devscan); ++ priv->cctx = NULL; ++ av_buffer_unref(&priv->cctx_buf); + return ret; +} + -+const AVHWAccel ff_hevc_v4l2request_hwaccel = { -+ .name = "hevc_v4l2request", -+ .type = AVMEDIA_TYPE_VIDEO, -+ .id = AV_CODEC_ID_HEVC, -+ .pix_fmt = AV_PIX_FMT_DRM_PRIME, -+ .alloc_frame = v4l2_req_hevc_alloc_frame, -+ .start_frame = v4l2_req_hevc_start_frame, -+ .decode_slice = v4l2_req_hevc_decode_slice, -+ .end_frame = v4l2_req_hevc_end_frame, -+ .abort_frame = v4l2_req_hevc_abort_frame, ++int ++ff_v4l2_request_update_thread_context(AVCodecContext *dst, const AVCodecContext *src) ++{ ++ V4L2RequestPrivHEVC * const spriv = src->internal->hwaccel_priv_data; ++ V4L2RequestPrivHEVC * const dpriv = dst->internal->hwaccel_priv_data; ++ int rv; ++ ++ av_log(dst, AV_LOG_DEBUG, "<<< %s (%s)\n", __func__, dpriv->cctx_buf ? "old" : "new"); ++ ++ if ((rv = av_buffer_replace(&dpriv->cctx_buf, spriv->cctx_buf)) != 0) ++ return rv; ++ ++ dpriv->cctx = spriv->cctx; ++ return 0; ++} ++ ++void ++ff_v4l2_request_free_frame_priv(FFRefStructOpaque hwctx, void *data) ++{ ++} ++ ++static int v4l2_request_hevc_init(AVCodecContext *avctx) ++{ ++ const HEVCContext *h = avctx->priv_data; ++ const HEVCPPS * const pps = h->pps; ++ const HEVCSPS * const sps = pps->sps; ++ ++ const struct v4l2_req_decode_fns * const try_fns[] = { ++ &V2(ff_v4l2_req_hevc, 4), ++#if CONFIG_V4L2_REQ_HEVC_VX ++ &V2(ff_v4l2_req_hevc, 3), ++ &V2(ff_v4l2_req_hevc, 2), ++ &V2(ff_v4l2_req_hevc, 1), ++#endif ++ NULL ++ }; ++ ++ // Give up immediately if this is something that we have no code to deal with ++ if (sps->chroma_format_idc != 1) { ++ av_log(avctx, AV_LOG_WARNING, "chroma_format_idc(%d) != 1: Not implemented\n", sps->chroma_format_idc); ++ return AVERROR_PATCHWELCOME; ++ } ++ if (!(sps->bit_depth == 10 || sps->bit_depth == 8) || ++ sps->bit_depth != sps->bit_depth_chroma) { ++ av_log(avctx, AV_LOG_WARNING, "Bit depth Y:%d C:%d: Not implemented\n", sps->bit_depth, sps->bit_depth_chroma); ++ return AVERROR_PATCHWELCOME; ++ } ++ ++ return ff_v4l2_request_init(avctx, try_fns, sps->width, sps->height, sps->bit_depth, ++ bit_buf_size(sps->width, sps->height, sps->bit_depth - 8), ++ sps->temporal_layer[sps->max_sub_layers - 1].max_dec_pic_buffering); ++} ++ ++const FFHWAccel ff_hevc_v4l2request_hwaccel = { ++ .p = { ++ .name = "hevc_v4l2request", ++ .type = AVMEDIA_TYPE_VIDEO, ++ .id = AV_CODEC_ID_HEVC, ++ .pix_fmt = AV_PIX_FMT_DRM_PRIME, ++ }, ++ .alloc_frame = ff_v4l2_request_alloc_frame, ++ .start_frame = ff_v4l2_request_start_frame, ++ .decode_slice = ff_v4l2_request_decode_slice, ++ .end_frame = ff_v4l2_request_end_frame, ++ .abort_frame = ff_v4l2_request_abort_frame, + .init = v4l2_request_hevc_init, -+ .uninit = v4l2_request_hevc_uninit, -+ .priv_data_size = sizeof(V4L2RequestContextHEVC), -+ .frame_params = v4l2_req_hevc_frame_params, -+ .caps_internal = HWACCEL_CAP_ASYNC_SAFE | HWACCEL_CAP_MT_SAFE, ++ .uninit = ff_v4l2_request_uninit, ++ .free_frame_priv = ff_v4l2_request_free_frame_priv, ++ .frame_priv_data_size = 128, ++ .update_thread_context = ff_v4l2_request_update_thread_context, ++ .priv_data_size = sizeof(V4L2RequestPrivHEVC), ++ .frame_params = ff_v4l2_request_frame_params, ++ .caps_internal = HWACCEL_CAP_ASYNC_SAFE | HWACCEL_CAP_THREAD_SAFE, +}; --- /dev/null +++ b/libavcodec/v4l2_request_hevc.h -@@ -0,0 +1,102 @@ +@@ -0,0 +1,163 @@ ++/* ++ Copyright (C) 2024 John Cox john.cox@raspberrypi.com ++ ++ 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. ++ */ ++ +#ifndef AVCODEC_V4L2_REQUEST_HEVC_H +#define AVCODEC_V4L2_REQUEST_HEVC_H + +#include +#include ++ ++#include "refstruct.h" +#include "v4l2_req_decode_q.h" + +#ifndef DRM_FORMAT_NV15 @@ -12436,6 +13012,13 @@ raspiberry pi support. +#define DRM_FORMAT_NV20 fourcc_code('N', 'V', '2', '0') +#endif + ++#ifndef V4L2_PIX_FMT_NV12_COL128M ++#define V4L2_PIX_FMT_NV12_COL128M v4l2_fourcc('N', 'c', '1', '2') /* 12 Y/CbCr 4:2:0 128 pixel wide column */ ++#define V4L2_PIX_FMT_NV12_10_COL128M v4l2_fourcc('N', 'c', '3', '0') ++ /* Y/CbCr 4:2:0 10bpc, 3x10 packed as 4 bytes in ++ * a 128 bytes / 96 pixel wide column */ ++#endif ++ +#include +#ifndef V4L2_CID_CODEC_BASE +#define V4L2_CID_CODEC_BASE V4L2_CID_MPEG_BASE @@ -12476,6 +13059,8 @@ raspiberry pi support. + unsigned int max_slices; // 0 => not wanted (frame mode) + unsigned int max_offsets; // 0 => not wanted + ++ int bit_size_is_offset; // Quirk for old RPi decodes (not worth an entire VX) ++ + req_decode_q decode_q; + + struct devscan *devscan; @@ -12483,25 +13068,51 @@ raspiberry pi support. + struct pollqueue *pq; + struct media_pool * mpool; + struct mediabufs_ctl *mbufs; ++ ++ void * decode_ctx; +} V4L2RequestContextHEVC; + ++typedef struct V4L2RequestPrivHEVC { ++ V4L2RequestContextHEVC * cctx; // Common context ++ AVBufferRef * cctx_buf; // Buf for cctx ++ int bit_depth; ++} V4L2RequestPrivHEVC; ++ +typedef struct v4l2_req_decode_fns { + int src_pix_fmt_v4l2; + const char * name; + + // Init setup + int (*probe)(AVCodecContext * const avctx, V4L2RequestContextHEVC * const ctx); ++ // Set controls & any other init (e.g. decode_ctx) + int (*set_controls)(AVCodecContext * const avctx, V4L2RequestContextHEVC * const ctx); + ++ // Called on shutdown - avctx may not exist ++ void (*uninit)(V4L2RequestContextHEVC * const ctx); ++ + // Passthrough of hwaccel fns -+ int (*start_frame)(AVCodecContext *avctx, const uint8_t *buf, uint32_t buf_size); -+ int (*decode_slice)(AVCodecContext *avctx, const uint8_t *buf, uint32_t buf_size); -+ int (*end_frame)(AVCodecContext *avctx); -+ void (*abort_frame)(AVCodecContext *avctx); -+ int (*frame_params)(AVCodecContext *avctx, AVBufferRef *hw_frames_ctx); -+ int (*alloc_frame)(AVCodecContext * avctx, AVFrame *frame); ++ int (*start_frame)(AVCodecContext *avctx, V4L2RequestContextHEVC *const ctx, const uint8_t *buf, uint32_t buf_size); ++ int (*decode_slice)(AVCodecContext *avctx, V4L2RequestContextHEVC *const ctx, const uint8_t *buf, uint32_t buf_size); ++ int (*end_frame)(AVCodecContext *avctx, V4L2RequestContextHEVC *const ctx); ++ void (*abort_frame)(AVCodecContext *avctx, V4L2RequestContextHEVC *const ctx); ++ int (*frame_params)(AVCodecContext *avctx, V4L2RequestContextHEVC *const ctx, AVBufferRef *hw_frames_ctx); ++ int (*alloc_frame)(AVCodecContext * avctx, V4L2RequestContextHEVC *const ctx, AVFrame *frame); +} v4l2_req_decode_fns; + ++int ff_v4l2_request_start_frame(AVCodecContext *avctx, const uint8_t *buffer, uint32_t size); ++int ff_v4l2_request_decode_slice(AVCodecContext *avctx, const uint8_t *buffer, uint32_t size); ++int ff_v4l2_request_end_frame(AVCodecContext *avctx); ++void ff_v4l2_request_abort_frame(AVCodecContext * const avctx); ++int ff_v4l2_request_frame_params(AVCodecContext *avctx, AVBufferRef *hw_frames_ctx); ++int ff_v4l2_request_alloc_frame(AVCodecContext * avctx, AVFrame *frame); ++int ff_v4l2_request_init(AVCodecContext *avctx, ++ const struct v4l2_req_decode_fns * const * const try_fns, ++ const int width, const int height, const int bit_depth, ++ const size_t src_bufsize, ++ const int dst_buffers); ++int ff_v4l2_request_uninit(AVCodecContext *avctx); ++int ff_v4l2_request_update_thread_context(AVCodecContext *dst, const AVCodecContext *src); ++void ff_v4l2_request_free_frame_priv(FFRefStructOpaque hwctx, void *data); + +extern const v4l2_req_decode_fns V2(ff_v4l2_req_hevc, 1); +extern const v4l2_req_decode_fns V2(ff_v4l2_req_hevc, 2); @@ -12511,7 +13122,31 @@ raspiberry pi support. +#endif --- /dev/null +++ b/libavcodec/weak_link.c -@@ -0,0 +1,103 @@ +@@ -0,0 +1,127 @@ ++/* ++ Copyright (C) 2024 John Cox john.cox@raspberrypi.com ++ ++ 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. ++ */ ++ +#include +#include +#include @@ -12617,7 +13252,34 @@ raspiberry pi support. + --- /dev/null +++ b/libavcodec/weak_link.h -@@ -0,0 +1,23 @@ +@@ -0,0 +1,46 @@ ++/* ++ Copyright (C) 2024 John Cox john.cox@raspberrypi.com ++ ++ 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. ++ */ ++ ++#ifndef AVCODEC_WEAK_LINK_H ++#define AVCODEC_WEAK_LINK_H ++ +struct ff_weak_link_master; +struct ff_weak_link_client; + @@ -12636,11 +13298,7 @@ raspiberry pi support. +void * ff_weak_link_lock(struct ff_weak_link_client ** ppLink); +void ff_weak_link_unlock(struct ff_weak_link_client * c); + -+ -+ -+ -+ -+ ++#endif --- a/libavdevice/Makefile +++ b/libavdevice/Makefile @@ -48,6 +48,8 @@ OBJS-$(CONFIG_SNDIO_OUTDEV) @@ -12654,18 +13312,18 @@ raspiberry pi support. --- a/libavdevice/alldevices.c +++ b/libavdevice/alldevices.c -@@ -51,6 +51,8 @@ extern const AVOutputFormat ff_sndio_mux - extern const AVInputFormat ff_v4l2_demuxer; - extern const AVOutputFormat ff_v4l2_muxer; - extern const AVInputFormat ff_vfwcap_demuxer; -+extern const AVOutputFormat ff_vout_drm_muxer; -+extern const AVOutputFormat ff_vout_egl_muxer; - extern const AVInputFormat ff_xcbgrab_demuxer; - extern const AVOutputFormat ff_xv_muxer; +@@ -56,6 +56,8 @@ extern const FFOutputFormat ff_sndio_mux + extern const FFInputFormat ff_v4l2_demuxer; + extern const FFOutputFormat ff_v4l2_muxer; + extern const FFInputFormat ff_vfwcap_demuxer; ++extern const FFOutputFormat ff_vout_drm_muxer; ++extern const FFOutputFormat ff_vout_egl_muxer; + extern const FFInputFormat ff_xcbgrab_demuxer; + extern const FFOutputFormat ff_xv_muxer; --- /dev/null +++ b/libavdevice/drm_vout.c -@@ -0,0 +1,680 @@ +@@ -0,0 +1,684 @@ +/* + * Copyright (c) 2020 John Cox for Raspberry Pi Trading + * @@ -12691,9 +13349,11 @@ raspiberry pi support. +// limited to testing. + +#include "libavutil/opt.h" ++#include "libavutil/frame.h" +#include "libavutil/pixdesc.h" ++#include "libavutil/hwcontext.h" +#include "libavutil/hwcontext_drm.h" -+#include "libavformat/internal.h" ++#include "libavformat/mux.h" +#include "avdevice.h" + +#include "pthread.h" @@ -13329,26 +13989,28 @@ raspiberry pi support. + .category = AV_CLASS_CATEGORY_DEVICE_VIDEO_OUTPUT, +}; + -+AVOutputFormat ff_vout_drm_muxer = { -+ .name = "vout_drm", -+ .long_name = NULL_IF_CONFIG_SMALL("Drm video output device"), ++FFOutputFormat ff_vout_drm_muxer = { ++ .p = { ++ .name = "vout_drm", ++ .long_name = NULL_IF_CONFIG_SMALL("Drm video output device"), ++ .audio_codec = AV_CODEC_ID_NONE, ++ .video_codec = AV_CODEC_ID_WRAPPED_AVFRAME, ++ .flags = AVFMT_NOFILE | AVFMT_VARIABLE_FPS | AVFMT_NOTIMESTAMPS, ++ .priv_class = &drm_vout_class, ++ }, + .priv_data_size = sizeof(drm_display_env_t), -+ .audio_codec = AV_CODEC_ID_NONE, -+ .video_codec = AV_CODEC_ID_WRAPPED_AVFRAME, + .write_header = drm_vout_write_header, + .write_packet = drm_vout_write_packet, + .write_uncoded_frame = drm_vout_write_frame, + .write_trailer = drm_vout_write_trailer, + .control_message = drm_vout_control_message, -+ .flags = AVFMT_NOFILE | AVFMT_VARIABLE_FPS | AVFMT_NOTIMESTAMPS, -+ .priv_class = &drm_vout_class, + .init = drm_vout_init, + .deinit = drm_vout_deinit, +}; + --- /dev/null +++ b/libavdevice/egl_vout.c -@@ -0,0 +1,781 @@ +@@ -0,0 +1,784 @@ +/* + * Copyright (c) 2020 John Cox for Raspberry Pi Trading + * @@ -13382,8 +14044,9 @@ raspiberry pi support. +#include "libavutil/avassert.h" +#include "libavutil/pixdesc.h" +#include "libavutil/imgutils.h" ++#include "libavutil/hwcontext.h" +#include "libavutil/hwcontext_drm.h" -+#include "libavformat/internal.h" ++#include "libavformat/mux.h" +#include "avdevice.h" + +#include "pthread.h" @@ -14113,34 +14776,36 @@ raspiberry pi support. + .category = AV_CLASS_CATEGORY_DEVICE_VIDEO_OUTPUT, +}; + -+AVOutputFormat ff_vout_egl_muxer = { -+ .name = "vout_egl", -+ .long_name = NULL_IF_CONFIG_SMALL("Egl video output device"), ++FFOutputFormat ff_vout_egl_muxer = { ++ .p = { ++ .name = "vout_egl", ++ .long_name = NULL_IF_CONFIG_SMALL("Egl video output device"), ++ .audio_codec = AV_CODEC_ID_NONE, ++ .video_codec = AV_CODEC_ID_WRAPPED_AVFRAME, ++ .flags = AVFMT_NOFILE | AVFMT_VARIABLE_FPS | AVFMT_NOTIMESTAMPS, ++ .priv_class = &egl_vout_class, ++ }, + .priv_data_size = sizeof(egl_display_env_t), -+ .audio_codec = AV_CODEC_ID_NONE, -+ .video_codec = AV_CODEC_ID_WRAPPED_AVFRAME, + .write_header = egl_vout_write_header, + .write_packet = egl_vout_write_packet, + .write_uncoded_frame = egl_vout_write_frame, + .write_trailer = egl_vout_write_trailer, + .control_message = egl_vout_control_message, -+ .flags = AVFMT_NOFILE | AVFMT_VARIABLE_FPS | AVFMT_NOTIMESTAMPS, -+ .priv_class = &egl_vout_class, + .init = egl_vout_init, + .deinit = egl_vout_deinit, +}; + --- a/libavfilter/Makefile +++ b/libavfilter/Makefile -@@ -254,6 +254,7 @@ OBJS-$(CONFIG_DEFLATE_FILTER) +@@ -272,6 +272,7 @@ OBJS-$(CONFIG_DEFLATE_FILTER) OBJS-$(CONFIG_DEFLICKER_FILTER) += vf_deflicker.o - OBJS-$(CONFIG_DEINTERLACE_QSV_FILTER) += vf_deinterlace_qsv.o + OBJS-$(CONFIG_DEINTERLACE_QSV_FILTER) += vf_vpp_qsv.o OBJS-$(CONFIG_DEINTERLACE_VAAPI_FILTER) += vf_deinterlace_vaapi.o vaapi_vpp.o +OBJS-$(CONFIG_DEINTERLACE_V4L2M2M_FILTER) += vf_deinterlace_v4l2m2m.o OBJS-$(CONFIG_DEJUDDER_FILTER) += vf_dejudder.o OBJS-$(CONFIG_DELOGO_FILTER) += vf_delogo.o OBJS-$(CONFIG_DENOISE_VAAPI_FILTER) += vf_misc_vaapi.o vaapi_vpp.o -@@ -509,6 +510,7 @@ OBJS-$(CONFIG_TRANSPOSE_VAAPI_FILTER) +@@ -536,6 +537,7 @@ OBJS-$(CONFIG_TRANSPOSE_VT_FILTER) OBJS-$(CONFIG_TRANSPOSE_VULKAN_FILTER) += vf_transpose_vulkan.o vulkan.o vulkan_filter.o OBJS-$(CONFIG_TRIM_FILTER) += trim.o OBJS-$(CONFIG_UNPREMULTIPLY_FILTER) += vf_premultiply.o framesync.o @@ -14148,936 +14813,9 @@ raspiberry pi support. OBJS-$(CONFIG_UNSHARP_FILTER) += vf_unsharp.o OBJS-$(CONFIG_UNSHARP_OPENCL_FILTER) += vf_unsharp_opencl.o opencl.o \ opencl/unsharp.o ---- a/libavfilter/aarch64/Makefile -+++ b/libavfilter/aarch64/Makefile -@@ -1,3 +1,5 @@ -+OBJS-$(CONFIG_BWDIF_FILTER) += aarch64/vf_bwdif_init_aarch64.o - OBJS-$(CONFIG_NLMEANS_FILTER) += aarch64/vf_nlmeans_init.o - -+NEON-OBJS-$(CONFIG_BWDIF_FILTER) += aarch64/vf_bwdif_neon.o - NEON-OBJS-$(CONFIG_NLMEANS_FILTER) += aarch64/vf_nlmeans_neon.o ---- /dev/null -+++ b/libavfilter/aarch64/vf_bwdif_init_aarch64.c -@@ -0,0 +1,125 @@ -+/* -+ * bwdif aarch64 NEON optimisations -+ * -+ * Copyright (c) 2023 John Cox -+ * -+ * This file is part of FFmpeg. -+ * -+ * FFmpeg is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2.1 of the License, or (at your option) any later version. -+ * -+ * FFmpeg is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with FFmpeg; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -+ */ -+ -+#include "libavutil/common.h" -+#include "libavfilter/bwdif.h" -+#include "libavutil/aarch64/cpu.h" -+ -+void ff_bwdif_filter_edge_neon(void *dst1, void *prev1, void *cur1, void *next1, -+ int w, int prefs, int mrefs, int prefs2, int mrefs2, -+ int parity, int clip_max, int spat); -+ -+void ff_bwdif_filter_intra_neon(void *dst1, void *cur1, int w, int prefs, int mrefs, -+ int prefs3, int mrefs3, int parity, int clip_max); -+ -+void ff_bwdif_filter_line_neon(void *dst1, void *prev1, void *cur1, void *next1, -+ int w, int prefs, int mrefs, int prefs2, int mrefs2, -+ int prefs3, int mrefs3, int prefs4, int mrefs4, -+ int parity, int clip_max); -+ -+void ff_bwdif_filter_line3_neon(void * dst1, int d_stride, -+ const void * prev1, const void * cur1, const void * next1, int s_stride, -+ int w, int parity, int clip_max); -+ -+ -+static void filter_line3_helper(void * dst1, int d_stride, -+ const void * prev1, const void * cur1, const void * next1, int s_stride, -+ int w, int parity, int clip_max) -+{ -+ // Asm works on 16 byte chunks -+ // If w is a multiple of 16 then all is good - if not then if width rounded -+ // up to nearest 16 will fit in both src & dst strides then allow the asm -+ // to write over the padding bytes as that is almost certainly faster than -+ // having to invoke the C version to clean up the tail. -+ const int w1 = FFALIGN(w, 16); -+ const int w0 = clip_max != 255 ? 0 : -+ d_stride <= w1 && s_stride <= w1 ? w : w & ~15; -+ -+ ff_bwdif_filter_line3_neon(dst1, d_stride, -+ prev1, cur1, next1, s_stride, -+ w0, parity, clip_max); -+ -+ if (w0 < w) -+ ff_bwdif_filter_line3_c((char *)dst1 + w0, d_stride, -+ (const char *)prev1 + w0, (const char *)cur1 + w0, (const char *)next1 + w0, s_stride, -+ w - w0, parity, clip_max); -+} -+ -+static void filter_line_helper(void *dst1, void *prev1, void *cur1, void *next1, -+ int w, int prefs, int mrefs, int prefs2, int mrefs2, -+ int prefs3, int mrefs3, int prefs4, int mrefs4, -+ int parity, int clip_max) -+{ -+ const int w0 = clip_max != 255 ? 0 : w & ~15; -+ -+ ff_bwdif_filter_line_neon(dst1, prev1, cur1, next1, -+ w0, prefs, mrefs, prefs2, mrefs2, prefs3, mrefs3, prefs4, mrefs4, parity, clip_max); -+ -+ if (w0 < w) -+ ff_bwdif_filter_line_c((char *)dst1 + w0, (char *)prev1 + w0, (char *)cur1 + w0, (char *)next1 + w0, -+ w - w0, prefs, mrefs, prefs2, mrefs2, prefs3, mrefs3, prefs4, mrefs4, parity, clip_max); -+} -+ -+static void filter_edge_helper(void *dst1, void *prev1, void *cur1, void *next1, -+ int w, int prefs, int mrefs, int prefs2, int mrefs2, -+ int parity, int clip_max, int spat) -+{ -+ const int w0 = clip_max != 255 ? 0 : w & ~15; -+ -+ ff_bwdif_filter_edge_neon(dst1, prev1, cur1, next1, w0, prefs, mrefs, prefs2, mrefs2, -+ parity, clip_max, spat); -+ -+ if (w0 < w) -+ ff_bwdif_filter_edge_c((char *)dst1 + w0, (char *)prev1 + w0, (char *)cur1 + w0, (char *)next1 + w0, -+ w - w0, prefs, mrefs, prefs2, mrefs2, -+ parity, clip_max, spat); -+} -+ -+static void filter_intra_helper(void *dst1, void *cur1, int w, int prefs, int mrefs, -+ int prefs3, int mrefs3, int parity, int clip_max) -+{ -+ const int w0 = clip_max != 255 ? 0 : w & ~15; -+ -+ ff_bwdif_filter_intra_neon(dst1, cur1, w0, prefs, mrefs, prefs3, mrefs3, parity, clip_max); -+ -+ if (w0 < w) -+ ff_bwdif_filter_intra_c((char *)dst1 + w0, (char *)cur1 + w0, -+ w - w0, prefs, mrefs, prefs3, mrefs3, parity, clip_max); -+} -+ -+void -+ff_bwdif_init_aarch64(BWDIFContext *s, int bit_depth) -+{ -+ const int cpu_flags = av_get_cpu_flags(); -+ -+ if (bit_depth != 8) -+ return; -+ -+ if (!have_neon(cpu_flags)) -+ return; -+ -+ s->filter_intra = filter_intra_helper; -+ s->filter_line = filter_line_helper; -+ s->filter_edge = filter_edge_helper; -+ s->filter_line3 = filter_line3_helper; -+} -+ ---- /dev/null -+++ b/libavfilter/aarch64/vf_bwdif_neon.S -@@ -0,0 +1,788 @@ -+/* -+ * bwdif aarch64 NEON optimisations -+ * -+ * Copyright (c) 2023 John Cox -+ * -+ * This file is part of FFmpeg. -+ * -+ * FFmpeg is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2.1 of the License, or (at your option) any later version. -+ * -+ * FFmpeg is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with FFmpeg; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -+ */ -+ -+ -+#include "libavutil/aarch64/asm.S" -+ -+// Space taken on the stack by an int (32-bit) -+#ifdef __APPLE__ -+.set SP_INT, 4 -+#else -+.set SP_INT, 8 -+#endif -+ -+.macro SQSHRUNN b, s0, s1, s2, s3, n -+ sqshrun \s0\().4h, \s0\().4s, #\n - 8 -+ sqshrun2 \s0\().8h, \s1\().4s, #\n - 8 -+ sqshrun \s1\().4h, \s2\().4s, #\n - 8 -+ sqshrun2 \s1\().8h, \s3\().4s, #\n - 8 -+ uzp2 \b\().16b, \s0\().16b, \s1\().16b -+.endm -+ -+.macro SMULL4K a0, a1, a2, a3, s0, s1, k -+ smull \a0\().4s, \s0\().4h, \k -+ smull2 \a1\().4s, \s0\().8h, \k -+ smull \a2\().4s, \s1\().4h, \k -+ smull2 \a3\().4s, \s1\().8h, \k -+.endm -+ -+.macro UMULL4K a0, a1, a2, a3, s0, s1, k -+ umull \a0\().4s, \s0\().4h, \k -+ umull2 \a1\().4s, \s0\().8h, \k -+ umull \a2\().4s, \s1\().4h, \k -+ umull2 \a3\().4s, \s1\().8h, \k -+.endm -+ -+.macro UMLAL4K a0, a1, a2, a3, s0, s1, k -+ umlal \a0\().4s, \s0\().4h, \k -+ umlal2 \a1\().4s, \s0\().8h, \k -+ umlal \a2\().4s, \s1\().4h, \k -+ umlal2 \a3\().4s, \s1\().8h, \k -+.endm -+ -+.macro UMLSL4K a0, a1, a2, a3, s0, s1, k -+ umlsl \a0\().4s, \s0\().4h, \k -+ umlsl2 \a1\().4s, \s0\().8h, \k -+ umlsl \a2\().4s, \s1\().4h, \k -+ umlsl2 \a3\().4s, \s1\().8h, \k -+.endm -+ -+// int b = m2s1 - m1; -+// int f = p2s1 - p1; -+// int dc = c0s1 - m1; -+// int de = c0s1 - p1; -+// int sp_max = FFMIN(p1 - c0s1, m1 - c0s1); -+// sp_max = FFMIN(sp_max, FFMAX(-b,-f)); -+// int sp_min = FFMIN(c0s1 - p1, c0s1 - m1); -+// sp_min = FFMIN(sp_min, FFMAX(b,f)); -+// diff = diff == 0 ? 0 : FFMAX3(diff, sp_min, sp_max); -+.macro SPAT_CHECK diff, m2s1, m1, c0s1, p1, p2s1, t0, t1, t2, t3 -+ uqsub \t0\().16b, \p1\().16b, \c0s1\().16b -+ uqsub \t2\().16b, \m1\().16b, \c0s1\().16b -+ umin \t2\().16b, \t0\().16b, \t2\().16b -+ -+ uqsub \t1\().16b, \m1\().16b, \m2s1\().16b -+ uqsub \t3\().16b, \p1\().16b, \p2s1\().16b -+ umax \t3\().16b, \t3\().16b, \t1\().16b -+ umin \t3\().16b, \t3\().16b, \t2\().16b -+ -+ uqsub \t0\().16b, \c0s1\().16b, \p1\().16b -+ uqsub \t2\().16b, \c0s1\().16b, \m1\().16b -+ umin \t2\().16b, \t0\().16b, \t2\().16b -+ -+ uqsub \t1\().16b, \m2s1\().16b, \m1\().16b -+ uqsub \t0\().16b, \p2s1\().16b, \p1\().16b -+ umax \t0\().16b, \t0\().16b, \t1\().16b -+ umin \t2\().16b, \t2\().16b, \t0\().16b -+ -+ cmeq \t1\().16b, \diff\().16b, #0 -+ umax \diff\().16b, \diff\().16b, \t3\().16b -+ umax \diff\().16b, \diff\().16b, \t2\().16b -+ bic \diff\().16b, \diff\().16b, \t1\().16b -+.endm -+ -+// i0 = s0; -+// if (i0 > d0 + diff0) -+// i0 = d0 + diff0; -+// else if (i0 < d0 - diff0) -+// i0 = d0 - diff0; -+// -+// i0 = s0 is safe -+.macro DIFF_CLIP i0, s0, d0, diff, t0, t1 -+ uqadd \t0\().16b, \d0\().16b, \diff\().16b -+ uqsub \t1\().16b, \d0\().16b, \diff\().16b -+ umin \i0\().16b, \s0\().16b, \t0\().16b -+ umax \i0\().16b, \i0\().16b, \t1\().16b -+.endm -+ -+// i0 = FFABS(m1 - p1) > td0 ? i1 : i2; -+// DIFF_CLIP -+// -+// i0 = i1 is safe -+.macro INTERPOL i0, i1, i2, m1, d0, p1, td0, diff, t0, t1, t2 -+ uabd \t0\().16b, \m1\().16b, \p1\().16b -+ cmhi \t0\().16b, \t0\().16b, \td0\().16b -+ bsl \t0\().16b, \i1\().16b, \i2\().16b -+ DIFF_CLIP \i0, \t0, \d0, \diff, \t1, \t2 -+.endm -+ -+.macro PUSH_VREGS -+ stp d8, d9, [sp, #-64]! -+ stp d10, d11, [sp, #16] -+ stp d12, d13, [sp, #32] -+ stp d14, d15, [sp, #48] -+.endm -+ -+.macro POP_VREGS -+ ldp d14, d15, [sp, #48] -+ ldp d12, d13, [sp, #32] -+ ldp d10, d11, [sp, #16] -+ ldp d8, d9, [sp], #64 -+.endm -+ -+.macro LDR_COEFFS d, t0 -+ movrel \t0, coeffs, 0 -+ ld1 {\d\().8h}, [\t0] -+.endm -+ -+// static const uint16_t coef_lf[2] = { 4309, 213 }; -+// static const uint16_t coef_hf[3] = { 5570, 3801, 1016 }; -+// static const uint16_t coef_sp[2] = { 5077, 981 }; -+ -+const coeffs, align=4 // align 4 means align on 2^4 boundry -+ .hword 4309 * 4, 213 * 4 // lf[0]*4 = v0.h[0] -+ .hword 5570, 3801, 1016, -3801 // hf[0] = v0.h[2], -hf[1] = v0.h[5] -+ .hword 5077, 981 // sp[0] = v0.h[6] -+endconst -+ -+// =========================================================================== -+// -+// void ff_bwdif_filter_line3_neon( -+// void * dst1, // x0 -+// int d_stride, // w1 -+// const void * prev1, // x2 -+// const void * cur1, // x3 -+// const void * next1, // x4 -+// int s_stride, // w5 -+// int w, // w6 -+// int parity, // w7 -+// int clip_max); // [sp, #0] (Ignored) -+ -+function ff_bwdif_filter_line3_neon, export=1 -+ // Sanity check w -+ cmp w6, #0 -+ ble 99f -+ -+ LDR_COEFFS v0, x17 -+ -+// #define prev2 cur -+// const uint8_t * restrict next2 = parity ? prev : next; -+ cmp w7, #0 -+ csel x17, x2, x4, ne -+ -+ // We want all the V registers - save all the ones we must -+ PUSH_VREGS -+ -+ // Some rearrangement of initial values for nice layout of refs in regs -+ mov w10, w6 // w10 = loop count -+ neg w9, w5 // w9 = mref -+ lsl w8, w9, #1 // w8 = mref2 -+ add w7, w9, w9, LSL #1 // w7 = mref3 -+ lsl w6, w9, #2 // w6 = mref4 -+ mov w11, w5 // w11 = pref -+ lsl w12, w5, #1 // w12 = pref2 -+ add w13, w5, w5, LSL #1 // w13 = pref3 -+ lsl w14, w5, #2 // w14 = pref4 -+ add w15, w5, w5, LSL #2 // w15 = pref5 -+ add w16, w14, w12 // w16 = pref6 -+ -+ lsl w5, w1, #1 // w5 = d_stride * 2 -+ -+// for (x = 0; x < w; x++) { -+// int diff0, diff2; -+// int d0, d2; -+// int temporal_diff0, temporal_diff2; -+// -+// int i1, i2; -+// int j1, j2; -+// int p6, p5, p4, p3, p2, p1, c0, m1, m2, m3, m4; -+ -+10: -+// c0 = prev2[0] + next2[0]; // c0 = v20, v21 -+// d0 = c0 >> 1; // d0 = v10 -+// temporal_diff0 = FFABS(prev2[0] - next2[0]); // td0 = v11 -+ ldr q31, [x3] -+ ldr q21, [x17] -+ uhadd v10.16b, v31.16b, v21.16b -+ uabd v11.16b, v31.16b, v21.16b -+ uaddl v20.8h, v21.8b, v31.8b -+ uaddl2 v21.8h, v21.16b, v31.16b -+ -+ ldr q31, [x3, w6, sxtw] -+ ldr q23, [x17, w6, sxtw] -+ -+// i1 = coef_hf[0] * c0; // i1 = v2-v5 -+ UMULL4K v2, v3, v4, v5, v20, v21, v0.h[2] -+ -+ ldr q30, [x3, w14, sxtw] -+ ldr q25, [x17, w14, sxtw] -+ -+// m4 = prev2[mrefs4] + next2[mrefs4]; // m4 = v22,v23 -+ uaddl v22.8h, v23.8b, v31.8b -+ uaddl2 v23.8h, v23.16b, v31.16b -+ -+// p4 = prev2[prefs4] + next2[prefs4]; // p4 = v24,v25, (p4 >> 1) = v12 -+ uhadd v12.16b, v25.16b, v30.16b -+ uaddl v24.8h, v25.8b, v30.8b -+ uaddl2 v25.8h, v25.16b, v30.16b -+ -+// j1 = -coef_hf[1] * (c0 + p4); // j1 = v6-v9 (-c0:v20,v21) -+ add v20.8h, v20.8h, v24.8h -+ add v21.8h, v21.8h, v25.8h -+ SMULL4K v6, v7, v8, v9, v20, v21, v0.h[5] -+ -+// m3 = cur[mrefs3]; // m3 = v20 -+ ldr q20, [x3, w7, sxtw] -+ -+// p3 = cur[prefs3]; // p3 = v21 -+ ldr q21, [x3, w13, sxtw] -+ -+// i1 += coef_hf[2] * (m4 + p4); // (-m4:v22,v23) (-p4:v24,v25) -+ add v22.8h, v22.8h, v24.8h -+ add v23.8h, v23.8h, v25.8h -+ UMLAL4K v2, v3, v4, v5, v22, v23, v0.h[4] -+ -+ ldr q29, [x3, w8, sxtw] -+ ldr q23, [x17, w8, sxtw] -+ -+// i1 -= coef_lf[1] * 4 * (m3 + p3); // - -+ uaddl v30.8h, v20.8b, v21.8b -+ uaddl2 v31.8h, v20.16b, v21.16b -+ -+ ldr q28, [x3, w16, sxtw] -+ ldr q25, [x17, w16, sxtw] -+ -+ UMLSL4K v2, v3, v4, v5, v30, v31, v0.h[1] -+ -+// m2 = prev2[mrefs2] + next2[mrefs2]; // m2 = v22,v23, (m2 >> 1) = v13 -+ uhadd v13.16b, v23.16b, v29.16b -+ uaddl v22.8h, v23.8b, v29.8b -+ uaddl2 v23.8h, v23.16b, v29.16b -+ -+ ldr q31, [x3, w12, sxtw] -+ ldr q27, [x17, w12, sxtw] -+ -+// p6 = prev2[prefs6] + next2[prefs6]; // p6 = v24,v25 -+ uaddl v24.8h, v25.8b, v28.8b -+ uaddl2 v25.8h, v25.16b, v28.16b -+ -+// j1 += coef_hf[2] * (m2 + p6); // (-p6:v24,v25) -+ add v24.8h, v24.8h, v22.8h -+ add v25.8h, v25.8h, v23.8h -+ UMLAL4K v6, v7, v8, v9, v24, v25, v0.h[4] -+ -+// m1 = cur[mrefs]; // m1 = v24 -+ ldr q24, [x3, w9, sxtw] -+ -+// p5 = cur[prefs5]; // p5 = v25 -+ ldr q25, [x3, w15, sxtw] -+ -+// p2 = prev2[prefs2] + next2[prefs2]; // p2 = v26, v27 -+// temporal_diff2 = FFABS(prev2[prefs2] - next2[prefs2]); // td2 = v14 -+// d2 = p2 >> 1; // d2 = v15 -+ uabd v14.16b, v31.16b, v27.16b -+ uhadd v15.16b, v31.16b, v27.16b -+ uaddl v26.8h, v27.8b, v31.8b -+ uaddl2 v27.8h, v27.16b, v31.16b -+ -+// j1 += coef_hf[0] * p2; // - -+ UMLAL4K v6, v7, v8, v9, v26, v27, v0.h[2] -+ -+// i1 -= coef_hf[1] * (m2 + p2); // (-m2:v22,v23*) (-p2:v26*,v27*) -+ add v22.8h, v22.8h, v26.8h -+ add v23.8h, v23.8h, v27.8h -+ UMLSL4K v2, v3, v4, v5, v22, v23, v0.h[3] -+ -+// p1 = cur[prefs]; // p1 = v22 -+ ldr q22, [x3, w11, sxtw] -+ -+// j1 -= coef_lf[1] * 4 * (m1 + p5); // - -+ uaddl v26.8h, v24.8b, v25.8b -+ uaddl2 v27.8h, v24.16b, v25.16b -+ UMLSL4K v6, v7, v8, v9, v26, v27, v0.h[1] -+ -+// j2 = (coef_sp[0] * (p1 + p3) - coef_sp[1] * (m1 + p5)) >> 13; // (-p5:v25*) j2=v16 -+ uaddl v18.8h, v22.8b, v21.8b -+ uaddl2 v19.8h, v22.16b, v21.16b -+ UMULL4K v28, v29, v30, v31, v18, v19, v0.h[6] -+ -+ uaddl v18.8h, v24.8b, v25.8b -+ uaddl2 v19.8h, v24.16b, v25.16b -+ UMLSL4K v28, v29, v30, v31, v18, v19, v0.h[7] -+ -+ SQSHRUNN v16, v28, v29, v30, v31, 13 -+ -+// i2 = (coef_sp[0] * (m1 + p1) - coef_sp[1] * (m3 + p3)) >> 13; // (-m3:v20*) i2=v17 -+ uaddl v18.8h, v22.8b, v24.8b -+ uaddl2 v19.8h, v22.16b, v24.16b -+ UMULL4K v28, v29, v30, v31, v18, v19, v0.h[6] -+ -+ uaddl v18.8h, v20.8b, v21.8b -+ uaddl2 v19.8h, v20.16b, v21.16b -+ UMLSL4K v28, v29, v30, v31, v18, v19, v0.h[7] -+ -+ SQSHRUNN v17, v28, v29, v30, v31, 13 -+ -+// i1 += coef_lf[0] * 4 * (m1 + p1); // p1 = v22, m1 = v24 -+ uaddl v26.8h, v24.8b, v22.8b -+ uaddl2 v27.8h, v24.16b, v22.16b -+ UMLAL4K v2, v3, v4, v5, v26, v27, v0.h[0] -+ -+ ldr q31, [x2, w9, sxtw] -+ ldr q29, [x4, w9, sxtw] -+ -+// j1 += coef_lf[0] * 4 * (p1 + p3); // p1 = v22, p3 = v21 -+ uaddl v26.8h, v21.8b, v22.8b -+ uaddl2 v27.8h, v21.16b, v22.16b -+ UMLAL4K v6, v7, v8, v9, v26, v27, v0.h[0] -+ -+ ldr q30, [x2, w11, sxtw] -+ ldr q28, [x4, w11, sxtw] -+ -+// i1 >>= 15; // i1 = v2, -v3, -v4*, -v5* -+ SQSHRUNN v2, v2, v3, v4, v5, 15 -+ -+// j1 >>= 15; // j1 = v3, -v6*, -v7*, -v8*, -v9* -+ SQSHRUNN v3, v6, v7, v8, v9, 15 -+ -+// { -+// int t1 =(FFABS(prev[mrefs] - m1) + FFABS(prev[prefs] - p1)) >> 1; -+// int t2 =(FFABS(next[mrefs] - m1) + FFABS(next[prefs] - p1)) >> 1; -+ uabd v30.16b, v22.16b, v30.16b -+ uabd v31.16b, v24.16b, v31.16b -+ uabd v28.16b, v22.16b, v28.16b -+ uabd v29.16b, v24.16b, v29.16b -+ uhadd v31.16b, v31.16b, v30.16b -+ uhadd v29.16b, v29.16b, v28.16b -+ -+ ldr q27, [x2, w13, sxtw] -+ ldr q26, [x4, w13, sxtw] -+ -+// diff0 = FFMAX3(temporal_diff0 >> 1, t1, t2); // diff0=v18 -+ ushr v18.16b, v11.16b, #1 -+ umax v18.16b, v18.16b, v31.16b -+ umax v18.16b, v18.16b, v29.16b -+// } // v28, v30 preserved for next block -+// { // tdiff2 = v14 -+// int t1 =(FFABS(prev[prefs] - p1) + FFABS(prev[prefs3] - p3)) >> 1; -+// int t2 =(FFABS(next[prefs] - p1) + FFABS(next[prefs3] - p3)) >> 1; -+ uabd v31.16b, v21.16b, v27.16b -+ uabd v29.16b, v21.16b, v26.16b -+ uhadd v31.16b, v31.16b, v30.16b -+ uhadd v29.16b, v29.16b, v28.16b -+ -+// diff2 = FFMAX3(temporal_diff2 >> 1, t1, t2); // diff2=v19 -+ ushr v19.16b, v14.16b, #1 -+ umax v19.16b, v19.16b, v31.16b -+ umax v19.16b, v19.16b, v29.16b -+// } -+ -+ // diff0 = v18, (m2 >> 1) = v13, m1 = v24, d0 = v10, p1 = v22, d2 = v15 -+ SPAT_CHECK v18, v13, v24, v10, v22, v15, v31, v30, v29, v28 -+ -+ // diff2 = v19, d0 = v10, p1 = v22, d2 = v15, p3 = v21, (p4 >> 1) = v12 -+ SPAT_CHECK v19, v10, v22, v15, v21, v12, v31, v30, v29, v28 -+ -+ // j1 = v3, j2 = v16, p1 = v22, d2 = v15, p3 = v21, td2 = v14, diff2 = v19 -+ INTERPOL v3, v3, v16, v22, v15, v21, v14, v19, v31, v30, v29 -+ -+// dst[d_stride * 2] = av_clip_uint8(interpol); -+ str q3, [x0, w5, sxtw] -+ -+// dst[d_stride] = p1; -+ str q22, [x0, w1, sxtw] -+ -+ // i1 = v2, i2 = v17, m1 = v24, d0 = v10, p1 = v22, td2 = v11, diff2 = v18 -+ INTERPOL v2, v2, v17, v24, v10, v22, v11, v18, v31, v30, v29 -+ -+// dst[0] = av_clip_uint8(interpol); -+ str q2, [x0], #16 -+// } -+// -+// dst++; -+// cur++; -+// prev++; -+// prev2++; -+// next++; -+// } -+ subs w10, w10, #16 -+ add x2, x2, #16 -+ add x3, x3, #16 -+ add x4, x4, #16 -+ add x17, x17, #16 -+ bgt 10b -+ -+ POP_VREGS -+99: -+ ret -+endfunc -+ -+// =========================================================================== -+// -+// void filter_line( -+// void *dst1, // x0 -+// void *prev1, // x1 -+// void *cur1, // x2 -+// void *next1, // x3 -+// int w, // w4 -+// int prefs, // w5 -+// int mrefs, // w6 -+// int prefs2, // w7 -+// int mrefs2, // [sp, #0] -+// int prefs3, // [sp, #SP_INT] -+// int mrefs3, // [sp, #SP_INT*2] -+// int prefs4, // [sp, #SP_INT*3] -+// int mrefs4, // [sp, #SP_INT*4] -+// int parity, // [sp, #SP_INT*5] -+// int clip_max) // [sp, #SP_INT*6] -+ -+function ff_bwdif_filter_line_neon, export=1 -+ // Sanity check w -+ cmp w4, #0 -+ ble 99f -+ -+ // Rearrange regs to be the same as line3 for ease of debug! -+ mov w10, w4 // w10 = loop count -+ mov w9, w6 // w9 = mref -+ mov w12, w7 // w12 = pref2 -+ mov w11, w5 // w11 = pref -+ ldr w8, [sp, #0] // w8 = mref2 -+ ldr w7, [sp, #SP_INT*2] // w7 = mref3 -+ ldr w6, [sp, #SP_INT*4] // w6 = mref4 -+ ldr w13, [sp, #SP_INT] // w13 = pref3 -+ ldr w14, [sp, #SP_INT*3] // w14 = pref4 -+ -+ mov x4, x3 -+ mov x3, x2 -+ mov x2, x1 -+ -+ LDR_COEFFS v0, x17 -+ -+// #define prev2 cur -+// const uint8_t * restrict next2 = parity ? prev : next; -+ ldr w17, [sp, #SP_INT*5] // parity -+ cmp w17, #0 -+ csel x17, x2, x4, ne -+ -+ PUSH_VREGS -+ -+// for (x = 0; x < w; x++) { -+// int diff0, diff2; -+// int d0, d2; -+// int temporal_diff0, temporal_diff2; -+// -+// int i1, i2; -+// int j1, j2; -+// int p6, p5, p4, p3, p2, p1, c0, m1, m2, m3, m4; -+ -+10: -+// c0 = prev2[0] + next2[0]; // c0 = v20, v21 -+// d0 = c0 >> 1; // d0 = v10 -+// temporal_diff0 = FFABS(prev2[0] - next2[0]); // td0 = v11 -+ ldr q31, [x3] -+ ldr q21, [x17] -+ uhadd v10.16b, v31.16b, v21.16b -+ uabd v11.16b, v31.16b, v21.16b -+ uaddl v20.8h, v21.8b, v31.8b -+ uaddl2 v21.8h, v21.16b, v31.16b -+ -+ ldr q31, [x3, w6, sxtw] -+ ldr q23, [x17, w6, sxtw] -+ -+// i1 = coef_hf[0] * c0; // i1 = v2-v5 -+ UMULL4K v2, v3, v4, v5, v20, v21, v0.h[2] -+ -+ ldr q30, [x3, w14, sxtw] -+ ldr q25, [x17, w14, sxtw] -+ -+// m4 = prev2[mrefs4] + next2[mrefs4]; // m4 = v22,v23 -+ uaddl v22.8h, v23.8b, v31.8b -+ uaddl2 v23.8h, v23.16b, v31.16b -+ -+// p4 = prev2[prefs4] + next2[prefs4]; // p4 = v24,v25, (p4 >> 1) = v12 -+ uhadd v12.16b, v25.16b, v30.16b -+ uaddl v24.8h, v25.8b, v30.8b -+ uaddl2 v25.8h, v25.16b, v30.16b -+ -+// m3 = cur[mrefs3]; // m3 = v20 -+ ldr q20, [x3, w7, sxtw] -+ -+// p3 = cur[prefs3]; // p3 = v21 -+ ldr q21, [x3, w13, sxtw] -+ -+// i1 += coef_hf[2] * (m4 + p4); // (-m4:v22,v23) (-p4:v24,v25) -+ add v22.8h, v22.8h, v24.8h -+ add v23.8h, v23.8h, v25.8h -+ UMLAL4K v2, v3, v4, v5, v22, v23, v0.h[4] -+ -+ ldr q29, [x3, w8, sxtw] -+ ldr q23, [x17, w8, sxtw] -+ -+// i1 -= coef_lf[1] * 4 * (m3 + p3); // - -+ uaddl v30.8h, v20.8b, v21.8b -+ uaddl2 v31.8h, v20.16b, v21.16b -+ -+ UMLSL4K v2, v3, v4, v5, v30, v31, v0.h[1] -+ -+ ldr q31, [x3, w12, sxtw] -+ ldr q27, [x17, w12, sxtw] -+ -+// m2 = prev2[mrefs2] + next2[mrefs2]; // m2 = v22,v23, (m2 >> 1) = v13 -+ uhadd v13.16b, v23.16b, v29.16b -+ uaddl v22.8h, v23.8b, v29.8b -+ uaddl2 v23.8h, v23.16b, v29.16b -+ -+// m1 = cur[mrefs]; // m1 = v24 -+ ldr q24, [x3, w9, sxtw] -+ -+// p2 = prev2[prefs2] + next2[prefs2]; // p2 = v26, v27 -+// temporal_diff2 = FFABS(prev2[prefs2] - next2[prefs2]); // td2 = v14 -+// d2 = p2 >> 1; // d2 = v15 -+ uabd v14.16b, v31.16b, v27.16b -+ uhadd v15.16b, v31.16b, v27.16b -+ uaddl v26.8h, v27.8b, v31.8b -+ uaddl2 v27.8h, v27.16b, v31.16b -+ -+// i1 -= coef_hf[1] * (m2 + p2); // (-m2:v22,v23*) (-p2:v26*,v27*) -+ add v22.8h, v22.8h, v26.8h -+ add v23.8h, v23.8h, v27.8h -+ UMLSL4K v2, v3, v4, v5, v22, v23, v0.h[3] -+ -+// p1 = cur[prefs]; // p1 = v22 -+ ldr q22, [x3, w11, sxtw] -+ -+// i2 = (coef_sp[0] * (m1 + p1) - coef_sp[1] * (m3 + p3)) >> 13; // (-m3:v20*) i2=v17 -+ uaddl v18.8h, v22.8b, v24.8b -+ uaddl2 v19.8h, v22.16b, v24.16b -+ UMULL4K v28, v29, v30, v31, v18, v19, v0.h[6] -+ -+ uaddl v18.8h, v20.8b, v21.8b -+ uaddl2 v19.8h, v20.16b, v21.16b -+ UMLSL4K v28, v29, v30, v31, v18, v19, v0.h[7] -+ -+ SQSHRUNN v17, v28, v29, v30, v31, 13 -+ -+// i1 += coef_lf[0] * 4 * (m1 + p1); // p1 = v22, m1 = v24 -+ uaddl v26.8h, v24.8b, v22.8b -+ uaddl2 v27.8h, v24.16b, v22.16b -+ UMLAL4K v2, v3, v4, v5, v26, v27, v0.h[0] -+ -+ ldr q31, [x2, w9, sxtw] -+ ldr q29, [x4, w9, sxtw] -+ -+ ldr q30, [x2, w11, sxtw] -+ ldr q28, [x4, w11, sxtw] -+ -+// i1 >>= 15; // i1 = v2, -v3, -v4*, -v5* -+ SQSHRUNN v2, v2, v3, v4, v5, 15 -+ -+// { -+// int t1 =(FFABS(prev[mrefs] - m1) + FFABS(prev[prefs] - p1)) >> 1; -+// int t2 =(FFABS(next[mrefs] - m1) + FFABS(next[prefs] - p1)) >> 1; -+ uabd v30.16b, v22.16b, v30.16b -+ uabd v31.16b, v24.16b, v31.16b -+ uabd v28.16b, v22.16b, v28.16b -+ uabd v29.16b, v24.16b, v29.16b -+ uhadd v31.16b, v31.16b, v30.16b -+ uhadd v29.16b, v29.16b, v28.16b -+ -+// diff0 = FFMAX3(temporal_diff0 >> 1, t1, t2); // diff0=v18 -+ ushr v18.16b, v11.16b, #1 -+ umax v18.16b, v18.16b, v31.16b -+ umax v18.16b, v18.16b, v29.16b -+ -+ // diff0 = v18, (m2 >> 1) = v13, m1 = v24, d0 = v10, p1 = v22, d2 = v15 -+ SPAT_CHECK v18, v13, v24, v10, v22, v15, v31, v30, v29, v28 -+ -+ // i1 = v2, i2 = v17, m1 = v24, d0 = v10, p1 = v22, td2 = v11, diff2 = v18 -+ INTERPOL v2, v2, v17, v24, v10, v22, v11, v18, v31, v30, v29 -+ -+// dst[0] = av_clip_uint8(interpol); -+ str q2, [x0], #16 -+// } -+// -+// dst++; -+// cur++; -+// prev++; -+// prev2++; -+// next++; -+// } -+ -+ subs w10, w10, #16 -+ add x2, x2, #16 -+ add x3, x3, #16 -+ add x4, x4, #16 -+ add x17, x17, #16 -+ bgt 10b -+ -+ POP_VREGS -+99: -+ ret -+endfunc -+ -+// ============================================================================ -+// -+// void ff_bwdif_filter_edge_neon( -+// void *dst1, // x0 -+// void *prev1, // x1 -+// void *cur1, // x2 -+// void *next1, // x3 -+// int w, // w4 -+// int prefs, // w5 -+// int mrefs, // w6 -+// int prefs2, // w7 -+// int mrefs2, // [sp, #0] -+// int parity, // [sp, #SP_INT] -+// int clip_max, // [sp, #SP_INT*2] unused -+// int spat); // [sp, #SP_INT*3] -+ -+function ff_bwdif_filter_edge_neon, export=1 -+ // Sanity check w -+ cmp w4, #0 -+ ble 99f -+ -+// #define prev2 cur -+// const uint8_t * restrict next2 = parity ? prev : next; -+ -+ ldr w8, [sp, #0] // mrefs2 -+ -+ ldr w17, [sp, #SP_INT] // parity -+ ldr w16, [sp, #SP_INT*3] // spat -+ cmp w17, #0 -+ csel x17, x1, x3, ne -+ -+// for (x = 0; x < w; x++) { -+ -+10: -+// int m1 = cur[mrefs]; -+// int d = (prev2[0] + next2[0]) >> 1; -+// int p1 = cur[prefs]; -+// int temporal_diff0 = FFABS(prev2[0] - next2[0]); -+// int temporal_diff1 =(FFABS(prev[mrefs] - m1) + FFABS(prev[prefs] - p1)) >> 1; -+// int temporal_diff2 =(FFABS(next[mrefs] - m1) + FFABS(next[prefs] - p1)) >> 1; -+// int diff = FFMAX3(temporal_diff0 >> 1, temporal_diff1, temporal_diff2); -+ ldr q31, [x2] -+ ldr q21, [x17] -+ uhadd v16.16b, v31.16b, v21.16b // d0 = v16 -+ uabd v17.16b, v31.16b, v21.16b // td0 = v17 -+ ldr q24, [x2, w6, sxtw] // m1 = v24 -+ ldr q22, [x2, w5, sxtw] // p1 = v22 -+ -+ ldr q0, [x1, w6, sxtw] // prev[mrefs] -+ ldr q2, [x1, w5, sxtw] // prev[prefs] -+ ldr q1, [x3, w6, sxtw] // next[mrefs] -+ ldr q3, [x3, w5, sxtw] // next[prefs] -+ -+ ushr v29.16b, v17.16b, #1 -+ -+ uabd v31.16b, v0.16b, v24.16b -+ uabd v30.16b, v2.16b, v22.16b -+ uhadd v0.16b, v31.16b, v30.16b // td1 = q0 -+ -+ uabd v31.16b, v1.16b, v24.16b -+ uabd v30.16b, v3.16b, v22.16b -+ uhadd v1.16b, v31.16b, v30.16b // td2 = q1 -+ -+ umax v0.16b, v0.16b, v29.16b -+ umax v0.16b, v0.16b, v1.16b // diff = v0 -+ -+// if (spat) { -+// SPAT_CHECK() -+// } -+// i0 = (m1 + p1) >> 1; -+ cbz w16, 1f -+ -+ ldr q31, [x2, w8, sxtw] -+ ldr q18, [x17, w8, sxtw] -+ ldr q30, [x2, w7, sxtw] -+ ldr q19, [x17, w7, sxtw] -+ uhadd v18.16b, v18.16b, v31.16b -+ uhadd v19.16b, v19.16b, v30.16b -+ -+ SPAT_CHECK v0, v18, v24, v16, v22, v19, v31, v30, v29, v28 -+ -+1: -+ uhadd v2.16b, v22.16b, v24.16b -+ -+ // i0 = v2, s0 = v2, d0 = v16, diff = v0, t0 = v31, t1 = v30 -+ DIFF_CLIP v2, v2, v16, v0, v31, v30 -+ -+// dst[0] = av_clip(interpol, 0, clip_max); -+ str q2, [x0], #16 -+ -+// dst++; -+// cur++; -+// } -+ subs w4, w4, #16 -+ add x1, x1, #16 -+ add x2, x2, #16 -+ add x3, x3, #16 -+ add x17, x17, #16 -+ bgt 10b -+ -+99: -+ ret -+endfunc -+ -+// ============================================================================ -+// -+// void ff_bwdif_filter_intra_neon( -+// void *dst1, // x0 -+// void *cur1, // x1 -+// int w, // w2 -+// int prefs, // w3 -+// int mrefs, // w4 -+// int prefs3, // w5 -+// int mrefs3, // w6 -+// int parity, // w7 unused -+// int clip_max) // [sp, #0] unused -+ -+function ff_bwdif_filter_intra_neon, export=1 -+ cmp w2, #0 -+ ble 99f -+ -+ LDR_COEFFS v0, x17 -+ -+// for (x = 0; x < w; x++) { -+10: -+ -+// interpol = (coef_sp[0] * (cur[mrefs] + cur[prefs]) - coef_sp[1] * (cur[mrefs3] + cur[prefs3])) >> 13; -+ ldr q31, [x1, w4, sxtw] -+ ldr q30, [x1, w3, sxtw] -+ ldr q29, [x1, w6, sxtw] -+ ldr q28, [x1, w5, sxtw] -+ -+ uaddl v20.8h, v31.8b, v30.8b -+ uaddl2 v21.8h, v31.16b, v30.16b -+ -+ UMULL4K v2, v3, v4, v5, v20, v21, v0.h[6] -+ -+ uaddl v20.8h, v29.8b, v28.8b -+ uaddl2 v21.8h, v29.16b, v28.16b -+ -+ UMLSL4K v2, v3, v4, v5, v20, v21, v0.h[7] -+ -+// dst[0] = av_clip(interpol, 0, clip_max); -+ SQSHRUNN v2, v2, v3, v4, v5, 13 -+ str q2, [x0], #16 -+ -+// dst++; -+// cur++; -+// } -+ -+ subs w2, w2, #16 -+ add x1, x1, #16 -+ bgt 10b -+ -+99: -+ ret -+endfunc --- a/libavfilter/allfilters.c +++ b/libavfilter/allfilters.c -@@ -242,6 +242,7 @@ extern const AVFilter ff_vf_derain; +@@ -256,6 +256,7 @@ extern const AVFilter ff_vf_derain; extern const AVFilter ff_vf_deshake; extern const AVFilter ff_vf_deshake_opencl; extern const AVFilter ff_vf_despill; @@ -15085,15 +14823,15 @@ raspiberry pi support. extern const AVFilter ff_vf_detelecine; extern const AVFilter ff_vf_dilation; extern const AVFilter ff_vf_dilation_opencl; -@@ -414,6 +415,7 @@ extern const AVFilter ff_vf_scale; +@@ -434,6 +435,7 @@ extern const AVFilter ff_vf_scale; extern const AVFilter ff_vf_scale_cuda; extern const AVFilter ff_vf_scale_npp; extern const AVFilter ff_vf_scale_qsv; +extern const AVFilter ff_vf_scale_v4l2m2m; extern const AVFilter ff_vf_scale_vaapi; + extern const AVFilter ff_vf_scale_vt; extern const AVFilter ff_vf_scale_vulkan; - extern const AVFilter ff_vf_scale2ref; -@@ -483,6 +485,7 @@ extern const AVFilter ff_vf_trim; +@@ -507,6 +509,7 @@ extern const AVFilter ff_vf_trim; extern const AVFilter ff_vf_unpremultiply; extern const AVFilter ff_vf_unsharp; extern const AVFilter ff_vf_unsharp_opencl; @@ -15103,7 +14841,7 @@ raspiberry pi support. extern const AVFilter ff_vf_v360; --- a/libavfilter/buffersink.c +++ b/libavfilter/buffersink.c -@@ -62,6 +62,11 @@ typedef struct BufferSinkContext { +@@ -60,6 +60,11 @@ typedef struct BufferSinkContext { int sample_rates_size; AVFrame *peeked_frame; @@ -15115,7 +14853,7 @@ raspiberry pi support. } BufferSinkContext; #define NB_ITEMS(list) (list ## _size / sizeof(*list)) -@@ -154,6 +159,22 @@ int attribute_align_arg av_buffersink_ge +@@ -129,6 +134,22 @@ int attribute_align_arg av_buffersink_ge return get_frame_internal(ctx, frame, 0, nb_samples); } @@ -15135,20 +14873,36 @@ raspiberry pi support. + return 0; +} + - #if FF_API_BUFFERSINK_ALLOC - AVBufferSinkParams *av_buffersink_params_alloc(void) + static av_cold int common_init(AVFilterContext *ctx) { -@@ -403,6 +424,7 @@ static const AVFilterPad avfilter_vsink_ - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, -+ .get_buffer = {.video = alloc_video_buffer}, - }, - }; + BufferSinkContext *buf = ctx->priv; +@@ -355,6 +376,14 @@ static const AVOption abuffersink_option + AVFILTER_DEFINE_CLASS(buffersink); + AVFILTER_DEFINE_CLASS(abuffersink); ++static const AVFilterPad avfilter_vsink_buffer_inputs[] = { ++ { ++ .name = "default", ++ .type = AVMEDIA_TYPE_VIDEO, ++ .get_buffer = {.video = alloc_video_buffer}, ++ }, ++}; ++ + const AVFilter ff_vsink_buffer = { + .name = "buffersink", + .description = NULL_IF_CONFIG_SMALL("Buffer video frames, and make them available to the end of the filter graph."), +@@ -363,7 +392,7 @@ const AVFilter ff_vsink_buffer = { + .init = common_init, + .uninit = uninit, + .activate = activate, +- FILTER_INPUTS(ff_video_default_filterpad), ++ FILTER_INPUTS(avfilter_vsink_buffer_inputs), + .outputs = NULL, + FILTER_QUERY_FUNC(vsink_query_formats), + }; --- a/libavfilter/buffersink.h +++ b/libavfilter/buffersink.h -@@ -202,6 +202,9 @@ int av_buffersink_get_frame(AVFilterCont +@@ -166,6 +166,9 @@ int av_buffersink_get_frame(AVFilterCont */ int av_buffersink_get_samples(AVFilterContext *ctx, AVFrame *frame, int nb_samples); @@ -15160,152 +14914,18 @@ raspiberry pi support. */ --- a/libavfilter/buffersrc.c +++ b/libavfilter/buffersrc.c -@@ -204,7 +204,7 @@ FF_ENABLE_DEPRECATION_WARNINGS +@@ -210,7 +210,7 @@ int attribute_align_arg av_buffersrc_add switch (ctx->outputs[0]->type) { case AVMEDIA_TYPE_VIDEO: - CHECK_VIDEO_PARAM_CHANGE(ctx, s, frame->width, frame->height, + CHECK_VIDEO_PARAM_CHANGE(ctx, s, av_frame_cropped_width(frame), av_frame_cropped_height(frame), - frame->format, frame->pts); + frame->format, frame->colorspace, + frame->color_range, frame->pts); break; - case AVMEDIA_TYPE_AUDIO: ---- a/libavfilter/bwdif.h -+++ b/libavfilter/bwdif.h -@@ -35,8 +35,29 @@ typedef struct BWDIFContext { - void (*filter_edge)(void *dst, void *prev, void *cur, void *next, - int w, int prefs, int mrefs, int prefs2, int mrefs2, - int parity, int clip_max, int spat); -+ void (*filter_line3)(void *dst, int dstride, -+ const void *prev, const void *cur, const void *next, int prefs, -+ int w, int parity, int clip_max); - } BWDIFContext; - --void ff_bwdif_init_x86(BWDIFContext *bwdif); -+void ff_bwdif_init_filter_line(BWDIFContext *bwdif, int bit_depth); -+void ff_bwdif_init_x86(BWDIFContext *bwdif, int bit_depth); -+void ff_bwdif_init_aarch64(BWDIFContext *bwdif, int bit_depth); -+ -+void ff_bwdif_filter_edge_c(void *dst1, void *prev1, void *cur1, void *next1, -+ int w, int prefs, int mrefs, int prefs2, int mrefs2, -+ int parity, int clip_max, int spat); -+ -+void ff_bwdif_filter_intra_c(void *dst1, void *cur1, int w, int prefs, int mrefs, -+ int prefs3, int mrefs3, int parity, int clip_max); -+ -+void ff_bwdif_filter_line_c(void *dst1, void *prev1, void *cur1, void *next1, -+ int w, int prefs, int mrefs, int prefs2, int mrefs2, -+ int prefs3, int mrefs3, int prefs4, int mrefs4, -+ int parity, int clip_max); -+ -+void ff_bwdif_filter_line3_c(void * dst1, int d_stride, -+ const void * prev1, const void * cur1, const void * next1, int s_stride, -+ int w, int parity, int clip_max); - - #endif /* AVFILTER_BWDIF_H */ --- a/libavfilter/vf_bwdif.c +++ b/libavfilter/vf_bwdif.c -@@ -122,8 +122,8 @@ typedef struct ThreadData { - next2++; \ - } - --static void filter_intra(void *dst1, void *cur1, int w, int prefs, int mrefs, -- int prefs3, int mrefs3, int parity, int clip_max) -+void ff_bwdif_filter_intra_c(void *dst1, void *cur1, int w, int prefs, int mrefs, -+ int prefs3, int mrefs3, int parity, int clip_max) - { - uint8_t *dst = dst1; - uint8_t *cur = cur1; -@@ -132,10 +132,10 @@ static void filter_intra(void *dst1, voi - FILTER_INTRA() - } - --static void filter_line_c(void *dst1, void *prev1, void *cur1, void *next1, -- int w, int prefs, int mrefs, int prefs2, int mrefs2, -- int prefs3, int mrefs3, int prefs4, int mrefs4, -- int parity, int clip_max) -+void ff_bwdif_filter_line_c(void *dst1, void *prev1, void *cur1, void *next1, -+ int w, int prefs, int mrefs, int prefs2, int mrefs2, -+ int prefs3, int mrefs3, int prefs4, int mrefs4, -+ int parity, int clip_max) - { - uint8_t *dst = dst1; - uint8_t *prev = prev1; -@@ -150,9 +150,34 @@ static void filter_line_c(void *dst1, vo - FILTER2() - } - --static void filter_edge(void *dst1, void *prev1, void *cur1, void *next1, -- int w, int prefs, int mrefs, int prefs2, int mrefs2, -- int parity, int clip_max, int spat) -+#define NEXT_LINE()\ -+ dst += d_stride; \ -+ prev += prefs; \ -+ cur += prefs; \ -+ next += prefs; -+ -+void ff_bwdif_filter_line3_c(void * dst1, int d_stride, -+ const void * prev1, const void * cur1, const void * next1, int s_stride, -+ int w, int parity, int clip_max) -+{ -+ const int prefs = s_stride; -+ uint8_t * dst = dst1; -+ const uint8_t * prev = prev1; -+ const uint8_t * cur = cur1; -+ const uint8_t * next = next1; -+ -+ ff_bwdif_filter_line_c(dst, (void*)prev, (void*)cur, (void*)next, w, -+ prefs, -prefs, prefs * 2, - prefs * 2, prefs * 3, -prefs * 3, prefs * 4, -prefs * 4, parity, clip_max); -+ NEXT_LINE(); -+ memcpy(dst, cur, w); -+ NEXT_LINE(); -+ ff_bwdif_filter_line_c(dst, (void*)prev, (void*)cur, (void*)next, w, -+ prefs, -prefs, prefs * 2, - prefs * 2, prefs * 3, -prefs * 3, prefs * 4, -prefs * 4, parity, clip_max); -+} -+ -+void ff_bwdif_filter_edge_c(void *dst1, void *prev1, void *cur1, void *next1, -+ int w, int prefs, int mrefs, int prefs2, int mrefs2, -+ int parity, int clip_max, int spat) - { - uint8_t *dst = dst1; - uint8_t *prev = prev1; -@@ -212,6 +237,13 @@ static void filter_edge_16bit(void *dst1 - FILTER2() - } - -+// Round job start line down to multiple of 4 so that if filter_line3 exists -+// and the frame is a multiple of 4 high then filter_line will never be called -+static inline int job_start(const int jobnr, const int nb_jobs, const int h) -+{ -+ return jobnr >= nb_jobs ? h : ((h * jobnr) / nb_jobs) & ~3; -+} -+ - static int filter_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) - { - BWDIFContext *s = ctx->priv; -@@ -221,8 +253,8 @@ static int filter_slice(AVFilterContext - int clip_max = (1 << (yadif->csp->comp[td->plane].depth)) - 1; - int df = (yadif->csp->comp[td->plane].depth + 7) / 8; - int refs = linesize / df; -- int slice_start = (td->h * jobnr ) / nb_jobs; -- int slice_end = (td->h * (jobnr+1)) / nb_jobs; -+ int slice_start = job_start(jobnr, nb_jobs, td->h); -+ int slice_end = job_start(jobnr + 1, nb_jobs, td->h); - int y; - - for (y = slice_start; y < slice_end; y++) { -@@ -244,6 +276,11 @@ static int filter_slice(AVFilterContext - refs << 1, -(refs << 1), - td->parity ^ td->tff, clip_max, - (y < 2) || ((y + 3) > td->h) ? 0 : 1); -+ } else if (s->filter_line3 && y + 2 < slice_end && y + 6 < td->h) { -+ s->filter_line3(dst, td->frame->linesize[td->plane], -+ prev, cur, next, linesize, td->w, -+ td->parity ^ td->tff, clip_max); -+ y += 2; - } else { - s->filter_line(dst, prev, cur, next, td->w, - refs, -refs, refs << 1, -(refs << 1), -@@ -265,22 +302,31 @@ static void filter(AVFilterContext *ctx, +@@ -115,19 +115,28 @@ static void filter(AVFilterContext *ctx, YADIFContext *yadif = &bwdif->yadif; ThreadData td = { .frame = dstpic, .parity = parity, .tff = tff }; int i; @@ -15336,12 +14956,8 @@ raspiberry pi support. + td.plane = comp->plane; ff_filter_execute(ctx, filter_slice, &td, NULL, -- FFMIN(h, ff_filter_get_nb_threads(ctx))); -+ FFMIN((h+3)/4, ff_filter_get_nb_threads(ctx))); - } - if (yadif->current_field == YADIF_FIELD_END) { - yadif->current_field = YADIF_FIELD_NORMAL; -@@ -313,6 +359,7 @@ static const enum AVPixelFormat pix_fmts + FFMIN((h+3)/4, ff_filter_get_nb_threads(ctx))); +@@ -151,6 +160,7 @@ static const enum AVPixelFormat pix_fmts AV_PIX_FMT_YUVA420P9, AV_PIX_FMT_YUVA422P9, AV_PIX_FMT_YUVA444P9, AV_PIX_FMT_YUVA420P10, AV_PIX_FMT_YUVA422P10, AV_PIX_FMT_YUVA444P10, AV_PIX_FMT_YUVA420P16, AV_PIX_FMT_YUVA422P16, AV_PIX_FMT_YUVA444P16, @@ -15349,46 +14965,9 @@ raspiberry pi support. AV_PIX_FMT_GBRP, AV_PIX_FMT_GBRP9, AV_PIX_FMT_GBRP10, AV_PIX_FMT_GBRP12, AV_PIX_FMT_GBRP14, AV_PIX_FMT_GBRP16, AV_PIX_FMT_GBRAP, AV_PIX_FMT_GBRAP16, -@@ -340,21 +387,29 @@ static int config_props(AVFilterLink *li - - yadif->csp = av_pix_fmt_desc_get(link->format); - yadif->filter = filter; -- if (yadif->csp->comp[0].depth > 8) { -+ ff_bwdif_init_filter_line(s, yadif->csp->comp[0].depth); -+ -+ return 0; -+} -+ -+av_cold void ff_bwdif_init_filter_line(BWDIFContext *s, int bit_depth) -+{ -+ s->filter_line3 = 0; -+ if (bit_depth > 8) { - s->filter_intra = filter_intra_16bit; - s->filter_line = filter_line_c_16bit; - s->filter_edge = filter_edge_16bit; - } else { -- s->filter_intra = filter_intra; -- s->filter_line = filter_line_c; -- s->filter_edge = filter_edge; -+ s->filter_intra = ff_bwdif_filter_intra_c; -+ s->filter_line = ff_bwdif_filter_line_c; -+ s->filter_edge = ff_bwdif_filter_edge_c; - } - - #if ARCH_X86 -- ff_bwdif_init_x86(s); -+ ff_bwdif_init_x86(s, bit_depth); -+#elif ARCH_AARCH64 -+ ff_bwdif_init_aarch64(s, bit_depth); - #endif -- -- return 0; - } - - --- /dev/null +++ b/libavfilter/vf_deinterlace_v4l2m2m.c -@@ -0,0 +1,2102 @@ +@@ -0,0 +1,2120 @@ +/* + * This file is part of FFmpeg. + * @@ -15435,6 +15014,7 @@ raspiberry pi support. +#include "libavutil/hwcontext_drm.h" +#include "libavutil/internal.h" +#include "libavutil/mathematics.h" ++#include "libavutil/mem.h" +#include "libavutil/opt.h" +#include "libavutil/pixdesc.h" +#include "libavutil/time.h" @@ -15444,7 +15024,6 @@ raspiberry pi support. +#include "filters.h" +#include "avfilter.h" +#include "formats.h" -+#include "internal.h" +#include "scale_eval.h" +#include "video.h" + @@ -15593,6 +15172,39 @@ raspiberry pi support. +} DeintV4L2M2MContext; + + ++static inline void frame_set_progressive(AVFrame* frame) ++{ ++#if FF_API_INTERLACED_FRAME ++FF_DISABLE_DEPRECATION_WARNINGS ++ frame->interlaced_frame = 0; ++ frame->top_field_first = 0; ++FF_ENABLE_DEPRECATION_WARNINGS ++#endif ++ frame->flags &= ~(AV_FRAME_FLAG_TOP_FIELD_FIRST | AV_FRAME_FLAG_INTERLACED); ++} ++ ++static inline int frame_is_interlaced(const AVFrame* const frame) ++{ ++#if FF_API_INTERLACED_FRAME ++FF_DISABLE_DEPRECATION_WARNINGS ++ return frame->interlaced_frame || (frame->flags & AV_FRAME_FLAG_INTERLACED) != 0; ++FF_ENABLE_DEPRECATION_WARNINGS ++#else ++ return (frame->flags & AV_FRAME_FLAG_INTERLACED) != 0; ++#endif ++} ++ ++static inline int frame_is_tff(const AVFrame* const frame) ++{ ++#if FF_API_INTERLACED_FRAME ++FF_DISABLE_DEPRECATION_WARNINGS ++ return frame->top_field_first || (frame->flags & AV_FRAME_FLAG_TOP_FIELD_FIRST) != 0; ++FF_ENABLE_DEPRECATION_WARNINGS ++#else ++ return (frame->flags & AV_FRAME_FLAG_TOP_FIELD_FIRST) != 0; ++#endif ++} ++ +static inline int drain_frame_expected(const drain_state_t d) +{ + return d == DRAIN_EOS || d == DRAIN_LAST; @@ -16826,8 +16438,8 @@ raspiberry pi support. + else + buf->buffer.m.fd = drm_desc->objects[0].fd; + -+ buf->buffer.field = !frame->interlaced_frame ? V4L2_FIELD_NONE : -+ frame->top_field_first ? V4L2_FIELD_INTERLACED_TB : ++ buf->buffer.field = !frame_is_interlaced(frame) ? V4L2_FIELD_NONE : ++ frame_is_tff(frame) ? V4L2_FIELD_INTERLACED_TB : + V4L2_FIELD_INTERLACED_BT; + + if (ctx->field_order != buf->buffer.field) { @@ -16957,10 +16569,9 @@ raspiberry pi support. + + if (ctx->filter_type == FILTER_V4L2_DEINTERLACE) { + // Not interlaced now -+ frame->interlaced_frame = 0; // *** Fill in from dst buffer? -+ frame->top_field_first = 0; -+ // Pkt duration halved -+ frame->pkt_duration /= 2; ++ frame_set_progressive(frame); ++ // Duration halved ++ frame->duration /= 2; + } + + if (avbuf->buffer.flags & V4L2_BUF_FLAG_ERROR) { @@ -16998,32 +16609,20 @@ raspiberry pi support. + ctx->output_height = ctx->height; + } + -+ av_log(priv, AV_LOG_DEBUG, "%s: %dx%d->%dx%d FR: %d/%d->%d/%d\n", __func__, -+ ctx->width, ctx->height, ctx->output_width, ctx->output_height, -+ inlink->frame_rate.num, inlink->frame_rate.den, outlink->frame_rate.num, outlink->frame_rate.den); ++ av_log(priv, AV_LOG_DEBUG, "%s: %dx%d->%dx%d\n", __func__, ++ ctx->width, ctx->height, ctx->output_width, ctx->output_height); + + outlink->time_base = inlink->time_base; + outlink->w = ctx->output_width; + outlink->h = ctx->output_height; + outlink->format = inlink->format; -+ if (ctx->filter_type == FILTER_V4L2_DEINTERLACE && inlink->frame_rate.den != 0) -+ outlink->frame_rate = (AVRational){inlink->frame_rate.num * 2, inlink->frame_rate.den}; + + if (inlink->sample_aspect_ratio.num) + outlink->sample_aspect_ratio = av_mul_q((AVRational){outlink->h * inlink->w, outlink->w * inlink->h}, inlink->sample_aspect_ratio); + else + outlink->sample_aspect_ratio = inlink->sample_aspect_ratio; + -+ ret = deint_v4l2m2m_find_device(ctx); -+ if (ret) -+ return ret; -+ -+ if (inlink->hw_frames_ctx) { -+ ctx->hw_frames_ctx = av_buffer_ref(inlink->hw_frames_ctx); -+ if (!ctx->hw_frames_ctx) -+ return AVERROR(ENOMEM); -+ } -+ return 0; ++ return deint_v4l2m2m_find_device(ctx); +} + +static uint32_t desc_pixelformat(const AVDRMFrameDescriptor * const drm_desc) @@ -17060,9 +16659,7 @@ raspiberry pi support. + int ret; + + av_log(priv, AV_LOG_DEBUG, "<<< %s: input pts: %"PRId64" dts: %"PRId64" field :%d interlaced: %d aspect:%d/%d\n", -+ __func__, in->pts, in->pkt_dts, in->top_field_first, in->interlaced_frame, in->sample_aspect_ratio.num, in->sample_aspect_ratio.den); -+ av_log(priv, AV_LOG_DEBUG, "--- %s: in status in %d/ot %d; out status in %d/out %d\n", __func__, -+ avctx->inputs[0]->status_in, avctx->inputs[0]->status_out, avctx->outputs[0]->status_in, avctx->outputs[0]->status_out); ++ __func__, in->pts, in->pkt_dts, frame_is_tff(in), frame_is_interlaced(in), in->sample_aspect_ratio.num, in->sample_aspect_ratio.den); + + if (ctx->field_order == V4L2_FIELD_ANY) { + const AVDRMFrameDescriptor * const drm_desc = (AVDRMFrameDescriptor *)in->data[0]; @@ -17125,7 +16722,7 @@ raspiberry pi support. + return ret; + } + -+ if (in->top_field_first) ++ if (frame_is_tff(in)) + ctx->field_order = V4L2_FIELD_INTERLACED_TB; + else + ctx->field_order = V4L2_FIELD_INTERLACED_BT; @@ -17236,7 +16833,7 @@ raspiberry pi support. + } + } + else { -+ frame->interlaced_frame = 0; ++ frame_set_progressive(frame); + // frame is always consumed by filter_frame - even on error despite + // a somewhat confusing comment in the header + rv = ff_filter_frame(outlink, frame); @@ -17473,7 +17070,7 @@ raspiberry pi support. + .uninit = &deint_v4l2m2m_uninit, + FILTER_INPUTS(deint_v4l2m2m_inputs), + FILTER_OUTPUTS(deint_v4l2m2m_outputs), -+ FILTER_SINGLE_SAMPLEFMT(AV_PIX_FMT_DRM_PRIME), ++ FILTER_SINGLE_PIXFMT(AV_PIX_FMT_DRM_PRIME), + .priv_class = &deinterlace_v4l2m2m_class, + .activate = deint_v4l2m2m_activate, +}; @@ -17486,14 +17083,14 @@ raspiberry pi support. + .uninit = &deint_v4l2m2m_uninit, + FILTER_INPUTS(deint_v4l2m2m_inputs), + FILTER_OUTPUTS(deint_v4l2m2m_outputs), -+ FILTER_SINGLE_SAMPLEFMT(AV_PIX_FMT_DRM_PRIME), ++ FILTER_SINGLE_PIXFMT(AV_PIX_FMT_DRM_PRIME), + .priv_class = &scale_v4l2m2m_class, + .activate = deint_v4l2m2m_activate, +}; + --- /dev/null +++ b/libavfilter/vf_unsand.c -@@ -0,0 +1,228 @@ +@@ -0,0 +1,227 @@ +/* + * Copyright (c) 2007 Bobby Bingham + * @@ -17529,7 +17126,6 @@ raspiberry pi support. + +#include "avfilter.h" +#include "formats.h" -+#include "internal.h" +#include "video.h" + +typedef struct UnsandContext { @@ -17722,24 +17318,520 @@ raspiberry pi support. + FILTER_OUTPUTS(avfilter_vf_unsand_outputs), +}; + ---- a/libavfilter/x86/vf_bwdif_init.c -+++ b/libavfilter/x86/vf_bwdif_init.c -@@ -42,11 +42,9 @@ void ff_bwdif_filter_line_12bit_ssse3(vo - int mrefs2, int prefs3, int mrefs3, int prefs4, - int mrefs4, int parity, int clip_max); - --av_cold void ff_bwdif_init_x86(BWDIFContext *bwdif) -+av_cold void ff_bwdif_init_x86(BWDIFContext *bwdif, int bit_depth) - { -- YADIFContext *yadif = &bwdif->yadif; - int cpu_flags = av_get_cpu_flags(); -- int bit_depth = (!yadif->csp) ? 8 : yadif->csp->comp[0].depth; - - if (bit_depth <= 8) { - if (EXTERNAL_SSE2(cpu_flags)) +--- a/libavformat/Makefile ++++ b/libavformat/Makefile +@@ -171,6 +171,7 @@ OBJS-$(CONFIG_CODEC2_MUXER) + OBJS-$(CONFIG_CODEC2RAW_DEMUXER) += codec2.o pcm.o + OBJS-$(CONFIG_CODEC2RAW_MUXER) += rawenc.o + OBJS-$(CONFIG_CONCAT_DEMUXER) += concatdec.o ++OBJS-$(CONFIG_CONFORM_MUXER) += conformenc.o + OBJS-$(CONFIG_CRC_MUXER) += crcenc.o + OBJS-$(CONFIG_DATA_DEMUXER) += rawdec.o + OBJS-$(CONFIG_DATA_MUXER) += rawenc.o +--- a/libavformat/allformats.c ++++ b/libavformat/allformats.c +@@ -125,6 +125,7 @@ extern const FFOutputFormat ff_codec2_mu + extern const FFInputFormat ff_codec2raw_demuxer; + extern const FFOutputFormat ff_codec2raw_muxer; + extern const FFInputFormat ff_concat_demuxer; ++extern const FFOutputFormat ff_conform_muxer; + extern const FFOutputFormat ff_crc_muxer; + extern const FFInputFormat ff_dash_demuxer; + extern const FFOutputFormat ff_dash_muxer; +--- /dev/null ++++ b/libavformat/conformenc.c +@@ -0,0 +1,488 @@ ++/* ++ * Copyright (c) 2020 John Cox for Raspberry Pi Trading ++ * ++ * This file is part of FFmpeg. ++ * ++ * FFmpeg is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2.1 of the License, or (at your option) any later version. ++ * ++ * FFmpeg is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with FFmpeg; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ++ */ ++ ++ ++// *** This module is a work in progress and its utility is strictly ++// limited to testing. ++ ++#include "config.h" ++#include "libavutil/opt.h" ++#include "libavutil/frame.h" ++#include "libavutil/md5.h" ++#include "libavutil/mem.h" ++#include "libavutil/pixdesc.h" ++#include "libavutil/hwcontext.h" ++#include "libavutil/hwcontext_drm.h" ++#if CONFIG_SAND ++#include "libavutil/rpi_sand_fns.h" ++#endif ++#include "mux.h" ++ ++#include "pthread.h" ++#include ++#include ++ ++#define TRACE_ALL 0 ++ ++#define DRM_MODULE "vc4" ++ ++enum conform_optype_e { ++ CONFORM_OPTYPE_NONE, ++ CONFORM_OPTYPE_PLANAR, ++ CONFORM_OPTYPE_RAW_CROP, ++ CONFORM_OPTYPE_RAW_FULL, ++}; ++ ++static const struct { ++ const char * name; ++ enum conform_optype_e op; ++} optable[] = { ++ {"planar", CONFORM_OPTYPE_PLANAR}, ++ {"raw_crop", CONFORM_OPTYPE_RAW_CROP}, ++ {"raw_full", CONFORM_OPTYPE_RAW_FULL}, ++ {NULL, CONFORM_OPTYPE_NONE} ++}; ++ ++static enum conform_optype_e ++op_str_to_enum(const char * const str) ++{ ++ unsigned int i; ++ for (i = 0; optable[i].name != NULL; ++i) { ++ if (strcmp(optable[i].name, str) == 0) ++ break; ++ } ++ return optable[i].op; ++} ++ ++enum conform_outtype_e { ++ CONFORM_OUTTYPE_NONE, ++ CONFORM_OUTTYPE_MD5, ++ CONFORM_OUTTYPE_FILE, ++}; ++ ++static const struct { ++ const char * name; ++ enum conform_optype_e op; ++} outtable[] = { ++ {"md5", CONFORM_OUTTYPE_MD5}, ++ {"file", CONFORM_OUTTYPE_FILE}, ++ {NULL, CONFORM_OPTYPE_NONE} ++}; ++ ++static enum conform_outtype_e ++out_str_to_enum(const char * const str) ++{ ++ unsigned int i; ++ for (i = 0; outtable[i].name != NULL; ++i) { ++ if (strcmp(outtable[i].name, str) == 0) ++ break; ++ } ++ return outtable[i].op; ++} ++ ++ ++// Aux size should only need to be 2, but on a few streams (Hobbit) under FKMS ++// we get initial flicker probably due to dodgy drm timing ++#define AUX_SIZE 3 ++typedef struct conform_display_env_s ++{ ++ AVClass *class; ++ ++ void * line_buf; ++ size_t line_size; ++ ++ struct AVMD5 * frame_md5; ++ struct AVMD5 * md5; ++ ++ int frame_md5_flag; ++ char * optype_str; ++ enum conform_optype_e optype; ++ char * outtype_str; ++ enum conform_outtype_e outtype; ++ ++ unsigned long long foffset; ++ unsigned int fno; ++} conform_display_env_t; ++ ++ ++static int conform_vout_write_trailer(AVFormatContext *s) ++{ ++ conform_display_env_t * const de = s->priv_data; ++ ++#if TRACE_ALL ++ av_log(s, AV_LOG_DEBUG, "%s\n", __func__); ++#endif ++ ++ if (de->md5) { ++ uint8_t m[16]; ++ av_md5_final(de->md5, m); ++ avio_printf(s->pb, "MD5=%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n", ++ m[0], m[1], m[2], m[3], m[4], m[5], m[6], m[7], m[8], m[9], m[10], m[11], m[12], m[13], m[14], m[15]); ++ } ++ ++ return 0; ++} ++ ++static int conform_vout_write_header(AVFormatContext *s) ++{ ++ conform_display_env_t * const de = s->priv_data; ++ ++#if TRACE_ALL ++ av_log(s, AV_LOG_DEBUG, "%s\n", __func__); ++#endif ++ ++ if (de->md5) ++ av_md5_init(de->md5); ++ de->fno = 1; ++ de->foffset = 0; ++ ++ return 0; ++} ++ ++static int start_frame(AVFormatContext * const s, conform_display_env_t * const de, const AVFrame * const sf) ++{ ++ if ((sf->flags & AV_FRAME_FLAG_CORRUPT) != 0) { ++ av_log(s, AV_LOG_WARNING, "Discard corrupt frame: fmt=%d, ts=%" PRId64 "\n", sf->format, sf->pts); ++ if (de->frame_md5) ++ avio_printf(s->pb, "MD5-Frame-%d=*BAD*\n", de->fno); ++ ++de->fno; ++ return -1; ++ } ++ ++ if (de->frame_md5) ++ av_md5_init(de->frame_md5); ++ return 0; ++} ++ ++static void add_block(AVFormatContext * const s, conform_display_env_t * const de, ++ const void * const line, const size_t size) ++{ ++ if (de->frame_md5) ++ av_md5_update(de->frame_md5, line, size); ++ if (de->md5) ++ av_md5_update(de->md5, line, size); ++ else ++ avio_write(s->pb, line, size); ++ de->foffset += size; ++} ++ ++static void end_frame(AVFormatContext * const s, conform_display_env_t * const de) ++{ ++ if (de->frame_md5) { ++ uint8_t m[16]; ++ av_md5_final(de->frame_md5, m); ++ avio_printf(s->pb, "MD5-Frame-%d=%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n", ++ de->fno, ++ m[0], m[1], m[2], m[3], m[4], m[5], m[6], m[7], m[8], m[9], m[10], m[11], m[12], m[13], m[14], m[15]); ++ } ++ ++de->fno; ++} ++ ++static int conform_planar(AVFormatContext * const s, conform_display_env_t * const de, const AVFrame * const sf) ++{ ++ AVFrame * cf = NULL; ++ const AVFrame * f = sf; ++ ++ const AVPixFmtDescriptor * pix_desc = av_pix_fmt_desc_get(sf->format); ++ int is_hw = (pix_desc->flags & AV_PIX_FMT_FLAG_HWACCEL) != 0; ++ enum AVPixelFormat fmt = is_hw ? AV_PIX_FMT_NONE : sf->format; ++ unsigned int i; ++ char * meta = NULL; ++ ++ if (is_hw) { ++ enum AVPixelFormat *xfmts = NULL; ++ av_hwframe_transfer_get_formats(sf->hw_frames_ctx, AV_HWFRAME_TRANSFER_DIRECTION_FROM, &xfmts, 0); ++ fmt = *xfmts; ++ av_free(xfmts); ++ } ++ ++ av_dict_get_string(sf->metadata, &meta, '=', ';'); ++ av_log(s, AV_LOG_DEBUG, "%s: Frame %3d: %#08llx %dx%d crop(ltrb) %zd,%zd,%zd,%zd fmt %s -> %s PTS %"PRId64" [%s]\n", __func__, ++ de->fno, de->foffset, ++ sf->width, sf->height, sf->crop_left, sf->crop_top, sf->crop_right, sf->crop_bottom, ++ av_get_pix_fmt_name(sf->format), av_get_pix_fmt_name(fmt), sf->pts, meta); ++ free(meta); ++ ++ if (start_frame(s, de, sf)) ++ return 0; ++ ++ if (is_hw) { ++ cf = av_frame_alloc(); ++ cf->format = fmt; ++ av_hwframe_transfer_data(cf, sf, AV_HWFRAME_TRANSFER_DIRECTION_FROM); ++ pix_desc = av_pix_fmt_desc_get(cf->format); ++ f = cf; ++ } ++ ++ // This is fully generic - much optimisation possible ++ for (i = 0; i != pix_desc->nb_components; ++i) { ++ const AVComponentDescriptor * const cd = pix_desc->comp + i; ++ const unsigned int srw = ((i == 1 || i == 2) ? pix_desc->log2_chroma_w : 0); ++ const unsigned int rndw = (1 << srw) - 1; ++ const unsigned int srh = ((i == 1 || i == 2) ? pix_desc->log2_chroma_h : 0); ++ const unsigned int rndh = (1 << srh) - 1; ++ const unsigned int srp = cd->shift; ++ const unsigned int bpp = cd->depth > 8 ? 2 : 1; ++ const unsigned int h = (f->height - (f->crop_top + f->crop_bottom) + rndh) >> srh; ++ const unsigned int w = (f->width - (f->crop_left + f->crop_right) + rndw) >> srw; ++ unsigned int y; ++ for (y = 0; y < h; ++y) { ++ const void *const lstart = f->data[cd->plane] + (y + (f->crop_top >> srh)) * f->linesize[cd->plane] + cd->offset + (f->crop_left >> srw) * cd->step; ++ unsigned int x; ++ ++ // If line_buf construction would be a simple copy then bypass ++ if (srp == 0 && cd->step == bpp) { ++ add_block(s, de, lstart, w * bpp); ++ continue; ++ } ++ ++ if (bpp == 1) { ++ uint8_t *d = de->line_buf; ++ const uint8_t *s = lstart; ++ for (x = 0; x != w; ++x) { ++ *d++ = *s >> srp; ++ s += cd->step; ++ } ++ } ++ else { ++ uint16_t *d = de->line_buf; ++ const uint8_t *s = lstart; ++ for (x = 0; x != w; ++x) { ++ *d++ = *(uint16_t*)s >> srp; ++ s += cd->step; ++ } ++ } ++ ++ // We have one line ++ ++ add_block(s, de, de->line_buf, w * bpp); ++ } ++ } ++ ++ end_frame(s, de); ++ ++ av_frame_free(&cf); ++ ++ return 0; ++} ++ ++static int conform_raw(AVFormatContext * const s, conform_display_env_t * const de, const AVFrame * const sf, const int full) ++{ ++ AVFrame * cf = NULL; ++ const AVFrame * f = sf; ++ ++ const AVPixFmtDescriptor * pix_desc = av_pix_fmt_desc_get(sf->format); ++ int is_hw = (pix_desc->flags & AV_PIX_FMT_FLAG_HWACCEL) != 0; ++ unsigned int i; ++ unsigned int planes_done = 0; ++ ++ av_log(s, AV_LOG_DEBUG, "%s: Frame %3d: %#08llx %dx%d crop(ltrb) %zd,%zd,%zd,%zd fmt %s\n", __func__, ++ de->fno, de->foffset, ++ sf->width, sf->height, sf->crop_left, sf->crop_top, sf->crop_right, sf->crop_bottom, ++ av_get_pix_fmt_name(sf->format)); ++ ++ if (start_frame(s, de, sf)) ++ return 0; ++ ++ if (is_hw) { ++ int rv; ++ cf = av_frame_alloc(); ++ if ((rv = av_hwframe_map(cf, sf, AV_HWFRAME_MAP_READ)) != 0) { ++ av_log(s, AV_LOG_ERROR, "Failed to map input frame\n"); ++ return rv; ++ } ++ pix_desc = av_pix_fmt_desc_get(cf->format); ++ f = cf; ++ } ++ ++#if CONFIG_SAND ++ if (av_rpi_is_sand_frame(f)) { ++ // Raw sand doesn't make sense cropped so treat as full ++ // If Single buffer SAND (i.e. a single stripe has Y & C) then dump as ++ // one buffer - otherwise y then C ++ const unsigned int stride1 = av_rpi_sand_frame_stride1(f); ++ const unsigned int w = ((f->width + stride1 - 1) / stride1) * stride1; ++ const unsigned int stride2_y = av_rpi_sand_frame_stride2_y(f); ++ const unsigned int stride2_c = av_rpi_sand_frame_stride2_c(f); ++ if (stride2_c == stride2_y) { ++ // Single buffer ++ av_log(s, AV_LOG_TRACE, "%s: %s single %d x %d\n", __func__, av_get_pix_fmt_name(f->format), w, stride2_y); ++ add_block(s, de, f->data[0], w * stride2_y); ++ } ++ else { ++ // Two buffers ++ av_log(s, AV_LOG_TRACE, "%s: %s double %d x %d,%d\n", __func__, av_get_pix_fmt_name(f->format), w, stride2_y, stride2_c); ++ add_block(s, de, f->data[0], w * stride2_y); ++ add_block(s, de, f->data[1], w * stride2_c); ++ } ++ } ++ else ++#endif ++ if (!full) { ++ for (i = 0; i != pix_desc->nb_components; ++i) { ++ const AVComponentDescriptor * const cd = pix_desc->comp + i; ++ const unsigned int srw = ((i == 1 || i == 2) ? pix_desc->log2_chroma_w : 0); ++ const unsigned int rndw = (1 << srw) - 1; ++ const unsigned int srh = ((i == 1 || i == 2) ? pix_desc->log2_chroma_h : 0); ++ const unsigned int rndh = (1 << srh) - 1; ++ const unsigned int h = (f->height - (f->crop_top + f->crop_bottom) + rndh) >> srh; ++ const unsigned int w = (f->width - (f->crop_left + f->crop_right) + rndw) >> srw; ++ const unsigned int plane_bit = (1U << cd->plane); ++ unsigned int y; ++ ++ if ((planes_done & plane_bit) != 0) ++ continue; ++ planes_done |= plane_bit; ++ ++ for (y = 0; y < h; ++y) { ++ const void *const lstart = f->data[cd->plane] + (y + (f->crop_top >> srh)) * f->linesize[cd->plane] + (f->crop_left >> srw) * cd->step; ++ ++ // We have one line ++ ++ add_block(s, de, lstart, w * cd->step); ++ } ++ } ++ } ++ else { ++ for (i = 0; i != pix_desc->nb_components; ++i) { ++ const AVComponentDescriptor * const cd = pix_desc->comp + i; ++ const unsigned int srh = ((i == 1 || i == 2) ? pix_desc->log2_chroma_h : 0); ++ const unsigned int rndh = (1 << srh) - 1; ++ const unsigned int h = (f->height + rndh) >> srh; ++ const unsigned int plane_bit = (1U << cd->plane); ++ ++ if ((planes_done & plane_bit) != 0) ++ continue; ++ planes_done |= plane_bit; ++ ++ add_block(s, de, f->data[cd->plane], h * f->linesize[cd->plane]); ++ } ++ } ++ ++ end_frame(s, de); ++ ++ av_frame_free(&cf); ++ return 0; ++} ++ ++static int conform_vout_write_packet(AVFormatContext *s, AVPacket *pkt) ++{ ++ conform_display_env_t * const de = s->priv_data; ++ const AVFrame * const sf = (AVFrame *)pkt->data; ++ ++ switch (de->optype) { ++ case CONFORM_OPTYPE_PLANAR: ++ return conform_planar(s, de, sf); ++ case CONFORM_OPTYPE_RAW_CROP: ++ return conform_raw(s, de, sf, 0); ++ case CONFORM_OPTYPE_RAW_FULL: ++ return conform_raw(s, de, sf, 1); ++ default: ++ break; ++ } ++ return 0; ++} ++ ++static int conform_vout_write_frame(AVFormatContext *s, int stream_index, AVFrame **ppframe, ++ unsigned flags) ++{ ++ av_log(s, AV_LOG_ERROR, "%s: NIF: idx=%d, flags=%#x\n", __func__, stream_index, flags); ++ return AVERROR_PATCHWELCOME; ++} ++ ++// deinit is called if init fails so no need to clean up explicity here ++static int conform_vout_init(struct AVFormatContext * s) ++{ ++ conform_display_env_t * const de = s->priv_data; ++ ++ av_log(s, AV_LOG_DEBUG, "<<< %s (%s -> %s)\n", __func__, de->optype_str, de->outtype_str); ++ ++ de->optype = op_str_to_enum(de->optype_str); ++ if (de->optype == CONFORM_OPTYPE_NONE) { ++ av_log(s, AV_LOG_ERROR, "Unknown optype '%s'\n", de->optype_str); ++ return AVERROR_OPTION_NOT_FOUND; ++ } ++ de->outtype = out_str_to_enum(de->outtype_str); ++ if (de->outtype == CONFORM_OUTTYPE_NONE) { ++ av_log(s, AV_LOG_ERROR, "Unknown output '%s'\n", de->optype_str); ++ return AVERROR_OPTION_NOT_FOUND; ++ } ++ ++ de->line_size = (8192 * 4); // 4bpp * 8k seems plenty ++ de->line_buf = av_malloc(de->line_size); ++ if (de->outtype == CONFORM_OUTTYPE_MD5) { ++ de->md5 = av_md5_alloc(); ++ if (de->frame_md5_flag) ++ de->frame_md5 = av_md5_alloc(); ++ } ++ ++ av_log(s, AV_LOG_DEBUG, ">>> %s\n", __func__); ++ ++ return 0; ++} ++ ++static void conform_vout_deinit(struct AVFormatContext * s) ++{ ++ conform_display_env_t * const de = s->priv_data; ++ ++ av_log(s, AV_LOG_DEBUG, "<<< %s\n", __func__); ++ ++ av_freep(&de->line_buf); ++ av_freep(&de->md5); ++ av_freep(&de->frame_md5); ++ ++ av_log(s, AV_LOG_DEBUG, ">>> %s\n", __func__); ++} ++ ++ ++#define OFFSET(x) offsetof(conform_display_env_t, x) ++static const AVOption options[] = { ++ { "conform_frame_md5", "Produce per-frame MD5s as well as final", OFFSET(frame_md5_flag), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, AV_OPT_FLAG_ENCODING_PARAM }, ++ { "conform_out", "Output type ('md5', 'file') [default: md5]", OFFSET(outtype_str), AV_OPT_TYPE_STRING, { .str = "md5" }, 0, 0, AV_OPT_FLAG_ENCODING_PARAM }, ++ { "conform_type", "Type of buffer to work on ('planar', 'raw_crop', 'raw_full') [default: planar]", OFFSET(optype_str), AV_OPT_TYPE_STRING, {.str = "planar"}, 0, 0, AV_OPT_FLAG_ENCODING_PARAM }, ++ { NULL } ++}; ++ ++static const AVClass conform_vid_class = { ++ .class_name = "conform vid muxer", ++ .item_name = av_default_item_name, ++ .option = options, ++ .version = LIBAVUTIL_VERSION_INT, ++ .category = AV_CLASS_CATEGORY_DEVICE_VIDEO_OUTPUT, ++}; ++ ++const FFOutputFormat ff_conform_muxer = { ++ .p = { ++ .name = "conform", ++ .long_name = NULL_IF_CONFIG_SMALL("Video out conformance test helper"), ++ .audio_codec = AV_CODEC_ID_NONE, ++ .video_codec = AV_CODEC_ID_WRAPPED_AVFRAME, ++ .flags = AVFMT_VARIABLE_FPS | AVFMT_NOTIMESTAMPS, ++ .priv_class = &conform_vid_class, ++ }, ++ .priv_data_size = sizeof(conform_display_env_t), ++ .write_header = conform_vout_write_header, ++ .write_packet = conform_vout_write_packet, ++ .write_uncoded_frame = conform_vout_write_frame, ++ .write_trailer = conform_vout_write_trailer, ++ .init = conform_vout_init, ++ .deinit = conform_vout_deinit, ++}; ++ --- a/libavformat/matroskaenc.c +++ b/libavformat/matroskaenc.c -@@ -75,6 +75,10 @@ +@@ -84,6 +84,10 @@ #define IS_WEBM(mkv) (CONFIG_WEBM_MUXER && CONFIG_MATROSKA_MUXER ? \ ((mkv)->mode == MODE_WEBM) : CONFIG_WEBM_MUXER) @@ -17750,7 +17842,7 @@ raspiberry pi support. #define IS_SEEKABLE(pb, mkv) (((pb)->seekable & AVIO_SEEKABLE_NORMAL) && \ !(mkv)->is_live) -@@ -1119,8 +1123,12 @@ static int mkv_assemble_native_codecpriv +@@ -1136,8 +1140,12 @@ static int mkv_assemble_native_codecpriv case AV_CODEC_ID_WAVPACK: return put_wv_codecpriv(dyn_cp, extradata, extradata_size); case AV_CODEC_ID_H264: @@ -17765,7 +17857,7 @@ raspiberry pi support. case AV_CODEC_ID_HEVC: return ff_isom_write_hvcc(dyn_cp, extradata, extradata_size, 0); -@@ -2726,8 +2734,8 @@ static int mkv_check_new_extra_data(AVFo +@@ -2966,8 +2974,8 @@ static int mkv_check_new_extra_data(AVFo } break; #endif @@ -17776,7 +17868,7 @@ raspiberry pi support. case AV_CODEC_ID_AV1: if (side_data_size && mkv->track.bc && !par->extradata_size) { // If the reserved space doesn't suffice, only write -@@ -2739,6 +2747,16 @@ static int mkv_check_new_extra_data(AVFo +@@ -2979,6 +2987,16 @@ static int mkv_check_new_extra_data(AVFo } else if (!par->extradata_size) return AVERROR_INVALIDDATA; break; @@ -17793,7 +17885,7 @@ raspiberry pi support. default: if (side_data_size) av_log(s, AV_LOG_DEBUG, "Ignoring new extradata in a packet for stream %d.\n", pkt->stream_index); -@@ -3171,9 +3189,15 @@ static int mkv_init(struct AVFormatConte +@@ -3440,9 +3458,15 @@ static int mkv_init(struct AVFormatConte track->reformat = mkv_reformat_wavpack; break; case AV_CODEC_ID_H264: @@ -17813,7 +17905,7 @@ raspiberry pi support. break; --- a/libavformat/movenc.c +++ b/libavformat/movenc.c -@@ -6318,6 +6318,7 @@ static int mov_write_single_packet(AVFor +@@ -6906,6 +6906,7 @@ static int mov_write_single_packet(AVFor if (trk->par->codec_id == AV_CODEC_ID_MP4ALS || trk->par->codec_id == AV_CODEC_ID_AAC || trk->par->codec_id == AV_CODEC_ID_AV1 || @@ -17831,7 +17923,7 @@ raspiberry pi support. #include "avformat.h" #include "mpegts.h" #include "internal.h" -@@ -584,8 +585,25 @@ static int rtp_write_packet(AVFormatCont +@@ -586,8 +587,25 @@ static int rtp_write_packet(AVFormatCont ff_rtp_send_vc2hq(s1, pkt->data, size, st->codecpar->field_order != AV_FIELD_PROGRESSIVE ? 1 : 0); break; case AV_CODEC_ID_H264: @@ -17859,7 +17951,7 @@ raspiberry pi support. break; --- a/libavutil/Makefile +++ b/libavutil/Makefile -@@ -72,6 +72,7 @@ HEADERS = adler32.h +@@ -76,6 +76,7 @@ HEADERS = adler32.h rational.h \ replaygain.h \ ripemd.h \ @@ -17867,7 +17959,7 @@ raspiberry pi support. samplefmt.h \ sha.h \ sha512.h \ -@@ -191,6 +192,7 @@ OBJS-$(CONFIG_MACOS_KPERF) +@@ -201,6 +202,7 @@ OBJS-$(CONFIG_MACOS_KPERF) OBJS-$(CONFIG_MEDIACODEC) += hwcontext_mediacodec.o OBJS-$(CONFIG_OPENCL) += hwcontext_opencl.o OBJS-$(CONFIG_QSV) += hwcontext_qsv.o @@ -17875,7 +17967,7 @@ raspiberry pi support. OBJS-$(CONFIG_VAAPI) += hwcontext_vaapi.o OBJS-$(CONFIG_VIDEOTOOLBOX) += hwcontext_videotoolbox.o OBJS-$(CONFIG_VDPAU) += hwcontext_vdpau.o -@@ -211,6 +213,7 @@ SKIPHEADERS-$(CONFIG_D3D11VA) + +@@ -222,6 +224,7 @@ SKIPHEADERS-$(CONFIG_D3D12VA) + SKIPHEADERS-$(CONFIG_DXVA2) += hwcontext_dxva2.h SKIPHEADERS-$(CONFIG_QSV) += hwcontext_qsv.h SKIPHEADERS-$(CONFIG_OPENCL) += hwcontext_opencl.h @@ -17885,12 +17977,10 @@ raspiberry pi support. SKIPHEADERS-$(CONFIG_VDPAU) += hwcontext_vdpau.h --- a/libavutil/aarch64/Makefile +++ b/libavutil/aarch64/Makefile -@@ -1,4 +1,6 @@ - OBJS += aarch64/cpu.o \ - aarch64/float_dsp_init.o \ +@@ -4,3 +4,5 @@ OBJS += aarch64/cpu.o --NEON-OBJS += aarch64/float_dsp_neon.o -+NEON-OBJS += aarch64/float_dsp_neon.o \ + NEON-OBJS += aarch64/float_dsp_neon.o \ + aarch64/tx_float_neon.o \ + aarch64/rpi_sand_neon.o \ + --- /dev/null @@ -18570,7 +18660,7 @@ raspiberry pi support. + --- /dev/null +++ b/libavutil/aarch64/rpi_sand_neon.h -@@ -0,0 +1,59 @@ +@@ -0,0 +1,61 @@ +/* +Copyright (c) 2021 Michael Eiler + @@ -18599,7 +18689,8 @@ raspiberry pi support. +Authors: Michael Eiler +*/ + -+#pragma once ++#ifndef AVUTIL_AARCH64_RPI_SAND_NEON_H ++#define AVUTIL_AARCH64_RPI_SAND_NEON_H + +#ifdef __cplusplus +extern "C" { @@ -18630,6 +18721,7 @@ raspiberry pi support. +} +#endif + ++#endif /* AVCODEC_SAND_NEON_H */ --- a/libavutil/arm/Makefile +++ b/libavutil/arm/Makefile @@ -6,3 +6,4 @@ VFP-OBJS += arm/float_dsp_init_vfp.o @@ -19597,8 +19689,8 @@ raspiberry pi support. +Authors: John Cox +*/ + -+#ifndef AVUTIL_ARM_SAND_NEON_H -+#define AVUTIL_ARM_SAND_NEON_H ++#ifndef AVUTIL_ARM_RPI_SAND_NEON_H ++#define AVUTIL_ARM_RPI_SAND_NEON_H + +void ff_rpi_sand128b_stripe_to_8_10( + uint8_t * dest, // [r0] @@ -19697,9 +19789,9 @@ raspiberry pi support. +#include "rpi_sand_fns.h" +#endif - #if FF_API_OLD_CHANNEL_LAYOUT - #define CHECK_CHANNELS_CONSISTENCY(frame) \ -@@ -875,6 +880,12 @@ int av_frame_apply_cropping(AVFrame *fra + static const AVSideDataDescriptor sd_props[] = { + [AV_FRAME_DATA_PANSCAN] = { "AVPanScan" }, +@@ -1077,6 +1082,12 @@ int av_frame_apply_cropping(AVFrame *fra (frame->crop_top + frame->crop_bottom) >= frame->height) return AVERROR(ERANGE); @@ -19714,7 +19806,7 @@ raspiberry pi support. return AVERROR_BUG; --- a/libavutil/frame.h +++ b/libavutil/frame.h -@@ -940,6 +940,16 @@ int av_frame_apply_cropping(AVFrame *fra +@@ -1037,6 +1037,16 @@ int av_frame_apply_cropping(AVFrame *fra */ const char *av_frame_side_data_name(enum AVFrameSideDataType type); @@ -19729,8 +19821,8 @@ raspiberry pi support. +} + /** - * @} - */ + * @return side data descriptor corresponding to a given side data type, NULL + * when not available. --- a/libavutil/hwcontext_drm.c +++ b/libavutil/hwcontext_drm.c @@ -21,6 +21,7 @@ @@ -19749,18 +19841,17 @@ raspiberry pi support. #include #include "avassert.h" -@@ -38,7 +40,9 @@ - #include "hwcontext_drm.h" - #include "hwcontext_internal.h" +@@ -40,6 +42,9 @@ #include "imgutils.h" -- + #include "mem.h" + +#if CONFIG_SAND +#include "libavutil/rpi_sand_fns.h" +#endif static void drm_device_free(AVHWDeviceContext *hwdev) { -@@ -53,6 +57,11 @@ static int drm_device_create(AVHWDeviceC +@@ -54,6 +59,11 @@ static int drm_device_create(AVHWDeviceC AVDRMDeviceContext *hwctx = hwdev->hwctx; drmVersionPtr version; @@ -19772,7 +19863,7 @@ raspiberry pi support. hwctx->fd = open(device, O_RDWR); if (hwctx->fd < 0) return AVERROR(errno); -@@ -139,6 +148,8 @@ static int drm_map_frame(AVHWFramesConte +@@ -140,6 +150,8 @@ static int drm_map_frame(AVHWFramesConte if (flags & AV_HWFRAME_MAP_WRITE) mmap_prot |= PROT_WRITE; @@ -19781,14 +19872,11 @@ raspiberry pi support. #if HAVE_LINUX_DMA_BUF_H if (flags & AV_HWFRAME_MAP_READ) map->sync_flags |= DMA_BUF_SYNC_READ; -@@ -185,6 +196,23 @@ static int drm_map_frame(AVHWFramesConte +@@ -186,12 +198,34 @@ static int drm_map_frame(AVHWFramesConte dst->width = src->width; dst->height = src->height; -+ dst->crop_top = src->crop_top; -+ dst->crop_bottom = src->crop_bottom; -+ dst->crop_left = src->crop_left; -+ dst->crop_right = src->crop_right; ++ // Crop copied with props + +#if CONFIG_SAND + // Rework for sand frames @@ -19796,16 +19884,31 @@ raspiberry pi support. + // As it stands the sand formats hold stride2 in linesize[3] + // linesize[0] & [1] contain stride1 which is always 128 for everything we do + // * Arguably this should be reworked s.t. stride2 is in linesize[0] & [1] -+ dst->linesize[3] = fourcc_mod_broadcom_param(desc->objects[0].format_modifier); ++ int mod_stride = fourcc_mod_broadcom_param(desc->objects[0].format_modifier); ++ if (mod_stride == 0) { ++ dst->linesize[3] = dst->linesize[0]; ++ dst->linesize[4] = dst->linesize[1]; ++ } ++ else { ++ dst->linesize[3] = mod_stride; ++ dst->linesize[4] = mod_stride; ++ } + dst->linesize[0] = 128; + dst->linesize[1] = 128; -+ // *** Are we sure src->height is actually what we want ??? + } +#endif err = ff_hwframe_map_create(src->hw_frames_ctx, dst, src, - &drm_unmap_frame, map); -@@ -206,16 +234,29 @@ static int drm_transfer_get_formats(AVHW +- &drm_unmap_frame, map); ++ drm_unmap_frame, map); + if (err < 0) + goto fail; + ++ av_frame_copy_props(dst, src); + return 0; + + fail: +@@ -207,16 +241,29 @@ static int drm_transfer_get_formats(AVHW enum AVHWFrameTransferDirection dir, enum AVPixelFormat **formats) { @@ -19841,7 +19944,7 @@ raspiberry pi support. return 0; } -@@ -231,18 +272,62 @@ static int drm_transfer_data_from(AVHWFr +@@ -232,18 +279,62 @@ static int drm_transfer_data_from(AVHWFr map = av_frame_alloc(); if (!map) return AVERROR(ENOMEM); @@ -19870,8 +19973,6 @@ raspiberry pi support. +#endif +#if CONFIG_SAND + if (av_rpi_is_sand_frame(map)) { -+ // Preserve crop - later ffmpeg code assumes that we have in that it -+ // overwrites any crop that we create with the old values + const unsigned int w = FFMIN(dst->width, map->width); + const unsigned int h = FFMIN(dst->height, map->height); + @@ -19889,15 +19990,17 @@ raspiberry pi support. + + dst->width = w; + dst->height = h; ++ // Cropping restored as part of props + } + else +#endif + { -+ // Kludge mapped h/w s.t. frame_copy works -+ map->width = dst->width; -+ map->height = dst->height; ++ dst->width = map->width; ++ dst->height = map->height; + err = av_frame_copy(dst, map); + } ++ ++ av_frame_copy_props(dst, src); - err = av_frame_copy(dst, map); if (err) @@ -19908,7 +20011,7 @@ raspiberry pi support. err = 0; fail: -@@ -257,7 +342,10 @@ static int drm_transfer_data_to(AVHWFram +@@ -258,7 +349,10 @@ static int drm_transfer_data_to(AVHWFram int err; if (src->width > hwfc->width || src->height > hwfc->height) @@ -19919,9 +20022,18 @@ raspiberry pi support. map = av_frame_alloc(); if (!map) +@@ -288,7 +382,7 @@ static int drm_map_from(AVHWFramesContex + { + int err; + +- if (hwfc->sw_format != dst->format) ++ if (hwfc->sw_format != dst->format && dst->format != AV_PIX_FMT_NONE) + return AVERROR(ENOSYS); + + err = drm_map_frame(hwfc, dst, src, flags); --- a/libavutil/hwcontext_vulkan.c +++ b/libavutil/hwcontext_vulkan.c -@@ -57,6 +57,14 @@ +@@ -72,6 +72,14 @@ #define CHECK_CU(x) FF_CUDA_CHECK_DL(cuda_cu, cu, x) #endif @@ -19933,12 +20045,12 @@ raspiberry pi support. +#define VK_EXT_VIDEO_DECODE_H265_EXTENSION_NAME "VK_EXT_video_decode_h265" +#endif + - typedef struct VulkanQueueCtx { - VkFence fence; - VkQueue queue; + typedef struct VulkanDevicePriv { + /** + * The public AVVulkanDeviceContext. See hwcontext_vulkan.h for it. --- a/libavutil/pixdesc.c +++ b/libavutil/pixdesc.c -@@ -2491,6 +2491,50 @@ static const AVPixFmtDescriptor av_pix_f +@@ -2791,6 +2791,50 @@ static const AVPixFmtDescriptor av_pix_f }, .flags = AV_PIX_FMT_FLAG_PLANAR, }, @@ -19991,10 +20103,10 @@ raspiberry pi support. static const char * const color_range_names[] = { --- a/libavutil/pixfmt.h +++ b/libavutil/pixfmt.h -@@ -349,6 +349,14 @@ enum AVPixelFormat { +@@ -439,6 +439,15 @@ enum AVPixelFormat { + */ + AV_PIX_FMT_D3D12, - AV_PIX_FMT_Y210BE, ///< packed YUV 4:2:2 like YUYV422, 20bpp, data in the high bits, big-endian - AV_PIX_FMT_Y210LE, ///< packed YUV 4:2:2 like YUYV422, 20bpp, data in the high bits, little-endian +// RPI - not on ifdef so can be got at by calling progs +// #define so code that uses this can know it is there +#define AVUTIL_HAVE_PIX_FMT_SAND 1 @@ -20003,11 +20115,12 @@ raspiberry pi support. + AV_PIX_FMT_SAND64_16, ///< 4:2:0 16-bit 64x*Y stripe, 32x*UV stripe, then next x stripe, mysterious padding + AV_PIX_FMT_RPI4_8, + AV_PIX_FMT_RPI4_10, ++ + 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 + }; - AV_PIX_FMT_X2RGB10LE, ///< packed RGB 10:10:10, 30bpp, (msb)2X 10R 10G 10B(lsb), little-endian, X=unused/undefined - AV_PIX_FMT_X2RGB10BE, ///< packed RGB 10:10:10, 30bpp, (msb)2X 10R 10G 10B(lsb), big-endian, X=unused/undefined --- /dev/null -+++ b/libavutil/rpi_sand_fn_pw.h ++++ b/libavutil/rpi_sand_fn_pw.c @@ -0,0 +1,227 @@ +/* +Copyright (c) 2018 Raspberry Pi (Trading) Ltd. @@ -20238,7 +20351,7 @@ raspiberry pi support. + --- /dev/null +++ b/libavutil/rpi_sand_fns.c -@@ -0,0 +1,447 @@ +@@ -0,0 +1,449 @@ +/* +Copyright (c) 2018 Raspberry Pi (Trading) Ltd. +All rights reserved. @@ -20288,11 +20401,11 @@ raspiberry pi support. +#endif + +#define PW 1 -+#include "rpi_sand_fn_pw.h" ++#include "rpi_sand_fn_pw.c" +#undef PW + +#define PW 2 -+#include "rpi_sand_fn_pw.h" ++#include "rpi_sand_fn_pw.c" +#undef PW + +#if 1 @@ -20600,6 +20713,8 @@ raspiberry pi support. + const int h = av_frame_cropped_height(src); + const int x = src->crop_left; + const int y = src->crop_top; ++ const unsigned int stride2_y = av_rpi_sand_frame_stride2_y(src); ++ const unsigned int stride2_c = av_rpi_sand_frame_stride2_c(src); + + // We will crop as part of the conversion + dst->crop_top = 0; @@ -20614,22 +20729,22 @@ raspiberry pi support. + case AV_PIX_FMT_YUV420P: + av_rpi_sand_to_planar_y8(dst->data[0], dst->linesize[0], + src->data[0], -+ av_rpi_sand_frame_stride1(src), av_rpi_sand_frame_stride2(src), ++ av_rpi_sand_frame_stride1(src), stride2_y, + x, y, w, h); + av_rpi_sand_to_planar_c8(dst->data[1], dst->linesize[1], + dst->data[2], dst->linesize[2], + src->data[1], -+ av_rpi_sand_frame_stride1(src), av_rpi_sand_frame_stride2(src), ++ av_rpi_sand_frame_stride1(src), stride2_c, + x/2, y/2, w/2, h/2); + break; + case AV_PIX_FMT_NV12: + av_rpi_sand_to_planar_y8(dst->data[0], dst->linesize[0], + src->data[0], -+ av_rpi_sand_frame_stride1(src), av_rpi_sand_frame_stride2(src), ++ av_rpi_sand_frame_stride1(src), stride2_y, + x, y, w, h); + av_rpi_sand_to_planar_y8(dst->data[1], dst->linesize[1], + src->data[1], -+ av_rpi_sand_frame_stride1(src), av_rpi_sand_frame_stride2(src), ++ av_rpi_sand_frame_stride1(src), stride2_c, + x/2, y/2, w, h/2); + break; + default: @@ -20641,12 +20756,12 @@ raspiberry pi support. + case AV_PIX_FMT_YUV420P10: + av_rpi_sand_to_planar_y16(dst->data[0], dst->linesize[0], + src->data[0], -+ av_rpi_sand_frame_stride1(src), av_rpi_sand_frame_stride2(src), ++ av_rpi_sand_frame_stride1(src), stride2_y, + x*2, y, w*2, h); + av_rpi_sand_to_planar_c16(dst->data[1], dst->linesize[1], + dst->data[2], dst->linesize[2], + src->data[1], -+ av_rpi_sand_frame_stride1(src), av_rpi_sand_frame_stride2(src), ++ av_rpi_sand_frame_stride1(src), stride2_c, + x, y/2, w, h/2); + break; + default: @@ -20658,22 +20773,22 @@ raspiberry pi support. + case AV_PIX_FMT_YUV420P10: + av_rpi_sand30_to_planar_y16(dst->data[0], dst->linesize[0], + src->data[0], -+ av_rpi_sand_frame_stride1(src), av_rpi_sand_frame_stride2(src), ++ av_rpi_sand_frame_stride1(src), stride2_y, + x, y, w, h); + av_rpi_sand30_to_planar_c16(dst->data[1], dst->linesize[1], + dst->data[2], dst->linesize[2], + src->data[1], -+ av_rpi_sand_frame_stride1(src), av_rpi_sand_frame_stride2(src), ++ av_rpi_sand_frame_stride1(src), stride2_c, + x/2, y/2, w/2, h/2); + break; + case AV_PIX_FMT_NV12: + av_rpi_sand30_to_planar_y8(dst->data[0], dst->linesize[0], + src->data[0], -+ av_rpi_sand_frame_stride1(src), av_rpi_sand_frame_stride2(src), ++ av_rpi_sand_frame_stride1(src), stride2_y, + x, y, w, h); + av_rpi_sand30_to_planar_y8(dst->data[1], dst->linesize[1], + src->data[1], -+ av_rpi_sand_frame_stride1(src), av_rpi_sand_frame_stride2(src), ++ av_rpi_sand_frame_stride1(src), stride2_c, + x/2, y/2, w, h/2); + break; + default: @@ -20688,7 +20803,7 @@ raspiberry pi support. +} --- /dev/null +++ b/libavutil/rpi_sand_fns.h -@@ -0,0 +1,188 @@ +@@ -0,0 +1,157 @@ +/* +Copyright (c) 2018 Raspberry Pi (Trading) Ltd. +All rights reserved. @@ -20718,8 +20833,8 @@ raspiberry pi support. +Authors: John Cox +*/ + -+#ifndef AVUTIL_RPI_SAND_FNS -+#define AVUTIL_RPI_SAND_FNS ++#ifndef AVUTIL_RPI_SAND_FNS_H ++#define AVUTIL_RPI_SAND_FNS_H + +#include "libavutil/frame.h" + @@ -20804,11 +20919,15 @@ raspiberry pi support. +#endif +} + -+static inline unsigned int av_rpi_sand_frame_stride2(const AVFrame * const frame) ++static inline unsigned int av_rpi_sand_frame_stride2_y(const AVFrame * const frame) +{ + return frame->linesize[3]; +} + ++static inline unsigned int av_rpi_sand_frame_stride2_c(const AVFrame * const frame) ++{ ++ return frame->linesize[4]; ++} + +static inline int av_rpi_is_sand_format(const int format) +{ @@ -20840,49 +20959,14 @@ raspiberry pi support. + return av_rpi_is_sand8_frame(frame) ? 0 : 1; +} + -+// If x is measured in bytes (not pixels) then this works for sand64_16 as -+// well as sand128 - but in the general case we work that out -+ -+static inline unsigned int av_rpi_sand_frame_off_y(const AVFrame * const frame, const unsigned int x_y, const unsigned int y) -+{ -+ const unsigned int stride1 = av_rpi_sand_frame_stride1(frame); -+ const unsigned int stride2 = av_rpi_sand_frame_stride2(frame); -+ const unsigned int x = x_y << av_rpi_sand_frame_xshl(frame); -+ const unsigned int x1 = x & (stride1 - 1); -+ const unsigned int x2 = x ^ x1; -+ -+ return x1 + stride1 * y + stride2 * x2; -+} -+ -+static inline unsigned int av_rpi_sand_frame_off_c(const AVFrame * const frame, const unsigned int x_c, const unsigned int y_c) -+{ -+ const unsigned int stride1 = av_rpi_sand_frame_stride1(frame); -+ const unsigned int stride2 = av_rpi_sand_frame_stride2(frame); -+ const unsigned int x = x_c << (av_rpi_sand_frame_xshl(frame) + 1); -+ const unsigned int x1 = x & (stride1 - 1); -+ const unsigned int x2 = x ^ x1; -+ -+ return x1 + stride1 * y_c + stride2 * x2; -+} -+ -+static inline uint8_t * av_rpi_sand_frame_pos_y(const AVFrame * const frame, const unsigned int x, const unsigned int y) -+{ -+ return frame->data[0] + av_rpi_sand_frame_off_y(frame, x, y); -+} -+ -+static inline uint8_t * av_rpi_sand_frame_pos_c(const AVFrame * const frame, const unsigned int x, const unsigned int y) -+{ -+ return frame->data[1] + av_rpi_sand_frame_off_c(frame, x, y); -+} -+ +#endif + --- a/libswscale/aarch64/rgb2rgb.c +++ b/libswscale/aarch64/rgb2rgb.c -@@ -30,6 +30,12 @@ - void ff_interleave_bytes_neon(const uint8_t *src1, const uint8_t *src2, - uint8_t *dest, int width, int height, - int src1Stride, int src2Stride, int dstStride); +@@ -57,6 +57,12 @@ void ff_interleave_bytes_neon(const uint + void ff_deinterleave_bytes_neon(const uint8_t *src, uint8_t *dst1, uint8_t *dst2, + int width, int height, int srcStride, + int dst1Stride, int dst2Stride); +void ff_bgr24toyv12_aarch64(const uint8_t *src, uint8_t *ydst, uint8_t *udst, + uint8_t *vdst, int width, int height, int lumStride, + int chromStride, int srcStride, int32_t *rgb2yuv); @@ -20892,17 +20976,17 @@ raspiberry pi support. av_cold void rgb2rgb_init_aarch64(void) { -@@ -37,5 +43,7 @@ av_cold void rgb2rgb_init_aarch64(void) - - if (have_neon(cpu_flags)) { +@@ -66,5 +72,7 @@ av_cold void rgb2rgb_init_aarch64(void) + ff_rgb24toyv12 = rgb24toyv12; interleaveBytes = ff_interleave_bytes_neon; + deinterleaveBytes = ff_deinterleave_bytes_neon; + ff_rgb24toyv12 = ff_rgb24toyv12_aarch64; + ff_bgr24toyv12 = ff_bgr24toyv12_aarch64; } } --- a/libswscale/aarch64/rgb2rgb_neon.S +++ b/libswscale/aarch64/rgb2rgb_neon.S -@@ -77,3 +77,359 @@ function ff_interleave_bytes_neon, expor +@@ -296,3 +296,359 @@ function ff_deinterleave_bytes_neon, exp 0: ret endfunc @@ -21308,7 +21392,7 @@ raspiberry pi support. /** * Height should be a multiple of 2 and width should be a multiple of 16. -@@ -128,6 +131,26 @@ extern void (*ff_rgb24toyv12)(const uint +@@ -126,6 +129,26 @@ extern void (*ff_rgb24toyv12)(const uint int width, int height, int lumStride, int chromStride, int srcStride, int32_t *rgb2yuv); @@ -21337,30 +21421,63 @@ raspiberry pi support. --- a/libswscale/rgb2rgb_template.c +++ b/libswscale/rgb2rgb_template.c -@@ -646,13 +646,14 @@ static inline void uyvytoyv12_c(const ui - * others are ignored in the C version. - * FIXME: Write HQ version. - */ --void ff_rgb24toyv12_c(const uint8_t *src, uint8_t *ydst, uint8_t *udst, +@@ -639,6 +639,12 @@ static inline void uyvytoyv12_c(const ui + } + } + ++#if 0 ++// This is the upstream version of this function. It has centre positioned ++// chroma rather than our simpler top-left and only covers one arrangement ++// of RGB. Left here for reference and to fix some ugly diffing by git. ++// If this version is wanted - lose the entire patchset ++ + /** + * width should be a multiple of 2. + * (If this is a problem for anyone then tell me, and I will fix it.) +@@ -705,6 +711,237 @@ void ff_rgb24toyv12_c(const uint8_t *src + vdst += chromStride; + } + } ++#endif ++ ++/** ++ * Chrominance data is only taken from every second line, ++ * others are ignored. This matches the ARM64 asm. ++ */ +static void rgb24toyv12_x(const uint8_t *src, uint8_t *ydst, uint8_t *udst, - uint8_t *vdst, int width, int height, int lumStride, -- int chromStride, int srcStride, int32_t *rgb2yuv) ++ uint8_t *vdst, int width, int height, int lumStride, + int chromStride, int srcStride, int32_t *rgb2yuv, + const uint8_t x[9]) - { -- int32_t ry = rgb2yuv[RY_IDX], gy = rgb2yuv[GY_IDX], by = rgb2yuv[BY_IDX]; -- int32_t ru = rgb2yuv[RU_IDX], gu = rgb2yuv[GU_IDX], bu = rgb2yuv[BU_IDX]; -- int32_t rv = rgb2yuv[RV_IDX], gv = rgb2yuv[GV_IDX], bv = rgb2yuv[BV_IDX]; ++{ + int32_t ry = rgb2yuv[x[0]], gy = rgb2yuv[x[1]], by = rgb2yuv[x[2]]; + int32_t ru = rgb2yuv[x[3]], gu = rgb2yuv[x[4]], bu = rgb2yuv[x[5]]; + int32_t rv = rgb2yuv[x[6]], gv = rgb2yuv[x[7]], bv = rgb2yuv[x[8]]; - int y; - const int chromWidth = width >> 1; - -@@ -678,6 +679,19 @@ void ff_rgb24toyv12_c(const uint8_t *src - Y = ((ry * r + gy * g + by * b) >> RGB2YUV_SHIFT) + 16; - ydst[2 * i + 1] = Y; - } ++ int y; ++ const int chromWidth = width >> 1; ++ ++ for (y = 0; y < height; y += 2) { ++ int i; ++ ++ for (i = 0; i < chromWidth; i++) { ++ unsigned int b = src[6 * i + 0]; ++ unsigned int g = src[6 * i + 1]; ++ unsigned int r = src[6 * i + 2]; ++ ++ unsigned int Y = ((ry * r + gy * g + by * b) >> RGB2YUV_SHIFT) + 16; ++ unsigned int V = ((rv * r + gv * g + bv * b) >> RGB2YUV_SHIFT) + 128; ++ unsigned int U = ((ru * r + gu * g + bu * b) >> RGB2YUV_SHIFT) + 128; ++ ++ udst[i] = U; ++ vdst[i] = V; ++ ydst[2 * i] = Y; ++ ++ b = src[6 * i + 3]; ++ g = src[6 * i + 4]; ++ r = src[6 * i + 5]; ++ ++ Y = ((ry * r + gy * g + by * b) >> RGB2YUV_SHIFT) + 16; ++ ydst[2 * i + 1] = Y; ++ } + if ((width & 1) != 0) { + unsigned int b = src[6 * i + 0]; + unsigned int g = src[6 * i + 1]; @@ -21374,13 +21491,28 @@ raspiberry pi support. + vdst[i] = V; + ydst[2 * i] = Y; + } - ydst += lumStride; - src += srcStride; - -@@ -700,6 +714,15 @@ void ff_rgb24toyv12_c(const uint8_t *src - Y = ((ry * r + gy * g + by * b) >> RGB2YUV_SHIFT) + 16; - ydst[2 * i + 1] = Y; - } ++ ydst += lumStride; ++ src += srcStride; ++ ++ if (y+1 == height) ++ break; ++ ++ for (i = 0; i < chromWidth; i++) { ++ unsigned int b = src[6 * i + 0]; ++ unsigned int g = src[6 * i + 1]; ++ unsigned int r = src[6 * i + 2]; ++ ++ unsigned int Y = ((ry * r + gy * g + by * b) >> RGB2YUV_SHIFT) + 16; ++ ++ ydst[2 * i] = Y; ++ ++ b = src[6 * i + 3]; ++ g = src[6 * i + 4]; ++ r = src[6 * i + 5]; ++ ++ Y = ((ry * r + gy * g + by * b) >> RGB2YUV_SHIFT) + 16; ++ ydst[2 * i + 1] = Y; ++ } + if ((width & 1) != 0) { + unsigned int b = src[6 * i + 0]; + unsigned int g = src[6 * i + 1]; @@ -21390,13 +21522,13 @@ raspiberry pi support. + + ydst[2 * i] = Y; + } - udst += chromStride; - vdst += chromStride; - ydst += lumStride; -@@ -707,6 +730,147 @@ void ff_rgb24toyv12_c(const uint8_t *src - } - } - ++ udst += chromStride; ++ vdst += chromStride; ++ ydst += lumStride; ++ src += srcStride; ++ } ++} ++ +static const uint8_t x_rgb[9] = { + RY_IDX, GY_IDX, BY_IDX, + RU_IDX, GU_IDX, BU_IDX, @@ -21537,11 +21669,10 @@ raspiberry pi support. + rgbxtoyv12_x(src + 1, ydst, udst, vdst, width, height, lumStride, chromStride, srcStride, rgb2yuv, x_bgr); +} + -+ + static void interleaveBytes_c(const uint8_t *src1, const uint8_t *src2, uint8_t *dest, int width, int height, - int src1Stride, int src2Stride, int dstStride) -@@ -980,6 +1144,11 @@ static av_cold void rgb2rgb_init_c(void) +@@ -979,6 +1216,11 @@ static av_cold void rgb2rgb_init_c(void) yuy2toyv12 = yuy2toyv12_c; planar2x = planar2x_c; ff_rgb24toyv12 = ff_rgb24toyv12_c; @@ -21555,7 +21686,7 @@ raspiberry pi support. vu9_to_vu12 = vu9_to_vu12_c; --- a/libswscale/swscale_unscaled.c +++ b/libswscale/swscale_unscaled.c -@@ -1654,6 +1654,91 @@ static int bgr24ToYv12Wrapper(SwsContext +@@ -1698,6 +1698,91 @@ static int bgr24ToYv12Wrapper(SwsContext return srcSliceH; } @@ -21647,7 +21778,7 @@ raspiberry pi support. static int yvu9ToYv12Wrapper(SwsContext *c, const uint8_t *src[], int srcStride[], int srcSliceY, int srcSliceH, uint8_t *dst[], int dstStride[]) -@@ -1977,7 +2062,6 @@ void ff_get_unscaled_swscale(SwsContext +@@ -2021,7 +2106,6 @@ void ff_get_unscaled_swscale(SwsContext const enum AVPixelFormat dstFormat = c->dstFormat; const int flags = c->flags; const int dstH = c->dstH; @@ -21655,7 +21786,7 @@ raspiberry pi support. int needsDither; needsDither = isAnyRGB(dstFormat) && -@@ -2035,8 +2119,34 @@ void ff_get_unscaled_swscale(SwsContext +@@ -2079,8 +2163,34 @@ void ff_get_unscaled_swscale(SwsContext /* bgr24toYV12 */ if (srcFormat == AV_PIX_FMT_BGR24 && (dstFormat == AV_PIX_FMT_YUV420P || dstFormat == AV_PIX_FMT_YUVA420P) && @@ -21701,7 +21832,7 @@ raspiberry pi support. #undef HAVE_AV_CONFIG_H #include "libavutil/cpu.h" -@@ -78,6 +79,15 @@ struct Results { +@@ -98,6 +99,15 @@ struct Results { uint32_t crc; }; @@ -21717,7 +21848,7 @@ raspiberry pi support. // test by ref -> src -> dst -> out & compare out against ref // ref & out are YV12 static int doTest(const uint8_t * const ref[4], int refStride[4], int w, int h, -@@ -174,7 +184,7 @@ static int doTest(const uint8_t * const +@@ -213,7 +223,7 @@ static int doTest(const uint8_t * const goto end; } @@ -21726,7 +21857,7 @@ raspiberry pi support. desc_src->name, srcW, srcH, desc_dst->name, dstW, dstH, flags); -@@ -182,6 +192,17 @@ static int doTest(const uint8_t * const +@@ -221,6 +231,17 @@ static int doTest(const uint8_t * const sws_scale(dstContext, (const uint8_t * const*)src, srcStride, 0, srcH, dst, dstStride); @@ -21744,7 +21875,7 @@ raspiberry pi support. for (i = 0; i < 4 && dstStride[i]; i++) crc = av_crc(av_crc_get_table(AV_CRC_32_IEEE), crc, dst[i], dstStride[i] * dstH); -@@ -355,56 +376,78 @@ static int fileTest(const uint8_t * cons +@@ -413,30 +434,31 @@ static int fileTest(const uint8_t * cons return 0; } @@ -21785,6 +21916,10 @@ raspiberry pi support. for (i = 1; i < argc; i += 2) { + const char * const arg2 = argv[i+1]; + + if (!strcmp(argv[i], "-help") || !strcmp(argv[i], "--help")) { + fprintf(stderr, + "swscale [options...]\n" +@@ -459,29 +481,50 @@ int main(int argc, char **argv) if (argv[i][0] != '-' || i + 1 == argc) goto bad_option; if (!strcmp(argv[i], "-ref")) { @@ -21842,10 +21977,10 @@ raspiberry pi support. + fprintf(stderr, "bad time repetitions '%s'\n", arg2); return -1; } - } else { -@@ -414,15 +457,34 @@ bad_option: - } - } + } else if (!strcmp(argv[i], "-p")) { +@@ -495,15 +538,34 @@ bad_option: + + ff_sfc64_init(&prng_state, 0, 0, 0, 12); - sws = sws_getContext(W / 12, H / 12, AV_PIX_FMT_RGB32, W, H, + S = (W + 15) & ~15; @@ -21881,7 +22016,7 @@ raspiberry pi support. if (res < 0 || res != H) { res = -1; goto error; -@@ -431,10 +493,10 @@ bad_option: +@@ -512,10 +574,10 @@ bad_option: av_free(rgb_data); if(fp) { @@ -22039,88 +22174,88 @@ raspiberry pi support. --- /dev/null +++ b/pi-util/TESTMESA.txt @@ -0,0 +1,82 @@ -+# Setup & Build instructions for testing Argon30 mesa support (on Pi4) -+ -+# These assume that the drm_mmal test for Sand8 has been built on this Pi -+# as build relies on many of the same files -+ -+# 1st get everything required to build ffmpeg -+# If sources aren't already enabled on your Pi then enable them -+sudo su -+sed "s/#deb-src/deb-src/" /etc/apt/sources.list > /tmp/sources.list -+sed "s/#deb-src/deb-src/" /etc/apt/sources.list.d/raspi.list > /tmp/raspi.list -+mv /tmp/sources.list /etc/apt/ -+mv /tmp/raspi.list /etc/apt/sources.list.d/ -+apt update -+ -+# Get dependancies -+sudo apt build-dep ffmpeg -+ -+sudo apt install meson libepoxy-dev libxcb-dri3-dev libxcb1-dev libx11-dev libx11-xcb-dev libdrm-dev -+ -+# Enable H265 V4L2 request decoder -+sudo su -+echo dtoverlay=rpivid-v4l2 >> /boot/config.txt -+# You may also want to add more CMA if you are going to try 4k videos -+# Change the dtoverlay=vc4-fkms-v3d line in config.txt to read -+# dtoverlay=vc4-fkms-v3d,cma-512 -+reboot -+# Check it has turned up -+ls -la /dev/video* -+# This should include video19 -+# crw-rw----+ 1 root video 81, 7 Aug 4 17:25 /dev/video19 -+ -+# Currently on the Pi the linux headers from the debian distro don't match -+# the kernel that we ship and we need to update them - hopefully this step -+# will be unneeded in the future -+sudo apt install git bc bison flex libssl-dev make -+git clone --depth=1 https://github.com/raspberrypi/linux --branch rpi-5.10.y -+cd linux -+KERNEL=kernel7l -+make bcm2711_defconfig -+make headers_install -+sudo cp -r usr/include/linux /usr/include -+cd .. -+ -+# Config - this builds a staticly linked ffmpeg which is easier for testing -+pi-util/conf_native.sh --noshared -+ -+# Build (this is a bit dull) -+# If you want to poke the source the libavdevice/egl_vout.c contains the -+# output code - -+cd out/armv7-static-rel -+ -+# Check that you have actually configured V4L2 request -+grep HEVC_V4L2REQUEST config.h -+# You are hoping for -+# #define CONFIG_HEVC_V4L2REQUEST_HWACCEL 1 -+# if you get 0 then the config has failed -+ -+make -j6 -+ -+# Grab test streams -+wget http://www.jell.yfish.us/media/jellyfish-3-mbps-hd-h264.mkv -+wget http://www.jell.yfish.us/media/jellyfish-3-mbps-hd-hevc.mkv -+wget http://www.jell.yfish.us/media/jellyfish-3-mbps-hd-hevc-10bit.mkv -+ -+# Test i420 output (works currently) -+./ffmpeg -no_cvt_hw -vcodec h264_v4l2m2m -i jellyfish-3-mbps-hd-h264.mkv -f vout_egl - -+ -+# Test Sand8 output - doesn't currently work but should once you have -+# Sand8 working in drm_mmal. I can't guarantee that this will work as -+# I can't test this path with a known working format, but the debug looks -+# good. If this doesn't work & drm_mmal does with sand8 then come back to me -+# The "show_all 1" forces vout to display every frame otherwise it drops any -+# frame that would cause it to block -+./ffmpeg -no_cvt_hw -hwaccel drm -vcodec hevc -i jellyfish-3-mbps-hd-hevc.mkv -show_all 1 -f vout_egl - -+ -+# Test Sand30 - doesn't currently work -+# (Beware that when FFmpeg errors out it often leaves your teminal window -+# in a state where you need to reset it) -+./ffmpeg -no_cvt_hw -hwaccel drm -vcodec hevc -i jellyfish-3-mbps-hd-hevc-10bit.mkv -f vout_egl - -+ -+ -+ ++# Setup & Build instructions for testing Argon30 mesa support (on Pi4) ++ ++# These assume that the drm_mmal test for Sand8 has been built on this Pi ++# as build relies on many of the same files ++ ++# 1st get everything required to build ffmpeg ++# If sources aren't already enabled on your Pi then enable them ++sudo su ++sed "s/#deb-src/deb-src/" /etc/apt/sources.list > /tmp/sources.list ++sed "s/#deb-src/deb-src/" /etc/apt/sources.list.d/raspi.list > /tmp/raspi.list ++mv /tmp/sources.list /etc/apt/ ++mv /tmp/raspi.list /etc/apt/sources.list.d/ ++apt update ++ ++# Get dependancies ++sudo apt build-dep ffmpeg ++ ++sudo apt install meson libepoxy-dev libxcb-dri3-dev libxcb1-dev libx11-dev libx11-xcb-dev libdrm-dev ++ ++# Enable H265 V4L2 request decoder ++sudo su ++echo dtoverlay=rpivid-v4l2 >> /boot/config.txt ++# You may also want to add more CMA if you are going to try 4k videos ++# Change the dtoverlay=vc4-fkms-v3d line in config.txt to read ++# dtoverlay=vc4-fkms-v3d,cma-512 ++reboot ++# Check it has turned up ++ls -la /dev/video* ++# This should include video19 ++# crw-rw----+ 1 root video 81, 7 Aug 4 17:25 /dev/video19 ++ ++# Currently on the Pi the linux headers from the debian distro don't match ++# the kernel that we ship and we need to update them - hopefully this step ++# will be unneeded in the future ++sudo apt install git bc bison flex libssl-dev make ++git clone --depth=1 https://github.com/raspberrypi/linux --branch rpi-5.10.y ++cd linux ++KERNEL=kernel7l ++make bcm2711_defconfig ++make headers_install ++sudo cp -r usr/include/linux /usr/include ++cd .. ++ ++# Config - this builds a staticly linked ffmpeg which is easier for testing ++pi-util/conf_native.sh --noshared ++ ++# Build (this is a bit dull) ++# If you want to poke the source the libavdevice/egl_vout.c contains the ++# output code - ++cd out/armv7-static-rel ++ ++# Check that you have actually configured V4L2 request ++grep HEVC_V4L2REQUEST config.h ++# You are hoping for ++# #define CONFIG_HEVC_V4L2REQUEST_HWACCEL 1 ++# if you get 0 then the config has failed ++ ++make -j6 ++ ++# Grab test streams ++wget http://www.jell.yfish.us/media/jellyfish-3-mbps-hd-h264.mkv ++wget http://www.jell.yfish.us/media/jellyfish-3-mbps-hd-hevc.mkv ++wget http://www.jell.yfish.us/media/jellyfish-3-mbps-hd-hevc-10bit.mkv ++ ++# Test i420 output (works currently) ++./ffmpeg -no_cvt_hw -vcodec h264_v4l2m2m -i jellyfish-3-mbps-hd-h264.mkv -f vout_egl - ++ ++# Test Sand8 output - doesn't currently work but should once you have ++# Sand8 working in drm_mmal. I can't guarantee that this will work as ++# I can't test this path with a known working format, but the debug looks ++# good. If this doesn't work & drm_mmal does with sand8 then come back to me ++# The "show_all 1" forces vout to display every frame otherwise it drops any ++# frame that would cause it to block ++./ffmpeg -no_cvt_hw -hwaccel drm -vcodec hevc -i jellyfish-3-mbps-hd-hevc.mkv -show_all 1 -f vout_egl - ++ ++# Test Sand30 - doesn't currently work ++# (Beware that when FFmpeg errors out it often leaves your teminal window ++# in a state where you need to reset it) ++./ffmpeg -no_cvt_hw -hwaccel drm -vcodec hevc -i jellyfish-3-mbps-hd-hevc-10bit.mkv -f vout_egl - ++ ++ ++ --- /dev/null +++ b/pi-util/clean_usr_libs.sh @@ -0,0 +1,42 @@ @@ -22217,498 +22352,498 @@ raspiberry pi support. --- /dev/null +++ b/pi-util/conf_h265.2016.csv @@ -0,0 +1,195 @@ -+1,HEVC_v1/AMP_A_Samsung_7,AMP_A_Samsung_7.bin,AMP_A_Samsung_7.md5,8 -+1,HEVC_v1/AMP_B_Samsung_7,AMP_B_Samsung_7.bin,AMP_B_Samsung_7.md5,8 -+1,HEVC_v1/AMP_D_Hisilicon_3,AMP_D_Hisilicon.bit,AMP_D_Hisilicon_3.yuv.md5,8 -+1,HEVC_v1/AMP_E_Hisilicon_3,AMP_E_Hisilicon.bit,AMP_E_Hisilicon_3.yuv.md5,8 -+1,HEVC_v1/AMP_F_Hisilicon_3,AMP_F_Hisilicon_3.bit,AMP_F_Hisilicon_3.yuv.md5,8 -+1,HEVC_v1/AMVP_A_MTK_4,AMVP_A_MTK_4.bit,AMVP_A_MTK_4.md5,8 -+1,HEVC_v1/AMVP_B_MTK_4,AMVP_B_MTK_4.bit,AMVP_B_MTK_4.md5,8 -+1,HEVC_v1/AMVP_C_Samsung_7,AMVP_C_Samsung_7.bin,AMVP_C_Samsung_7.md5,8 -+1,HEVC_v1/BUMPING_A_ericsson_1,BUMPING_A_ericsson_1.bit,BUMPING_A_ericsson_1.md5,8 -+1,HEVC_v1/CAINIT_A_SHARP_4,CAINIT_A_SHARP_4.bit,CAINIT_A_SHARP_4.md5,8 -+1,HEVC_v1/CAINIT_B_SHARP_4,CAINIT_B_SHARP_4.bit,CAINIT_B_SHARP_4.md5,8 -+1,HEVC_v1/CAINIT_C_SHARP_3,CAINIT_C_SHARP_3.bit,CAINIT_C_SHARP_3.md5,8 -+1,HEVC_v1/CAINIT_D_SHARP_3,CAINIT_D_SHARP_3.bit,CAINIT_D_SHARP_3.md5,8 -+1,HEVC_v1/CAINIT_E_SHARP_3,CAINIT_E_SHARP_3.bit,CAINIT_E_SHARP_3.md5,8 -+1,HEVC_v1/CAINIT_F_SHARP_3,CAINIT_F_SHARP_3.bit,CAINIT_F_SHARP_3.md5,8 -+1,HEVC_v1/CAINIT_G_SHARP_3,CAINIT_G_SHARP_3.bit,CAINIT_G_SHARP_3.md5,8 -+1,HEVC_v1/CAINIT_H_SHARP_3,CAINIT_H_SHARP_3.bit,CAINIT_H_SHARP_3.md5,8 -+1,HEVC_v1/CIP_A_Panasonic_3,CIP_A_Panasonic_3.bit,CIP_A_Panasonic_3_yuv.md5,8 -+1,HEVC_v1/cip_B_NEC_3,cip_B_NEC_3.bit,cip_B_NEC_3.md5,8 -+1,HEVC_v1/CIP_C_Panasonic_2,CIP_C_Panasonic_2.bit,CIP_C_Panasonic_2_yuv.md5,8 -+1,HEVC_v1/CONFWIN_A_Sony_1,CONFWIN_A_Sony_1.bit,CONFWIN_A_Sony_1.md5,8 -+1,HEVC_v1/DBLK_A_MAIN10_VIXS_4,DBLK_A_MAIN10_VIXS_4.bit,DBLK_A_MAIN10_VIXS_4.md5,10 -+1,HEVC_v1/DBLK_A_SONY_3,DBLK_A_SONY_3.bit,DBLK_A_SONY_3.bit.yuv.md5,8 -+1,HEVC_v1/DBLK_B_SONY_3,DBLK_B_SONY_3.bit,DBLK_B_SONY_3.bit.yuv.md5,8 -+1,HEVC_v1/DBLK_C_SONY_3,DBLK_C_SONY_3.bit,DBLK_C_SONY_3.bit.yuv.md5,8 -+1,HEVC_v1/DBLK_D_VIXS_2,DBLK_D_VIXS_2.bit,DBLK_D_VIXS_2_yuv.md5,8 -+1,HEVC_v1/DBLK_E_VIXS_2,DBLK_E_VIXS_2.bit,DBLK_E_VIXS_2_yuv.md5,8 -+1,HEVC_v1/DBLK_F_VIXS_2,DBLK_F_VIXS_2.bit,DBLK_F_VIXS_2_yuv.md5,8 -+1,HEVC_v1/DBLK_G_VIXS_2,DBLK_G_VIXS_2.bit,DBLK_G_VIXS_2_yuv.md5,8 -+1,HEVC_v1/DELTAQP_A_BRCM_4,DELTAQP_A_BRCM_4.bit,DELTAQP_A_BRCM_4_yuv.md5,8 -+1,HEVC_v1/DELTAQP_B_SONY_3,DELTAQP_B_SONY_3.bit,DELTAQP_B_SONY_3.bit.yuv.md5,8 -+1,HEVC_v1/DELTAQP_C_SONY_3,DELTAQP_C_SONY_3.bit,DELTAQP_C_SONY_3.bit.yuv.md5,8 -+1,HEVC_v1/DSLICE_A_HHI_5,DSLICE_A_HHI_5.bin,DSLICE_A_HHI_5.md5,8 -+1,HEVC_v1/DSLICE_B_HHI_5,DSLICE_B_HHI_5.bin,DSLICE_B_HHI_5.md5,8 -+1,HEVC_v1/DSLICE_C_HHI_5,DSLICE_C_HHI_5.bin,DSLICE_C_HHI_5.md5,8 -+1,HEVC_v1/ENTP_A_QUALCOMM_1,ENTP_A_Qualcomm_1.bit,ENTP_A_Qualcomm_1.md5,8 -+1,HEVC_v1/ENTP_B_Qualcomm_1,ENTP_B_Qualcomm_1.bit,ENTP_B_Qualcomm_1.md5,8 -+1,HEVC_v1/ENTP_C_Qualcomm_1,ENTP_C_Qualcomm_1.bit,ENTP_C_Qualcomm_1.md5,8 -+1,HEVC_v1/EXT_A_ericsson_4,EXT_A_ericsson_4.bit,EXT_A_ericsson_4.md5,8 -+1,HEVC_v1/FILLER_A_Sony_1,FILLER_A_Sony_1.bit,FILLER_A_Sony_1.md5,8 -+1,HEVC_v1/HRD_A_Fujitsu_3,HRD_A_Fujitsu_3.bin,HRD_A_Fujitsu_3.md5,8 -+1,HEVC_v1/INITQP_A_Sony_1,INITQP_A_Sony_1.bit,INITQP_A_Sony_1.md5,8 -+1,HEVC_v1/INITQP_B_Main10_Sony_1,INITQP_B_Main10_Sony_1.bit,INITQP_B_Main10_Sony_1.md5,10 -+1,HEVC_v1/ipcm_A_NEC_3,ipcm_A_NEC_3.bit,ipcm_A_NEC_3.md5,8 -+1,HEVC_v1/ipcm_B_NEC_3,ipcm_B_NEC_3.bit,ipcm_B_NEC_3.md5,8 -+1,HEVC_v1/ipcm_C_NEC_3,ipcm_C_NEC_3.bit,ipcm_C_NEC_3.md5,8 -+1,HEVC_v1/ipcm_D_NEC_3,ipcm_D_NEC_3.bit,ipcm_D_NEC_3.md5,8 -+1,HEVC_v1/ipcm_E_NEC_2,ipcm_E_NEC_2.bit,ipcm_E_NEC_2.md5,8 -+1,HEVC_v1/IPRED_A_docomo_2,IPRED_A_docomo_2.bit,IPRED_A_docomo_2.md5,8 -+1,HEVC_v1/IPRED_B_Nokia_3,IPRED_B_Nokia_3.bit,IPRED_B_Nokia_3_yuv.md5,8 -+1,HEVC_v1/IPRED_C_Mitsubishi_3,IPRED_C_Mitsubishi_3.bit,IPRED_C_Mitsubishi_3_yuv.md5,8 -+1,HEVC_v1/LS_A_Orange_2,LS_A_Orange_2.bit,LS_A_Orange_2_yuv.md5,8 -+1,HEVC_v1/LS_B_Orange_4,LS_B_Orange_4.bit,LS_B_Orange_4_yuv.md5,8 -+1,HEVC_v1/LTRPSPS_A_Qualcomm_1,LTRPSPS_A_Qualcomm_1.bit,LTRPSPS_A_Qualcomm_1.md5,8 -+1,HEVC_v1/MAXBINS_A_TI_5,MAXBINS_A_TI_5.bit,MAXBINS_A_TI_5_yuv.md5,8 -+1,HEVC_v1/MAXBINS_B_TI_5,MAXBINS_B_TI_5.bit,MAXBINS_B_TI_5_yuv.md5,8 -+1,HEVC_v1/MAXBINS_C_TI_5,MAXBINS_C_TI_5.bit,MAXBINS_C_TI_5_yuv.md5,8 -+1,HEVC_v1/MERGE_A_TI_3,MERGE_A_TI_3.bit,MERGE_A_TI_3.md5,8 -+1,HEVC_v1/MERGE_B_TI_3,MERGE_B_TI_3.bit,MERGE_B_TI_3.md5,8 -+1,HEVC_v1/MERGE_C_TI_3,MERGE_C_TI_3.bit,MERGE_C_TI_3.md5,8 -+1,HEVC_v1/MERGE_D_TI_3,MERGE_D_TI_3.bit,MERGE_D_TI_3.md5,8 -+1,HEVC_v1/MERGE_E_TI_3,MERGE_E_TI_3.bit,MERGE_E_TI_3.md5,8 -+1,HEVC_v1/MERGE_F_MTK_4,MERGE_F_MTK_4.bit,MERGE_F_MTK_4.md5,8 -+1,HEVC_v1/MERGE_G_HHI_4,MERGE_G_HHI_4.bit,MERGE_G_HHI_4.md5,8 -+1,HEVC_v1/MVCLIP_A_qualcomm_3,MVCLIP_A_qualcomm_3.bit,MVCLIP_A_qualcomm_3.yuv.md5,8 -+1,HEVC_v1/MVDL1ZERO_A_docomo_4,MVDL1ZERO_A_docomo_4.bit,MVDL1ZERO_A_docomo_4.md5,8 -+1,HEVC_v1/MVEDGE_A_qualcomm_3,MVEDGE_A_qualcomm_3.bit,MVEDGE_A_qualcomm_3.yuv.md5,8 -+1,HEVC_v1/NoOutPrior_A_Qualcomm_1,NoOutPrior_A_Qualcomm_1.bit,NoOutPrior_A_Qualcomm_1.md5,8 -+1,HEVC_v1/NoOutPrior_B_Qualcomm_1,NoOutPrior_B_Qualcomm_1.bit,NoOutPrior_B_Qualcomm_1.md5,8 -+1,HEVC_v1/NUT_A_ericsson_5,NUT_A_ericsson_5.bit,NUT_A_ericsson_5.md5,8 -+1,HEVC_v1/OPFLAG_A_Qualcomm_1,OPFLAG_A_Qualcomm_1.bit,OPFLAG_A_Qualcomm_1.md5,8 -+1,HEVC_v1/OPFLAG_B_Qualcomm_1,OPFLAG_B_Qualcomm_1.bit,OPFLAG_B_Qualcomm_1.md5,8 -+1,HEVC_v1/OPFLAG_C_Qualcomm_1,OPFLAG_C_Qualcomm_1.bit,OPFLAG_C_Qualcomm_1.md5,8 -+1,HEVC_v1/PICSIZE_A_Bossen_1,PICSIZE_A_Bossen_1.bin,PICSIZE_A_Bossen_1.md5,8 -+1,HEVC_v1/PICSIZE_B_Bossen_1,PICSIZE_B_Bossen_1.bin,PICSIZE_B_Bossen_1.md5,8 -+1,HEVC_v1/PICSIZE_C_Bossen_1,PICSIZE_C_Bossen_1.bin,PICSIZE_C_Bossen_1.md5,8 -+1,HEVC_v1/PICSIZE_D_Bossen_1,PICSIZE_D_Bossen_1.bin,PICSIZE_D_Bossen_1.md5,8 -+1,HEVC_v1/PMERGE_A_TI_3,PMERGE_A_TI_3.bit,PMERGE_A_TI_3.md5,8 -+1,HEVC_v1/PMERGE_B_TI_3,PMERGE_B_TI_3.bit,PMERGE_B_TI_3.md5,8 -+1,HEVC_v1/PMERGE_C_TI_3,PMERGE_C_TI_3.bit,PMERGE_C_TI_3.md5,8 -+1,HEVC_v1/PMERGE_D_TI_3,PMERGE_D_TI_3.bit,PMERGE_D_TI_3.md5,8 -+1,HEVC_v1/PMERGE_E_TI_3,PMERGE_E_TI_3.bit,PMERGE_E_TI_3.md5,8 -+1,HEVC_v1/POC_A_Bossen_3,POC_A_Bossen_3.bin,POC_A_Bossen_3.md5,8 -+1,HEVC_v1/PPS_A_qualcomm_7,PPS_A_qualcomm_7.bit,PPS_A_qualcomm_7.yuv.md5,8 -+1,HEVC_v1/PS_B_VIDYO_3,PS_B_VIDYO_3.bit,PS_B_VIDYO_3_yuv.md5,8 -+1,HEVC_v1/RAP_A_docomo_6,RAP_A_docomo_6.bit,RAP_A_docomo_6.md5,8 -+1,HEVC_v1/RAP_B_Bossen_2,RAP_B_Bossen_2.bit,RAP_B_Bossen_2.md5,8 -+1,HEVC_v1/RPLM_A_qualcomm_4,RPLM_A_qualcomm_4.bit,RPLM_A_qualcomm_4.yuv.md5,8 -+1,HEVC_v1/RPLM_B_qualcomm_4,RPLM_B_qualcomm_4.bit,RPLM_B_qualcomm_4.yuv.md5,8 -+1,HEVC_v1/RPS_A_docomo_5,RPS_A_docomo_5.bit,RPS_A_docomo_5.md5,8 -+1,HEVC_v1/RPS_B_qualcomm_5,RPS_B_qualcomm_5.bit,RPS_B_qualcomm_5.yuv.md5,8 -+1,HEVC_v1/RPS_C_ericsson_5,RPS_C_ericsson_5.bit,RPS_C_ericsson_5.md5,8 -+1,HEVC_v1/RPS_D_ericsson_6,RPS_D_ericsson_6.bit,RPS_D_ericsson_6.md5,8 -+1,HEVC_v1/RPS_E_qualcomm_5,RPS_E_qualcomm_5.bit,RPS_E_qualcomm_5.yuv.md5,8 -+1,HEVC_v1/RPS_F_docomo_2,RPS_F_docomo_2.bit,RPS_F_docomo_2.md5,8 -+1,HEVC_v1/RQT_A_HHI_4,RQT_A_HHI_4.bit,RQT_A_HHI_4.md5,8 -+1,HEVC_v1/RQT_B_HHI_4,RQT_B_HHI_4.bit,RQT_B_HHI_4.md5,8 -+1,HEVC_v1/RQT_C_HHI_4,RQT_C_HHI_4.bit,RQT_C_HHI_4.md5,8 -+1,HEVC_v1/RQT_D_HHI_4,RQT_D_HHI_4.bit,RQT_D_HHI_4.md5,8 -+1,HEVC_v1/RQT_E_HHI_4,RQT_E_HHI_4.bit,RQT_E_HHI_4.md5,8 -+1,HEVC_v1/RQT_F_HHI_4,RQT_F_HHI_4.bit,RQT_F_HHI_4.md5,8 -+1,HEVC_v1/RQT_G_HHI_4,RQT_G_HHI_4.bit,RQT_G_HHI_4.md5,8 -+1,HEVC_v1/SAO_A_MediaTek_4,SAO_A_MediaTek_4.bit,SAO_A_MediaTek_4.md5,8 -+1,HEVC_v1/SAO_B_MediaTek_5,SAO_B_MediaTek_5.bit,SAO_B_MediaTek_5.md5,8 -+1,HEVC_v1/SAO_C_Samsung_5,SAO_C_Samsung_5.bin,SAO_C_Samsung_5.md5,8 -+1,HEVC_v1/SAO_D_Samsung_5,SAO_D_Samsung_5.bin,SAO_D_Samsung_5.md5,8 -+1,HEVC_v1/SAO_E_Canon_4,SAO_E_Canon_4.bit,SAO_E_Canon_4.md5,8 -+1,HEVC_v1/SAO_F_Canon_3,SAO_F_Canon_3.bit,SAO_F_Canon_3.md5,8 -+1,HEVC_v1/SAO_G_Canon_3,SAO_G_Canon_3.bit,SAO_G_Canon_3.md5,8 -+1,HEVC_v1/SAO_H_Parabola_1,SAO_H_Parabola_1.bit,SAO_H_Parabola_1.md5,8 -+1,HEVC_v1/SAODBLK_A_MainConcept_4,SAODBLK_A_MainConcept_4.bin,SAODBLK_A_MainConcept_4_md5.txt,8 -+1,HEVC_v1/SAODBLK_B_MainConcept_4,SAODBLK_B_MainConcept_4.bin,SAODBLK_B_MainConcept_4_md5.txt,8 -+1,HEVC_v1/SDH_A_Orange_4,SDH_A_Orange_4.bit,SDH_A_Orange_4_yuv.md5,8 -+1,HEVC_v1/SLICES_A_Rovi_3,SLICES_A_Rovi_3.bin,SLICES_A_Rovi_3.md5,8 -+1,HEVC_v1/SLIST_A_Sony_5,SLIST_A_Sony_5.bin,SLIST_A_Sony_5_yuv.md5,8 -+1,HEVC_v1/SLIST_B_Sony_9,SLIST_B_Sony_9.bin,SLIST_B_Sony_9_yuv.md5,8 -+1,HEVC_v1/SLIST_C_Sony_4,SLIST_C_Sony_4.bin,SLIST_C_Sony_4_yuv.md5,8 -+1,HEVC_v1/SLIST_D_Sony_9,str.bin,SLIST_D_Sony_9_yuv.md5,8 -+1,HEVC_v1/SLPPLP_A_VIDYO_2,SLPPLP_A_VIDYO_2.bit,SLPPLP_A_VIDYO_2_yuv.md5,8 -+1,HEVC_v1/STRUCT_A_Samsung_7,STRUCT_A_Samsung_7.bin,STRUCT_A_Samsung_7.md5,8 -+1,HEVC_v1/STRUCT_B_Samsung_7,STRUCT_B_Samsung_7.bin,STRUCT_B_Samsung_7.md5,8 -+1,HEVC_v1/TILES_A_Cisco_2,TILES_A_Cisco_2.bin,TILES_A_Cisco_2_yuv.md5,8 -+1,HEVC_v1/TILES_B_Cisco_1,TILES_B_Cisco_1.bin,TILES_B_Cisco_1_yuv.md5,8 -+1,HEVC_v1/TMVP_A_MS_3,TMVP_A_MS_3.bit,TMVP_A_MS_3.yuv.md5,8 -+1,HEVC_v1/TSCL_A_VIDYO_5,TSCL_A_VIDYO_5.bit,TSCL_A_VIDYO_5_yuv.md5,8 -+1,HEVC_v1/TSCL_B_VIDYO_4,TSCL_B_VIDYO_4.bit,TSCL_B_VIDYO_4_yuv.md5,8 -+1,HEVC_v1/TSKIP_A_MS_3,TSKIP_A_MS_3.bit,TSKIP_A_MS_3.yuv.md5,8 -+3,HEVC_v1/TSUNEQBD_A_MAIN10_Technicolor_2,TSUNEQBD_A_MAIN10_Technicolor_2.bit,TSUNEQBD_A_MAIN10_Technicolor_2_yuv.md5, # unequal bit depth,10 -+1,HEVC_v1/TUSIZE_A_Samsung_1,TUSIZE_A_Samsung_1.bin,TUSIZE_A_Samsung_1.md5,8 -+1,HEVC_v1/VPSID_A_VIDYO_2,VPSID_A_VIDYO_2.bit,VPSID_A_VIDYO_2_yuv.md5,8 -+3,HEVC_v1/VPSSPSPPS_A_MainConcept_1,VPSSPSPPS_A_MainConcept_1.bin,VPSSPSPPS_A_MainConcept_1_md5.txt, # ???,8 -+1,HEVC_v1/WP_A_MAIN10_Toshiba_3,WP_A_MAIN10_Toshiba_3.bit,WP_A_MAIN10_Toshiba_3_yuv.md5,10 -+1,HEVC_v1/WP_A_Toshiba_3,WP_A_Toshiba_3.bit,WP_A_Toshiba_3_yuv.md5,8 -+1,HEVC_v1/WP_B_Toshiba_3,WP_B_Toshiba_3.bit,WP_B_Toshiba_3_yuv.md5,8 -+1,HEVC_v1/WP_MAIN10_B_Toshiba_3,WP_MAIN10_B_Toshiba_3.bit,WP_MAIN10_B_Toshiba_3_yuv.md5,10 -+1,HEVC_v1/WPP_A_ericsson_MAIN10_2,WPP_A_ericsson_MAIN10_2.bit,WPP_A_ericsson_MAIN10_yuv.md5,10 -+1,HEVC_v1/WPP_A_ericsson_MAIN_2,WPP_A_ericsson_MAIN_2.bit,WPP_A_ericsson_MAIN_2_yuv.md5,8 -+1,HEVC_v1/WPP_B_ericsson_MAIN10_2,WPP_B_ericsson_MAIN10_2.bit,WPP_B_ericsson_MAIN10_yuv.md5,10 -+1,HEVC_v1/WPP_B_ericsson_MAIN_2,WPP_B_ericsson_MAIN_2.bit,WPP_B_ericsson_MAIN_2_yuv.md5,8 -+1,HEVC_v1/WPP_C_ericsson_MAIN10_2,WPP_C_ericsson_MAIN10_2.bit,WPP_C_ericsson_MAIN10_yuv.md5,10 -+1,HEVC_v1/WPP_C_ericsson_MAIN_2,WPP_C_ericsson_MAIN_2.bit,WPP_C_ericsson_MAIN_2_yuv.md5,8 -+1,HEVC_v1/WPP_D_ericsson_MAIN10_2,WPP_D_ericsson_MAIN10_2.bit,WPP_D_ericsson_MAIN10_yuv.md5,10 -+1,HEVC_v1/WPP_D_ericsson_MAIN_2,WPP_D_ericsson_MAIN_2.bit,WPP_D_ericsson_MAIN_2_yuv.md5,8 -+1,HEVC_v1/WPP_E_ericsson_MAIN10_2,WPP_E_ericsson_MAIN10_2.bit,WPP_E_ericsson_MAIN10_yuv.md5,10 -+1,HEVC_v1/WPP_E_ericsson_MAIN_2,WPP_E_ericsson_MAIN_2.bit,WPP_E_ericsson_MAIN_2_yuv.md5,8 -+1,HEVC_v1/WPP_F_ericsson_MAIN10_2,WPP_F_ericsson_MAIN10_2.bit,WPP_F_ericsson_MAIN10_yuv.md5,10 -+1,HEVC_v1/WPP_F_ericsson_MAIN_2,WPP_F_ericsson_MAIN_2.bit,WPP_F_ericsson_MAIN_2_yuv.md5,8 -+1,RExt/ADJUST_IPRED_ANGLE_A_RExt_Mitsubishi_2,ADJUST_IPRED_ANGLE_A_RExt_Mitsubishi_2.bit,ADJUST_IPRED_ANGLE_A_RExt_Mitsubishi_yuv_2.md5,0 -+0,RExt/Bitdepth_A_RExt_Sony_1,Bitdepth_A_RExt_Sony_1.bin,md5sum.txt,8 -+0,RExt/Bitdepth_B_RExt_Sony_1,Bitdepth_B_RExt_Sony_1.bin,md5sum.txt,8 -+0,RExt/CCP_10bit_RExt_QCOM,CCP_10bit_RExt_QCOM.bin,CCP_10bit_RExt_QCOM_md5sum.txt,10 -+0,RExt/CCP_12bit_RExt_QCOM,CCP_12bit_RExt_QCOM.bin,CCP_12bit_RExt_QCOM_md5sum.txt,8 -+0,RExt/CCP_8bit_RExt_QCOM,CCP_8bit_RExt_QCOM.bin,CCP_8bit_RExt_QCOM_md5sum.txt,8 -+1,RExt/ExplicitRdpcm_A_BBC_1,ExplicitRdpcm_A_BBC_1.bit,md5sum.txt,0 -+0,RExt/ExplicitRdpcm_B_BBC_2,ExplicitRdpcm_B_BBC_1.bit,md5sum.txt,8 -+0,RExt/EXTPREC_HIGHTHROUGHPUT_444_16_INTRA_10BIT_RExt_Sony_1,EXTPREC_HIGHTHROUGHPUT_444_16_INTRA_10BIT_RExt_Sony_1.bit,EXTPREC_HIGHTHROUGHPUT_444_16_INTRA_10BIT_RExt_Sony_1.md5,10 -+0,RExt/EXTPREC_HIGHTHROUGHPUT_444_16_INTRA_12BIT_RExt_Sony_1,EXTPREC_HIGHTHROUGHPUT_444_16_INTRA_12BIT_RExt_Sony_1.bit,EXTPREC_HIGHTHROUGHPUT_444_16_INTRA_12BIT_RExt_Sony_1.md5,8 -+0,RExt/EXTPREC_HIGHTHROUGHPUT_444_16_INTRA_16BIT_RExt_Sony_1,EXTPREC_HIGHTHROUGHPUT_444_16_INTRA_16BIT_RExt_Sony_1.bit,EXTPREC_HIGHTHROUGHPUT_444_16_INTRA_16BIT_RExt_Sony_1.md5,8 -+0,RExt/EXTPREC_HIGHTHROUGHPUT_444_16_INTRA_8BIT_RExt_Sony_1,EXTPREC_HIGHTHROUGHPUT_444_16_INTRA_8BIT_RExt_Sony_1.bit,EXTPREC_HIGHTHROUGHPUT_444_16_INTRA_8BIT_RExt_Sony_1.md5,8 -+0,RExt/EXTPREC_MAIN_444_16_INTRA_10BIT_RExt_Sony_1,EXTPREC_MAIN_444_16_INTRA_10BIT_RExt_Sony_1.bit,EXTPREC_MAIN_444_16_INTRA_10BIT_RExt_Sony_1.md5,10 -+0,RExt/EXTPREC_MAIN_444_16_INTRA_12BIT_RExt_Sony_1,EXTPREC_MAIN_444_16_INTRA_12BIT_RExt_Sony_1.bit,EXTPREC_MAIN_444_16_INTRA_12BIT_RExt_Sony_1.md5,8 -+0,RExt/EXTPREC_MAIN_444_16_INTRA_16BIT_RExt_Sony_1,EXTPREC_MAIN_444_16_INTRA_16BIT_RExt_Sony_1.bit,EXTPREC_MAIN_444_16_INTRA_16BIT_RExt_Sony_1.md5,8 -+0,RExt/EXTPREC_MAIN_444_16_INTRA_8BIT_RExt_Sony_1,EXTPREC_MAIN_444_16_INTRA_8BIT_RExt_Sony_1.bit,EXTPREC_MAIN_444_16_INTRA_8BIT_RExt_Sony_1.md5,8 -+1,RExt/GENERAL_10b_420_RExt_Sony_1,GENERAL_10b_420_RExt_Sony_1.bit,GENERAL_10b_420_RExt_Sony_1.md5,10 -+1,RExt/GENERAL_10b_422_RExt_Sony_1,GENERAL_10b_422_RExt_Sony_1.bit,GENERAL_10b_422_RExt_Sony_1.md5,0 -+1,RExt/GENERAL_10b_444_RExt_Sony_2,GENERAL_10b_444_RExt_Sony_2.bit,GENERAL_10b_444_RExt_Sony_2.md5,0 -+1,RExt/GENERAL_12b_400_RExt_Sony_1,GENERAL_12b_400_RExt_Sony_1.bit,GENERAL_12b_400_RExt_Sony_1.md5,0 -+1,RExt/GENERAL_12b_420_RExt_Sony_1,GENERAL_12b_420_RExt_Sony_1.bit,GENERAL_12b_420_RExt_Sony_1.md5,0 -+1,RExt/GENERAL_12b_422_RExt_Sony_1,GENERAL_12b_422_RExt_Sony_1.bit,GENERAL_12b_422_RExt_Sony_1.md5,0 -+1,RExt/GENERAL_12b_444_RExt_Sony_2,GENERAL_12b_444_RExt_Sony_2.bit,GENERAL_12b_444_RExt_Sony_2.md5,0 -+0,RExt/GENERAL_16b_400_RExt_Sony_1,GENERAL_16b_400_RExt_Sony_1.bit,GENERAL_16b_400_RExt_Sony_1.md5,0 -+0,RExt/GENERAL_16b_444_highThroughput_RExt_Sony_2,GENERAL_16b_444_highThroughput_RExt_Sony_2.bit,GENERAL_16b_444_highThroughput_RExt_Sony_2.md5,8 -+0,RExt/GENERAL_16b_444_RExt_Sony_2,GENERAL_16b_444_RExt_Sony_2.bit,GENERAL_16b_444_RExt_Sony_2.md5,8 -+1,RExt/GENERAL_8b_400_RExt_Sony_1,GENERAL_8b_400_RExt_Sony_1.bit,GENERAL_8b_400_RExt_Sony_1.md5,0 -+1,RExt/GENERAL_8b_420_RExt_Sony_1,GENERAL_8b_420_RExt_Sony_1.bit,GENERAL_8b_420_RExt_Sony_1.md5,8 -+1,RExt/GENERAL_8b_444_RExt_Sony_2,GENERAL_8b_444_RExt_Sony_2.bit,GENERAL_8b_444_RExt_Sony_2.md5,0 -+1,RExt/IPCM_A_RExt_NEC_2,IPCM_A_RExt_NEC_2.bit,IPCM_A_RExt_NEC_2_yuv.md5,0 -+1,RExt/IPCM_B_RExt_NEC,IPCM_B_RExt_NEC.bit,IPCM_B_RExt_NEC_yuv.md5,0 -+1,RExt/Main_422_10_A_RExt_Sony_2,Main_422_10_A_RExt_Sony_2.bin,md5sum.txt,0 -+1,RExt/Main_422_10_B_RExt_Sony_2,Main_422_10_B_RExt_Sony_2.bin,md5sum.txt,0 -+1,RExt/PERSIST_RPARAM_A_RExt_Sony_3,PERSIST_RPARAM_A_RExt_Sony_3.bit,PERSIST_RPARAM_A_RExt_Sony_3.md5,0 -+1,RExt/QMATRIX_A_RExt_Sony_1,QMATRIX_A_RExt_Sony_1.bit,QMATRIX_A_RExt_Sony_1.md5,0 -+0,RExt/SAO_A_RExt_MediaTek_1,SAO_A_RExt_MediaTek_1.bit,SAO_A_RExt_MediaTek_1.md5, # Runs out of memory - could be fixed,8 -+0,RExt/TSCTX_10bit_I_RExt_SHARP_1,TSCTX_10bit_I_RExt_SHARP_1.bin,TSCTX_10bit_I_RExt_SHARP_1.md5,10 -+0,RExt/TSCTX_10bit_RExt_SHARP_1,TSCTX_10bit_RExt_SHARP_1.bin,TSCTX_10bit_RExt_SHARP_1.md5,10 -+0,RExt/TSCTX_12bit_I_RExt_SHARP_1,TSCTX_12bit_I_RExt_SHARP_1.bin,TSCTX_12bit_I_RExt_SHARP_1.md5,8 -+0,RExt/TSCTX_12bit_RExt_SHARP_1,TSCTX_12bit_RExt_SHARP_1.bin,TSCTX_12bit_RExt_SHARP_1.md5,8 -+0,RExt/TSCTX_8bit_I_RExt_SHARP_1,TSCTX_8bit_I_RExt_SHARP_1.bin,TSCTX_8bit_I_RExt_SHARP_1.md5,8 -+0,RExt/TSCTX_8bit_RExt_SHARP_1,TSCTX_8bit_RExt_SHARP_1.bin,TSCTX_8bit_RExt_SHARP_1.md5,8 -+0,RExt/WAVETILES_RExt_Sony_2,WAVETILES_RExt_Sony_2.bit,WAVETILES_RExt_Sony_2.md5,8 -+1,local/sao_cu16_mobile_344x280,sao_cu16_mobile_344x280.265,sao_cu16_mobile_344x280.md5,8 -+1,local/dblk_cu16_mobile_344x280,dblk_cu16_mobile_344x280.265,dblk_cu16_mobile_344x280.md5,8 -+1,local/dblksao_cu16_mobile_344x280,dblksao_cu16_mobile_344x280.265,dblksao_cu16_mobile_344x280.md5,8 -+1,local/dblk_pu32_horses_832x448,dblk_pu32_horses_832x448.265,dblk_pu32_horses_832x448.md5,8 -+1,local/intra_pred_21_laps,intra_pred_21_laps.265,intra_pred_21_laps.md5,8 ++1,HEVC_v1/AMP_A_Samsung_7,AMP_A_Samsung_7.bin,AMP_A_Samsung_7.md5,8 ++1,HEVC_v1/AMP_B_Samsung_7,AMP_B_Samsung_7.bin,AMP_B_Samsung_7.md5,8 ++1,HEVC_v1/AMP_D_Hisilicon_3,AMP_D_Hisilicon.bit,AMP_D_Hisilicon_3.yuv.md5,8 ++1,HEVC_v1/AMP_E_Hisilicon_3,AMP_E_Hisilicon.bit,AMP_E_Hisilicon_3.yuv.md5,8 ++1,HEVC_v1/AMP_F_Hisilicon_3,AMP_F_Hisilicon_3.bit,AMP_F_Hisilicon_3.yuv.md5,8 ++1,HEVC_v1/AMVP_A_MTK_4,AMVP_A_MTK_4.bit,AMVP_A_MTK_4.md5,8 ++1,HEVC_v1/AMVP_B_MTK_4,AMVP_B_MTK_4.bit,AMVP_B_MTK_4.md5,8 ++1,HEVC_v1/AMVP_C_Samsung_7,AMVP_C_Samsung_7.bin,AMVP_C_Samsung_7.md5,8 ++1,HEVC_v1/BUMPING_A_ericsson_1,BUMPING_A_ericsson_1.bit,BUMPING_A_ericsson_1.md5,8 ++1,HEVC_v1/CAINIT_A_SHARP_4,CAINIT_A_SHARP_4.bit,CAINIT_A_SHARP_4.md5,8 ++1,HEVC_v1/CAINIT_B_SHARP_4,CAINIT_B_SHARP_4.bit,CAINIT_B_SHARP_4.md5,8 ++1,HEVC_v1/CAINIT_C_SHARP_3,CAINIT_C_SHARP_3.bit,CAINIT_C_SHARP_3.md5,8 ++1,HEVC_v1/CAINIT_D_SHARP_3,CAINIT_D_SHARP_3.bit,CAINIT_D_SHARP_3.md5,8 ++1,HEVC_v1/CAINIT_E_SHARP_3,CAINIT_E_SHARP_3.bit,CAINIT_E_SHARP_3.md5,8 ++1,HEVC_v1/CAINIT_F_SHARP_3,CAINIT_F_SHARP_3.bit,CAINIT_F_SHARP_3.md5,8 ++1,HEVC_v1/CAINIT_G_SHARP_3,CAINIT_G_SHARP_3.bit,CAINIT_G_SHARP_3.md5,8 ++1,HEVC_v1/CAINIT_H_SHARP_3,CAINIT_H_SHARP_3.bit,CAINIT_H_SHARP_3.md5,8 ++1,HEVC_v1/CIP_A_Panasonic_3,CIP_A_Panasonic_3.bit,CIP_A_Panasonic_3_yuv.md5,8 ++1,HEVC_v1/cip_B_NEC_3,cip_B_NEC_3.bit,cip_B_NEC_3.md5,8 ++1,HEVC_v1/CIP_C_Panasonic_2,CIP_C_Panasonic_2.bit,CIP_C_Panasonic_2_yuv.md5,8 ++1,HEVC_v1/CONFWIN_A_Sony_1,CONFWIN_A_Sony_1.bit,CONFWIN_A_Sony_1.md5,8 ++1,HEVC_v1/DBLK_A_MAIN10_VIXS_4,DBLK_A_MAIN10_VIXS_4.bit,DBLK_A_MAIN10_VIXS_4.md5,10 ++1,HEVC_v1/DBLK_A_SONY_3,DBLK_A_SONY_3.bit,DBLK_A_SONY_3.bit.yuv.md5,8 ++1,HEVC_v1/DBLK_B_SONY_3,DBLK_B_SONY_3.bit,DBLK_B_SONY_3.bit.yuv.md5,8 ++1,HEVC_v1/DBLK_C_SONY_3,DBLK_C_SONY_3.bit,DBLK_C_SONY_3.bit.yuv.md5,8 ++1,HEVC_v1/DBLK_D_VIXS_2,DBLK_D_VIXS_2.bit,DBLK_D_VIXS_2_yuv.md5,8 ++1,HEVC_v1/DBLK_E_VIXS_2,DBLK_E_VIXS_2.bit,DBLK_E_VIXS_2_yuv.md5,8 ++1,HEVC_v1/DBLK_F_VIXS_2,DBLK_F_VIXS_2.bit,DBLK_F_VIXS_2_yuv.md5,8 ++1,HEVC_v1/DBLK_G_VIXS_2,DBLK_G_VIXS_2.bit,DBLK_G_VIXS_2_yuv.md5,8 ++1,HEVC_v1/DELTAQP_A_BRCM_4,DELTAQP_A_BRCM_4.bit,DELTAQP_A_BRCM_4_yuv.md5,8 ++1,HEVC_v1/DELTAQP_B_SONY_3,DELTAQP_B_SONY_3.bit,DELTAQP_B_SONY_3.bit.yuv.md5,8 ++1,HEVC_v1/DELTAQP_C_SONY_3,DELTAQP_C_SONY_3.bit,DELTAQP_C_SONY_3.bit.yuv.md5,8 ++1,HEVC_v1/DSLICE_A_HHI_5,DSLICE_A_HHI_5.bin,DSLICE_A_HHI_5.md5,8 ++1,HEVC_v1/DSLICE_B_HHI_5,DSLICE_B_HHI_5.bin,DSLICE_B_HHI_5.md5,8 ++1,HEVC_v1/DSLICE_C_HHI_5,DSLICE_C_HHI_5.bin,DSLICE_C_HHI_5.md5,8 ++1,HEVC_v1/ENTP_A_QUALCOMM_1,ENTP_A_Qualcomm_1.bit,ENTP_A_Qualcomm_1.md5,8 ++1,HEVC_v1/ENTP_B_Qualcomm_1,ENTP_B_Qualcomm_1.bit,ENTP_B_Qualcomm_1.md5,8 ++1,HEVC_v1/ENTP_C_Qualcomm_1,ENTP_C_Qualcomm_1.bit,ENTP_C_Qualcomm_1.md5,8 ++1,HEVC_v1/EXT_A_ericsson_4,EXT_A_ericsson_4.bit,EXT_A_ericsson_4.md5,8 ++1,HEVC_v1/FILLER_A_Sony_1,FILLER_A_Sony_1.bit,FILLER_A_Sony_1.md5,8 ++1,HEVC_v1/HRD_A_Fujitsu_3,HRD_A_Fujitsu_3.bin,HRD_A_Fujitsu_3.md5,8 ++1,HEVC_v1/INITQP_A_Sony_1,INITQP_A_Sony_1.bit,INITQP_A_Sony_1.md5,8 ++1,HEVC_v1/INITQP_B_Main10_Sony_1,INITQP_B_Main10_Sony_1.bit,INITQP_B_Main10_Sony_1.md5,10 ++1,HEVC_v1/ipcm_A_NEC_3,ipcm_A_NEC_3.bit,ipcm_A_NEC_3.md5,8 ++1,HEVC_v1/ipcm_B_NEC_3,ipcm_B_NEC_3.bit,ipcm_B_NEC_3.md5,8 ++1,HEVC_v1/ipcm_C_NEC_3,ipcm_C_NEC_3.bit,ipcm_C_NEC_3.md5,8 ++1,HEVC_v1/ipcm_D_NEC_3,ipcm_D_NEC_3.bit,ipcm_D_NEC_3.md5,8 ++1,HEVC_v1/ipcm_E_NEC_2,ipcm_E_NEC_2.bit,ipcm_E_NEC_2.md5,8 ++1,HEVC_v1/IPRED_A_docomo_2,IPRED_A_docomo_2.bit,IPRED_A_docomo_2.md5,8 ++1,HEVC_v1/IPRED_B_Nokia_3,IPRED_B_Nokia_3.bit,IPRED_B_Nokia_3_yuv.md5,8 ++1,HEVC_v1/IPRED_C_Mitsubishi_3,IPRED_C_Mitsubishi_3.bit,IPRED_C_Mitsubishi_3_yuv.md5,8 ++1,HEVC_v1/LS_A_Orange_2,LS_A_Orange_2.bit,LS_A_Orange_2_yuv.md5,8 ++1,HEVC_v1/LS_B_Orange_4,LS_B_Orange_4.bit,LS_B_Orange_4_yuv.md5,8 ++1,HEVC_v1/LTRPSPS_A_Qualcomm_1,LTRPSPS_A_Qualcomm_1.bit,LTRPSPS_A_Qualcomm_1.md5,8 ++1,HEVC_v1/MAXBINS_A_TI_5,MAXBINS_A_TI_5.bit,MAXBINS_A_TI_5_yuv.md5,8 ++1,HEVC_v1/MAXBINS_B_TI_5,MAXBINS_B_TI_5.bit,MAXBINS_B_TI_5_yuv.md5,8 ++1,HEVC_v1/MAXBINS_C_TI_5,MAXBINS_C_TI_5.bit,MAXBINS_C_TI_5_yuv.md5,8 ++1,HEVC_v1/MERGE_A_TI_3,MERGE_A_TI_3.bit,MERGE_A_TI_3.md5,8 ++1,HEVC_v1/MERGE_B_TI_3,MERGE_B_TI_3.bit,MERGE_B_TI_3.md5,8 ++1,HEVC_v1/MERGE_C_TI_3,MERGE_C_TI_3.bit,MERGE_C_TI_3.md5,8 ++1,HEVC_v1/MERGE_D_TI_3,MERGE_D_TI_3.bit,MERGE_D_TI_3.md5,8 ++1,HEVC_v1/MERGE_E_TI_3,MERGE_E_TI_3.bit,MERGE_E_TI_3.md5,8 ++1,HEVC_v1/MERGE_F_MTK_4,MERGE_F_MTK_4.bit,MERGE_F_MTK_4.md5,8 ++1,HEVC_v1/MERGE_G_HHI_4,MERGE_G_HHI_4.bit,MERGE_G_HHI_4.md5,8 ++1,HEVC_v1/MVCLIP_A_qualcomm_3,MVCLIP_A_qualcomm_3.bit,MVCLIP_A_qualcomm_3.yuv.md5,8 ++1,HEVC_v1/MVDL1ZERO_A_docomo_4,MVDL1ZERO_A_docomo_4.bit,MVDL1ZERO_A_docomo_4.md5,8 ++1,HEVC_v1/MVEDGE_A_qualcomm_3,MVEDGE_A_qualcomm_3.bit,MVEDGE_A_qualcomm_3.yuv.md5,8 ++1,HEVC_v1/NoOutPrior_A_Qualcomm_1,NoOutPrior_A_Qualcomm_1.bit,NoOutPrior_A_Qualcomm_1.md5,8 ++1,HEVC_v1/NoOutPrior_B_Qualcomm_1,NoOutPrior_B_Qualcomm_1.bit,NoOutPrior_B_Qualcomm_1.md5,8 ++1,HEVC_v1/NUT_A_ericsson_5,NUT_A_ericsson_5.bit,NUT_A_ericsson_5.md5,8 ++1,HEVC_v1/OPFLAG_A_Qualcomm_1,OPFLAG_A_Qualcomm_1.bit,OPFLAG_A_Qualcomm_1.md5,8 ++1,HEVC_v1/OPFLAG_B_Qualcomm_1,OPFLAG_B_Qualcomm_1.bit,OPFLAG_B_Qualcomm_1.md5,8 ++1,HEVC_v1/OPFLAG_C_Qualcomm_1,OPFLAG_C_Qualcomm_1.bit,OPFLAG_C_Qualcomm_1.md5,8 ++1,HEVC_v1/PICSIZE_A_Bossen_1,PICSIZE_A_Bossen_1.bin,PICSIZE_A_Bossen_1.md5,8 ++1,HEVC_v1/PICSIZE_B_Bossen_1,PICSIZE_B_Bossen_1.bin,PICSIZE_B_Bossen_1.md5,8 ++1,HEVC_v1/PICSIZE_C_Bossen_1,PICSIZE_C_Bossen_1.bin,PICSIZE_C_Bossen_1.md5,8 ++1,HEVC_v1/PICSIZE_D_Bossen_1,PICSIZE_D_Bossen_1.bin,PICSIZE_D_Bossen_1.md5,8 ++1,HEVC_v1/PMERGE_A_TI_3,PMERGE_A_TI_3.bit,PMERGE_A_TI_3.md5,8 ++1,HEVC_v1/PMERGE_B_TI_3,PMERGE_B_TI_3.bit,PMERGE_B_TI_3.md5,8 ++1,HEVC_v1/PMERGE_C_TI_3,PMERGE_C_TI_3.bit,PMERGE_C_TI_3.md5,8 ++1,HEVC_v1/PMERGE_D_TI_3,PMERGE_D_TI_3.bit,PMERGE_D_TI_3.md5,8 ++1,HEVC_v1/PMERGE_E_TI_3,PMERGE_E_TI_3.bit,PMERGE_E_TI_3.md5,8 ++1,HEVC_v1/POC_A_Bossen_3,POC_A_Bossen_3.bin,POC_A_Bossen_3.md5,8 ++1,HEVC_v1/PPS_A_qualcomm_7,PPS_A_qualcomm_7.bit,PPS_A_qualcomm_7.yuv.md5,8 ++1,HEVC_v1/PS_B_VIDYO_3,PS_B_VIDYO_3.bit,PS_B_VIDYO_3_yuv.md5,8 ++1,HEVC_v1/RAP_A_docomo_6,RAP_A_docomo_6.bit,RAP_A_docomo_6.md5,8 ++1,HEVC_v1/RAP_B_Bossen_2,RAP_B_Bossen_2.bit,RAP_B_Bossen_2.md5,8 ++1,HEVC_v1/RPLM_A_qualcomm_4,RPLM_A_qualcomm_4.bit,RPLM_A_qualcomm_4.yuv.md5,8 ++1,HEVC_v1/RPLM_B_qualcomm_4,RPLM_B_qualcomm_4.bit,RPLM_B_qualcomm_4.yuv.md5,8 ++1,HEVC_v1/RPS_A_docomo_5,RPS_A_docomo_5.bit,RPS_A_docomo_5.md5,8 ++1,HEVC_v1/RPS_B_qualcomm_5,RPS_B_qualcomm_5.bit,RPS_B_qualcomm_5.yuv.md5,8 ++1,HEVC_v1/RPS_C_ericsson_5,RPS_C_ericsson_5.bit,RPS_C_ericsson_5.md5,8 ++1,HEVC_v1/RPS_D_ericsson_6,RPS_D_ericsson_6.bit,RPS_D_ericsson_6.md5,8 ++1,HEVC_v1/RPS_E_qualcomm_5,RPS_E_qualcomm_5.bit,RPS_E_qualcomm_5.yuv.md5,8 ++1,HEVC_v1/RPS_F_docomo_2,RPS_F_docomo_2.bit,RPS_F_docomo_2.md5,8 ++1,HEVC_v1/RQT_A_HHI_4,RQT_A_HHI_4.bit,RQT_A_HHI_4.md5,8 ++1,HEVC_v1/RQT_B_HHI_4,RQT_B_HHI_4.bit,RQT_B_HHI_4.md5,8 ++1,HEVC_v1/RQT_C_HHI_4,RQT_C_HHI_4.bit,RQT_C_HHI_4.md5,8 ++1,HEVC_v1/RQT_D_HHI_4,RQT_D_HHI_4.bit,RQT_D_HHI_4.md5,8 ++1,HEVC_v1/RQT_E_HHI_4,RQT_E_HHI_4.bit,RQT_E_HHI_4.md5,8 ++1,HEVC_v1/RQT_F_HHI_4,RQT_F_HHI_4.bit,RQT_F_HHI_4.md5,8 ++1,HEVC_v1/RQT_G_HHI_4,RQT_G_HHI_4.bit,RQT_G_HHI_4.md5,8 ++1,HEVC_v1/SAO_A_MediaTek_4,SAO_A_MediaTek_4.bit,SAO_A_MediaTek_4.md5,8 ++1,HEVC_v1/SAO_B_MediaTek_5,SAO_B_MediaTek_5.bit,SAO_B_MediaTek_5.md5,8 ++1,HEVC_v1/SAO_C_Samsung_5,SAO_C_Samsung_5.bin,SAO_C_Samsung_5.md5,8 ++1,HEVC_v1/SAO_D_Samsung_5,SAO_D_Samsung_5.bin,SAO_D_Samsung_5.md5,8 ++1,HEVC_v1/SAO_E_Canon_4,SAO_E_Canon_4.bit,SAO_E_Canon_4.md5,8 ++1,HEVC_v1/SAO_F_Canon_3,SAO_F_Canon_3.bit,SAO_F_Canon_3.md5,8 ++1,HEVC_v1/SAO_G_Canon_3,SAO_G_Canon_3.bit,SAO_G_Canon_3.md5,8 ++1,HEVC_v1/SAO_H_Parabola_1,SAO_H_Parabola_1.bit,SAO_H_Parabola_1.md5,8 ++1,HEVC_v1/SAODBLK_A_MainConcept_4,SAODBLK_A_MainConcept_4.bin,SAODBLK_A_MainConcept_4_md5.txt,8 ++1,HEVC_v1/SAODBLK_B_MainConcept_4,SAODBLK_B_MainConcept_4.bin,SAODBLK_B_MainConcept_4_md5.txt,8 ++1,HEVC_v1/SDH_A_Orange_4,SDH_A_Orange_4.bit,SDH_A_Orange_4_yuv.md5,8 ++1,HEVC_v1/SLICES_A_Rovi_3,SLICES_A_Rovi_3.bin,SLICES_A_Rovi_3.md5,8 ++1,HEVC_v1/SLIST_A_Sony_5,SLIST_A_Sony_5.bin,SLIST_A_Sony_5_yuv.md5,8 ++1,HEVC_v1/SLIST_B_Sony_9,SLIST_B_Sony_9.bin,SLIST_B_Sony_9_yuv.md5,8 ++1,HEVC_v1/SLIST_C_Sony_4,SLIST_C_Sony_4.bin,SLIST_C_Sony_4_yuv.md5,8 ++1,HEVC_v1/SLIST_D_Sony_9,str.bin,SLIST_D_Sony_9_yuv.md5,8 ++1,HEVC_v1/SLPPLP_A_VIDYO_2,SLPPLP_A_VIDYO_2.bit,SLPPLP_A_VIDYO_2_yuv.md5,8 ++1,HEVC_v1/STRUCT_A_Samsung_7,STRUCT_A_Samsung_7.bin,STRUCT_A_Samsung_7.md5,8 ++1,HEVC_v1/STRUCT_B_Samsung_7,STRUCT_B_Samsung_7.bin,STRUCT_B_Samsung_7.md5,8 ++1,HEVC_v1/TILES_A_Cisco_2,TILES_A_Cisco_2.bin,TILES_A_Cisco_2_yuv.md5,8 ++1,HEVC_v1/TILES_B_Cisco_1,TILES_B_Cisco_1.bin,TILES_B_Cisco_1_yuv.md5,8 ++1,HEVC_v1/TMVP_A_MS_3,TMVP_A_MS_3.bit,TMVP_A_MS_3.yuv.md5,8 ++1,HEVC_v1/TSCL_A_VIDYO_5,TSCL_A_VIDYO_5.bit,TSCL_A_VIDYO_5_yuv.md5,8 ++1,HEVC_v1/TSCL_B_VIDYO_4,TSCL_B_VIDYO_4.bit,TSCL_B_VIDYO_4_yuv.md5,8 ++1,HEVC_v1/TSKIP_A_MS_3,TSKIP_A_MS_3.bit,TSKIP_A_MS_3.yuv.md5,8 ++3,HEVC_v1/TSUNEQBD_A_MAIN10_Technicolor_2,TSUNEQBD_A_MAIN10_Technicolor_2.bit,TSUNEQBD_A_MAIN10_Technicolor_2_yuv.md5, # unequal bit depth,10 ++1,HEVC_v1/TUSIZE_A_Samsung_1,TUSIZE_A_Samsung_1.bin,TUSIZE_A_Samsung_1.md5,8 ++1,HEVC_v1/VPSID_A_VIDYO_2,VPSID_A_VIDYO_2.bit,VPSID_A_VIDYO_2_yuv.md5,8 ++2,HEVC_v1/VPSSPSPPS_A_MainConcept_1,VPSSPSPPS_A_MainConcept_1.bin,VPSSPSPPS_A_MainConcept_1_md5.txt, # ???,8 ++1,HEVC_v1/WP_A_MAIN10_Toshiba_3,WP_A_MAIN10_Toshiba_3.bit,WP_A_MAIN10_Toshiba_3_yuv.md5,10 ++1,HEVC_v1/WP_A_Toshiba_3,WP_A_Toshiba_3.bit,WP_A_Toshiba_3_yuv.md5,8 ++1,HEVC_v1/WP_B_Toshiba_3,WP_B_Toshiba_3.bit,WP_B_Toshiba_3_yuv.md5,8 ++1,HEVC_v1/WP_MAIN10_B_Toshiba_3,WP_MAIN10_B_Toshiba_3.bit,WP_MAIN10_B_Toshiba_3_yuv.md5,10 ++1,HEVC_v1/WPP_A_ericsson_MAIN10_2,WPP_A_ericsson_MAIN10_2.bit,WPP_A_ericsson_MAIN10_yuv.md5,10 ++1,HEVC_v1/WPP_A_ericsson_MAIN_2,WPP_A_ericsson_MAIN_2.bit,WPP_A_ericsson_MAIN_2_yuv.md5,8 ++1,HEVC_v1/WPP_B_ericsson_MAIN10_2,WPP_B_ericsson_MAIN10_2.bit,WPP_B_ericsson_MAIN10_yuv.md5,10 ++1,HEVC_v1/WPP_B_ericsson_MAIN_2,WPP_B_ericsson_MAIN_2.bit,WPP_B_ericsson_MAIN_2_yuv.md5,8 ++1,HEVC_v1/WPP_C_ericsson_MAIN10_2,WPP_C_ericsson_MAIN10_2.bit,WPP_C_ericsson_MAIN10_yuv.md5,10 ++1,HEVC_v1/WPP_C_ericsson_MAIN_2,WPP_C_ericsson_MAIN_2.bit,WPP_C_ericsson_MAIN_2_yuv.md5,8 ++1,HEVC_v1/WPP_D_ericsson_MAIN10_2,WPP_D_ericsson_MAIN10_2.bit,WPP_D_ericsson_MAIN10_yuv.md5,10 ++1,HEVC_v1/WPP_D_ericsson_MAIN_2,WPP_D_ericsson_MAIN_2.bit,WPP_D_ericsson_MAIN_2_yuv.md5,8 ++1,HEVC_v1/WPP_E_ericsson_MAIN10_2,WPP_E_ericsson_MAIN10_2.bit,WPP_E_ericsson_MAIN10_yuv.md5,10 ++1,HEVC_v1/WPP_E_ericsson_MAIN_2,WPP_E_ericsson_MAIN_2.bit,WPP_E_ericsson_MAIN_2_yuv.md5,8 ++1,HEVC_v1/WPP_F_ericsson_MAIN10_2,WPP_F_ericsson_MAIN10_2.bit,WPP_F_ericsson_MAIN10_yuv.md5,10 ++1,HEVC_v1/WPP_F_ericsson_MAIN_2,WPP_F_ericsson_MAIN_2.bit,WPP_F_ericsson_MAIN_2_yuv.md5,8 ++1,RExt/ADJUST_IPRED_ANGLE_A_RExt_Mitsubishi_2,ADJUST_IPRED_ANGLE_A_RExt_Mitsubishi_2.bit,ADJUST_IPRED_ANGLE_A_RExt_Mitsubishi_yuv_2.md5,0 ++0,RExt/Bitdepth_A_RExt_Sony_1,Bitdepth_A_RExt_Sony_1.bin,md5sum.txt,8 ++0,RExt/Bitdepth_B_RExt_Sony_1,Bitdepth_B_RExt_Sony_1.bin,md5sum.txt,8 ++0,RExt/CCP_10bit_RExt_QCOM,CCP_10bit_RExt_QCOM.bin,CCP_10bit_RExt_QCOM_md5sum.txt,10 ++0,RExt/CCP_12bit_RExt_QCOM,CCP_12bit_RExt_QCOM.bin,CCP_12bit_RExt_QCOM_md5sum.txt,8 ++0,RExt/CCP_8bit_RExt_QCOM,CCP_8bit_RExt_QCOM.bin,CCP_8bit_RExt_QCOM_md5sum.txt,8 ++1,RExt/ExplicitRdpcm_A_BBC_1,ExplicitRdpcm_A_BBC_1.bit,md5sum.txt,0 ++0,RExt/ExplicitRdpcm_B_BBC_2,ExplicitRdpcm_B_BBC_1.bit,md5sum.txt,8 ++0,RExt/EXTPREC_HIGHTHROUGHPUT_444_16_INTRA_10BIT_RExt_Sony_1,EXTPREC_HIGHTHROUGHPUT_444_16_INTRA_10BIT_RExt_Sony_1.bit,EXTPREC_HIGHTHROUGHPUT_444_16_INTRA_10BIT_RExt_Sony_1.md5,10 ++0,RExt/EXTPREC_HIGHTHROUGHPUT_444_16_INTRA_12BIT_RExt_Sony_1,EXTPREC_HIGHTHROUGHPUT_444_16_INTRA_12BIT_RExt_Sony_1.bit,EXTPREC_HIGHTHROUGHPUT_444_16_INTRA_12BIT_RExt_Sony_1.md5,8 ++0,RExt/EXTPREC_HIGHTHROUGHPUT_444_16_INTRA_16BIT_RExt_Sony_1,EXTPREC_HIGHTHROUGHPUT_444_16_INTRA_16BIT_RExt_Sony_1.bit,EXTPREC_HIGHTHROUGHPUT_444_16_INTRA_16BIT_RExt_Sony_1.md5,8 ++0,RExt/EXTPREC_HIGHTHROUGHPUT_444_16_INTRA_8BIT_RExt_Sony_1,EXTPREC_HIGHTHROUGHPUT_444_16_INTRA_8BIT_RExt_Sony_1.bit,EXTPREC_HIGHTHROUGHPUT_444_16_INTRA_8BIT_RExt_Sony_1.md5,8 ++0,RExt/EXTPREC_MAIN_444_16_INTRA_10BIT_RExt_Sony_1,EXTPREC_MAIN_444_16_INTRA_10BIT_RExt_Sony_1.bit,EXTPREC_MAIN_444_16_INTRA_10BIT_RExt_Sony_1.md5,10 ++0,RExt/EXTPREC_MAIN_444_16_INTRA_12BIT_RExt_Sony_1,EXTPREC_MAIN_444_16_INTRA_12BIT_RExt_Sony_1.bit,EXTPREC_MAIN_444_16_INTRA_12BIT_RExt_Sony_1.md5,8 ++0,RExt/EXTPREC_MAIN_444_16_INTRA_16BIT_RExt_Sony_1,EXTPREC_MAIN_444_16_INTRA_16BIT_RExt_Sony_1.bit,EXTPREC_MAIN_444_16_INTRA_16BIT_RExt_Sony_1.md5,8 ++0,RExt/EXTPREC_MAIN_444_16_INTRA_8BIT_RExt_Sony_1,EXTPREC_MAIN_444_16_INTRA_8BIT_RExt_Sony_1.bit,EXTPREC_MAIN_444_16_INTRA_8BIT_RExt_Sony_1.md5,8 ++1,RExt/GENERAL_10b_420_RExt_Sony_1,GENERAL_10b_420_RExt_Sony_1.bit,GENERAL_10b_420_RExt_Sony_1.md5,10 ++1,RExt/GENERAL_10b_422_RExt_Sony_1,GENERAL_10b_422_RExt_Sony_1.bit,GENERAL_10b_422_RExt_Sony_1.md5,0 ++1,RExt/GENERAL_10b_444_RExt_Sony_2,GENERAL_10b_444_RExt_Sony_2.bit,GENERAL_10b_444_RExt_Sony_2.md5,0 ++1,RExt/GENERAL_12b_400_RExt_Sony_1,GENERAL_12b_400_RExt_Sony_1.bit,GENERAL_12b_400_RExt_Sony_1.md5,0 ++1,RExt/GENERAL_12b_420_RExt_Sony_1,GENERAL_12b_420_RExt_Sony_1.bit,GENERAL_12b_420_RExt_Sony_1.md5,0 ++1,RExt/GENERAL_12b_422_RExt_Sony_1,GENERAL_12b_422_RExt_Sony_1.bit,GENERAL_12b_422_RExt_Sony_1.md5,0 ++1,RExt/GENERAL_12b_444_RExt_Sony_2,GENERAL_12b_444_RExt_Sony_2.bit,GENERAL_12b_444_RExt_Sony_2.md5,0 ++0,RExt/GENERAL_16b_400_RExt_Sony_1,GENERAL_16b_400_RExt_Sony_1.bit,GENERAL_16b_400_RExt_Sony_1.md5,0 ++0,RExt/GENERAL_16b_444_highThroughput_RExt_Sony_2,GENERAL_16b_444_highThroughput_RExt_Sony_2.bit,GENERAL_16b_444_highThroughput_RExt_Sony_2.md5,8 ++0,RExt/GENERAL_16b_444_RExt_Sony_2,GENERAL_16b_444_RExt_Sony_2.bit,GENERAL_16b_444_RExt_Sony_2.md5,8 ++1,RExt/GENERAL_8b_400_RExt_Sony_1,GENERAL_8b_400_RExt_Sony_1.bit,GENERAL_8b_400_RExt_Sony_1.md5,0 ++1,RExt/GENERAL_8b_420_RExt_Sony_1,GENERAL_8b_420_RExt_Sony_1.bit,GENERAL_8b_420_RExt_Sony_1.md5,8 ++1,RExt/GENERAL_8b_444_RExt_Sony_2,GENERAL_8b_444_RExt_Sony_2.bit,GENERAL_8b_444_RExt_Sony_2.md5,0 ++1,RExt/IPCM_A_RExt_NEC_2,IPCM_A_RExt_NEC_2.bit,IPCM_A_RExt_NEC_2_yuv.md5,0 ++1,RExt/IPCM_B_RExt_NEC,IPCM_B_RExt_NEC.bit,IPCM_B_RExt_NEC_yuv.md5,0 ++1,RExt/Main_422_10_A_RExt_Sony_2,Main_422_10_A_RExt_Sony_2.bin,md5sum.txt,0 ++1,RExt/Main_422_10_B_RExt_Sony_2,Main_422_10_B_RExt_Sony_2.bin,md5sum.txt,0 ++1,RExt/PERSIST_RPARAM_A_RExt_Sony_3,PERSIST_RPARAM_A_RExt_Sony_3.bit,PERSIST_RPARAM_A_RExt_Sony_3.md5,0 ++1,RExt/QMATRIX_A_RExt_Sony_1,QMATRIX_A_RExt_Sony_1.bit,QMATRIX_A_RExt_Sony_1.md5,0 ++0,RExt/SAO_A_RExt_MediaTek_1,SAO_A_RExt_MediaTek_1.bit,SAO_A_RExt_MediaTek_1.md5, # Runs out of memory - could be fixed,8 ++0,RExt/TSCTX_10bit_I_RExt_SHARP_1,TSCTX_10bit_I_RExt_SHARP_1.bin,TSCTX_10bit_I_RExt_SHARP_1.md5,10 ++0,RExt/TSCTX_10bit_RExt_SHARP_1,TSCTX_10bit_RExt_SHARP_1.bin,TSCTX_10bit_RExt_SHARP_1.md5,10 ++0,RExt/TSCTX_12bit_I_RExt_SHARP_1,TSCTX_12bit_I_RExt_SHARP_1.bin,TSCTX_12bit_I_RExt_SHARP_1.md5,8 ++0,RExt/TSCTX_12bit_RExt_SHARP_1,TSCTX_12bit_RExt_SHARP_1.bin,TSCTX_12bit_RExt_SHARP_1.md5,8 ++0,RExt/TSCTX_8bit_I_RExt_SHARP_1,TSCTX_8bit_I_RExt_SHARP_1.bin,TSCTX_8bit_I_RExt_SHARP_1.md5,8 ++0,RExt/TSCTX_8bit_RExt_SHARP_1,TSCTX_8bit_RExt_SHARP_1.bin,TSCTX_8bit_RExt_SHARP_1.md5,8 ++0,RExt/WAVETILES_RExt_Sony_2,WAVETILES_RExt_Sony_2.bit,WAVETILES_RExt_Sony_2.md5,8 ++1,local/sao_cu16_mobile_344x280,sao_cu16_mobile_344x280.265,sao_cu16_mobile_344x280.md5,8 ++1,local/dblk_cu16_mobile_344x280,dblk_cu16_mobile_344x280.265,dblk_cu16_mobile_344x280.md5,8 ++1,local/dblksao_cu16_mobile_344x280,dblksao_cu16_mobile_344x280.265,dblksao_cu16_mobile_344x280.md5,8 ++1,local/dblk_pu32_horses_832x448,dblk_pu32_horses_832x448.265,dblk_pu32_horses_832x448.md5,8 ++1,local/intra_pred_21_laps,intra_pred_21_laps.265,intra_pred_21_laps.md5,8 --- /dev/null +++ b/pi-util/conf_h265.2016_HEVC_v1.csv @@ -0,0 +1,147 @@ -+1,AMP_A_Samsung_7,AMP_A_Samsung_7.bin,AMP_A_Samsung_7.md5 -+1,AMP_B_Samsung_7,AMP_B_Samsung_7.bin,AMP_B_Samsung_7.md5 -+1,AMP_D_Hisilicon_3,AMP_D_Hisilicon.bit,AMP_D_Hisilicon_3.yuv.md5 -+1,AMP_E_Hisilicon_3,AMP_E_Hisilicon.bit,AMP_E_Hisilicon_3.yuv.md5 -+1,AMP_F_Hisilicon_3,AMP_F_Hisilicon_3.bit,AMP_F_Hisilicon_3.yuv.md5 -+1,AMVP_A_MTK_4,AMVP_A_MTK_4.bit,AMVP_A_MTK_4.md5 -+1,AMVP_B_MTK_4,AMVP_B_MTK_4.bit,AMVP_B_MTK_4.md5 -+1,AMVP_C_Samsung_7,AMVP_C_Samsung_7.bin,AMVP_C_Samsung_7.md5 -+1,BUMPING_A_ericsson_1,BUMPING_A_ericsson_1.bit,BUMPING_A_ericsson_1.md5 -+1,CAINIT_A_SHARP_4,CAINIT_A_SHARP_4.bit,CAINIT_A_SHARP_4.md5 -+1,CAINIT_B_SHARP_4,CAINIT_B_SHARP_4.bit,CAINIT_B_SHARP_4.md5 -+1,CAINIT_C_SHARP_3,CAINIT_C_SHARP_3.bit,CAINIT_C_SHARP_3.md5 -+1,CAINIT_D_SHARP_3,CAINIT_D_SHARP_3.bit,CAINIT_D_SHARP_3.md5 -+1,CAINIT_E_SHARP_3,CAINIT_E_SHARP_3.bit,CAINIT_E_SHARP_3.md5 -+1,CAINIT_F_SHARP_3,CAINIT_F_SHARP_3.bit,CAINIT_F_SHARP_3.md5 -+1,CAINIT_G_SHARP_3,CAINIT_G_SHARP_3.bit,CAINIT_G_SHARP_3.md5 -+1,CAINIT_H_SHARP_3,CAINIT_H_SHARP_3.bit,CAINIT_H_SHARP_3.md5 -+1,CIP_A_Panasonic_3,CIP_A_Panasonic_3.bit,CIP_A_Panasonic_3_yuv.md5 -+1,cip_B_NEC_3,cip_B_NEC_3.bit,cip_B_NEC_3.md5 -+1,CIP_C_Panasonic_2,CIP_C_Panasonic_2.bit,CIP_C_Panasonic_2_yuv.md5 -+1,CONFWIN_A_Sony_1,CONFWIN_A_Sony_1.bit,CONFWIN_A_Sony_1.md5 -+1,DBLK_A_MAIN10_VIXS_4,DBLK_A_MAIN10_VIXS_4.bit,DBLK_A_MAIN10_VIXS_4.md5 -+1,DBLK_A_SONY_3,DBLK_A_SONY_3.bit,DBLK_A_SONY_3.bit.yuv.md5 -+1,DBLK_B_SONY_3,DBLK_B_SONY_3.bit,DBLK_B_SONY_3.bit.yuv.md5 -+1,DBLK_C_SONY_3,DBLK_C_SONY_3.bit,DBLK_C_SONY_3.bit.yuv.md5 -+1,DBLK_D_VIXS_2,DBLK_D_VIXS_2.bit,DBLK_D_VIXS_2_yuv.md5 -+1,DBLK_E_VIXS_2,DBLK_E_VIXS_2.bit,DBLK_E_VIXS_2_yuv.md5 -+1,DBLK_F_VIXS_2,DBLK_F_VIXS_2.bit,DBLK_F_VIXS_2_yuv.md5 -+1,DBLK_G_VIXS_2,DBLK_G_VIXS_2.bit,DBLK_G_VIXS_2_yuv.md5 -+1,DELTAQP_A_BRCM_4,DELTAQP_A_BRCM_4.bit,DELTAQP_A_BRCM_4_yuv.md5 -+1,DELTAQP_B_SONY_3,DELTAQP_B_SONY_3.bit,DELTAQP_B_SONY_3.bit.yuv.md5 -+1,DELTAQP_C_SONY_3,DELTAQP_C_SONY_3.bit,DELTAQP_C_SONY_3.bit.yuv.md5 -+1,DSLICE_A_HHI_5,DSLICE_A_HHI_5.bin,DSLICE_A_HHI_5.md5 -+1,DSLICE_B_HHI_5,DSLICE_B_HHI_5.bin,DSLICE_B_HHI_5.md5 -+1,DSLICE_C_HHI_5,DSLICE_C_HHI_5.bin,DSLICE_C_HHI_5.md5 -+1,ENTP_A_QUALCOMM_1,ENTP_A_Qualcomm_1.bit,ENTP_A_Qualcomm_1.md5 -+1,ENTP_B_Qualcomm_1,ENTP_B_Qualcomm_1.bit,ENTP_B_Qualcomm_1.md5 -+1,ENTP_C_Qualcomm_1,ENTP_C_Qualcomm_1.bit,ENTP_C_Qualcomm_1.md5 -+1,EXT_A_ericsson_4,EXT_A_ericsson_4.bit,EXT_A_ericsson_4.md5 -+1,FILLER_A_Sony_1,FILLER_A_Sony_1.bit,FILLER_A_Sony_1.md5 -+1,HRD_A_Fujitsu_3,HRD_A_Fujitsu_3.bin,HRD_A_Fujitsu_3.md5 -+1,INITQP_A_Sony_1,INITQP_A_Sony_1.bit,INITQP_A_Sony_1.md5 -+1,INITQP_B_Main10_Sony_1,INITQP_B_Main10_Sony_1.bit,INITQP_B_Main10_Sony_1.md5 -+1,ipcm_A_NEC_3,ipcm_A_NEC_3.bit,ipcm_A_NEC_3.md5 -+1,ipcm_B_NEC_3,ipcm_B_NEC_3.bit,ipcm_B_NEC_3.md5 -+1,ipcm_C_NEC_3,ipcm_C_NEC_3.bit,ipcm_C_NEC_3.md5 -+1,ipcm_D_NEC_3,ipcm_D_NEC_3.bit,ipcm_D_NEC_3.md5 -+1,ipcm_E_NEC_2,ipcm_E_NEC_2.bit,ipcm_E_NEC_2.md5 -+1,IPRED_A_docomo_2,IPRED_A_docomo_2.bit,IPRED_A_docomo_2.md5 -+1,IPRED_B_Nokia_3,IPRED_B_Nokia_3.bit,IPRED_B_Nokia_3_yuv.md5 -+1,IPRED_C_Mitsubishi_3,IPRED_C_Mitsubishi_3.bit,IPRED_C_Mitsubishi_3_yuv.md5 -+1,LS_A_Orange_2,LS_A_Orange_2.bit,LS_A_Orange_2_yuv.md5 -+1,LS_B_Orange_4,LS_B_Orange_4.bit,LS_B_Orange_4_yuv.md5 -+1,LTRPSPS_A_Qualcomm_1,LTRPSPS_A_Qualcomm_1.bit,LTRPSPS_A_Qualcomm_1.md5 -+1,MAXBINS_A_TI_5,MAXBINS_A_TI_5.bit,MAXBINS_A_TI_5_yuv.md5 -+1,MAXBINS_B_TI_5,MAXBINS_B_TI_5.bit,MAXBINS_B_TI_5_yuv.md5 -+1,MAXBINS_C_TI_5,MAXBINS_C_TI_5.bit,MAXBINS_C_TI_5_yuv.md5 -+1,MERGE_A_TI_3,MERGE_A_TI_3.bit,MERGE_A_TI_3.md5 -+1,MERGE_B_TI_3,MERGE_B_TI_3.bit,MERGE_B_TI_3.md5 -+1,MERGE_C_TI_3,MERGE_C_TI_3.bit,MERGE_C_TI_3.md5 -+1,MERGE_D_TI_3,MERGE_D_TI_3.bit,MERGE_D_TI_3.md5 -+1,MERGE_E_TI_3,MERGE_E_TI_3.bit,MERGE_E_TI_3.md5 -+1,MERGE_F_MTK_4,MERGE_F_MTK_4.bit,MERGE_F_MTK_4.md5 -+1,MERGE_G_HHI_4,MERGE_G_HHI_4.bit,MERGE_G_HHI_4.md5 -+1,MVCLIP_A_qualcomm_3,MVCLIP_A_qualcomm_3.bit,MVCLIP_A_qualcomm_3.yuv.md5 -+1,MVDL1ZERO_A_docomo_4,MVDL1ZERO_A_docomo_4.bit,MVDL1ZERO_A_docomo_4.md5 -+1,MVEDGE_A_qualcomm_3,MVEDGE_A_qualcomm_3.bit,MVEDGE_A_qualcomm_3.yuv.md5 -+1,NoOutPrior_A_Qualcomm_1,NoOutPrior_A_Qualcomm_1.bit,NoOutPrior_A_Qualcomm_1.md5 -+1,NoOutPrior_B_Qualcomm_1,NoOutPrior_B_Qualcomm_1.bit,NoOutPrior_B_Qualcomm_1.md5 -+1,NUT_A_ericsson_5,NUT_A_ericsson_5.bit,NUT_A_ericsson_5.md5 -+1,OPFLAG_A_Qualcomm_1,OPFLAG_A_Qualcomm_1.bit,OPFLAG_A_Qualcomm_1.md5 -+1,OPFLAG_B_Qualcomm_1,OPFLAG_B_Qualcomm_1.bit,OPFLAG_B_Qualcomm_1.md5 -+1,OPFLAG_C_Qualcomm_1,OPFLAG_C_Qualcomm_1.bit,OPFLAG_C_Qualcomm_1.md5 -+1,PICSIZE_A_Bossen_1,PICSIZE_A_Bossen_1.bin,PICSIZE_A_Bossen_1.md5 -+1,PICSIZE_B_Bossen_1,PICSIZE_B_Bossen_1.bin,PICSIZE_B_Bossen_1.md5 -+1,PICSIZE_C_Bossen_1,PICSIZE_C_Bossen_1.bin,PICSIZE_C_Bossen_1.md5 -+1,PICSIZE_D_Bossen_1,PICSIZE_D_Bossen_1.bin,PICSIZE_D_Bossen_1.md5 -+1,PMERGE_A_TI_3,PMERGE_A_TI_3.bit,PMERGE_A_TI_3.md5 -+1,PMERGE_B_TI_3,PMERGE_B_TI_3.bit,PMERGE_B_TI_3.md5 -+1,PMERGE_C_TI_3,PMERGE_C_TI_3.bit,PMERGE_C_TI_3.md5 -+1,PMERGE_D_TI_3,PMERGE_D_TI_3.bit,PMERGE_D_TI_3.md5 -+1,PMERGE_E_TI_3,PMERGE_E_TI_3.bit,PMERGE_E_TI_3.md5 -+1,POC_A_Bossen_3,POC_A_Bossen_3.bin,POC_A_Bossen_3.md5 -+1,PPS_A_qualcomm_7,PPS_A_qualcomm_7.bit,PPS_A_qualcomm_7.yuv.md5 -+1,PS_B_VIDYO_3,PS_B_VIDYO_3.bit,PS_B_VIDYO_3_yuv.md5 -+1,RAP_A_docomo_6,RAP_A_docomo_6.bit,RAP_A_docomo_6.md5 -+1,RAP_B_Bossen_2,RAP_B_Bossen_2.bit,RAP_B_Bossen_2.md5 -+1,RPLM_A_qualcomm_4,RPLM_A_qualcomm_4.bit,RPLM_A_qualcomm_4.yuv.md5 -+1,RPLM_B_qualcomm_4,RPLM_B_qualcomm_4.bit,RPLM_B_qualcomm_4.yuv.md5 -+1,RPS_A_docomo_5,RPS_A_docomo_5.bit,RPS_A_docomo_5.md5 -+1,RPS_B_qualcomm_5,RPS_B_qualcomm_5.bit,RPS_B_qualcomm_5.yuv.md5 -+1,RPS_C_ericsson_5,RPS_C_ericsson_5.bit,RPS_C_ericsson_5.md5 -+1,RPS_D_ericsson_6,RPS_D_ericsson_6.bit,RPS_D_ericsson_6.md5 -+1,RPS_E_qualcomm_5,RPS_E_qualcomm_5.bit,RPS_E_qualcomm_5.yuv.md5 -+1,RPS_F_docomo_2,RPS_F_docomo_2.bit,RPS_F_docomo_2.md5 -+1,RQT_A_HHI_4,RQT_A_HHI_4.bit,RQT_A_HHI_4.md5 -+1,RQT_B_HHI_4,RQT_B_HHI_4.bit,RQT_B_HHI_4.md5 -+1,RQT_C_HHI_4,RQT_C_HHI_4.bit,RQT_C_HHI_4.md5 -+1,RQT_D_HHI_4,RQT_D_HHI_4.bit,RQT_D_HHI_4.md5 -+1,RQT_E_HHI_4,RQT_E_HHI_4.bit,RQT_E_HHI_4.md5 -+1,RQT_F_HHI_4,RQT_F_HHI_4.bit,RQT_F_HHI_4.md5 -+1,RQT_G_HHI_4,RQT_G_HHI_4.bit,RQT_G_HHI_4.md5 -+1,SAO_A_MediaTek_4,SAO_A_MediaTek_4.bit,SAO_A_MediaTek_4.md5 -+1,SAO_B_MediaTek_5,SAO_B_MediaTek_5.bit,SAO_B_MediaTek_5.md5 -+1,SAO_C_Samsung_5,SAO_C_Samsung_5.bin,SAO_C_Samsung_5.md5 -+1,SAO_D_Samsung_5,SAO_D_Samsung_5.bin,SAO_D_Samsung_5.md5 -+1,SAO_E_Canon_4,SAO_E_Canon_4.bit,SAO_E_Canon_4.md5 -+1,SAO_F_Canon_3,SAO_F_Canon_3.bit,SAO_F_Canon_3.md5 -+1,SAO_G_Canon_3,SAO_G_Canon_3.bit,SAO_G_Canon_3.md5 -+1,SAO_H_Parabola_1,SAO_H_Parabola_1.bit,SAO_H_Parabola_1.md5 -+2,SAODBLK_A_MainConcept_4,SAODBLK_A_MainConcept_4.bin,SAODBLK_A_MainConcept_4_md5.txt -+2,SAODBLK_B_MainConcept_4,SAODBLK_B_MainConcept_4.bin,SAODBLK_B_MainConcept_4_md5.txt -+1,SDH_A_Orange_4,SDH_A_Orange_4.bit,SDH_A_Orange_4_yuv.md5 -+1,SLICES_A_Rovi_3,SLICES_A_Rovi_3.bin,SLICES_A_Rovi_3.md5 -+1,SLIST_A_Sony_5,SLIST_A_Sony_5.bin,SLIST_A_Sony_5_yuv.md5 -+1,SLIST_B_Sony_9,SLIST_B_Sony_9.bin,SLIST_B_Sony_9_yuv.md5 -+1,SLIST_C_Sony_4,SLIST_C_Sony_4.bin,SLIST_C_Sony_4_yuv.md5 -+1,SLIST_D_Sony_9,str.bin,SLIST_D_Sony_9_yuv.md5 -+1,SLPPLP_A_VIDYO_2,SLPPLP_A_VIDYO_2.bit,SLPPLP_A_VIDYO_2_yuv.md5 -+1,STRUCT_A_Samsung_7,STRUCT_A_Samsung_7.bin,STRUCT_A_Samsung_7.md5 -+1,STRUCT_B_Samsung_7,STRUCT_B_Samsung_7.bin,STRUCT_B_Samsung_7.md5 -+1,TILES_A_Cisco_2,TILES_A_Cisco_2.bin,TILES_A_Cisco_2_yuv.md5 -+1,TILES_B_Cisco_1,TILES_B_Cisco_1.bin,TILES_B_Cisco_1_yuv.md5 -+1,TMVP_A_MS_3,TMVP_A_MS_3.bit,TMVP_A_MS_3.yuv.md5 -+1,TSCL_A_VIDYO_5,TSCL_A_VIDYO_5.bit,TSCL_A_VIDYO_5_yuv.md5 -+1,TSCL_B_VIDYO_4,TSCL_B_VIDYO_4.bit,TSCL_B_VIDYO_4_yuv.md5 -+1,TSKIP_A_MS_3,TSKIP_A_MS_3.bit,TSKIP_A_MS_3.yuv.md5 -+3,TSUNEQBD_A_MAIN10_Technicolor_2,TSUNEQBD_A_MAIN10_Technicolor_2.bit,TSUNEQBD_A_MAIN10_Technicolor_2_yuv.md5, # unequal bit depth -+1,TUSIZE_A_Samsung_1,TUSIZE_A_Samsung_1.bin,TUSIZE_A_Samsung_1.md5 -+1,VPSID_A_VIDYO_2,VPSID_A_VIDYO_2.bit,VPSID_A_VIDYO_2_yuv.md5 -+3,VPSSPSPPS_A_MainConcept_1,VPSSPSPPS_A_MainConcept_1.bin,VPSSPSPPS_A_MainConcept_1_md5.txt, # ??? -+1,WP_A_MAIN10_Toshiba_3,WP_A_MAIN10_Toshiba_3.bit,WP_A_MAIN10_Toshiba_3_yuv.md5 -+1,WP_A_Toshiba_3,WP_A_Toshiba_3.bit,WP_A_Toshiba_3_yuv.md5 -+1,WP_B_Toshiba_3,WP_B_Toshiba_3.bit,WP_B_Toshiba_3_yuv.md5 -+1,WP_MAIN10_B_Toshiba_3,WP_MAIN10_B_Toshiba_3.bit,WP_MAIN10_B_Toshiba_3_yuv.md5 -+1,WPP_A_ericsson_MAIN10_2,WPP_A_ericsson_MAIN10_2.bit,WPP_A_ericsson_MAIN10_yuv.md5 -+1,WPP_A_ericsson_MAIN_2,WPP_A_ericsson_MAIN_2.bit,WPP_A_ericsson_MAIN_2_yuv.md5 -+1,WPP_B_ericsson_MAIN10_2,WPP_B_ericsson_MAIN10_2.bit,WPP_B_ericsson_MAIN10_yuv.md5 -+1,WPP_B_ericsson_MAIN_2,WPP_B_ericsson_MAIN_2.bit,WPP_B_ericsson_MAIN_2_yuv.md5 -+1,WPP_C_ericsson_MAIN10_2,WPP_C_ericsson_MAIN10_2.bit,WPP_C_ericsson_MAIN10_yuv.md5 -+1,WPP_C_ericsson_MAIN_2,WPP_C_ericsson_MAIN_2.bit,WPP_C_ericsson_MAIN_2_yuv.md5 -+1,WPP_D_ericsson_MAIN10_2,WPP_D_ericsson_MAIN10_2.bit,WPP_D_ericsson_MAIN10_yuv.md5 -+1,WPP_D_ericsson_MAIN_2,WPP_D_ericsson_MAIN_2.bit,WPP_D_ericsson_MAIN_2_yuv.md5 -+1,WPP_E_ericsson_MAIN10_2,WPP_E_ericsson_MAIN10_2.bit,WPP_E_ericsson_MAIN10_yuv.md5 -+1,WPP_E_ericsson_MAIN_2,WPP_E_ericsson_MAIN_2.bit,WPP_E_ericsson_MAIN_2_yuv.md5 -+1,WPP_F_ericsson_MAIN10_2,WPP_F_ericsson_MAIN10_2.bit,WPP_F_ericsson_MAIN10_yuv.md5 -+1,WPP_F_ericsson_MAIN_2,WPP_F_ericsson_MAIN_2.bit,WPP_F_ericsson_MAIN_2_yuv.md5 ++1,AMP_A_Samsung_7,AMP_A_Samsung_7.bin,AMP_A_Samsung_7.md5 ++1,AMP_B_Samsung_7,AMP_B_Samsung_7.bin,AMP_B_Samsung_7.md5 ++1,AMP_D_Hisilicon_3,AMP_D_Hisilicon.bit,AMP_D_Hisilicon_3.yuv.md5 ++1,AMP_E_Hisilicon_3,AMP_E_Hisilicon.bit,AMP_E_Hisilicon_3.yuv.md5 ++1,AMP_F_Hisilicon_3,AMP_F_Hisilicon_3.bit,AMP_F_Hisilicon_3.yuv.md5 ++1,AMVP_A_MTK_4,AMVP_A_MTK_4.bit,AMVP_A_MTK_4.md5 ++1,AMVP_B_MTK_4,AMVP_B_MTK_4.bit,AMVP_B_MTK_4.md5 ++1,AMVP_C_Samsung_7,AMVP_C_Samsung_7.bin,AMVP_C_Samsung_7.md5 ++1,BUMPING_A_ericsson_1,BUMPING_A_ericsson_1.bit,BUMPING_A_ericsson_1.md5 ++1,CAINIT_A_SHARP_4,CAINIT_A_SHARP_4.bit,CAINIT_A_SHARP_4.md5 ++1,CAINIT_B_SHARP_4,CAINIT_B_SHARP_4.bit,CAINIT_B_SHARP_4.md5 ++1,CAINIT_C_SHARP_3,CAINIT_C_SHARP_3.bit,CAINIT_C_SHARP_3.md5 ++1,CAINIT_D_SHARP_3,CAINIT_D_SHARP_3.bit,CAINIT_D_SHARP_3.md5 ++1,CAINIT_E_SHARP_3,CAINIT_E_SHARP_3.bit,CAINIT_E_SHARP_3.md5 ++1,CAINIT_F_SHARP_3,CAINIT_F_SHARP_3.bit,CAINIT_F_SHARP_3.md5 ++1,CAINIT_G_SHARP_3,CAINIT_G_SHARP_3.bit,CAINIT_G_SHARP_3.md5 ++1,CAINIT_H_SHARP_3,CAINIT_H_SHARP_3.bit,CAINIT_H_SHARP_3.md5 ++1,CIP_A_Panasonic_3,CIP_A_Panasonic_3.bit,CIP_A_Panasonic_3_yuv.md5 ++1,cip_B_NEC_3,cip_B_NEC_3.bit,cip_B_NEC_3.md5 ++1,CIP_C_Panasonic_2,CIP_C_Panasonic_2.bit,CIP_C_Panasonic_2_yuv.md5 ++1,CONFWIN_A_Sony_1,CONFWIN_A_Sony_1.bit,CONFWIN_A_Sony_1.md5 ++1,DBLK_A_MAIN10_VIXS_4,DBLK_A_MAIN10_VIXS_4.bit,DBLK_A_MAIN10_VIXS_4.md5 ++1,DBLK_A_SONY_3,DBLK_A_SONY_3.bit,DBLK_A_SONY_3.bit.yuv.md5 ++1,DBLK_B_SONY_3,DBLK_B_SONY_3.bit,DBLK_B_SONY_3.bit.yuv.md5 ++1,DBLK_C_SONY_3,DBLK_C_SONY_3.bit,DBLK_C_SONY_3.bit.yuv.md5 ++1,DBLK_D_VIXS_2,DBLK_D_VIXS_2.bit,DBLK_D_VIXS_2_yuv.md5 ++1,DBLK_E_VIXS_2,DBLK_E_VIXS_2.bit,DBLK_E_VIXS_2_yuv.md5 ++1,DBLK_F_VIXS_2,DBLK_F_VIXS_2.bit,DBLK_F_VIXS_2_yuv.md5 ++1,DBLK_G_VIXS_2,DBLK_G_VIXS_2.bit,DBLK_G_VIXS_2_yuv.md5 ++1,DELTAQP_A_BRCM_4,DELTAQP_A_BRCM_4.bit,DELTAQP_A_BRCM_4_yuv.md5 ++1,DELTAQP_B_SONY_3,DELTAQP_B_SONY_3.bit,DELTAQP_B_SONY_3.bit.yuv.md5 ++1,DELTAQP_C_SONY_3,DELTAQP_C_SONY_3.bit,DELTAQP_C_SONY_3.bit.yuv.md5 ++1,DSLICE_A_HHI_5,DSLICE_A_HHI_5.bin,DSLICE_A_HHI_5.md5 ++1,DSLICE_B_HHI_5,DSLICE_B_HHI_5.bin,DSLICE_B_HHI_5.md5 ++1,DSLICE_C_HHI_5,DSLICE_C_HHI_5.bin,DSLICE_C_HHI_5.md5 ++1,ENTP_A_QUALCOMM_1,ENTP_A_Qualcomm_1.bit,ENTP_A_Qualcomm_1.md5 ++1,ENTP_B_Qualcomm_1,ENTP_B_Qualcomm_1.bit,ENTP_B_Qualcomm_1.md5 ++1,ENTP_C_Qualcomm_1,ENTP_C_Qualcomm_1.bit,ENTP_C_Qualcomm_1.md5 ++1,EXT_A_ericsson_4,EXT_A_ericsson_4.bit,EXT_A_ericsson_4.md5 ++1,FILLER_A_Sony_1,FILLER_A_Sony_1.bit,FILLER_A_Sony_1.md5 ++1,HRD_A_Fujitsu_3,HRD_A_Fujitsu_3.bin,HRD_A_Fujitsu_3.md5 ++1,INITQP_A_Sony_1,INITQP_A_Sony_1.bit,INITQP_A_Sony_1.md5 ++1,INITQP_B_Main10_Sony_1,INITQP_B_Main10_Sony_1.bit,INITQP_B_Main10_Sony_1.md5 ++1,ipcm_A_NEC_3,ipcm_A_NEC_3.bit,ipcm_A_NEC_3.md5 ++1,ipcm_B_NEC_3,ipcm_B_NEC_3.bit,ipcm_B_NEC_3.md5 ++1,ipcm_C_NEC_3,ipcm_C_NEC_3.bit,ipcm_C_NEC_3.md5 ++1,ipcm_D_NEC_3,ipcm_D_NEC_3.bit,ipcm_D_NEC_3.md5 ++1,ipcm_E_NEC_2,ipcm_E_NEC_2.bit,ipcm_E_NEC_2.md5 ++1,IPRED_A_docomo_2,IPRED_A_docomo_2.bit,IPRED_A_docomo_2.md5 ++1,IPRED_B_Nokia_3,IPRED_B_Nokia_3.bit,IPRED_B_Nokia_3_yuv.md5 ++1,IPRED_C_Mitsubishi_3,IPRED_C_Mitsubishi_3.bit,IPRED_C_Mitsubishi_3_yuv.md5 ++1,LS_A_Orange_2,LS_A_Orange_2.bit,LS_A_Orange_2_yuv.md5 ++1,LS_B_Orange_4,LS_B_Orange_4.bit,LS_B_Orange_4_yuv.md5 ++1,LTRPSPS_A_Qualcomm_1,LTRPSPS_A_Qualcomm_1.bit,LTRPSPS_A_Qualcomm_1.md5 ++1,MAXBINS_A_TI_5,MAXBINS_A_TI_5.bit,MAXBINS_A_TI_5_yuv.md5 ++1,MAXBINS_B_TI_5,MAXBINS_B_TI_5.bit,MAXBINS_B_TI_5_yuv.md5 ++1,MAXBINS_C_TI_5,MAXBINS_C_TI_5.bit,MAXBINS_C_TI_5_yuv.md5 ++1,MERGE_A_TI_3,MERGE_A_TI_3.bit,MERGE_A_TI_3.md5 ++1,MERGE_B_TI_3,MERGE_B_TI_3.bit,MERGE_B_TI_3.md5 ++1,MERGE_C_TI_3,MERGE_C_TI_3.bit,MERGE_C_TI_3.md5 ++1,MERGE_D_TI_3,MERGE_D_TI_3.bit,MERGE_D_TI_3.md5 ++1,MERGE_E_TI_3,MERGE_E_TI_3.bit,MERGE_E_TI_3.md5 ++1,MERGE_F_MTK_4,MERGE_F_MTK_4.bit,MERGE_F_MTK_4.md5 ++1,MERGE_G_HHI_4,MERGE_G_HHI_4.bit,MERGE_G_HHI_4.md5 ++1,MVCLIP_A_qualcomm_3,MVCLIP_A_qualcomm_3.bit,MVCLIP_A_qualcomm_3.yuv.md5 ++1,MVDL1ZERO_A_docomo_4,MVDL1ZERO_A_docomo_4.bit,MVDL1ZERO_A_docomo_4.md5 ++1,MVEDGE_A_qualcomm_3,MVEDGE_A_qualcomm_3.bit,MVEDGE_A_qualcomm_3.yuv.md5 ++1,NoOutPrior_A_Qualcomm_1,NoOutPrior_A_Qualcomm_1.bit,NoOutPrior_A_Qualcomm_1.md5 ++1,NoOutPrior_B_Qualcomm_1,NoOutPrior_B_Qualcomm_1.bit,NoOutPrior_B_Qualcomm_1.md5 ++1,NUT_A_ericsson_5,NUT_A_ericsson_5.bit,NUT_A_ericsson_5.md5 ++1,OPFLAG_A_Qualcomm_1,OPFLAG_A_Qualcomm_1.bit,OPFLAG_A_Qualcomm_1.md5 ++1,OPFLAG_B_Qualcomm_1,OPFLAG_B_Qualcomm_1.bit,OPFLAG_B_Qualcomm_1.md5 ++1,OPFLAG_C_Qualcomm_1,OPFLAG_C_Qualcomm_1.bit,OPFLAG_C_Qualcomm_1.md5 ++1,PICSIZE_A_Bossen_1,PICSIZE_A_Bossen_1.bin,PICSIZE_A_Bossen_1.md5 ++1,PICSIZE_B_Bossen_1,PICSIZE_B_Bossen_1.bin,PICSIZE_B_Bossen_1.md5 ++1,PICSIZE_C_Bossen_1,PICSIZE_C_Bossen_1.bin,PICSIZE_C_Bossen_1.md5 ++1,PICSIZE_D_Bossen_1,PICSIZE_D_Bossen_1.bin,PICSIZE_D_Bossen_1.md5 ++1,PMERGE_A_TI_3,PMERGE_A_TI_3.bit,PMERGE_A_TI_3.md5 ++1,PMERGE_B_TI_3,PMERGE_B_TI_3.bit,PMERGE_B_TI_3.md5 ++1,PMERGE_C_TI_3,PMERGE_C_TI_3.bit,PMERGE_C_TI_3.md5 ++1,PMERGE_D_TI_3,PMERGE_D_TI_3.bit,PMERGE_D_TI_3.md5 ++1,PMERGE_E_TI_3,PMERGE_E_TI_3.bit,PMERGE_E_TI_3.md5 ++1,POC_A_Bossen_3,POC_A_Bossen_3.bin,POC_A_Bossen_3.md5 ++1,PPS_A_qualcomm_7,PPS_A_qualcomm_7.bit,PPS_A_qualcomm_7.yuv.md5 ++1,PS_B_VIDYO_3,PS_B_VIDYO_3.bit,PS_B_VIDYO_3_yuv.md5 ++1,RAP_A_docomo_6,RAP_A_docomo_6.bit,RAP_A_docomo_6.md5 ++1,RAP_B_Bossen_2,RAP_B_Bossen_2.bit,RAP_B_Bossen_2.md5 ++1,RPLM_A_qualcomm_4,RPLM_A_qualcomm_4.bit,RPLM_A_qualcomm_4.yuv.md5 ++1,RPLM_B_qualcomm_4,RPLM_B_qualcomm_4.bit,RPLM_B_qualcomm_4.yuv.md5 ++1,RPS_A_docomo_5,RPS_A_docomo_5.bit,RPS_A_docomo_5.md5 ++1,RPS_B_qualcomm_5,RPS_B_qualcomm_5.bit,RPS_B_qualcomm_5.yuv.md5 ++1,RPS_C_ericsson_5,RPS_C_ericsson_5.bit,RPS_C_ericsson_5.md5 ++1,RPS_D_ericsson_6,RPS_D_ericsson_6.bit,RPS_D_ericsson_6.md5 ++1,RPS_E_qualcomm_5,RPS_E_qualcomm_5.bit,RPS_E_qualcomm_5.yuv.md5 ++1,RPS_F_docomo_2,RPS_F_docomo_2.bit,RPS_F_docomo_2.md5 ++1,RQT_A_HHI_4,RQT_A_HHI_4.bit,RQT_A_HHI_4.md5 ++1,RQT_B_HHI_4,RQT_B_HHI_4.bit,RQT_B_HHI_4.md5 ++1,RQT_C_HHI_4,RQT_C_HHI_4.bit,RQT_C_HHI_4.md5 ++1,RQT_D_HHI_4,RQT_D_HHI_4.bit,RQT_D_HHI_4.md5 ++1,RQT_E_HHI_4,RQT_E_HHI_4.bit,RQT_E_HHI_4.md5 ++1,RQT_F_HHI_4,RQT_F_HHI_4.bit,RQT_F_HHI_4.md5 ++1,RQT_G_HHI_4,RQT_G_HHI_4.bit,RQT_G_HHI_4.md5 ++1,SAO_A_MediaTek_4,SAO_A_MediaTek_4.bit,SAO_A_MediaTek_4.md5 ++1,SAO_B_MediaTek_5,SAO_B_MediaTek_5.bit,SAO_B_MediaTek_5.md5 ++1,SAO_C_Samsung_5,SAO_C_Samsung_5.bin,SAO_C_Samsung_5.md5 ++1,SAO_D_Samsung_5,SAO_D_Samsung_5.bin,SAO_D_Samsung_5.md5 ++1,SAO_E_Canon_4,SAO_E_Canon_4.bit,SAO_E_Canon_4.md5 ++1,SAO_F_Canon_3,SAO_F_Canon_3.bit,SAO_F_Canon_3.md5 ++1,SAO_G_Canon_3,SAO_G_Canon_3.bit,SAO_G_Canon_3.md5 ++1,SAO_H_Parabola_1,SAO_H_Parabola_1.bit,SAO_H_Parabola_1.md5 ++2,SAODBLK_A_MainConcept_4,SAODBLK_A_MainConcept_4.bin,SAODBLK_A_MainConcept_4_md5.txt ++2,SAODBLK_B_MainConcept_4,SAODBLK_B_MainConcept_4.bin,SAODBLK_B_MainConcept_4_md5.txt ++1,SDH_A_Orange_4,SDH_A_Orange_4.bit,SDH_A_Orange_4_yuv.md5 ++1,SLICES_A_Rovi_3,SLICES_A_Rovi_3.bin,SLICES_A_Rovi_3.md5 ++1,SLIST_A_Sony_5,SLIST_A_Sony_5.bin,SLIST_A_Sony_5_yuv.md5 ++1,SLIST_B_Sony_9,SLIST_B_Sony_9.bin,SLIST_B_Sony_9_yuv.md5 ++1,SLIST_C_Sony_4,SLIST_C_Sony_4.bin,SLIST_C_Sony_4_yuv.md5 ++1,SLIST_D_Sony_9,str.bin,SLIST_D_Sony_9_yuv.md5 ++1,SLPPLP_A_VIDYO_2,SLPPLP_A_VIDYO_2.bit,SLPPLP_A_VIDYO_2_yuv.md5 ++1,STRUCT_A_Samsung_7,STRUCT_A_Samsung_7.bin,STRUCT_A_Samsung_7.md5 ++1,STRUCT_B_Samsung_7,STRUCT_B_Samsung_7.bin,STRUCT_B_Samsung_7.md5 ++1,TILES_A_Cisco_2,TILES_A_Cisco_2.bin,TILES_A_Cisco_2_yuv.md5 ++1,TILES_B_Cisco_1,TILES_B_Cisco_1.bin,TILES_B_Cisco_1_yuv.md5 ++1,TMVP_A_MS_3,TMVP_A_MS_3.bit,TMVP_A_MS_3.yuv.md5 ++1,TSCL_A_VIDYO_5,TSCL_A_VIDYO_5.bit,TSCL_A_VIDYO_5_yuv.md5 ++1,TSCL_B_VIDYO_4,TSCL_B_VIDYO_4.bit,TSCL_B_VIDYO_4_yuv.md5 ++1,TSKIP_A_MS_3,TSKIP_A_MS_3.bit,TSKIP_A_MS_3.yuv.md5 ++3,TSUNEQBD_A_MAIN10_Technicolor_2,TSUNEQBD_A_MAIN10_Technicolor_2.bit,TSUNEQBD_A_MAIN10_Technicolor_2_yuv.md5, # unequal bit depth ++1,TUSIZE_A_Samsung_1,TUSIZE_A_Samsung_1.bin,TUSIZE_A_Samsung_1.md5 ++1,VPSID_A_VIDYO_2,VPSID_A_VIDYO_2.bit,VPSID_A_VIDYO_2_yuv.md5 ++3,VPSSPSPPS_A_MainConcept_1,VPSSPSPPS_A_MainConcept_1.bin,VPSSPSPPS_A_MainConcept_1_md5.txt, # ??? ++1,WP_A_MAIN10_Toshiba_3,WP_A_MAIN10_Toshiba_3.bit,WP_A_MAIN10_Toshiba_3_yuv.md5 ++1,WP_A_Toshiba_3,WP_A_Toshiba_3.bit,WP_A_Toshiba_3_yuv.md5 ++1,WP_B_Toshiba_3,WP_B_Toshiba_3.bit,WP_B_Toshiba_3_yuv.md5 ++1,WP_MAIN10_B_Toshiba_3,WP_MAIN10_B_Toshiba_3.bit,WP_MAIN10_B_Toshiba_3_yuv.md5 ++1,WPP_A_ericsson_MAIN10_2,WPP_A_ericsson_MAIN10_2.bit,WPP_A_ericsson_MAIN10_yuv.md5 ++1,WPP_A_ericsson_MAIN_2,WPP_A_ericsson_MAIN_2.bit,WPP_A_ericsson_MAIN_2_yuv.md5 ++1,WPP_B_ericsson_MAIN10_2,WPP_B_ericsson_MAIN10_2.bit,WPP_B_ericsson_MAIN10_yuv.md5 ++1,WPP_B_ericsson_MAIN_2,WPP_B_ericsson_MAIN_2.bit,WPP_B_ericsson_MAIN_2_yuv.md5 ++1,WPP_C_ericsson_MAIN10_2,WPP_C_ericsson_MAIN10_2.bit,WPP_C_ericsson_MAIN10_yuv.md5 ++1,WPP_C_ericsson_MAIN_2,WPP_C_ericsson_MAIN_2.bit,WPP_C_ericsson_MAIN_2_yuv.md5 ++1,WPP_D_ericsson_MAIN10_2,WPP_D_ericsson_MAIN10_2.bit,WPP_D_ericsson_MAIN10_yuv.md5 ++1,WPP_D_ericsson_MAIN_2,WPP_D_ericsson_MAIN_2.bit,WPP_D_ericsson_MAIN_2_yuv.md5 ++1,WPP_E_ericsson_MAIN10_2,WPP_E_ericsson_MAIN10_2.bit,WPP_E_ericsson_MAIN10_yuv.md5 ++1,WPP_E_ericsson_MAIN_2,WPP_E_ericsson_MAIN_2.bit,WPP_E_ericsson_MAIN_2_yuv.md5 ++1,WPP_F_ericsson_MAIN10_2,WPP_F_ericsson_MAIN10_2.bit,WPP_F_ericsson_MAIN10_yuv.md5 ++1,WPP_F_ericsson_MAIN_2,WPP_F_ericsson_MAIN_2.bit,WPP_F_ericsson_MAIN_2_yuv.md5 --- /dev/null +++ b/pi-util/conf_h265.csv @@ -0,0 +1,144 @@ -+1,ADJUST_IPRED_ANGLE_A_RExt_Mitsubishi_1,ADJUST_IPRED_ANGLE_A_RExt_Mitsubishi_1.bit,ADJUST_IPRED_ANGLE_A_RExt_Mitsubishi_1.md5 -+1,AMP_A_Samsung_6,AMP_A_Samsung_6.bin,AMP_A_Samsung_6.md5 -+1,AMP_B_Samsung_6,AMP_B_Samsung_6.bin,AMP_B_Samsung_6.md5 -+1,AMP_D_Hisilicon_3,AMP_D_Hisilicon.bit,AMP_D_Hisilicon_3.yuv.md5 -+1,AMP_E_Hisilicon_3,AMP_E_Hisilicon.bit,AMP_E_Hisilicon_3.yuv.md5 -+1,AMP_F_Hisilicon_3,AMP_F_Hisilicon_3.bit,AMP_F_Hisilicon_3.yuv.md5 -+1,AMVP_A_MTK_4,AMVP_A_MTK_4.bit,AMVP_A_MTK_4.md5 -+1,AMVP_B_MTK_4,AMVP_B_MTK_4.bit,AMVP_B_MTK_4.md5 -+1,AMVP_C_Samsung_6,AMVP_C_Samsung_6.bin,AMVP_C_Samsung_6.md5 -+1,BUMPING_A_ericsson_1,BUMPING_A_ericsson_1.bit,BUMPING_A_ericsson_1.md5 -+1,CAINIT_A_SHARP_4,CAINIT_A_SHARP_4.bit,CAINIT_A_SHARP_4.md5 -+1,CAINIT_B_SHARP_4,CAINIT_B_SHARP_4.bit,CAINIT_B_SHARP_4.md5 -+1,CAINIT_C_SHARP_3,CAINIT_C_SHARP_3.bit,CAINIT_C_SHARP_3.md5 -+1,CAINIT_D_SHARP_3,CAINIT_D_SHARP_3.bit,CAINIT_D_SHARP_3.md5 -+1,CAINIT_E_SHARP_3,CAINIT_E_SHARP_3.bit,CAINIT_E_SHARP_3.md5 -+1,CAINIT_F_SHARP_3,CAINIT_F_SHARP_3.bit,CAINIT_F_SHARP_3.md5 -+1,CAINIT_G_SHARP_3,CAINIT_G_SHARP_3.bit,CAINIT_G_SHARP_3.md5 -+1,CAINIT_H_SHARP_3,CAINIT_H_SHARP_3.bit,CAINIT_H_SHARP_3.md5 -+1,CIP_A_Panasonic_3,CIP_A_Panasonic_3.bit,CIP_A_Panasonic_3_yuv.md5 -+1,cip_B_NEC_3,cip_B_NEC_3.bit,cip_B_NEC_3.md5 -+1,CIP_C_Panasonic_2,CIP_C_Panasonic_2.bit,CIP_C_Panasonic_2_yuv.md5 -+1,CONFWIN_A_Sony_1,CONFWIN_A_Sony_1.bit,CONFWIN_A_Sony_1.md5 -+1,DBLK_A_MAIN10_VIXS_3,DBLK_A_MAIN10_VIXS_3.bit,DBLK_A_MAIN10_VIXS_3.md5 -+1,DBLK_A_SONY_3,DBLK_A_SONY_3.bit,DBLK_A_SONY_3.bit.yuv.md5 -+1,DBLK_B_SONY_3,DBLK_B_SONY_3.bit,DBLK_B_SONY_3.bit.yuv.md5 -+1,DBLK_C_SONY_3,DBLK_C_SONY_3.bit,DBLK_C_SONY_3.bit.yuv.md5 -+1,DBLK_D_VIXS_2,DBLK_D_VIXS_2.bit,DBLK_D_VIXS_2_yuv.md5 -+1,DBLK_E_VIXS_2,DBLK_E_VIXS_2.bit,DBLK_E_VIXS_2_yuv.md5 -+1,DBLK_F_VIXS_2,DBLK_F_VIXS_2.bit,DBLK_F_VIXS_2_yuv.md5 -+1,DBLK_G_VIXS_2,DBLK_G_VIXS_2.bit,DBLK_G_VIXS_2_yuv.md5 -+1,DELTAQP_A_BRCM_4,DELTAQP_A_BRCM_4.bit,DELTAQP_A_BRCM_4_yuv.md5 -+1,DELTAQP_B_SONY_3,DELTAQP_B_SONY_3.bit,DELTAQP_B_SONY_3.bit.yuv.md5 -+1,DELTAQP_C_SONY_3,DELTAQP_C_SONY_3.bit,DELTAQP_C_SONY_3.bit.yuv.md5 -+1,DSLICE_A_HHI_5,DSLICE_A_HHI_5.bin,DSLICE_A_HHI_5.md5 -+1,DSLICE_B_HHI_5,DSLICE_B_HHI_5.bin,DSLICE_B_HHI_5.md5 -+1,DSLICE_C_HHI_5,DSLICE_C_HHI_5.bin,DSLICE_C_HHI_5.md5 -+1,ENTP_A_QUALCOMM_1,ENTP_A_Qualcomm_1.bit,ENTP_A_Qualcomm_1.md5 -+1,ENTP_B_Qualcomm_1,ENTP_B_Qualcomm_1.bit,ENTP_B_Qualcomm_1.md5 -+1,ENTP_C_Qualcomm_1,ENTP_C_Qualcomm_1.bit,ENTP_C_Qualcomm_1.md5 -+1,EXT_A_ericsson_4,EXT_A_ericsson_4.bit,EXT_A_ericsson_4.md5 -+1,FILLER_A_Sony_1,FILLER_A_Sony_1.bit,FILLER_A_Sony_1.md5 -+1,HRD_A_Fujitsu_3,HRD_A_Fujitsu_3.bin,HRD_A_Fujitsu_3.md5 -+1,INITQP_A_Sony_1,INITQP_A_Sony_1.bit,INITQP_A_Sony_1.md5 -+1,INITQP_B_Main10_Sony_1,INITQP_B_Main10_Sony_1.bit,INITQP_B_Main10_Sony_1.md5 -+1,ipcm_A_NEC_3,ipcm_A_NEC_3.bit,ipcm_A_NEC_3.md5 -+1,ipcm_B_NEC_3,ipcm_B_NEC_3.bit,ipcm_B_NEC_3.md5 -+1,ipcm_C_NEC_3,ipcm_C_NEC_3.bit,ipcm_C_NEC_3.md5 -+1,ipcm_D_NEC_3,ipcm_D_NEC_3.bit,ipcm_D_NEC_3.md5 -+1,ipcm_E_NEC_2,ipcm_E_NEC_2.bit,ipcm_E_NEC_2.md5 -+1,IPRED_A_docomo_2,IPRED_A_docomo_2.bit,IPRED_A_docomo_2.md5 -+1,IPRED_B_Nokia_3,IPRED_B_Nokia_3.bit,IPRED_B_Nokia_3_yuv.md5 -+1,IPRED_C_Mitsubishi_3,IPRED_C_Mitsubishi_3.bit,IPRED_C_Mitsubishi_3_yuv.md5 -+1,LS_A_Orange_2,LS_A_Orange_2.bit,LS_A_Orange_2_yuv.md5 -+1,LS_B_Orange_4,LS_B_Orange_4.bit,LS_B_Orange_4_yuv.md5 -+1,LTRPSPS_A_Qualcomm_1,LTRPSPS_A_Qualcomm_1.bit,LTRPSPS_A_Qualcomm_1.md5 -+1,MAXBINS_A_TI_4,MAXBINS_A_TI_4.bit,MAXBINS_A_TI_4.md5 -+1,MAXBINS_B_TI_4,MAXBINS_B_TI_4.bit,MAXBINS_B_TI_4.md5 -+1,MAXBINS_C_TI_4,MAXBINS_C_TI_4.bit,MAXBINS_C_TI_4.md5 -+1,MERGE_A_TI_3,MERGE_A_TI_3.bit,MERGE_A_TI_3.md5 -+1,MERGE_B_TI_3,MERGE_B_TI_3.bit,MERGE_B_TI_3.md5 -+1,MERGE_C_TI_3,MERGE_C_TI_3.bit,MERGE_C_TI_3.md5 -+1,MERGE_D_TI_3,MERGE_D_TI_3.bit,MERGE_D_TI_3.md5 -+1,MERGE_E_TI_3,MERGE_E_TI_3.bit,MERGE_E_TI_3.md5 -+1,MERGE_F_MTK_4,MERGE_F_MTK_4.bit,MERGE_F_MTK_4.md5 -+1,MERGE_G_HHI_4,MERGE_G_HHI_4.bit,MERGE_G_HHI_4.md5 -+1,MVCLIP_A_qualcomm_3,MVCLIP_A_qualcomm_3.bit,MVCLIP_A_qualcomm_3.yuv.md5 -+1,MVDL1ZERO_A_docomo_4,MVDL1ZERO_A_docomo_4.bit,MVDL1ZERO_A_docomo_4.md5 -+1,MVEDGE_A_qualcomm_3,MVEDGE_A_qualcomm_3.bit,MVEDGE_A_qualcomm_3.yuv.md5 -+1,NoOutPrior_A_Qualcomm_1,NoOutPrior_A_Qualcomm_1.bit,NoOutPrior_A_Qualcomm_1.md5 -+1,NoOutPrior_B_Qualcomm_1,NoOutPrior_B_Qualcomm_1.bit,NoOutPrior_B_Qualcomm_1.md5 -+1,NUT_A_ericsson_5,NUT_A_ericsson_5.bit,NUT_A_ericsson_5.md5 -+1,OPFLAG_A_Qualcomm_1,OPFLAG_A_Qualcomm_1.bit,OPFLAG_A_Qualcomm_1.md5 -+1,OPFLAG_B_Qualcomm_1,OPFLAG_B_Qualcomm_1.bit,OPFLAG_B_Qualcomm_1.md5 -+1,OPFLAG_C_Qualcomm_1,OPFLAG_C_Qualcomm_1.bit,OPFLAG_C_Qualcomm_1.md5 -+1,PICSIZE_A_Bossen_1,PICSIZE_A_Bossen_1.bin,PICSIZE_A_Bossen_1.md5 -+1,PICSIZE_B_Bossen_1,PICSIZE_B_Bossen_1.bin,PICSIZE_B_Bossen_1.md5 -+1,PICSIZE_C_Bossen_1,PICSIZE_C_Bossen_1.bin,PICSIZE_C_Bossen_1.md5 -+1,PICSIZE_D_Bossen_1,PICSIZE_D_Bossen_1.bin,PICSIZE_D_Bossen_1.md5 -+1,PMERGE_A_TI_3,PMERGE_A_TI_3.bit,PMERGE_A_TI_3.md5 -+1,PMERGE_B_TI_3,PMERGE_B_TI_3.bit,PMERGE_B_TI_3.md5 -+1,PMERGE_C_TI_3,PMERGE_C_TI_3.bit,PMERGE_C_TI_3.md5 -+1,PMERGE_D_TI_3,PMERGE_D_TI_3.bit,PMERGE_D_TI_3.md5 -+1,PMERGE_E_TI_3,PMERGE_E_TI_3.bit,PMERGE_E_TI_3.md5 -+1,POC_A_Bossen_3,POC_A_Bossen_3.bin,POC_A_Bossen_3.md5 -+1,PPS_A_qualcomm_7,PPS_A_qualcomm_7.bit,PPS_A_qualcomm_7.yuv.md5 -+1,PS_B_VIDYO_3,PS_B_VIDYO_3.bit,PS_B_VIDYO_3_yuv.md5 -+1,RAP_A_docomo_6,RAP_A_docomo_6.bit,RAP_A_docomo_6.md5 -+1,RAP_B_Bossen_2,RAP_B_Bossen_2.bit,RAP_B_Bossen_2.md5 -+1,RPLM_A_qualcomm_4,RPLM_A_qualcomm_4.bit,RPLM_A_qualcomm_4.yuv.md5 -+1,RPLM_B_qualcomm_4,RPLM_B_qualcomm_4.bit,RPLM_B_qualcomm_4.yuv.md5 -+1,RPS_A_docomo_5,RPS_A_docomo_5.bit,RPS_A_docomo_5.md5 -+1,RPS_B_qualcomm_5,RPS_B_qualcomm_5.bit,RPS_B_qualcomm_5.yuv.md5 -+1,RPS_C_ericsson_5,RPS_C_ericsson_5.bit,RPS_C_ericsson_5.md5 -+1,RPS_D_ericsson_6,RPS_D_ericsson_6.bit,RPS_D_ericsson_6.md5 -+1,RPS_E_qualcomm_5,RPS_E_qualcomm_5.bit,RPS_E_qualcomm_5.yuv.md5 -+1,RPS_F_docomo_2,RPS_F_docomo_2.bit,RPS_F_docomo_2.md5 -+1,RQT_A_HHI_4,RQT_A_HHI_4.bit,RQT_A_HHI_4.md5 -+1,RQT_B_HHI_4,RQT_B_HHI_4.bit,RQT_B_HHI_4.md5 -+1,RQT_C_HHI_4,RQT_C_HHI_4.bit,RQT_C_HHI_4.md5 -+1,RQT_D_HHI_4,RQT_D_HHI_4.bit,RQT_D_HHI_4.md5 -+1,RQT_E_HHI_4,RQT_E_HHI_4.bit,RQT_E_HHI_4.md5 -+1,RQT_F_HHI_4,RQT_F_HHI_4.bit,RQT_F_HHI_4.md5 -+1,RQT_G_HHI_4,RQT_G_HHI_4.bit,RQT_G_HHI_4.md5 -+1,SAO_A_MediaTek_4,SAO_A_MediaTek_4.bit,SAO_A_MediaTek_4.md5 -+1,SAO_B_MediaTek_5,SAO_B_MediaTek_5.bit,SAO_B_MediaTek_5.md5 -+1,SAO_C_Samsung_5,SAO_C_Samsung_5.bin,SAO_C_Samsung_5.md5 -+1,SAO_D_Samsung_5,SAO_D_Samsung_5.bin,SAO_D_Samsung_5.md5 -+1,SAO_E_Canon_4,SAO_E_Canon_4.bit,SAO_E_Canon_4.md5 -+1,SAO_F_Canon_3,SAO_F_Canon_3.bit,SAO_F_Canon_3.md5 -+1,SAO_G_Canon_3,SAO_G_Canon_3.bit,SAO_G_Canon_3.md5 -+1,SDH_A_Orange_4,SDH_A_Orange_4.bit,SDH_A_Orange_4_yuv.md5 -+1,SLICES_A_Rovi_3,SLICES_A_Rovi_3.bin,SLICES_A_Rovi_3.md5 -+1,SLIST_A_Sony_4,str.bin,SLIST_A_Sony_4_yuv.md5 -+1,SLIST_B_Sony_8,str.bin,SLIST_B_Sony_8_yuv.md5 -+1,SLIST_C_Sony_3,str.bin,SLIST_C_Sony_3_yuv.md5 -+1,SLIST_D_Sony_9,str.bin,SLIST_D_Sony_9_yuv.md5 -+1,SLPPLP_A_VIDYO_2,SLPPLP_A_VIDYO_2.bit,SLPPLP_A_VIDYO_2_yuv.md5 -+1,STRUCT_A_Samsung_6,STRUCT_A_Samsung_6.bin,STRUCT_A_Samsung_6.md5 -+1,STRUCT_B_Samsung_6,STRUCT_B_Samsung_6.bin,STRUCT_B_Samsung_6.md5 -+1,TILES_A_Cisco_2,TILES_A_Cisco_2.bin,TILES_A_Cisco_2_yuv.md5 -+1,TILES_B_Cisco_1,TILES_B_Cisco_1.bin,TILES_B_Cisco_1_yuv.md5 -+1,TMVP_A_MS_3,TMVP_A_MS_3.bit,TMVP_A_MS_3.yuv.md5 -+1,TSCL_A_VIDYO_5,TSCL_A_VIDYO_5.bit,TSCL_A_VIDYO_5_yuv.md5 -+1,TSCL_B_VIDYO_4,TSCL_B_VIDYO_4.bit,TSCL_B_VIDYO_4_yuv.md5 -+1,TSKIP_A_MS_3,TSKIP_A_MS_3.bit,TSKIP_A_MS_3.yuv.md5 -+0,TSUNEQBD_A_MAIN10_Technicolor_2,TSUNEQBD_A_MAIN10_Technicolor_2.bit,TSUNEQBD_A_MAIN10_Technicolor_2_yuv.md5, # Y/C bit depth unmatched -+1,TUSIZE_A_Samsung_1,TUSIZE_A_Samsung_1.bin,TUSIZE_A_Samsung_1.md5 -+1,VPSID_A_VIDYO_2,VPSID_A_VIDYO_2.bit,VPSID_A_VIDYO_2_yuv.md5 -+1,WP_A_MAIN10_Toshiba_3,WP_A_MAIN10_Toshiba_3.bit,WP_A_MAIN10_Toshiba_3_yuv.md5 -+1,WP_A_Toshiba_3,WP_A_Toshiba_3.bit,WP_A_Toshiba_3_yuv.md5 -+1,WP_B_Toshiba_3,WP_B_Toshiba_3.bit,WP_B_Toshiba_3_yuv.md5 -+1,WP_MAIN10_B_Toshiba_3,WP_MAIN10_B_Toshiba_3.bit,WP_MAIN10_B_Toshiba_3_yuv.md5 -+1,WPP_A_ericsson_MAIN10_2,WPP_A_ericsson_MAIN10_2.bit,WPP_A_ericsson_MAIN10_yuv.md5 -+1,WPP_A_ericsson_MAIN_2,WPP_A_ericsson_MAIN_2.bit,WPP_A_ericsson_MAIN_2_yuv.md5 -+1,WPP_B_ericsson_MAIN10_2,WPP_B_ericsson_MAIN10_2.bit,WPP_B_ericsson_MAIN10_yuv.md5 -+1,WPP_B_ericsson_MAIN_2,WPP_B_ericsson_MAIN_2.bit,WPP_B_ericsson_MAIN_2_yuv.md5 -+1,WPP_C_ericsson_MAIN10_2,WPP_C_ericsson_MAIN10_2.bit,WPP_C_ericsson_MAIN10_yuv.md5 -+1,WPP_C_ericsson_MAIN_2,WPP_C_ericsson_MAIN_2.bit,WPP_C_ericsson_MAIN_2_yuv.md5 -+1,WPP_D_ericsson_MAIN10_2,WPP_D_ericsson_MAIN10_2.bit,WPP_D_ericsson_MAIN10_yuv.md5 -+1,WPP_D_ericsson_MAIN_2,WPP_D_ericsson_MAIN_2.bit,WPP_D_ericsson_MAIN_2_yuv.md5 -+1,WPP_E_ericsson_MAIN10_2,WPP_E_ericsson_MAIN10_2.bit,WPP_E_ericsson_MAIN10_yuv.md5 -+1,WPP_E_ericsson_MAIN_2,WPP_E_ericsson_MAIN_2.bit,WPP_E_ericsson_MAIN_2_yuv.md5 -+1,WPP_F_ericsson_MAIN10_2,WPP_F_ericsson_MAIN10_2.bit,WPP_F_ericsson_MAIN10_yuv.md5 -+1,WPP_F_ericsson_MAIN_2,WPP_F_ericsson_MAIN_2.bit,WPP_F_ericsson_MAIN_2_yuv.md5 ++1,ADJUST_IPRED_ANGLE_A_RExt_Mitsubishi_1,ADJUST_IPRED_ANGLE_A_RExt_Mitsubishi_1.bit,ADJUST_IPRED_ANGLE_A_RExt_Mitsubishi_1.md5 ++1,AMP_A_Samsung_6,AMP_A_Samsung_6.bin,AMP_A_Samsung_6.md5 ++1,AMP_B_Samsung_6,AMP_B_Samsung_6.bin,AMP_B_Samsung_6.md5 ++1,AMP_D_Hisilicon_3,AMP_D_Hisilicon.bit,AMP_D_Hisilicon_3.yuv.md5 ++1,AMP_E_Hisilicon_3,AMP_E_Hisilicon.bit,AMP_E_Hisilicon_3.yuv.md5 ++1,AMP_F_Hisilicon_3,AMP_F_Hisilicon_3.bit,AMP_F_Hisilicon_3.yuv.md5 ++1,AMVP_A_MTK_4,AMVP_A_MTK_4.bit,AMVP_A_MTK_4.md5 ++1,AMVP_B_MTK_4,AMVP_B_MTK_4.bit,AMVP_B_MTK_4.md5 ++1,AMVP_C_Samsung_6,AMVP_C_Samsung_6.bin,AMVP_C_Samsung_6.md5 ++1,BUMPING_A_ericsson_1,BUMPING_A_ericsson_1.bit,BUMPING_A_ericsson_1.md5 ++1,CAINIT_A_SHARP_4,CAINIT_A_SHARP_4.bit,CAINIT_A_SHARP_4.md5 ++1,CAINIT_B_SHARP_4,CAINIT_B_SHARP_4.bit,CAINIT_B_SHARP_4.md5 ++1,CAINIT_C_SHARP_3,CAINIT_C_SHARP_3.bit,CAINIT_C_SHARP_3.md5 ++1,CAINIT_D_SHARP_3,CAINIT_D_SHARP_3.bit,CAINIT_D_SHARP_3.md5 ++1,CAINIT_E_SHARP_3,CAINIT_E_SHARP_3.bit,CAINIT_E_SHARP_3.md5 ++1,CAINIT_F_SHARP_3,CAINIT_F_SHARP_3.bit,CAINIT_F_SHARP_3.md5 ++1,CAINIT_G_SHARP_3,CAINIT_G_SHARP_3.bit,CAINIT_G_SHARP_3.md5 ++1,CAINIT_H_SHARP_3,CAINIT_H_SHARP_3.bit,CAINIT_H_SHARP_3.md5 ++1,CIP_A_Panasonic_3,CIP_A_Panasonic_3.bit,CIP_A_Panasonic_3_yuv.md5 ++1,cip_B_NEC_3,cip_B_NEC_3.bit,cip_B_NEC_3.md5 ++1,CIP_C_Panasonic_2,CIP_C_Panasonic_2.bit,CIP_C_Panasonic_2_yuv.md5 ++1,CONFWIN_A_Sony_1,CONFWIN_A_Sony_1.bit,CONFWIN_A_Sony_1.md5 ++1,DBLK_A_MAIN10_VIXS_3,DBLK_A_MAIN10_VIXS_3.bit,DBLK_A_MAIN10_VIXS_3.md5 ++1,DBLK_A_SONY_3,DBLK_A_SONY_3.bit,DBLK_A_SONY_3.bit.yuv.md5 ++1,DBLK_B_SONY_3,DBLK_B_SONY_3.bit,DBLK_B_SONY_3.bit.yuv.md5 ++1,DBLK_C_SONY_3,DBLK_C_SONY_3.bit,DBLK_C_SONY_3.bit.yuv.md5 ++1,DBLK_D_VIXS_2,DBLK_D_VIXS_2.bit,DBLK_D_VIXS_2_yuv.md5 ++1,DBLK_E_VIXS_2,DBLK_E_VIXS_2.bit,DBLK_E_VIXS_2_yuv.md5 ++1,DBLK_F_VIXS_2,DBLK_F_VIXS_2.bit,DBLK_F_VIXS_2_yuv.md5 ++1,DBLK_G_VIXS_2,DBLK_G_VIXS_2.bit,DBLK_G_VIXS_2_yuv.md5 ++1,DELTAQP_A_BRCM_4,DELTAQP_A_BRCM_4.bit,DELTAQP_A_BRCM_4_yuv.md5 ++1,DELTAQP_B_SONY_3,DELTAQP_B_SONY_3.bit,DELTAQP_B_SONY_3.bit.yuv.md5 ++1,DELTAQP_C_SONY_3,DELTAQP_C_SONY_3.bit,DELTAQP_C_SONY_3.bit.yuv.md5 ++1,DSLICE_A_HHI_5,DSLICE_A_HHI_5.bin,DSLICE_A_HHI_5.md5 ++1,DSLICE_B_HHI_5,DSLICE_B_HHI_5.bin,DSLICE_B_HHI_5.md5 ++1,DSLICE_C_HHI_5,DSLICE_C_HHI_5.bin,DSLICE_C_HHI_5.md5 ++1,ENTP_A_QUALCOMM_1,ENTP_A_Qualcomm_1.bit,ENTP_A_Qualcomm_1.md5 ++1,ENTP_B_Qualcomm_1,ENTP_B_Qualcomm_1.bit,ENTP_B_Qualcomm_1.md5 ++1,ENTP_C_Qualcomm_1,ENTP_C_Qualcomm_1.bit,ENTP_C_Qualcomm_1.md5 ++1,EXT_A_ericsson_4,EXT_A_ericsson_4.bit,EXT_A_ericsson_4.md5 ++1,FILLER_A_Sony_1,FILLER_A_Sony_1.bit,FILLER_A_Sony_1.md5 ++1,HRD_A_Fujitsu_3,HRD_A_Fujitsu_3.bin,HRD_A_Fujitsu_3.md5 ++1,INITQP_A_Sony_1,INITQP_A_Sony_1.bit,INITQP_A_Sony_1.md5 ++1,INITQP_B_Main10_Sony_1,INITQP_B_Main10_Sony_1.bit,INITQP_B_Main10_Sony_1.md5 ++1,ipcm_A_NEC_3,ipcm_A_NEC_3.bit,ipcm_A_NEC_3.md5 ++1,ipcm_B_NEC_3,ipcm_B_NEC_3.bit,ipcm_B_NEC_3.md5 ++1,ipcm_C_NEC_3,ipcm_C_NEC_3.bit,ipcm_C_NEC_3.md5 ++1,ipcm_D_NEC_3,ipcm_D_NEC_3.bit,ipcm_D_NEC_3.md5 ++1,ipcm_E_NEC_2,ipcm_E_NEC_2.bit,ipcm_E_NEC_2.md5 ++1,IPRED_A_docomo_2,IPRED_A_docomo_2.bit,IPRED_A_docomo_2.md5 ++1,IPRED_B_Nokia_3,IPRED_B_Nokia_3.bit,IPRED_B_Nokia_3_yuv.md5 ++1,IPRED_C_Mitsubishi_3,IPRED_C_Mitsubishi_3.bit,IPRED_C_Mitsubishi_3_yuv.md5 ++1,LS_A_Orange_2,LS_A_Orange_2.bit,LS_A_Orange_2_yuv.md5 ++1,LS_B_Orange_4,LS_B_Orange_4.bit,LS_B_Orange_4_yuv.md5 ++1,LTRPSPS_A_Qualcomm_1,LTRPSPS_A_Qualcomm_1.bit,LTRPSPS_A_Qualcomm_1.md5 ++1,MAXBINS_A_TI_4,MAXBINS_A_TI_4.bit,MAXBINS_A_TI_4.md5 ++1,MAXBINS_B_TI_4,MAXBINS_B_TI_4.bit,MAXBINS_B_TI_4.md5 ++1,MAXBINS_C_TI_4,MAXBINS_C_TI_4.bit,MAXBINS_C_TI_4.md5 ++1,MERGE_A_TI_3,MERGE_A_TI_3.bit,MERGE_A_TI_3.md5 ++1,MERGE_B_TI_3,MERGE_B_TI_3.bit,MERGE_B_TI_3.md5 ++1,MERGE_C_TI_3,MERGE_C_TI_3.bit,MERGE_C_TI_3.md5 ++1,MERGE_D_TI_3,MERGE_D_TI_3.bit,MERGE_D_TI_3.md5 ++1,MERGE_E_TI_3,MERGE_E_TI_3.bit,MERGE_E_TI_3.md5 ++1,MERGE_F_MTK_4,MERGE_F_MTK_4.bit,MERGE_F_MTK_4.md5 ++1,MERGE_G_HHI_4,MERGE_G_HHI_4.bit,MERGE_G_HHI_4.md5 ++1,MVCLIP_A_qualcomm_3,MVCLIP_A_qualcomm_3.bit,MVCLIP_A_qualcomm_3.yuv.md5 ++1,MVDL1ZERO_A_docomo_4,MVDL1ZERO_A_docomo_4.bit,MVDL1ZERO_A_docomo_4.md5 ++1,MVEDGE_A_qualcomm_3,MVEDGE_A_qualcomm_3.bit,MVEDGE_A_qualcomm_3.yuv.md5 ++1,NoOutPrior_A_Qualcomm_1,NoOutPrior_A_Qualcomm_1.bit,NoOutPrior_A_Qualcomm_1.md5 ++1,NoOutPrior_B_Qualcomm_1,NoOutPrior_B_Qualcomm_1.bit,NoOutPrior_B_Qualcomm_1.md5 ++1,NUT_A_ericsson_5,NUT_A_ericsson_5.bit,NUT_A_ericsson_5.md5 ++1,OPFLAG_A_Qualcomm_1,OPFLAG_A_Qualcomm_1.bit,OPFLAG_A_Qualcomm_1.md5 ++1,OPFLAG_B_Qualcomm_1,OPFLAG_B_Qualcomm_1.bit,OPFLAG_B_Qualcomm_1.md5 ++1,OPFLAG_C_Qualcomm_1,OPFLAG_C_Qualcomm_1.bit,OPFLAG_C_Qualcomm_1.md5 ++1,PICSIZE_A_Bossen_1,PICSIZE_A_Bossen_1.bin,PICSIZE_A_Bossen_1.md5 ++1,PICSIZE_B_Bossen_1,PICSIZE_B_Bossen_1.bin,PICSIZE_B_Bossen_1.md5 ++1,PICSIZE_C_Bossen_1,PICSIZE_C_Bossen_1.bin,PICSIZE_C_Bossen_1.md5 ++1,PICSIZE_D_Bossen_1,PICSIZE_D_Bossen_1.bin,PICSIZE_D_Bossen_1.md5 ++1,PMERGE_A_TI_3,PMERGE_A_TI_3.bit,PMERGE_A_TI_3.md5 ++1,PMERGE_B_TI_3,PMERGE_B_TI_3.bit,PMERGE_B_TI_3.md5 ++1,PMERGE_C_TI_3,PMERGE_C_TI_3.bit,PMERGE_C_TI_3.md5 ++1,PMERGE_D_TI_3,PMERGE_D_TI_3.bit,PMERGE_D_TI_3.md5 ++1,PMERGE_E_TI_3,PMERGE_E_TI_3.bit,PMERGE_E_TI_3.md5 ++1,POC_A_Bossen_3,POC_A_Bossen_3.bin,POC_A_Bossen_3.md5 ++1,PPS_A_qualcomm_7,PPS_A_qualcomm_7.bit,PPS_A_qualcomm_7.yuv.md5 ++1,PS_B_VIDYO_3,PS_B_VIDYO_3.bit,PS_B_VIDYO_3_yuv.md5 ++1,RAP_A_docomo_6,RAP_A_docomo_6.bit,RAP_A_docomo_6.md5 ++1,RAP_B_Bossen_2,RAP_B_Bossen_2.bit,RAP_B_Bossen_2.md5 ++1,RPLM_A_qualcomm_4,RPLM_A_qualcomm_4.bit,RPLM_A_qualcomm_4.yuv.md5 ++1,RPLM_B_qualcomm_4,RPLM_B_qualcomm_4.bit,RPLM_B_qualcomm_4.yuv.md5 ++1,RPS_A_docomo_5,RPS_A_docomo_5.bit,RPS_A_docomo_5.md5 ++1,RPS_B_qualcomm_5,RPS_B_qualcomm_5.bit,RPS_B_qualcomm_5.yuv.md5 ++1,RPS_C_ericsson_5,RPS_C_ericsson_5.bit,RPS_C_ericsson_5.md5 ++1,RPS_D_ericsson_6,RPS_D_ericsson_6.bit,RPS_D_ericsson_6.md5 ++1,RPS_E_qualcomm_5,RPS_E_qualcomm_5.bit,RPS_E_qualcomm_5.yuv.md5 ++1,RPS_F_docomo_2,RPS_F_docomo_2.bit,RPS_F_docomo_2.md5 ++1,RQT_A_HHI_4,RQT_A_HHI_4.bit,RQT_A_HHI_4.md5 ++1,RQT_B_HHI_4,RQT_B_HHI_4.bit,RQT_B_HHI_4.md5 ++1,RQT_C_HHI_4,RQT_C_HHI_4.bit,RQT_C_HHI_4.md5 ++1,RQT_D_HHI_4,RQT_D_HHI_4.bit,RQT_D_HHI_4.md5 ++1,RQT_E_HHI_4,RQT_E_HHI_4.bit,RQT_E_HHI_4.md5 ++1,RQT_F_HHI_4,RQT_F_HHI_4.bit,RQT_F_HHI_4.md5 ++1,RQT_G_HHI_4,RQT_G_HHI_4.bit,RQT_G_HHI_4.md5 ++1,SAO_A_MediaTek_4,SAO_A_MediaTek_4.bit,SAO_A_MediaTek_4.md5 ++1,SAO_B_MediaTek_5,SAO_B_MediaTek_5.bit,SAO_B_MediaTek_5.md5 ++1,SAO_C_Samsung_5,SAO_C_Samsung_5.bin,SAO_C_Samsung_5.md5 ++1,SAO_D_Samsung_5,SAO_D_Samsung_5.bin,SAO_D_Samsung_5.md5 ++1,SAO_E_Canon_4,SAO_E_Canon_4.bit,SAO_E_Canon_4.md5 ++1,SAO_F_Canon_3,SAO_F_Canon_3.bit,SAO_F_Canon_3.md5 ++1,SAO_G_Canon_3,SAO_G_Canon_3.bit,SAO_G_Canon_3.md5 ++1,SDH_A_Orange_4,SDH_A_Orange_4.bit,SDH_A_Orange_4_yuv.md5 ++1,SLICES_A_Rovi_3,SLICES_A_Rovi_3.bin,SLICES_A_Rovi_3.md5 ++1,SLIST_A_Sony_4,str.bin,SLIST_A_Sony_4_yuv.md5 ++1,SLIST_B_Sony_8,str.bin,SLIST_B_Sony_8_yuv.md5 ++1,SLIST_C_Sony_3,str.bin,SLIST_C_Sony_3_yuv.md5 ++1,SLIST_D_Sony_9,str.bin,SLIST_D_Sony_9_yuv.md5 ++1,SLPPLP_A_VIDYO_2,SLPPLP_A_VIDYO_2.bit,SLPPLP_A_VIDYO_2_yuv.md5 ++1,STRUCT_A_Samsung_6,STRUCT_A_Samsung_6.bin,STRUCT_A_Samsung_6.md5 ++1,STRUCT_B_Samsung_6,STRUCT_B_Samsung_6.bin,STRUCT_B_Samsung_6.md5 ++1,TILES_A_Cisco_2,TILES_A_Cisco_2.bin,TILES_A_Cisco_2_yuv.md5 ++1,TILES_B_Cisco_1,TILES_B_Cisco_1.bin,TILES_B_Cisco_1_yuv.md5 ++1,TMVP_A_MS_3,TMVP_A_MS_3.bit,TMVP_A_MS_3.yuv.md5 ++1,TSCL_A_VIDYO_5,TSCL_A_VIDYO_5.bit,TSCL_A_VIDYO_5_yuv.md5 ++1,TSCL_B_VIDYO_4,TSCL_B_VIDYO_4.bit,TSCL_B_VIDYO_4_yuv.md5 ++1,TSKIP_A_MS_3,TSKIP_A_MS_3.bit,TSKIP_A_MS_3.yuv.md5 ++0,TSUNEQBD_A_MAIN10_Technicolor_2,TSUNEQBD_A_MAIN10_Technicolor_2.bit,TSUNEQBD_A_MAIN10_Technicolor_2_yuv.md5, # Y/C bit depth unmatched ++1,TUSIZE_A_Samsung_1,TUSIZE_A_Samsung_1.bin,TUSIZE_A_Samsung_1.md5 ++1,VPSID_A_VIDYO_2,VPSID_A_VIDYO_2.bit,VPSID_A_VIDYO_2_yuv.md5 ++1,WP_A_MAIN10_Toshiba_3,WP_A_MAIN10_Toshiba_3.bit,WP_A_MAIN10_Toshiba_3_yuv.md5 ++1,WP_A_Toshiba_3,WP_A_Toshiba_3.bit,WP_A_Toshiba_3_yuv.md5 ++1,WP_B_Toshiba_3,WP_B_Toshiba_3.bit,WP_B_Toshiba_3_yuv.md5 ++1,WP_MAIN10_B_Toshiba_3,WP_MAIN10_B_Toshiba_3.bit,WP_MAIN10_B_Toshiba_3_yuv.md5 ++1,WPP_A_ericsson_MAIN10_2,WPP_A_ericsson_MAIN10_2.bit,WPP_A_ericsson_MAIN10_yuv.md5 ++1,WPP_A_ericsson_MAIN_2,WPP_A_ericsson_MAIN_2.bit,WPP_A_ericsson_MAIN_2_yuv.md5 ++1,WPP_B_ericsson_MAIN10_2,WPP_B_ericsson_MAIN10_2.bit,WPP_B_ericsson_MAIN10_yuv.md5 ++1,WPP_B_ericsson_MAIN_2,WPP_B_ericsson_MAIN_2.bit,WPP_B_ericsson_MAIN_2_yuv.md5 ++1,WPP_C_ericsson_MAIN10_2,WPP_C_ericsson_MAIN10_2.bit,WPP_C_ericsson_MAIN10_yuv.md5 ++1,WPP_C_ericsson_MAIN_2,WPP_C_ericsson_MAIN_2.bit,WPP_C_ericsson_MAIN_2_yuv.md5 ++1,WPP_D_ericsson_MAIN10_2,WPP_D_ericsson_MAIN10_2.bit,WPP_D_ericsson_MAIN10_yuv.md5 ++1,WPP_D_ericsson_MAIN_2,WPP_D_ericsson_MAIN_2.bit,WPP_D_ericsson_MAIN_2_yuv.md5 ++1,WPP_E_ericsson_MAIN10_2,WPP_E_ericsson_MAIN10_2.bit,WPP_E_ericsson_MAIN10_yuv.md5 ++1,WPP_E_ericsson_MAIN_2,WPP_E_ericsson_MAIN_2.bit,WPP_E_ericsson_MAIN_2_yuv.md5 ++1,WPP_F_ericsson_MAIN10_2,WPP_F_ericsson_MAIN10_2.bit,WPP_F_ericsson_MAIN10_yuv.md5 ++1,WPP_F_ericsson_MAIN_2,WPP_F_ericsson_MAIN_2.bit,WPP_F_ericsson_MAIN_2_yuv.md5 --- /dev/null +++ b/pi-util/conf_native.sh @@ -0,0 +1,135 @@ @@ -22849,7 +22984,7 @@ raspiberry pi support. +# -Wa,-ahls --- /dev/null +++ b/pi-util/ffconf.py -@@ -0,0 +1,215 @@ +@@ -0,0 +1,268 @@ +#!/usr/bin/env python3 + +import string @@ -22861,27 +22996,21 @@ raspiberry pi support. +import csv +from stat import * + -+CODEC_HEVC_RPI = 1 -+HWACCEL_RPI = 2 -+HWACCEL_DRM = 3 -+HWACCEL_VAAPI = 4 ++class DecodeType: ++ def __init__(self, textname, hwaccel): ++ self.textname = textname ++ self.hwaccel = hwaccel + -+def testone(fileroot, srcname, es_file, md5_file, pix, dectype, vcodec, ffmpeg_exec): -+ hwaccel = "" -+ if dectype == HWACCEL_RPI: -+ hwaccel = "rpi" -+ elif dectype == HWACCEL_DRM: -+ hwaccel = "drm" -+ elif dectype == HWACCEL_VAAPI: -+ hwaccel = "vaapi" ++hwaccel_rpi = DecodeType("RPI Test/Legacy", "rpi") ++hwaccel_sw = DecodeType("Software", None) ++hwaccel_drm = DecodeType("DRM Prime", "drm") ++hwaccel_vaapi = DecodeType("VAAPI", "vaapi") + -+ pix_fmt = [] -+ if pix == "8": -+ pix_fmt = ["-pix_fmt", "yuv420p"] -+ elif pix == "10": -+ pix_fmt = ["-pix_fmt", "yuv420p10le"] -+ elif pix == "12": -+ pix_fmt = ["-pix_fmt", "yuv420p12le"] ++def testone(fileroot, srcname, es_file, md5_file, pix, dectype, vcodec, args): ++ ffmpeg_exec = args.ffmpeg ++ gen_yuv = args.gen_yuv ++ valgrind = args.valgrind ++ rv = 0 + + tmp_root = "/tmp" + @@ -22900,17 +23029,29 @@ raspiberry pi support. + except: + pass + -+ flog = open(os.path.join(tmp_root, name + ".log"), "wt") ++ yuv_file = os.path.join(tmp_root, name + ".dec.yuv") ++ try: ++ os.remove(yuv_file) ++ except: ++ pass + -+ ffargs = [ffmpeg_exec, "-flags", "unaligned", "-hwaccel", hwaccel, "-vcodec", "hevc", "-i", os.path.join(fileroot, es_file)] + pix_fmt + ["-f", "md5", dec_file] ++ flog = open(os.path.join(tmp_root, name + ".log"), "w+t") ++ ++ ffargs = [ffmpeg_exec, "-flags", "unaligned"] +\ ++ ["-no_cvt_hw"] +\ ++ (["-hwaccel", dectype.hwaccel] if dectype.hwaccel else []) +\ ++ ["-vcodec", "hevc", "-i", os.path.join(fileroot, es_file)] +\ ++ (["-conform_out", "file", "-f", "conform", yuv_file] if gen_yuv else ["-conform_out", "md5", "-f", "conform", dec_file]) ++ ++ if valgrind: ++ ffargs = ['valgrind', '--leak-check=full'] + ffargs + + # Unaligned needed for cropping conformance -+ if hwaccel: -+ rstr = subprocess.call(ffargs, stdout=flog, stderr=subprocess.STDOUT) -+ else: -+ rstr = subprocess.call( -+ [ffmpeg_exec, "-flags", "unaligned", "-vcodec", vcodec, "-i", os.path.join(fileroot, es_file), "-f", "md5", dec_file], -+ stdout=flog, stderr=subprocess.STDOUT) ++ rstr = subprocess.call(ffargs, stdout=flog, stderr=subprocess.STDOUT) ++ ++ if gen_yuv: ++ with open(dec_file, 'wt') as f: ++ subprocess.call(["md5sum", yuv_file], stdout=f, stderr=subprocess.STDOUT) + + try: + m1 = None @@ -22926,9 +23067,21 @@ raspiberry pi support. + except: + pass + ++ if valgrind: ++ flog.seek(0) ++ leak = True ++ valerr = True ++ ++ for line in flog: ++ if re.search("^==[0-9]+== All heap blocks were freed", line): ++ leak = False ++ if re.search("^==[0-9]+== ERROR SUMMARY: 0 errors", line): ++ valerr = False ++ if leak or valerr: ++ rv = 4 ++ + if m1 and m2 and m1.group() == m2.group(): + print("Match: " + m1.group(), file=flog) -+ rv = 0 + elif not m1: + print("****** Cannot find m1", file=flog) + rv = 3 @@ -22973,7 +23126,7 @@ raspiberry pi support. + return True + return False + -+def doconf(csva, tests, test_root, vcodec, dectype, ffmpeg_exec): ++def doconf(csva, tests, test_root, vcodec, dectype, args): + unx_failures = [] + unx_success = [] + failures = 0 @@ -22985,7 +23138,7 @@ raspiberry pi support. + print ("==== ", name, end="") + sys.stdout.flush() + -+ rv = testone(os.path.join(test_root, name), name, a[2], a[3], a[4], dectype=dectype, vcodec=vcodec, ffmpeg_exec=ffmpeg_exec) ++ rv = testone(os.path.join(test_root, name), name, a[2], a[3], a[4], dectype=dectype, vcodec=vcodec, args=args) + if (rv == 0): + successes += 1 + else: @@ -23010,15 +23163,21 @@ raspiberry pi support. + print(": * CRASH *") + elif (rv == 3) : + print(": * MD5 MISSING *") ++ elif (rv == 4) : ++ print(": * VALGRIND *") + else : + print(": * BANG *") + ++ print() ++ print("Tested using decode type:", dectype.textname) + if unx_failures or unx_success: + print("Unexpected Failures:", unx_failures) + print("Unexpected Success: ", unx_success) + else: + print("All tests normal:", successes, "ok,", failures, "failed") + ++ return unx_failures + unx_success ++ + +class ConfCSVDialect(csv.Dialect): + delimiter = ',' @@ -23029,20 +23188,30 @@ raspiberry pi support. + skipinitialspace = True + strict = True + ++ ++ +if __name__ == '__main__': + + argp = argparse.ArgumentParser(description="FFmpeg h265 conformance tester") + argp.add_argument("tests", nargs='*') + argp.add_argument("--pi4", action='store_true', help="Force pi4 cmd line") + argp.add_argument("--drm", action='store_true', help="Force v4l2 drm cmd line") ++ argp.add_argument("--sw", action='store_true', help="Use software decode") + argp.add_argument("--vaapi", action='store_true', help="Force vaapi cmd line") + argp.add_argument("--test_root", default="/opt/conform/h265.2016", help="Root dir for test") + argp.add_argument("--csvgen", action='store_true', help="Generate CSV file for dir") + argp.add_argument("--csv", default="pi-util/conf_h265.2016.csv", help="CSV filename") + argp.add_argument("--vcodec", default="hevc_rpi", help="vcodec name to use") -+ argp.add_argument("--ffmpeg", default="./ffmpeg", help="ffmpeg exec name") ++ argp.add_argument("--ffmpeg", default="./ffmpeg", help="ffmpeg exec name; if directory given use /ffmpeg") ++ argp.add_argument("--valgrind", action='store_true', help="Run valgrind on tests") ++ argp.add_argument("--gen_yuv", action='store_true', help="Create yuv file (stored with log under /tmp)") ++ argp.add_argument("--loop", default=0, type=int, help="Loop n times, or until unexpected result") + args = argp.parse_args() + ++ if not os.path.isdir(args.test_root): ++ print("Test root dir '%s' not found" % args.test_root) ++ exit(1) ++ + if args.csvgen: + csv.writer(sys.stdout).writerows(scandir(args.test_root)) + exit(0) @@ -23050,26 +23219,46 @@ raspiberry pi support. + with open(args.csv, 'rt') as csvfile: + csva = [a for a in csv.reader(csvfile, ConfCSVDialect())] + -+ dectype = CODEC_HEVC_RPI ++ dectype = None + if os.path.exists("/dev/rpivid-hevcmem"): -+ dectype = HWACCEL_RPI -+ if args.drm or os.path.exists("/sys/module/rpivid_hevc"): -+ dectype = HWACCEL_DRM ++ dectype = hwaccel_rpi ++ if args.drm or os.path.exists("/sys/module/rpivid_hevc") or os.path.exists("/sys/module/rpi_hevc_dec"): ++ dectype = hwaccel_drm + + if args.pi4: -+ dectype = HWACCEL_RPI ++ dectype = hwaccel_rpi + elif args.drm: -+ dectype = HWACCEL_DRM ++ dectype = hwaccel_drm + elif args.vaapi: -+ dectype = HWACCEL_VAAPI ++ dectype = hwaccel_vaapi ++ elif args.sw: ++ dectype = hwaccel_sw + -+ doconf(csva, args.tests, args.test_root, args.vcodec, dectype, args.ffmpeg) ++ if os.path.isdir(args.ffmpeg): ++ args.ffmpeg = os.path.join(args.ffmpeg, "ffmpeg") ++ if not os.path.isfile(args.ffmpeg): ++ print("FFmpeg file '%s' not found" % args.ffmpeg) ++ exit(1) ++ ++ if not dectype: ++ print("No decode type selected and no h/w detected") ++ exit(1) ++ print("Running test using decode:", dectype.textname) ++ ++ i = 0 ++ while True: ++ i = i + 1 ++ if args.loop: ++ print("== Loop ", i) ++ if doconf(csva, args.tests, args.test_root, args.vcodec, dectype, args) or (args.loop >= 0 and i > args.loop): ++ break + --- /dev/null +++ b/pi-util/ffperf.py -@@ -0,0 +1,128 @@ +@@ -0,0 +1,140 @@ +#!/usr/bin/env python3 + ++import shlex +import time +import string +import os @@ -23106,14 +23295,20 @@ raspiberry pi support. + def __gt__(self, other): + return self.elapsed > other.elapsed + -+ def time_file(name, prefix, ffmpeg="./ffmpeg"): ++ def time_file(name, prefix, args): ++ cmdargs = [args.ffmpeg] ++ for x in args.args : ++ if x == '{INPUT}': ++ cmdargs.append(prefix + name) ++ elif x == '{NULL}': ++ cmdargs.append(os.devnull) ++ else: ++ cmdargs.append(x) ++ + stats = tstats() + stats.name = name + start_time = time.clock_gettime(time.CLOCK_MONOTONIC); -+ cproc = subprocess.Popen([ffmpeg, "-no_cvt_hw", -+ "-vcodec", "hevc_rpi", -+ "-t", "30", "-i", prefix + name, -+ "-f", "vout_rpi", os.devnull], bufsize=-1, stdout=flog, stderr=flog); ++ cproc = subprocess.Popen(cmdargs, bufsize=-1, stdout=flog, stderr=flog); + pinfo = os.wait4(cproc.pid, 0) + end_time = time.clock_gettime(time.CLOCK_MONOTONIC); + stats.elapsed = end_time - start_time @@ -23137,6 +23332,10 @@ raspiberry pi support. +""") + + argp.add_argument("streams", nargs='*') ++ argp.add_argument("--args", default='-t 30 -i {INPUT} -f null {NULL}', help=""" ++ffmpeg arguments, default='-t 30 -i {INPUT} -f null {NULL}'; ++ {INPUT} is replaced by current inputfile path; ++ {NULL} is replaced by the system null device""") + argp.add_argument("--csv_out", default="ffperf_out.csv", help="CSV output filename") + argp.add_argument("--csv_in", help="CSV input filename") + argp.add_argument("--prefix", help="Filename prefix (include terminal '/' if a directory).") @@ -23144,6 +23343,7 @@ raspiberry pi support. + argp.add_argument("--ffmpeg", default="./ffmpeg", help="FFmpeg executable") + + args = argp.parse_args() ++ args.args = shlex.split(args.args) + + csv_out = csv.DictWriter(open(args.csv_out, 'w', newline=''), ["name", "elapsed", "user", "sys"]) + csv_out.writeheader() @@ -23177,7 +23377,7 @@ raspiberry pi support. + + t0 = tstats({"name":f, "elapsed":999, "user":999, "sys":999}) + for i in range(args.repeat): -+ t = tstats.time_file(f, prefix, args.ffmpeg) ++ t = tstats.time_file(f, prefix, args) + print ("...", t.times_str()) + if t0 > t: + t0 = t @@ -23615,18 +23815,10 @@ raspiberry pi support. + --- a/tests/checkasm/Makefile +++ b/tests/checkasm/Makefile -@@ -38,6 +38,7 @@ CHECKASMOBJS-$(CONFIG_AVCODEC) - # libavfilter tests - AVFILTEROBJS-$(CONFIG_AFIR_FILTER) += af_afir.o - AVFILTEROBJS-$(CONFIG_BLEND_FILTER) += vf_blend.o -+AVFILTEROBJS-$(CONFIG_BWDIF_FILTER) += vf_bwdif.o - AVFILTEROBJS-$(CONFIG_COLORSPACE_FILTER) += vf_colorspace.o - AVFILTEROBJS-$(CONFIG_EQ_FILTER) += vf_eq.o - AVFILTEROBJS-$(CONFIG_GBLUR_FILTER) += vf_gblur.o -@@ -56,8 +57,9 @@ CHECKASMOBJS-$(CONFIG_SWSCALE) += $(SWS - AVUTILOBJS += av_tx.o +@@ -73,8 +73,9 @@ AVUTILOBJS AVUTILOBJS += fixed_dsp.o AVUTILOBJS += float_dsp.o + AVUTILOBJS += lls.o +AVUTILOBJS-$(CONFIG_SAND) += rpi_sand.o -CHECKASMOBJS-$(CONFIG_AVUTIL) += $(AVUTILOBJS) @@ -23636,19 +23828,9 @@ raspiberry pi support. CHECKASMOBJS-$(HAVE_ARMV5TE_EXTERNAL) += arm/checkasm.o --- a/tests/checkasm/checkasm.c +++ b/tests/checkasm/checkasm.c -@@ -173,6 +173,9 @@ static const struct { - #if CONFIG_BLEND_FILTER - { "vf_blend", checkasm_check_blend }, - #endif -+ #if CONFIG_BWDIF_FILTER -+ { "vf_bwdif", checkasm_check_vf_bwdif }, -+ #endif - #if CONFIG_COLORSPACE_FILTER - { "vf_colorspace", checkasm_check_colorspace }, - #endif -@@ -201,6 +204,9 @@ static const struct { - { "fixed_dsp", checkasm_check_fixed_dsp }, +@@ -290,6 +290,9 @@ static const struct { { "float_dsp", checkasm_check_float_dsp }, + { "lls", checkasm_check_lls }, { "av_tx", checkasm_check_av_tx }, + #if CONFIG_SAND + { "rpi_sand", checkasm_check_rpi_sand }, @@ -23658,25 +23840,17 @@ raspiberry pi support. }; --- a/tests/checkasm/checkasm.h +++ b/tests/checkasm/checkasm.h -@@ -72,6 +72,7 @@ void checkasm_check_motion(void); +@@ -114,6 +114,7 @@ void checkasm_check_mpegvideoencdsp(void void checkasm_check_nlmeans(void); void checkasm_check_opusdsp(void); void checkasm_check_pixblockdsp(void); +void checkasm_check_rpi_sand(void); void checkasm_check_sbrdsp(void); - void checkasm_check_synth_filter(void); - void checkasm_check_sw_gbrp(void); -@@ -81,6 +82,7 @@ void checkasm_check_utvideodsp(void); - void checkasm_check_v210dec(void); - void checkasm_check_v210enc(void); - void checkasm_check_vc1dsp(void); -+void checkasm_check_vf_bwdif(void); - void checkasm_check_vf_eq(void); - void checkasm_check_vf_gblur(void); - void checkasm_check_vf_hflip(void); + void checkasm_check_rv34dsp(void); + void checkasm_check_rv40dsp(void); --- /dev/null +++ b/tests/checkasm/rpi_sand.c -@@ -0,0 +1,118 @@ +@@ -0,0 +1,122 @@ +/* + * Copyright (c) 2023 John Cox + * @@ -23708,6 +23882,10 @@ raspiberry pi support. +#elif ARCH_AARCH64 +#include "libavutil/aarch64/cpu.h" +#include "libavutil/aarch64/rpi_sand_neon.h" ++#else ++#define have_neon(flags) 0 ++#define ff_rpi_sand30_lines_to_planar_y16 NULL ++#define ff_rpi_sand30_lines_to_planar_c16 NULL +#endif + +static inline uint32_t pack30(unsigned int a, unsigned int b, unsigned int c) @@ -23795,280 +23973,109 @@ raspiberry pi support. + free(vbuf1); +} + ---- /dev/null -+++ b/tests/checkasm/vf_bwdif.c -@@ -0,0 +1,256 @@ -+/* -+ * This file is part of FFmpeg. -+ * -+ * FFmpeg is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * FFmpeg is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License along -+ * with FFmpeg; if not, write to the Free Software Foundation, Inc., -+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -+ */ -+ -+#include -+#include "checkasm.h" -+#include "libavcodec/internal.h" -+#include "libavfilter/bwdif.h" -+#include "libavutil/mem_internal.h" -+ -+#define WIDTH 256 -+ -+#define randomize_buffers(buf0, buf1, mask, count) \ -+ for (size_t i = 0; i < count; i++) \ -+ buf0[i] = buf1[i] = rnd() & mask -+ -+#define randomize_overflow_check(buf0, buf1, mask, count) \ -+ for (size_t i = 0; i < count; i++) \ -+ buf0[i] = buf1[i] = (rnd() & 1) != 0 ? mask : 0; -+ -+#define BODY(type, depth) \ -+ do { \ -+ type prev0[9*WIDTH], prev1[9*WIDTH]; \ -+ type next0[9*WIDTH], next1[9*WIDTH]; \ -+ type cur0[9*WIDTH], cur1[9*WIDTH]; \ -+ type dst0[WIDTH], dst1[WIDTH]; \ -+ const int stride = WIDTH; \ -+ const int mask = (1<