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<