diff --git a/CMakeLists.txt b/CMakeLists.txt index c8e9ebf8a..3faa2b5ac 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -12,6 +12,8 @@ project(yuzu) # OFF by default, but if ENABLE_SDL2 and MSVC are true then ON option(ENABLE_SDL2 "Enable the SDL2 frontend" ON) CMAKE_DEPENDENT_OPTION(YUZU_USE_BUNDLED_SDL2 "Download bundled SDL2 binaries" ON "ENABLE_SDL2;MSVC" OFF) +# On Linux system SDL2 is likely to be lacking HIDAPI support which have drawbacks but is needed for SDL motion +CMAKE_DEPENDENT_OPTION(YUZU_ALLOW_SYSTEM_SDL2 "Try using system SDL2 before fallling back to one from externals" NOT UNIX "ENABLE_SDL2" OFF) option(ENABLE_QT "Enable the Qt frontend" ON) option(ENABLE_QT_TRANSLATION "Enable translations for the Qt frontend" OFF) @@ -292,20 +294,24 @@ if (ENABLE_SDL2) target_link_libraries(SDL2 INTERFACE "${SDL2_LIBRARY}") target_include_directories(SDL2 INTERFACE "${SDL2_INCLUDE_DIR}") else() - find_package(SDL2 2.0.15 QUIET) + if (YUZU_ALLOW_SYSTEM_SDL2) + find_package(SDL2 2.0.15 QUIET) - if (SDL2_FOUND) - # Some installations don't set SDL2_LIBRARIES - if("${SDL2_LIBRARIES}" STREQUAL "") - message(WARNING "SDL2_LIBRARIES wasn't set, manually setting to SDL2::SDL2") - set(SDL2_LIBRARIES "SDL2::SDL2") + if (SDL2_FOUND) + # Some installations don't set SDL2_LIBRARIES + if("${SDL2_LIBRARIES}" STREQUAL "") + message(WARNING "SDL2_LIBRARIES wasn't set, manually setting to SDL2::SDL2") + set(SDL2_LIBRARIES "SDL2::SDL2") + endif() + + include_directories(SYSTEM ${SDL2_INCLUDE_DIRS}) + add_library(SDL2 INTERFACE) + target_link_libraries(SDL2 INTERFACE "${SDL2_LIBRARIES}") + else() + message(STATUS "SDL2 2.0.15 or newer not found, falling back to externals.") endif() - - include_directories(SYSTEM ${SDL2_INCLUDE_DIRS}) - add_library(SDL2 INTERFACE) - target_link_libraries(SDL2 INTERFACE "${SDL2_LIBRARIES}") else() - message(STATUS "SDL2 2.0.15 or newer not found, falling back to externals.") + message(STATUS "Using SDL2 from externals.") endif() endif() endif() diff --git a/README.md b/README.md index cacf1fd47..216f82088 100755 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ yuzu emulator early access ============= -This is the source code for early-access 1679. +This is the source code for early-access 1680. ## Legal Notice diff --git a/externals/CMakeLists.txt b/externals/CMakeLists.txt index e280e53d7..fe1c088ca 100755 --- a/externals/CMakeLists.txt +++ b/externals/CMakeLists.txt @@ -47,8 +47,20 @@ target_include_directories(unicorn-headers INTERFACE ./unicorn/include) # SDL2 if (NOT SDL2_FOUND AND ENABLE_SDL2) + # Yuzu itself needs: Events Joystick Haptic Sensor Timers + # Yuzu-cmd also needs: Video (depends on Loadso/Dlopen) + set(SDL_UNUSED_SUBSYSTEMS + Atomic Audio Render Power Threads + File CPUinfo Filesystem Locale) + foreach(_SUB ${SDL_UNUSED_SUBSYSTEMS}) + string(TOUPPER ${_SUB} _OPT) + option(SDL_${_OPT} "" OFF) + endforeach() + set(SDL_STATIC ON) set(SDL_SHARED OFF) + option(HIDAPI "" ON) + add_subdirectory(SDL EXCLUDE_FROM_ALL) add_library(SDL2 ALIAS SDL2-static) endif() diff --git a/externals/ffmpeg/.mailmap b/externals/ffmpeg/.mailmap index 50b8c0452..f14770d80 100755 --- a/externals/ffmpeg/.mailmap +++ b/externals/ffmpeg/.mailmap @@ -15,7 +15,9 @@ - + + rcombs + diff --git a/externals/ffmpeg/Changelog b/externals/ffmpeg/Changelog index be7588bbb..49fc26045 100755 --- a/externals/ffmpeg/Changelog +++ b/externals/ffmpeg/Changelog @@ -1,47 +1,13 @@ Entries are sorted chronologically from oldest to youngest within each release, releases are sorted from youngest to oldest. -version 4.3.1: - avcodec/tiff: Check input space in dng_decode_jpeg() - avcodec/mjpeg_parser: Adjust size rejection threshold - avcodec/cbs_jpeg: Fix uninitialized end index in cbs_jpeg_split_fragment() - avformat/sdp: Fix potential write beyond end of buffer - avformat/mm: Check for existence of audio stream - avformat/mov: Fix unaligned read of uint32_t and endian-dependance in mov_read_default - avcodec/apedec: Fix undefined integer overflow with 24bit - avcodec/loco: Fix integer overflow with large values from loco_get_rice() - avformat/smjpegdec: Check the existence of referred streams - avcodec/tiff: Check frame parameters before blit for DNG - avcodec/mjpegdec: Limit bayer to single plane outputting format - avcodec/pnmdec: Fix misaligned reads - avcodec/mv30: Fix integer overflows in idct2_1d() - avcodec/hcadec: Check total_band_count against imdct_in size - avcodec/scpr3: Fix out of array access with dectab - avcodec/tiff: Do not overrun the array ends in dng_blit() - avcodec/dstdec: Replace AC overread check by sample rate check - dnn_backend_native: Add overflow check for length calculation. - avcodec/h264_metadata_bsf: Fix invalid av_freep - avcodec/cbs_h265: set default VUI parameters when vui_parameters_present_flag is false - avcodec/av1_parser: initialize avctx->pix_fmt - avcodec/av1_parser: add missing parsing for RGB pixel format signaling - avcodec/av1_parser: set context values outside the OBU parsing loop - avutil/avsscanf: Add () to avoid integer overflow in scanexp() - avformat/utils: reorder duration computation to avoid overflow - avcodec/pngdec: Check for fctl after idat - avformat/hls: Pass a copy of the URL for probing - avutil/common: Fix integer overflow in av_ceil_log2_c() - avcodec/wmalosslessdec: fix overflow with pred in revert_cdlms - avformat/mvdec: Fix integer overflow with billions of channels - avformat/microdvddec: skip malformed lines without frame number. - dnn_backend_native: check operand index - dnn_backend_native.c: refine code for fail case - avformat/mov: fix memleaks - libavformat/mov: Fix memleaks when demuxing DV audio - avcodec/cbs_av1: Fix writing uvlc numbers >= INT_MAX - avformat/avc, mxfenc: Avoid allocation of H264 SPS structure, fix memleak - avcodec/bitstream: Don't check for undefined behaviour after it happened - avformat/aviobuf: Also return truncated buffer in avio_get_dyn_buf() - avformat/aviobuf: Don't check for overflow after it happened +version : +- AudioToolbox output device +- MacCaption demuxer +- PGX decoder +- chromanr video filter +- VDPAU accelerated HEVC 10/12bit decoding + version 4.3: - v360 filter diff --git a/externals/ffmpeg/MAINTAINERS b/externals/ffmpeg/MAINTAINERS index af02cf00a..02af52101 100755 --- a/externals/ffmpeg/MAINTAINERS +++ b/externals/ffmpeg/MAINTAINERS @@ -55,7 +55,7 @@ fate.ffmpeg.org Timothy Gu Trac bug tracker Alexander Strasser, Michael Niedermayer, Carl Eugen Hoyos Patchwork Andriy Gelman mailing lists Baptiste Coudurier -Twitter Lou Logan, Reynaldo H. Verdejo Pinochet +Twitter Reynaldo H. Verdejo Pinochet Launchpad Timothy Gu ffmpeg-security Andreas Cadhalpun, Carl Eugen Hoyos, Clément Bœsch, Michael Niedermayer, Reimar Doeffinger, Rodger Combs, wm4 diff --git a/externals/ffmpeg/RELEASE b/externals/ffmpeg/RELEASE index f77856a6f..a9c240624 100755 --- a/externals/ffmpeg/RELEASE +++ b/externals/ffmpeg/RELEASE @@ -1 +1 @@ -4.3.1 +4.3.git diff --git a/externals/ffmpeg/configure b/externals/ffmpeg/configure index 8569a60bf..bdfd73160 100755 --- a/externals/ffmpeg/configure +++ b/externals/ffmpeg/configure @@ -253,6 +253,8 @@ External library support: --enable-libopenh264 enable H.264 encoding via OpenH264 [no] --enable-libopenjpeg enable JPEG 2000 de/encoding via OpenJPEG [no] --enable-libopenmpt enable decoding tracked files via libopenmpt [no] + --enable-libopenvino enable OpenVINO as a DNN module backend + for DNN based filters like dnn_processing [no] --enable-libopus enable Opus de/encoding via libopus [no] --enable-libpulse enable Pulseaudio input via libpulse [no] --enable-librabbitmq enable RabbitMQ library [no] @@ -1741,7 +1743,6 @@ EXTERNAL_LIBRARY_VERSION3_LIST=" liblensfun libopencore_amrnb libopencore_amrwb - libvmaf libvo_amrwbenc mbedtls rkmpp @@ -1790,6 +1791,7 @@ EXTERNAL_LIBRARY_LIST=" libopenh264 libopenjpeg libopenmpt + libopenvino libopus libpulse librabbitmq @@ -1808,6 +1810,7 @@ EXTERNAL_LIBRARY_LIST=" libtheora libtwolame libv4l2 + libvmaf libvorbis libvpx libwavpack @@ -2620,7 +2623,7 @@ cbs_mpeg2_select="cbs" cbs_vp9_select="cbs" dct_select="rdft" dirac_parse_select="golomb" -dnn_suggest="libtensorflow" +dnn_suggest="libtensorflow libopenvino" error_resilience_select="me_cmp" faandct_deps="faan" faandct_select="fdctdsp" @@ -3367,6 +3370,8 @@ alsa_outdev_deps="alsa" avfoundation_indev_deps="avfoundation corevideo coremedia pthreads" avfoundation_indev_suggest="coregraphics applicationservices" avfoundation_indev_extralibs="-framework Foundation" +audiotoolbox_outdev_deps="audiotoolbox pthreads" +audiotoolbox_outdev_extralibs="-framework AudioToolbox -framework CoreAudio" bktr_indev_deps_any="dev_bktr_ioctl_bt848_h machine_ioctl_bt848_h dev_video_bktr_ioctl_bt848_h dev_ic_bt8xx_h" caca_outdev_deps="libcaca" decklink_deps_any="libdl LoadLibrary" @@ -6152,6 +6157,7 @@ enabled videotoolbox && check_apple_framework VideoToolbox check_apple_framework CoreFoundation check_apple_framework CoreMedia check_apple_framework CoreVideo +check_apple_framework CoreAudio enabled avfoundation && { disable coregraphics applicationservices @@ -6275,7 +6281,7 @@ enabled avisynth && require_headers "avisynth/avisynth_c.h" enabled cuda_nvcc && { check_nvcc cuda_nvcc || die "ERROR: failed checking for nvcc."; } enabled chromaprint && require chromaprint chromaprint.h chromaprint_get_version -lchromaprint enabled decklink && { require_headers DeckLinkAPI.h && - { test_cpp_condition DeckLinkAPIVersion.h "BLACKMAGIC_DECKLINK_API_VERSION >= 0x0a090500" || die "ERROR: Decklink API version must be >= 10.9.5."; } } + { test_cpp_condition DeckLinkAPIVersion.h "BLACKMAGIC_DECKLINK_API_VERSION >= 0x0a0a0000" || die "ERROR: Decklink API version must be >= 10.10"; } } enabled frei0r && require_headers "frei0r.h dlfcn.h" enabled gmp && require gmp gmp.h mpz_export -lgmp enabled gnutls && require_pkg_config gnutls gnutls gnutls/gnutls.h gnutls_global_init @@ -6347,6 +6353,7 @@ enabled libopenh264 && require_pkg_config libopenh264 openh264 wels/codec_ enabled libopenjpeg && { check_pkg_config libopenjpeg "libopenjp2 >= 2.1.0" openjpeg.h opj_version || { require_pkg_config libopenjpeg "libopenjp2 >= 2.1.0" openjpeg.h opj_version -DOPJ_STATIC && add_cppflags -DOPJ_STATIC; } } enabled libopenmpt && require_pkg_config libopenmpt "libopenmpt >= 0.2.6557" libopenmpt/libopenmpt.h openmpt_module_create -lstdc++ && append libopenmpt_extralibs "-lstdc++" +enabled libopenvino && require libopenvino c_api/ie_c_api.h ie_c_api_version -linference_engine_c_api enabled libopus && { enabled libopus_decoder && { require_pkg_config libopus opus opus_multistream.h opus_multistream_decoder_create @@ -6378,7 +6385,7 @@ enabled libtwolame && require libtwolame twolame.h twolame_init -ltwolame die "ERROR: libtwolame must be installed and version must be >= 0.3.10"; } enabled libv4l2 && require_pkg_config libv4l2 libv4l2 libv4l2.h v4l2_ioctl enabled libvidstab && require_pkg_config libvidstab "vidstab >= 0.98" vid.stab/libvidstab.h vsMotionDetectInit -enabled libvmaf && require_pkg_config libvmaf "libvmaf >= 1.3.9" libvmaf.h compute_vmaf +enabled libvmaf && require_pkg_config libvmaf "libvmaf >= 1.5.2" libvmaf.h compute_vmaf enabled libvo_amrwbenc && require libvo_amrwbenc vo-amrwbenc/enc_if.h E_IF_init -lvo-amrwbenc enabled libvorbis && require_pkg_config libvorbis vorbis vorbis/codec.h vorbis_info_init && require_pkg_config libvorbisenc vorbisenc vorbis/vorbisenc.h vorbis_encode_init diff --git a/externals/ffmpeg/doc/APIchanges b/externals/ffmpeg/doc/APIchanges index 70579df21..1d6cc36b8 100755 --- a/externals/ffmpeg/doc/APIchanges +++ b/externals/ffmpeg/doc/APIchanges @@ -15,6 +15,16 @@ libavutil: 2017-10-21 API changes, most recent first: +2020-06-12 - b09fb030c1 - lavu 56.55.100 - pixdesc.h + Add AV_PIX_FMT_X2RGB10. + +2020-06-xx - xxxxxxxxxx - lavu 56.54.100 - frame.h + Add AV_FRAME_DATA_SEI_UNREGISTERED. + +2020-06-xx - xxxxxxxxxx - lavu 56.53.100 - log.h opt.h + Add av_opt_child_class_iterate() and AVClass.child_class_iterate(). + Deprecate av_opt_child_class_next() and AVClass.child_class_next(). + 2020-06-05 - ec39c2276a - lavu 56.50.100 - buffer.h Passing NULL as alloc argument to av_buffer_pool_init2() is now allowed. diff --git a/externals/ffmpeg/doc/Doxyfile b/externals/ffmpeg/doc/Doxyfile index a53a48907..089189950 100755 --- a/externals/ffmpeg/doc/Doxyfile +++ b/externals/ffmpeg/doc/Doxyfile @@ -38,7 +38,7 @@ PROJECT_NAME = FFmpeg # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = 4.3.1 +PROJECT_NUMBER = # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a diff --git a/externals/ffmpeg/doc/encoders.texi b/externals/ffmpeg/doc/encoders.texi index 1331b7945..5406d20c0 100755 --- a/externals/ffmpeg/doc/encoders.texi +++ b/externals/ffmpeg/doc/encoders.texi @@ -1599,6 +1599,36 @@ Enable the use of global motion for block prediction. Default is true. Enable block copy mode for intra block prediction. This mode is useful for screen content. Default is true. +@item enable-rect-partitions (@emph{boolean}) (Requires libaom >= v2.0.0) +Enable rectangular partitions. Default is true. + +@item enable-1to4-partitions (@emph{boolean}) (Requires libaom >= v2.0.0) +Enable 1:4/4:1 partitions. Default is true. + +@item enable-ab-partitions (@emph{boolean}) (Requires libaom >= v2.0.0) +Enable AB shape partitions. Default is true. + +@item enable-angle-delta (@emph{boolean}) (Requires libaom >= v2.0.0) +Enable angle delta intra prediction. Default is true. + +@item enable-cfl-intra (@emph{boolean}) (Requires libaom >= v2.0.0) +Enable chroma predicted from luma intra prediction. Default is true. + +@item enable-filter-intra (@emph{boolean}) (Requires libaom >= v2.0.0) +Enable filter intra predictor. Default is true. + +@item enable-intra-edge-filter (@emph{boolean}) (Requires libaom >= v2.0.0) +Enable intra edge filter. Default is true. + +@item enable-smooth-intra (@emph{boolean}) (Requires libaom >= v2.0.0) +Enable smooth intra prediction mode. Default is true. + +@item enable-paeth-intra (@emph{boolean}) (Requires libaom >= v2.0.0) +Enable paeth predictor in intra prediction. Default is true. + +@item enable-palette (@emph{boolean}) (Requires libaom >= v2.0.0) +Enable palette prediction mode. Default is true. + @end table @section libkvazaar @@ -2740,17 +2770,17 @@ MPEG-2 video encoder. @subsection Options @table @option -@item profile @var{integer} +@item profile Select the mpeg2 profile to encode: @table @samp @item 422 -@item main +@item high @item ss Spatially Scalable @item snr SNR Scalable -@item high +@item main @item simple @end table diff --git a/externals/ffmpeg/doc/ffmpeg.texi b/externals/ffmpeg/doc/ffmpeg.texi index 76fafdcf7..70b8965d7 100755 --- a/externals/ffmpeg/doc/ffmpeg.texi +++ b/externals/ffmpeg/doc/ffmpeg.texi @@ -734,10 +734,6 @@ ffmpeg -dump_attachment:t "" -i INPUT Technical note -- attachments are implemented as codec extradata, so this option can actually be used to extract extradata from any stream, not just attachments. - -@item -noautorotate -Disable automatically rotating video based on file metadata. - @end table @section Video Options @@ -819,6 +815,18 @@ Create the filtergraph specified by @var{filtergraph} and use it to filter the stream. This is an alias for @code{-filter:v}, see the @ref{filter_option,,-filter option}. + +@item -autorotate +Automatically rotate the video according to file metadata. Enabled by +default, use @option{-noautorotate} to disable it. + +@item -autoscale +Automatically scale the video according to the resolution of first frame. +Enabled by default, use @option{-noautoscale} to disable it. When autoscale is +disabled, all output frames of filter graph might not be in the same resolution +and may be inadequate for some encoder/muxer. Therefore, it is not recommended +to disable it unless you really know what you are doing. +Disable autoscale at your own risk. @end table @section Advanced Video options @@ -848,8 +856,8 @@ factor if negative. Force interlacing support in encoder (MPEG-2 and MPEG-4 only). Use this option if your input file is interlaced and you want to keep the interlaced format for minimum losses. -The alternative is to deinterlace the input stream with -@option{-deinterlace}, but deinterlacing introduces losses. +The alternative is to deinterlace the input stream by use of a filter +such as @code{yadif} or @code{bwdif}, but deinterlacing introduces losses. @item -psnr Calculate PSNR of compressed frames. @item -vstats diff --git a/externals/ffmpeg/doc/filters.texi b/externals/ffmpeg/doc/filters.texi index 84567dec1..12d40029d 100755 --- a/externals/ffmpeg/doc/filters.texi +++ b/externals/ffmpeg/doc/filters.texi @@ -4197,6 +4197,9 @@ If not specified, or the expressed duration is negative, the audio is supposed to be generated forever. Only used if plugin have zero inputs. +@item latency, l +Enable latency compensation, by default is disabled. +Only used if plugin have inputs. @end table @subsection Examples @@ -7180,6 +7183,42 @@ ffmpeg -f lavfi -i color=c=black:s=1280x720 -i video.mp4 -shortest -filter_compl @end example @end itemize +@section chromanr +Reduce chrominance noise. + +The filter accepts the following options: + +@table @option +@item thres +Set threshold for averaging chrominance values. +Sum of absolute difference of U and V pixel components or current +pixel and neighbour pixels lower than this threshold will be used in +averaging. Luma component is left unchanged and is copied to output. +Default value is 30. Allowed range is from 1 to 200. + +@item sizew +Set horizontal radius of rectangle used for averaging. +Allowed range is from 1 to 100. Default value is 5. + +@item sizeh +Set vertical radius of rectangle used for averaging. +Allowed range is from 1 to 100. Default value is 5. + +@item stepw +Set horizontal step when averaging. Default value is 1. +Allowed range is from 1 to 50. +Mostly useful to speed-up filtering. + +@item steph +Set vertical step when averaging. Default value is 1. +Allowed range is from 1 to 50. +Mostly useful to speed-up filtering. +@end table + +@subsection Commands +This filter supports same @ref{commands} as options. +The command accepts the same syntax of the corresponding option. + @section chromashift Shift chroma pixels horizontally and/or vertically. @@ -9288,13 +9327,21 @@ TensorFlow backend. To enable this backend you need to install the TensorFlow for C library (see @url{https://www.tensorflow.org/install/install_c}) and configure FFmpeg with @code{--enable-libtensorflow} + +@item openvino +OpenVINO backend. To enable this backend you +need to build and install the OpenVINO for C library (see +@url{https://github.com/openvinotoolkit/openvino/blob/master/build-instruction.md}) and configure FFmpeg with +@code{--enable-libopenvino} (--extra-cflags=-I... --extra-ldflags=-L... might +be needed if the header files and libraries are not installed into system path) + @end table Default value is @samp{native}. @item model Set path to model file specifying network architecture and its parameters. -Note that different backends use different file formats. TensorFlow and native +Note that different backends use different file formats. TensorFlow, OpenVINO and native backend can load files for only its format. Native model file (.model) can be generated from TensorFlow model file (.pb) by using tools/python/convert.py @@ -12809,7 +12856,7 @@ The obtained VMAF score is printed through the logging system. It requires Netflix's vmaf library (libvmaf) as a pre-requisite. After installing the library it can be enabled using: -@code{./configure --enable-libvmaf --enable-version3}. +@code{./configure --enable-libvmaf}. If no model path is specified it uses the default model: @code{vmaf_v0.6.1.pkl}. The filter has following options: @@ -14342,9 +14389,15 @@ It accepts the following values: @item yuv420 force YUV420 output +@item yuv420p10 +force YUV420p10 output + @item yuv422 force YUV422 output +@item yuv422p10 +force YUV422p10 output + @item yuv444 force YUV444 output @@ -17971,7 +18024,7 @@ subtitles=video.mkv:si=1 To make the subtitles stream from @file{sub.srt} appear in 80% transparent blue @code{DejaVu Serif}, use: @example -subtitles=sub.srt:force_style='FontName=DejaVu Serif,PrimaryColour=&HCCFF0000' +subtitles=sub.srt:force_style='Fontname=DejaVu Serif,PrimaryColour=&HCCFF0000' @end example @section super2xsai @@ -19313,6 +19366,46 @@ Truncated square pyramid projection. @item he @item hequirect Half equirectangular projection. + +@item equisolid +Equisolid format. + +Format specific options: +@table @option +@item h_fov +@item v_fov +@item d_fov +Set output horizontal/vertical/diagonal field of view. Values in degrees. + +If diagonal field of view is set it overrides horizontal and vertical field of view. + +@item ih_fov +@item iv_fov +@item id_fov +Set input horizontal/vertical/diagonal field of view. Values in degrees. + +If diagonal field of view is set it overrides horizontal and vertical field of view. +@end table + +@item og +Orthographic format. + +Format specific options: +@table @option +@item h_fov +@item v_fov +@item d_fov +Set output horizontal/vertical/diagonal field of view. Values in degrees. + +If diagonal field of view is set it overrides horizontal and vertical field of view. + +@item ih_fov +@item iv_fov +@item id_fov +Set input horizontal/vertical/diagonal field of view. Values in degrees. + +If diagonal field of view is set it overrides horizontal and vertical field of view. +@end table @end table @item interp @@ -20733,6 +20826,12 @@ Input frame count. @item on Output frame count. +@item in_time, it +The input timestamp expressed in seconds. It's NAN if the input timestamp is unknown. + +@item out_time, time, ot +The output timestamp expressed in seconds. + @item x @item y Last calculated 'x' and 'y' position from 'x' and 'y' expression @@ -20771,13 +20870,13 @@ display aspect ratio @itemize @item -Zoom-in up to 1.5 and pan at same time to some spot near center of picture: +Zoom in up to 1.5x and pan at same time to some spot near center of picture: @example zoompan=z='min(zoom+0.0015,1.5)':d=700:x='if(gte(zoom,1.5),x,x+1/a)':y='if(gte(zoom,1.5),y,y+1)':s=640x360 @end example @item -Zoom-in up to 1.5 and pan always at center of picture: +Zoom in up to 1.5x and pan always at center of picture: @example zoompan=z='min(zoom+0.0015,1.5)':d=700:x='iw/2-(iw/zoom/2)':y='ih/2-(ih/zoom/2)' @end example @@ -20787,6 +20886,13 @@ Same as above but without pausing: @example zoompan=z='min(max(zoom,pzoom)+0.0015,1.5)':d=1:x='iw/2-(iw/zoom/2)':y='ih/2-(ih/zoom/2)' @end example + +@item +Zoom in 2x into center of picture only for the first second of the input video: +@example +zoompan=z='if(between(in_time,0,1),2,1)':d=1:x='iw/2-(iw/zoom/2)':y='ih/2-(ih/zoom/2)' +@end example + @end itemize @anchor{zscale} diff --git a/externals/ffmpeg/doc/general.texi b/externals/ffmpeg/doc/general.texi index 9b0ee9675..53d556c56 100755 --- a/externals/ffmpeg/doc/general.texi +++ b/externals/ffmpeg/doc/general.texi @@ -751,6 +751,8 @@ following image formats are supported: @tab Portable GrayMap image @item PGMYUV @tab X @tab X @tab PGM with U and V components in YUV 4:2:0 +@item PGX @tab @tab X + @tab PGX file decoder @item PIC @tab @tab X @tab Pictor/PC Paint @item PNG @tab X @tab X @@ -803,6 +805,7 @@ following image formats are supported: @item Apple MJPEG-B @tab @tab X @item Apple Pixlet @tab @tab X @item Apple ProRes @tab X @tab X + @tab fourcc: apch,apcn,apcs,apco,ap4h,ap4x @item Apple QuickDraw @tab @tab X @tab fourcc: qdrw @item Asus v1 @tab X @tab X @@ -835,6 +838,8 @@ following image formats are supported: @item BitJazz SheerVideo @tab @tab X @item Bitmap Brothers JV video @tab @tab X @item y41p Brooktree uncompressed 4:1:1 12-bit @tab X @tab X +@item Brooktree ProSumer Video @tab @tab X + @tab fourcc: BT20 @item Brute Force & Ignorance @tab @tab X @tab Used in the game Flash Traffic: City of Angels. @item C93 video @tab @tab X @@ -968,6 +973,7 @@ following image formats are supported: @item MPEG-4 part 2 Microsoft variant version 3 @tab X @tab X @item Newtek SpeedHQ @tab @tab X @item Nintendo Gamecube THP video @tab @tab X +@item NotchLC @tab @tab X @item NuppelVideo/RTjpeg @tab @tab X @tab Video encoding used in NuppelVideo files. @item On2 VP3 @tab @tab X @@ -986,8 +992,6 @@ following image formats are supported: @tab encoding supported through external library libvpx @item Pinnacle TARGA CineWave YUV16 @tab @tab X @tab fourcc: Y216 -@item Prores @tab @tab X - @tab fourcc: apch,apcn,apcs,apco @item Q-team QPEG @tab @tab X @tab fourccs: QPEG, Q1.0, Q1.1 @item QuickTime 8BPS video @tab @tab X diff --git a/externals/ffmpeg/doc/indevs.texi b/externals/ffmpeg/doc/indevs.texi index 6f5afaf34..0f33fc66d 100755 --- a/externals/ffmpeg/doc/indevs.texi +++ b/externals/ffmpeg/doc/indevs.texi @@ -398,6 +398,12 @@ are dropped till a frame with timecode is received. Option @var{timecode_format} must be specified. Defaults to @option{false}. +@item enable_klv(@emph{bool}) +If set to @option{true}, extracts KLV data from VANC and outputs KLV packets. +KLV VANC packets are joined based on MID and PSC fields and aggregated into +one KLV packet. +Defaults to @option{false}. + @end table @subsection Examples diff --git a/externals/ffmpeg/doc/muxers.texi b/externals/ffmpeg/doc/muxers.texi index c598abbe6..86976f4f6 100755 --- a/externals/ffmpeg/doc/muxers.texi +++ b/externals/ffmpeg/doc/muxers.texi @@ -267,8 +267,10 @@ Override User-Agent field in HTTP header. Applicable only for HTTP output. @item http_persistent @var{http_persistent} Use persistent HTTP connections. Applicable only for HTTP output. @item hls_playlist @var{hls_playlist} -Generate HLS playlist files as well. The master playlist is generated with the filename master.m3u8. +Generate HLS playlist files as well. The master playlist is generated with the filename @var{hls_master_name}. One media playlist file is generated for each stream with filenames media_0.m3u8, media_1.m3u8, etc. +@item hls_master_name @var{file_name} +HLS master playlist name. Default is "master.m3u8". @item streaming @var{streaming} Enable (1) or disable (0) chunk streaming mode of output. In chunk streaming mode, each frame will be a moof fragment which forms a chunk. @@ -364,6 +366,10 @@ adjusting playback latency and buffer occupancy during normal playback by client Set the maximum playback rate indicated as appropriate for the purposes of automatically adjusting playback latency and buffer occupancy during normal playback by clients. +@item update_period @var{update_period} + Set the mpd update period ,for dynamic content. + The unit is second. + @end table @anchor{framecrc} @@ -2275,6 +2281,11 @@ certain (usually permanent) errors the recovery is not attempted even when Specify whether to wait for the keyframe after recovering from queue overflow or failure. This option is set to 0 (false) by default. +@item timeshift @var{duration} +Buffer the specified amount of packets and delay writing the output. Note that +@var{queue_size} must be big enough to store the packets for timeshift. At the +end of the input the fifo buffer is flushed at realtime speed. + @end table @subsection Examples diff --git a/externals/ffmpeg/doc/outdevs.texi b/externals/ffmpeg/doc/outdevs.texi index 60606eb6e..aaf247995 100755 --- a/externals/ffmpeg/doc/outdevs.texi +++ b/externals/ffmpeg/doc/outdevs.texi @@ -38,6 +38,52 @@ ffmpeg -i INPUT -f alsa hw:1,7 @end example @end itemize +@section AudioToolbox + +AudioToolbox output device. + +Allows native output to CoreAudio devices on OSX. + +The output filename can be empty (or @code{-}) to refer to the default system output device or a number that refers to the device index as shown using: @code{-list_devices true}. + +Alternatively, the audio input device can be chosen by index using the +@option{ + -audio_device_index +} +, overriding any device name or index given in the input filename. + +All available devices can be enumerated by using @option{-list_devices true}, listing +all device names, UIDs and corresponding indices. + +@subsection Options + +AudioToolbox supports the following options: + +@table @option + +@item -audio_device_index +Specify the audio device by its index. Overrides anything given in the output filename. + +@end table + +@subsection Examples + +@itemize + +@item +Print the list of supported devices and output a sine wave to the default device: +@example +$ ffmpeg -f lavfi -i sine=r=44100 -f audiotoolbox -list_devices true - +@end example + +@item +Output a sine wave to the device with the index 2, overriding any output filename: +@example +$ ffmpeg -f lavfi -i sine=r=44100 -f audiotoolbox -audio_device_index 2 - +@end example + +@end itemize + @section caca CACA output device. diff --git a/externals/ffmpeg/doc/protocols.texi b/externals/ffmpeg/doc/protocols.texi index 7aa758541..64ad3f05d 100755 --- a/externals/ffmpeg/doc/protocols.texi +++ b/externals/ffmpeg/doc/protocols.texi @@ -109,6 +109,21 @@ the received message may be truncated causing decoding errors. The timeout in seconds during the initial connection to the broker. The default value is rw_timeout, or 5 seconds if rw_timeout is not set. +@item delivery_mode @var{mode} +Sets the delivery mode of each message sent to broker. +The following values are accepted: +@table @samp +@item persistent +Delivery mode set to "persistent" (2). This is the default value. +Messages may be written to the broker's disk depending on its setup. + +@item non-persistent +Delivery mode set to "non-persistent" (1). +Messages will stay in broker's memory unless the broker is under memory +pressure. + +@end table + @end table @section async @@ -520,6 +535,9 @@ audio/mpeg. This enables support for Icecast versions < 2.4.0, that do not support the HTTP PUT method but the SOURCE method. +@item tls +Establish a TLS (HTTPS) connection to Icecast. + @end table @example diff --git a/externals/ffmpeg/doc/utils.texi b/externals/ffmpeg/doc/utils.texi index e7a9b40b3..44ce285d2 100755 --- a/externals/ffmpeg/doc/utils.texi +++ b/externals/ffmpeg/doc/utils.texi @@ -110,11 +110,13 @@ maximum of 2 digits. The @var{m} at the end expresses decimal value for @emph{or} @example -[-]@var{S}+[.@var{m}...] +[-]@var{S}+[.@var{m}...][s|ms|us] @end example @var{S} expresses the number of seconds, with the optional decimal part -@var{m}. +@var{m}. The optional literal suffixes @samp{s}, @samp{ms} or @samp{us} +indicate to interpret the value as seconds, milliseconds or microseconds, +respectively. In both expressions, the optional @samp{-} indicates negative duration. diff --git a/externals/ffmpeg/fftools/cmdutils.c b/externals/ffmpeg/fftools/cmdutils.c index 13567a777..88fdbeaf1 100755 --- a/externals/ffmpeg/fftools/cmdutils.c +++ b/externals/ffmpeg/fftools/cmdutils.c @@ -202,13 +202,14 @@ void show_help_options(const OptionDef *options, const char *msg, int req_flags, void show_help_children(const AVClass *class, int flags) { - const AVClass *child = NULL; + void *iter = NULL; + const AVClass *child; if (class->option) { av_opt_show2(&class, NULL, flags, 0); printf("\n"); } - while (child = av_opt_child_class_next(class, child)) + while (child = av_opt_child_class_iterate(class, &iter)) show_help_children(child, flags); } diff --git a/externals/ffmpeg/fftools/ffmpeg.h b/externals/ffmpeg/fftools/ffmpeg.h index 828cb2a4f..6e3f2545c 100755 --- a/externals/ffmpeg/fftools/ffmpeg.h +++ b/externals/ffmpeg/fftools/ffmpeg.h @@ -229,6 +229,8 @@ typedef struct OptionsContext { int nb_time_bases; SpecifierOpt *enc_time_bases; int nb_enc_time_bases; + SpecifierOpt *autoscale; + int nb_autoscale; } OptionsContext; typedef struct InputFilter { @@ -479,6 +481,7 @@ typedef struct OutputStream { int force_fps; int top_field_first; int rotate_overridden; + int autoscale; double rotate_override_value; AVRational frame_aspect_ratio; diff --git a/externals/ffmpeg/fftools/ffmpeg_filter.c b/externals/ffmpeg/fftools/ffmpeg_filter.c index 422e1268e..4784e8a57 100755 --- a/externals/ffmpeg/fftools/ffmpeg_filter.c +++ b/externals/ffmpeg/fftools/ffmpeg_filter.c @@ -470,7 +470,7 @@ static int configure_output_video_filter(FilterGraph *fg, OutputFilter *ofilter, if (ret < 0) return ret; - if (ofilter->width || ofilter->height) { + if ((ofilter->width || ofilter->height) && ofilter->ost->autoscale) { char args[255]; AVFilterContext *filter; AVDictionaryEntry *e = NULL; diff --git a/externals/ffmpeg/fftools/ffmpeg_opt.c b/externals/ffmpeg/fftools/ffmpeg_opt.c index 2eb4e1c97..9d1489ce0 100755 --- a/externals/ffmpeg/fftools/ffmpeg_opt.c +++ b/externals/ffmpeg/fftools/ffmpeg_opt.c @@ -62,6 +62,7 @@ static const char *opt_name_hwaccels[] = {"hwaccel", NULL}; static const char *opt_name_hwaccel_devices[] = {"hwaccel_device", NULL}; static const char *opt_name_hwaccel_output_formats[] = {"hwaccel_output_format", NULL}; static const char *opt_name_autorotate[] = {"autorotate", NULL}; +static const char *opt_name_autoscale[] = {"autoscale", NULL}; static const char *opt_name_max_frames[] = {"frames", "aframes", "vframes", "dframes", NULL}; static const char *opt_name_bitstream_filters[] = {"bsf", "absf", "vbsf", NULL}; static const char *opt_name_codec_tags[] = {"tag", "atag", "vtag", "stag", NULL}; @@ -1462,6 +1463,8 @@ static OutputStream *new_output_stream(OptionsContext *o, AVFormatContext *oc, e ost->encoder_opts = filter_codec_opts(o->g->codec_opts, ost->enc->id, oc, st, ost->enc); MATCH_PER_STREAM_OPT(presets, str, preset, oc, st); + ost->autoscale = 1; + MATCH_PER_STREAM_OPT(autoscale, i, ost->autoscale, oc, st); if (preset && (!(ret = get_preset_file_2(preset, ost->enc->name, &s)))) { do { buf = get_line(s); @@ -3664,6 +3667,9 @@ const OptionDef options[] = { { "autorotate", HAS_ARG | OPT_BOOL | OPT_SPEC | OPT_EXPERT | OPT_INPUT, { .off = OFFSET(autorotate) }, "automatically insert correct rotate filters" }, + { "autoscale", HAS_ARG | OPT_BOOL | OPT_SPEC | + OPT_EXPERT | OPT_OUTPUT, { .off = OFFSET(autoscale) }, + "automatically insert a scale filter at the end of the filter graph" }, /* audio options */ { "aframes", OPT_AUDIO | HAS_ARG | OPT_PERFILE | OPT_OUTPUT, { .func_arg = opt_audio_frames }, diff --git a/externals/ffmpeg/fftools/ffprobe.c b/externals/ffmpeg/fftools/ffprobe.c index 5515e1b31..d4e494f11 100755 --- a/externals/ffmpeg/fftools/ffprobe.c +++ b/externals/ffmpeg/fftools/ffprobe.c @@ -2854,7 +2854,7 @@ static int open_input_file(InputFile *ifile, const char *filename, { int err, i; AVFormatContext *fmt_ctx = NULL; - AVDictionaryEntry *t; + AVDictionaryEntry *t = NULL; int scan_all_pmts_set = 0; fmt_ctx = avformat_alloc_context(); @@ -2879,10 +2879,8 @@ static int open_input_file(InputFile *ifile, const char *filename, ifile->fmt_ctx = fmt_ctx; if (scan_all_pmts_set) av_dict_set(&format_opts, "scan_all_pmts", NULL, AV_DICT_MATCH_CASE); - if ((t = av_dict_get(format_opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) { - av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key); - return AVERROR_OPTION_NOT_FOUND; - } + while ((t = av_dict_get(format_opts, "", t, AV_DICT_IGNORE_SUFFIX))) + av_log(NULL, AV_LOG_WARNING, "Option %s skipped - not known to demuxer.\n", t->key); if (find_stream_info) { AVDictionary **opts = setup_find_stream_info_opts(fmt_ctx, codec_opts); diff --git a/externals/ffmpeg/libavcodec/Makefile b/externals/ffmpeg/libavcodec/Makefile index 5a6ea5971..18353da54 100755 --- a/externals/ffmpeg/libavcodec/Makefile +++ b/externals/ffmpeg/libavcodec/Makefile @@ -536,6 +536,7 @@ OBJS-$(CONFIG_PGM_ENCODER) += pnmenc.o OBJS-$(CONFIG_PGMYUV_DECODER) += pnmdec.o pnm.o OBJS-$(CONFIG_PGMYUV_ENCODER) += pnmenc.o OBJS-$(CONFIG_PGSSUB_DECODER) += pgssubdec.o +OBJS-$(CONFIG_PGX_DECODER) += pgxdec.o OBJS-$(CONFIG_PICTOR_DECODER) += pictordec.o cga_data.o OBJS-$(CONFIG_PIXLET_DECODER) += pixlet.o OBJS-$(CONFIG_PJS_DECODER) += textdec.o ass.o @@ -910,7 +911,7 @@ OBJS-$(CONFIG_HEVC_DXVA2_HWACCEL) += dxva2_hevc.o OBJS-$(CONFIG_HEVC_NVDEC_HWACCEL) += nvdec_hevc.o OBJS-$(CONFIG_HEVC_QSV_HWACCEL) += qsvdec_h2645.o OBJS-$(CONFIG_HEVC_VAAPI_HWACCEL) += vaapi_hevc.o h265_profile_level.o -OBJS-$(CONFIG_HEVC_VDPAU_HWACCEL) += vdpau_hevc.o +OBJS-$(CONFIG_HEVC_VDPAU_HWACCEL) += vdpau_hevc.o h265_profile_level.o OBJS-$(CONFIG_MJPEG_NVDEC_HWACCEL) += nvdec_mjpeg.o OBJS-$(CONFIG_MJPEG_VAAPI_HWACCEL) += vaapi_mjpeg.o OBJS-$(CONFIG_MPEG1_NVDEC_HWACCEL) += nvdec_mpeg12.o diff --git a/externals/ffmpeg/libavcodec/aac_ac3_parser.c b/externals/ffmpeg/libavcodec/aac_ac3_parser.c index 54e459844..0746798da 100755 --- a/externals/ffmpeg/libavcodec/aac_ac3_parser.c +++ b/externals/ffmpeg/libavcodec/aac_ac3_parser.c @@ -97,8 +97,13 @@ get_next: avctx->audio_service_type = s->service_type; } - if (avctx->codec_id != AV_CODEC_ID_EAC3) - avctx->bit_rate = s->bit_rate; + /* Calculate the average bit rate */ + s->frame_number++; + if (avctx->codec_id != AV_CODEC_ID_EAC3) { + avctx->bit_rate = + (s->last_bit_rate * (s->frame_number -1) + s->bit_rate)/s->frame_number; + s->last_bit_rate = avctx->bit_rate; + } } return i; diff --git a/externals/ffmpeg/libavcodec/aac_ac3_parser.h b/externals/ffmpeg/libavcodec/aac_ac3_parser.h index c2506a5bf..b04041f69 100755 --- a/externals/ffmpeg/libavcodec/aac_ac3_parser.h +++ b/externals/ffmpeg/libavcodec/aac_ac3_parser.h @@ -55,6 +55,8 @@ typedef struct AACAC3ParseContext { uint64_t state; int need_next_header; + int frame_number; + int last_bit_rate; enum AVCodecID codec_id; } AACAC3ParseContext; diff --git a/externals/ffmpeg/libavcodec/aacenc.c b/externals/ffmpeg/libavcodec/aacenc.c index db11e0ca2..e65b76cd7 100755 --- a/externals/ffmpeg/libavcodec/aacenc.c +++ b/externals/ffmpeg/libavcodec/aacenc.c @@ -941,15 +941,14 @@ static av_cold int dsp_init(AVCodecContext *avctx, AACEncContext *s) static av_cold int alloc_buffers(AVCodecContext *avctx, AACEncContext *s) { int ch; - FF_ALLOCZ_ARRAY_OR_GOTO(avctx, s->buffer.samples, s->channels, 3 * 1024 * sizeof(s->buffer.samples[0]), alloc_fail); - FF_ALLOCZ_ARRAY_OR_GOTO(avctx, s->cpe, s->chan_map[0], sizeof(ChannelElement), alloc_fail); + if (!FF_ALLOCZ_TYPED_ARRAY(s->buffer.samples, s->channels * 3 * 1024) || + !FF_ALLOCZ_TYPED_ARRAY(s->cpe, s->chan_map[0])) + return AVERROR(ENOMEM); for(ch = 0; ch < s->channels; ch++) s->planar_samples[ch] = s->buffer.samples + 3 * 1024 * ch; return 0; -alloc_fail: - return AVERROR(ENOMEM); } static av_cold void aac_encode_init_tables(void) @@ -1078,13 +1077,13 @@ static av_cold int aac_encode_init(AVCodecContext *avctx) s->options.mid_side = 0; if ((ret = dsp_init(avctx, s)) < 0) - goto fail; + return ret; if ((ret = alloc_buffers(avctx, s)) < 0) - goto fail; + return ret; if ((ret = put_audio_specific_config(avctx))) - goto fail; + return ret; sizes[0] = ff_aac_swb_size_1024[s->samplerate_index]; sizes[1] = ff_aac_swb_size_128[s->samplerate_index]; @@ -1094,7 +1093,7 @@ static av_cold int aac_encode_init(AVCodecContext *avctx) grouping[i] = s->chan_map[i + 1] == TYPE_CPE; if ((ret = ff_psy_init(&s->psy, avctx, 2, sizes, lengths, s->chan_map[0], grouping)) < 0) - goto fail; + return ret; s->psypp = ff_psy_preprocess_init(avctx); ff_lpc_init(&s->lpc, 2*avctx->frame_size, TNS_MAX_ORDER, FF_LPC_TYPE_LEVINSON); s->random_state = 0x1f2e3d4c; @@ -1114,9 +1113,6 @@ static av_cold int aac_encode_init(AVCodecContext *avctx) ff_af_queue_init(avctx, &s->afq); return 0; -fail: - aac_encode_end(avctx); - return ret; } #define AACENC_FLAGS AV_OPT_FLAG_ENCODING_PARAM | AV_OPT_FLAG_AUDIO_PARAM @@ -1159,7 +1155,7 @@ AVCodec ff_aac_encoder = { .close = aac_encode_end, .defaults = aac_encode_defaults, .supported_samplerates = mpeg4audio_sample_rates, - .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP, .capabilities = AV_CODEC_CAP_SMALL_LAST_FRAME | AV_CODEC_CAP_DELAY, .sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_NONE }, diff --git a/externals/ffmpeg/libavcodec/ac3enc.c b/externals/ffmpeg/libavcodec/ac3enc.c index ddbc7b247..37dc0fb2e 100755 --- a/externals/ffmpeg/libavcodec/ac3enc.c +++ b/externals/ffmpeg/libavcodec/ac3enc.c @@ -2322,60 +2322,46 @@ static av_cold void set_bandwidth(AC3EncodeContext *s) static av_cold int allocate_buffers(AC3EncodeContext *s) { - AVCodecContext *avctx = s->avctx; int blk, ch; int channels = s->channels + 1; /* includes coupling channel */ int channel_blocks = channels * s->num_blocks; int total_coefs = AC3_MAX_COEFS * channel_blocks; if (s->allocate_sample_buffers(s)) - goto alloc_fail; + return AVERROR(ENOMEM); + + if (!FF_ALLOC_TYPED_ARRAY(s->bap_buffer, total_coefs) || + !FF_ALLOC_TYPED_ARRAY(s->bap1_buffer, total_coefs) || + !FF_ALLOCZ_TYPED_ARRAY(s->mdct_coef_buffer, total_coefs) || + !FF_ALLOC_TYPED_ARRAY(s->exp_buffer, total_coefs) || + !FF_ALLOC_TYPED_ARRAY(s->grouped_exp_buffer, channel_blocks * 128) || + !FF_ALLOC_TYPED_ARRAY(s->psd_buffer, total_coefs) || + !FF_ALLOC_TYPED_ARRAY(s->band_psd_buffer, channel_blocks * 64) || + !FF_ALLOC_TYPED_ARRAY(s->mask_buffer, channel_blocks * 64) || + !FF_ALLOC_TYPED_ARRAY(s->qmant_buffer, total_coefs)) + return AVERROR(ENOMEM); - FF_ALLOC_ARRAY_OR_GOTO(avctx, s->bap_buffer, total_coefs, - sizeof(*s->bap_buffer), alloc_fail); - FF_ALLOC_ARRAY_OR_GOTO(avctx, s->bap1_buffer, total_coefs, - sizeof(*s->bap1_buffer), alloc_fail); - FF_ALLOCZ_ARRAY_OR_GOTO(avctx, s->mdct_coef_buffer, total_coefs, - sizeof(*s->mdct_coef_buffer), alloc_fail); - FF_ALLOC_ARRAY_OR_GOTO(avctx, s->exp_buffer, total_coefs, - sizeof(*s->exp_buffer), alloc_fail); - FF_ALLOC_ARRAY_OR_GOTO(avctx, s->grouped_exp_buffer, channel_blocks, 128 * - sizeof(*s->grouped_exp_buffer), alloc_fail); - FF_ALLOC_ARRAY_OR_GOTO(avctx, s->psd_buffer, total_coefs, - sizeof(*s->psd_buffer), alloc_fail); - FF_ALLOC_ARRAY_OR_GOTO(avctx, s->band_psd_buffer, channel_blocks, 64 * - sizeof(*s->band_psd_buffer), alloc_fail); - FF_ALLOC_ARRAY_OR_GOTO(avctx, s->mask_buffer, channel_blocks, 64 * - sizeof(*s->mask_buffer), alloc_fail); - FF_ALLOC_ARRAY_OR_GOTO(avctx, s->qmant_buffer, total_coefs, - sizeof(*s->qmant_buffer), alloc_fail); if (s->cpl_enabled) { - FF_ALLOC_ARRAY_OR_GOTO(avctx, s->cpl_coord_exp_buffer, channel_blocks, 16 * - sizeof(*s->cpl_coord_exp_buffer), alloc_fail); - FF_ALLOC_ARRAY_OR_GOTO(avctx, s->cpl_coord_mant_buffer, channel_blocks, 16 * - sizeof(*s->cpl_coord_mant_buffer), alloc_fail); + if (!FF_ALLOC_TYPED_ARRAY(s->cpl_coord_exp_buffer, channel_blocks * 16) || + !FF_ALLOC_TYPED_ARRAY(s->cpl_coord_mant_buffer, channel_blocks * 16)) + return AVERROR(ENOMEM); } for (blk = 0; blk < s->num_blocks; blk++) { AC3Block *block = &s->blocks[blk]; - FF_ALLOCZ_ARRAY_OR_GOTO(avctx, block->mdct_coef, channels, sizeof(*block->mdct_coef), - alloc_fail); - FF_ALLOCZ_ARRAY_OR_GOTO(avctx, block->exp, channels, sizeof(*block->exp), - alloc_fail); - FF_ALLOCZ_ARRAY_OR_GOTO(avctx, block->grouped_exp, channels, sizeof(*block->grouped_exp), - alloc_fail); - FF_ALLOCZ_ARRAY_OR_GOTO(avctx, block->psd, channels, sizeof(*block->psd), - alloc_fail); - FF_ALLOCZ_ARRAY_OR_GOTO(avctx, block->band_psd, channels, sizeof(*block->band_psd), - alloc_fail); - FF_ALLOCZ_ARRAY_OR_GOTO(avctx, block->mask, channels, sizeof(*block->mask), - alloc_fail); - FF_ALLOCZ_ARRAY_OR_GOTO(avctx, block->qmant, channels, sizeof(*block->qmant), - alloc_fail); + + if (!FF_ALLOCZ_TYPED_ARRAY(block->mdct_coef, channels) || + !FF_ALLOCZ_TYPED_ARRAY(block->exp, channels) || + !FF_ALLOCZ_TYPED_ARRAY(block->grouped_exp, channels) || + !FF_ALLOCZ_TYPED_ARRAY(block->psd, channels) || + !FF_ALLOCZ_TYPED_ARRAY(block->band_psd, channels) || + !FF_ALLOCZ_TYPED_ARRAY(block->mask, channels) || + !FF_ALLOCZ_TYPED_ARRAY(block->qmant, channels)) + return AVERROR(ENOMEM); + if (s->cpl_enabled) { - FF_ALLOCZ_ARRAY_OR_GOTO(avctx, block->cpl_coord_exp, channels, sizeof(*block->cpl_coord_exp), - alloc_fail); - FF_ALLOCZ_ARRAY_OR_GOTO(avctx, block->cpl_coord_mant, channels, sizeof(*block->cpl_coord_mant), - alloc_fail); + if (!FF_ALLOCZ_TYPED_ARRAY(block->cpl_coord_exp, channels) || + !FF_ALLOCZ_TYPED_ARRAY(block->cpl_coord_mant, channels)) + return AVERROR(ENOMEM); } for (ch = 0; ch < channels; ch++) { @@ -2397,28 +2383,26 @@ static av_cold int allocate_buffers(AC3EncodeContext *s) } if (!s->fixed_point) { - FF_ALLOCZ_ARRAY_OR_GOTO(avctx, s->fixed_coef_buffer, total_coefs, - sizeof(*s->fixed_coef_buffer), alloc_fail); + if (!FF_ALLOCZ_TYPED_ARRAY(s->fixed_coef_buffer, total_coefs)) + return AVERROR(ENOMEM); for (blk = 0; blk < s->num_blocks; blk++) { AC3Block *block = &s->blocks[blk]; - FF_ALLOCZ_ARRAY_OR_GOTO(avctx, block->fixed_coef, channels, - sizeof(*block->fixed_coef), alloc_fail); + if (!FF_ALLOCZ_TYPED_ARRAY(block->fixed_coef, channels)) + return AVERROR(ENOMEM); for (ch = 0; ch < channels; ch++) block->fixed_coef[ch] = &s->fixed_coef_buffer[AC3_MAX_COEFS * (s->num_blocks * ch + blk)]; } } else { for (blk = 0; blk < s->num_blocks; blk++) { AC3Block *block = &s->blocks[blk]; - FF_ALLOCZ_ARRAY_OR_GOTO(avctx, block->fixed_coef, channels, - sizeof(*block->fixed_coef), alloc_fail); + if (!FF_ALLOCZ_TYPED_ARRAY(block->fixed_coef, channels)) + return AVERROR(ENOMEM); for (ch = 0; ch < channels; ch++) block->fixed_coef[ch] = (int32_t *)block->mdct_coef[ch]; } } return 0; -alloc_fail: - return AVERROR(ENOMEM); } @@ -2433,7 +2417,7 @@ av_cold int ff_ac3_encode_init(AVCodecContext *avctx) ret = validate_options(s); if (ret) - goto init_fail; + return ret; avctx->frame_size = AC3_BLOCK_SIZE * s->num_blocks; avctx->initial_padding = AC3_BLOCK_SIZE; @@ -2476,11 +2460,11 @@ av_cold int ff_ac3_encode_init(AVCodecContext *avctx) ret = s->mdct_init(s); if (ret) - goto init_fail; + return ret; ret = allocate_buffers(s); if (ret) - goto init_fail; + return ret; ff_audiodsp_init(&s->adsp); ff_me_cmp_init(&s->mecc, avctx); @@ -2489,7 +2473,4 @@ av_cold int ff_ac3_encode_init(AVCodecContext *avctx) dprint_options(s); return 0; -init_fail: - ff_ac3_encode_close(avctx); - return ret; } diff --git a/externals/ffmpeg/libavcodec/ac3enc_fixed.c b/externals/ffmpeg/libavcodec/ac3enc_fixed.c index e57d03529..428bbfb3c 100755 --- a/externals/ffmpeg/libavcodec/ac3enc_fixed.c +++ b/externals/ffmpeg/libavcodec/ac3enc_fixed.c @@ -155,6 +155,7 @@ AVCodec ff_ac3_fixed_encoder = { .sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16P, AV_SAMPLE_FMT_NONE }, .priv_class = &ac3enc_class, + .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, .supported_samplerates = ff_ac3_sample_rate_tab, .channel_layouts = ff_ac3_channel_layouts, .defaults = ac3_defaults, diff --git a/externals/ffmpeg/libavcodec/ac3enc_template.c b/externals/ffmpeg/libavcodec/ac3enc_template.c index be659872f..985b35e5b 100755 --- a/externals/ffmpeg/libavcodec/ac3enc_template.c +++ b/externals/ffmpeg/libavcodec/ac3enc_template.c @@ -41,19 +41,16 @@ int AC3_NAME(allocate_sample_buffers)(AC3EncodeContext *s) { int ch; - FF_ALLOC_OR_GOTO(s->avctx, s->windowed_samples, AC3_WINDOW_SIZE * - sizeof(*s->windowed_samples), alloc_fail); - FF_ALLOC_ARRAY_OR_GOTO(s->avctx, s->planar_samples, s->channels, sizeof(*s->planar_samples), - alloc_fail); - for (ch = 0; ch < s->channels; ch++) { - FF_ALLOCZ_OR_GOTO(s->avctx, s->planar_samples[ch], - (AC3_FRAME_SIZE+AC3_BLOCK_SIZE) * sizeof(**s->planar_samples), - alloc_fail); - } + if (!FF_ALLOC_TYPED_ARRAY(s->windowed_samples, AC3_WINDOW_SIZE) || + !FF_ALLOC_TYPED_ARRAY(s->planar_samples, s->channels)) + return AVERROR(ENOMEM); + for (ch = 0; ch < s->channels; ch++) { + if (!(s->planar_samples[ch] = av_mallocz((AC3_FRAME_SIZE + AC3_BLOCK_SIZE) * + sizeof(**s->planar_samples)))) + return AVERROR(ENOMEM); + } return 0; -alloc_fail: - return AVERROR(ENOMEM); } diff --git a/externals/ffmpeg/libavcodec/adpcm.c b/externals/ffmpeg/libavcodec/adpcm.c index 79c5d625d..4de4a2328 100755 --- a/externals/ffmpeg/libavcodec/adpcm.c +++ b/externals/ffmpeg/libavcodec/adpcm.c @@ -162,11 +162,18 @@ static av_cold int adpcm_decode_init(AVCodecContext * avctx) } break; case AV_CODEC_ID_ADPCM_IMA_APM: - if (avctx->extradata && avctx->extradata_size >= 16) { - c->status[0].predictor = av_clip_intp2(AV_RL32(avctx->extradata + 0), 18); - c->status[0].step_index = av_clip(AV_RL32(avctx->extradata + 4), 0, 88); - c->status[1].predictor = av_clip_intp2(AV_RL32(avctx->extradata + 8), 18); - c->status[1].step_index = av_clip(AV_RL32(avctx->extradata + 12), 0, 88); + if (avctx->extradata) { + if (avctx->extradata_size >= 28) { + c->status[0].predictor = av_clip_intp2(AV_RL32(avctx->extradata + 16), 18); + c->status[0].step_index = av_clip(AV_RL32(avctx->extradata + 20), 0, 88); + c->status[1].predictor = av_clip_intp2(AV_RL32(avctx->extradata + 4), 18); + c->status[1].step_index = av_clip(AV_RL32(avctx->extradata + 8), 0, 88); + } else if (avctx->extradata_size >= 16) { + c->status[0].predictor = av_clip_intp2(AV_RL32(avctx->extradata + 0), 18); + c->status[0].step_index = av_clip(AV_RL32(avctx->extradata + 4), 0, 88); + c->status[1].predictor = av_clip_intp2(AV_RL32(avctx->extradata + 8), 18); + c->status[1].step_index = av_clip(AV_RL32(avctx->extradata + 12), 0, 88); + } } break; case AV_CODEC_ID_ADPCM_IMA_WS: diff --git a/externals/ffmpeg/libavcodec/adpcmenc.c b/externals/ffmpeg/libavcodec/adpcmenc.c index d5fbc0b9a..1e94ef404 100755 --- a/externals/ffmpeg/libavcodec/adpcmenc.c +++ b/externals/ffmpeg/libavcodec/adpcmenc.c @@ -58,14 +58,11 @@ typedef struct ADPCMEncodeContext { #define FREEZE_INTERVAL 128 -static av_cold int adpcm_encode_close(AVCodecContext *avctx); - static av_cold int adpcm_encode_init(AVCodecContext *avctx) { ADPCMEncodeContext *s = avctx->priv_data; uint8_t *extradata; int i; - int ret = AVERROR(ENOMEM); if (avctx->channels > 2) { av_log(avctx, AV_LOG_ERROR, "only stereo or mono is supported\n"); @@ -89,14 +86,11 @@ static av_cold int adpcm_encode_init(AVCodecContext *avctx) if (avctx->trellis) { int frontier = 1 << avctx->trellis; int max_paths = frontier * FREEZE_INTERVAL; - FF_ALLOC_OR_GOTO(avctx, s->paths, - max_paths * sizeof(*s->paths), error); - FF_ALLOC_OR_GOTO(avctx, s->node_buf, - 2 * frontier * sizeof(*s->node_buf), error); - FF_ALLOC_OR_GOTO(avctx, s->nodep_buf, - 2 * frontier * sizeof(*s->nodep_buf), error); - FF_ALLOC_OR_GOTO(avctx, s->trellis_hash, - 65536 * sizeof(*s->trellis_hash), error); + if (!FF_ALLOC_TYPED_ARRAY(s->paths, max_paths) || + !FF_ALLOC_TYPED_ARRAY(s->node_buf, 2 * frontier) || + !FF_ALLOC_TYPED_ARRAY(s->nodep_buf, 2 * frontier) || + !FF_ALLOC_TYPED_ARRAY(s->trellis_hash, 65536)) + return AVERROR(ENOMEM); } avctx->bits_per_coded_sample = av_get_bits_per_sample(avctx->codec->id); @@ -123,7 +117,7 @@ static av_cold int adpcm_encode_init(AVCodecContext *avctx) avctx->bits_per_coded_sample = 4; avctx->block_align = BLKSIZE; if (!(avctx->extradata = av_malloc(32 + AV_INPUT_BUFFER_PADDING_SIZE))) - goto error; + return AVERROR(ENOMEM); avctx->extradata_size = 32; extradata = avctx->extradata; bytestream_put_le16(&extradata, avctx->frame_size); @@ -143,8 +137,7 @@ static av_cold int adpcm_encode_init(AVCodecContext *avctx) avctx->sample_rate != 44100) { av_log(avctx, AV_LOG_ERROR, "Sample rate must be 11025, " "22050 or 44100\n"); - ret = AVERROR(EINVAL); - goto error; + return AVERROR(EINVAL); } avctx->frame_size = 512 * (avctx->sample_rate / 11025); break; @@ -153,13 +146,10 @@ static av_cold int adpcm_encode_init(AVCodecContext *avctx) avctx->block_align = BLKSIZE; break; default: - ret = AVERROR(EINVAL); - goto error; + return AVERROR(EINVAL); } return 0; -error: - return ret; } static av_cold int adpcm_encode_close(AVCodecContext *avctx) @@ -523,7 +513,8 @@ static int adpcm_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, /* stereo: 4 bytes (8 samples) for left, 4 bytes for right */ if (avctx->trellis > 0) { - FF_ALLOC_ARRAY_OR_GOTO(avctx, buf, avctx->channels, blocks * 8, error); + if (!FF_ALLOC_TYPED_ARRAY(buf, avctx->channels * blocks * 8)) + return AVERROR(ENOMEM); for (ch = 0; ch < avctx->channels; ch++) { adpcm_compress_trellis(avctx, &samples_p[ch][1], buf + ch * blocks * 8, &c->status[ch], @@ -618,7 +609,8 @@ static int adpcm_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, } if (avctx->trellis > 0) { - FF_ALLOC_OR_GOTO(avctx, buf, 2 * n, error); + if (!(buf = av_malloc(2 * n))) + return AVERROR(ENOMEM); adpcm_compress_trellis(avctx, samples + avctx->channels, buf, &c->status[0], n, avctx->channels); if (avctx->channels == 2) @@ -666,7 +658,8 @@ static int adpcm_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, if (avctx->trellis > 0) { n = avctx->block_align - 7 * avctx->channels; - FF_ALLOC_OR_GOTO(avctx, buf, 2 * n, error); + if (!(buf = av_malloc(2 * n))) + return AVERROR(ENOMEM); if (avctx->channels == 1) { adpcm_compress_trellis(avctx, samples, buf, &c->status[0], n, avctx->channels); @@ -693,7 +686,8 @@ static int adpcm_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, case AV_CODEC_ID_ADPCM_YAMAHA: n = frame->nb_samples / 2; if (avctx->trellis > 0) { - FF_ALLOC_OR_GOTO(avctx, buf, 2 * n * 2, error); + if (!(buf = av_malloc(2 * n * 2))) + return AVERROR(ENOMEM); n *= 2; if (avctx->channels == 1) { adpcm_compress_trellis(avctx, samples, buf, &c->status[0], n, @@ -724,8 +718,6 @@ static int adpcm_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, avpkt->size = pkt_size; *got_packet_ptr = 1; return 0; -error: - return AVERROR(ENOMEM); } static const enum AVSampleFormat sample_fmts[] = { diff --git a/externals/ffmpeg/libavcodec/alac.c b/externals/ffmpeg/libavcodec/alac.c index 82689da02..bf0540623 100755 --- a/externals/ffmpeg/libavcodec/alac.c +++ b/externals/ffmpeg/libavcodec/alac.c @@ -489,6 +489,7 @@ static int allocate_buffers(ALACContext *alac) { int ch; unsigned buf_size = alac->max_samples_per_frame * sizeof(int32_t); + unsigned extra_buf_size = buf_size + AV_INPUT_BUFFER_PADDING_SIZE; for (ch = 0; ch < 2; ch++) { alac->predict_error_buffer[ch] = NULL; @@ -497,22 +498,19 @@ static int allocate_buffers(ALACContext *alac) } for (ch = 0; ch < FFMIN(alac->channels, 2); ch++) { - FF_ALLOC_OR_GOTO(alac->avctx, alac->predict_error_buffer[ch], - buf_size, buf_alloc_fail); + if (!(alac->predict_error_buffer[ch] = av_malloc(buf_size))) + return AVERROR(ENOMEM); alac->direct_output = alac->sample_size > 16; if (!alac->direct_output) { - FF_ALLOC_OR_GOTO(alac->avctx, alac->output_samples_buffer[ch], - buf_size + AV_INPUT_BUFFER_PADDING_SIZE, buf_alloc_fail); + if (!(alac->output_samples_buffer[ch] = av_malloc(extra_buf_size))) + return AVERROR(ENOMEM); } - FF_ALLOC_OR_GOTO(alac->avctx, alac->extra_bits_buffer[ch], - buf_size + AV_INPUT_BUFFER_PADDING_SIZE, buf_alloc_fail); + if (!(alac->extra_bits_buffer[ch] = av_malloc(extra_buf_size))) + return AVERROR(ENOMEM); } return 0; -buf_alloc_fail: - alac_decode_close(alac->avctx); - return AVERROR(ENOMEM); } static int alac_set_info(ALACContext *alac) @@ -625,5 +623,6 @@ AVCodec ff_alac_decoder = { .close = alac_decode_close, .decode = alac_decode_frame, .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS, + .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, .priv_class = &alac_class }; diff --git a/externals/ffmpeg/libavcodec/allcodecs.c b/externals/ffmpeg/libavcodec/allcodecs.c index 80f128cad..a5048290f 100755 --- a/externals/ffmpeg/libavcodec/allcodecs.c +++ b/externals/ffmpeg/libavcodec/allcodecs.c @@ -238,6 +238,7 @@ extern AVCodec ff_pgm_encoder; extern AVCodec ff_pgm_decoder; extern AVCodec ff_pgmyuv_encoder; extern AVCodec ff_pgmyuv_decoder; +extern AVCodec ff_pgx_decoder; extern AVCodec ff_pictor_decoder; extern AVCodec ff_pixlet_decoder; extern AVCodec ff_png_encoder; @@ -679,9 +680,7 @@ extern AVCodec ff_xsub_decoder; /* external libraries */ extern AVCodec ff_aac_at_encoder; extern AVCodec ff_aac_at_decoder; -extern AVCodec ff_aac_mf_encoder; extern AVCodec ff_ac3_at_decoder; -extern AVCodec ff_ac3_mf_encoder; extern AVCodec ff_adpcm_ima_qt_at_decoder; extern AVCodec ff_alac_at_encoder; extern AVCodec ff_alac_at_decoder; @@ -693,7 +692,6 @@ extern AVCodec ff_ilbc_at_decoder; extern AVCodec ff_mp1_at_decoder; extern AVCodec ff_mp2_at_decoder; extern AVCodec ff_mp3_at_decoder; -extern AVCodec ff_mp3_mf_encoder; extern AVCodec ff_pcm_alaw_at_encoder; extern AVCodec ff_pcm_alaw_at_decoder; extern AVCodec ff_pcm_mulaw_at_encoder; @@ -757,6 +755,8 @@ extern AVCodec ff_idf_decoder; /* external libraries, that shouldn't be used by default if one of the * above is available */ +extern AVCodec ff_aac_mf_encoder; +extern AVCodec ff_ac3_mf_encoder; extern AVCodec ff_h263_v4l2m2m_encoder; extern AVCodec ff_libaom_av1_decoder; extern AVCodec ff_libopenh264_encoder; @@ -789,6 +789,7 @@ extern AVCodec ff_mjpeg_cuvid_decoder; extern AVCodec ff_mjpeg_qsv_encoder; extern AVCodec ff_mjpeg_qsv_decoder; extern AVCodec ff_mjpeg_vaapi_encoder; +extern AVCodec ff_mp3_mf_encoder; extern AVCodec ff_mpeg1_cuvid_decoder; extern AVCodec ff_mpeg2_cuvid_decoder; extern AVCodec ff_mpeg2_qsv_encoder; diff --git a/externals/ffmpeg/libavcodec/amfenc.c b/externals/ffmpeg/libavcodec/amfenc.c index 876fddd2b..da0652943 100755 --- a/externals/ffmpeg/libavcodec/amfenc.c +++ b/externals/ffmpeg/libavcodec/amfenc.c @@ -33,6 +33,7 @@ #include "libavutil/time.h" #include "amfenc.h" +#include "encode.h" #include "internal.h" #if CONFIG_D3D11VA @@ -588,17 +589,27 @@ static void amf_release_buffer_with_frame_ref(AMFBuffer *frame_ref_storage_buffe frame_ref_storage_buffer->pVtbl->Release(frame_ref_storage_buffer); } -int ff_amf_send_frame(AVCodecContext *avctx, const AVFrame *frame) +int ff_amf_receive_packet(AVCodecContext *avctx, AVPacket *avpkt) { AmfContext *ctx = avctx->priv_data; AMFSurface *surface; AMF_RESULT res; int ret; + AMF_RESULT res_query; + AMFData *data = NULL; + AVFrame *frame = ctx->delayed_frame; + int block_and_wait; if (!ctx->encoder) return AVERROR(EINVAL); - if (!frame) { // submit drain + if (!frame->buf[0]) { + ret = ff_encode_get_frame(avctx, frame); + if (ret < 0 && ret != AVERROR_EOF) + return ret; + } + + if (!frame->buf[0]) { // submit drain if (!ctx->eof) { // submit drain one time only if (ctx->delayed_surface != NULL) { ctx->delayed_drain = 1; // input queue is full: resubmit Drain() in ff_amf_receive_packet @@ -613,15 +624,10 @@ int ff_amf_send_frame(AVCodecContext *avctx, const AVFrame *frame) AMF_RETURN_IF_FALSE(ctx, res == AMF_OK, AVERROR_UNKNOWN, "Drain() failed with error %d\n", res); } } - } else{ - return AVERROR_EOF; } - } else { // submit frame + } else if (!ctx->delayed_surface) { // submit frame int hw_surface = 0; - if (ctx->delayed_surface != NULL) { - return AVERROR(EAGAIN); // should not happen when called from ffmpeg, other clients may resubmit - } // prepare surface from frame switch (frame->format) { #if CONFIG_D3D11VA @@ -693,38 +699,23 @@ int ff_amf_send_frame(AVCodecContext *avctx, const AVFrame *frame) break; } - // submit surface res = ctx->encoder->pVtbl->SubmitInput(ctx->encoder, (AMFData*)surface); if (res == AMF_INPUT_FULL) { // handle full queue //store surface for later submission ctx->delayed_surface = surface; - if (surface->pVtbl->GetMemoryType(surface) == AMF_MEMORY_DX11) { - av_frame_ref(ctx->delayed_frame, frame); - } } else { + int64_t pts = frame->pts; surface->pVtbl->Release(surface); AMF_RETURN_IF_FALSE(ctx, res == AMF_OK, AVERROR_UNKNOWN, "SubmitInput() failed with error %d\n", res); - if ((ret = timestamp_queue_enqueue(avctx, frame->pts)) < 0) { + av_frame_unref(frame); + if ((ret = timestamp_queue_enqueue(avctx, pts)) < 0) { return ret; } - } } - return 0; -} -int ff_amf_receive_packet(AVCodecContext *avctx, AVPacket *avpkt) -{ - int ret; - AMF_RESULT res; - AMF_RESULT res_query; - AmfContext *ctx = avctx->priv_data; - AMFData *data = NULL; - int block_and_wait; - if (!ctx->encoder) - return AVERROR(EINVAL); do { block_and_wait = 0; diff --git a/externals/ffmpeg/libavcodec/amfenc.h b/externals/ffmpeg/libavcodec/amfenc.h index b1361842b..80658c6b2 100755 --- a/externals/ffmpeg/libavcodec/amfenc.h +++ b/externals/ffmpeg/libavcodec/amfenc.h @@ -129,8 +129,6 @@ int ff_amf_encode_close(AVCodecContext *avctx); /** * Ecoding one frame - common function for all AMF encoders */ - -int ff_amf_send_frame(AVCodecContext *avctx, const AVFrame *frame); int ff_amf_receive_packet(AVCodecContext *avctx, AVPacket *avpkt); /** diff --git a/externals/ffmpeg/libavcodec/amfenc_h264.c b/externals/ffmpeg/libavcodec/amfenc_h264.c index 7f2817f11..7a8029f3b 100755 --- a/externals/ffmpeg/libavcodec/amfenc_h264.c +++ b/externals/ffmpeg/libavcodec/amfenc_h264.c @@ -383,7 +383,6 @@ AVCodec ff_h264_amf_encoder = { .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_H264, .init = amf_encode_init_h264, - .send_frame = ff_amf_send_frame, .receive_packet = ff_amf_receive_packet, .close = ff_amf_encode_close, .priv_data_size = sizeof(AmfContext), diff --git a/externals/ffmpeg/libavcodec/amfenc_hevc.c b/externals/ffmpeg/libavcodec/amfenc_hevc.c index 77e57d246..fa12a3a3f 100755 --- a/externals/ffmpeg/libavcodec/amfenc_hevc.c +++ b/externals/ffmpeg/libavcodec/amfenc_hevc.c @@ -69,7 +69,7 @@ static const AVOption options[] = { { "gop", "", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_HEVC_HEADER_INSERTION_MODE_GOP_ALIGNED }, 0, 0, VE, "hdrmode" }, { "idr", "", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_HEVC_HEADER_INSERTION_MODE_IDR_ALIGNED }, 0, 0, VE, "hdrmode" }, - { "gops_per_idr", "GOPs per IDR 0-no IDR will be inserted", OFFSET(gops_per_idr), AV_OPT_TYPE_INT, { .i64 = 60 }, 0, INT_MAX, VE }, + { "gops_per_idr", "GOPs per IDR 0-no IDR will be inserted", OFFSET(gops_per_idr), AV_OPT_TYPE_INT, { .i64 = 1 }, 0, INT_MAX, VE }, { "preanalysis", "Enable preanalysis", OFFSET(preanalysis), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE}, { "vbaq", "Enable VBAQ", OFFSET(enable_vbaq), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE}, { "enforce_hrd", "Enforce HRD", OFFSET(enforce_hrd), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE}, @@ -313,7 +313,6 @@ AVCodec ff_hevc_amf_encoder = { .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_HEVC, .init = amf_encode_init_hevc, - .send_frame = ff_amf_send_frame, .receive_packet = ff_amf_receive_packet, .close = ff_amf_encode_close, .priv_data_size = sizeof(AmfContext), diff --git a/externals/ffmpeg/libavcodec/apedec.c b/externals/ffmpeg/libavcodec/apedec.c index 4cbbfa40a..c76c0509d 100755 --- a/externals/ffmpeg/libavcodec/apedec.c +++ b/externals/ffmpeg/libavcodec/apedec.c @@ -262,9 +262,8 @@ static av_cold int ape_decode_init(AVCodecContext *avctx) for (i = 0; i < APE_FILTER_LEVELS; i++) { if (!ape_filter_orders[s->fset][i]) break; - FF_ALLOC_OR_GOTO(avctx, s->filterbuf[i], - (ape_filter_orders[s->fset][i] * 3 + HISTORY_SIZE) * 4, - filter_alloc_fail); + if (!(s->filterbuf[i] = av_malloc((ape_filter_orders[s->fset][i] * 3 + HISTORY_SIZE) * 4))) + return AVERROR(ENOMEM); } if (s->fileversion < 3860) { @@ -300,9 +299,6 @@ static av_cold int ape_decode_init(AVCodecContext *avctx) avctx->channel_layout = (avctx->channels==2) ? AV_CH_LAYOUT_STEREO : AV_CH_LAYOUT_MONO; return 0; -filter_alloc_fail: - ape_decode_close(avctx); - return AVERROR(ENOMEM); } /** @@ -1638,6 +1634,7 @@ AVCodec ff_ape_decoder = { .decode = ape_decode_frame, .capabilities = AV_CODEC_CAP_SUBFRAMES | AV_CODEC_CAP_DELAY | AV_CODEC_CAP_DR1, + .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, .flush = ape_flush, .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_U8P, AV_SAMPLE_FMT_S16P, diff --git a/externals/ffmpeg/libavcodec/audiotoolboxdec.c b/externals/ffmpeg/libavcodec/audiotoolboxdec.c index 5c0a9de8f..66055b79a 100755 --- a/externals/ffmpeg/libavcodec/audiotoolboxdec.c +++ b/externals/ffmpeg/libavcodec/audiotoolboxdec.c @@ -483,7 +483,7 @@ static int ffat_decode(AVCodecContext *avctx, void *data, if (avctx->codec_id == AV_CODEC_ID_AAC) { if (!at->extradata_size) { uint8_t *side_data; - int side_data_size = 0; + int side_data_size; side_data = av_packet_get_side_data(avpkt, AV_PKT_DATA_NEW_EXTRADATA, &side_data_size); diff --git a/externals/ffmpeg/libavcodec/av1_frame_merge_bsf.c b/externals/ffmpeg/libavcodec/av1_frame_merge_bsf.c index b5aa57e0f..baea5596d 100755 --- a/externals/ffmpeg/libavcodec/av1_frame_merge_bsf.c +++ b/externals/ffmpeg/libavcodec/av1_frame_merge_bsf.c @@ -34,8 +34,8 @@ static void av1_frame_merge_flush(AVBSFContext *bsf) { AV1FMergeContext *ctx = bsf->priv_data; - ff_cbs_fragment_reset(ctx->cbc, &ctx->frag[0]); - ff_cbs_fragment_reset(ctx->cbc, &ctx->frag[1]); + ff_cbs_fragment_reset(&ctx->frag[0]); + ff_cbs_fragment_reset(&ctx->frag[1]); av_packet_unref(ctx->in); av_packet_unref(ctx->pkt); } @@ -93,7 +93,7 @@ eof: ctx->idx = !ctx->idx; } else { for (i = 0; i < frag->nb_units; i++) { - err = ff_cbs_insert_unit_content(ctx->cbc, tu, -1, frag->units[i].type, + err = ff_cbs_insert_unit_content(tu, -1, frag->units[i].type, frag->units[i].content, frag->units[i].content_ref); if (err < 0) goto fail; @@ -108,7 +108,7 @@ eof: else av_packet_unref(in); - ff_cbs_fragment_reset(ctx->cbc, &ctx->frag[ctx->idx]); + ff_cbs_fragment_reset(&ctx->frag[ctx->idx]); fail: if (err < 0 && err != AVERROR(EAGAIN)) @@ -133,8 +133,8 @@ static void av1_frame_merge_close(AVBSFContext *bsf) { AV1FMergeContext *ctx = bsf->priv_data; - ff_cbs_fragment_free(ctx->cbc, &ctx->frag[0]); - ff_cbs_fragment_free(ctx->cbc, &ctx->frag[1]); + ff_cbs_fragment_free(&ctx->frag[0]); + ff_cbs_fragment_free(&ctx->frag[1]); av_packet_free(&ctx->in); av_packet_free(&ctx->pkt); ff_cbs_close(&ctx->cbc); diff --git a/externals/ffmpeg/libavcodec/av1_frame_split_bsf.c b/externals/ffmpeg/libavcodec/av1_frame_split_bsf.c index 87dfc8310..13bebe19f 100755 --- a/externals/ffmpeg/libavcodec/av1_frame_split_bsf.c +++ b/externals/ffmpeg/libavcodec/av1_frame_split_bsf.c @@ -172,7 +172,7 @@ static int av1_frame_split_filter(AVBSFContext *ctx, AVPacket *out) if (s->cur_frame == s->nb_frames) { av_packet_unref(s->buffer_pkt); - ff_cbs_fragment_reset(s->cbc, td); + ff_cbs_fragment_reset(td); } return 0; @@ -187,7 +187,7 @@ fail: av_packet_unref(out); av_packet_unref(s->buffer_pkt); } - ff_cbs_fragment_reset(s->cbc, td); + ff_cbs_fragment_reset(td); return ret; } @@ -224,7 +224,7 @@ static int av1_frame_split_init(AVBSFContext *ctx) if (ret < 0) av_log(ctx, AV_LOG_WARNING, "Failed to parse extradata.\n"); - ff_cbs_fragment_reset(s->cbc, td); + ff_cbs_fragment_reset(td); return 0; } @@ -234,7 +234,7 @@ static void av1_frame_split_flush(AVBSFContext *ctx) AV1FSplitContext *s = ctx->priv_data; av_packet_unref(s->buffer_pkt); - ff_cbs_fragment_reset(s->cbc, &s->temporal_unit); + ff_cbs_fragment_reset(&s->temporal_unit); } static void av1_frame_split_close(AVBSFContext *ctx) @@ -242,7 +242,7 @@ static void av1_frame_split_close(AVBSFContext *ctx) AV1FSplitContext *s = ctx->priv_data; av_packet_free(&s->buffer_pkt); - ff_cbs_fragment_free(s->cbc, &s->temporal_unit); + ff_cbs_fragment_free(&s->temporal_unit); ff_cbs_close(&s->cbc); } diff --git a/externals/ffmpeg/libavcodec/av1_metadata_bsf.c b/externals/ffmpeg/libavcodec/av1_metadata_bsf.c index ee1a63c1e..3e3cbfd17 100755 --- a/externals/ffmpeg/libavcodec/av1_metadata_bsf.c +++ b/externals/ffmpeg/libavcodec/av1_metadata_bsf.c @@ -151,7 +151,7 @@ static int av1_metadata_update_side_data(AVBSFContext *bsf, AVPacket *pkt) return AVERROR(ENOMEM); memcpy(side_data, frag->data, frag->data_size); - ff_cbs_fragment_reset(ctx->cbc, frag); + ff_cbs_fragment_reset(frag); return 0; } @@ -195,13 +195,13 @@ static int av1_metadata_filter(AVBSFContext *bsf, AVPacket *pkt) // If a Temporal Delimiter is present, it must be the first OBU. if (frag->units[0].type == AV1_OBU_TEMPORAL_DELIMITER) { if (ctx->td == REMOVE) - ff_cbs_delete_unit(ctx->cbc, frag, 0); + ff_cbs_delete_unit(frag, 0); } else if (ctx->td == INSERT) { td = (AV1RawOBU) { .header.obu_type = AV1_OBU_TEMPORAL_DELIMITER, }; - err = ff_cbs_insert_unit_content(ctx->cbc, frag, 0, AV1_OBU_TEMPORAL_DELIMITER, + err = ff_cbs_insert_unit_content(frag, 0, AV1_OBU_TEMPORAL_DELIMITER, &td, NULL); if (err < 0) { av_log(bsf, AV_LOG_ERROR, "Failed to insert Temporal Delimiter.\n"); @@ -212,7 +212,7 @@ static int av1_metadata_filter(AVBSFContext *bsf, AVPacket *pkt) if (ctx->delete_padding) { for (i = frag->nb_units - 1; i >= 0; i--) { if (frag->units[i].type == AV1_OBU_PADDING) - ff_cbs_delete_unit(ctx->cbc, frag, i); + ff_cbs_delete_unit(frag, i); } } @@ -224,7 +224,7 @@ static int av1_metadata_filter(AVBSFContext *bsf, AVPacket *pkt) err = 0; fail: - ff_cbs_fragment_reset(ctx->cbc, frag); + ff_cbs_fragment_reset(frag); if (err < 0) av_packet_unref(pkt); @@ -268,7 +268,7 @@ static int av1_metadata_init(AVBSFContext *bsf) err = 0; fail: - ff_cbs_fragment_reset(ctx->cbc, frag); + ff_cbs_fragment_reset(frag); return err; } @@ -276,7 +276,7 @@ static void av1_metadata_close(AVBSFContext *bsf) { AV1MetadataContext *ctx = bsf->priv_data; - ff_cbs_fragment_free(ctx->cbc, &ctx->access_unit); + ff_cbs_fragment_free(&ctx->access_unit); ff_cbs_close(&ctx->cbc); } diff --git a/externals/ffmpeg/libavcodec/av1_parser.c b/externals/ffmpeg/libavcodec/av1_parser.c index 036ab5e14..cd426a2b0 100755 --- a/externals/ffmpeg/libavcodec/av1_parser.c +++ b/externals/ffmpeg/libavcodec/av1_parser.c @@ -78,7 +78,7 @@ static int av1_parser_parse(AVCodecParserContext *ctx, av_log(avctx, AV_LOG_WARNING, "Failed to parse extradata.\n"); } - ff_cbs_fragment_reset(s->cbc, td); + ff_cbs_fragment_reset(td); } ret = ff_cbs_read(s->cbc, td, data, size); @@ -191,7 +191,7 @@ static int av1_parser_parse(AVCodecParserContext *ctx, avctx->time_base = av_inv_q(av_mul_q(avctx->framerate, (AVRational){avctx->ticks_per_frame, 1})); end: - ff_cbs_fragment_reset(s->cbc, td); + ff_cbs_fragment_reset(td); s->cbc->log_ctx = NULL; @@ -225,7 +225,7 @@ static void av1_parser_close(AVCodecParserContext *ctx) { AV1ParseContext *s = ctx->priv_data; - ff_cbs_fragment_free(s->cbc, &s->temporal_unit); + ff_cbs_fragment_free(&s->temporal_unit); ff_cbs_close(&s->cbc); } diff --git a/externals/ffmpeg/libavcodec/avrndec.c b/externals/ffmpeg/libavcodec/avrndec.c index 104ff2d90..a7bdab280 100755 --- a/externals/ffmpeg/libavcodec/avrndec.c +++ b/externals/ffmpeg/libavcodec/avrndec.c @@ -91,8 +91,7 @@ static av_cold int end(AVCodecContext *avctx) { AVRnContext *a = avctx->priv_data; - avcodec_close(a->mjpeg_avctx); - av_freep(&a->mjpeg_avctx); + avcodec_free_context(&a->mjpeg_avctx); return 0; } diff --git a/externals/ffmpeg/libavcodec/bitstream.c b/externals/ffmpeg/libavcodec/bitstream.c index 53a2db745..d379dbc0e 100755 --- a/externals/ffmpeg/libavcodec/bitstream.c +++ b/externals/ffmpeg/libavcodec/bitstream.c @@ -285,7 +285,6 @@ int ff_init_vlc_sparse(VLC *vlc_arg, int nb_bits, int nb_codes, vlc->bits = nb_bits; if (flags & INIT_VLC_USE_NEW_STATIC) { av_assert0(nb_codes + 1 <= FF_ARRAY_ELEMS(localbuf)); - buf = localbuf; localvlc = *vlc_arg; vlc = &localvlc; vlc->table_size = 0; @@ -293,11 +292,13 @@ int ff_init_vlc_sparse(VLC *vlc_arg, int nb_bits, int nb_codes, vlc->table = NULL; vlc->table_allocated = 0; vlc->table_size = 0; - + } + if (nb_codes + 1 > FF_ARRAY_ELEMS(localbuf)) { buf = av_malloc_array((nb_codes + 1), sizeof(VLCcode)); if (!buf) return AVERROR(ENOMEM); - } + } else + buf = localbuf; av_assert0(symbols_size <= 2 || !symbols); @@ -309,7 +310,7 @@ int ff_init_vlc_sparse(VLC *vlc_arg, int nb_bits, int nb_codes, continue; \ if (buf[j].bits > 3*nb_bits || buf[j].bits>32) { \ av_log(NULL, AV_LOG_ERROR, "Too long VLC (%d) in init_vlc\n", buf[j].bits);\ - if (!(flags & INIT_VLC_USE_NEW_STATIC)) \ + if (buf != localbuf) \ av_free(buf); \ return AVERROR(EINVAL); \ } \ @@ -317,7 +318,7 @@ int ff_init_vlc_sparse(VLC *vlc_arg, int nb_bits, int nb_codes, if (buf[j].code >= (1LL<= 0); *vlc_arg = *vlc; } else { - av_free(buf); + if (buf != localbuf) + av_free(buf); if (ret < 0) { av_freep(&vlc->table); return ret; diff --git a/externals/ffmpeg/libavcodec/bitstream_filters.c b/externals/ffmpeg/libavcodec/bitstream_filters.c index a7aa5dca6..b26d6a910 100755 --- a/externals/ffmpeg/libavcodec/bitstream_filters.c +++ b/externals/ffmpeg/libavcodec/bitstream_filters.c @@ -96,6 +96,7 @@ const AVBitStreamFilter *av_bsf_get_by_name(const char *name) return NULL; } +#if FF_API_CHILD_CLASS_NEXT const AVClass *ff_bsf_child_class_next(const AVClass *prev) { const AVBitStreamFilter *f = NULL; @@ -115,3 +116,16 @@ const AVClass *ff_bsf_child_class_next(const AVClass *prev) } return NULL; } +#endif + +const AVClass *ff_bsf_child_class_iterate(void **opaque) +{ + const AVBitStreamFilter *f; + + /* find next filter with priv options */ + while ((f = av_bsf_iterate(opaque))) { + if (f->priv_class) + return f->priv_class; + } + return NULL; +} diff --git a/externals/ffmpeg/libavcodec/bsf.c b/externals/ffmpeg/libavcodec/bsf.c index 5e1c794a7..d71bc3258 100755 --- a/externals/ffmpeg/libavcodec/bsf.c +++ b/externals/ffmpeg/libavcodec/bsf.c @@ -79,7 +79,10 @@ static const AVClass bsf_class = { .item_name = bsf_to_name, .version = LIBAVUTIL_VERSION_INT, .child_next = bsf_child_next, +#if FF_API_CHILD_CLASS_NEXT .child_class_next = ff_bsf_child_class_next, +#endif + .child_class_iterate = ff_bsf_child_class_iterate, .category = AV_CLASS_CATEGORY_BITSTREAM_FILTER, }; diff --git a/externals/ffmpeg/libavcodec/bsf_internal.h b/externals/ffmpeg/libavcodec/bsf_internal.h index fefd5b890..b78c134bd 100755 --- a/externals/ffmpeg/libavcodec/bsf_internal.h +++ b/externals/ffmpeg/libavcodec/bsf_internal.h @@ -42,6 +42,10 @@ int ff_bsf_get_packet(AVBSFContext *ctx, AVPacket **pkt); */ int ff_bsf_get_packet_ref(AVBSFContext *ctx, AVPacket *pkt); +#if FF_API_CHILD_CLASS_NEXT const AVClass *ff_bsf_child_class_next(const AVClass *prev); +#endif + +const AVClass *ff_bsf_child_class_iterate(void **opaque); #endif /* AVCODEC_BSF_INTERNAL_H */ diff --git a/externals/ffmpeg/libavcodec/cbs.c b/externals/ffmpeg/libavcodec/cbs.c index 42cb9711f..6464980c8 100755 --- a/externals/ffmpeg/libavcodec/cbs.c +++ b/externals/ffmpeg/libavcodec/cbs.c @@ -127,8 +127,7 @@ void ff_cbs_close(CodedBitstreamContext **ctx_ptr) av_freep(ctx_ptr); } -static void cbs_unit_uninit(CodedBitstreamContext *ctx, - CodedBitstreamUnit *unit) +static void cbs_unit_uninit(CodedBitstreamUnit *unit) { av_buffer_unref(&unit->content_ref); unit->content = NULL; @@ -139,13 +138,12 @@ static void cbs_unit_uninit(CodedBitstreamContext *ctx, unit->data_bit_padding = 0; } -void ff_cbs_fragment_reset(CodedBitstreamContext *ctx, - CodedBitstreamFragment *frag) +void ff_cbs_fragment_reset(CodedBitstreamFragment *frag) { int i; for (i = 0; i < frag->nb_units; i++) - cbs_unit_uninit(ctx, &frag->units[i]); + cbs_unit_uninit(&frag->units[i]); frag->nb_units = 0; av_buffer_unref(&frag->data_ref); @@ -154,10 +152,9 @@ void ff_cbs_fragment_reset(CodedBitstreamContext *ctx, frag->data_bit_padding = 0; } -void ff_cbs_fragment_free(CodedBitstreamContext *ctx, - CodedBitstreamFragment *frag) +void ff_cbs_fragment_free(CodedBitstreamFragment *frag) { - ff_cbs_fragment_reset(ctx, frag); + ff_cbs_fragment_reset(frag); av_freep(&frag->units); frag->nb_units_allocated = 0; @@ -200,8 +197,7 @@ static int cbs_read_fragment_content(CodedBitstreamContext *ctx, return 0; } -static int cbs_fill_fragment_data(CodedBitstreamContext *ctx, - CodedBitstreamFragment *frag, +static int cbs_fill_fragment_data(CodedBitstreamFragment *frag, const uint8_t *data, size_t size) { av_assert0(!frag->data && !frag->data_ref); @@ -227,7 +223,7 @@ int ff_cbs_read_extradata(CodedBitstreamContext *ctx, { int err; - err = cbs_fill_fragment_data(ctx, frag, par->extradata, + err = cbs_fill_fragment_data(frag, par->extradata, par->extradata_size); if (err < 0) return err; @@ -254,7 +250,7 @@ int ff_cbs_read_packet(CodedBitstreamContext *ctx, frag->data_size = pkt->size; } else { - err = cbs_fill_fragment_data(ctx, frag, pkt->data, pkt->size); + err = cbs_fill_fragment_data(frag, pkt->data, pkt->size); if (err < 0) return err; } @@ -272,7 +268,7 @@ int ff_cbs_read(CodedBitstreamContext *ctx, { int err; - err = cbs_fill_fragment_data(ctx, frag, data, size); + err = cbs_fill_fragment_data(frag, data, size); if (err < 0) return err; @@ -328,7 +324,7 @@ static int cbs_write_unit_data(CodedBitstreamContext *ctx, flush_put_bits(&pbc); - ret = ff_cbs_alloc_unit_data(ctx, unit, put_bits_count(&pbc) / 8); + ret = ff_cbs_alloc_unit_data(unit, put_bits_count(&pbc) / 8); if (ret < 0) return ret; @@ -641,8 +637,7 @@ int ff_cbs_write_signed(CodedBitstreamContext *ctx, PutBitContext *pbc, } -int ff_cbs_alloc_unit_content(CodedBitstreamContext *ctx, - CodedBitstreamUnit *unit, +int ff_cbs_alloc_unit_content(CodedBitstreamUnit *unit, size_t size, void (*free)(void *opaque, uint8_t *data)) { @@ -662,8 +657,7 @@ int ff_cbs_alloc_unit_content(CodedBitstreamContext *ctx, return 0; } -int ff_cbs_alloc_unit_data(CodedBitstreamContext *ctx, - CodedBitstreamUnit *unit, +int ff_cbs_alloc_unit_data(CodedBitstreamUnit *unit, size_t size) { av_assert0(!unit->data && !unit->data_ref); @@ -680,8 +674,7 @@ int ff_cbs_alloc_unit_data(CodedBitstreamContext *ctx, return 0; } -static int cbs_insert_unit(CodedBitstreamContext *ctx, - CodedBitstreamFragment *frag, +static int cbs_insert_unit(CodedBitstreamFragment *frag, int position) { CodedBitstreamUnit *units; @@ -719,8 +712,7 @@ static int cbs_insert_unit(CodedBitstreamContext *ctx, return 0; } -int ff_cbs_insert_unit_content(CodedBitstreamContext *ctx, - CodedBitstreamFragment *frag, +int ff_cbs_insert_unit_content(CodedBitstreamFragment *frag, int position, CodedBitstreamUnitType type, void *content, @@ -742,7 +734,7 @@ int ff_cbs_insert_unit_content(CodedBitstreamContext *ctx, content_ref = NULL; } - err = cbs_insert_unit(ctx, frag, position); + err = cbs_insert_unit(frag, position); if (err < 0) { av_buffer_unref(&content_ref); return err; @@ -756,8 +748,7 @@ int ff_cbs_insert_unit_content(CodedBitstreamContext *ctx, return 0; } -int ff_cbs_insert_unit_data(CodedBitstreamContext *ctx, - CodedBitstreamFragment *frag, +int ff_cbs_insert_unit_data(CodedBitstreamFragment *frag, int position, CodedBitstreamUnitType type, uint8_t *data, size_t data_size, @@ -781,7 +772,7 @@ int ff_cbs_insert_unit_data(CodedBitstreamContext *ctx, return AVERROR(ENOMEM); } - err = cbs_insert_unit(ctx, frag, position); + err = cbs_insert_unit(frag, position); if (err < 0) { av_buffer_unref(&data_ref); return err; @@ -796,14 +787,13 @@ int ff_cbs_insert_unit_data(CodedBitstreamContext *ctx, return 0; } -void ff_cbs_delete_unit(CodedBitstreamContext *ctx, - CodedBitstreamFragment *frag, +void ff_cbs_delete_unit(CodedBitstreamFragment *frag, int position) { av_assert0(0 <= position && position < frag->nb_units && "Unit to be deleted not in fragment."); - cbs_unit_uninit(ctx, &frag->units[position]); + cbs_unit_uninit(&frag->units[position]); --frag->nb_units; diff --git a/externals/ffmpeg/libavcodec/cbs.h b/externals/ffmpeg/libavcodec/cbs.h index 9ca1fbd60..e897e348a 100755 --- a/externals/ffmpeg/libavcodec/cbs.h +++ b/externals/ffmpeg/libavcodec/cbs.h @@ -330,23 +330,20 @@ int ff_cbs_write_packet(CodedBitstreamContext *ctx, * Free the units contained in a fragment as well as the fragment's * own data buffer, but not the units array itself. */ -void ff_cbs_fragment_reset(CodedBitstreamContext *ctx, - CodedBitstreamFragment *frag); +void ff_cbs_fragment_reset(CodedBitstreamFragment *frag); /** * Free the units array of a fragment in addition to what * ff_cbs_fragment_reset does. */ -void ff_cbs_fragment_free(CodedBitstreamContext *ctx, - CodedBitstreamFragment *frag); +void ff_cbs_fragment_free(CodedBitstreamFragment *frag); /** * Allocate a new internal content buffer of the given size in the unit. * * The content will be zeroed. */ -int ff_cbs_alloc_unit_content(CodedBitstreamContext *ctx, - CodedBitstreamUnit *unit, +int ff_cbs_alloc_unit_content(CodedBitstreamUnit *unit, size_t size, void (*free)(void *opaque, uint8_t *content)); @@ -355,8 +352,7 @@ int ff_cbs_alloc_unit_content(CodedBitstreamContext *ctx, * * The data buffer will have input padding. */ -int ff_cbs_alloc_unit_data(CodedBitstreamContext *ctx, - CodedBitstreamUnit *unit, +int ff_cbs_alloc_unit_data(CodedBitstreamUnit *unit, size_t size); /** @@ -365,8 +361,7 @@ int ff_cbs_alloc_unit_data(CodedBitstreamContext *ctx, * The content structure continues to be owned by the caller if * content_buf is not supplied. */ -int ff_cbs_insert_unit_content(CodedBitstreamContext *ctx, - CodedBitstreamFragment *frag, +int ff_cbs_insert_unit_content(CodedBitstreamFragment *frag, int position, CodedBitstreamUnitType type, void *content, @@ -379,8 +374,7 @@ int ff_cbs_insert_unit_content(CodedBitstreamContext *ctx, * av_malloc() and will on success become owned by the unit after this * call or freed on error. */ -int ff_cbs_insert_unit_data(CodedBitstreamContext *ctx, - CodedBitstreamFragment *frag, +int ff_cbs_insert_unit_data(CodedBitstreamFragment *frag, int position, CodedBitstreamUnitType type, uint8_t *data, size_t data_size, @@ -391,8 +385,7 @@ int ff_cbs_insert_unit_data(CodedBitstreamContext *ctx, * * Requires position to be >= 0 and < frag->nb_units. */ -void ff_cbs_delete_unit(CodedBitstreamContext *ctx, - CodedBitstreamFragment *frag, +void ff_cbs_delete_unit(CodedBitstreamFragment *frag, int position); diff --git a/externals/ffmpeg/libavcodec/cbs_av1.c b/externals/ffmpeg/libavcodec/cbs_av1.c index 0abcba9c6..b2a1d2ded 100755 --- a/externals/ffmpeg/libavcodec/cbs_av1.c +++ b/externals/ffmpeg/libavcodec/cbs_av1.c @@ -120,16 +120,11 @@ static int cbs_av1_write_uvlc(CodedBitstreamContext *ctx, PutBitContext *pbc, if (ctx->trace_enable) position = put_bits_count(pbc); - if (value == 0) { - zeroes = 0; - put_bits(pbc, 1, 1); - } else { - zeroes = av_log2(value + 1); - v = value - (1U << zeroes) + 1; - put_bits(pbc, zeroes, 0); - put_bits(pbc, 1, 1); - put_bits(pbc, zeroes, v); - } + zeroes = av_log2(value + 1); + v = value - (1U << zeroes) + 1; + put_bits(pbc, zeroes, 0); + put_bits(pbc, 1, 1); + put_bits(pbc, zeroes, v); if (ctx->trace_enable) { char bits[65]; @@ -799,7 +794,7 @@ static int cbs_av1_split_fragment(CodedBitstreamContext *ctx, goto fail; } - err = ff_cbs_insert_unit_data(ctx, frag, -1, header.obu_type, + err = ff_cbs_insert_unit_data(frag, -1, header.obu_type, data, obu_length, frag->data_ref); if (err < 0) goto fail; @@ -892,7 +887,7 @@ static int cbs_av1_read_unit(CodedBitstreamContext *ctx, GetBitContext gbc; int err, start_pos, end_pos; - err = ff_cbs_alloc_unit_content(ctx, unit, sizeof(*obu), + err = ff_cbs_alloc_unit_content(unit, sizeof(*obu), &cbs_av1_free_obu); if (err < 0) return err; diff --git a/externals/ffmpeg/libavcodec/cbs_h264.h b/externals/ffmpeg/libavcodec/cbs_h264.h index 9f7c2a0d3..f54ccd3b3 100755 --- a/externals/ffmpeg/libavcodec/cbs_h264.h +++ b/externals/ffmpeg/libavcodec/cbs_h264.h @@ -472,8 +472,7 @@ typedef struct CodedBitstreamH264Context { * On success, the payload will be owned by a unit in access_unit; * on failure, the content of the payload will be freed. */ -int ff_cbs_h264_add_sei_message(CodedBitstreamContext *ctx, - CodedBitstreamFragment *access_unit, +int ff_cbs_h264_add_sei_message(CodedBitstreamFragment *access_unit, H264RawSEIPayload *payload); /** @@ -485,8 +484,7 @@ int ff_cbs_h264_add_sei_message(CodedBitstreamContext *ctx, * Requires nal_unit to be a unit in access_unit and position to be >= 0 * and < the payload count of the SEI nal_unit. */ -void ff_cbs_h264_delete_sei_message(CodedBitstreamContext *ctx, - CodedBitstreamFragment *access_unit, +void ff_cbs_h264_delete_sei_message(CodedBitstreamFragment *access_unit, CodedBitstreamUnit *nal_unit, int position); diff --git a/externals/ffmpeg/libavcodec/cbs_h2645.c b/externals/ffmpeg/libavcodec/cbs_h2645.c index 64fe2c1b9..e5c8012d3 100755 --- a/externals/ffmpeg/libavcodec/cbs_h2645.c +++ b/externals/ffmpeg/libavcodec/cbs_h2645.c @@ -591,7 +591,7 @@ static int cbs_h2645_fragment_add_nals(CodedBitstreamContext *ctx, ref = (nal->data == nal->raw_data) ? frag->data_ref : packet->rbsp.rbsp_buffer_ref; - err = ff_cbs_insert_unit_data(ctx, frag, -1, nal->type, + err = ff_cbs_insert_unit_data(frag, -1, nal->type, (uint8_t*)nal->data, size, ref); if (err < 0) return err; @@ -807,7 +807,7 @@ static int cbs_h264_read_nal_unit(CodedBitstreamContext *ctx, { H264RawSPS *sps; - err = ff_cbs_alloc_unit_content(ctx, unit, sizeof(*sps), NULL); + err = ff_cbs_alloc_unit_content(unit, sizeof(*sps), NULL); if (err < 0) return err; sps = unit->content; @@ -824,7 +824,7 @@ static int cbs_h264_read_nal_unit(CodedBitstreamContext *ctx, case H264_NAL_SPS_EXT: { - err = ff_cbs_alloc_unit_content(ctx, unit, + err = ff_cbs_alloc_unit_content(unit, sizeof(H264RawSPSExtension), NULL); if (err < 0) @@ -840,7 +840,7 @@ static int cbs_h264_read_nal_unit(CodedBitstreamContext *ctx, { H264RawPPS *pps; - err = ff_cbs_alloc_unit_content(ctx, unit, sizeof(*pps), + err = ff_cbs_alloc_unit_content(unit, sizeof(*pps), &cbs_h264_free_pps); if (err < 0) return err; @@ -863,7 +863,7 @@ static int cbs_h264_read_nal_unit(CodedBitstreamContext *ctx, H264RawSlice *slice; int pos, len; - err = ff_cbs_alloc_unit_content(ctx, unit, sizeof(*slice), + err = ff_cbs_alloc_unit_content(unit, sizeof(*slice), &cbs_h264_free_slice); if (err < 0) return err; @@ -890,7 +890,7 @@ static int cbs_h264_read_nal_unit(CodedBitstreamContext *ctx, case H264_NAL_AUD: { - err = ff_cbs_alloc_unit_content(ctx, unit, + err = ff_cbs_alloc_unit_content(unit, sizeof(H264RawAUD), NULL); if (err < 0) return err; @@ -903,7 +903,7 @@ static int cbs_h264_read_nal_unit(CodedBitstreamContext *ctx, case H264_NAL_SEI: { - err = ff_cbs_alloc_unit_content(ctx, unit, sizeof(H264RawSEI), + err = ff_cbs_alloc_unit_content(unit, sizeof(H264RawSEI), &cbs_h264_free_sei); if (err < 0) return err; @@ -916,7 +916,7 @@ static int cbs_h264_read_nal_unit(CodedBitstreamContext *ctx, case H264_NAL_FILLER_DATA: { - err = ff_cbs_alloc_unit_content(ctx, unit, + err = ff_cbs_alloc_unit_content(unit, sizeof(H264RawFiller), NULL); if (err < 0) return err; @@ -930,7 +930,7 @@ static int cbs_h264_read_nal_unit(CodedBitstreamContext *ctx, case H264_NAL_END_SEQUENCE: case H264_NAL_END_STREAM: { - err = ff_cbs_alloc_unit_content(ctx, unit, + err = ff_cbs_alloc_unit_content(unit, sizeof(H264RawNALUnitHeader), NULL); if (err < 0) @@ -966,7 +966,7 @@ static int cbs_h265_read_nal_unit(CodedBitstreamContext *ctx, { H265RawVPS *vps; - err = ff_cbs_alloc_unit_content(ctx, unit, sizeof(*vps), + err = ff_cbs_alloc_unit_content(unit, sizeof(*vps), &cbs_h265_free_vps); if (err < 0) return err; @@ -985,7 +985,7 @@ static int cbs_h265_read_nal_unit(CodedBitstreamContext *ctx, { H265RawSPS *sps; - err = ff_cbs_alloc_unit_content(ctx, unit, sizeof(*sps), + err = ff_cbs_alloc_unit_content(unit, sizeof(*sps), &cbs_h265_free_sps); if (err < 0) return err; @@ -1005,7 +1005,7 @@ static int cbs_h265_read_nal_unit(CodedBitstreamContext *ctx, { H265RawPPS *pps; - err = ff_cbs_alloc_unit_content(ctx, unit, sizeof(*pps), + err = ff_cbs_alloc_unit_content(unit, sizeof(*pps), &cbs_h265_free_pps); if (err < 0) return err; @@ -1041,7 +1041,7 @@ static int cbs_h265_read_nal_unit(CodedBitstreamContext *ctx, H265RawSlice *slice; int pos, len; - err = ff_cbs_alloc_unit_content(ctx, unit, sizeof(*slice), + err = ff_cbs_alloc_unit_content(unit, sizeof(*slice), &cbs_h265_free_slice); if (err < 0) return err; @@ -1068,7 +1068,7 @@ static int cbs_h265_read_nal_unit(CodedBitstreamContext *ctx, case HEVC_NAL_AUD: { - err = ff_cbs_alloc_unit_content(ctx, unit, + err = ff_cbs_alloc_unit_content(unit, sizeof(H265RawAUD), NULL); if (err < 0) return err; @@ -1082,7 +1082,7 @@ static int cbs_h265_read_nal_unit(CodedBitstreamContext *ctx, case HEVC_NAL_SEI_PREFIX: case HEVC_NAL_SEI_SUFFIX: { - err = ff_cbs_alloc_unit_content(ctx, unit, sizeof(H265RawSEI), + err = ff_cbs_alloc_unit_content(unit, sizeof(H265RawSEI), &cbs_h265_free_sei); if (err < 0) @@ -1531,8 +1531,7 @@ const CodedBitstreamType ff_cbs_type_h265 = { .close = &cbs_h265_close, }; -int ff_cbs_h264_add_sei_message(CodedBitstreamContext *ctx, - CodedBitstreamFragment *au, +int ff_cbs_h264_add_sei_message(CodedBitstreamFragment *au, H264RawSEIPayload *payload) { H264RawSEI *sei = NULL; @@ -1577,7 +1576,7 @@ int ff_cbs_h264_add_sei_message(CodedBitstreamContext *ctx, break; } - err = ff_cbs_insert_unit_content(ctx, au, i, H264_NAL_SEI, + err = ff_cbs_insert_unit_content(au, i, H264_NAL_SEI, sei, sei_ref); av_buffer_unref(&sei_ref); if (err < 0) @@ -1593,8 +1592,7 @@ fail: return err; } -void ff_cbs_h264_delete_sei_message(CodedBitstreamContext *ctx, - CodedBitstreamFragment *au, +void ff_cbs_h264_delete_sei_message(CodedBitstreamFragment *au, CodedBitstreamUnit *nal, int position) { @@ -1612,7 +1610,7 @@ void ff_cbs_h264_delete_sei_message(CodedBitstreamContext *ctx, break; } - ff_cbs_delete_unit(ctx, au, i); + ff_cbs_delete_unit(au, i); } else { cbs_h264_free_sei_payload(&sei->payload[position]); diff --git a/externals/ffmpeg/libavcodec/cbs_jpeg.c b/externals/ffmpeg/libavcodec/cbs_jpeg.c index 471d77074..7d3e10fcc 100755 --- a/externals/ffmpeg/libavcodec/cbs_jpeg.c +++ b/externals/ffmpeg/libavcodec/cbs_jpeg.c @@ -226,7 +226,7 @@ static int cbs_jpeg_split_fragment(CodedBitstreamContext *ctx, data_ref = frag->data_ref; } - err = ff_cbs_insert_unit_data(ctx, frag, unit, marker, + err = ff_cbs_insert_unit_data(frag, unit, marker, data, data_size, data_ref); if (err < 0) return err; @@ -252,7 +252,7 @@ static int cbs_jpeg_read_unit(CodedBitstreamContext *ctx, if (unit->type >= JPEG_MARKER_SOF0 && unit->type <= JPEG_MARKER_SOF3) { - err = ff_cbs_alloc_unit_content(ctx, unit, + err = ff_cbs_alloc_unit_content(unit, sizeof(JPEGRawFrameHeader), NULL); if (err < 0) @@ -264,7 +264,7 @@ static int cbs_jpeg_read_unit(CodedBitstreamContext *ctx, } else if (unit->type >= JPEG_MARKER_APPN && unit->type <= JPEG_MARKER_APPN + 15) { - err = ff_cbs_alloc_unit_content(ctx, unit, + err = ff_cbs_alloc_unit_content(unit, sizeof(JPEGRawApplicationData), &cbs_jpeg_free_application_data); if (err < 0) @@ -278,7 +278,7 @@ static int cbs_jpeg_read_unit(CodedBitstreamContext *ctx, JPEGRawScan *scan; int pos; - err = ff_cbs_alloc_unit_content(ctx, unit, + err = ff_cbs_alloc_unit_content(unit, sizeof(JPEGRawScan), &cbs_jpeg_free_scan); if (err < 0) @@ -304,7 +304,7 @@ static int cbs_jpeg_read_unit(CodedBitstreamContext *ctx, #define SEGMENT(marker, type, func, free) \ case JPEG_MARKER_ ## marker: \ { \ - err = ff_cbs_alloc_unit_content(ctx, unit, \ + err = ff_cbs_alloc_unit_content(unit, \ sizeof(type), free); \ if (err < 0) \ return err; \ diff --git a/externals/ffmpeg/libavcodec/cbs_mpeg2.c b/externals/ffmpeg/libavcodec/cbs_mpeg2.c index 97f7889cb..8b6e5a985 100755 --- a/externals/ffmpeg/libavcodec/cbs_mpeg2.c +++ b/externals/ffmpeg/libavcodec/cbs_mpeg2.c @@ -207,7 +207,7 @@ static int cbs_mpeg2_split_fragment(CodedBitstreamContext *ctx, final = 1; } - err = ff_cbs_insert_unit_data(ctx, frag, i, unit_type, (uint8_t*)start, + err = ff_cbs_insert_unit_data(frag, i, unit_type, (uint8_t*)start, unit_size, frag->data_ref); if (err < 0) return err; @@ -235,7 +235,7 @@ static int cbs_mpeg2_read_unit(CodedBitstreamContext *ctx, MPEG2RawSlice *slice; int pos, len; - err = ff_cbs_alloc_unit_content(ctx, unit, sizeof(*slice), + err = ff_cbs_alloc_unit_content(unit, sizeof(*slice), &cbs_mpeg2_free_slice); if (err < 0) return err; @@ -265,7 +265,7 @@ static int cbs_mpeg2_read_unit(CodedBitstreamContext *ctx, case start_code: \ { \ type *header; \ - err = ff_cbs_alloc_unit_content(ctx, unit, \ + err = ff_cbs_alloc_unit_content(unit, \ sizeof(*header), free_func); \ if (err < 0) \ return err; \ diff --git a/externals/ffmpeg/libavcodec/cbs_vp9.c b/externals/ffmpeg/libavcodec/cbs_vp9.c index eef603bfb..6e0a7dcbe 100755 --- a/externals/ffmpeg/libavcodec/cbs_vp9.c +++ b/externals/ffmpeg/libavcodec/cbs_vp9.c @@ -451,7 +451,7 @@ static int cbs_vp9_split_fragment(CodedBitstreamContext *ctx, return AVERROR_INVALIDDATA; } - err = ff_cbs_insert_unit_data(ctx, frag, -1, 0, + err = ff_cbs_insert_unit_data(frag, -1, 0, frag->data + pos, sfi.frame_sizes[i], frag->data_ref); @@ -469,7 +469,7 @@ static int cbs_vp9_split_fragment(CodedBitstreamContext *ctx, return 0; } else { - err = ff_cbs_insert_unit_data(ctx, frag, -1, 0, + err = ff_cbs_insert_unit_data(frag, -1, 0, frag->data, frag->data_size, frag->data_ref); if (err < 0) @@ -497,7 +497,7 @@ static int cbs_vp9_read_unit(CodedBitstreamContext *ctx, if (err < 0) return err; - err = ff_cbs_alloc_unit_content(ctx, unit, sizeof(*frame), + err = ff_cbs_alloc_unit_content(unit, sizeof(*frame), &cbs_vp9_free_frame); if (err < 0) return err; diff --git a/externals/ffmpeg/libavcodec/ccaption_dec.c b/externals/ffmpeg/libavcodec/ccaption_dec.c index bf3563a0b..a208e19b9 100755 --- a/externals/ffmpeg/libavcodec/ccaption_dec.c +++ b/externals/ffmpeg/libavcodec/ccaption_dec.c @@ -32,10 +32,6 @@ static const AVRational ms_tb = {1, 1000}; -/* - * TODO list - * 1) handle font and color completely - */ enum cc_mode { CCMODE_POPON, CCMODE_PAINTON, @@ -173,6 +169,18 @@ static const char *charset_overrides[4][128] = }, }; +static const unsigned char bg_attribs[8] = // Color +{ + CCCOL_WHITE, + CCCOL_GREEN, + CCCOL_BLUE, + CCCOL_CYAN, + CCCOL_RED, + CCCOL_YELLOW, + CCCOL_MAGENTA, + CCCOL_BLACK, +}; + static const unsigned char pac2_attribs[32][3] = // Color, font, ident { { CCCOL_WHITE, CCFONT_REGULAR, 0 }, // 0x40 || 0x60 @@ -215,6 +223,7 @@ struct Screen { uint8_t characters[SCREEN_ROWS+1][SCREEN_COLUMNS+1]; uint8_t charsets[SCREEN_ROWS+1][SCREEN_COLUMNS+1]; uint8_t colors[SCREEN_ROWS+1][SCREEN_COLUMNS+1]; + uint8_t bgs[SCREEN_ROWS+1][SCREEN_COLUMNS+1]; uint8_t fonts[SCREEN_ROWS+1][SCREEN_COLUMNS+1]; /* * Bitmask of used rows; if a bit is not set, the @@ -228,39 +237,37 @@ struct Screen { typedef struct CCaptionSubContext { AVClass *class; int real_time; + int data_field; struct Screen screen[2]; int active_screen; uint8_t cursor_row; uint8_t cursor_column; uint8_t cursor_color; + uint8_t bg_color; uint8_t cursor_font; uint8_t cursor_charset; - AVBPrint buffer; + AVBPrint buffer[2]; + int buffer_index; int buffer_changed; int rollup; enum cc_mode mode; - int64_t start_time; - /* visible screen time */ - int64_t startv_time; - int64_t end_time; + int64_t buffer_time[2]; int screen_touched; int64_t last_real_time; - char prev_cmd[2]; - /* buffer to store pkt data */ - uint8_t *pktbuf; - int pktbuf_size; + uint8_t prev_cmd[2]; int readorder; } CCaptionSubContext; - static av_cold int init_decoder(AVCodecContext *avctx) { int ret; CCaptionSubContext *ctx = avctx->priv_data; - av_bprint_init(&ctx->buffer, 0, AV_BPRINT_SIZE_UNLIMITED); + av_bprint_init(&ctx->buffer[0], 0, AV_BPRINT_SIZE_UNLIMITED); + av_bprint_init(&ctx->buffer[1], 0, AV_BPRINT_SIZE_UNLIMITED); /* taking by default roll up to 2 */ ctx->mode = CCMODE_ROLLUP; + ctx->bg_color = CCCOL_BLACK; ctx->rollup = 2; ctx->cursor_row = 10; ret = ff_ass_subtitle_header(avctx, "Monospace", @@ -282,9 +289,8 @@ static av_cold int init_decoder(AVCodecContext *avctx) static av_cold int close_decoder(AVCodecContext *avctx) { CCaptionSubContext *ctx = avctx->priv_data; - av_bprint_finalize(&ctx->buffer, NULL); - av_freep(&ctx->pktbuf); - ctx->pktbuf_size = 0; + av_bprint_finalize(&ctx->buffer[0], NULL); + av_bprint_finalize(&ctx->buffer[1], NULL); return 0; } @@ -301,6 +307,7 @@ static void flush_decoder(AVCodecContext *avctx) ctx->cursor_column = 0; ctx->cursor_font = 0; ctx->cursor_color = 0; + ctx->bg_color = CCCOL_BLACK; ctx->cursor_charset = 0; ctx->active_screen = 0; ctx->last_real_time = 0; @@ -308,7 +315,8 @@ static void flush_decoder(AVCodecContext *avctx) ctx->buffer_changed = 0; if (!(avctx->flags2 & AV_CODEC_FLAG2_RO_FLUSH_NOOP)) ctx->readorder = 0; - av_bprint_clear(&ctx->buffer); + av_bprint_clear(&ctx->buffer[0]); + av_bprint_clear(&ctx->buffer[1]); } /** @@ -319,11 +327,15 @@ static void write_char(CCaptionSubContext *ctx, struct Screen *screen, char ch) uint8_t col = ctx->cursor_column; char *row = screen->characters[ctx->cursor_row]; char *font = screen->fonts[ctx->cursor_row]; + char *color = screen->colors[ctx->cursor_row]; + char *bg = screen->bgs[ctx->cursor_row]; char *charset = screen->charsets[ctx->cursor_row]; if (col < SCREEN_COLUMNS) { row[col] = ch; font[col] = ctx->cursor_font; + color[col] = ctx->cursor_color; + bg[col] = ctx->bg_color; charset[col] = ctx->cursor_charset; ctx->cursor_charset = CCSET_BASIC_AMERICAN; if (ch) ctx->cursor_column++; @@ -347,11 +359,13 @@ static void write_char(CCaptionSubContext *ctx, struct Screen *screen, char ch) * If the second byte doesn't pass parity, it returns INVALIDDATA * user can ignore the whole pair and pass the other pair. */ -static int validate_cc_data_pair(uint8_t *cc_data_pair) +static int validate_cc_data_pair(const uint8_t *cc_data_pair, uint8_t *hi) { uint8_t cc_valid = (*cc_data_pair & 4) >>2; uint8_t cc_type = *cc_data_pair & 3; + *hi = cc_data_pair[1]; + if (!cc_valid) return AVERROR_INVALIDDATA; @@ -361,7 +375,7 @@ static int validate_cc_data_pair(uint8_t *cc_data_pair) return AVERROR_INVALIDDATA; } if (!av_parity(cc_data_pair[1])) { - cc_data_pair[1]=0x7F; + *hi = 0x7F; } } @@ -374,10 +388,6 @@ static int validate_cc_data_pair(uint8_t *cc_data_pair) if (cc_type == 3 || cc_type == 2) return AVERROR_PATCHWELCOME; - /* remove parity bit */ - cc_data_pair[1] &= 0x7F; - cc_data_pair[2] &= 0x7F; - return 0; } @@ -423,6 +433,7 @@ static void roll_up(CCaptionSubContext *ctx) memcpy(screen->characters[i_row], screen->characters[i_row+1], SCREEN_COLUMNS); memcpy(screen->colors[i_row], screen->colors[i_row+1], SCREEN_COLUMNS); + memcpy(screen->bgs[i_row], screen->bgs[i_row+1], SCREEN_COLUMNS); memcpy(screen->fonts[i_row], screen->fonts[i_row+1], SCREEN_COLUMNS); memcpy(screen->charsets[i_row], screen->charsets[i_row+1], SCREEN_COLUMNS); if (CHECK_FLAG(screen->row_used, i_row + 1)) @@ -437,7 +448,11 @@ static int capture_screen(CCaptionSubContext *ctx) int i, j, tab = 0; struct Screen *screen = ctx->screen + ctx->active_screen; enum cc_font prev_font = CCFONT_REGULAR; - av_bprint_clear(&ctx->buffer); + enum cc_color_code prev_color = CCCOL_WHITE; + enum cc_color_code prev_bg_color = CCCOL_BLACK; + const int bidx = ctx->buffer_index; + + av_bprint_clear(&ctx->buffer[bidx]); for (i = 0; screen->row_used && i < SCREEN_ROWS; i++) { @@ -457,6 +472,8 @@ static int capture_screen(CCaptionSubContext *ctx) if (CHECK_FLAG(screen->row_used, i)) { const char *row = screen->characters[i]; const char *font = screen->fonts[i]; + const char *bg = screen->bgs[i]; + const char *color = screen->colors[i]; const char *charset = screen->charsets[i]; const char *override; int x, y, seen_char = 0; @@ -468,10 +485,10 @@ static int capture_screen(CCaptionSubContext *ctx) x = ASS_DEFAULT_PLAYRESX * (0.1 + 0.0250 * j); y = ASS_DEFAULT_PLAYRESY * (0.1 + 0.0533 * i); - av_bprintf(&ctx->buffer, "{\\an7}{\\pos(%d,%d)}", x, y); + av_bprintf(&ctx->buffer[bidx], "{\\an7}{\\pos(%d,%d)}", x, y); for (; j < SCREEN_COLUMNS; j++) { - const char *e_tag = "", *s_tag = ""; + const char *e_tag = "", *s_tag = "", *c_tag = "", *b_tag = ""; if (row[j] == 0) break; @@ -500,38 +517,99 @@ static int capture_screen(CCaptionSubContext *ctx) break; } } + if (prev_color != color[j]) { + switch (color[j]) { + case CCCOL_WHITE: + c_tag = "{\\c&HFFFFFF&}"; + break; + case CCCOL_GREEN: + c_tag = "{\\c&H00FF00&}"; + break; + case CCCOL_BLUE: + c_tag = "{\\c&HFF0000&}"; + break; + case CCCOL_CYAN: + c_tag = "{\\c&HFFFF00&}"; + break; + case CCCOL_RED: + c_tag = "{\\c&H0000FF&}"; + break; + case CCCOL_YELLOW: + c_tag = "{\\c&H00FFFF&}"; + break; + case CCCOL_MAGENTA: + c_tag = "{\\c&HFF00FF&}"; + break; + } + } + if (prev_bg_color != bg[j]) { + switch (bg[j]) { + case CCCOL_WHITE: + b_tag = "{\\3c&HFFFFFF&}"; + break; + case CCCOL_GREEN: + b_tag = "{\\3c&H00FF00&}"; + break; + case CCCOL_BLUE: + b_tag = "{\\3c&HFF0000&}"; + break; + case CCCOL_CYAN: + b_tag = "{\\3c&HFFFF00&}"; + break; + case CCCOL_RED: + b_tag = "{\\3c&H0000FF&}"; + break; + case CCCOL_YELLOW: + b_tag = "{\\3c&H00FFFF&}"; + break; + case CCCOL_MAGENTA: + b_tag = "{\\3c&HFF00FF&}"; + break; + case CCCOL_BLACK: + b_tag = "{\\3c&H000000&}"; + break; + } + } + prev_font = font[j]; + prev_color = color[j]; + prev_bg_color = bg[j]; override = charset_overrides[(int)charset[j]][(int)row[j]]; if (override) { - av_bprintf(&ctx->buffer, "%s%s%s", e_tag, s_tag, override); + av_bprintf(&ctx->buffer[bidx], "%s%s%s%s%s", e_tag, s_tag, c_tag, b_tag, override); seen_char = 1; } else if (row[j] == ' ' && !seen_char) { - av_bprintf(&ctx->buffer, "%s%s\\h", e_tag, s_tag); + av_bprintf(&ctx->buffer[bidx], "%s%s%s%s\\h", e_tag, s_tag, c_tag, b_tag); } else { - av_bprintf(&ctx->buffer, "%s%s%c", e_tag, s_tag, row[j]); + av_bprintf(&ctx->buffer[bidx], "%s%s%s%s%c", e_tag, s_tag, c_tag, b_tag, row[j]); seen_char = 1; } } - av_bprintf(&ctx->buffer, "\\N"); + av_bprintf(&ctx->buffer[bidx], "\\N"); } } - if (!av_bprint_is_complete(&ctx->buffer)) + if (!av_bprint_is_complete(&ctx->buffer[bidx])) return AVERROR(ENOMEM); - if (screen->row_used && ctx->buffer.len >= 2) { - ctx->buffer.len -= 2; - ctx->buffer.str[ctx->buffer.len] = 0; + if (screen->row_used && ctx->buffer[bidx].len >= 2) { + ctx->buffer[bidx].len -= 2; + ctx->buffer[bidx].str[ctx->buffer[bidx].len] = 0; } ctx->buffer_changed = 1; return 0; } -static int reap_screen(CCaptionSubContext *ctx, int64_t pts) +static void update_time(CCaptionSubContext *ctx, int64_t pts) { - ctx->start_time = ctx->startv_time; - ctx->startv_time = pts; - ctx->end_time = pts; - return capture_screen(ctx); + ctx->buffer_time[0] = ctx->buffer_time[1]; + ctx->buffer_time[1] = pts; +} + +static void handle_bgattr(CCaptionSubContext *ctx, uint8_t hi, uint8_t lo) +{ + const int i = (lo & 0xf) >> 1; + + ctx->bg_color = bg_attribs[i]; } static void handle_textattr(CCaptionSubContext *ctx, uint8_t hi, uint8_t lo) @@ -576,49 +654,55 @@ static void handle_pac(CCaptionSubContext *ctx, uint8_t hi, uint8_t lo) } } -/** - * @param pts it is required to set end time - */ -static void handle_edm(CCaptionSubContext *ctx, int64_t pts) +static int handle_edm(CCaptionSubContext *ctx) { struct Screen *screen = ctx->screen + ctx->active_screen; + int ret; // In buffered mode, keep writing to screen until it is wiped. // Before wiping the display, capture contents to emit subtitle. if (!ctx->real_time) - reap_screen(ctx, pts); + ret = capture_screen(ctx); screen->row_used = 0; + ctx->bg_color = CCCOL_BLACK; // In realtime mode, emit an empty caption so the last one doesn't // stay on the screen. if (ctx->real_time) - reap_screen(ctx, pts); + ret = capture_screen(ctx); + + return ret; } -static void handle_eoc(CCaptionSubContext *ctx, int64_t pts) +static int handle_eoc(CCaptionSubContext *ctx) { - // In buffered mode, we wait til the *next* EOC and - // reap what was already on the screen since the last EOC. - if (!ctx->real_time) - handle_edm(ctx,pts); + int ret; ctx->active_screen = !ctx->active_screen; + + // In buffered mode, we wait til the *next* EOC and + // capture what was already on the screen since the last EOC. + if (!ctx->real_time) + ret = handle_edm(ctx); + ctx->cursor_column = 0; // In realtime mode, we display the buffered contents (after // flipping the buffer to active above) as soon as EOC arrives. if (ctx->real_time) - reap_screen(ctx, pts); + ret = capture_screen(ctx); + + return ret; } -static void handle_delete_end_of_row(CCaptionSubContext *ctx, char hi, char lo) +static void handle_delete_end_of_row(CCaptionSubContext *ctx) { struct Screen *screen = get_writing_screen(ctx); write_char(ctx, screen, 0); } -static void handle_char(CCaptionSubContext *ctx, char hi, char lo, int64_t pts) +static void handle_char(CCaptionSubContext *ctx, char hi, char lo) { struct Screen *screen = get_writing_screen(ctx); @@ -658,11 +742,12 @@ static void handle_char(CCaptionSubContext *ctx, char hi, char lo, int64_t pts) ff_dlog(ctx, "(%c)\n", hi); } -static void process_cc608(CCaptionSubContext *ctx, int64_t pts, uint8_t hi, uint8_t lo) +static int process_cc608(CCaptionSubContext *ctx, uint8_t hi, uint8_t lo) { + int ret = 0; + if (hi == ctx->prev_cmd[0] && lo == ctx->prev_cmd[1]) { - /* ignore redundant command */ - return; + return 0; } /* set prev command */ @@ -675,6 +760,8 @@ static void process_cc608(CCaptionSubContext *ctx, int64_t pts, uint8_t hi, uint } else if ( ( hi == 0x11 && lo >= 0x20 && lo <= 0x2f ) || ( hi == 0x17 && lo >= 0x2e && lo <= 0x2f) ) { handle_textattr(ctx, hi, lo); + } else if ((hi == 0x10 && lo >= 0x20 && lo <= 0x2f)) { + handle_bgattr(ctx, hi, lo); } else if (hi == 0x14 || hi == 0x15 || hi == 0x1c) { switch (lo) { case 0x20: @@ -682,7 +769,7 @@ static void process_cc608(CCaptionSubContext *ctx, int64_t pts, uint8_t hi, uint ctx->mode = CCMODE_POPON; break; case 0x24: - handle_delete_end_of_row(ctx, hi, lo); + handle_delete_end_of_row(ctx); break; case 0x25: case 0x26: @@ -700,13 +787,13 @@ static void process_cc608(CCaptionSubContext *ctx, int64_t pts, uint8_t hi, uint break; case 0x2c: /* erase display memory */ - handle_edm(ctx, pts); + handle_edm(ctx); break; case 0x2d: /* carriage return */ ff_dlog(ctx, "carriage return\n"); if (!ctx->real_time) - reap_screen(ctx, pts); + ret = capture_screen(ctx); roll_up(ctx); ctx->cursor_column = 0; break; @@ -722,7 +809,7 @@ static void process_cc608(CCaptionSubContext *ctx, int64_t pts, uint8_t hi, uint case 0x2f: /* end of caption */ ff_dlog(ctx, "handle_eoc\n"); - handle_eoc(ctx, pts); + ret = handle_eoc(ctx); break; default: ff_dlog(ctx, "Unknown command 0x%hhx 0x%hhx\n", hi, lo); @@ -730,73 +817,93 @@ static void process_cc608(CCaptionSubContext *ctx, int64_t pts, uint8_t hi, uint } } else if (hi >= 0x11 && hi <= 0x13) { /* Special characters */ - handle_char(ctx, hi, lo, pts); + handle_char(ctx, hi, lo); } else if (hi >= 0x20) { /* Standard characters (always in pairs) */ - handle_char(ctx, hi, lo, pts); + handle_char(ctx, hi, lo); ctx->prev_cmd[0] = ctx->prev_cmd[1] = 0; } else if (hi == 0x17 && lo >= 0x21 && lo <= 0x23) { int i; /* Tab offsets (spacing) */ for (i = 0; i < lo - 0x20; i++) { - handle_char(ctx, ' ', 0, pts); + handle_char(ctx, ' ', 0); } } else { /* Ignoring all other non data code */ ff_dlog(ctx, "Unknown command 0x%hhx 0x%hhx\n", hi, lo); } + + return ret; } static int decode(AVCodecContext *avctx, void *data, int *got_sub, AVPacket *avpkt) { CCaptionSubContext *ctx = avctx->priv_data; AVSubtitle *sub = data; - const int64_t start_time = sub->pts; - uint8_t *bptr = NULL; + int64_t in_time = sub->pts; + int64_t start_time; + int64_t end_time; + int bidx = ctx->buffer_index; + const uint8_t *bptr = avpkt->data; int len = avpkt->size; int ret = 0; int i; - av_fast_padded_malloc(&ctx->pktbuf, &ctx->pktbuf_size, len); - if (!ctx->pktbuf) { - av_log(ctx, AV_LOG_WARNING, "Insufficient Memory of %d truncated to %d\n", len, ctx->pktbuf_size); - return AVERROR(ENOMEM); - } - memcpy(ctx->pktbuf, avpkt->data, len); - bptr = ctx->pktbuf; + for (i = 0; i < len; i += 3) { + uint8_t hi, cc_type = bptr[i] & 1; - for (i = 0; i < len; i += 3) { - uint8_t cc_type = *(bptr + i) & 3; - if (validate_cc_data_pair(bptr + i)) + if (ctx->data_field < 0) + ctx->data_field = cc_type; + + if (validate_cc_data_pair(bptr + i, &hi)) continue; - /* ignoring data field 1 */ - if(cc_type == 1) + + if (cc_type != ctx->data_field) continue; - else - process_cc608(ctx, start_time, *(bptr + i + 1) & 0x7f, *(bptr + i + 2) & 0x7f); + + ret = process_cc608(ctx, hi & 0x7f, bptr[i + 2] & 0x7f); + if (ret < 0) + return ret; if (!ctx->buffer_changed) continue; ctx->buffer_changed = 0; - if (*ctx->buffer.str || ctx->real_time) - { - ff_dlog(ctx, "cdp writing data (%s)\n",ctx->buffer.str); - ret = ff_ass_add_rect(sub, ctx->buffer.str, ctx->readorder++, 0, NULL, NULL); - if (ret < 0) - return ret; - sub->pts = ctx->start_time; + if (!ctx->real_time && ctx->mode == CCMODE_POPON) + ctx->buffer_index = bidx = !ctx->buffer_index; + + update_time(ctx, in_time); + + if (ctx->buffer[bidx].str[0] || ctx->real_time) { + ff_dlog(ctx, "cdp writing data (%s)\n", ctx->buffer[bidx].str); + start_time = ctx->buffer_time[0]; + sub->pts = start_time; + end_time = ctx->buffer_time[1]; if (!ctx->real_time) - sub->end_display_time = av_rescale_q(ctx->end_time - ctx->start_time, + sub->end_display_time = av_rescale_q(end_time - start_time, AV_TIME_BASE_Q, ms_tb); else sub->end_display_time = -1; - ctx->buffer_changed = 0; + ret = ff_ass_add_rect(sub, ctx->buffer[bidx].str, ctx->readorder++, 0, NULL, NULL); + if (ret < 0) + return ret; ctx->last_real_time = sub->pts; ctx->screen_touched = 0; } } + if (!bptr && !ctx->real_time && ctx->buffer[!ctx->buffer_index].str[0]) { + bidx = !ctx->buffer_index; + ret = ff_ass_add_rect(sub, ctx->buffer[bidx].str, ctx->readorder++, 0, NULL, NULL); + if (ret < 0) + return ret; + sub->pts = ctx->buffer_time[1]; + sub->end_display_time = av_rescale_q(ctx->buffer_time[1] - ctx->buffer_time[0], + AV_TIME_BASE_Q, ms_tb); + if (sub->end_display_time == 0) + sub->end_display_time = ctx->buffer[bidx].len * 20; + } + if (ctx->real_time && ctx->screen_touched && sub->pts > ctx->last_real_time + av_rescale_q(200, ms_tb, AV_TIME_BASE_Q)) { ctx->last_real_time = sub->pts; @@ -805,7 +912,7 @@ static int decode(AVCodecContext *avctx, void *data, int *got_sub, AVPacket *avp capture_screen(ctx); ctx->buffer_changed = 0; - ret = ff_ass_add_rect(sub, ctx->buffer.str, ctx->readorder++, 0, NULL, NULL); + ret = ff_ass_add_rect(sub, ctx->buffer[bidx].str, ctx->readorder++, 0, NULL, NULL); if (ret < 0) return ret; sub->end_display_time = -1; @@ -819,6 +926,10 @@ static int decode(AVCodecContext *avctx, void *data, int *got_sub, AVPacket *avp #define SD AV_OPT_FLAG_SUBTITLE_PARAM | AV_OPT_FLAG_DECODING_PARAM static const AVOption options[] = { { "real_time", "emit subtitle events as they are decoded for real-time display", OFFSET(real_time), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, SD }, + { "data_field", "select data field", OFFSET(data_field), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 1, SD, "data_field" }, + { "auto", "pick first one that appears", 0, AV_OPT_TYPE_CONST, { .i64 =-1 }, 0, 0, SD, "data_field" }, + { "first", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 0 }, 0, 0, SD, "data_field" }, + { "second", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 1 }, 0, 0, SD, "data_field" }, {NULL} }; @@ -840,4 +951,5 @@ AVCodec ff_ccaption_decoder = { .flush = flush_decoder, .decode = decode, .priv_class = &ccaption_dec_class, + .capabilities = AV_CODEC_CAP_DELAY, }; diff --git a/externals/ffmpeg/libavcodec/cfhd.c b/externals/ffmpeg/libavcodec/cfhd.c index 7956367b4..299d98780 100755 --- a/externals/ffmpeg/libavcodec/cfhd.c +++ b/externals/ffmpeg/libavcodec/cfhd.c @@ -41,15 +41,25 @@ #define ALPHA_COMPAND_GAIN 9400 enum CFHDParam { + SampleType = 1, + SampleIndexTable = 2, + BitstreamMarker = 4, + TransformType = 10, ChannelCount = 12, SubbandCount = 14, ImageWidth = 20, ImageHeight = 21, + LowpassWidth = 27, + LowpassHeight = 28, LowpassPrecision = 35, + HighpassWidth = 41, + HighpassHeight = 42, SubbandNumber = 48, Quantization = 53, + BandHeader = 55, ChannelNumber = 62, SampleFlags = 68, + EncodedFormat = 84, BitsPerComponent = 101, ChannelWidth = 104, ChannelHeight = 105, @@ -479,7 +489,7 @@ static int cfhd_decode(AVCodecContext *avctx, void *data, int *got_frame, s->prescale_shift[1] = (data >> 3) & 0x7; s->prescale_shift[2] = (data >> 6) & 0x7; av_log(avctx, AV_LOG_DEBUG, "Prescale shift (VC-5): %x\n", data); - } else if (tag == 27) { + } else if (tag == LowpassWidth) { av_log(avctx, AV_LOG_DEBUG, "Lowpass width %"PRIu16"\n", data); if (data < 3 || data > s->plane[s->channel_num].band[0][0].a_width) { av_log(avctx, AV_LOG_ERROR, "Invalid lowpass width\n"); @@ -488,7 +498,7 @@ static int cfhd_decode(AVCodecContext *avctx, void *data, int *got_frame, } s->plane[s->channel_num].band[0][0].width = data; s->plane[s->channel_num].band[0][0].stride = data; - } else if (tag == 28) { + } else if (tag == LowpassHeight) { av_log(avctx, AV_LOG_DEBUG, "Lowpass height %"PRIu16"\n", data); if (data < 3 || data > s->plane[s->channel_num].band[0][0].a_height) { av_log(avctx, AV_LOG_ERROR, "Invalid lowpass height\n"); @@ -496,9 +506,9 @@ static int cfhd_decode(AVCodecContext *avctx, void *data, int *got_frame, break; } s->plane[s->channel_num].band[0][0].height = data; - } else if (tag == 1) + } else if (tag == SampleType) av_log(avctx, AV_LOG_DEBUG, "Sample type? %"PRIu16"\n", data); - else if (tag == 10) { + else if (tag == TransformType) { if (data != 0) { avpriv_report_missing_feature(avctx, "Transform type of %"PRIu16, data); ret = AVERROR_PATCHWELCOME; @@ -515,7 +525,7 @@ static int cfhd_decode(AVCodecContext *avctx, void *data, int *got_frame, avpriv_report_missing_feature(avctx, "Skip frame"); ret = AVERROR_PATCHWELCOME; break; - } else if (tag == 2) { + } else if (tag == SampleIndexTable) { av_log(avctx, AV_LOG_DEBUG, "tag=2 header - skipping %i tag/value pairs\n", data); if (data > bytestream2_get_bytes_left(&gb) / 4) { av_log(avctx, AV_LOG_ERROR, "too many tag/value pairs (%d)\n", data); @@ -527,7 +537,7 @@ static int cfhd_decode(AVCodecContext *avctx, void *data, int *got_frame, uint16_t val2 = bytestream2_get_be16(&gb); av_log(avctx, AV_LOG_DEBUG, "Tag/Value = %x %x\n", tag2, val2); } - } else if (tag == 41) { + } else if (tag == HighpassWidth) { av_log(avctx, AV_LOG_DEBUG, "Highpass width %i channel %i level %i subband %i\n", data, s->channel_num, s->level, s->subband_num); if (data < 3) { av_log(avctx, AV_LOG_ERROR, "Invalid highpass width\n"); @@ -536,7 +546,7 @@ static int cfhd_decode(AVCodecContext *avctx, void *data, int *got_frame, } s->plane[s->channel_num].band[s->level][s->subband_num].width = data; s->plane[s->channel_num].band[s->level][s->subband_num].stride = FFALIGN(data, 8); - } else if (tag == 42) { + } else if (tag == HighpassHeight) { av_log(avctx, AV_LOG_DEBUG, "Highpass height %i\n", data); if (data < 3) { av_log(avctx, AV_LOG_ERROR, "Invalid highpass height\n"); @@ -576,7 +586,7 @@ static int cfhd_decode(AVCodecContext *avctx, void *data, int *got_frame, break; } s->bpc = data; - } else if (tag == 84) { + } else if (tag == EncodedFormat) { av_log(avctx, AV_LOG_DEBUG, "Sample format? %i\n", data); if (data == 1) { s->coded_format = AV_PIX_FMT_YUV422P10; @@ -612,7 +622,7 @@ static int cfhd_decode(AVCodecContext *avctx, void *data, int *got_frame, av_log(avctx, AV_LOG_DEBUG, "Unknown tag %i data %x\n", tag, data); /* Some kind of end of header tag */ - if (tag == 4 && data == 0x1a4a && s->coded_width && s->coded_height && + if (tag == BitstreamMarker && data == 0x1a4a && s->coded_width && s->coded_height && s->coded_format != AV_PIX_FMT_NONE) { if (s->a_width != s->coded_width || s->a_height != s->coded_height || s->a_format != s->coded_format) { @@ -645,7 +655,7 @@ static int cfhd_decode(AVCodecContext *avctx, void *data, int *got_frame, coeff_data = s->plane[s->channel_num].subband[s->subband_num_actual]; /* Lowpass coefficients */ - if (tag == 4 && data == 0xf0f && s->a_width && s->a_height) { + if (tag == BitstreamMarker && data == 0xf0f && s->a_width && s->a_height) { int lowpass_height = s->plane[s->channel_num].band[0][0].height; int lowpass_width = s->plane[s->channel_num].band[0][0].width; int lowpass_a_height = s->plane[s->channel_num].band[0][0].a_height; @@ -685,7 +695,7 @@ static int cfhd_decode(AVCodecContext *avctx, void *data, int *got_frame, av_log(avctx, AV_LOG_DEBUG, "Lowpass coefficients %d\n", lowpass_width * lowpass_height); } - if (tag == 55 && s->subband_num_actual != 255 && s->a_width && s->a_height) { + if (tag == BandHeader && s->subband_num_actual != 255 && s->a_width && s->a_height) { int highpass_height = s->plane[s->channel_num].band[s->level][s->subband_num].height; int highpass_width = s->plane[s->channel_num].band[s->level][s->subband_num].width; int highpass_a_width = s->plane[s->channel_num].band[s->level][s->subband_num].a_width; diff --git a/externals/ffmpeg/libavcodec/codec.h b/externals/ffmpeg/libavcodec/codec.h index 1fda619ee..713774a63 100755 --- a/externals/ffmpeg/libavcodec/codec.h +++ b/externals/ffmpeg/libavcodec/codec.h @@ -282,14 +282,10 @@ typedef struct AVCodec { int (*decode)(struct AVCodecContext *, void *outdata, int *outdata_size, struct AVPacket *avpkt); int (*close)(struct AVCodecContext *); /** - * Encode API with decoupled packet/frame dataflow. The API is the - * same as the avcodec_ prefixed APIs (avcodec_send_frame() etc.), except - * that: - * - never called if the codec is closed or the wrong type, - * - if AV_CODEC_CAP_DELAY is not set, drain frames are never sent, - * - only one drain frame is ever passed down, + * Encode API with decoupled frame/packet dataflow. This function is called + * to get one output packet. It should call ff_encode_get_frame() to obtain + * input data. */ - int (*send_frame)(struct AVCodecContext *avctx, const struct AVFrame *frame); int (*receive_packet)(struct AVCodecContext *avctx, struct AVPacket *avpkt); /** diff --git a/externals/ffmpeg/libavcodec/codec_desc.c b/externals/ffmpeg/libavcodec/codec_desc.c index 9f8847544..ced00bd34 100755 --- a/externals/ffmpeg/libavcodec/codec_desc.c +++ b/externals/ffmpeg/libavcodec/codec_desc.c @@ -1405,6 +1405,13 @@ static const AVCodecDescriptor codec_descriptors[] = { .long_name = NULL_IF_CONFIG_SMALL("AVS2-P2/IEEE1857.4"), .props = AV_CODEC_PROP_LOSSY, }, + { + .id = AV_CODEC_ID_PGX, + .type = AVMEDIA_TYPE_VIDEO, + .name = "pgx", + .long_name = NULL_IF_CONFIG_SMALL("PGX (JPEG2000 Test Format)"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, + }, { .id = AV_CODEC_ID_Y41P, .type = AVMEDIA_TYPE_VIDEO, @@ -2897,7 +2904,7 @@ static const AVCodecDescriptor codec_descriptors[] = { .type = AVMEDIA_TYPE_AUDIO, .name = "tak", .long_name = NULL_IF_CONFIG_SMALL("TAK (Tom's lossless Audio Kompressor)"), - .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, + .props = AV_CODEC_PROP_LOSSLESS, }, { .id = AV_CODEC_ID_METASOUND, diff --git a/externals/ffmpeg/libavcodec/codec_id.h b/externals/ffmpeg/libavcodec/codec_id.h index d885962c9..896ecb0ce 100755 --- a/externals/ffmpeg/libavcodec/codec_id.h +++ b/externals/ffmpeg/libavcodec/codec_id.h @@ -241,6 +241,7 @@ enum AVCodecID { AV_CODEC_ID_SCREENPRESSO, AV_CODEC_ID_RSCC, AV_CODEC_ID_AVS2, + AV_CODEC_ID_PGX, AV_CODEC_ID_Y41P = 0x8000, AV_CODEC_ID_AVRP, diff --git a/externals/ffmpeg/libavcodec/decode.c b/externals/ffmpeg/libavcodec/decode.c index a4e50c0d0..de9c079f9 100755 --- a/externals/ffmpeg/libavcodec/decode.c +++ b/externals/ffmpeg/libavcodec/decode.c @@ -66,7 +66,7 @@ typedef struct FramePool { static int apply_param_change(AVCodecContext *avctx, const AVPacket *avpkt) { - int size = 0, ret; + int size, ret; const uint8_t *data; uint32_t flags; int64_t val; diff --git a/externals/ffmpeg/libavcodec/dnxhdenc.c b/externals/ffmpeg/libavcodec/dnxhdenc.c index 5d5f1ffc0..91eeb47e3 100755 --- a/externals/ffmpeg/libavcodec/dnxhdenc.c +++ b/externals/ffmpeg/libavcodec/dnxhdenc.c @@ -207,15 +207,11 @@ static av_cold int dnxhd_init_vlc(DNXHDEncContext *ctx) int i, j, level, run; int max_level = 1 << (ctx->bit_depth + 2); - FF_ALLOCZ_ARRAY_OR_GOTO(ctx->m.avctx, ctx->orig_vlc_codes, - max_level, 4 * sizeof(*ctx->orig_vlc_codes), fail); - FF_ALLOCZ_ARRAY_OR_GOTO(ctx->m.avctx, ctx->orig_vlc_bits, - max_level, 4 * sizeof(*ctx->orig_vlc_bits), fail); - FF_ALLOCZ_OR_GOTO(ctx->m.avctx, ctx->run_codes, - 63 * 2, fail); - FF_ALLOCZ_OR_GOTO(ctx->m.avctx, ctx->run_bits, - 63, fail); - + if (!FF_ALLOCZ_TYPED_ARRAY(ctx->orig_vlc_codes, max_level * 4) || + !FF_ALLOCZ_TYPED_ARRAY(ctx->orig_vlc_bits, max_level * 4) || + !(ctx->run_codes = av_mallocz(63 * 2)) || + !(ctx->run_bits = av_mallocz(63))) + return AVERROR(ENOMEM); ctx->vlc_codes = ctx->orig_vlc_codes + max_level * 2; ctx->vlc_bits = ctx->orig_vlc_bits + max_level * 2; for (level = -max_level; level < max_level; level++) { @@ -259,8 +255,6 @@ static av_cold int dnxhd_init_vlc(DNXHDEncContext *ctx) ctx->run_bits[run] = ctx->cid_table->run_bits[i]; } return 0; -fail: - return AVERROR(ENOMEM); } static av_cold int dnxhd_init_qmat(DNXHDEncContext *ctx, int lbias, int cbias) @@ -271,16 +265,11 @@ static av_cold int dnxhd_init_qmat(DNXHDEncContext *ctx, int lbias, int cbias) const uint8_t *luma_weight_table = ctx->cid_table->luma_weight; const uint8_t *chroma_weight_table = ctx->cid_table->chroma_weight; - FF_ALLOCZ_ARRAY_OR_GOTO(ctx->m.avctx, ctx->qmatrix_l, - (ctx->m.avctx->qmax + 1), 64 * sizeof(int), fail); - FF_ALLOCZ_ARRAY_OR_GOTO(ctx->m.avctx, ctx->qmatrix_c, - (ctx->m.avctx->qmax + 1), 64 * sizeof(int), fail); - FF_ALLOCZ_ARRAY_OR_GOTO(ctx->m.avctx, ctx->qmatrix_l16, - (ctx->m.avctx->qmax + 1), 64 * 2 * sizeof(uint16_t), - fail); - FF_ALLOCZ_ARRAY_OR_GOTO(ctx->m.avctx, ctx->qmatrix_c16, - (ctx->m.avctx->qmax + 1), 64 * 2 * sizeof(uint16_t), - fail); + if (!FF_ALLOCZ_TYPED_ARRAY(ctx->qmatrix_l, ctx->m.avctx->qmax + 1) || + !FF_ALLOCZ_TYPED_ARRAY(ctx->qmatrix_c, ctx->m.avctx->qmax + 1) || + !FF_ALLOCZ_TYPED_ARRAY(ctx->qmatrix_l16, ctx->m.avctx->qmax + 1) || + !FF_ALLOCZ_TYPED_ARRAY(ctx->qmatrix_c16, ctx->m.avctx->qmax + 1)) + return AVERROR(ENOMEM); if (ctx->bit_depth == 8) { for (i = 1; i < 64; i++) { @@ -339,27 +328,23 @@ static av_cold int dnxhd_init_qmat(DNXHDEncContext *ctx, int lbias, int cbias) ctx->m.q_intra_matrix = ctx->qmatrix_l; return 0; -fail: - return AVERROR(ENOMEM); } static av_cold int dnxhd_init_rc(DNXHDEncContext *ctx) { - FF_ALLOCZ_ARRAY_OR_GOTO(ctx->m.avctx, ctx->mb_rc, (ctx->m.avctx->qmax + 1), - ctx->m.mb_num * sizeof(RCEntry), fail); + if (!FF_ALLOCZ_TYPED_ARRAY(ctx->mb_rc, (ctx->m.avctx->qmax + 1) * ctx->m.mb_num)) + return AVERROR(ENOMEM); + if (ctx->m.avctx->mb_decision != FF_MB_DECISION_RD) { - FF_ALLOCZ_ARRAY_OR_GOTO(ctx->m.avctx, ctx->mb_cmp, - ctx->m.mb_num, sizeof(RCCMPEntry), fail); - FF_ALLOCZ_ARRAY_OR_GOTO(ctx->m.avctx, ctx->mb_cmp_tmp, - ctx->m.mb_num, sizeof(RCCMPEntry), fail); + if (!FF_ALLOCZ_TYPED_ARRAY(ctx->mb_cmp, ctx->m.mb_num) || + !FF_ALLOCZ_TYPED_ARRAY(ctx->mb_cmp_tmp, ctx->m.mb_num)) + return AVERROR(ENOMEM); } ctx->frame_bits = (ctx->coding_unit_size - ctx->data_offset - 4 - ctx->min_padding) * 8; ctx->qscale = 1; ctx->lambda = 2 << LAMBDA_FRAC_BITS; // qscale 2 return 0; -fail: - return AVERROR(ENOMEM); } static av_cold int dnxhd_encode_init(AVCodecContext *avctx) @@ -510,15 +495,11 @@ static av_cold int dnxhd_encode_init(AVCodecContext *avctx) if ((ret = dnxhd_init_rc(ctx)) < 0) return ret; - FF_ALLOCZ_OR_GOTO(ctx->m.avctx, ctx->slice_size, - ctx->m.mb_height * sizeof(uint32_t), fail); - FF_ALLOCZ_OR_GOTO(ctx->m.avctx, ctx->slice_offs, - ctx->m.mb_height * sizeof(uint32_t), fail); - FF_ALLOCZ_OR_GOTO(ctx->m.avctx, ctx->mb_bits, - ctx->m.mb_num * sizeof(uint16_t), fail); - FF_ALLOCZ_OR_GOTO(ctx->m.avctx, ctx->mb_qscale, - ctx->m.mb_num * sizeof(uint8_t), fail); - + if (!FF_ALLOCZ_TYPED_ARRAY(ctx->slice_size, ctx->m.mb_height) || + !FF_ALLOCZ_TYPED_ARRAY(ctx->slice_offs, ctx->m.mb_height) || + !FF_ALLOCZ_TYPED_ARRAY(ctx->mb_bits, ctx->m.mb_num) || + !FF_ALLOCZ_TYPED_ARRAY(ctx->mb_qscale, ctx->m.mb_num)) + return AVERROR(ENOMEM); #if FF_API_CODED_FRAME FF_DISABLE_DEPRECATION_WARNINGS avctx->coded_frame->key_frame = 1; @@ -543,14 +524,12 @@ FF_ENABLE_DEPRECATION_WARNINGS for (i = 1; i < avctx->thread_count; i++) { ctx->thread[i] = av_malloc(sizeof(DNXHDEncContext)); if (!ctx->thread[i]) - goto fail; + return AVERROR(ENOMEM); memcpy(ctx->thread[i], ctx, sizeof(DNXHDEncContext)); } } return 0; -fail: // for FF_ALLOCZ_OR_GOTO - return AVERROR(ENOMEM); } static int dnxhd_write_header(AVCodecContext *avctx, uint8_t *buf) diff --git a/externals/ffmpeg/libavcodec/dvbsub_parser.c b/externals/ffmpeg/libavcodec/dvbsub_parser.c index 8ced3c4c3..b7a3d6154 100755 --- a/externals/ffmpeg/libavcodec/dvbsub_parser.c +++ b/externals/ffmpeg/libavcodec/dvbsub_parser.c @@ -35,20 +35,12 @@ /* parser definition */ typedef struct DVBSubParseContext { - uint8_t *packet_buf; int packet_start; int packet_index; int in_packet; + uint8_t packet_buf[PARSE_BUF_SIZE]; } DVBSubParseContext; -static av_cold int dvbsub_parse_init(AVCodecParserContext *s) -{ - DVBSubParseContext *pc = s->priv_data; - pc->packet_buf = av_malloc(PARSE_BUF_SIZE); - - return 0; -} - static int dvbsub_parse(AVCodecParserContext *s, AVCodecContext *avctx, const uint8_t **poutbuf, int *poutbuf_size, @@ -173,16 +165,8 @@ static int dvbsub_parse(AVCodecParserContext *s, return buf_size; } -static av_cold void dvbsub_parse_close(AVCodecParserContext *s) -{ - DVBSubParseContext *pc = s->priv_data; - av_freep(&pc->packet_buf); -} - AVCodecParser ff_dvbsub_parser = { .codec_ids = { AV_CODEC_ID_DVB_SUBTITLE }, .priv_data_size = sizeof(DVBSubParseContext), - .parser_init = dvbsub_parse_init, .parser_parse = dvbsub_parse, - .parser_close = dvbsub_parse_close, }; diff --git a/externals/ffmpeg/libavcodec/dvbsubdec.c b/externals/ffmpeg/libavcodec/dvbsubdec.c index f63a1f3bf..c179f6461 100755 --- a/externals/ffmpeg/libavcodec/dvbsubdec.c +++ b/externals/ffmpeg/libavcodec/dvbsubdec.c @@ -710,8 +710,8 @@ static void compute_default_clut(DVBSubContext *ctx, uint8_t *clut, AVSubtitleRe } count = FFMAX(i - 1, 1); - for (i--; i>=0; i--) { - int v = i*255/count; + for (i--; i >= 0; i--) { + int v = i * 255 / count; AV_WN32(clut + 4*list_inv[i], RGBA(v/2,v,v/2,v)); } } @@ -737,7 +737,7 @@ static int save_subtitle_set(AVCodecContext *avctx, AVSubtitle *sub, int *got_ou } /* Not touching AVSubtitles again*/ - if(sub->num_rects) { + if (sub->num_rects) { avpriv_request_sample(ctx, "Different Version of Segment asked Twice"); return AVERROR_PATCHWELCOME; } @@ -747,7 +747,7 @@ static int save_subtitle_set(AVCodecContext *avctx, AVSubtitle *sub, int *got_ou sub->num_rects++; } - if(ctx->compute_edt == 0) { + if (ctx->compute_edt == 0) { sub->end_display_time = ctx->time_out * 1000; *got_output = 1; } else if (ctx->prev_start != AV_NOPTS_VALUE) { @@ -813,7 +813,7 @@ static int save_subtitle_set(AVCodecContext *avctx, AVSubtitle *sub, int *got_ou ret = AVERROR(ENOMEM); goto fail; } - memcpy(rect->data[1], clut_table, (1 << region->depth) * sizeof(uint32_t)); + memcpy(rect->data[1], clut_table, (1 << region->depth) * sizeof(*clut_table)); rect->data[0] = av_malloc(region->buf_size); if (!rect->data[0]) { @@ -851,7 +851,7 @@ FF_ENABLE_DEPRECATION_WARNINGS return 0; fail: if (sub->rects) { - for(i=0; inum_rects; i++) { + for (i=0; i < sub->num_rects; i++) { rect = sub->rects[i]; if (rect) { av_freep(&rect->data[0]); @@ -1073,11 +1073,11 @@ static int dvbsub_parse_clut_segment(AVCodecContext *avctx, clut = get_clut(ctx, clut_id); if (!clut) { - clut = av_malloc(sizeof(DVBSubCLUT)); + clut = av_malloc(sizeof(*clut)); if (!clut) return AVERROR(ENOMEM); - memcpy(clut, &default_clut, sizeof(DVBSubCLUT)); + memcpy(clut, &default_clut, sizeof(*clut)); clut->id = clut_id; clut->version = -1; @@ -1088,53 +1088,53 @@ static int dvbsub_parse_clut_segment(AVCodecContext *avctx, if (clut->version != version) { - clut->version = version; + clut->version = version; - while (buf + 4 < buf_end) { - entry_id = *buf++; + while (buf + 4 < buf_end) { + entry_id = *buf++; - depth = (*buf) & 0xe0; + depth = (*buf) & 0xe0; - if (depth == 0) { - av_log(avctx, AV_LOG_ERROR, "Invalid clut depth 0x%x!\n", *buf); + if (depth == 0) { + av_log(avctx, AV_LOG_ERROR, "Invalid clut depth 0x%x!\n", *buf); + } + + full_range = (*buf++) & 1; + + if (full_range) { + y = *buf++; + cr = *buf++; + cb = *buf++; + alpha = *buf++; + } else { + y = buf[0] & 0xfc; + cr = (((buf[0] & 3) << 2) | ((buf[1] >> 6) & 3)) << 4; + cb = (buf[1] << 2) & 0xf0; + alpha = (buf[1] << 6) & 0xc0; + + buf += 2; + } + + if (y == 0) + alpha = 0xff; + + YUV_TO_RGB1_CCIR(cb, cr); + YUV_TO_RGB2_CCIR(r, g, b, y); + + ff_dlog(avctx, "clut %d := (%d,%d,%d,%d)\n", entry_id, r, g, b, alpha); + if (!!(depth & 0x80) + !!(depth & 0x40) + !!(depth & 0x20) > 1) { + ff_dlog(avctx, "More than one bit level marked: %x\n", depth); + if (avctx->strict_std_compliance > FF_COMPLIANCE_NORMAL) + return AVERROR_INVALIDDATA; + } + + if (depth & 0x80 && entry_id < 4) + clut->clut4[entry_id] = RGBA(r,g,b,255 - alpha); + else if (depth & 0x40 && entry_id < 16) + clut->clut16[entry_id] = RGBA(r,g,b,255 - alpha); + else if (depth & 0x20) + clut->clut256[entry_id] = RGBA(r,g,b,255 - alpha); } - - full_range = (*buf++) & 1; - - if (full_range) { - y = *buf++; - cr = *buf++; - cb = *buf++; - alpha = *buf++; - } else { - y = buf[0] & 0xfc; - cr = (((buf[0] & 3) << 2) | ((buf[1] >> 6) & 3)) << 4; - cb = (buf[1] << 2) & 0xf0; - alpha = (buf[1] << 6) & 0xc0; - - buf += 2; - } - - if (y == 0) - alpha = 0xff; - - YUV_TO_RGB1_CCIR(cb, cr); - YUV_TO_RGB2_CCIR(r, g, b, y); - - ff_dlog(avctx, "clut %d := (%d,%d,%d,%d)\n", entry_id, r, g, b, alpha); - if (!!(depth & 0x80) + !!(depth & 0x40) + !!(depth & 0x20) > 1) { - ff_dlog(avctx, "More than one bit level marked: %x\n", depth); - if (avctx->strict_std_compliance > FF_COMPLIANCE_NORMAL) - return AVERROR_INVALIDDATA; - } - - if (depth & 0x80 && entry_id < 4) - clut->clut4[entry_id] = RGBA(r,g,b,255 - alpha); - else if (depth & 0x40 && entry_id < 16) - clut->clut16[entry_id] = RGBA(r,g,b,255 - alpha); - else if (depth & 0x20) - clut->clut256[entry_id] = RGBA(r,g,b,255 - alpha); - } } return 0; @@ -1163,7 +1163,7 @@ static int dvbsub_parse_region_segment(AVCodecContext *avctx, region = get_region(ctx, region_id); if (!region) { - region = av_mallocz(sizeof(DVBSubRegion)); + region = av_mallocz(sizeof(*region)); if (!region) return AVERROR(ENOMEM); @@ -1210,7 +1210,7 @@ static int dvbsub_parse_region_segment(AVCodecContext *avctx, } region->depth = 1 << (((*buf++) >> 2) & 7); - if(region->depth<2 || region->depth>8){ + if (region->depth < 2 || region->depth > 8) { av_log(avctx, AV_LOG_ERROR, "region depth %d is invalid\n", region->depth); region->depth= 4; } @@ -1244,7 +1244,7 @@ static int dvbsub_parse_region_segment(AVCodecContext *avctx, object = get_object(ctx, object_id); if (!object) { - object = av_mallocz(sizeof(DVBSubObject)); + object = av_mallocz(sizeof(*object)); if (!object) return AVERROR(ENOMEM); @@ -1255,7 +1255,7 @@ static int dvbsub_parse_region_segment(AVCodecContext *avctx, object->type = (*buf) >> 6; - display = av_mallocz(sizeof(DVBSubObjectDisplay)); + display = av_mallocz(sizeof(*display)); if (!display) return AVERROR(ENOMEM); @@ -1318,7 +1318,7 @@ static int dvbsub_parse_page_segment(AVCodecContext *avctx, ff_dlog(avctx, "Page time out %ds, state %d\n", ctx->time_out, page_state); - if(ctx->compute_edt == 1) + if (ctx->compute_edt == 1) save_subtitle_set(avctx, sub, got_output); if (page_state == 1 || page_state == 2) { @@ -1352,7 +1352,7 @@ static int dvbsub_parse_page_segment(AVCodecContext *avctx, } if (!display) { - display = av_mallocz(sizeof(DVBSubRegionDisplay)); + display = av_mallocz(sizeof(*display)); if (!display) return AVERROR(ENOMEM); } @@ -1601,7 +1601,7 @@ static int dvbsub_display_end_segment(AVCodecContext *avctx, const uint8_t *buf, { DVBSubContext *ctx = avctx->priv_data; - if(ctx->compute_edt == 0) + if (ctx->compute_edt == 0) save_subtitle_set(avctx, sub, got_output); #ifdef DEBUG save_display_set(ctx); @@ -1717,12 +1717,12 @@ static int dvbsub_decode(AVCodecContext *avctx, } end: - if(ret < 0) { + if (ret < 0) { *got_sub_ptr = 0; avsubtitle_free(sub); return ret; } else { - if(ctx->compute_edt == 1 ) + if (ctx->compute_edt == 1) FFSWAP(int64_t, ctx->prev_start, sub->pts); } @@ -1730,10 +1730,11 @@ end: } #define DS AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_SUBTITLE_PARAM +#define OFFSET(x) offsetof(DVBSubContext, x) static const AVOption options[] = { - {"compute_edt", "compute end of time using pts or timeout", offsetof(DVBSubContext, compute_edt), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, DS}, - {"compute_clut", "compute clut when not available(-1) or always(1) or never(0)", offsetof(DVBSubContext, compute_clut), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, DS}, - {"dvb_substream", "", offsetof(DVBSubContext, substream), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 63, DS}, + {"compute_edt", "compute end of time using pts or timeout", OFFSET(compute_edt), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, DS}, + {"compute_clut", "compute clut when not available(-1) or always(1) or never(0)", OFFSET(compute_clut), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, DS}, + {"dvb_substream", "", OFFSET(substream), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 63, DS}, {NULL} }; static const AVClass dvbsubdec_class = { diff --git a/externals/ffmpeg/libavcodec/dvdsub_parser.c b/externals/ffmpeg/libavcodec/dvdsub_parser.c index 698ccb698..054af69db 100755 --- a/externals/ffmpeg/libavcodec/dvdsub_parser.c +++ b/externals/ffmpeg/libavcodec/dvdsub_parser.c @@ -32,11 +32,6 @@ typedef struct DVDSubParseContext { int packet_index; } DVDSubParseContext; -static av_cold int dvdsub_parse_init(AVCodecParserContext *s) -{ - return 0; -} - static int dvdsub_parse(AVCodecParserContext *s, AVCodecContext *avctx, const uint8_t **poutbuf, int *poutbuf_size, @@ -92,7 +87,6 @@ static av_cold void dvdsub_parse_close(AVCodecParserContext *s) AVCodecParser ff_dvdsub_parser = { .codec_ids = { AV_CODEC_ID_DVD_SUBTITLE }, .priv_data_size = sizeof(DVDSubParseContext), - .parser_init = dvdsub_parse_init, .parser_parse = dvdsub_parse, .parser_close = dvdsub_parse_close, }; diff --git a/externals/ffmpeg/libavcodec/encode.c b/externals/ffmpeg/libavcodec/encode.c index b1784ed05..8bc10c4ab 100755 --- a/externals/ffmpeg/libavcodec/encode.c +++ b/externals/ffmpeg/libavcodec/encode.c @@ -26,61 +26,43 @@ #include "libavutil/samplefmt.h" #include "avcodec.h" +#include "encode.h" #include "frame_thread_encoder.h" #include "internal.h" int ff_alloc_packet2(AVCodecContext *avctx, AVPacket *avpkt, int64_t size, int64_t min_size) { - if (avpkt->size < 0) { - av_log(avctx, AV_LOG_ERROR, "Invalid negative user packet size %d\n", avpkt->size); - return AVERROR(EINVAL); - } if (size < 0 || size > INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE) { av_log(avctx, AV_LOG_ERROR, "Invalid minimum required packet size %"PRId64" (max allowed is %d)\n", size, INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE); return AVERROR(EINVAL); } + av_assert0(!avpkt->data); + if (avctx && 2*min_size < size) { // FIXME The factor needs to be finetuned - av_assert0(!avpkt->data || avpkt->data != avctx->internal->byte_buffer); - if (!avpkt->data || avpkt->size < size) { - av_fast_padded_malloc(&avctx->internal->byte_buffer, &avctx->internal->byte_buffer_size, size); - avpkt->data = avctx->internal->byte_buffer; - avpkt->size = avctx->internal->byte_buffer_size; - } + av_fast_padded_malloc(&avctx->internal->byte_buffer, &avctx->internal->byte_buffer_size, size); + avpkt->data = avctx->internal->byte_buffer; + avpkt->size = size; } - if (avpkt->data) { - AVBufferRef *buf = avpkt->buf; - - if (avpkt->size < size) { - av_log(avctx, AV_LOG_ERROR, "User packet is too small (%d < %"PRId64")\n", avpkt->size, size); - return AVERROR(EINVAL); - } - - av_init_packet(avpkt); - avpkt->buf = buf; - avpkt->size = size; - return 0; - } else { + if (!avpkt->data) { int ret = av_new_packet(avpkt, size); if (ret < 0) av_log(avctx, AV_LOG_ERROR, "Failed to allocate packet of size %"PRId64"\n", size); return ret; } + + return 0; } /** * Pad last frame with silence. */ -static int pad_last_frame(AVCodecContext *s, AVFrame **dst, const AVFrame *src) +static int pad_last_frame(AVCodecContext *s, AVFrame *frame, const AVFrame *src) { - AVFrame *frame = NULL; int ret; - if (!(frame = av_frame_alloc())) - return AVERROR(ENOMEM); - frame->format = src->format; frame->channel_layout = src->channel_layout; frame->channels = src->channels; @@ -101,246 +83,10 @@ static int pad_last_frame(AVCodecContext *s, AVFrame **dst, const AVFrame *src) s->channels, s->sample_fmt)) < 0) goto fail; - *dst = frame; - return 0; fail: - av_frame_free(&frame); - return ret; -} - -int attribute_align_arg avcodec_encode_audio2(AVCodecContext *avctx, - AVPacket *avpkt, - const AVFrame *frame, - int *got_packet_ptr) -{ - AVFrame *extended_frame = NULL; - AVFrame *padded_frame = NULL; - int ret; - AVPacket user_pkt = *avpkt; - int needs_realloc = !user_pkt.data; - - *got_packet_ptr = 0; - - if (!avctx->codec->encode2) { - av_log(avctx, AV_LOG_ERROR, "This encoder requires using the avcodec_send_frame() API.\n"); - return AVERROR(ENOSYS); - } - - if (!(avctx->codec->capabilities & AV_CODEC_CAP_DELAY) && !frame) { - av_packet_unref(avpkt); - return 0; - } - - /* ensure that extended_data is properly set */ - if (frame && !frame->extended_data) { - if (av_sample_fmt_is_planar(avctx->sample_fmt) && - avctx->channels > AV_NUM_DATA_POINTERS) { - av_log(avctx, AV_LOG_ERROR, "Encoding to a planar sample format, " - "with more than %d channels, but extended_data is not set.\n", - AV_NUM_DATA_POINTERS); - return AVERROR(EINVAL); - } - av_log(avctx, AV_LOG_WARNING, "extended_data is not set.\n"); - - extended_frame = av_frame_alloc(); - if (!extended_frame) - return AVERROR(ENOMEM); - - memcpy(extended_frame, frame, sizeof(AVFrame)); - extended_frame->extended_data = extended_frame->data; - frame = extended_frame; - } - - /* extract audio service type metadata */ - if (frame) { - AVFrameSideData *sd = av_frame_get_side_data(frame, AV_FRAME_DATA_AUDIO_SERVICE_TYPE); - if (sd && sd->size >= sizeof(enum AVAudioServiceType)) - avctx->audio_service_type = *(enum AVAudioServiceType*)sd->data; - } - - /* check for valid frame size */ - if (frame) { - if (avctx->codec->capabilities & AV_CODEC_CAP_SMALL_LAST_FRAME) { - if (frame->nb_samples > avctx->frame_size) { - av_log(avctx, AV_LOG_ERROR, "more samples than frame size (avcodec_encode_audio2)\n"); - ret = AVERROR(EINVAL); - goto end; - } - } else if (!(avctx->codec->capabilities & AV_CODEC_CAP_VARIABLE_FRAME_SIZE)) { - /* if we already got an undersized frame, that must have been the last */ - if (avctx->internal->last_audio_frame) { - av_log(avctx, AV_LOG_ERROR, "frame_size (%d) was not respected for a non-last frame (avcodec_encode_audio2)\n", avctx->frame_size); - ret = AVERROR(EINVAL); - goto end; - } - - if (frame->nb_samples < avctx->frame_size) { - ret = pad_last_frame(avctx, &padded_frame, frame); - if (ret < 0) - goto end; - - frame = padded_frame; - avctx->internal->last_audio_frame = 1; - } - - if (frame->nb_samples != avctx->frame_size) { - av_log(avctx, AV_LOG_ERROR, "nb_samples (%d) != frame_size (%d) (avcodec_encode_audio2)\n", frame->nb_samples, avctx->frame_size); - ret = AVERROR(EINVAL); - goto end; - } - } - } - - av_assert0(avctx->codec->encode2); - - ret = avctx->codec->encode2(avctx, avpkt, frame, got_packet_ptr); - if (!ret) { - if (*got_packet_ptr) { - if (!(avctx->codec->capabilities & AV_CODEC_CAP_DELAY)) { - if (avpkt->pts == AV_NOPTS_VALUE) - avpkt->pts = frame->pts; - if (!avpkt->duration) - avpkt->duration = ff_samples_to_time_base(avctx, - frame->nb_samples); - } - avpkt->dts = avpkt->pts; - } else { - avpkt->size = 0; - } - } - if (avpkt->data && avpkt->data == avctx->internal->byte_buffer) { - needs_realloc = 0; - if (user_pkt.data) { - if (user_pkt.size >= avpkt->size) { - memcpy(user_pkt.data, avpkt->data, avpkt->size); - } else { - av_log(avctx, AV_LOG_ERROR, "Provided packet is too small, needs to be %d\n", avpkt->size); - avpkt->size = user_pkt.size; - ret = -1; - } - avpkt->buf = user_pkt.buf; - avpkt->data = user_pkt.data; - } else if (!avpkt->buf) { - ret = av_packet_make_refcounted(avpkt); - if (ret < 0) - goto end; - } - } - - if (!ret) { - if (needs_realloc && avpkt->data) { - ret = av_buffer_realloc(&avpkt->buf, avpkt->size + AV_INPUT_BUFFER_PADDING_SIZE); - if (ret >= 0) - avpkt->data = avpkt->buf->data; - } - if (frame) - avctx->frame_number++; - } - - if (ret < 0 || !*got_packet_ptr) { - av_packet_unref(avpkt); - goto end; - } - - /* NOTE: if we add any audio encoders which output non-keyframe packets, - * this needs to be moved to the encoders, but for now we can do it - * here to simplify things */ - avpkt->flags |= AV_PKT_FLAG_KEY; - -end: - av_frame_free(&padded_frame); - av_free(extended_frame); - - return ret; -} - -int attribute_align_arg avcodec_encode_video2(AVCodecContext *avctx, - AVPacket *avpkt, - const AVFrame *frame, - int *got_packet_ptr) -{ - int ret; - AVPacket user_pkt = *avpkt; - int needs_realloc = !user_pkt.data; - - *got_packet_ptr = 0; - - if (!avctx->codec->encode2) { - av_log(avctx, AV_LOG_ERROR, "This encoder requires using the avcodec_send_frame() API.\n"); - return AVERROR(ENOSYS); - } - - if ((avctx->flags&AV_CODEC_FLAG_PASS1) && avctx->stats_out) - avctx->stats_out[0] = '\0'; - - if (!frame && - !(avctx->codec->capabilities & AV_CODEC_CAP_DELAY || - (avctx->internal->frame_thread_encoder && avctx->active_thread_type & FF_THREAD_FRAME))) { - av_packet_unref(avpkt); - return 0; - } - - if (av_image_check_size2(avctx->width, avctx->height, avctx->max_pixels, AV_PIX_FMT_NONE, 0, avctx)) - return AVERROR(EINVAL); - - if (frame && frame->format == AV_PIX_FMT_NONE) - av_log(avctx, AV_LOG_WARNING, "AVFrame.format is not set\n"); - if (frame && (frame->width == 0 || frame->height == 0)) - av_log(avctx, AV_LOG_WARNING, "AVFrame.width or height is not set\n"); - - av_assert0(avctx->codec->encode2); - - - if (CONFIG_FRAME_THREAD_ENCODER && - avctx->internal->frame_thread_encoder && (avctx->active_thread_type & FF_THREAD_FRAME)) - ret = ff_thread_video_encode_frame(avctx, avpkt, frame, got_packet_ptr); - else { - ret = avctx->codec->encode2(avctx, avpkt, frame, got_packet_ptr); - if (*got_packet_ptr && !(avctx->codec->capabilities & AV_CODEC_CAP_DELAY)) - avpkt->pts = avpkt->dts = frame->pts; - } - av_assert0(ret <= 0); - - emms_c(); - - if (avpkt->data && avpkt->data == avctx->internal->byte_buffer) { - needs_realloc = 0; - if (user_pkt.data) { - if (user_pkt.size >= avpkt->size) { - memcpy(user_pkt.data, avpkt->data, avpkt->size); - } else { - av_log(avctx, AV_LOG_ERROR, "Provided packet is too small, needs to be %d\n", avpkt->size); - avpkt->size = user_pkt.size; - ret = -1; - } - avpkt->buf = user_pkt.buf; - avpkt->data = user_pkt.data; - } else if (!avpkt->buf) { - ret = av_packet_make_refcounted(avpkt); - if (ret < 0) - return ret; - } - } - - if (!ret) { - if (!*got_packet_ptr) - avpkt->size = 0; - - if (needs_realloc && avpkt->data) { - ret = av_buffer_realloc(&avpkt->buf, avpkt->size + AV_INPUT_BUFFER_PADDING_SIZE); - if (ret >= 0) - avpkt->data = avpkt->buf->data; - } - - if (frame) - avctx->frame_number++; - } - - if (ret < 0 || !*got_packet_ptr) - av_packet_unref(avpkt); - + av_frame_unref(frame); return ret; } @@ -358,101 +104,353 @@ int avcodec_encode_subtitle(AVCodecContext *avctx, uint8_t *buf, int buf_size, return ret; } -static int do_encode(AVCodecContext *avctx, const AVFrame *frame, int *got_packet) +int ff_encode_get_frame(AVCodecContext *avctx, AVFrame *frame) { + AVCodecInternal *avci = avctx->internal; + + if (avci->draining) + return AVERROR_EOF; + + if (!avci->buffer_frame->buf[0]) + return AVERROR(EAGAIN); + + av_frame_move_ref(frame, avci->buffer_frame); + + return 0; +} + +static int encode_simple_internal(AVCodecContext *avctx, AVPacket *avpkt) +{ + AVCodecInternal *avci = avctx->internal; + EncodeSimpleContext *es = &avci->es; + AVFrame *frame = es->in_frame; + int got_packet; int ret; - *got_packet = 0; - av_packet_unref(avctx->internal->buffer_pkt); - avctx->internal->buffer_pkt_valid = 0; + if (avci->draining_done) + return AVERROR_EOF; - if (avctx->codec_type == AVMEDIA_TYPE_VIDEO) { - ret = avcodec_encode_video2(avctx, avctx->internal->buffer_pkt, - frame, got_packet); - } else if (avctx->codec_type == AVMEDIA_TYPE_AUDIO) { - ret = avcodec_encode_audio2(avctx, avctx->internal->buffer_pkt, - frame, got_packet); - } else { - ret = AVERROR(EINVAL); + if (!frame->buf[0] && !avci->draining) { + av_frame_unref(frame); + ret = ff_encode_get_frame(avctx, frame); + if (ret < 0 && ret != AVERROR_EOF) + return ret; } - if (ret >= 0 && *got_packet) { + if (!frame->buf[0]) { + if (!(avctx->codec->capabilities & AV_CODEC_CAP_DELAY || + (avci->frame_thread_encoder && avctx->active_thread_type & FF_THREAD_FRAME))) + return AVERROR_EOF; + + // Flushing is signaled with a NULL frame + frame = NULL; + } + + got_packet = 0; + + av_assert0(avctx->codec->encode2); + + if (CONFIG_FRAME_THREAD_ENCODER && + avci->frame_thread_encoder && (avctx->active_thread_type & FF_THREAD_FRAME)) + ret = ff_thread_video_encode_frame(avctx, avpkt, frame, &got_packet); + else { + ret = avctx->codec->encode2(avctx, avpkt, frame, &got_packet); + if (avctx->codec->type == AVMEDIA_TYPE_VIDEO && !ret && got_packet && + !(avctx->codec->capabilities & AV_CODEC_CAP_DELAY)) + avpkt->pts = avpkt->dts = frame->pts; + } + + av_assert0(ret <= 0); + + emms_c(); + + if (!ret && got_packet) { + if (avpkt->data) { + ret = av_packet_make_refcounted(avpkt); + if (ret < 0) + goto end; + } + + if (frame && !(avctx->codec->capabilities & AV_CODEC_CAP_DELAY)) { + if (avctx->codec->type == AVMEDIA_TYPE_AUDIO) { + if (avpkt->pts == AV_NOPTS_VALUE) + avpkt->pts = frame->pts; + if (!avpkt->duration) + avpkt->duration = ff_samples_to_time_base(avctx, + frame->nb_samples); + } + } + if (avctx->codec->type == AVMEDIA_TYPE_AUDIO) { + /* NOTE: if we add any audio encoders which output non-keyframe packets, + * this needs to be moved to the encoders, but for now we can do it + * here to simplify things */ + avpkt->flags |= AV_PKT_FLAG_KEY; + avpkt->dts = avpkt->pts; + } + } + + if (avci->draining && !got_packet) + avci->draining_done = 1; + +end: + if (ret < 0 || !got_packet) + av_packet_unref(avpkt); + + if (frame) { + if (!ret) + avctx->frame_number++; + av_frame_unref(frame); + } + + if (got_packet) // Encoders must always return ref-counted buffers. // Side-data only packets have no data and can be not ref-counted. - av_assert0(!avctx->internal->buffer_pkt->data || avctx->internal->buffer_pkt->buf); - avctx->internal->buffer_pkt_valid = 1; - ret = 0; - } else { - av_packet_unref(avctx->internal->buffer_pkt); - } + av_assert0(!avpkt->data || avpkt->buf); return ret; } -int attribute_align_arg avcodec_send_frame(AVCodecContext *avctx, const AVFrame *frame) +static int encode_simple_receive_packet(AVCodecContext *avctx, AVPacket *avpkt) { - if (!avcodec_is_open(avctx) || !av_codec_is_encoder(avctx->codec)) - return AVERROR(EINVAL); + int ret; - if (avctx->internal->draining) - return AVERROR_EOF; - - if (!frame) { - avctx->internal->draining = 1; - - if (!(avctx->codec->capabilities & AV_CODEC_CAP_DELAY)) - return 0; + while (!avpkt->data && !avpkt->side_data) { + ret = encode_simple_internal(avctx, avpkt); + if (ret < 0) + return ret; } - if (avctx->codec->send_frame) - return avctx->codec->send_frame(avctx, frame); - - // Emulation via old API. Do it here instead of avcodec_receive_packet, because: - // 1. if the AVFrame is not refcounted, the copying will be much more - // expensive than copying the packet data - // 2. assume few users use non-refcounted AVPackets, so usually no copy is - // needed - - if (avctx->internal->buffer_pkt_valid) - return AVERROR(EAGAIN); - - return do_encode(avctx, frame, &(int){0}); + return 0; } -int attribute_align_arg avcodec_receive_packet(AVCodecContext *avctx, AVPacket *avpkt) +static int encode_receive_packet_internal(AVCodecContext *avctx, AVPacket *avpkt) { - av_packet_unref(avpkt); + AVCodecInternal *avci = avctx->internal; + int ret; - if (!avcodec_is_open(avctx) || !av_codec_is_encoder(avctx->codec)) - return AVERROR(EINVAL); + if (avci->draining_done) + return AVERROR_EOF; + + av_assert0(!avpkt->data && !avpkt->side_data); + + if (avctx->codec->type == AVMEDIA_TYPE_VIDEO) { + if ((avctx->flags & AV_CODEC_FLAG_PASS1) && avctx->stats_out) + avctx->stats_out[0] = '\0'; + if (av_image_check_size2(avctx->width, avctx->height, avctx->max_pixels, AV_PIX_FMT_NONE, 0, avctx)) + return AVERROR(EINVAL); + } if (avctx->codec->receive_packet) { - int ret; - if (avctx->internal->draining && !(avctx->codec->capabilities & AV_CODEC_CAP_DELAY)) - return AVERROR_EOF; ret = avctx->codec->receive_packet(avctx, avpkt); if (!ret) // Encoders must always return ref-counted buffers. // Side-data only packets have no data and can be not ref-counted. av_assert0(!avpkt->data || avpkt->buf); - return ret; + } else + ret = encode_simple_receive_packet(avctx, avpkt); + + if (ret == AVERROR_EOF) + avci->draining_done = 1; + + return ret; +} + +static int encode_send_frame_internal(AVCodecContext *avctx, const AVFrame *src) +{ + AVCodecInternal *avci = avctx->internal; + AVFrame *dst = avci->buffer_frame; + int ret; + + if (avctx->codec->type == AVMEDIA_TYPE_AUDIO) { + /* extract audio service type metadata */ + AVFrameSideData *sd = av_frame_get_side_data(src, AV_FRAME_DATA_AUDIO_SERVICE_TYPE); + if (sd && sd->size >= sizeof(enum AVAudioServiceType)) + avctx->audio_service_type = *(enum AVAudioServiceType*)sd->data; + + /* check for valid frame size */ + if (avctx->codec->capabilities & AV_CODEC_CAP_SMALL_LAST_FRAME) { + if (src->nb_samples > avctx->frame_size) { + av_log(avctx, AV_LOG_ERROR, "more samples than frame size\n"); + return AVERROR(EINVAL); + } + } else if (!(avctx->codec->capabilities & AV_CODEC_CAP_VARIABLE_FRAME_SIZE)) { + /* if we already got an undersized frame, that must have been the last */ + if (avctx->internal->last_audio_frame) { + av_log(avctx, AV_LOG_ERROR, "frame_size (%d) was not respected for a non-last frame\n", avctx->frame_size); + return AVERROR(EINVAL); + } + + if (src->nb_samples < avctx->frame_size) { + ret = pad_last_frame(avctx, dst, src); + if (ret < 0) + return ret; + + avctx->internal->last_audio_frame = 1; + } else if (src->nb_samples > avctx->frame_size) { + av_log(avctx, AV_LOG_ERROR, "nb_samples (%d) != frame_size (%d)\n", src->nb_samples, avctx->frame_size); + return AVERROR(EINVAL); + } + } } - // Emulation via old API. - - if (!avctx->internal->buffer_pkt_valid) { - int got_packet; - int ret; - if (!avctx->internal->draining) - return AVERROR(EAGAIN); - ret = do_encode(avctx, NULL, &got_packet); + if (!dst->data[0]) { + ret = av_frame_ref(dst, src); if (ret < 0) - return ret; - if (ret >= 0 && !got_packet) - return AVERROR_EOF; + return ret; } - av_packet_move_ref(avpkt, avctx->internal->buffer_pkt); - avctx->internal->buffer_pkt_valid = 0; return 0; } + +int attribute_align_arg avcodec_send_frame(AVCodecContext *avctx, const AVFrame *frame) +{ + AVCodecInternal *avci = avctx->internal; + int ret; + + if (!avcodec_is_open(avctx) || !av_codec_is_encoder(avctx->codec)) + return AVERROR(EINVAL); + + if (avci->draining) + return AVERROR_EOF; + + if (avci->buffer_frame->data[0]) + return AVERROR(EAGAIN); + + if (!frame) { + avci->draining = 1; + } else { + ret = encode_send_frame_internal(avctx, frame); + if (ret < 0) + return ret; + } + + if (!avci->buffer_pkt->data && !avci->buffer_pkt->side_data) { + ret = encode_receive_packet_internal(avctx, avci->buffer_pkt); + if (ret < 0 && ret != AVERROR(EAGAIN) && ret != AVERROR_EOF) + return ret; + } + + return 0; +} + +int attribute_align_arg avcodec_receive_packet(AVCodecContext *avctx, AVPacket *avpkt) +{ + AVCodecInternal *avci = avctx->internal; + int ret; + + av_packet_unref(avpkt); + + if (!avcodec_is_open(avctx) || !av_codec_is_encoder(avctx->codec)) + return AVERROR(EINVAL); + + if (avci->buffer_pkt->data || avci->buffer_pkt->side_data) { + av_packet_move_ref(avpkt, avci->buffer_pkt); + } else { + ret = encode_receive_packet_internal(avctx, avpkt); + if (ret < 0) + return ret; + } + + return 0; +} + +static int compat_encode(AVCodecContext *avctx, AVPacket *avpkt, + int *got_packet, const AVFrame *frame) +{ + AVCodecInternal *avci = avctx->internal; + AVPacket user_pkt; + int ret; + + *got_packet = 0; + + if (frame && avctx->codec->type == AVMEDIA_TYPE_VIDEO) { + if (frame->format == AV_PIX_FMT_NONE) + av_log(avctx, AV_LOG_WARNING, "AVFrame.format is not set\n"); + if (frame->width == 0 || frame->height == 0) + av_log(avctx, AV_LOG_WARNING, "AVFrame.width or height is not set\n"); + } + + ret = avcodec_send_frame(avctx, frame); + if (ret == AVERROR_EOF) + ret = 0; + else if (ret == AVERROR(EAGAIN)) { + /* we fully drain all the output in each encode call, so this should not + * ever happen */ + return AVERROR_BUG; + } else if (ret < 0) + return ret; + + av_packet_move_ref(&user_pkt, avpkt); + while (ret >= 0) { + ret = avcodec_receive_packet(avctx, avpkt); + if (ret < 0) { + if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) + ret = 0; + goto finish; + } + + if (avpkt != avci->compat_encode_packet) { + if (avpkt->data && user_pkt.data) { + if (user_pkt.size >= avpkt->size) { + memcpy(user_pkt.data, avpkt->data, avpkt->size); + av_buffer_unref(&avpkt->buf); + avpkt->buf = user_pkt.buf; + avpkt->data = user_pkt.data; + av_init_packet(&user_pkt); + } else { + av_log(avctx, AV_LOG_ERROR, "Provided packet is too small, needs to be %d\n", avpkt->size); + av_packet_unref(avpkt); + ret = AVERROR(EINVAL); + goto finish; + } + } + + *got_packet = 1; + avpkt = avci->compat_encode_packet; + } else { + if (!avci->compat_decode_warned) { + av_log(avctx, AV_LOG_WARNING, "The deprecated avcodec_encode_* " + "API cannot return all the packets for this encoder. " + "Some packets will be dropped. Update your code to the " + "new encoding API to fix this.\n"); + avci->compat_decode_warned = 1; + av_packet_unref(avpkt); + } + } + + if (avci->draining) + break; + } + +finish: + if (ret < 0) + av_packet_unref(&user_pkt); + + return ret; +} + +int attribute_align_arg avcodec_encode_audio2(AVCodecContext *avctx, + AVPacket *avpkt, + const AVFrame *frame, + int *got_packet_ptr) +{ + int ret = compat_encode(avctx, avpkt, got_packet_ptr, frame); + + if (ret < 0) + av_packet_unref(avpkt); + + return ret; +} + +int attribute_align_arg avcodec_encode_video2(AVCodecContext *avctx, + AVPacket *avpkt, + const AVFrame *frame, + int *got_packet_ptr) +{ + int ret = compat_encode(avctx, avpkt, got_packet_ptr, frame); + + if (ret < 0) + av_packet_unref(avpkt); + + return ret; +} diff --git a/externals/ffmpeg/libavcodec/encode.h b/externals/ffmpeg/libavcodec/encode.h new file mode 100755 index 000000000..dfa9cb2d9 --- /dev/null +++ b/externals/ffmpeg/libavcodec/encode.h @@ -0,0 +1,39 @@ +/* + * generic encoding-related code + * + * 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 + */ + +#ifndef AVCODEC_ENCODE_H +#define AVCODEC_ENCODE_H + +#include "libavutil/frame.h" + +#include "avcodec.h" + +/** + * Called by encoders to get the next frame for encoding. + * + * @param frame An empty frame to be filled with data. + * @return 0 if a new reference has been successfully written to frame + * AVERROR(EAGAIN) if no data is currently available + * AVERROR_EOF if end of stream has been reached, so no more data + * will be available + */ +int ff_encode_get_frame(AVCodecContext *avctx, AVFrame *frame); + +#endif /* AVCODEC_ENCODE_H */ diff --git a/externals/ffmpeg/libavcodec/filter_units_bsf.c b/externals/ffmpeg/libavcodec/filter_units_bsf.c index 700dc06ef..354594ac5 100755 --- a/externals/ffmpeg/libavcodec/filter_units_bsf.c +++ b/externals/ffmpeg/libavcodec/filter_units_bsf.c @@ -125,7 +125,7 @@ static int filter_units_filter(AVBSFContext *bsf, AVPacket *pkt) } if (ctx->mode == REMOVE ? j < ctx->nb_types : j >= ctx->nb_types) - ff_cbs_delete_unit(ctx->cbc, frag, i); + ff_cbs_delete_unit(frag, i); } if (frag->nb_units == 0) { @@ -143,7 +143,7 @@ static int filter_units_filter(AVBSFContext *bsf, AVPacket *pkt) fail: if (err < 0) av_packet_unref(pkt); - ff_cbs_fragment_reset(ctx->cbc, frag); + ff_cbs_fragment_reset(frag); return err; } @@ -199,7 +199,7 @@ static int filter_units_init(AVBSFContext *bsf) av_log(bsf, AV_LOG_ERROR, "Failed to write extradata.\n"); } - ff_cbs_fragment_reset(ctx->cbc, frag); + ff_cbs_fragment_reset(frag); } return err; @@ -211,7 +211,7 @@ static void filter_units_close(AVBSFContext *bsf) av_freep(&ctx->type_list); - ff_cbs_fragment_free(ctx->cbc, &ctx->fragment); + ff_cbs_fragment_free(&ctx->fragment); ff_cbs_close(&ctx->cbc); } diff --git a/externals/ffmpeg/libavcodec/h261dec.c b/externals/ffmpeg/libavcodec/h261dec.c index 14a874c45..8a49e7d89 100755 --- a/externals/ffmpeg/libavcodec/h261dec.c +++ b/externals/ffmpeg/libavcodec/h261dec.c @@ -686,5 +686,6 @@ AVCodec ff_h261_decoder = { .close = h261_decode_end, .decode = h261_decode_frame, .capabilities = AV_CODEC_CAP_DR1, + .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, .max_lowres = 3, }; diff --git a/externals/ffmpeg/libavcodec/h263dec.c b/externals/ffmpeg/libavcodec/h263dec.c index 31ac563f4..3b29a189e 100755 --- a/externals/ffmpeg/libavcodec/h263dec.c +++ b/externals/ffmpeg/libavcodec/h263dec.c @@ -770,7 +770,7 @@ AVCodec ff_h263_decoder = { .decode = ff_h263_decode_frame, .capabilities = AV_CODEC_CAP_DRAW_HORIZ_BAND | AV_CODEC_CAP_DR1 | AV_CODEC_CAP_TRUNCATED | AV_CODEC_CAP_DELAY, - .caps_internal = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM, + .caps_internal = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM | FF_CODEC_CAP_INIT_CLEANUP, .flush = ff_mpeg_flush, .max_lowres = 3, .pix_fmts = ff_h263_hwaccel_pixfmt_list_420, @@ -788,7 +788,7 @@ AVCodec ff_h263p_decoder = { .decode = ff_h263_decode_frame, .capabilities = AV_CODEC_CAP_DRAW_HORIZ_BAND | AV_CODEC_CAP_DR1 | AV_CODEC_CAP_TRUNCATED | AV_CODEC_CAP_DELAY, - .caps_internal = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM, + .caps_internal = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM | FF_CODEC_CAP_INIT_CLEANUP, .flush = ff_mpeg_flush, .max_lowres = 3, .pix_fmts = ff_h263_hwaccel_pixfmt_list_420, diff --git a/externals/ffmpeg/libavcodec/h264_metadata_bsf.c b/externals/ffmpeg/libavcodec/h264_metadata_bsf.c index cef054bd6..eb1503159 100755 --- a/externals/ffmpeg/libavcodec/h264_metadata_bsf.c +++ b/externals/ffmpeg/libavcodec/h264_metadata_bsf.c @@ -49,7 +49,8 @@ enum { typedef struct H264MetadataContext { const AVClass *class; - CodedBitstreamContext *cbc; + CodedBitstreamContext *input; + CodedBitstreamContext *output; CodedBitstreamFragment access_unit; int done_first_au; @@ -289,7 +290,7 @@ static int h264_metadata_update_side_data(AVBSFContext *bsf, AVPacket *pkt) if (!side_data_size) return 0; - err = ff_cbs_read(ctx->cbc, au, side_data, side_data_size); + err = ff_cbs_read(ctx->input, au, side_data, side_data_size); if (err < 0) { av_log(bsf, AV_LOG_ERROR, "Failed to read extradata from packet side data.\n"); return err; @@ -303,7 +304,7 @@ static int h264_metadata_update_side_data(AVBSFContext *bsf, AVPacket *pkt) } } - err = ff_cbs_write_fragment_data(ctx->cbc, au); + err = ff_cbs_write_fragment_data(ctx->output, au); if (err < 0) { av_log(bsf, AV_LOG_ERROR, "Failed to write extradata into packet side data.\n"); return err; @@ -314,7 +315,7 @@ static int h264_metadata_update_side_data(AVBSFContext *bsf, AVPacket *pkt) return AVERROR(ENOMEM); memcpy(side_data, au->data, au->data_size); - ff_cbs_fragment_reset(ctx->cbc, au); + ff_cbs_fragment_reset(au); return 0; } @@ -334,7 +335,7 @@ static int h264_metadata_filter(AVBSFContext *bsf, AVPacket *pkt) if (err < 0) goto fail; - err = ff_cbs_read_packet(ctx->cbc, au, pkt); + err = ff_cbs_read_packet(ctx->input, au, pkt); if (err < 0) { av_log(bsf, AV_LOG_ERROR, "Failed to read packet.\n"); goto fail; @@ -349,7 +350,7 @@ static int h264_metadata_filter(AVBSFContext *bsf, AVPacket *pkt) // If an AUD is present, it must be the first NAL unit. if (au->units[0].type == H264_NAL_AUD) { if (ctx->aud == REMOVE) - ff_cbs_delete_unit(ctx->cbc, au, 0); + ff_cbs_delete_unit(au, 0); } else { if (ctx->aud == INSERT) { static const int primary_pic_type_table[] = { @@ -390,7 +391,7 @@ static int h264_metadata_filter(AVBSFContext *bsf, AVPacket *pkt) .primary_pic_type = j, }; - err = ff_cbs_insert_unit_content(ctx->cbc, au, + err = ff_cbs_insert_unit_content(au, 0, H264_NAL_AUD, &aud, NULL); if (err < 0) { av_log(bsf, AV_LOG_ERROR, "Failed to insert AUD.\n"); @@ -448,7 +449,7 @@ static int h264_metadata_filter(AVBSFContext *bsf, AVPacket *pkt) udu->data_length = len + 1; memcpy(udu->data, ctx->sei_user_data + i + 1, len + 1); - err = ff_cbs_h264_add_sei_message(ctx->cbc, au, &payload); + err = ff_cbs_h264_add_sei_message(au, &payload); if (err < 0) { av_log(bsf, AV_LOG_ERROR, "Failed to add user data SEI " "message to access unit.\n"); @@ -467,7 +468,7 @@ static int h264_metadata_filter(AVBSFContext *bsf, AVPacket *pkt) if (ctx->delete_filler) { for (i = au->nb_units - 1; i >= 0; i--) { if (au->units[i].type == H264_NAL_FILLER_DATA) { - ff_cbs_delete_unit(ctx->cbc, au, i); + ff_cbs_delete_unit(au, i); continue; } @@ -478,8 +479,7 @@ static int h264_metadata_filter(AVBSFContext *bsf, AVPacket *pkt) for (j = sei->payload_count - 1; j >= 0; j--) { if (sei->payload[j].payload_type == H264_SEI_TYPE_FILLER_PAYLOAD) - ff_cbs_h264_delete_sei_message(ctx->cbc, au, - &au->units[i], j); + ff_cbs_h264_delete_sei_message(au, &au->units[i], j); } } } @@ -503,8 +503,7 @@ static int h264_metadata_filter(AVBSFContext *bsf, AVPacket *pkt) if (ctx->display_orientation == REMOVE || ctx->display_orientation == INSERT) { - ff_cbs_h264_delete_sei_message(ctx->cbc, au, - &au->units[i], j); + ff_cbs_h264_delete_sei_message(au, &au->units[i], j); continue; } @@ -595,7 +594,7 @@ static int h264_metadata_filter(AVBSFContext *bsf, AVPacket *pkt) if (write) { disp->display_orientation_repetition_period = 1; - err = ff_cbs_h264_add_sei_message(ctx->cbc, au, &payload); + err = ff_cbs_h264_add_sei_message(au, &payload); if (err < 0) { av_log(bsf, AV_LOG_ERROR, "Failed to add display orientation " "SEI message to access unit.\n"); @@ -604,7 +603,7 @@ static int h264_metadata_filter(AVBSFContext *bsf, AVPacket *pkt) } } - err = ff_cbs_write_packet(ctx->cbc, pkt, au); + err = ff_cbs_write_packet(ctx->output, pkt, au); if (err < 0) { av_log(bsf, AV_LOG_ERROR, "Failed to write packet.\n"); goto fail; @@ -614,7 +613,7 @@ static int h264_metadata_filter(AVBSFContext *bsf, AVPacket *pkt) err = 0; fail: - ff_cbs_fragment_reset(ctx->cbc, au); + ff_cbs_fragment_reset(au); if (err < 0) av_packet_unref(pkt); @@ -628,12 +627,15 @@ static int h264_metadata_init(AVBSFContext *bsf) CodedBitstreamFragment *au = &ctx->access_unit; int err, i; - err = ff_cbs_init(&ctx->cbc, AV_CODEC_ID_H264, bsf); + err = ff_cbs_init(&ctx->input, AV_CODEC_ID_H264, bsf); + if (err < 0) + return err; + err = ff_cbs_init(&ctx->output, AV_CODEC_ID_H264, bsf); if (err < 0) return err; if (bsf->par_in->extradata) { - err = ff_cbs_read_extradata(ctx->cbc, au, bsf->par_in); + err = ff_cbs_read_extradata(ctx->input, au, bsf->par_in); if (err < 0) { av_log(bsf, AV_LOG_ERROR, "Failed to read extradata.\n"); goto fail; @@ -647,7 +649,7 @@ static int h264_metadata_init(AVBSFContext *bsf) } } - err = ff_cbs_write_extradata(ctx->cbc, bsf->par_out, au); + err = ff_cbs_write_extradata(ctx->output, bsf->par_out, au); if (err < 0) { av_log(bsf, AV_LOG_ERROR, "Failed to write extradata.\n"); goto fail; @@ -656,7 +658,7 @@ static int h264_metadata_init(AVBSFContext *bsf) err = 0; fail: - ff_cbs_fragment_reset(ctx->cbc, au); + ff_cbs_fragment_reset(au); return err; } @@ -664,8 +666,9 @@ static void h264_metadata_close(AVBSFContext *bsf) { H264MetadataContext *ctx = bsf->priv_data; - ff_cbs_fragment_free(ctx->cbc, &ctx->access_unit); - ff_cbs_close(&ctx->cbc); + ff_cbs_fragment_free(&ctx->access_unit); + ff_cbs_close(&ctx->input); + ff_cbs_close(&ctx->output); } #define OFFSET(x) offsetof(H264MetadataContext, x) diff --git a/externals/ffmpeg/libavcodec/h264_redundant_pps_bsf.c b/externals/ffmpeg/libavcodec/h264_redundant_pps_bsf.c index 8f6978095..a8af4105c 100755 --- a/externals/ffmpeg/libavcodec/h264_redundant_pps_bsf.c +++ b/externals/ffmpeg/libavcodec/h264_redundant_pps_bsf.c @@ -95,7 +95,7 @@ static int h264_redundant_pps_filter(AVBSFContext *bsf, AVPacket *pkt) if (!au_has_sps) { av_log(bsf, AV_LOG_VERBOSE, "Deleting redundant PPS " "at %"PRId64".\n", pkt->pts); - ff_cbs_delete_unit(ctx->input, au, i); + ff_cbs_delete_unit(au, i); i--; continue; } @@ -113,7 +113,7 @@ static int h264_redundant_pps_filter(AVBSFContext *bsf, AVPacket *pkt) err = 0; fail: - ff_cbs_fragment_reset(ctx->output, au); + ff_cbs_fragment_reset(au); if (err < 0) av_packet_unref(pkt); @@ -161,7 +161,7 @@ static int h264_redundant_pps_init(AVBSFContext *bsf) err = 0; fail: - ff_cbs_fragment_reset(ctx->output, au); + ff_cbs_fragment_reset(au); return err; } @@ -175,7 +175,7 @@ static void h264_redundant_pps_close(AVBSFContext *bsf) { H264RedundantPPSContext *ctx = bsf->priv_data; - ff_cbs_fragment_free(ctx->input, &ctx->access_unit); + ff_cbs_fragment_free(&ctx->access_unit); ff_cbs_close(&ctx->input); ff_cbs_close(&ctx->output); } diff --git a/externals/ffmpeg/libavcodec/h264_sei.c b/externals/ffmpeg/libavcodec/h264_sei.c index 870dd9071..7b8e6bd7b 100755 --- a/externals/ffmpeg/libavcodec/h264_sei.c +++ b/externals/ffmpeg/libavcodec/h264_sei.c @@ -52,6 +52,10 @@ void ff_h264_sei_uninit(H264SEIContext *h) h->afd.present = 0; av_buffer_unref(&h->a53_caption.buf_ref); + for (int i = 0; i < h->unregistered.nb_buf_ref; i++) + av_buffer_unref(&h->unregistered.buf_ref[i]); + h->unregistered.nb_buf_ref = 0; + av_freep(&h->unregistered.buf_ref); } int ff_h264_sei_process_picture_timing(H264SEIPictureTiming *h, const SPS *sps, @@ -260,25 +264,34 @@ static int decode_unregistered_user_data(H264SEIUnregistered *h, GetBitContext * { uint8_t *user_data; int e, build, i; + AVBufferRef *buf_ref, **tmp; if (size < 16 || size >= INT_MAX - 1) return AVERROR_INVALIDDATA; - user_data = av_malloc(size + 1); - if (!user_data) + tmp = av_realloc_array(h->buf_ref, h->nb_buf_ref + 1, sizeof(*h->buf_ref)); + if (!tmp) return AVERROR(ENOMEM); + h->buf_ref = tmp; + + buf_ref = av_buffer_alloc(size + 1); + if (!buf_ref) + return AVERROR(ENOMEM); + user_data = buf_ref->data; for (i = 0; i < size; i++) user_data[i] = get_bits(gb, 8); user_data[i] = 0; + buf_ref->size = size; + h->buf_ref[h->nb_buf_ref++] = buf_ref; + e = sscanf(user_data + 16, "x264 - core %d", &build); if (e == 1 && build > 0) h->x264_build = build; if (e == 1 && build == 1 && !strncmp(user_data+16, "x264 - core 0000", 16)) h->x264_build = 67; - av_free(user_data); return 0; } diff --git a/externals/ffmpeg/libavcodec/h264_sei.h b/externals/ffmpeg/libavcodec/h264_sei.h index f07a5055c..4fdcf4ed3 100755 --- a/externals/ffmpeg/libavcodec/h264_sei.h +++ b/externals/ffmpeg/libavcodec/h264_sei.h @@ -126,6 +126,8 @@ typedef struct H264SEIA53Caption { typedef struct H264SEIUnregistered { int x264_build; + AVBufferRef **buf_ref; + int nb_buf_ref; } H264SEIUnregistered; typedef struct H264SEIRecoveryPoint { diff --git a/externals/ffmpeg/libavcodec/h264_slice.c b/externals/ffmpeg/libavcodec/h264_slice.c index 713953778..c7b276427 100755 --- a/externals/ffmpeg/libavcodec/h264_slice.c +++ b/externals/ffmpeg/libavcodec/h264_slice.c @@ -1125,9 +1125,10 @@ static int h264_export_frame_props(H264Context *h) { const SPS *sps = h->ps.sps; H264Picture *cur = h->cur_pic_ptr; + AVFrame *out = cur->f; - cur->f->interlaced_frame = 0; - cur->f->repeat_pict = 0; + out->interlaced_frame = 0; + out->repeat_pict = 0; /* Signal interlacing information externally. */ /* Prioritize picture timing SEI information over used @@ -1150,59 +1151,59 @@ static int h264_export_frame_props(H264Context *h) break; case H264_SEI_PIC_STRUCT_TOP_FIELD: case H264_SEI_PIC_STRUCT_BOTTOM_FIELD: - cur->f->interlaced_frame = 1; + out->interlaced_frame = 1; break; case H264_SEI_PIC_STRUCT_TOP_BOTTOM: case H264_SEI_PIC_STRUCT_BOTTOM_TOP: if (FIELD_OR_MBAFF_PICTURE(h)) - cur->f->interlaced_frame = 1; + out->interlaced_frame = 1; else // try to flag soft telecine progressive - cur->f->interlaced_frame = h->prev_interlaced_frame; + out->interlaced_frame = h->prev_interlaced_frame; break; case H264_SEI_PIC_STRUCT_TOP_BOTTOM_TOP: case H264_SEI_PIC_STRUCT_BOTTOM_TOP_BOTTOM: /* Signal the possibility of telecined film externally * (pic_struct 5,6). From these hints, let the applications * decide if they apply deinterlacing. */ - cur->f->repeat_pict = 1; + out->repeat_pict = 1; break; case H264_SEI_PIC_STRUCT_FRAME_DOUBLING: - cur->f->repeat_pict = 2; + out->repeat_pict = 2; break; case H264_SEI_PIC_STRUCT_FRAME_TRIPLING: - cur->f->repeat_pict = 4; + out->repeat_pict = 4; break; } if ((pt->ct_type & 3) && pt->pic_struct <= H264_SEI_PIC_STRUCT_BOTTOM_TOP) - cur->f->interlaced_frame = (pt->ct_type & (1 << 1)) != 0; + out->interlaced_frame = (pt->ct_type & (1 << 1)) != 0; } else { /* Derive interlacing flag from used decoding process. */ - cur->f->interlaced_frame = FIELD_OR_MBAFF_PICTURE(h); + out->interlaced_frame = FIELD_OR_MBAFF_PICTURE(h); } - h->prev_interlaced_frame = cur->f->interlaced_frame; + h->prev_interlaced_frame = out->interlaced_frame; if (cur->field_poc[0] != cur->field_poc[1]) { /* Derive top_field_first from field pocs. */ - cur->f->top_field_first = cur->field_poc[0] < cur->field_poc[1]; + out->top_field_first = cur->field_poc[0] < cur->field_poc[1]; } else { if (sps->pic_struct_present_flag && h->sei.picture_timing.present) { /* Use picture timing SEI information. Even if it is a * information of a past frame, better than nothing. */ if (h->sei.picture_timing.pic_struct == H264_SEI_PIC_STRUCT_TOP_BOTTOM || h->sei.picture_timing.pic_struct == H264_SEI_PIC_STRUCT_TOP_BOTTOM_TOP) - cur->f->top_field_first = 1; + out->top_field_first = 1; else - cur->f->top_field_first = 0; - } else if (cur->f->interlaced_frame) { + out->top_field_first = 0; + } else if (out->interlaced_frame) { /* Default to top field first when pic_struct_present_flag * is not set but interlaced frame detected */ - cur->f->top_field_first = 1; + out->top_field_first = 1; } else { /* Most likely progressive */ - cur->f->top_field_first = 0; + out->top_field_first = 0; } } @@ -1211,7 +1212,7 @@ static int h264_export_frame_props(H264Context *h) h->sei.frame_packing.content_interpretation_type > 0 && h->sei.frame_packing.content_interpretation_type < 3) { H264SEIFramePacking *fp = &h->sei.frame_packing; - AVStereo3D *stereo = av_stereo3d_create_side_data(cur->f); + AVStereo3D *stereo = av_stereo3d_create_side_data(out); if (stereo) { switch (fp->arrangement_type) { case H264_SEI_FPA_TYPE_CHECKERBOARD: @@ -1258,7 +1259,7 @@ static int h264_export_frame_props(H264Context *h) h->sei.display_orientation.vflip)) { H264SEIDisplayOrientation *o = &h->sei.display_orientation; double angle = o->anticlockwise_rotation * 360 / (double) (1 << 16); - AVFrameSideData *rotation = av_frame_new_side_data(cur->f, + AVFrameSideData *rotation = av_frame_new_side_data(out, AV_FRAME_DATA_DISPLAYMATRIX, sizeof(int32_t) * 9); if (rotation) { @@ -1269,7 +1270,7 @@ static int h264_export_frame_props(H264Context *h) } if (h->sei.afd.present) { - AVFrameSideData *sd = av_frame_new_side_data(cur->f, AV_FRAME_DATA_AFD, + AVFrameSideData *sd = av_frame_new_side_data(out, AV_FRAME_DATA_AFD, sizeof(uint8_t)); if (sd) { @@ -1281,7 +1282,7 @@ static int h264_export_frame_props(H264Context *h) if (h->sei.a53_caption.buf_ref) { H264SEIA53Caption *a53 = &h->sei.a53_caption; - AVFrameSideData *sd = av_frame_new_side_data_from_buf(cur->f, AV_FRAME_DATA_A53_CC, a53->buf_ref); + AVFrameSideData *sd = av_frame_new_side_data_from_buf(out, AV_FRAME_DATA_A53_CC, a53->buf_ref); if (!sd) av_buffer_unref(&a53->buf_ref); a53->buf_ref = NULL; @@ -1289,11 +1290,25 @@ static int h264_export_frame_props(H264Context *h) h->avctx->properties |= FF_CODEC_PROPERTY_CLOSED_CAPTIONS; } - if (h->sei.picture_timing.timecode_cnt > 0) { - uint32_t tc = 0; - uint32_t *tc_sd; + for (int i = 0; i < h->sei.unregistered.nb_buf_ref; i++) { + H264SEIUnregistered *unreg = &h->sei.unregistered; - AVFrameSideData *tcside = av_frame_new_side_data(cur->f, + if (unreg->buf_ref[i]) { + AVFrameSideData *sd = av_frame_new_side_data_from_buf(out, + AV_FRAME_DATA_SEI_UNREGISTERED, + unreg->buf_ref[i]); + if (!sd) + av_buffer_unref(&unreg->buf_ref[i]); + unreg->buf_ref[i] = NULL; + } + } + h->sei.unregistered.nb_buf_ref = 0; + + if (h->sei.picture_timing.timecode_cnt > 0) { + uint32_t *tc_sd; + char tcbuf[AV_TIMECODE_STR_SIZE]; + + AVFrameSideData *tcside = av_frame_new_side_data(out, AV_FRAME_DATA_S12M_TIMECODE, sizeof(uint32_t)*4); if (!tcside) @@ -1303,33 +1318,15 @@ static int h264_export_frame_props(H264Context *h) tc_sd[0] = h->sei.picture_timing.timecode_cnt; for (int i = 0; i < tc_sd[0]; i++) { - uint32_t frames; + int drop = h->sei.picture_timing.timecode[i].dropframe; + int hh = h->sei.picture_timing.timecode[i].hours; + int mm = h->sei.picture_timing.timecode[i].minutes; + int ss = h->sei.picture_timing.timecode[i].seconds; + int ff = h->sei.picture_timing.timecode[i].frame; - /* For SMPTE 12-M timecodes, frame count is a special case if > 30 FPS. - See SMPTE ST 12-1:2014 Sec 12.1 for more info. */ - if (av_cmp_q(h->avctx->framerate, (AVRational) {30, 1}) == 1) { - frames = h->sei.picture_timing.timecode[i].frame / 2; - if (h->sei.picture_timing.timecode[i].frame % 2 == 1) { - if (av_cmp_q(h->avctx->framerate, (AVRational) {50, 1}) == 0) - tc |= (1 << 7); - else - tc |= (1 << 23); - } - } else { - frames = h->sei.picture_timing.timecode[i].frame; - } - - tc |= h->sei.picture_timing.timecode[i].dropframe << 30; - tc |= (frames / 10) << 28; - tc |= (frames % 10) << 24; - tc |= (h->sei.picture_timing.timecode[i].seconds / 10) << 20; - tc |= (h->sei.picture_timing.timecode[i].seconds % 10) << 16; - tc |= (h->sei.picture_timing.timecode[i].minutes / 10) << 12; - tc |= (h->sei.picture_timing.timecode[i].minutes % 10) << 8; - tc |= (h->sei.picture_timing.timecode[i].hours / 10) << 4; - tc |= (h->sei.picture_timing.timecode[i].hours % 10); - - tc_sd[i + 1] = tc; + tc_sd[i + 1] = av_timecode_get_smpte(h->avctx->framerate, drop, hh, mm, ss, ff); + av_timecode_make_smpte_tc_string(tcbuf, tc_sd[i + 1], 0); + av_dict_set(&out->metadata, "timecode", tcbuf, 0); } h->sei.picture_timing.timecode_cnt = 0; } diff --git a/externals/ffmpeg/libavcodec/h264dec.c b/externals/ffmpeg/libavcodec/h264dec.c index 6270ea80d..46495d586 100755 --- a/externals/ffmpeg/libavcodec/h264dec.c +++ b/externals/ffmpeg/libavcodec/h264dec.c @@ -182,40 +182,27 @@ int ff_h264_alloc_tables(H264Context *h) { const int big_mb_num = h->mb_stride * (h->mb_height + 1); const int row_mb_num = 2*h->mb_stride*FFMAX(h->nb_slice_ctx, 1); + const int st_size = big_mb_num + h->mb_stride; int x, y; - FF_ALLOCZ_ARRAY_OR_GOTO(h->avctx, h->intra4x4_pred_mode, - row_mb_num, 8 * sizeof(uint8_t), fail) + if (!FF_ALLOCZ_TYPED_ARRAY(h->intra4x4_pred_mode, row_mb_num * 8) || + !FF_ALLOCZ_TYPED_ARRAY(h->non_zero_count, big_mb_num) || + !FF_ALLOCZ_TYPED_ARRAY(h->slice_table_base, st_size) || + !FF_ALLOCZ_TYPED_ARRAY(h->cbp_table, big_mb_num) || + !FF_ALLOCZ_TYPED_ARRAY(h->chroma_pred_mode_table, big_mb_num) || + !FF_ALLOCZ_TYPED_ARRAY(h->mvd_table[0], row_mb_num * 8) || + !FF_ALLOCZ_TYPED_ARRAY(h->mvd_table[1], row_mb_num * 8) || + !FF_ALLOCZ_TYPED_ARRAY(h->direct_table, big_mb_num * 4) || + !FF_ALLOCZ_TYPED_ARRAY(h->list_counts, big_mb_num) || + !FF_ALLOCZ_TYPED_ARRAY(h->mb2b_xy, big_mb_num) || + !FF_ALLOCZ_TYPED_ARRAY(h->mb2br_xy, big_mb_num)) + return AVERROR(ENOMEM); h->slice_ctx[0].intra4x4_pred_mode = h->intra4x4_pred_mode; - - FF_ALLOCZ_OR_GOTO(h->avctx, h->non_zero_count, - big_mb_num * 48 * sizeof(uint8_t), fail) - FF_ALLOCZ_OR_GOTO(h->avctx, h->slice_table_base, - (big_mb_num + h->mb_stride) * sizeof(*h->slice_table_base), fail) - FF_ALLOCZ_OR_GOTO(h->avctx, h->cbp_table, - big_mb_num * sizeof(uint16_t), fail) - FF_ALLOCZ_OR_GOTO(h->avctx, h->chroma_pred_mode_table, - big_mb_num * sizeof(uint8_t), fail) - FF_ALLOCZ_ARRAY_OR_GOTO(h->avctx, h->mvd_table[0], - row_mb_num, 16 * sizeof(uint8_t), fail); - FF_ALLOCZ_ARRAY_OR_GOTO(h->avctx, h->mvd_table[1], - row_mb_num, 16 * sizeof(uint8_t), fail); h->slice_ctx[0].mvd_table[0] = h->mvd_table[0]; h->slice_ctx[0].mvd_table[1] = h->mvd_table[1]; - - FF_ALLOCZ_OR_GOTO(h->avctx, h->direct_table, - 4 * big_mb_num * sizeof(uint8_t), fail); - FF_ALLOCZ_OR_GOTO(h->avctx, h->list_counts, - big_mb_num * sizeof(uint8_t), fail) - memset(h->slice_table_base, -1, - (big_mb_num + h->mb_stride) * sizeof(*h->slice_table_base)); + st_size * sizeof(*h->slice_table_base)); h->slice_table = h->slice_table_base + h->mb_stride * 2 + 1; - - FF_ALLOCZ_OR_GOTO(h->avctx, h->mb2b_xy, - big_mb_num * sizeof(uint32_t), fail); - FF_ALLOCZ_OR_GOTO(h->avctx, h->mb2br_xy, - big_mb_num * sizeof(uint32_t), fail); for (y = 0; y < h->mb_height; y++) for (x = 0; x < h->mb_width; x++) { const int mb_xy = x + y * h->mb_stride; @@ -226,9 +213,6 @@ int ff_h264_alloc_tables(H264Context *h) } return 0; - -fail: - return AVERROR(ENOMEM); } /** @@ -253,8 +237,8 @@ int ff_h264_slice_context_init(H264Context *h, H264SliceContext *sl) if (sl != h->slice_ctx) { memset(er, 0, sizeof(*er)); - } else - if (CONFIG_ERROR_RESILIENCE) { + } else if (CONFIG_ERROR_RESILIENCE) { + const int er_size = h->mb_height * h->mb_stride * (4*sizeof(int) + 1); /* init ER */ er->avctx = h->avctx; @@ -269,8 +253,11 @@ int ff_h264_slice_context_init(H264Context *h, H264SliceContext *sl) er->b8_stride = h->mb_width * 2 + 1; // error resilience code looks cleaner with this - FF_ALLOCZ_OR_GOTO(h->avctx, er->mb_index2xy, - (h->mb_num + 1) * sizeof(int), fail); + if (!FF_ALLOCZ_TYPED_ARRAY(er->mb_index2xy, h->mb_num + 1) || + !FF_ALLOCZ_TYPED_ARRAY(er->error_status_table, mb_array_size) || + !FF_ALLOCZ_TYPED_ARRAY(er->er_temp_buffer, er_size) || + !FF_ALLOCZ_TYPED_ARRAY(sl->dc_val_base, yc_size)) + return AVERROR(ENOMEM); // ff_h264_free_tables will clean up for us for (y = 0; y < h->mb_height; y++) for (x = 0; x < h->mb_width; x++) @@ -278,15 +265,6 @@ int ff_h264_slice_context_init(H264Context *h, H264SliceContext *sl) er->mb_index2xy[h->mb_height * h->mb_width] = (h->mb_height - 1) * h->mb_stride + h->mb_width; - - FF_ALLOCZ_OR_GOTO(h->avctx, er->error_status_table, - mb_array_size * sizeof(uint8_t), fail); - - FF_ALLOC_OR_GOTO(h->avctx, er->er_temp_buffer, - h->mb_height * h->mb_stride * (4*sizeof(int) + 1), fail); - - FF_ALLOCZ_OR_GOTO(h->avctx, sl->dc_val_base, - yc_size * sizeof(int16_t), fail); er->dc_val[0] = sl->dc_val_base + h->mb_width * 2 + 2; er->dc_val[1] = sl->dc_val_base + y_size + h->mb_stride + 1; er->dc_val[2] = er->dc_val[1] + c_size; @@ -295,9 +273,6 @@ int ff_h264_slice_context_init(H264Context *h, H264SliceContext *sl) } return 0; - -fail: - return AVERROR(ENOMEM); // ff_h264_free_tables will clean up for us } static int h264_init_context(AVCodecContext *avctx, H264Context *h) @@ -872,7 +847,7 @@ fail: return ret; } -static int is_extra(const uint8_t *buf, int buf_size) +static int is_avcc_extradata(const uint8_t *buf, int buf_size) { int cnt= buf[5]&0x1f; const uint8_t *p= buf+6; @@ -999,16 +974,15 @@ static int h264_decode_frame(AVCodecContext *avctx, void *data, if (buf_size == 0) return send_next_delayed_frame(h, pict, got_frame, 0); - if (h->is_avc && av_packet_get_side_data(avpkt, AV_PKT_DATA_NEW_EXTRADATA, NULL)) { + if (av_packet_get_side_data(avpkt, AV_PKT_DATA_NEW_EXTRADATA, NULL)) { int side_size; uint8_t *side = av_packet_get_side_data(avpkt, AV_PKT_DATA_NEW_EXTRADATA, &side_size); - if (is_extra(side, side_size)) - ff_h264_decode_extradata(side, side_size, - &h->ps, &h->is_avc, &h->nal_length_size, - avctx->err_recognition, avctx); + ff_h264_decode_extradata(side, side_size, + &h->ps, &h->is_avc, &h->nal_length_size, + avctx->err_recognition, avctx); } if (h->is_avc && buf_size >= 9 && buf[0]==1 && buf[2]==0 && (buf[4]&0xFC)==0xFC) { - if (is_extra(buf, buf_size)) + if (is_avcc_extradata(buf, buf_size)) return ff_h264_decode_extradata(buf, buf_size, &h->ps, &h->is_avc, &h->nal_length_size, avctx->err_recognition, avctx); diff --git a/externals/ffmpeg/libavcodec/h265_metadata_bsf.c b/externals/ffmpeg/libavcodec/h265_metadata_bsf.c index 749456157..504a75dac 100755 --- a/externals/ffmpeg/libavcodec/h265_metadata_bsf.c +++ b/externals/ffmpeg/libavcodec/h265_metadata_bsf.c @@ -40,7 +40,8 @@ enum { typedef struct H265MetadataContext { const AVClass *class; - CodedBitstreamContext *cbc; + CodedBitstreamContext *input; + CodedBitstreamContext *output; CodedBitstreamFragment access_unit; H265RawAUD aud_nal; @@ -350,7 +351,7 @@ static int h265_metadata_update_side_data(AVBSFContext *bsf, AVPacket *pkt) if (!side_data_size) return 0; - err = ff_cbs_read(ctx->cbc, au, side_data, side_data_size); + err = ff_cbs_read(ctx->input, au, side_data, side_data_size); if (err < 0) { av_log(bsf, AV_LOG_ERROR, "Failed to read extradata from packet side data.\n"); return err; @@ -372,7 +373,7 @@ static int h265_metadata_update_side_data(AVBSFContext *bsf, AVPacket *pkt) } } - err = ff_cbs_write_fragment_data(ctx->cbc, au); + err = ff_cbs_write_fragment_data(ctx->output, au); if (err < 0) { av_log(bsf, AV_LOG_ERROR, "Failed to write extradata into packet side data.\n"); return err; @@ -383,7 +384,7 @@ static int h265_metadata_update_side_data(AVBSFContext *bsf, AVPacket *pkt) return AVERROR(ENOMEM); memcpy(side_data, au->data, au->data_size); - ff_cbs_fragment_reset(ctx->cbc, au); + ff_cbs_fragment_reset(au); return 0; } @@ -402,7 +403,7 @@ static int h265_metadata_filter(AVBSFContext *bsf, AVPacket *pkt) if (err < 0) goto fail; - err = ff_cbs_read_packet(ctx->cbc, au, pkt); + err = ff_cbs_read_packet(ctx->input, au, pkt); if (err < 0) { av_log(bsf, AV_LOG_ERROR, "Failed to read packet.\n"); goto fail; @@ -417,7 +418,7 @@ static int h265_metadata_filter(AVBSFContext *bsf, AVPacket *pkt) // If an AUD is present, it must be the first NAL unit. if (au->units[0].type == HEVC_NAL_AUD) { if (ctx->aud == REMOVE) - ff_cbs_delete_unit(ctx->cbc, au, 0); + ff_cbs_delete_unit(au, 0); } else { if (ctx->aud == INSERT) { H265RawAUD *aud = &ctx->aud_nal; @@ -449,8 +450,7 @@ static int h265_metadata_filter(AVBSFContext *bsf, AVPacket *pkt) }; aud->pic_type = pic_type; - err = ff_cbs_insert_unit_content(ctx->cbc, au, - 0, HEVC_NAL_AUD, aud, NULL); + err = ff_cbs_insert_unit_content(au, 0, HEVC_NAL_AUD, aud, NULL); if (err < 0) { av_log(bsf, AV_LOG_ERROR, "Failed to insert AUD.\n"); goto fail; @@ -474,7 +474,7 @@ static int h265_metadata_filter(AVBSFContext *bsf, AVPacket *pkt) } } - err = ff_cbs_write_packet(ctx->cbc, pkt, au); + err = ff_cbs_write_packet(ctx->output, pkt, au); if (err < 0) { av_log(bsf, AV_LOG_ERROR, "Failed to write packet.\n"); goto fail; @@ -482,7 +482,7 @@ static int h265_metadata_filter(AVBSFContext *bsf, AVPacket *pkt) err = 0; fail: - ff_cbs_fragment_reset(ctx->cbc, au); + ff_cbs_fragment_reset(au); if (err < 0) av_packet_unref(pkt); @@ -496,12 +496,15 @@ static int h265_metadata_init(AVBSFContext *bsf) CodedBitstreamFragment *au = &ctx->access_unit; int err, i; - err = ff_cbs_init(&ctx->cbc, AV_CODEC_ID_HEVC, bsf); + err = ff_cbs_init(&ctx->input, AV_CODEC_ID_HEVC, bsf); + if (err < 0) + return err; + err = ff_cbs_init(&ctx->output, AV_CODEC_ID_HEVC, bsf); if (err < 0) return err; if (bsf->par_in->extradata) { - err = ff_cbs_read_extradata(ctx->cbc, au, bsf->par_in); + err = ff_cbs_read_extradata(ctx->input, au, bsf->par_in); if (err < 0) { av_log(bsf, AV_LOG_ERROR, "Failed to read extradata.\n"); goto fail; @@ -523,7 +526,7 @@ static int h265_metadata_init(AVBSFContext *bsf) } } - err = ff_cbs_write_extradata(ctx->cbc, bsf->par_out, au); + err = ff_cbs_write_extradata(ctx->output, bsf->par_out, au); if (err < 0) { av_log(bsf, AV_LOG_ERROR, "Failed to write extradata.\n"); goto fail; @@ -532,7 +535,7 @@ static int h265_metadata_init(AVBSFContext *bsf) err = 0; fail: - ff_cbs_fragment_reset(ctx->cbc, au); + ff_cbs_fragment_reset(au); return err; } @@ -540,8 +543,9 @@ static void h265_metadata_close(AVBSFContext *bsf) { H265MetadataContext *ctx = bsf->priv_data; - ff_cbs_fragment_free(ctx->cbc, &ctx->access_unit); - ff_cbs_close(&ctx->cbc); + ff_cbs_fragment_free(&ctx->access_unit); + ff_cbs_close(&ctx->input); + ff_cbs_close(&ctx->output); } #define OFFSET(x) offsetof(H265MetadataContext, x) diff --git a/externals/ffmpeg/libavcodec/hca_data.h b/externals/ffmpeg/libavcodec/hca_data.h index 80b4a794d..7093221c2 100755 --- a/externals/ffmpeg/libavcodec/hca_data.h +++ b/externals/ffmpeg/libavcodec/hca_data.h @@ -86,18 +86,18 @@ static const float intensity_ratio_table[] = { 2.0, 1.85714, 1.71429, 1.57143, 1.42857, 1.28571, 1.14286, 1.0, 0.857143, 0.714286, 0.571429, 0.428571, 0.285714, 0.142857, 0.0, 0.0, - 0, 1.87066e-08, 2.49253e-08, 3.32113e-08, 4.42518e-08, 5.89626e-08, 7.85637e-08, 1.04681e-07, +}; + +static const float scale_conversion_table[] = +{ + 0, 0, 1.87066e-08, 2.49253e-08, 3.32113e-08, 4.42518e-08, 5.89626e-08, 7.85637e-08, 1.04681e-07, 1.3948e-07, 1.85848e-07, 2.4763e-07, 3.2995e-07, 4.39636e-07, 5.85785e-07, 7.80519e-07, 1.03999e-06, 1.38572e-06, 1.84637e-06, 2.46017e-06, 3.27801e-06, 4.36772e-06, 5.8197e-06, 7.75435e-06, 1.03321e-05, 1.37669e-05, 1.83435e-05, 2.44414e-05, 3.25665e-05, 4.33927e-05, 5.78179e-05, 7.70384e-05, 0.000102648, 0.000136772, 0.00018224, 0.000242822, 0.000323544, 0.000431101, 0.000574413, 0.000765366, 0.0010198, 0.00135881, 0.00181053, 0.0024124, 0.00321437, 0.00428293, 0.00570671, 0.00760381, 0.0101316, 0.0134996, 0.0179873, 0.0239669, 0.0319343, 0.0425503, 0.0566954, 0.0755428, 0.100656, - 0.134117, 0.178702, 0.238108, 0.317263, 0.422731, 0.563261, 0.750507, 0.0, -}; - -static const float scale_conversion_table[] = -{ + 0.134117, 0.178702, 0.238108, 0.317263, 0.422731, 0.563261, 0.750507, 1.0, 1.33243, 1.77538, 2.36557, 3.15196, 4.19978, 5.59592, 7.45618, 9.93486, 13.2375, 17.6381, 23.5016, 31.3143, 41.7242, 55.5947, 74.0762, 98.7015, 131.513, 175.232, 233.485, 311.103, 414.524, 552.326, 735.937, @@ -108,6 +108,8 @@ static const float scale_conversion_table[] = 9.55285e+06, 1.27285e+07, 1.69599e+07, 2.25979e+07, 3.01102e+07, 4.01198e+07, 5.3457e+07, 0, }; +static const int scale_conv_bias = 64; + static const float dequantizer_scaling_table[] = { 1.58838e-07, 2.11641e-07, 2.81998e-07, 3.75743e-07, 5.00652e-07, 6.67085e-07, 8.88846e-07, 1.18433e-06, diff --git a/externals/ffmpeg/libavcodec/hcadec.c b/externals/ffmpeg/libavcodec/hcadec.c index f46ed699d..11cb15727 100755 --- a/externals/ffmpeg/libavcodec/hcadec.c +++ b/externals/ffmpeg/libavcodec/hcadec.c @@ -267,7 +267,7 @@ static void apply_intensity_stereo(HCAContext *s, ChannelContext *ch1, ChannelCo int index, unsigned band_count, unsigned base_band_count, unsigned stereo_band_count) { - float ratio_l = intensity_ratio_table[ch1->intensity[index]]; + float ratio_l = intensity_ratio_table[ch2->intensity[index]]; float ratio_r = ratio_l - 2.0f; float *c1 = &ch1->imdct_in[base_band_count]; float *c2 = &ch2->imdct_in[base_band_count]; @@ -291,7 +291,8 @@ static void reconstruct_hfr(HCAContext *s, ChannelContext *ch, for (int i = 0, k = start_band, l = start_band - 1; i < hfr_group_count; i++){ for (int j = 0; j < bands_per_hfr_group && k < total_band_count && l >= 0; j++, k++, l--){ - ch->imdct_in[k] = scale_conversion_table[ (ch->hfr_scale[i] - ch->scale_factors[l]) & 63 ] * ch->imdct_in[l]; + ch->imdct_in[k] = scale_conversion_table[ scale_conv_bias + + av_clip_intp2(ch->hfr_scale[i] - ch->scale_factors[l], 6) ] * ch->imdct_in[l]; } } diff --git a/externals/ffmpeg/libavcodec/hevc_sei.c b/externals/ffmpeg/libavcodec/hevc_sei.c index 60570690c..a4ec65dc1 100755 --- a/externals/ffmpeg/libavcodec/hevc_sei.c +++ b/externals/ffmpeg/libavcodec/hevc_sei.c @@ -213,6 +213,32 @@ static int decode_registered_user_data_closed_caption(HEVCSEIA53Caption *s, GetB return 0; } +static int decode_nal_sei_user_data_unregistered(HEVCSEIUnregistered *s, GetBitContext *gb, + int size) +{ + AVBufferRef *buf_ref, **tmp; + + if (size < 16 || size >= INT_MAX - 1) + return AVERROR_INVALIDDATA; + + tmp = av_realloc_array(s->buf_ref, s->nb_buf_ref + 1, sizeof(*s->buf_ref)); + if (!tmp) + return AVERROR(ENOMEM); + s->buf_ref = tmp; + + buf_ref = av_buffer_alloc(size + 1); + if (!buf_ref) + return AVERROR(ENOMEM); + + for (int i = 0; i < size; i++) + buf_ref->data[i] = get_bits(gb, 8); + buf_ref->data[size] = 0; + buf_ref->size = size; + s->buf_ref[s->nb_buf_ref++] = buf_ref; + + return 0; +} + static int decode_nal_sei_user_data_registered_itu_t_t35(HEVCSEI *s, GetBitContext *gb, int size) { @@ -280,6 +306,53 @@ static int decode_nal_sei_alternative_transfer(HEVCSEIAlternativeTransfer *s, Ge return 0; } +static int decode_nal_sei_timecode(HEVCSEITimeCode *s, GetBitContext *gb) +{ + s->num_clock_ts = get_bits(gb, 2); + + for (int i = 0; i < s->num_clock_ts; i++) { + s->clock_timestamp_flag[i] = get_bits(gb, 1); + + if (s->clock_timestamp_flag[i]) { + s->units_field_based_flag[i] = get_bits(gb, 1); + s->counting_type[i] = get_bits(gb, 5); + s->full_timestamp_flag[i] = get_bits(gb, 1); + s->discontinuity_flag[i] = get_bits(gb, 1); + s->cnt_dropped_flag[i] = get_bits(gb, 1); + + s->n_frames[i] = get_bits(gb, 9); + + if (s->full_timestamp_flag[i]) { + s->seconds_value[i] = av_clip(get_bits(gb, 6), 0, 59); + s->minutes_value[i] = av_clip(get_bits(gb, 6), 0, 59); + s->hours_value[i] = av_clip(get_bits(gb, 5), 0, 23); + } else { + s->seconds_flag[i] = get_bits(gb, 1); + if (s->seconds_flag[i]) { + s->seconds_value[i] = av_clip(get_bits(gb, 6), 0, 59); + s->minutes_flag[i] = get_bits(gb, 1); + if (s->minutes_flag[i]) { + s->minutes_value[i] = av_clip(get_bits(gb, 6), 0, 59); + s->hours_flag[i] = get_bits(gb, 1); + if (s->hours_flag[i]) { + s->hours_value[i] = av_clip(get_bits(gb, 5), 0, 23); + } + } + } + } + + s->time_offset_length[i] = get_bits(gb, 5); + if (s->time_offset_length[i] > 0) { + s->time_offset_value[i] = get_bits(gb, s->time_offset_length[i]); + } + } + } + + s->present = 1; + return 0; +} + + static int decode_nal_sei_prefix(GetBitContext *gb, void *logctx, HEVCSEI *s, const HEVCParamSets *ps, int type, int size) { @@ -300,8 +373,12 @@ static int decode_nal_sei_prefix(GetBitContext *gb, void *logctx, HEVCSEI *s, return decode_nal_sei_active_parameter_sets(s, gb, logctx); case HEVC_SEI_TYPE_USER_DATA_REGISTERED_ITU_T_T35: return decode_nal_sei_user_data_registered_itu_t_t35(s, gb, size); + case HEVC_SEI_TYPE_USER_DATA_UNREGISTERED: + return decode_nal_sei_user_data_unregistered(&s->unregistered, gb, size); case HEVC_SEI_TYPE_ALTERNATIVE_TRANSFER_CHARACTERISTICS: return decode_nal_sei_alternative_transfer(&s->alternative_transfer, gb); + case HEVC_SEI_TYPE_TIME_CODE: + return decode_nal_sei_timecode(&s->timecode, gb); default: av_log(logctx, AV_LOG_DEBUG, "Skipped PREFIX SEI %d\n", type); skip_bits_long(gb, 8 * size); @@ -371,4 +448,9 @@ int ff_hevc_decode_nal_sei(GetBitContext *gb, void *logctx, HEVCSEI *s, void ff_hevc_reset_sei(HEVCSEI *s) { av_buffer_unref(&s->a53_caption.buf_ref); + + for (int i = 0; i < s->unregistered.nb_buf_ref; i++) + av_buffer_unref(&s->unregistered.buf_ref[i]); + s->unregistered.nb_buf_ref = 0; + av_freep(&s->unregistered.buf_ref); } diff --git a/externals/ffmpeg/libavcodec/hevc_sei.h b/externals/ffmpeg/libavcodec/hevc_sei.h index a44ccca7f..5ee7a4796 100755 --- a/externals/ffmpeg/libavcodec/hevc_sei.h +++ b/externals/ffmpeg/libavcodec/hevc_sei.h @@ -91,6 +91,11 @@ typedef struct HEVCSEIA53Caption { AVBufferRef *buf_ref; } HEVCSEIA53Caption; +typedef struct HEVCSEIUnregistered { + AVBufferRef **buf_ref; + int nb_buf_ref; +} HEVCSEIUnregistered; + typedef struct HEVCSEIMasteringDisplay { int present; uint16_t display_primaries[3][2]; @@ -110,16 +115,38 @@ typedef struct HEVCSEIAlternativeTransfer { int preferred_transfer_characteristics; } HEVCSEIAlternativeTransfer; +typedef struct HEVCSEITimeCode { + int present; + uint8_t num_clock_ts; + uint8_t clock_timestamp_flag[3]; + uint8_t units_field_based_flag[3]; + uint8_t counting_type[3]; + uint8_t full_timestamp_flag[3]; + uint8_t discontinuity_flag[3]; + uint8_t cnt_dropped_flag[3]; + uint16_t n_frames[3]; + uint8_t seconds_value[3]; + uint8_t minutes_value[3]; + uint8_t hours_value[3]; + uint8_t seconds_flag[3]; + uint8_t minutes_flag[3]; + uint8_t hours_flag[3]; + uint8_t time_offset_length[3]; + int32_t time_offset_value[3]; +} HEVCSEITimeCode; + typedef struct HEVCSEI { HEVCSEIPictureHash picture_hash; HEVCSEIFramePacking frame_packing; HEVCSEIDisplayOrientation display_orientation; HEVCSEIPictureTiming picture_timing; HEVCSEIA53Caption a53_caption; + HEVCSEIUnregistered unregistered; HEVCSEIMasteringDisplay mastering_display; HEVCSEIContentLight content_light; int active_seq_parameter_set_id; HEVCSEIAlternativeTransfer alternative_transfer; + HEVCSEITimeCode timecode; } HEVCSEI; struct HEVCParamSets; diff --git a/externals/ffmpeg/libavcodec/hevcdec.c b/externals/ffmpeg/libavcodec/hevcdec.c index 0772608a3..b77df8d89 100755 --- a/externals/ffmpeg/libavcodec/hevcdec.c +++ b/externals/ffmpeg/libavcodec/hevcdec.c @@ -32,6 +32,7 @@ #include "libavutil/opt.h" #include "libavutil/pixdesc.h" #include "libavutil/stereo3d.h" +#include "libavutil/timecode.h" #include "bswapdsp.h" #include "bytestream.h" @@ -348,6 +349,15 @@ static void export_stream_params(HEVCContext *s, const HEVCSPS *sps) avctx->colorspace = AVCOL_SPC_UNSPECIFIED; } + avctx->chroma_sample_location = AVCHROMA_LOC_UNSPECIFIED; + if (sps->chroma_format_idc == 1) { + if (sps->vui.chroma_loc_info_present_flag) { + if (sps->vui.chroma_sample_loc_type_top_field <= 5) + avctx->chroma_sample_location = sps->vui.chroma_sample_loc_type_top_field + 1; + } else + avctx->chroma_sample_location = AVCHROMA_LOC_LEFT; + } + if (vps->vps_timing_info_present_flag) { num = vps->vps_num_units_in_tick; den = vps->vps_time_scale; @@ -414,6 +424,9 @@ static enum AVPixelFormat get_format(HEVCContext *s, const HEVCSPS *sps) #if CONFIG_HEVC_VIDEOTOOLBOX_HWACCEL *fmt++ = AV_PIX_FMT_VIDEOTOOLBOX; #endif +#if CONFIG_HEVC_VDPAU_HWACCEL + *fmt++ = AV_PIX_FMT_VDPAU; +#endif #if CONFIG_HEVC_NVDEC_HWACCEL *fmt++ = AV_PIX_FMT_CUDA; #endif @@ -435,6 +448,9 @@ static enum AVPixelFormat get_format(HEVCContext *s, const HEVCSPS *sps) case AV_PIX_FMT_YUV420P12: case AV_PIX_FMT_YUV444P10: case AV_PIX_FMT_YUV444P12: +#if CONFIG_HEVC_VDPAU_HWACCEL + *fmt++ = AV_PIX_FMT_VDPAU; +#endif #if CONFIG_HEVC_NVDEC_HWACCEL *fmt++ = AV_PIX_FMT_CUDA; #endif @@ -2794,6 +2810,46 @@ static int set_side_data(HEVCContext *s) s->avctx->properties |= FF_CODEC_PROPERTY_CLOSED_CAPTIONS; } + for (int i = 0; i < s->sei.unregistered.nb_buf_ref; i++) { + HEVCSEIUnregistered *unreg = &s->sei.unregistered; + + if (unreg->buf_ref[i]) { + AVFrameSideData *sd = av_frame_new_side_data_from_buf(out, + AV_FRAME_DATA_SEI_UNREGISTERED, + unreg->buf_ref[i]); + if (!sd) + av_buffer_unref(&unreg->buf_ref[i]); + unreg->buf_ref[i] = NULL; + } + } + s->sei.unregistered.nb_buf_ref = 0; + + if (s->sei.timecode.present) { + uint32_t *tc_sd; + char tcbuf[AV_TIMECODE_STR_SIZE]; + AVFrameSideData *tcside = av_frame_new_side_data(out, AV_FRAME_DATA_S12M_TIMECODE, + sizeof(uint32_t) * 4); + if (!tcside) + return AVERROR(ENOMEM); + + tc_sd = (uint32_t*)tcside->data; + tc_sd[0] = s->sei.timecode.num_clock_ts; + + for (int i = 0; i < tc_sd[0]; i++) { + int drop = s->sei.timecode.cnt_dropped_flag[i]; + int hh = s->sei.timecode.hours_value[i]; + int mm = s->sei.timecode.minutes_value[i]; + int ss = s->sei.timecode.seconds_value[i]; + int ff = s->sei.timecode.n_frames[i]; + + tc_sd[i + 1] = av_timecode_get_smpte(s->avctx->framerate, drop, hh, mm, ss, ff); + av_timecode_make_smpte_tc_string(tcbuf, tc_sd[i + 1], 0); + av_dict_set(&out->metadata, "timecode", tcbuf, 0); + } + + s->sei.timecode.num_clock_ts = 0; + } + return 0; } diff --git a/externals/ffmpeg/libavcodec/iirfilter.c b/externals/ffmpeg/libavcodec/iirfilter.c index b20251582..cd5bbc943 100755 --- a/externals/ffmpeg/libavcodec/iirfilter.c +++ b/externals/ffmpeg/libavcodec/iirfilter.c @@ -171,12 +171,10 @@ av_cold struct FFIIRFilterCoeffs *ff_iir_filter_init_coeffs(void *avc, if (order <= 0 || order > MAXORDER || cutoff_ratio >= 1.0) return NULL; - FF_ALLOCZ_OR_GOTO(avc, c, sizeof(FFIIRFilterCoeffs), - init_fail); - FF_ALLOC_OR_GOTO(avc, c->cx, sizeof(c->cx[0]) * ((order >> 1) + 1), - init_fail); - FF_ALLOC_OR_GOTO(avc, c->cy, sizeof(c->cy[0]) * order, - init_fail); + if (!(c = av_mallocz(sizeof(*c))) || + !(c->cx = av_malloc (sizeof(c->cx[0]) * ((order >> 1) + 1))) || + !(c->cy = av_malloc (sizeof(c->cy[0]) * order))) + goto free; c->order = order; switch (filt_type) { @@ -190,13 +188,12 @@ av_cold struct FFIIRFilterCoeffs *ff_iir_filter_init_coeffs(void *avc, break; default: av_log(avc, AV_LOG_ERROR, "filter type is not currently implemented\n"); - goto init_fail; + goto free; } if (!ret) return c; - -init_fail: +free: ff_iir_filter_free_coeffsp(&c); return NULL; } diff --git a/externals/ffmpeg/libavcodec/internal.h b/externals/ffmpeg/libavcodec/internal.h index 0a72a0e37..0a1c0a17e 100755 --- a/externals/ffmpeg/libavcodec/internal.h +++ b/externals/ffmpeg/libavcodec/internal.h @@ -110,9 +110,12 @@ typedef struct DecodeSimpleContext { AVPacket *in_pkt; - AVFrame *out_frame; } DecodeSimpleContext; +typedef struct EncodeSimpleContext { + AVFrame *in_frame; +} EncodeSimpleContext; + typedef struct AVCodecInternal { /** * Whether the parent AVCodecContext is a copy of the context which had @@ -151,6 +154,8 @@ typedef struct AVCodecInternal { void *frame_thread_encoder; + EncodeSimpleContext es; + /** * Number of audio samples to skip at the start of the next decoded frame */ @@ -170,7 +175,6 @@ typedef struct AVCodecInternal { * buffers for using new encode/decode API through legacy API */ AVPacket *buffer_pkt; - int buffer_pkt_valid; // encoding: packet without data can be valid AVFrame *buffer_frame; int draining_done; int compat_decode_warned; @@ -181,6 +185,7 @@ typedef struct AVCodecInternal { * of the packet (that should be submitted in the next decode call */ size_t compat_decode_partial_size; AVFrame *compat_decode_frame; + AVPacket *compat_encode_packet; int showed_multi_packet_warning; @@ -373,6 +378,21 @@ AVCPBProperties *ff_add_cpb_side_data(AVCodecContext *avctx); int ff_alloc_a53_sei(const AVFrame *frame, size_t prefix_len, void **data, size_t *sei_size); +/** + * Check AVFrame for S12M timecode side data and allocate and fill TC SEI message with timecode info + * + * @param frame Raw frame to get S12M timecode side data from + * @param prefix_len Number of bytes to allocate before SEI message + * @param data Pointer to a variable to store allocated memory + * Upon return the variable will hold NULL on error or if frame has no S12M timecode info. + * Otherwise it will point to prefix_len uninitialized bytes followed by + * *sei_size SEI message + * @param sei_size Pointer to a variable to store generated SEI message length + * @return Zero on success, negative error code on failure + */ +int ff_alloc_timecode_sei(const AVFrame *frame, size_t prefix_len, + void **data, size_t *sei_size); + /** * Get an estimated video bitrate based on frame size, frame rate and coded * bits per pixel. diff --git a/externals/ffmpeg/libavcodec/jpeg2000.c b/externals/ffmpeg/libavcodec/jpeg2000.c index 73206d17f..1aca31ffa 100755 --- a/externals/ffmpeg/libavcodec/jpeg2000.c +++ b/externals/ffmpeg/libavcodec/jpeg2000.c @@ -509,9 +509,6 @@ int ff_jpeg2000_init_component(Jpeg2000Component *comp, // update precincts size: 2^n value reslevel->log2_prec_width = codsty->log2_prec_widths[reslevelno]; reslevel->log2_prec_height = codsty->log2_prec_heights[reslevelno]; - if (!reslevel->log2_prec_width || !reslevel->log2_prec_height) { - return AVERROR_INVALIDDATA; - } /* Number of bands for each resolution level */ if (reslevelno == 0) diff --git a/externals/ffmpeg/libavcodec/jpeg2000.h b/externals/ffmpeg/libavcodec/jpeg2000.h index 0f8271698..27df43786 100755 --- a/externals/ffmpeg/libavcodec/jpeg2000.h +++ b/externals/ffmpeg/libavcodec/jpeg2000.h @@ -144,6 +144,7 @@ typedef struct Jpeg2000CodingStyle { uint8_t prog_order; // progression order uint8_t log2_prec_widths[JPEG2000_MAX_RESLEVELS]; // precincts size according resolution levels uint8_t log2_prec_heights[JPEG2000_MAX_RESLEVELS]; // TODO: initialize prec_size array with 0? + uint8_t init; } Jpeg2000CodingStyle; typedef struct Jpeg2000QuantStyle { diff --git a/externals/ffmpeg/libavcodec/jpeg2000dec.c b/externals/ffmpeg/libavcodec/jpeg2000dec.c index ab36009a2..18a933077 100755 --- a/externals/ffmpeg/libavcodec/jpeg2000dec.c +++ b/externals/ffmpeg/libavcodec/jpeg2000dec.c @@ -269,6 +269,8 @@ static int get_siz(Jpeg2000DecoderContext *s) const enum AVPixelFormat *possible_fmts = NULL; int possible_fmts_nb = 0; int ret; + int o_dimx, o_dimy; //original image dimensions. + int dimx, dimy; if (bytestream2_get_bytes_left(&s->g) < 36) { av_log(s->avctx, AV_LOG_ERROR, "Insufficient space for SIZ\n"); @@ -286,10 +288,6 @@ static int get_siz(Jpeg2000DecoderContext *s) s->tile_offset_y = bytestream2_get_be32u(&s->g); // YT0Siz ncomponents = bytestream2_get_be16u(&s->g); // CSiz - if (s->image_offset_x || s->image_offset_y) { - avpriv_request_sample(s->avctx, "Support for image offsets"); - return AVERROR_PATCHWELCOME; - } if (av_image_check_size2(s->width, s->height, s->avctx->max_pixels, AV_PIX_FMT_NONE, 0, s->avctx)) { avpriv_request_sample(s->avctx, "Large Dimensions"); return AVERROR_PATCHWELCOME; @@ -371,11 +369,18 @@ static int get_siz(Jpeg2000DecoderContext *s) } /* compute image size with reduction factor */ - ret = ff_set_dimensions(s->avctx, - ff_jpeg2000_ceildivpow2(s->width - s->image_offset_x, - s->reduction_factor), - ff_jpeg2000_ceildivpow2(s->height - s->image_offset_y, - s->reduction_factor)); + o_dimx = ff_jpeg2000_ceildivpow2(s->width - s->image_offset_x, + s->reduction_factor); + o_dimy = ff_jpeg2000_ceildivpow2(s->height - s->image_offset_y, + s->reduction_factor); + dimx = ff_jpeg2000_ceildiv(o_dimx, s->cdx[0]); + dimy = ff_jpeg2000_ceildiv(o_dimy, s->cdy[0]); + for (i = 1; i < s->ncomponents; i++) { + dimx = FFMAX(dimx, ff_jpeg2000_ceildiv(o_dimx, s->cdx[i])); + dimy = FFMAX(dimy, ff_jpeg2000_ceildiv(o_dimy, s->cdy[i])); + } + + ret = ff_set_dimensions(s->avctx, dimx, dimy); if (ret < 0) return ret; @@ -427,6 +432,18 @@ static int get_siz(Jpeg2000DecoderContext *s) s->cdef[3] = 3; i = 0; } + } else if (ncomponents == 3 && s->precision == 8 && + s->cdx[0] == s->cdx[1] && s->cdx[0] == s->cdx[2] && + s->cdy[0] == s->cdy[1] && s->cdy[0] == s->cdy[2]) { + s->avctx->pix_fmt = AV_PIX_FMT_RGB24; + i = 0; + } else if (ncomponents == 2 && s->precision == 8 && + s->cdx[0] == s->cdx[1] && s->cdy[0] == s->cdy[1]) { + s->avctx->pix_fmt = AV_PIX_FMT_YA8; + i = 0; + } else if (ncomponents == 1 && s->precision == 8) { + s->avctx->pix_fmt = AV_PIX_FMT_GRAY8; + i = 0; } } @@ -558,7 +575,7 @@ static int get_cod(Jpeg2000DecoderContext *s, Jpeg2000CodingStyle *c, if ((ret = get_cox(s, &tmp)) < 0) return ret; - + tmp.init = 1; for (compno = 0; compno < s->ncomponents; compno++) if (!(properties[compno] & HAD_COC)) memcpy(c + compno, &tmp, sizeof(tmp)); @@ -596,6 +613,7 @@ static int get_coc(Jpeg2000DecoderContext *s, Jpeg2000CodingStyle *c, return ret; properties[compno] |= HAD_COC; + c->init = 1; return 0; } @@ -969,12 +987,11 @@ static int init_tile(Jpeg2000DecoderContext *s, int tileno) comp->coord_o[0][1] = tile->coord[0][1]; comp->coord_o[1][0] = tile->coord[1][0]; comp->coord_o[1][1] = tile->coord[1][1]; - if (compno) { - comp->coord_o[0][0] /= s->cdx[compno]; - comp->coord_o[0][1] /= s->cdx[compno]; - comp->coord_o[1][0] /= s->cdy[compno]; - comp->coord_o[1][1] /= s->cdy[compno]; - } + + comp->coord_o[0][0] = ff_jpeg2000_ceildiv(comp->coord_o[0][0], s->cdx[compno]); + comp->coord_o[0][1] = ff_jpeg2000_ceildiv(comp->coord_o[0][1], s->cdx[compno]); + comp->coord_o[1][0] = ff_jpeg2000_ceildiv(comp->coord_o[1][0], s->cdy[compno]); + comp->coord_o[1][1] = ff_jpeg2000_ceildiv(comp->coord_o[1][1], s->cdy[compno]); comp->coord[0][0] = ff_jpeg2000_ceildivpow2(comp->coord_o[0][0], s->reduction_factor); comp->coord[0][1] = ff_jpeg2000_ceildivpow2(comp->coord_o[0][1], s->reduction_factor); @@ -983,7 +1000,8 @@ static int init_tile(Jpeg2000DecoderContext *s, int tileno) if (!comp->roi_shift) comp->roi_shift = s->roi_shift[compno]; - + if (!codsty->init) + return AVERROR_INVALIDDATA; if (ret = ff_jpeg2000_init_component(comp, codsty, qntsty, s->cbps[compno], s->cdx[compno], s->cdy[compno], s->avctx)) @@ -1927,18 +1945,23 @@ static inline void tile_codeblocks(Jpeg2000DecoderContext *s, Jpeg2000Tile *tile float *datap = comp->f_data; \ int32_t *i_datap = comp->i_data; \ int cbps = s->cbps[compno]; \ - int w = tile->comp[compno].coord[0][1] - s->image_offset_x; \ + int w = tile->comp[compno].coord[0][1] - \ + ff_jpeg2000_ceildiv(s->image_offset_x, s->cdx[compno]); \ + int h = tile->comp[compno].coord[1][1] - \ + ff_jpeg2000_ceildiv(s->image_offset_y, s->cdy[compno]); \ int plane = 0; \ \ if (planar) \ plane = s->cdef[compno] ? s->cdef[compno]-1 : (s->ncomponents-1); \ \ - y = tile->comp[compno].coord[1][0] - s->image_offset_y / s->cdy[compno]; \ + y = tile->comp[compno].coord[1][0] - \ + ff_jpeg2000_ceildiv(s->image_offset_y, s->cdy[compno]); \ line = (PIXEL *)picture->data[plane] + y * (picture->linesize[plane] / sizeof(PIXEL));\ - for (; y < tile->comp[compno].coord[1][1] - s->image_offset_y; y++) { \ + for (; y < h; y++) { \ PIXEL *dst; \ \ - x = tile->comp[compno].coord[0][0] - s->image_offset_x / s->cdx[compno]; \ + x = tile->comp[compno].coord[0][0] - \ + ff_jpeg2000_ceildiv(s->image_offset_x, s->cdx[compno]); \ dst = line + x * pixelsize + compno*!planar; \ \ if (codsty->transform == FF_DWT97) { \ diff --git a/externals/ffmpeg/libavcodec/libaomenc.c b/externals/ffmpeg/libavcodec/libaomenc.c index 1c78da719..2ecb3de3a 100755 --- a/externals/ffmpeg/libavcodec/libaomenc.c +++ b/externals/ffmpeg/libavcodec/libaomenc.c @@ -96,6 +96,16 @@ typedef struct AOMEncoderContext { int enable_restoration; int usage; int tune; + int enable_rect_partitions; + int enable_1to4_partitions; + int enable_ab_partitions; + int enable_angle_delta; + int enable_cfl_intra; + int enable_paeth_intra; + int enable_smooth_intra; + int enable_intra_edge_filter; + int enable_palette; + int enable_filter_intra; } AOMContext; static const char *const ctlidstr[] = { @@ -135,6 +145,18 @@ static const char *const ctlidstr[] = { #endif [AV1E_SET_ENABLE_CDEF] = "AV1E_SET_ENABLE_CDEF", [AOME_SET_TUNING] = "AOME_SET_TUNING", +#if AOM_ENCODER_ABI_VERSION >= 22 + [AV1E_SET_ENABLE_1TO4_PARTITIONS] = "AV1E_SET_ENABLE_1TO4_PARTITIONS", + [AV1E_SET_ENABLE_AB_PARTITIONS] = "AV1E_SET_ENABLE_AB_PARTITIONS", + [AV1E_SET_ENABLE_RECT_PARTITIONS] = "AV1E_SET_ENABLE_RECT_PARTITIONS", + [AV1E_SET_ENABLE_ANGLE_DELTA] = "AV1E_SET_ENABLE_ANGLE_DELTA", + [AV1E_SET_ENABLE_CFL_INTRA] = "AV1E_SET_ENABLE_CFL_INTRA", + [AV1E_SET_ENABLE_FILTER_INTRA] = "AV1E_SET_ENABLE_FILTER_INTRA", + [AV1E_SET_ENABLE_INTRA_EDGE_FILTER] = "AV1E_SET_ENABLE_INTRA_EDGE_FILTER", + [AV1E_SET_ENABLE_PAETH_INTRA] = "AV1E_SET_ENABLE_PAETH_INTRA", + [AV1E_SET_ENABLE_SMOOTH_INTRA] = "AV1E_SET_ENABLE_SMOOTH_INTRA", + [AV1E_SET_ENABLE_PALETTE] = "AV1E_SET_ENABLE_PALETTE", +#endif }; static av_cold void log_encoder_error(AVCodecContext *avctx, const char *desc) @@ -698,6 +720,28 @@ static av_cold int aom_init(AVCodecContext *avctx, codecctl_int(avctx, AV1E_SET_ENABLE_CDEF, ctx->enable_cdef); if (ctx->enable_restoration >= 0) codecctl_int(avctx, AV1E_SET_ENABLE_RESTORATION, ctx->enable_restoration); +#if AOM_ENCODER_ABI_VERSION >= 22 + if (ctx->enable_rect_partitions >= 0) + codecctl_int(avctx, AV1E_SET_ENABLE_RECT_PARTITIONS, ctx->enable_rect_partitions); + if (ctx->enable_1to4_partitions >= 0) + codecctl_int(avctx, AV1E_SET_ENABLE_1TO4_PARTITIONS, ctx->enable_1to4_partitions); + if (ctx->enable_ab_partitions >= 0) + codecctl_int(avctx, AV1E_SET_ENABLE_AB_PARTITIONS, ctx->enable_ab_partitions); + if (ctx->enable_angle_delta >= 0) + codecctl_int(avctx, AV1E_SET_ENABLE_ANGLE_DELTA, ctx->enable_angle_delta); + if (ctx->enable_cfl_intra >= 0) + codecctl_int(avctx, AV1E_SET_ENABLE_CFL_INTRA, ctx->enable_cfl_intra); + if (ctx->enable_filter_intra >= 0) + codecctl_int(avctx, AV1E_SET_ENABLE_FILTER_INTRA, ctx->enable_filter_intra); + if (ctx->enable_intra_edge_filter >= 0) + codecctl_int(avctx, AV1E_SET_ENABLE_INTRA_EDGE_FILTER, ctx->enable_intra_edge_filter); + if (ctx->enable_paeth_intra >= 0) + codecctl_int(avctx, AV1E_SET_ENABLE_PAETH_INTRA, ctx->enable_paeth_intra); + if (ctx->enable_smooth_intra >= 0) + codecctl_int(avctx, AV1E_SET_ENABLE_SMOOTH_INTRA, ctx->enable_smooth_intra); + if (ctx->enable_palette >= 0) + codecctl_int(avctx, AV1E_SET_ENABLE_PALETTE, ctx->enable_palette); +#endif codecctl_int(avctx, AOME_SET_STATIC_THRESHOLD, ctx->static_thresh); if (ctx->crf >= 0) @@ -1107,6 +1151,17 @@ static const AVOption options[] = { { "tune", "The metric that the encoder tunes for. Automatically chosen by the encoder by default", OFFSET(tune), AV_OPT_TYPE_INT, {.i64 = -1}, -1, AOM_TUNE_SSIM, VE, "tune"}, { "psnr", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = AOM_TUNE_PSNR}, 0, 0, VE, "tune"}, { "ssim", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = AOM_TUNE_SSIM}, 0, 0, VE, "tune"}, + FF_AV1_PROFILE_OPTS + { "enable-rect-partitions", "Enable rectangular partitions", OFFSET(enable_rect_partitions), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE}, + { "enable-1to4-partitions", "Enable 1:4/4:1 partitions", OFFSET(enable_1to4_partitions), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE}, + { "enable-ab-partitions", "Enable ab shape partitions", OFFSET(enable_ab_partitions), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE}, + { "enable-angle-delta", "Enable angle delta intra prediction", OFFSET(enable_angle_delta), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE}, + { "enable-cfl-intra", "Enable chroma predicted from luma intra prediction", OFFSET(enable_cfl_intra), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE}, + { "enable-filter-intra", "Enable filter intra predictor", OFFSET(enable_filter_intra), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE}, + { "enable-intra-edge-filter", "Enable intra edge filter", OFFSET(enable_intra_edge_filter), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE}, + { "enable-smooth-intra", "Enable smooth intra prediction mode", OFFSET(enable_smooth_intra), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE}, + { "enable-paeth-intra", "Enable paeth predictor in intra prediction", OFFSET(enable_paeth_intra), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE}, + { "enable-palette", "Enable palette prediction mode", OFFSET(enable_palette), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE}, { NULL }, }; diff --git a/externals/ffmpeg/libavcodec/librav1e.c b/externals/ffmpeg/libavcodec/librav1e.c index 6f9b4cce4..e9b82a724 100755 --- a/externals/ffmpeg/libavcodec/librav1e.c +++ b/externals/ffmpeg/libavcodec/librav1e.c @@ -30,12 +30,15 @@ #include "libavutil/opt.h" #include "libavutil/pixdesc.h" #include "avcodec.h" +#include "encode.h" #include "internal.h" typedef struct librav1eContext { const AVClass *class; RaContext *ctx; + AVFrame *frame; + RaFrame *rframe; AVBSFContext *bsf; uint8_t *pass_data; @@ -165,7 +168,12 @@ static av_cold int librav1e_encode_close(AVCodecContext *avctx) rav1e_context_unref(ctx->ctx); ctx->ctx = NULL; } + if (ctx->rframe) { + rav1e_frame_unref(ctx->rframe); + ctx->rframe = NULL; + } + av_frame_free(&ctx->frame); av_bsf_free(&ctx->bsf); av_freep(&ctx->pass_data); @@ -180,6 +188,10 @@ static av_cold int librav1e_encode_init(AVCodecContext *avctx) int rret; int ret = 0; + ctx->frame = av_frame_alloc(); + if (!ctx->frame) + return AVERROR(ENOMEM); + cfg = rav1e_config_default(); if (!cfg) { av_log(avctx, AV_LOG_ERROR, "Could not allocate rav1e config.\n"); @@ -416,18 +428,27 @@ end: return ret; } -static int librav1e_send_frame(AVCodecContext *avctx, const AVFrame *frame) +static int librav1e_receive_packet(AVCodecContext *avctx, AVPacket *pkt) { librav1eContext *ctx = avctx->priv_data; - RaFrame *rframe = NULL; + RaFrame *rframe = ctx->rframe; + RaPacket *rpkt = NULL; int ret; - if (frame) { + if (!rframe) { + AVFrame *frame = ctx->frame; + + ret = ff_encode_get_frame(avctx, frame); + if (ret < 0 && ret != AVERROR_EOF) + return ret; + + if (frame->buf[0]) { const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(frame->format); rframe = rav1e_frame_new(ctx->ctx); if (!rframe) { av_log(avctx, AV_LOG_ERROR, "Could not allocate new rav1e frame.\n"); + av_frame_unref(frame); return AVERROR(ENOMEM); } @@ -438,17 +459,23 @@ static int librav1e_send_frame(AVCodecContext *avctx, const AVFrame *frame) (frame->height >> shift) * frame->linesize[i], frame->linesize[i], bytes); } + av_frame_unref(frame); + } } ret = rav1e_send_frame(ctx->ctx, rframe); if (rframe) + if (ret == RA_ENCODER_STATUS_ENOUGH_DATA) { + ctx->rframe = rframe; /* Queue is full. Store the RaFrame to retry next call */ + } else { rav1e_frame_unref(rframe); /* No need to unref if flushing. */ + ctx->rframe = NULL; + } switch (ret) { case RA_ENCODER_STATUS_SUCCESS: - break; case RA_ENCODER_STATUS_ENOUGH_DATA: - return AVERROR(EAGAIN); + break; case RA_ENCODER_STATUS_FAILURE: av_log(avctx, AV_LOG_ERROR, "Could not send frame: %s\n", rav1e_status_to_str(ret)); return AVERROR_EXTERNAL; @@ -457,15 +484,6 @@ static int librav1e_send_frame(AVCodecContext *avctx, const AVFrame *frame) return AVERROR_UNKNOWN; } - return 0; -} - -static int librav1e_receive_packet(AVCodecContext *avctx, AVPacket *pkt) -{ - librav1eContext *ctx = avctx->priv_data; - RaPacket *rpkt = NULL; - int ret; - retry: if (avctx->flags & AV_CODEC_FLAG_PASS1) { @@ -490,9 +508,7 @@ retry: } return AVERROR_EOF; case RA_ENCODER_STATUS_ENCODED: - if (avctx->internal->draining) - goto retry; - return AVERROR(EAGAIN); + goto retry; case RA_ENCODER_STATUS_NEED_MORE_DATA: if (avctx->internal->draining) { av_log(avctx, AV_LOG_ERROR, "Unexpected error when receiving packet after EOF.\n"); @@ -592,7 +608,6 @@ AVCodec ff_librav1e_encoder = { .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_AV1, .init = librav1e_encode_init, - .send_frame = librav1e_send_frame, .receive_packet = librav1e_receive_packet, .close = librav1e_encode_close, .priv_data_size = sizeof(librav1eContext), diff --git a/externals/ffmpeg/libavcodec/libvpxdec.c b/externals/ffmpeg/libavcodec/libvpxdec.c index 1063c546b..eddcea894 100755 --- a/externals/ffmpeg/libavcodec/libvpxdec.c +++ b/externals/ffmpeg/libavcodec/libvpxdec.c @@ -220,7 +220,7 @@ static int vpx_decode(AVCodecContext *avctx, struct vpx_image *img, *img_alpha; int ret; uint8_t *side_data = NULL; - int side_data_size = 0; + int side_data_size; ret = decode_frame(avctx, &ctx->decoder, avpkt->data, avpkt->size); if (ret) diff --git a/externals/ffmpeg/libavcodec/libx265.c b/externals/ffmpeg/libavcodec/libx265.c index f560d7f62..686c205b6 100755 --- a/externals/ffmpeg/libavcodec/libx265.c +++ b/externals/ffmpeg/libavcodec/libx265.c @@ -310,8 +310,8 @@ static av_cold int libx265_encode_init(AVCodecContext *avctx) if (!cpb_props) return AVERROR(ENOMEM); cpb_props->buffer_size = ctx->params->rc.vbvBufferSize * 1000; - cpb_props->max_bitrate = ctx->params->rc.vbvMaxBitrate * 1000; - cpb_props->avg_bitrate = ctx->params->rc.bitrate * 1000; + cpb_props->max_bitrate = ctx->params->rc.vbvMaxBitrate * 1000LL; + cpb_props->avg_bitrate = ctx->params->rc.bitrate * 1000LL; if (!(avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER)) ctx->params->bRepeatHeaders = 1; diff --git a/externals/ffmpeg/libavcodec/mfenc.c b/externals/ffmpeg/libavcodec/mfenc.c index ee3c164e6..7fdc7af33 100755 --- a/externals/ffmpeg/libavcodec/mfenc.c +++ b/externals/ffmpeg/libavcodec/mfenc.c @@ -22,6 +22,7 @@ #define _WIN32_WINNT 0x0602 #endif +#include "encode.h" #include "mf_utils.h" #include "libavutil/imgutils.h" #include "libavutil/opt.h" @@ -30,6 +31,7 @@ typedef struct MFContext { AVClass *av_class; + AVFrame *frame; int is_video, is_audio; GUID main_subtype; IMFTransform *mft; @@ -398,26 +400,6 @@ static int mf_send_sample(AVCodecContext *avctx, IMFSample *sample) return 0; } -static int mf_send_frame(AVCodecContext *avctx, const AVFrame *frame) -{ - MFContext *c = avctx->priv_data; - int ret; - IMFSample *sample = NULL; - if (frame) { - sample = mf_avframe_to_sample(avctx, frame); - if (!sample) - return AVERROR(ENOMEM); - if (c->is_video && c->codec_api) { - if (frame->pict_type == AV_PICTURE_TYPE_I || !c->sample_sent) - ICodecAPI_SetValue(c->codec_api, &ff_CODECAPI_AVEncVideoForceKeyFrame, FF_VAL_VT_UI4(1)); - } - } - ret = mf_send_sample(avctx, sample); - if (sample) - IMFSample_Release(sample); - return ret; -} - static int mf_receive_sample(AVCodecContext *avctx, IMFSample **out_sample) { MFContext *c = avctx->priv_data; @@ -500,9 +482,36 @@ static int mf_receive_sample(AVCodecContext *avctx, IMFSample **out_sample) static int mf_receive_packet(AVCodecContext *avctx, AVPacket *avpkt) { - IMFSample *sample; + MFContext *c = avctx->priv_data; + IMFSample *sample = NULL; int ret; + if (!c->frame->buf[0]) { + ret = ff_encode_get_frame(avctx, c->frame); + if (ret < 0 && ret != AVERROR_EOF) + return ret; + } + + if (c->frame->buf[0]) { + sample = mf_avframe_to_sample(avctx, c->frame); + if (!sample) { + av_frame_unref(c->frame); + return AVERROR(ENOMEM); + } + if (c->is_video && c->codec_api) { + if (c->frame->pict_type == AV_PICTURE_TYPE_I || !c->sample_sent) + ICodecAPI_SetValue(c->codec_api, &ff_CODECAPI_AVEncVideoForceKeyFrame, FF_VAL_VT_UI4(1)); + } + } + + ret = mf_send_sample(avctx, sample); + if (sample) + IMFSample_Release(sample); + if (ret != AVERROR(EAGAIN)) + av_frame_unref(c->frame); + if (ret < 0 && ret != AVERROR(EAGAIN) && ret != AVERROR_EOF) + return ret; + ret = mf_receive_sample(avctx, &sample); if (ret < 0) return ret; @@ -1034,6 +1043,10 @@ static int mf_init(AVCodecContext *avctx) const CLSID *subtype = ff_codec_to_mf_subtype(avctx->codec_id); int use_hw = 0; + c->frame = av_frame_alloc(); + if (!c->frame) + return AVERROR(ENOMEM); + c->is_audio = avctx->codec_type == AVMEDIA_TYPE_AUDIO; c->is_video = !c->is_audio; c->reorder_delay = AV_NOPTS_VALUE; @@ -1122,6 +1135,8 @@ static int mf_close(AVCodecContext *avctx) ff_free_mf(&c->mft); + av_frame_free(&c->frame); + av_freep(&avctx->extradata); avctx->extradata_size = 0; @@ -1146,7 +1161,6 @@ static int mf_close(AVCodecContext *avctx) .priv_data_size = sizeof(MFContext), \ .init = mf_init, \ .close = mf_close, \ - .send_frame = mf_send_frame, \ .receive_packet = mf_receive_packet, \ EXTRA \ .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HYBRID, \ diff --git a/externals/ffmpeg/libavcodec/mlpenc.c b/externals/ffmpeg/libavcodec/mlpenc.c index c6a7963c2..52ea06ed9 100755 --- a/externals/ffmpeg/libavcodec/mlpenc.c +++ b/externals/ffmpeg/libavcodec/mlpenc.c @@ -531,7 +531,7 @@ static av_cold int mlp_encode_init(AVCodecContext *avctx) av_log(avctx, AV_LOG_ERROR, "Unsupported sample rate %d. Supported " "sample rates are 44100, 88200, 176400, 48000, " "96000, and 192000.\n", avctx->sample_rate); - return -1; + return AVERROR(EINVAL); } ctx->coded_sample_rate[1] = -1 & 0xf; @@ -564,7 +564,7 @@ static av_cold int mlp_encode_init(AVCodecContext *avctx) default: av_log(avctx, AV_LOG_ERROR, "Sample format not supported. " "Only 16- and 24-bit samples are supported.\n"); - return -1; + return AVERROR(EINVAL); } ctx->coded_sample_fmt[1] = -1 & 0xf; @@ -638,7 +638,7 @@ static av_cold int mlp_encode_init(AVCodecContext *avctx) ctx->channel_arrangement = 12; break; default: av_log(avctx, AV_LOG_ERROR, "Unsupported channel arrangement\n"); - return -1; + return AVERROR(EINVAL); } ctx->flags = FLAGS_DVDA; ctx->channel_occupancy = ff_mlp_ch_info[ctx->channel_arrangement].channel_occupancy; @@ -666,7 +666,7 @@ static av_cold int mlp_encode_init(AVCodecContext *avctx) break; default: av_log(avctx, AV_LOG_ERROR, "Unsupported channel arrangement\n"); - return -1; + return AVERROR(EINVAL); } ctx->flags = 0; ctx->channel_occupancy = 0; @@ -1190,7 +1190,7 @@ static unsigned int write_access_unit(MLPEncodeContext *ctx, uint8_t *buf, int total_length; if (buf_size < 4) - return -1; + return AVERROR(EINVAL); /* Frame header will be written at the end. */ buf += 4; @@ -1198,7 +1198,7 @@ static unsigned int write_access_unit(MLPEncodeContext *ctx, uint8_t *buf, if (restart_frame) { if (buf_size < 28) - return -1; + return AVERROR(EINVAL); write_major_sync(ctx, buf, buf_size); buf += 28; buf_size -= 28; @@ -1820,7 +1820,8 @@ static int apply_filter(MLPEncodeContext *ctx, unsigned int channel) if (!filter_state_buffer[i]) { av_log(ctx->avctx, AV_LOG_ERROR, "Not enough memory for applying filters.\n"); - return -1; + ret = AVERROR(ENOMEM); + goto free_and_return; } } @@ -1848,7 +1849,7 @@ static int apply_filter(MLPEncodeContext *ctx, unsigned int channel) residual = sample - (accum & mask); if (residual < SAMPLE_MIN(24) || residual > SAMPLE_MAX(24)) { - ret = -1; + ret = AVERROR_INVALIDDATA; goto free_and_return; } @@ -2226,9 +2227,6 @@ static int mlp_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, if ((ret = ff_alloc_packet2(avctx, avpkt, 87500 * avctx->channels, 0)) < 0) return ret; - if (!frame) - return 1; - /* add current frame to queue */ if ((ret = ff_af_queue_add(&ctx->afq, frame)) < 0) return ret; @@ -2267,7 +2265,7 @@ static int mlp_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, if (ctx->frame_size[ctx->frame_index] > MAX_BLOCKSIZE) { av_log(avctx, AV_LOG_ERROR, "Invalid frame size (%d > %d)\n", ctx->frame_size[ctx->frame_index], MAX_BLOCKSIZE); - return -1; + return AVERROR_INVALIDDATA; } restart_frame = !ctx->frame_index; @@ -2389,7 +2387,7 @@ AVCodec ff_mlp_encoder = { .init = mlp_encode_init, .encode2 = mlp_encode_frame, .close = mlp_encode_close, - .capabilities = AV_CODEC_CAP_SMALL_LAST_FRAME | AV_CODEC_CAP_DELAY | AV_CODEC_CAP_EXPERIMENTAL, + .capabilities = AV_CODEC_CAP_SMALL_LAST_FRAME | AV_CODEC_CAP_EXPERIMENTAL, .sample_fmts = (const enum AVSampleFormat[]) {AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE}, .supported_samplerates = (const int[]) {44100, 48000, 88200, 96000, 176400, 192000, 0}, .channel_layouts = ff_mlp_channel_layouts, @@ -2405,7 +2403,7 @@ AVCodec ff_truehd_encoder = { .init = mlp_encode_init, .encode2 = mlp_encode_frame, .close = mlp_encode_close, - .capabilities = AV_CODEC_CAP_SMALL_LAST_FRAME | AV_CODEC_CAP_DELAY | AV_CODEC_CAP_EXPERIMENTAL, + .capabilities = AV_CODEC_CAP_SMALL_LAST_FRAME | AV_CODEC_CAP_EXPERIMENTAL, .sample_fmts = (const enum AVSampleFormat[]) {AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE}, .supported_samplerates = (const int[]) {44100, 48000, 88200, 96000, 176400, 192000, 0}, .channel_layouts = (const uint64_t[]) {AV_CH_LAYOUT_STEREO, AV_CH_LAYOUT_5POINT0_BACK, AV_CH_LAYOUT_5POINT1_BACK, 0}, diff --git a/externals/ffmpeg/libavcodec/mpeg12dec.c b/externals/ffmpeg/libavcodec/mpeg12dec.c index 99e56532a..ab470187a 100755 --- a/externals/ffmpeg/libavcodec/mpeg12dec.c +++ b/externals/ffmpeg/libavcodec/mpeg12dec.c @@ -57,8 +57,7 @@ typedef struct Mpeg1Context { AVPanScan pan_scan; /* some temporary storage for the panscan */ AVStereo3D stereo3d; int has_stereo3d; - uint8_t *a53_caption; - int a53_caption_size; + AVBufferRef *a53_buf_ref; uint8_t afd; int has_afd; int slice_count; @@ -1635,13 +1634,13 @@ static int mpeg_field_start(MpegEncContext *s, const uint8_t *buf, int buf_size) return AVERROR(ENOMEM); memcpy(pan_scan->data, &s1->pan_scan, sizeof(s1->pan_scan)); - if (s1->a53_caption) { - AVFrameSideData *sd = av_frame_new_side_data( + if (s1->a53_buf_ref) { + AVFrameSideData *sd = av_frame_new_side_data_from_buf( s->current_picture_ptr->f, AV_FRAME_DATA_A53_CC, - s1->a53_caption_size); - if (sd) - memcpy(sd->data, s1->a53_caption, s1->a53_caption_size); - av_freep(&s1->a53_caption); + s1->a53_buf_ref); + if (!sd) + av_buffer_unref(&s1->a53_buf_ref); + s1->a53_buf_ref = NULL; } if (s1->has_stereo3d) { @@ -2242,14 +2241,18 @@ static int mpeg_decode_a53_cc(AVCodecContext *avctx, /* extract A53 Part 4 CC data */ int cc_count = p[5] & 0x1f; if (cc_count > 0 && buf_size >= 7 + cc_count * 3) { - av_freep(&s1->a53_caption); - s1->a53_caption_size = cc_count * 3; - s1->a53_caption = av_malloc(s1->a53_caption_size); - if (!s1->a53_caption) { - s1->a53_caption_size = 0; - } else { - memcpy(s1->a53_caption, p + 7, s1->a53_caption_size); - } + int old_size = s1->a53_buf_ref ? s1->a53_buf_ref->size : 0; + const uint64_t new_size = (old_size + cc_count + * UINT64_C(3)); + int ret; + + if (new_size > INT_MAX) + return AVERROR(EINVAL); + + ret = av_buffer_realloc(&s1->a53_buf_ref, new_size); + if (ret >= 0) + memcpy(s1->a53_buf_ref->data + old_size, p + 7, cc_count * UINT64_C(3)); + avctx->properties |= FF_CODEC_PROPERTY_CLOSED_CAPTIONS; } return 1; @@ -2258,19 +2261,23 @@ static int mpeg_decode_a53_cc(AVCodecContext *avctx, /* extract SCTE-20 CC data */ GetBitContext gb; int cc_count = 0; - int i; + int i, ret; init_get_bits(&gb, p + 2, buf_size - 2); cc_count = get_bits(&gb, 5); if (cc_count > 0) { - av_freep(&s1->a53_caption); - s1->a53_caption_size = cc_count * 3; - s1->a53_caption = av_mallocz(s1->a53_caption_size); - if (!s1->a53_caption) { - s1->a53_caption_size = 0; - } else { + int old_size = s1->a53_buf_ref ? s1->a53_buf_ref->size : 0; + const uint64_t new_size = (old_size + cc_count + * UINT64_C(3)); + if (new_size > INT_MAX) + return AVERROR(EINVAL); + + ret = av_buffer_realloc(&s1->a53_buf_ref, new_size); + if (ret >= 0) { uint8_t field, cc1, cc2; - uint8_t *cap = s1->a53_caption; + uint8_t *cap = s1->a53_buf_ref->data; + + memset(s1->a53_buf_ref->data + old_size, 0, cc_count * 3); for (i = 0; i < cc_count && get_bits_left(&gb) >= 26; i++) { skip_bits(&gb, 2); // priority field = get_bits(&gb, 2); @@ -2322,21 +2329,23 @@ static int mpeg_decode_a53_cc(AVCodecContext *avctx, * on the even field. There also exist DVDs in the wild that encode an odd field count and the * caption_extra_field_added/caption_odd_field_first bits change per packet to allow that. */ int cc_count = 0; - int i; + int i, ret; // There is a caption count field in the data, but it is often // incorrect. So count the number of captions present. for (i = 5; i + 6 <= buf_size && ((p[i] & 0xfe) == 0xfe); i += 6) cc_count++; // Transform the DVD format into A53 Part 4 format if (cc_count > 0) { - av_freep(&s1->a53_caption); - s1->a53_caption_size = cc_count * 6; - s1->a53_caption = av_malloc(s1->a53_caption_size); - if (!s1->a53_caption) { - s1->a53_caption_size = 0; - } else { + int old_size = s1->a53_buf_ref ? s1->a53_buf_ref->size : 0; + const uint64_t new_size = (old_size + cc_count + * UINT64_C(6)); + if (new_size > INT_MAX) + return AVERROR(EINVAL); + + ret = av_buffer_realloc(&s1->a53_buf_ref, new_size); + if (ret >= 0) { uint8_t field1 = !!(p[4] & 0x80); - uint8_t *cap = s1->a53_caption; + uint8_t *cap = s1->a53_buf_ref->data; p += 5; for (i = 0; i < cc_count; i++) { cap[0] = (p[0] == 0xff && field1) ? 0xfc : 0xfd; @@ -2846,6 +2855,7 @@ static int mpeg_decode_frame(AVCodecContext *avctx, void *data, s2->current_picture_ptr = NULL; if (s2->timecode_frame_start != -1 && *got_output) { + char tcbuf[AV_TIMECODE_STR_SIZE]; AVFrameSideData *tcside = av_frame_new_side_data(picture, AV_FRAME_DATA_GOP_TIMECODE, sizeof(int64_t)); @@ -2853,6 +2863,9 @@ static int mpeg_decode_frame(AVCodecContext *avctx, void *data, return AVERROR(ENOMEM); memcpy(tcside->data, &s2->timecode_frame_start, sizeof(int64_t)); + av_timecode_make_mpeg_tc_string(tcbuf, s2->timecode_frame_start); + av_dict_set(&picture->metadata, "timecode", tcbuf, 0); + s2->timecode_frame_start = -1; } } @@ -2873,9 +2886,8 @@ static av_cold int mpeg_decode_end(AVCodecContext *avctx) { Mpeg1Context *s = avctx->priv_data; - if (s->mpeg_enc_ctx_allocated) - ff_mpv_common_end(&s->mpeg_enc_ctx); - av_freep(&s->a53_caption); + ff_mpv_common_end(&s->mpeg_enc_ctx); + av_buffer_unref(&s->a53_buf_ref); return 0; } @@ -2891,7 +2903,7 @@ AVCodec ff_mpeg1video_decoder = { .capabilities = AV_CODEC_CAP_DRAW_HORIZ_BAND | AV_CODEC_CAP_DR1 | AV_CODEC_CAP_TRUNCATED | AV_CODEC_CAP_DELAY | AV_CODEC_CAP_SLICE_THREADS, - .caps_internal = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM, + .caps_internal = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM | FF_CODEC_CAP_INIT_CLEANUP, .flush = flush, .max_lowres = 3, .update_thread_context = ONLY_IF_THREADS_ENABLED(mpeg_decode_update_thread_context), @@ -2924,7 +2936,7 @@ AVCodec ff_mpeg2video_decoder = { .capabilities = AV_CODEC_CAP_DRAW_HORIZ_BAND | AV_CODEC_CAP_DR1 | AV_CODEC_CAP_TRUNCATED | AV_CODEC_CAP_DELAY | AV_CODEC_CAP_SLICE_THREADS, - .caps_internal = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM, + .caps_internal = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM | FF_CODEC_CAP_INIT_CLEANUP, .flush = flush, .max_lowres = 3, .profiles = NULL_IF_CONFIG_SMALL(ff_mpeg2_video_profiles), @@ -2968,7 +2980,7 @@ AVCodec ff_mpegvideo_decoder = { .close = mpeg_decode_end, .decode = mpeg_decode_frame, .capabilities = AV_CODEC_CAP_DRAW_HORIZ_BAND | AV_CODEC_CAP_DR1 | AV_CODEC_CAP_TRUNCATED | AV_CODEC_CAP_DELAY | AV_CODEC_CAP_SLICE_THREADS, - .caps_internal = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM, + .caps_internal = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM | FF_CODEC_CAP_INIT_CLEANUP, .flush = flush, .max_lowres = 3, }; diff --git a/externals/ffmpeg/libavcodec/mpeg2_metadata_bsf.c b/externals/ffmpeg/libavcodec/mpeg2_metadata_bsf.c index b1e2d6128..d0048c0e2 100755 --- a/externals/ffmpeg/libavcodec/mpeg2_metadata_bsf.c +++ b/externals/ffmpeg/libavcodec/mpeg2_metadata_bsf.c @@ -137,7 +137,7 @@ static int mpeg2_metadata_update_fragment(AVBSFContext *bsf, se->vertical_size_extension << 12 | sh->vertical_size_value, }; - err = ff_cbs_insert_unit_content(ctx->cbc, frag, se_pos + 1, + err = ff_cbs_insert_unit_content(frag, se_pos + 1, MPEG2_START_EXTENSION, &ctx->sequence_display_extension, NULL); @@ -200,7 +200,7 @@ static int mpeg2_metadata_filter(AVBSFContext *bsf, AVPacket *pkt) err = 0; fail: - ff_cbs_fragment_reset(ctx->cbc, frag); + ff_cbs_fragment_reset(frag); if (err < 0) av_packet_unref(pkt); @@ -252,7 +252,7 @@ static int mpeg2_metadata_init(AVBSFContext *bsf) err = 0; fail: - ff_cbs_fragment_reset(ctx->cbc, frag); + ff_cbs_fragment_reset(frag); return err; } @@ -260,7 +260,7 @@ static void mpeg2_metadata_close(AVBSFContext *bsf) { MPEG2MetadataContext *ctx = bsf->priv_data; - ff_cbs_fragment_free(ctx->cbc, &ctx->fragment); + ff_cbs_fragment_free(&ctx->fragment); ff_cbs_close(&ctx->cbc); } diff --git a/externals/ffmpeg/libavcodec/mpeg4videodec.c b/externals/ffmpeg/libavcodec/mpeg4videodec.c index 610e365c3..14fb79261 100755 --- a/externals/ffmpeg/libavcodec/mpeg4videodec.c +++ b/externals/ffmpeg/libavcodec/mpeg4videodec.c @@ -3603,7 +3603,8 @@ AVCodec ff_mpeg4_decoder = { AV_CODEC_CAP_TRUNCATED | AV_CODEC_CAP_DELAY | AV_CODEC_CAP_FRAME_THREADS, .caps_internal = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM | - FF_CODEC_CAP_ALLOCATE_PROGRESS, + FF_CODEC_CAP_ALLOCATE_PROGRESS | + FF_CODEC_CAP_INIT_CLEANUP, .flush = ff_mpeg_flush, .max_lowres = 3, .pix_fmts = ff_h263_hwaccel_pixfmt_list_420, diff --git a/externals/ffmpeg/libavcodec/mpegpicture.c b/externals/ffmpeg/libavcodec/mpegpicture.c index 5fce25ec6..83426bbda 100755 --- a/externals/ffmpeg/libavcodec/mpegpicture.c +++ b/externals/ffmpeg/libavcodec/mpegpicture.c @@ -78,20 +78,15 @@ int ff_mpeg_framesize_alloc(AVCodecContext *avctx, MotionEstContext *me, // at uvlinesize. It supports only YUV420 so 24x24 is enough // linesize * interlaced * MBsize // we also use this buffer for encoding in encode_mb_internal() needig an additional 32 lines - FF_ALLOCZ_ARRAY_OR_GOTO(avctx, sc->edge_emu_buffer, alloc_size, EMU_EDGE_HEIGHT, - fail); - - FF_ALLOCZ_ARRAY_OR_GOTO(avctx, me->scratchpad, alloc_size, 4 * 16 * 2, - fail) + if (!FF_ALLOCZ_TYPED_ARRAY(sc->edge_emu_buffer, alloc_size * EMU_EDGE_HEIGHT) || + !FF_ALLOCZ_TYPED_ARRAY(me->scratchpad, alloc_size * 4 * 16 * 2)) + return AVERROR(ENOMEM); me->temp = me->scratchpad; sc->rd_scratchpad = me->scratchpad; sc->b_scratchpad = me->scratchpad; sc->obmc_scratchpad = me->scratchpad + 16; return 0; -fail: - av_freep(&sc->edge_emu_buffer); - return AVERROR(ENOMEM); } /** diff --git a/externals/ffmpeg/libavcodec/mpegvideo.c b/externals/ffmpeg/libavcodec/mpegvideo.c index 49fd1c999..c28d1adef 100755 --- a/externals/ffmpeg/libavcodec/mpegvideo.c +++ b/externals/ffmpeg/libavcodec/mpegvideo.c @@ -372,25 +372,27 @@ static int init_duplicate_context(MpegEncContext *s) s->sc.obmc_scratchpad = NULL; if (s->encoding) { - FF_ALLOCZ_OR_GOTO(s->avctx, s->me.map, - ME_MAP_SIZE * sizeof(uint32_t), fail) - FF_ALLOCZ_OR_GOTO(s->avctx, s->me.score_map, - ME_MAP_SIZE * sizeof(uint32_t), fail) + if (!FF_ALLOCZ_TYPED_ARRAY(s->me.map, ME_MAP_SIZE) || + !FF_ALLOCZ_TYPED_ARRAY(s->me.score_map, ME_MAP_SIZE)) + return AVERROR(ENOMEM); + if (s->noise_reduction) { - FF_ALLOCZ_OR_GOTO(s->avctx, s->dct_error_sum, - 2 * 64 * sizeof(int), fail) + if (!FF_ALLOCZ_TYPED_ARRAY(s->dct_error_sum, 2)) + return AVERROR(ENOMEM); } } - FF_ALLOCZ_OR_GOTO(s->avctx, s->blocks, 64 * 12 * 2 * sizeof(int16_t), fail) + if (!FF_ALLOCZ_TYPED_ARRAY(s->blocks, 2)) + return AVERROR(ENOMEM); s->block = s->blocks[0]; for (i = 0; i < 12; i++) { s->pblocks[i] = &s->block[i]; } - FF_ALLOCZ_OR_GOTO(s->avctx, s->block32, sizeof(*s->block32), fail) + if (!(s->block32 = av_mallocz(sizeof(*s->block32))) || + !(s->dpcm_macroblock = av_mallocz(sizeof(*s->dpcm_macroblock)))) + return AVERROR(ENOMEM); s->dpcm_direction = 0; - FF_ALLOCZ_OR_GOTO(s->avctx, s->dpcm_macroblock, sizeof(*s->dpcm_macroblock), fail) if (s->avctx->codec_tag == AV_RL32("VCR2")) { // exchange uv @@ -399,16 +401,14 @@ static int init_duplicate_context(MpegEncContext *s) if (s->out_format == FMT_H263) { /* ac values */ - FF_ALLOCZ_OR_GOTO(s->avctx, s->ac_val_base, - yc_size * sizeof(int16_t) * 16, fail); + if (!FF_ALLOCZ_TYPED_ARRAY(s->ac_val_base, yc_size)) + return AVERROR(ENOMEM); s->ac_val[0] = s->ac_val_base + s->b8_stride + 1; s->ac_val[1] = s->ac_val_base + y_size + s->mb_stride + 1; s->ac_val[2] = s->ac_val[1] + c_size; } return 0; -fail: - return AVERROR(ENOMEM); // free() through ff_mpv_common_end() } static void free_duplicate_context(MpegEncContext *s) @@ -715,8 +715,8 @@ static int init_context_frame(MpegEncContext *s) if (s->mb_height & 1) yc_size += 2*s->b8_stride + 2*s->mb_stride; - FF_ALLOCZ_OR_GOTO(s->avctx, s->mb_index2xy, (s->mb_num + 1) * sizeof(int), - fail); // error resilience code looks cleaner with this + if (!FF_ALLOCZ_TYPED_ARRAY(s->mb_index2xy, s->mb_num + 1)) + return AVERROR(ENOMEM); for (y = 0; y < s->mb_height; y++) for (x = 0; x < s->mb_width; x++) s->mb_index2xy[x + y * s->mb_width] = x + y * s->mb_stride; @@ -725,12 +725,13 @@ static int init_context_frame(MpegEncContext *s) if (s->encoding) { /* Allocate MV tables */ - FF_ALLOCZ_OR_GOTO(s->avctx, s->p_mv_table_base, mv_table_size * 2 * sizeof(int16_t), fail) - FF_ALLOCZ_OR_GOTO(s->avctx, s->b_forw_mv_table_base, mv_table_size * 2 * sizeof(int16_t), fail) - FF_ALLOCZ_OR_GOTO(s->avctx, s->b_back_mv_table_base, mv_table_size * 2 * sizeof(int16_t), fail) - FF_ALLOCZ_OR_GOTO(s->avctx, s->b_bidir_forw_mv_table_base, mv_table_size * 2 * sizeof(int16_t), fail) - FF_ALLOCZ_OR_GOTO(s->avctx, s->b_bidir_back_mv_table_base, mv_table_size * 2 * sizeof(int16_t), fail) - FF_ALLOCZ_OR_GOTO(s->avctx, s->b_direct_mv_table_base, mv_table_size * 2 * sizeof(int16_t), fail) + if (!FF_ALLOCZ_TYPED_ARRAY(s->p_mv_table_base, mv_table_size) || + !FF_ALLOCZ_TYPED_ARRAY(s->b_forw_mv_table_base, mv_table_size) || + !FF_ALLOCZ_TYPED_ARRAY(s->b_back_mv_table_base, mv_table_size) || + !FF_ALLOCZ_TYPED_ARRAY(s->b_bidir_forw_mv_table_base, mv_table_size) || + !FF_ALLOCZ_TYPED_ARRAY(s->b_bidir_back_mv_table_base, mv_table_size) || + !FF_ALLOCZ_TYPED_ARRAY(s->b_direct_mv_table_base, mv_table_size)) + return AVERROR(ENOMEM); s->p_mv_table = s->p_mv_table_base + s->mb_stride + 1; s->b_forw_mv_table = s->b_forw_mv_table_base + s->mb_stride + 1; s->b_back_mv_table = s->b_back_mv_table_base + s->mb_stride + 1; @@ -739,15 +740,11 @@ static int init_context_frame(MpegEncContext *s) s->b_direct_mv_table = s->b_direct_mv_table_base + s->mb_stride + 1; /* Allocate MB type table */ - FF_ALLOCZ_OR_GOTO(s->avctx, s->mb_type, mb_array_size * sizeof(uint16_t), fail) // needed for encoding - - FF_ALLOCZ_OR_GOTO(s->avctx, s->lambda_table, mb_array_size * sizeof(int), fail) - - FF_ALLOC_OR_GOTO(s->avctx, s->cplx_tab, - mb_array_size * sizeof(float), fail); - FF_ALLOC_OR_GOTO(s->avctx, s->bits_tab, - mb_array_size * sizeof(float), fail); - + if (!FF_ALLOCZ_TYPED_ARRAY(s->mb_type, mb_array_size) || + !FF_ALLOCZ_TYPED_ARRAY(s->lambda_table, mb_array_size) || + !FF_ALLOC_TYPED_ARRAY (s->cplx_tab, mb_array_size) || + !FF_ALLOC_TYPED_ARRAY (s->bits_tab, mb_array_size)) + return AVERROR(ENOMEM); } if (s->codec_id == AV_CODEC_ID_MPEG4 || @@ -757,34 +754,34 @@ static int init_context_frame(MpegEncContext *s) int j, k; for (j = 0; j < 2; j++) { for (k = 0; k < 2; k++) { - FF_ALLOCZ_OR_GOTO(s->avctx, - s->b_field_mv_table_base[i][j][k], - mv_table_size * 2 * sizeof(int16_t), - fail); + if (!FF_ALLOCZ_TYPED_ARRAY(s->b_field_mv_table_base[i][j][k], mv_table_size)) + return AVERROR(ENOMEM); s->b_field_mv_table[i][j][k] = s->b_field_mv_table_base[i][j][k] + s->mb_stride + 1; } - FF_ALLOCZ_OR_GOTO(s->avctx, s->b_field_select_table [i][j], mb_array_size * 2 * sizeof(uint8_t), fail) - FF_ALLOCZ_OR_GOTO(s->avctx, s->p_field_mv_table_base[i][j], mv_table_size * 2 * sizeof(int16_t), fail) + if (!FF_ALLOCZ_TYPED_ARRAY(s->b_field_select_table [i][j], mv_table_size * 2) || + !FF_ALLOCZ_TYPED_ARRAY(s->p_field_mv_table_base[i][j], mv_table_size)) + return AVERROR(ENOMEM); s->p_field_mv_table[i][j] = s->p_field_mv_table_base[i][j] + s->mb_stride + 1; } - FF_ALLOCZ_OR_GOTO(s->avctx, s->p_field_select_table[i], mb_array_size * 2 * sizeof(uint8_t), fail) + if (!FF_ALLOCZ_TYPED_ARRAY(s->p_field_select_table[i], mv_table_size * 2)) + return AVERROR(ENOMEM); } } if (s->out_format == FMT_H263) { - /* cbp values */ - FF_ALLOCZ_OR_GOTO(s->avctx, s->coded_block_base, y_size + (s->mb_height&1)*2*s->b8_stride, fail); + /* cbp values, cbp, ac_pred, pred_dir */ + if (!FF_ALLOCZ_TYPED_ARRAY(s->coded_block_base, y_size + (s->mb_height&1)*2*s->b8_stride) || + !FF_ALLOCZ_TYPED_ARRAY(s->cbp_table, mb_array_size) || + !FF_ALLOCZ_TYPED_ARRAY(s->pred_dir_table, mb_array_size)) + return AVERROR(ENOMEM); s->coded_block = s->coded_block_base + s->b8_stride + 1; - - /* cbp, ac_pred, pred_dir */ - FF_ALLOCZ_OR_GOTO(s->avctx, s->cbp_table , mb_array_size * sizeof(uint8_t), fail); - FF_ALLOCZ_OR_GOTO(s->avctx, s->pred_dir_table, mb_array_size * sizeof(uint8_t), fail); } if (s->h263_pred || s->h263_plus || !s->encoding) { /* dc values */ // MN: we need these for error resilience of intra-frames - FF_ALLOCZ_OR_GOTO(s->avctx, s->dc_val_base, yc_size * sizeof(int16_t), fail); + if (!FF_ALLOCZ_TYPED_ARRAY(s->dc_val_base, yc_size)) + return AVERROR(ENOMEM); s->dc_val[0] = s->dc_val_base + s->b8_stride + 1; s->dc_val[1] = s->dc_val_base + y_size + s->mb_stride + 1; s->dc_val[2] = s->dc_val[1] + c_size; @@ -792,17 +789,14 @@ static int init_context_frame(MpegEncContext *s) s->dc_val_base[i] = 1024; } - /* which mb is an intra block */ - FF_ALLOCZ_OR_GOTO(s->avctx, s->mbintra_table, mb_array_size, fail); + /* which mb is an intra block, init macroblock skip table */ + if (!FF_ALLOCZ_TYPED_ARRAY(s->mbintra_table, mb_array_size) || + // Note the + 1 is for a quicker MPEG-4 slice_end detection + !FF_ALLOCZ_TYPED_ARRAY(s->mbskip_table, mb_array_size + 2)) + return AVERROR(ENOMEM); memset(s->mbintra_table, 1, mb_array_size); - /* init macroblock skip table */ - FF_ALLOCZ_OR_GOTO(s->avctx, s->mbskip_table, mb_array_size + 2, fail); - // Note the + 1 is for a quicker MPEG-4 slice_end detection - return ff_mpeg_er_init(s); -fail: - return AVERROR(ENOMEM); } static void clear_context(MpegEncContext *s) @@ -934,28 +928,22 @@ av_cold int ff_mpv_common_init(MpegEncContext *s) if (ret) return ret; - FF_ALLOCZ_OR_GOTO(s->avctx, s->picture, - MAX_PICTURE_COUNT * sizeof(Picture), fail_nomem); + if (!FF_ALLOCZ_TYPED_ARRAY(s->picture, MAX_PICTURE_COUNT)) + return AVERROR(ENOMEM); for (i = 0; i < MAX_PICTURE_COUNT; i++) { s->picture[i].f = av_frame_alloc(); if (!s->picture[i].f) - goto fail_nomem; + return AVERROR(ENOMEM); } - s->next_picture.f = av_frame_alloc(); - if (!s->next_picture.f) - goto fail_nomem; - s->last_picture.f = av_frame_alloc(); - if (!s->last_picture.f) - goto fail_nomem; - s->current_picture.f = av_frame_alloc(); - if (!s->current_picture.f) - goto fail_nomem; - s->new_picture.f = av_frame_alloc(); - if (!s->new_picture.f) - goto fail_nomem; + + if (!(s->next_picture.f = av_frame_alloc()) || + !(s->last_picture.f = av_frame_alloc()) || + !(s->current_picture.f = av_frame_alloc()) || + !(s->new_picture.f = av_frame_alloc())) + return AVERROR(ENOMEM); if ((ret = init_context_frame(s))) - goto fail_nomem; + return AVERROR(ENOMEM); s->parse_context.state = -1; @@ -969,10 +957,10 @@ av_cold int ff_mpv_common_init(MpegEncContext *s) if (i) { s->thread_context[i] = av_memdup(s, sizeof(MpegEncContext)); if (!s->thread_context[i]) - goto fail_nomem; + return AVERROR(ENOMEM); } if ((ret = init_duplicate_context(s->thread_context[i])) < 0) - goto fail; + return ret; s->thread_context[i]->start_mb_y = (s->mb_height * (i) + nb_slices / 2) / nb_slices; s->thread_context[i]->end_mb_y = @@ -980,7 +968,7 @@ av_cold int ff_mpv_common_init(MpegEncContext *s) } } else { if ((ret = init_duplicate_context(s)) < 0) - goto fail; + return ret; s->start_mb_y = 0; s->end_mb_y = s->mb_height; } @@ -988,11 +976,6 @@ av_cold int ff_mpv_common_init(MpegEncContext *s) // } return 0; - fail_nomem: - ret = AVERROR(ENOMEM); - fail: - ff_mpv_common_end(s); - return ret; } /** @@ -1085,10 +1068,10 @@ int ff_mpv_common_frame_size_change(MpegEncContext *s) if ((s->width || s->height) && (err = av_image_check_size(s->width, s->height, 0, s->avctx)) < 0) - goto fail; + return err; if ((err = init_context_frame(s))) - goto fail; + return err; memset(s->thread_context, 0, sizeof(s->thread_context)); s->thread_context[0] = s; @@ -1100,12 +1083,11 @@ int ff_mpv_common_frame_size_change(MpegEncContext *s) if (i) { s->thread_context[i] = av_memdup(s, sizeof(MpegEncContext)); if (!s->thread_context[i]) { - err = AVERROR(ENOMEM); - goto fail; + return AVERROR(ENOMEM); } } if ((err = init_duplicate_context(s->thread_context[i])) < 0) - goto fail; + return err; s->thread_context[i]->start_mb_y = (s->mb_height * (i) + nb_slices / 2) / nb_slices; s->thread_context[i]->end_mb_y = @@ -1114,7 +1096,7 @@ int ff_mpv_common_frame_size_change(MpegEncContext *s) } else { err = init_duplicate_context(s); if (err < 0) - goto fail; + return err; s->start_mb_y = 0; s->end_mb_y = s->mb_height; } @@ -1122,9 +1104,6 @@ int ff_mpv_common_frame_size_change(MpegEncContext *s) } return 0; - fail: - ff_mpv_common_end(s); - return err; } /* init common structure for both encoder and decoder */ @@ -1133,7 +1112,7 @@ void ff_mpv_common_end(MpegEncContext *s) int i; if (!s) - return ; + return; if (s->slice_context_count > 1) { for (i = 0; i < s->slice_context_count; i++) { @@ -1151,6 +1130,9 @@ void ff_mpv_common_end(MpegEncContext *s) av_freep(&s->bitstream_buffer); s->allocated_bitstream_buffer_size = 0; + if (!s->avctx) + return; + if (s->picture) { for (i = 0; i < MAX_PICTURE_COUNT; i++) { ff_free_picture_tables(&s->picture[i]); diff --git a/externals/ffmpeg/libavcodec/mpegvideo_enc.c b/externals/ffmpeg/libavcodec/mpegvideo_enc.c index d1e2bd997..c3ef40556 100755 --- a/externals/ffmpeg/libavcodec/mpegvideo_enc.c +++ b/externals/ffmpeg/libavcodec/mpegvideo_enc.c @@ -925,27 +925,25 @@ FF_ENABLE_DEPRECATION_WARNINGS ff_qpeldsp_init(&s->qdsp); if (s->msmpeg4_version) { - FF_ALLOCZ_OR_GOTO(s->avctx, s->ac_stats, - 2 * 2 * (MAX_LEVEL + 1) * - (MAX_RUN + 1) * 2 * sizeof(int), fail); + int ac_stats_size = 2 * 2 * (MAX_LEVEL + 1) * (MAX_RUN + 1) * 2 * sizeof(int); + if (!(s->ac_stats = av_mallocz(ac_stats_size))) + return AVERROR(ENOMEM); } - FF_ALLOCZ_OR_GOTO(s->avctx, s->avctx->stats_out, 256, fail); - - FF_ALLOCZ_OR_GOTO(s->avctx, s->q_intra_matrix, 64 * 32 * sizeof(int), fail); - FF_ALLOCZ_OR_GOTO(s->avctx, s->q_chroma_intra_matrix, 64 * 32 * sizeof(int), fail); - FF_ALLOCZ_OR_GOTO(s->avctx, s->q_inter_matrix, 64 * 32 * sizeof(int), fail); - FF_ALLOCZ_OR_GOTO(s->avctx, s->q_intra_matrix16, 64 * 32 * 2 * sizeof(uint16_t), fail); - FF_ALLOCZ_OR_GOTO(s->avctx, s->q_chroma_intra_matrix16, 64 * 32 * 2 * sizeof(uint16_t), fail); - FF_ALLOCZ_OR_GOTO(s->avctx, s->q_inter_matrix16, 64 * 32 * 2 * sizeof(uint16_t), fail); - FF_ALLOCZ_OR_GOTO(s->avctx, s->input_picture, - MAX_PICTURE_COUNT * sizeof(Picture *), fail); - FF_ALLOCZ_OR_GOTO(s->avctx, s->reordered_input_picture, - MAX_PICTURE_COUNT * sizeof(Picture *), fail); + if (!(s->avctx->stats_out = av_mallocz(256)) || + !FF_ALLOCZ_TYPED_ARRAY(s->q_intra_matrix, 32) || + !FF_ALLOCZ_TYPED_ARRAY(s->q_chroma_intra_matrix, 32) || + !FF_ALLOCZ_TYPED_ARRAY(s->q_inter_matrix, 32) || + !FF_ALLOCZ_TYPED_ARRAY(s->q_intra_matrix16, 32) || + !FF_ALLOCZ_TYPED_ARRAY(s->q_chroma_intra_matrix16, 32) || + !FF_ALLOCZ_TYPED_ARRAY(s->q_inter_matrix16, 32) || + !FF_ALLOCZ_TYPED_ARRAY(s->input_picture, MAX_PICTURE_COUNT) || + !FF_ALLOCZ_TYPED_ARRAY(s->reordered_input_picture, MAX_PICTURE_COUNT)) + return AVERROR(ENOMEM); if (s->noise_reduction) { - FF_ALLOCZ_OR_GOTO(s->avctx, s->dct_offset, - 2 * 64 * sizeof(uint16_t), fail); + if (!FF_ALLOCZ_TYPED_ARRAY(s->dct_offset, 2)) + return AVERROR(ENOMEM); } ff_dct_encode_init(s); @@ -1060,8 +1058,6 @@ FF_ENABLE_DEPRECATION_WARNINGS cpb_props->buffer_size = avctx->rc_buffer_size; return 0; -fail: - return AVERROR_UNKNOWN; } av_cold int ff_mpv_encode_end(AVCodecContext *avctx) diff --git a/externals/ffmpeg/libavcodec/msmpeg4dec.c b/externals/ffmpeg/libavcodec/msmpeg4dec.c index 16b67192b..49df06a9d 100755 --- a/externals/ffmpeg/libavcodec/msmpeg4dec.c +++ b/externals/ffmpeg/libavcodec/msmpeg4dec.c @@ -888,7 +888,7 @@ AVCodec ff_msmpeg4v1_decoder = { .close = ff_h263_decode_end, .decode = ff_h263_decode_frame, .capabilities = AV_CODEC_CAP_DRAW_HORIZ_BAND | AV_CODEC_CAP_DR1, - .caps_internal = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM, + .caps_internal = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM | FF_CODEC_CAP_INIT_CLEANUP, .max_lowres = 3, .pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV420P, @@ -906,7 +906,7 @@ AVCodec ff_msmpeg4v2_decoder = { .close = ff_h263_decode_end, .decode = ff_h263_decode_frame, .capabilities = AV_CODEC_CAP_DRAW_HORIZ_BAND | AV_CODEC_CAP_DR1, - .caps_internal = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM, + .caps_internal = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM | FF_CODEC_CAP_INIT_CLEANUP, .max_lowres = 3, .pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV420P, @@ -924,7 +924,7 @@ AVCodec ff_msmpeg4v3_decoder = { .close = ff_h263_decode_end, .decode = ff_h263_decode_frame, .capabilities = AV_CODEC_CAP_DRAW_HORIZ_BAND | AV_CODEC_CAP_DR1, - .caps_internal = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM, + .caps_internal = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM | FF_CODEC_CAP_INIT_CLEANUP, .max_lowres = 3, .pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV420P, @@ -942,7 +942,7 @@ AVCodec ff_wmv1_decoder = { .close = ff_h263_decode_end, .decode = ff_h263_decode_frame, .capabilities = AV_CODEC_CAP_DRAW_HORIZ_BAND | AV_CODEC_CAP_DR1, - .caps_internal = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM, + .caps_internal = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM | FF_CODEC_CAP_INIT_CLEANUP, .max_lowres = 3, .pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV420P, diff --git a/externals/ffmpeg/libavcodec/nellymoserdec.c b/externals/ffmpeg/libavcodec/nellymoserdec.c index b0deb79cf..d667d9ce7 100755 --- a/externals/ffmpeg/libavcodec/nellymoserdec.c +++ b/externals/ffmpeg/libavcodec/nellymoserdec.c @@ -143,7 +143,6 @@ static int decode_tag(AVCodecContext *avctx, void *data, { AVFrame *frame = data; const uint8_t *buf = avpkt->data; - const uint8_t *side=av_packet_get_side_data(avpkt, 'F', NULL); int buf_size = avpkt->size; NellyMoserDecodeContext *s = avctx->priv_data; int blocks, i, ret; @@ -160,15 +159,6 @@ static int decode_tag(AVCodecContext *avctx, void *data, av_log(avctx, AV_LOG_WARNING, "Leftover bytes: %d.\n", buf_size % NELLY_BLOCK_LEN); } - /* Normal numbers of blocks for sample rates: - * 8000 Hz - 1 - * 11025 Hz - 2 - * 16000 Hz - 3 - * 22050 Hz - 4 - * 44100 Hz - 8 - */ - if(side && blocks>1 && avctx->sample_rate%11025==0 && (1<<((side[0]>>2)&3)) == blocks) - avctx->sample_rate= 11025*(blocks/2); /* get output buffer */ frame->nb_samples = NELLY_SAMPLES * blocks; diff --git a/externals/ffmpeg/libavcodec/nvenc.c b/externals/ffmpeg/libavcodec/nvenc.c index e269c716a..c6740c184 100755 --- a/externals/ffmpeg/libavcodec/nvenc.c +++ b/externals/ffmpeg/libavcodec/nvenc.c @@ -22,6 +22,7 @@ #include "config.h" #include "nvenc.h" +#include "hevc_sei.h" #include "libavutil/hwcontext_cuda.h" #include "libavutil/hwcontext.h" @@ -30,6 +31,7 @@ #include "libavutil/avassert.h" #include "libavutil/mem.h" #include "libavutil/pixdesc.h" +#include "encode.h" #include "internal.h" #include "packet_internal.h" @@ -40,6 +42,12 @@ rc == NV_ENC_PARAMS_RC_CBR_LOWDELAY_HQ || \ rc == NV_ENC_PARAMS_RC_CBR_HQ) +#ifdef NVENC_HAVE_NEW_PRESETS +#define IS_SDK10_PRESET(p) ((p) >= PRESET_P1 && (p) <= PRESET_P7) +#else +#define IS_SDK10_PRESET(p) 0 +#endif + const enum AVPixelFormat ff_nvenc_pix_fmts[] = { AV_PIX_FMT_YUV420P, AV_PIX_FMT_NV12, @@ -143,8 +151,14 @@ static int nvenc_print_error(AVCodecContext *avctx, NVENCSTATUS err, static void nvenc_print_driver_requirement(AVCodecContext *avctx, int level) { -#if NVENCAPI_CHECK_VERSION(9, 2) +#if NVENCAPI_CHECK_VERSION(10, 1) const char *minver = "(unknown)"; +#elif NVENCAPI_CHECK_VERSION(10, 0) +# if defined(_WIN32) || defined(__CYGWIN__) + const char *minver = "450.51"; +# else + const char *minver = "445.87"; +# endif #elif NVENCAPI_CHECK_VERSION(9, 1) # if defined(_WIN32) || defined(__CYGWIN__) const char *minver = "436.15"; @@ -648,6 +662,15 @@ static void nvenc_map_preset(NvencContext *ctx) PRESET(LOW_LATENCY_HQ, NVENC_LOWLATENCY), PRESET(LOSSLESS_DEFAULT, NVENC_LOSSLESS), PRESET(LOSSLESS_HP, NVENC_LOSSLESS), +#ifdef NVENC_HAVE_NEW_PRESETS + PRESET(P1), + PRESET(P2), + PRESET(P3), + PRESET(P4), + PRESET(P5), + PRESET(P6), + PRESET(P7), +#endif }; GUIDTuple *t = &presets[ctx->preset]; @@ -857,6 +880,12 @@ static av_cold void nvenc_setup_rate_control(AVCodecContext *avctx) if (avctx->rc_max_rate > 0) ctx->encode_config.rcParams.maxBitRate = avctx->rc_max_rate; +#ifdef NVENC_HAVE_MULTIPASS + ctx->encode_config.rcParams.multiPass = ctx->multipass; + if (ctx->encode_config.rcParams.multiPass != NV_ENC_MULTI_PASS_DISABLED) + ctx->flags |= NVENC_TWO_PASSES; +#endif + if (ctx->rc < 0) { if (ctx->flags & NVENC_ONE_PASS) ctx->twopass = 0; @@ -891,6 +920,11 @@ static av_cold void nvenc_setup_rate_control(AVCodecContext *avctx) ctx->rc &= ~RC_MODE_DEPRECATED; } +#ifdef NVENC_HAVE_LDKFS + if (ctx->ldkfs) + ctx->encode_config.rcParams.lowDelayKeyFrameScale = ctx->ldkfs; +#endif + if (ctx->flags & NVENC_LOSSLESS) { set_lossless(avctx); } else if (ctx->rc >= 0) { @@ -1200,10 +1234,27 @@ static av_cold int nvenc_setup_encoder(AVCodecContext *avctx) preset_config.version = NV_ENC_PRESET_CONFIG_VER; preset_config.presetCfg.version = NV_ENC_CONFIG_VER; - nv_status = p_nvenc->nvEncGetEncodePresetConfig(ctx->nvencoder, - ctx->init_encode_params.encodeGUID, - ctx->init_encode_params.presetGUID, - &preset_config); + if (IS_SDK10_PRESET(ctx->preset)) { +#ifdef NVENC_HAVE_NEW_PRESETS + ctx->init_encode_params.tuningInfo = ctx->tuning_info; + + nv_status = p_nvenc->nvEncGetEncodePresetConfigEx(ctx->nvencoder, + ctx->init_encode_params.encodeGUID, + ctx->init_encode_params.presetGUID, + ctx->init_encode_params.tuningInfo, + &preset_config); +#endif + } else { +#ifdef NVENC_HAVE_NEW_PRESETS + // Turn off tuning info parameter if older presets are on + ctx->init_encode_params.tuningInfo = 0; +#endif + + nv_status = p_nvenc->nvEncGetEncodePresetConfig(ctx->nvencoder, + ctx->init_encode_params.encodeGUID, + ctx->init_encode_params.presetGUID, + &preset_config); + } if (nv_status != NV_ENC_SUCCESS) return nvenc_print_error(avctx, nv_status, "Cannot get the preset configuration"); @@ -1226,6 +1277,17 @@ static av_cold int nvenc_setup_encoder(AVCodecContext *avctx) ctx->init_encode_params.enableEncodeAsync = 0; ctx->init_encode_params.enablePTD = 1; +#ifdef NVENC_HAVE_NEW_PRESETS + /* If lookahead isn't set from CLI, use value from preset. + * P6 & P7 presets may enable lookahead for better quality. + * */ + if (ctx->rc_lookahead == 0 && ctx->encode_config.rcParams.enableLookahead) + ctx->rc_lookahead = ctx->encode_config.rcParams.lookaheadDepth; + + if (ctx->init_encode_params.tuningInfo == NV_ENC_TUNING_INFO_LOSSLESS) + ctx->flags |= NVENC_LOSSLESS; +#endif + if (ctx->weighted_pred == 1) ctx->init_encode_params.enableWeightedPrediction = 1; @@ -1509,6 +1571,8 @@ av_cold int ff_nvenc_encode_close(AVCodecContext *avctx) av_freep(&ctx->surfaces); ctx->nb_surfaces = 0; + av_frame_free(&ctx->frame); + if (ctx->nvencoder) { p_nvenc->nvEncDestroyEncoder(ctx->nvencoder); @@ -1562,6 +1626,10 @@ av_cold int ff_nvenc_encode_init(AVCodecContext *avctx) ctx->data_pix_fmt = avctx->pix_fmt; } + ctx->frame = av_frame_alloc(); + if (!ctx->frame) + return AVERROR(ENOMEM); + if ((ret = nvenc_load_libraries(avctx)) < 0) return ret; @@ -1776,7 +1844,8 @@ static int nvenc_upload_frame(AVCodecContext *avctx, const AVFrame *frame, static void nvenc_codec_specific_pic_params(AVCodecContext *avctx, NV_ENC_PIC_PARAMS *params, - NV_ENC_SEI_PAYLOAD *sei_data) + NV_ENC_SEI_PAYLOAD *sei_data, + int sei_count) { NvencContext *ctx = avctx->priv_data; @@ -1786,9 +1855,9 @@ static void nvenc_codec_specific_pic_params(AVCodecContext *avctx, ctx->encode_config.encodeCodecConfig.h264Config.sliceMode; params->codecPicParams.h264PicParams.sliceModeData = ctx->encode_config.encodeCodecConfig.h264Config.sliceModeData; - if (sei_data) { + if (sei_count > 0) { params->codecPicParams.h264PicParams.seiPayloadArray = sei_data; - params->codecPicParams.h264PicParams.seiPayloadArrayCnt = 1; + params->codecPicParams.h264PicParams.seiPayloadArrayCnt = sei_count; } break; @@ -1797,9 +1866,9 @@ static void nvenc_codec_specific_pic_params(AVCodecContext *avctx, ctx->encode_config.encodeCodecConfig.hevcConfig.sliceMode; params->codecPicParams.hevcPicParams.sliceModeData = ctx->encode_config.encodeCodecConfig.hevcConfig.sliceModeData; - if (sei_data) { + if (sei_count > 0) { params->codecPicParams.hevcPicParams.seiPayloadArray = sei_data; - params->codecPicParams.hevcPicParams.seiPayloadArrayCnt = 1; + params->codecPicParams.hevcPicParams.seiPayloadArrayCnt = sei_count; } break; @@ -1879,9 +1948,7 @@ static int process_output_surface(AVCodecContext *avctx, AVPacket *pkt, NvencSur goto error; } - res = pkt->data ? - ff_alloc_packet2(avctx, pkt, lock_params.bitstreamSizeInBytes, lock_params.bitstreamSizeInBytes) : - av_new_packet(pkt, lock_params.bitstreamSizeInBytes); + res = av_new_packet(pkt, lock_params.bitstreamSizeInBytes); if (res < 0) { p_nvenc->nvEncUnlockBitstream(ctx->nvencoder, tmpoutsurf->output_surface); @@ -2067,13 +2134,14 @@ static void reconfig_encoder(AVCodecContext *avctx, const AVFrame *frame) } } -int ff_nvenc_send_frame(AVCodecContext *avctx, const AVFrame *frame) +static int nvenc_send_frame(AVCodecContext *avctx, const AVFrame *frame) { NVENCSTATUS nv_status; NvencSurface *tmp_out_surf, *in_surf; int res, res2; - NV_ENC_SEI_PAYLOAD *sei_data = NULL; - size_t sei_size; + NV_ENC_SEI_PAYLOAD sei_data[8]; + int sei_count = 0; + int i; NvencContext *ctx = avctx->priv_data; NvencDynLoadFunctions *dl_fn = &ctx->nvenc_dload_funcs; @@ -2085,15 +2153,7 @@ int ff_nvenc_send_frame(AVCodecContext *avctx, const AVFrame *frame) if ((!ctx->cu_context && !ctx->d3d11_device) || !ctx->nvencoder) return AVERROR(EINVAL); - if (ctx->encoder_flushing) { - if (avctx->internal->draining) - return AVERROR_EOF; - - ctx->encoder_flushing = 0; - av_fifo_reset(ctx->timestamp_list); - } - - if (frame) { + if (frame && frame->buf[0]) { in_surf = get_free_frame(ctx); if (!in_surf) return AVERROR(EAGAIN); @@ -2139,21 +2199,40 @@ int ff_nvenc_send_frame(AVCodecContext *avctx, const AVFrame *frame) pic_params.inputTimeStamp = frame->pts; if (ctx->a53_cc && av_frame_get_side_data(frame, AV_FRAME_DATA_A53_CC)) { - if (ff_alloc_a53_sei(frame, sizeof(NV_ENC_SEI_PAYLOAD), (void**)&sei_data, &sei_size) < 0) { + void *a53_data = NULL; + size_t a53_size = 0; + + if (ff_alloc_a53_sei(frame, 0, (void**)&a53_data, &a53_size) < 0) { av_log(ctx, AV_LOG_ERROR, "Not enough memory for closed captions, skipping\n"); } - if (sei_data) { - sei_data->payloadSize = (uint32_t)sei_size; - sei_data->payloadType = 4; - sei_data->payload = (uint8_t*)(sei_data + 1); + if (a53_data) { + sei_data[sei_count].payloadSize = (uint32_t)a53_size; + sei_data[sei_count].payloadType = 4; + sei_data[sei_count].payload = (uint8_t*)a53_data; + sei_count ++; } } - nvenc_codec_specific_pic_params(avctx, &pic_params, sei_data); + if (ctx->s12m_tc && av_frame_get_side_data(frame, AV_FRAME_DATA_S12M_TIMECODE)) { + void *tc_data = NULL; + size_t tc_size = 0; + + if (ff_alloc_timecode_sei(frame, 0, (void**)&tc_data, &tc_size) < 0) { + av_log(ctx, AV_LOG_ERROR, "Not enough memory for timecode sei, skipping\n"); + } + + if (tc_data) { + sei_data[sei_count].payloadSize = (uint32_t)tc_size; + sei_data[sei_count].payloadType = HEVC_SEI_TYPE_TIME_CODE; + sei_data[sei_count].payload = (uint8_t*)tc_data; + sei_count ++; + } + } + + nvenc_codec_specific_pic_params(avctx, &pic_params, sei_data, sei_count); } else { pic_params.encodePicFlags = NV_ENC_PIC_FLAG_EOS; - ctx->encoder_flushing = 1; } res = nvenc_push_context(avctx); @@ -2161,7 +2240,9 @@ int ff_nvenc_send_frame(AVCodecContext *avctx, const AVFrame *frame) return res; nv_status = p_nvenc->nvEncEncodePicture(ctx->nvencoder, &pic_params); - av_free(sei_data); + + for ( i = 0; i < sei_count; i++) + av_freep(&sei_data[i].payload); res = nvenc_pop_context(avctx); if (res < 0) @@ -2171,7 +2252,7 @@ int ff_nvenc_send_frame(AVCodecContext *avctx, const AVFrame *frame) nv_status != NV_ENC_ERR_NEED_MORE_INPUT) return nvenc_print_error(avctx, nv_status, "EncodePicture failed!"); - if (frame) { + if (frame && frame->buf[0]) { av_fifo_generic_write(ctx->output_surface_queue, &in_surf, sizeof(in_surf), NULL); timestamp_queue_enqueue(ctx->timestamp_list, frame->pts); } @@ -2194,10 +2275,25 @@ int ff_nvenc_receive_packet(AVCodecContext *avctx, AVPacket *pkt) NvencContext *ctx = avctx->priv_data; + AVFrame *frame = ctx->frame; + if ((!ctx->cu_context && !ctx->d3d11_device) || !ctx->nvencoder) return AVERROR(EINVAL); - if (output_ready(avctx, ctx->encoder_flushing)) { + if (!frame->buf[0]) { + res = ff_encode_get_frame(avctx, frame); + if (res < 0 && res != AVERROR_EOF) + return res; + } + + res = nvenc_send_frame(avctx, frame); + if (res < 0) { + if (res != AVERROR(EAGAIN)) + return res; + } else + av_frame_unref(frame); + + if (output_ready(avctx, avctx->internal->draining)) { av_fifo_generic_read(ctx->output_surface_ready_queue, &tmp_out_surf, sizeof(tmp_out_surf), NULL); res = nvenc_push_context(avctx); @@ -2214,7 +2310,7 @@ int ff_nvenc_receive_packet(AVCodecContext *avctx, AVPacket *pkt) return res; av_fifo_generic_write(ctx->unused_surface_queue, &tmp_out_surf, sizeof(tmp_out_surf), NULL); - } else if (ctx->encoder_flushing) { + } else if (avctx->internal->draining) { return AVERROR_EOF; } else { return AVERROR(EAGAIN); @@ -2223,31 +2319,10 @@ int ff_nvenc_receive_packet(AVCodecContext *avctx, AVPacket *pkt) return 0; } -int ff_nvenc_encode_frame(AVCodecContext *avctx, AVPacket *pkt, - const AVFrame *frame, int *got_packet) -{ - NvencContext *ctx = avctx->priv_data; - int res; - - if (!ctx->encoder_flushing) { - res = ff_nvenc_send_frame(avctx, frame); - if (res < 0) - return res; - } - - res = ff_nvenc_receive_packet(avctx, pkt); - if (res == AVERROR(EAGAIN) || res == AVERROR_EOF) { - *got_packet = 0; - } else if (res < 0) { - return res; - } else { - *got_packet = 1; - } - - return 0; -} - av_cold void ff_nvenc_encode_flush(AVCodecContext *avctx) { - ff_nvenc_send_frame(avctx, NULL); + NvencContext *ctx = avctx->priv_data; + + nvenc_send_frame(avctx, NULL); + av_fifo_reset(ctx->timestamp_list); } diff --git a/externals/ffmpeg/libavcodec/nvenc.h b/externals/ffmpeg/libavcodec/nvenc.h index 7a415a483..fb3820f7c 100755 --- a/externals/ffmpeg/libavcodec/nvenc.h +++ b/externals/ffmpeg/libavcodec/nvenc.h @@ -62,6 +62,14 @@ typedef void ID3D11Device; #define NVENC_HAVE_GETLASTERRORSTRING #endif +// SDK 10.0 compile time feature checks +#if NVENCAPI_CHECK_VERSION(10, 0) +#define NVENC_HAVE_NEW_PRESETS +#define NVENC_HAVE_MULTIPASS +#define NVENC_HAVE_LDKFS +#define NVENC_HAVE_H264_LVL6 +#endif + typedef struct NvencSurface { NV_ENC_INPUT_PTR input_surface; @@ -98,6 +106,15 @@ enum { PRESET_LOW_LATENCY_HP, PRESET_LOSSLESS_DEFAULT, // lossless presets must be the last ones PRESET_LOSSLESS_HP, +#ifdef NVENC_HAVE_NEW_PRESETS + PRESET_P1, + PRESET_P2, + PRESET_P3, + PRESET_P4, + PRESET_P5, + PRESET_P6, + PRESET_P7, +#endif }; enum { @@ -138,6 +155,8 @@ typedef struct NvencContext CUstream cu_stream; ID3D11Device *d3d11_device; + AVFrame *frame; + int nb_surfaces; NvencSurface *surfaces; @@ -146,8 +165,6 @@ typedef struct NvencContext AVFifoBuffer *output_surface_ready_queue; AVFifoBuffer *timestamp_list; - int encoder_flushing; - struct { void *ptr; int ptr_index; @@ -196,20 +213,19 @@ typedef struct NvencContext int coder; int b_ref_mode; int a53_cc; + int s12m_tc; int dpb_size; + int tuning_info; + int multipass; + int ldkfs; } NvencContext; int ff_nvenc_encode_init(AVCodecContext *avctx); int ff_nvenc_encode_close(AVCodecContext *avctx); -int ff_nvenc_send_frame(AVCodecContext *avctx, const AVFrame *frame); - int ff_nvenc_receive_packet(AVCodecContext *avctx, AVPacket *pkt); -int ff_nvenc_encode_frame(AVCodecContext *avctx, AVPacket *pkt, - const AVFrame *frame, int *got_packet); - void ff_nvenc_encode_flush(AVCodecContext *avctx); extern const enum AVPixelFormat ff_nvenc_pix_fmts[]; diff --git a/externals/ffmpeg/libavcodec/nvenc_h264.c b/externals/ffmpeg/libavcodec/nvenc_h264.c index c877cf4a3..de8f4bd18 100755 --- a/externals/ffmpeg/libavcodec/nvenc_h264.c +++ b/externals/ffmpeg/libavcodec/nvenc_h264.c @@ -26,7 +26,11 @@ #define OFFSET(x) offsetof(NvencContext, x) #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM static const AVOption options[] = { +#ifdef NVENC_HAVE_NEW_PRESETS + { "preset", "Set the encoding preset", OFFSET(preset), AV_OPT_TYPE_INT, { .i64 = PRESET_P4 }, PRESET_DEFAULT, PRESET_P7, VE, "preset" }, +#else { "preset", "Set the encoding preset", OFFSET(preset), AV_OPT_TYPE_INT, { .i64 = PRESET_MEDIUM }, PRESET_DEFAULT, PRESET_LOSSLESS_HP, VE, "preset" }, +#endif { "default", "", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_DEFAULT }, 0, 0, VE, "preset" }, { "slow", "hq 2 passes", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_SLOW }, 0, 0, VE, "preset" }, { "medium", "hq 1 pass", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_MEDIUM }, 0, 0, VE, "preset" }, @@ -39,12 +43,30 @@ static const AVOption options[] = { { "llhp", "low latency hp", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_LOW_LATENCY_HP }, 0, 0, VE, "preset" }, { "lossless", "", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_LOSSLESS_DEFAULT }, 0, 0, VE, "preset" }, { "losslesshp", "", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_LOSSLESS_HP }, 0, 0, VE, "preset" }, +#ifdef NVENC_HAVE_NEW_PRESETS + { "p1", "fastest (lowest quality)", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_P1 }, 0, 0, VE, "preset" }, + { "p2", "faster (lower quality)", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_P2 }, 0, 0, VE, "preset" }, + { "p3", "fast (low quality)", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_P3 }, 0, 0, VE, "preset" }, + { "p4", "medium (default)", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_P4 }, 0, 0, VE, "preset" }, + { "p5", "slow (good quality)", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_P5 }, 0, 0, VE, "preset" }, + { "p6", "slower (better quality)", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_P6 }, 0, 0, VE, "preset" }, + { "p7", "slowest (best quality)", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_P7 }, 0, 0, VE, "preset" }, + { "tune", "Set the encoding tuning info", OFFSET(tuning_info), AV_OPT_TYPE_INT, { .i64 = NV_ENC_TUNING_INFO_HIGH_QUALITY }, NV_ENC_TUNING_INFO_HIGH_QUALITY, NV_ENC_TUNING_INFO_LOSSLESS, VE, "tune" }, + { "hq", "High quality", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_TUNING_INFO_HIGH_QUALITY }, 0, 0, VE, "tune" }, + { "ll", "Low latency", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_TUNING_INFO_LOW_LATENCY }, 0, 0, VE, "tune" }, + { "ull", "Ultra low latency", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_TUNING_INFO_ULTRA_LOW_LATENCY }, 0, 0, VE, "tune" }, + { "lossless", "Lossless", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_TUNING_INFO_LOSSLESS }, 0, 0, VE, "tune" }, +#endif { "profile", "Set the encoding profile", OFFSET(profile), AV_OPT_TYPE_INT, { .i64 = NV_ENC_H264_PROFILE_MAIN }, NV_ENC_H264_PROFILE_BASELINE, NV_ENC_H264_PROFILE_HIGH_444P, VE, "profile" }, { "baseline", "", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_H264_PROFILE_BASELINE }, 0, 0, VE, "profile" }, { "main", "", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_H264_PROFILE_MAIN }, 0, 0, VE, "profile" }, { "high", "", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_H264_PROFILE_HIGH }, 0, 0, VE, "profile" }, { "high444p", "", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_H264_PROFILE_HIGH_444P }, 0, 0, VE, "profile" }, - { "level", "Set the encoding level restriction", OFFSET(level), AV_OPT_TYPE_INT, { .i64 = NV_ENC_LEVEL_AUTOSELECT }, NV_ENC_LEVEL_AUTOSELECT, NV_ENC_LEVEL_H264_51, VE, "level" }, +#ifdef NVENC_HAVE_H264_LVL6 + { "level", "Set the encoding level restriction", OFFSET(level), AV_OPT_TYPE_INT, { .i64 = NV_ENC_LEVEL_AUTOSELECT }, NV_ENC_LEVEL_AUTOSELECT, NV_ENC_LEVEL_H264_62, VE, "level" }, +#else + { "level", "Set the encoding level restriction", OFFSET(level), AV_OPT_TYPE_INT, { .i64 = NV_ENC_LEVEL_AUTOSELECT }, NV_ENC_LEVEL_AUTOSELECT, NV_ENC_LEVEL_H264_52, VE, "level" }, +#endif { "auto", "", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_LEVEL_AUTOSELECT }, 0, 0, VE, "level" }, { "1", "", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_LEVEL_H264_1 }, 0, 0, VE, "level" }, { "1.0", "", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_LEVEL_H264_1 }, 0, 0, VE, "level" }, @@ -68,6 +90,12 @@ static const AVOption options[] = { { "5", "", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_LEVEL_H264_5 }, 0, 0, VE, "level" }, { "5.0", "", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_LEVEL_H264_5 }, 0, 0, VE, "level" }, { "5.1", "", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_LEVEL_H264_51 }, 0, 0, VE, "level" }, + { "5.2", "", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_LEVEL_H264_52 }, 0, 0, VE, "level" }, +#ifdef NVENC_HAVE_H264_LVL6 + { "6.0", "", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_LEVEL_H264_60 }, 0, 0, VE, "level" }, + { "6.1", "", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_LEVEL_H264_61 }, 0, 0, VE, "level" }, + { "6.2", "", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_LEVEL_H264_62 }, 0, 0, VE, "level" }, +#endif { "rc", "Override the preset rate-control", OFFSET(rc), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, VE, "rc" }, { "constqp", "Constant QP mode", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_PARAMS_RC_CONSTQP }, 0, 0, VE, "rc" }, { "vbr", "Variable bitrate mode", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_PARAMS_RC_VBR }, 0, 0, VE, "rc" }, @@ -142,6 +170,18 @@ static const AVOption options[] = { { "a53cc", "Use A53 Closed Captions (if available)", OFFSET(a53_cc), AV_OPT_TYPE_BOOL, { .i64 = 1 }, 0, 1, VE }, { "dpb_size", "Specifies the DPB size used for encoding (0 means automatic)", OFFSET(dpb_size), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, VE }, +#ifdef NVENC_HAVE_MULTIPASS + { "multipass", "Set the multipass encoding", OFFSET(multipass), AV_OPT_TYPE_INT, { .i64 = NV_ENC_MULTI_PASS_DISABLED }, NV_ENC_MULTI_PASS_DISABLED, NV_ENC_TWO_PASS_FULL_RESOLUTION, VE, "multipass" }, + { "disabled", "Single Pass", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_MULTI_PASS_DISABLED }, 0, 0, VE, "multipass" }, + { "qres", "Two Pass encoding is enabled where first Pass is quarter resolution", + 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_TWO_PASS_QUARTER_RESOLUTION }, 0, 0, VE, "multipass" }, + { "fullres", "Two Pass encoding is enabled where first Pass is full resolution", + 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_TWO_PASS_FULL_RESOLUTION }, 0, 0, VE, "multipass" }, +#endif +#ifdef NVENC_HAVE_LDKFS + { "ldkfs", "Low delay key frame scale; Specifies the Scene Change frame size increase allowed in case of single frame VBV and CBR", + OFFSET(ldkfs), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, UCHAR_MAX, VE }, +#endif { NULL } }; @@ -180,9 +220,7 @@ AVCodec ff_nvenc_encoder = { .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_H264, .init = nvenc_old_init, - .send_frame = ff_nvenc_send_frame, .receive_packet = ff_nvenc_receive_packet, - .encode2 = ff_nvenc_encode_frame, .close = ff_nvenc_encode_close, .flush = ff_nvenc_encode_flush, .priv_data_size = sizeof(NvencContext), @@ -212,9 +250,7 @@ AVCodec ff_nvenc_h264_encoder = { .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_H264, .init = nvenc_old_init, - .send_frame = ff_nvenc_send_frame, .receive_packet = ff_nvenc_receive_packet, - .encode2 = ff_nvenc_encode_frame, .close = ff_nvenc_encode_close, .flush = ff_nvenc_encode_flush, .priv_data_size = sizeof(NvencContext), @@ -244,9 +280,7 @@ AVCodec ff_h264_nvenc_encoder = { .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_H264, .init = ff_nvenc_encode_init, - .send_frame = ff_nvenc_send_frame, .receive_packet = ff_nvenc_receive_packet, - .encode2 = ff_nvenc_encode_frame, .close = ff_nvenc_encode_close, .flush = ff_nvenc_encode_flush, .priv_data_size = sizeof(NvencContext), diff --git a/externals/ffmpeg/libavcodec/nvenc_hevc.c b/externals/ffmpeg/libavcodec/nvenc_hevc.c index 7f12b56a4..074975f78 100755 --- a/externals/ffmpeg/libavcodec/nvenc_hevc.c +++ b/externals/ffmpeg/libavcodec/nvenc_hevc.c @@ -26,7 +26,11 @@ #define OFFSET(x) offsetof(NvencContext, x) #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM static const AVOption options[] = { +#ifdef NVENC_HAVE_NEW_PRESETS + { "preset", "Set the encoding preset", OFFSET(preset), AV_OPT_TYPE_INT, { .i64 = PRESET_P4 }, PRESET_DEFAULT, PRESET_P7, VE, "preset" }, +#else { "preset", "Set the encoding preset", OFFSET(preset), AV_OPT_TYPE_INT, { .i64 = PRESET_MEDIUM }, PRESET_DEFAULT, PRESET_LOSSLESS_HP, VE, "preset" }, +#endif { "default", "", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_DEFAULT }, 0, 0, VE, "preset" }, { "slow", "hq 2 passes", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_SLOW }, 0, 0, VE, "preset" }, { "medium", "hq 1 pass", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_MEDIUM }, 0, 0, VE, "preset" }, @@ -39,6 +43,20 @@ static const AVOption options[] = { { "llhp", "low latency hp", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_LOW_LATENCY_HP }, 0, 0, VE, "preset" }, { "lossless", "lossless", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_LOSSLESS_DEFAULT }, 0, 0, VE, "preset" }, { "losslesshp", "lossless hp", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_LOSSLESS_HP }, 0, 0, VE, "preset" }, +#ifdef NVENC_HAVE_NEW_PRESETS + { "p1", "fastest (lowest quality)", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_P1 }, 0, 0, VE, "preset" }, + { "p2", "faster (lower quality)", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_P2 }, 0, 0, VE, "preset" }, + { "p3", "fast (low quality)", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_P3 }, 0, 0, VE, "preset" }, + { "p4", "medium (default)", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_P4 }, 0, 0, VE, "preset" }, + { "p5", "slow (good quality)", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_P5 }, 0, 0, VE, "preset" }, + { "p6", "slower (better quality)", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_P6 }, 0, 0, VE, "preset" }, + { "p7", "slowest (best quality)", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_P7 }, 0, 0, VE, "preset" }, + { "tune", "Set the encoding tuning info", OFFSET(tuning_info), AV_OPT_TYPE_INT, { .i64 = NV_ENC_TUNING_INFO_HIGH_QUALITY }, NV_ENC_TUNING_INFO_HIGH_QUALITY, NV_ENC_TUNING_INFO_LOSSLESS, VE, "tune" }, + { "hq", "High quality", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_TUNING_INFO_HIGH_QUALITY }, 0, 0, VE, "tune" }, + { "ll", "Low latency", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_TUNING_INFO_LOW_LATENCY }, 0, 0, VE, "tune" }, + { "ull", "Ultra low latency", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_TUNING_INFO_ULTRA_LOW_LATENCY }, 0, 0, VE, "tune" }, + { "lossless", "Lossless", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_TUNING_INFO_LOSSLESS }, 0, 0, VE, "tune" }, +#endif { "profile", "Set the encoding profile", OFFSET(profile), AV_OPT_TYPE_INT, { .i64 = NV_ENC_HEVC_PROFILE_MAIN }, NV_ENC_HEVC_PROFILE_MAIN, FF_PROFILE_HEVC_REXT, VE, "profile" }, { "main", "", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_HEVC_PROFILE_MAIN }, 0, 0, VE, "profile" }, { "main10", "", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_HEVC_PROFILE_MAIN_10 }, 0, 0, VE, "profile" }, @@ -129,8 +147,22 @@ static const AVOption options[] = { { "each", "", 0, AV_OPT_TYPE_CONST, { .i64 = 1 }, 0, 0, VE, "b_ref_mode" }, { "middle", "", 0, AV_OPT_TYPE_CONST, { .i64 = 2 }, 0, 0, VE, "b_ref_mode" }, #endif + { "a53cc", "Use A53 Closed Captions (if available)", OFFSET(a53_cc), AV_OPT_TYPE_BOOL, { .i64 = 1 }, 0, 1, VE }, + { "s12m_tc", "Use timecode (if available)", OFFSET(s12m_tc), AV_OPT_TYPE_BOOL, { .i64 = 1 }, 0, 1, VE }, { "dpb_size", "Specifies the DPB size used for encoding (0 means automatic)", OFFSET(dpb_size), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, VE }, +#ifdef NVENC_HAVE_MULTIPASS + { "multipass", "Set the multipass encoding", OFFSET(multipass), AV_OPT_TYPE_INT, { .i64 = NV_ENC_MULTI_PASS_DISABLED }, NV_ENC_MULTI_PASS_DISABLED, NV_ENC_TWO_PASS_FULL_RESOLUTION, VE, "multipass" }, + { "disabled", "Single Pass", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_MULTI_PASS_DISABLED }, 0, 0, VE, "multipass" }, + { "qres", "Two Pass encoding is enabled where first Pass is quarter resolution", + 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_TWO_PASS_QUARTER_RESOLUTION }, 0, 0, VE, "multipass" }, + { "fullres", "Two Pass encoding is enabled where first Pass is full resolution", + 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_TWO_PASS_FULL_RESOLUTION }, 0, 0, VE, "multipass" }, +#endif +#ifdef NVENC_HAVE_LDKFS + { "ldkfs", "Low delay key frame scale; Specifies the Scene Change frame size increase allowed in case of single frame VBV and CBR", + OFFSET(ldkfs), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, UCHAR_MAX, VE }, +#endif { NULL } }; @@ -168,9 +200,7 @@ AVCodec ff_nvenc_hevc_encoder = { .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_HEVC, .init = nvenc_old_init, - .send_frame = ff_nvenc_send_frame, .receive_packet = ff_nvenc_receive_packet, - .encode2 = ff_nvenc_encode_frame, .close = ff_nvenc_encode_close, .priv_data_size = sizeof(NvencContext), .priv_class = &nvenc_hevc_class, @@ -198,9 +228,7 @@ AVCodec ff_hevc_nvenc_encoder = { .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_HEVC, .init = ff_nvenc_encode_init, - .send_frame = ff_nvenc_send_frame, .receive_packet = ff_nvenc_receive_packet, - .encode2 = ff_nvenc_encode_frame, .close = ff_nvenc_encode_close, .flush = ff_nvenc_encode_flush, .priv_data_size = sizeof(NvencContext), diff --git a/externals/ffmpeg/libavcodec/options.c b/externals/ffmpeg/libavcodec/options.c index 7706a0329..ff16e2cbf 100755 --- a/externals/ffmpeg/libavcodec/options.c +++ b/externals/ffmpeg/libavcodec/options.c @@ -53,6 +53,7 @@ static void *codec_child_next(void *obj, void *prev) return NULL; } +#if FF_API_CHILD_CLASS_NEXT static const AVClass *codec_child_class_next(const AVClass *prev) { void *iter = NULL; @@ -69,6 +70,17 @@ static const AVClass *codec_child_class_next(const AVClass *prev) return c->priv_class; return NULL; } +#endif + +static const AVClass *codec_child_class_iterate(void **iter) +{ + const AVCodec *c; + /* find next codec with priv options */ + while (c = av_codec_iterate(iter)) + if (c->priv_class) + return c->priv_class; + return NULL; +} static AVClassCategory get_category(void *ptr) { @@ -84,7 +96,10 @@ static const AVClass av_codec_context_class = { .version = LIBAVUTIL_VERSION_INT, .log_level_offset_offset = offsetof(AVCodecContext, log_level_offset), .child_next = codec_child_next, +#if FF_API_CHILD_CLASS_NEXT .child_class_next = codec_child_class_next, +#endif + .child_class_iterate = codec_child_class_iterate, .category = AV_CLASS_CATEGORY_ENCODER, .get_category = get_category, }; diff --git a/externals/ffmpeg/libavcodec/packet.h b/externals/ffmpeg/libavcodec/packet.h index 41485f452..96f237f09 100755 --- a/externals/ffmpeg/libavcodec/packet.h +++ b/externals/ffmpeg/libavcodec/packet.h @@ -580,7 +580,8 @@ int av_packet_shrink_side_data(AVPacket *pkt, enum AVPacketSideDataType type, * * @param pkt packet * @param type desired side information type - * @param size pointer for side information size to store (optional) + * @param size If supplied, *size will be set to the size of the side data + * or to zero if the desired side data is not present. * @return pointer to data if present or NULL otherwise */ uint8_t* av_packet_get_side_data(const AVPacket *pkt, enum AVPacketSideDataType type, diff --git a/externals/ffmpeg/libavcodec/pgxdec.c b/externals/ffmpeg/libavcodec/pgxdec.c new file mode 100755 index 000000000..93b9f4e7a --- /dev/null +++ b/externals/ffmpeg/libavcodec/pgxdec.c @@ -0,0 +1,168 @@ +/* + * PGX image format + * Copyright (c) 2020 Gautam Ramakrishnan + * + * 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 "avcodec.h" +#include "internal.h" +#include "bytestream.h" +#include "libavutil/imgutils.h" + +static int pgx_get_number(AVCodecContext *avctx, GetByteContext *g, int *number) { + int ret = AVERROR_INVALIDDATA; + char digit; + + *number = 0; + while (1) { + uint64_t temp; + if (!bytestream2_get_bytes_left(g)) + return AVERROR_INVALIDDATA; + digit = bytestream2_get_byte(g); + if (digit == ' ' || digit == 0xA || digit == 0xD) + break; + else if (digit < '0' || digit > '9') + return AVERROR_INVALIDDATA; + + temp = (uint64_t)10 * (*number) + (digit - '0'); + if (temp > INT_MAX) + return AVERROR_INVALIDDATA; + *number = temp; + ret = 0; + } + + return ret; +} + +static int pgx_decode_header(AVCodecContext *avctx, GetByteContext *g, + int *depth, int *width, int *height, + int *sign) +{ + int byte; + + if (bytestream2_get_bytes_left(g) < 6) { + return AVERROR_INVALIDDATA; + } + + bytestream2_skip(g, 6); + + // Is the component signed? + byte = bytestream2_peek_byte(g); + if (byte == '+') { + *sign = 0; + bytestream2_skip(g, 1); + } else if (byte == '-') { + *sign = 1; + bytestream2_skip(g, 1); + } else if (byte == 0) + goto error; + + byte = bytestream2_peek_byte(g); + if (byte == ' ') + bytestream2_skip(g, 1); + else if (byte == 0) + goto error; + + if (pgx_get_number(avctx, g, depth)) + goto error; + if (pgx_get_number(avctx, g, width)) + goto error; + if (pgx_get_number(avctx, g, height)) + goto error; + + if (bytestream2_peek_byte(g) == 0xA) + bytestream2_skip(g, 1); + return 0; + +error: + av_log(avctx, AV_LOG_ERROR, "Error in decoding header.\n"); + return AVERROR_INVALIDDATA; +} + +#define WRITE_FRAME(D, PIXEL, suffix) \ + static inline void write_frame_ ##D(AVPacket *avpkt, AVFrame *frame, GetByteContext *g, \ + int width, int height, int sign, int depth) \ + { \ + int i, j; \ + for (i = 0; i < height; i++) { \ + PIXEL *line = (PIXEL*)frame->data[0] + i*frame->linesize[0]/sizeof(PIXEL); \ + for (j = 0; j < width; j++) { \ + int val; \ + if (sign) \ + val = (PIXEL)bytestream2_get_ ##suffix(g) + (1 << (depth - 1)); \ + else \ + val = bytestream2_get_ ##suffix(g); \ + val <<= (D - depth); \ + *(line + j) = val; \ + } \ + } \ + } \ + +WRITE_FRAME(8, int8_t, byte) +WRITE_FRAME(16, int16_t, be16) + +static int pgx_decode_frame(AVCodecContext *avctx, void *data, + int *got_frame, AVPacket *avpkt) +{ + AVFrame *p = data; + int ret; + int bpp; + int width, height, depth; + int sign = 0; + GetByteContext g; + bytestream2_init(&g, avpkt->data, avpkt->size); + + if ((ret = pgx_decode_header(avctx, &g, &depth, &width, &height, &sign)) < 0) + return ret; + + if ((ret = ff_set_dimensions(avctx, width, height)) < 0) + return ret; + + if (depth <= 8) { + avctx->pix_fmt = AV_PIX_FMT_GRAY8; + bpp = 8; + } else if (depth <= 16) { + avctx->pix_fmt = AV_PIX_FMT_GRAY16BE; + bpp = 16; + } else { + av_log(avctx, AV_LOG_ERROR, "Maximum depth of 16 bits supported.\n"); + return AVERROR_PATCHWELCOME; + } + if (bytestream2_get_bytes_left(&g) < width * height * (bpp >> 3)) + return AVERROR_INVALIDDATA; + if ((ret = ff_get_buffer(avctx, p, 0)) < 0) + return ret; + p->pict_type = AV_PICTURE_TYPE_I; + p->key_frame = 1; + avctx->bits_per_raw_sample = depth; + if (bpp == 8) + write_frame_8(avpkt, p, &g, width, height, sign, depth); + else if (bpp == 16) + write_frame_16(avpkt, p, &g, width, height, sign, depth); + *got_frame = 1; + return 0; +} + +AVCodec ff_pgx_decoder = { + .name = "pgx", + .long_name = NULL_IF_CONFIG_SMALL("PGX (JPEG2000 Test Format)"), + .type = AVMEDIA_TYPE_VIDEO, + .id = AV_CODEC_ID_PGX, + .decode = pgx_decode_frame, + .capabilities = AV_CODEC_CAP_DR1, +}; diff --git a/externals/ffmpeg/libavcodec/profiles.h b/externals/ffmpeg/libavcodec/profiles.h index d2419257d..6baaba570 100755 --- a/externals/ffmpeg/libavcodec/profiles.h +++ b/externals/ffmpeg/libavcodec/profiles.h @@ -51,6 +51,11 @@ FF_AVCTX_PROFILE_OPTION("main", NULL, VIDEO, FF_PROFILE_MPEG2_MAIN)\ FF_AVCTX_PROFILE_OPTION("simple", NULL, VIDEO, FF_PROFILE_MPEG2_SIMPLE)\ +#define FF_AV1_PROFILE_OPTS \ + FF_AVCTX_PROFILE_OPTION("main", NULL, VIDEO, FF_PROFILE_AV1_MAIN)\ + FF_AVCTX_PROFILE_OPTION("high", NULL, VIDEO, FF_PROFILE_AV1_HIGH)\ + FF_AVCTX_PROFILE_OPTION("professional", NULL, VIDEO, FF_PROFILE_AV1_PROFESSIONAL)\ + extern const AVProfile ff_aac_profiles[]; extern const AVProfile ff_dca_profiles[]; extern const AVProfile ff_dnxhd_profiles[]; diff --git a/externals/ffmpeg/libavcodec/pthread_frame.c b/externals/ffmpeg/libavcodec/pthread_frame.c index 601f17044..3255aa933 100755 --- a/externals/ffmpeg/libavcodec/pthread_frame.c +++ b/externals/ffmpeg/libavcodec/pthread_frame.c @@ -246,7 +246,7 @@ static int update_context_from_thread(AVCodecContext *dst, AVCodecContext *src, { int err = 0; - if (dst != src && (for_user || !(src->codec_descriptor->props & AV_CODEC_PROP_INTRA_ONLY))) { + if (dst != src && (for_user || src->codec->update_thread_context)) { dst->time_base = src->time_base; dst->framerate = src->framerate; dst->width = src->width; diff --git a/externals/ffmpeg/libavcodec/qsv_internal.h b/externals/ffmpeg/libavcodec/qsv_internal.h index 6489836a6..6b2fbbe25 100755 --- a/externals/ffmpeg/libavcodec/qsv_internal.h +++ b/externals/ffmpeg/libavcodec/qsv_internal.h @@ -21,6 +21,8 @@ #ifndef AVCODEC_QSV_INTERNAL_H #define AVCODEC_QSV_INTERNAL_H +#include "config.h" + #if CONFIG_VAAPI #define AVCODEC_QSV_LINUX_SESSION_HANDLE #endif //CONFIG_VAAPI diff --git a/externals/ffmpeg/libavcodec/qsvenc.c b/externals/ffmpeg/libavcodec/qsvenc.c index ed4539f69..1ed8f5d97 100755 --- a/externals/ffmpeg/libavcodec/qsvenc.c +++ b/externals/ffmpeg/libavcodec/qsvenc.c @@ -735,6 +735,11 @@ FF_ENABLE_DEPRECATION_WARNINGS if (q->adaptive_b >= 0) q->extco2.AdaptiveB = q->adaptive_b ? MFX_CODINGOPTION_ON : MFX_CODINGOPTION_OFF; #endif + } + + if (avctx->codec_id == AV_CODEC_ID_H264 || avctx->codec_id == AV_CODEC_ID_HEVC) { + if (q->extbrc >= 0) + q->extco2.ExtBRC = q->extbrc ? MFX_CODINGOPTION_ON : MFX_CODINGOPTION_OFF; #if QSV_VERSION_ATLEAST(1, 9) if (avctx->qmin >= 0 && avctx->qmax >= 0 && avctx->qmin > avctx->qmax) { @@ -750,12 +755,6 @@ FF_ENABLE_DEPRECATION_WARNINGS q->extco2.MaxQPP = q->extco2.MaxQPB = q->extco2.MaxQPI; } #endif - } - - if (avctx->codec_id == AV_CODEC_ID_H264 || avctx->codec_id == AV_CODEC_ID_HEVC) { - if (q->extbrc >= 0) - q->extco2.ExtBRC = q->extbrc ? MFX_CODINGOPTION_ON : MFX_CODINGOPTION_OFF; - q->extco2.Header.BufferId = MFX_EXTBUFF_CODING_OPTION2; q->extco2.Header.BufferSz = sizeof(q->extco2); diff --git a/externals/ffmpeg/libavcodec/qsvenc_hevc.c b/externals/ffmpeg/libavcodec/qsvenc_hevc.c index 88c78a813..347f30655 100755 --- a/externals/ffmpeg/libavcodec/qsvenc_hevc.c +++ b/externals/ffmpeg/libavcodec/qsvenc_hevc.c @@ -263,6 +263,8 @@ static const AVCodecDefault qsv_enc_defaults[] = { // same as the x264 default { "g", "248" }, { "bf", "8" }, + { "qmin", "-1" }, + { "qmax", "-1" }, { "trellis", "-1" }, { "flags", "+cgop" }, #if FF_API_PRIVATE_OPT diff --git a/externals/ffmpeg/libavcodec/rv10.c b/externals/ffmpeg/libavcodec/rv10.c index 3b41d30b9..e594160fe 100755 --- a/externals/ffmpeg/libavcodec/rv10.c +++ b/externals/ffmpeg/libavcodec/rv10.c @@ -801,6 +801,7 @@ AVCodec ff_rv10_decoder = { .close = rv10_decode_end, .decode = rv10_decode_frame, .capabilities = AV_CODEC_CAP_DR1, + .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, .max_lowres = 3, .pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV420P, @@ -818,6 +819,7 @@ AVCodec ff_rv20_decoder = { .close = rv10_decode_end, .decode = rv10_decode_frame, .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY, + .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, .flush = ff_mpeg_flush, .max_lowres = 3, .pix_fmts = (const enum AVPixelFormat[]) { diff --git a/externals/ffmpeg/libavcodec/smacker.c b/externals/ffmpeg/libavcodec/smacker.c index b4c463b4b..9f054f071 100755 --- a/externals/ffmpeg/libavcodec/smacker.c +++ b/externals/ffmpeg/libavcodec/smacker.c @@ -600,13 +600,11 @@ static av_cold int decode_init(AVCodecContext *avctx) /* decode huffman trees from extradata */ if(avctx->extradata_size < 16){ av_log(avctx, AV_LOG_ERROR, "Extradata missing!\n"); - decode_end(avctx); return AVERROR(EINVAL); } ret = decode_header_trees(c); if (ret < 0) { - decode_end(avctx); return ret; } @@ -840,6 +838,7 @@ AVCodec ff_smacker_decoder = { .close = decode_end, .decode = decode_frame, .capabilities = AV_CODEC_CAP_DR1, + .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, }; AVCodec ff_smackaud_decoder = { diff --git a/externals/ffmpeg/libavcodec/smvjpegdec.c b/externals/ffmpeg/libavcodec/smvjpegdec.c index 7ea82ebfe..973a9117f 100755 --- a/externals/ffmpeg/libavcodec/smvjpegdec.c +++ b/externals/ffmpeg/libavcodec/smvjpegdec.c @@ -79,14 +79,12 @@ static av_cold int smvjpeg_decode_end(AVCodecContext *avctx) { SMVJpegDecodeContext *s = avctx->priv_data; MJpegDecodeContext *jpg = &s->jpg; - int ret; jpg->picture_ptr = NULL; av_frame_free(&s->picture[0]); av_frame_free(&s->picture[1]); - ret = avcodec_close(s->avctx); - av_freep(&s->avctx); - return ret; + avcodec_free_context(&s->avctx); + return 0; } static av_cold int smvjpeg_decode_init(AVCodecContext *avctx) diff --git a/externals/ffmpeg/libavcodec/snow.c b/externals/ffmpeg/libavcodec/snow.c index a3e6afc86..066efc517 100755 --- a/externals/ffmpeg/libavcodec/snow.c +++ b/externals/ffmpeg/libavcodec/snow.c @@ -487,28 +487,27 @@ av_cold int ff_snow_common_init(AVCodecContext *avctx){ width= s->avctx->width; height= s->avctx->height; - FF_ALLOCZ_ARRAY_OR_GOTO(avctx, s->spatial_idwt_buffer, width, height * sizeof(IDWTELEM), fail); - FF_ALLOCZ_ARRAY_OR_GOTO(avctx, s->spatial_dwt_buffer, width, height * sizeof(DWTELEM), fail); //FIXME this does not belong here - FF_ALLOCZ_ARRAY_OR_GOTO(avctx, s->temp_dwt_buffer, width, sizeof(DWTELEM), fail); - FF_ALLOCZ_ARRAY_OR_GOTO(avctx, s->temp_idwt_buffer, width, sizeof(IDWTELEM), fail); - FF_ALLOC_ARRAY_OR_GOTO(avctx, s->run_buffer, ((width + 1) >> 1), ((height + 1) >> 1) * sizeof(*s->run_buffer), fail); + if (!FF_ALLOCZ_TYPED_ARRAY(s->spatial_idwt_buffer, width * height) || + !FF_ALLOCZ_TYPED_ARRAY(s->spatial_dwt_buffer, width * height) || //FIXME this does not belong here + !FF_ALLOCZ_TYPED_ARRAY(s->temp_dwt_buffer, width) || + !FF_ALLOCZ_TYPED_ARRAY(s->temp_idwt_buffer, width) || + !FF_ALLOCZ_TYPED_ARRAY(s->run_buffer, ((width + 1) >> 1) * ((height + 1) >> 1))) + return AVERROR(ENOMEM); for(i=0; ilast_picture[i] = av_frame_alloc(); if (!s->last_picture[i]) - goto fail; + return AVERROR(ENOMEM); } s->mconly_picture = av_frame_alloc(); s->current_picture = av_frame_alloc(); if (!s->mconly_picture || !s->current_picture) - goto fail; + return AVERROR(ENOMEM); return 0; -fail: - return AVERROR(ENOMEM); } int ff_snow_common_init_after_header(AVCodecContext *avctx) { @@ -520,9 +519,10 @@ int ff_snow_common_init_after_header(AVCodecContext *avctx) { if ((ret = ff_get_buffer(s->avctx, s->mconly_picture, AV_GET_BUFFER_FLAG_REF)) < 0) return ret; - FF_ALLOCZ_ARRAY_OR_GOTO(avctx, s->scratchbuf, FFMAX(s->mconly_picture->linesize[0], 2*avctx->width+256), 7*MB_SIZE, fail); emu_buf_size = FFMAX(s->mconly_picture->linesize[0], 2*avctx->width+256) * (2 * MB_SIZE + HTAPS_MAX - 1); - FF_ALLOC_OR_GOTO(avctx, s->emu_edge_buffer, emu_buf_size, fail); + if (!FF_ALLOCZ_TYPED_ARRAY(s->scratchbuf, FFMAX(s->mconly_picture->linesize[0], 2*avctx->width+256) * 7 * MB_SIZE) || + !FF_ALLOCZ_TYPED_ARRAY(s->emu_edge_buffer, emu_buf_size)) + return AVERROR(ENOMEM); } if(s->mconly_picture->format != avctx->pix_fmt) { @@ -571,7 +571,7 @@ int ff_snow_common_init_after_header(AVCodecContext *avctx) { av_freep(&b->x_coeff); b->x_coeff=av_mallocz_array(((b->width+1) * b->height+1), sizeof(x_and_coeff)); if (!b->x_coeff) - goto fail; + return AVERROR(ENOMEM); } w= (w+1)>>1; h= (h+1)>>1; @@ -579,8 +579,6 @@ int ff_snow_common_init_after_header(AVCodecContext *avctx) { } return 0; -fail: - return AVERROR(ENOMEM); } #define USE_HALFPEL_PLANE 0 diff --git a/externals/ffmpeg/libavcodec/sonic.c b/externals/ffmpeg/libavcodec/sonic.c index b82c44344..ea6ef10c9 100755 --- a/externals/ffmpeg/libavcodec/sonic.c +++ b/externals/ffmpeg/libavcodec/sonic.c @@ -458,8 +458,8 @@ static void predictor_init_state(int *k, int *state, int order) for (j = 0, p = i+1; p < order; j++,p++) { - int tmp = x + shift_down(k[j] * state[p], LATTICE_SHIFT); - state[p] += shift_down(k[j]*x, LATTICE_SHIFT); + int tmp = x + shift_down(k[j] * (unsigned)state[p], LATTICE_SHIFT); + state[p] += shift_down(k[j]* (unsigned)x, LATTICE_SHIFT); x = tmp; } } @@ -467,7 +467,7 @@ static void predictor_init_state(int *k, int *state, int order) static int predictor_calc_error(int *k, int *state, int order, int error) { - int i, x = error - shift_down(k[order-1] * state[order-1], LATTICE_SHIFT); + int i, x = error - shift_down(k[order-1] * (unsigned)state[order-1], LATTICE_SHIFT); #if 1 int *k_ptr = &(k[order-2]), diff --git a/externals/ffmpeg/libavcodec/speedhq.c b/externals/ffmpeg/libavcodec/speedhq.c index 890b8253c..b834b79f2 100755 --- a/externals/ffmpeg/libavcodec/speedhq.c +++ b/externals/ffmpeg/libavcodec/speedhq.c @@ -447,7 +447,7 @@ static int speedhq_decode_frame(AVCodecContext *avctx, } frame->key_frame = 1; - if (second_field_offset == 4) { + if (second_field_offset == 4 || second_field_offset == (buf_size-4)) { /* * Overlapping first and second fields is used to signal * encoding only a single field. In this case, "height" diff --git a/externals/ffmpeg/libavcodec/svq1enc.c b/externals/ffmpeg/libavcodec/svq1enc.c index cb215c250..4bf9eb9a0 100755 --- a/externals/ffmpeg/libavcodec/svq1enc.c +++ b/externals/ffmpeg/libavcodec/svq1enc.c @@ -529,7 +529,6 @@ static av_cold int svq1_encode_init(AVCodecContext *avctx) s->current_picture = av_frame_alloc(); s->last_picture = av_frame_alloc(); if (!s->current_picture || !s->last_picture) { - svq1_encode_end(avctx); return AVERROR(ENOMEM); } @@ -546,7 +545,6 @@ static av_cold int svq1_encode_init(AVCodecContext *avctx) s->m.avctx = avctx; if ((ret = ff_mpv_common_init(&s->m)) < 0) { - svq1_encode_end(avctx); return ret; } @@ -564,7 +562,6 @@ static av_cold int svq1_encode_init(AVCodecContext *avctx) if (!s->m.me.temp || !s->m.me.scratchpad || !s->m.me.map || !s->m.me.score_map || !s->mb_type || !s->dummy) { - svq1_encode_end(avctx); return AVERROR(ENOMEM); } @@ -692,6 +689,7 @@ AVCodec ff_svq1_encoder = { .init = svq1_encode_init, .encode2 = svq1_encode_frame, .close = svq1_encode_end, + .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, .pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV410P, AV_PIX_FMT_NONE }, }; diff --git a/externals/ffmpeg/libavcodec/tests/options.c b/externals/ffmpeg/libavcodec/tests/options.c index 2e19a6eac..010e3c014 100755 --- a/externals/ffmpeg/libavcodec/tests/options.c +++ b/externals/ffmpeg/libavcodec/tests/options.c @@ -167,7 +167,6 @@ static void test_copy(const AVCodec *c1, const AVCodec *c2) avcodec_copy_context(ctx2, ctx1); test_copy_print_codec(ctx1); test_copy_print_codec(ctx2); - avcodec_close(ctx1); } avcodec_free_context(&ctx1); avcodec_free_context(&ctx2); diff --git a/externals/ffmpeg/libavcodec/trace_headers_bsf.c b/externals/ffmpeg/libavcodec/trace_headers_bsf.c index 8ee4dbd66..b891730ba 100755 --- a/externals/ffmpeg/libavcodec/trace_headers_bsf.c +++ b/externals/ffmpeg/libavcodec/trace_headers_bsf.c @@ -52,7 +52,7 @@ static int trace_headers_init(AVBSFContext *bsf) err = ff_cbs_read_extradata(ctx->cbc, frag, bsf->par_in); - ff_cbs_fragment_reset(ctx->cbc, frag); + ff_cbs_fragment_reset(frag); } return err; @@ -62,7 +62,7 @@ static void trace_headers_close(AVBSFContext *bsf) { TraceHeadersContext *ctx = bsf->priv_data; - ff_cbs_fragment_free(ctx->cbc, &ctx->fragment); + ff_cbs_fragment_free(&ctx->fragment); ff_cbs_close(&ctx->cbc); } @@ -97,7 +97,7 @@ static int trace_headers(AVBSFContext *bsf, AVPacket *pkt) err = ff_cbs_read_packet(ctx->cbc, frag, pkt); - ff_cbs_fragment_reset(ctx->cbc, frag); + ff_cbs_fragment_reset(frag); if (err < 0) av_packet_unref(pkt); diff --git a/externals/ffmpeg/libavcodec/twinvq.c b/externals/ffmpeg/libavcodec/twinvq.c index 34ca1846b..6dfaf06b1 100755 --- a/externals/ffmpeg/libavcodec/twinvq.c +++ b/externals/ffmpeg/libavcodec/twinvq.c @@ -538,6 +538,7 @@ static av_cold int init_mdct_win(TwinVQContext *tctx) int size_m = mtab->size / mtab->fmode[TWINVQ_FT_MEDIUM].sub; int channels = tctx->avctx->channels; float norm = channels == 1 ? 2.0 : 1.0; + int table_size = 2 * mtab->size * channels; for (i = 0; i < 3; i++) { int bsize = tctx->mtab->size / tctx->mtab->fmode[i].sub; @@ -546,25 +547,17 @@ static av_cold int init_mdct_win(TwinVQContext *tctx) return ret; } - FF_ALLOC_ARRAY_OR_GOTO(tctx->avctx, tctx->tmp_buf, - mtab->size, sizeof(*tctx->tmp_buf), alloc_fail); - - FF_ALLOC_ARRAY_OR_GOTO(tctx->avctx, tctx->spectrum, - 2 * mtab->size, channels * sizeof(*tctx->spectrum), - alloc_fail); - FF_ALLOC_ARRAY_OR_GOTO(tctx->avctx, tctx->curr_frame, - 2 * mtab->size, channels * sizeof(*tctx->curr_frame), - alloc_fail); - FF_ALLOC_ARRAY_OR_GOTO(tctx->avctx, tctx->prev_frame, - 2 * mtab->size, channels * sizeof(*tctx->prev_frame), - alloc_fail); + if (!FF_ALLOC_TYPED_ARRAY(tctx->tmp_buf, mtab->size) || + !FF_ALLOC_TYPED_ARRAY(tctx->spectrum, table_size) || + !FF_ALLOC_TYPED_ARRAY(tctx->curr_frame, table_size) || + !FF_ALLOC_TYPED_ARRAY(tctx->prev_frame, table_size)) + return AVERROR(ENOMEM); for (i = 0; i < 3; i++) { int m = 4 * mtab->size / mtab->fmode[i].sub; double freq = 2 * M_PI / m; - FF_ALLOC_ARRAY_OR_GOTO(tctx->avctx, tctx->cos_tabs[i], - (m / 4), sizeof(*tctx->cos_tabs[i]), alloc_fail); - + if (!FF_ALLOC_TYPED_ARRAY(tctx->cos_tabs[i], m / 4)) + return AVERROR(ENOMEM); for (j = 0; j <= m / 8; j++) tctx->cos_tabs[i][j] = cos((2 * j + 1) * freq); for (j = 1; j < m / 8; j++) @@ -576,9 +569,6 @@ static av_cold int init_mdct_win(TwinVQContext *tctx) ff_init_ff_sine_windows(av_log2(mtab->size)); return 0; - -alloc_fail: - return AVERROR(ENOMEM); } /** diff --git a/externals/ffmpeg/libavcodec/utils.c b/externals/ffmpeg/libavcodec/utils.c index a9c69e30d..2ece34f92 100755 --- a/externals/ffmpeg/libavcodec/utils.c +++ b/externals/ffmpeg/libavcodec/utils.c @@ -50,6 +50,7 @@ #include "thread.h" #include "frame_thread_encoder.h" #include "internal.h" +#include "put_bits.h" #include "raw.h" #include "bytestream.h" #include "version.h" @@ -93,7 +94,7 @@ void av_fast_padded_mallocz(void *ptr, unsigned int *size, size_t min_size) int av_codec_is_encoder(const AVCodec *codec) { - return codec && (codec->encode_sub || codec->encode2 ||codec->send_frame); + return codec && (codec->encode_sub || codec->encode2 || codec->receive_packet); } int av_codec_is_decoder(const AVCodec *codec) @@ -585,13 +586,16 @@ int attribute_align_arg avcodec_open2(AVCodecContext *avctx, const AVCodec *code avci->to_free = av_frame_alloc(); avci->compat_decode_frame = av_frame_alloc(); + avci->compat_encode_packet = av_packet_alloc(); avci->buffer_frame = av_frame_alloc(); avci->buffer_pkt = av_packet_alloc(); + avci->es.in_frame = av_frame_alloc(); avci->ds.in_pkt = av_packet_alloc(); avci->last_pkt_props = av_packet_alloc(); - if (!avci->to_free || !avci->compat_decode_frame || + if (!avci->compat_decode_frame || !avci->compat_encode_packet || !avci->buffer_frame || !avci->buffer_pkt || - !avci->ds.in_pkt || !avci->last_pkt_props) { + !avci->es.in_frame || !avci->ds.in_pkt || + !avci->to_free || !avci->last_pkt_props) { ret = AVERROR(ENOMEM); goto free_and_end; } @@ -1041,10 +1045,12 @@ FF_ENABLE_DEPRECATION_WARNINGS av_frame_free(&avci->to_free); av_frame_free(&avci->compat_decode_frame); av_frame_free(&avci->buffer_frame); + av_packet_free(&avci->compat_encode_packet); av_packet_free(&avci->buffer_pkt); av_packet_free(&avci->last_pkt_props); av_packet_free(&avci->ds.in_pkt); + av_frame_free(&avci->es.in_frame); av_bsf_free(&avci->bsf); av_buffer_unref(&avci->pool); @@ -1079,9 +1085,10 @@ void avcodec_flush_buffers(AVCodecContext *avctx) avci->nb_draining_errors = 0; av_frame_unref(avci->buffer_frame); av_frame_unref(avci->compat_decode_frame); + av_packet_unref(avci->compat_encode_packet); av_packet_unref(avci->buffer_pkt); - avci->buffer_pkt_valid = 0; + av_frame_unref(avci->es.in_frame); av_packet_unref(avci->ds.in_pkt); if (HAVE_THREADS && avctx->active_thread_type & FF_THREAD_FRAME) @@ -1139,10 +1146,12 @@ av_cold int avcodec_close(AVCodecContext *avctx) av_frame_free(&avctx->internal->to_free); av_frame_free(&avctx->internal->compat_decode_frame); av_frame_free(&avctx->internal->buffer_frame); + av_packet_free(&avctx->internal->compat_encode_packet); av_packet_free(&avctx->internal->buffer_pkt); av_packet_free(&avctx->internal->last_pkt_props); av_packet_free(&avctx->internal->ds.in_pkt); + av_frame_free(&avctx->internal->es.in_frame); av_buffer_unref(&avctx->internal->pool); @@ -2236,6 +2245,68 @@ int ff_alloc_a53_sei(const AVFrame *frame, size_t prefix_len, return 0; } +static unsigned bcd2uint(uint8_t bcd) +{ + unsigned low = bcd & 0xf; + unsigned high = bcd >> 4; + if (low > 9 || high > 9) + return 0; + return low + 10*high; +} + +int ff_alloc_timecode_sei(const AVFrame *frame, size_t prefix_len, + void **data, size_t *sei_size) +{ + AVFrameSideData *sd = NULL; + uint8_t *sei_data; + PutBitContext pb; + uint32_t *tc; + int m; + + if (frame) + sd = av_frame_get_side_data(frame, AV_FRAME_DATA_S12M_TIMECODE); + + if (!sd) { + *data = NULL; + return 0; + } + tc = (uint32_t*)sd->data; + m = tc[0] & 3; + + *sei_size = sizeof(uint32_t) * 4; + *data = av_mallocz(*sei_size + prefix_len); + if (!*data) + return AVERROR(ENOMEM); + sei_data = (uint8_t*)*data + prefix_len; + + init_put_bits(&pb, sei_data, *sei_size); + put_bits(&pb, 2, m); // num_clock_ts + + for (int j = 1; j <= m; j++) { + uint32_t tcsmpte = tc[j]; + unsigned hh = bcd2uint(tcsmpte & 0x3f); // 6-bit hours + unsigned mm = bcd2uint(tcsmpte>>8 & 0x7f); // 7-bit minutes + unsigned ss = bcd2uint(tcsmpte>>16 & 0x7f); // 7-bit seconds + unsigned ff = bcd2uint(tcsmpte>>24 & 0x3f); // 6-bit frames + unsigned drop = tcsmpte & 1<<30 && !0; // 1-bit drop if not arbitrary bit + + put_bits(&pb, 1, 1); // clock_timestamp_flag + put_bits(&pb, 1, 1); // units_field_based_flag + put_bits(&pb, 5, 0); // counting_type + put_bits(&pb, 1, 1); // full_timestamp_flag + put_bits(&pb, 1, 0); // discontinuity_flag + put_bits(&pb, 1, drop); + put_bits(&pb, 9, ff); + put_bits(&pb, 6, ss); + put_bits(&pb, 6, mm); + put_bits(&pb, 5, hh); + put_bits(&pb, 5, 0); + } + flush_put_bits(&pb); + + return 0; +} + int64_t ff_guess_coded_bitrate(AVCodecContext *avctx) { AVRational framerate = avctx->framerate; diff --git a/externals/ffmpeg/libavcodec/v4l2_m2m.c b/externals/ffmpeg/libavcodec/v4l2_m2m.c index e48b3a8cc..d8d872ea0 100755 --- a/externals/ffmpeg/libavcodec/v4l2_m2m.c +++ b/externals/ffmpeg/libavcodec/v4l2_m2m.c @@ -329,6 +329,7 @@ static void v4l2_m2m_destroy_context(void *opaque, uint8_t *context) sem_destroy(&s->refsync); close(s->fd); + av_frame_free(&s->frame); av_free(s); } @@ -415,5 +416,12 @@ int ff_v4l2_m2m_create_context(V4L2m2mPriv *priv, V4L2m2mContext **s) priv->context->self_ref = priv->context_ref; priv->context->fd = -1; + 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); + } + return 0; } diff --git a/externals/ffmpeg/libavcodec/v4l2_m2m.h b/externals/ffmpeg/libavcodec/v4l2_m2m.h index 456281f48..b67b21633 100755 --- a/externals/ffmpeg/libavcodec/v4l2_m2m.h +++ b/externals/ffmpeg/libavcodec/v4l2_m2m.h @@ -58,6 +58,9 @@ typedef struct V4L2m2mContext { int draining; AVPacket buf_pkt; + /* Reference to a frame. Only used during encoding */ + AVFrame *frame; + /* Reference to self; only valid while codec is active. */ AVBufferRef *self_ref; diff --git a/externals/ffmpeg/libavcodec/v4l2_m2m_enc.c b/externals/ffmpeg/libavcodec/v4l2_m2m_enc.c index 32321f392..56df4286a 100755 --- a/externals/ffmpeg/libavcodec/v4l2_m2m_enc.c +++ b/externals/ffmpeg/libavcodec/v4l2_m2m_enc.c @@ -24,6 +24,7 @@ #include #include #include +#include "encode.h" #include "libavcodec/avcodec.h" #include "libavcodec/internal.h" #include "libavutil/pixdesc.h" @@ -288,11 +289,24 @@ static int v4l2_receive_packet(AVCodecContext *avctx, AVPacket *avpkt) V4L2m2mContext *s = ((V4L2m2mPriv*)avctx->priv_data)->context; V4L2Context *const capture = &s->capture; V4L2Context *const output = &s->output; + AVFrame *frame = s->frame; int ret; if (s->draining) goto dequeue; + ret = ff_encode_get_frame(avctx, frame); + if (ret < 0 && ret != AVERROR_EOF) + return ret; + + if (ret == AVERROR_EOF) + frame = NULL; + + ret = v4l2_send_frame(avctx, frame); + av_frame_unref(frame); + if (ret < 0) + return ret; + if (!output->streamon) { ret = ff_v4l2_context_set_status(output, VIDIOC_STREAMON); if (ret) { @@ -411,7 +425,6 @@ static const AVCodecDefault v4l2_m2m_defaults[] = { .priv_data_size = sizeof(V4L2m2mPriv), \ .priv_class = &v4l2_m2m_ ## NAME ##_enc_class, \ .init = v4l2_encode_init, \ - .send_frame = v4l2_send_frame, \ .receive_packet = v4l2_receive_packet, \ .close = v4l2_encode_close, \ .defaults = v4l2_m2m_defaults, \ diff --git a/externals/ffmpeg/libavcodec/vaapi_encode.c b/externals/ffmpeg/libavcodec/vaapi_encode.c index cb05ebd77..e39db2020 100755 --- a/externals/ffmpeg/libavcodec/vaapi_encode.c +++ b/externals/ffmpeg/libavcodec/vaapi_encode.c @@ -25,6 +25,7 @@ #include "libavutil/pixdesc.h" #include "vaapi_encode.h" +#include "encode.h" #include "avcodec.h" const AVCodecHWConfigInternal *ff_vaapi_encode_hw_configs[] = { @@ -1043,7 +1044,7 @@ static int vaapi_encode_check_frame(AVCodecContext *avctx, return 0; } -int ff_vaapi_encode_send_frame(AVCodecContext *avctx, const AVFrame *frame) +static int vaapi_encode_send_frame(AVCodecContext *avctx, AVFrame *frame) { VAAPIEncodeContext *ctx = avctx->priv_data; VAAPIEncodePicture *pic; @@ -1066,9 +1067,6 @@ int ff_vaapi_encode_send_frame(AVCodecContext *avctx, const AVFrame *frame) err = AVERROR(ENOMEM); goto fail; } - err = av_frame_ref(pic->input_image, frame); - if (err < 0) - goto fail; if (ctx->input_order == 0 || frame->pict_type == AV_PICTURE_TYPE_I) pic->force_idr = 1; @@ -1076,6 +1074,8 @@ int ff_vaapi_encode_send_frame(AVCodecContext *avctx, const AVFrame *frame) pic->input_surface = (VASurfaceID)(uintptr_t)frame->data[3]; pic->pts = frame->pts; + av_frame_move_ref(pic->input_image, frame); + if (ctx->input_order == 0) ctx->first_pts = pic->pts; if (ctx->input_order == ctx->decode_delay) @@ -1114,8 +1114,20 @@ int ff_vaapi_encode_receive_packet(AVCodecContext *avctx, AVPacket *pkt) { VAAPIEncodeContext *ctx = avctx->priv_data; VAAPIEncodePicture *pic; + AVFrame *frame = ctx->frame; int err; + err = ff_encode_get_frame(avctx, frame); + if (err < 0 && err != AVERROR_EOF) + return err; + + if (err == AVERROR_EOF) + frame = NULL; + + err = vaapi_encode_send_frame(avctx, frame); + if (err < 0) + return err; + if (!ctx->pic_start) { if (ctx->end_of_stream) return AVERROR_EOF; @@ -2214,6 +2226,11 @@ av_cold int ff_vaapi_encode_init(AVCodecContext *avctx) VAStatus vas; int err; + ctx->frame = av_frame_alloc(); + if (!ctx->frame) { + return AVERROR(ENOMEM); + } + if (!avctx->hw_frames_ctx) { av_log(avctx, AV_LOG_ERROR, "A hardware frames reference is " "required to associate the encoding device.\n"); @@ -2391,6 +2408,8 @@ av_cold int ff_vaapi_encode_close(AVCodecContext *avctx) ctx->va_config = VA_INVALID_ID; } + av_frame_free(&ctx->frame); + av_freep(&ctx->codec_sequence_params); av_freep(&ctx->codec_picture_params); diff --git a/externals/ffmpeg/libavcodec/vaapi_encode.h b/externals/ffmpeg/libavcodec/vaapi_encode.h index 1329f6428..85d2a8f61 100755 --- a/externals/ffmpeg/libavcodec/vaapi_encode.h +++ b/externals/ffmpeg/libavcodec/vaapi_encode.h @@ -328,6 +328,8 @@ typedef struct VAAPIEncodeContext { // If the driver does not support ROI then warn the first time we // encounter a frame with ROI side data. int roi_warned; + + AVFrame *frame; } VAAPIEncodeContext; enum { @@ -419,7 +421,6 @@ typedef struct VAAPIEncodeType { } VAAPIEncodeType; -int ff_vaapi_encode_send_frame(AVCodecContext *avctx, const AVFrame *frame); int ff_vaapi_encode_receive_packet(AVCodecContext *avctx, AVPacket *pkt); int ff_vaapi_encode_init(AVCodecContext *avctx); diff --git a/externals/ffmpeg/libavcodec/vaapi_encode_h264.c b/externals/ffmpeg/libavcodec/vaapi_encode_h264.c index e195650ef..5e1683e85 100755 --- a/externals/ffmpeg/libavcodec/vaapi_encode_h264.c +++ b/externals/ffmpeg/libavcodec/vaapi_encode_h264.c @@ -135,11 +135,10 @@ static int vaapi_encode_h264_add_nal(AVCodecContext *avctx, CodedBitstreamFragment *au, void *nal_unit) { - VAAPIEncodeH264Context *priv = avctx->priv_data; H264RawNALUnitHeader *header = nal_unit; int err; - err = ff_cbs_insert_unit_content(priv->cbc, au, -1, + err = ff_cbs_insert_unit_content(au, -1, header->nal_unit_type, nal_unit, NULL); if (err < 0) { av_log(avctx, AV_LOG_ERROR, "Failed to add NAL unit: " @@ -174,7 +173,7 @@ static int vaapi_encode_h264_write_sequence_header(AVCodecContext *avctx, err = vaapi_encode_h264_write_access_unit(avctx, data, data_len, au); fail: - ff_cbs_fragment_reset(priv->cbc, au); + ff_cbs_fragment_reset(au); return err; } @@ -200,7 +199,7 @@ static int vaapi_encode_h264_write_slice_header(AVCodecContext *avctx, err = vaapi_encode_h264_write_access_unit(avctx, data, data_len, au); fail: - ff_cbs_fragment_reset(priv->cbc, au); + ff_cbs_fragment_reset(au); return err; } @@ -264,7 +263,7 @@ static int vaapi_encode_h264_write_extra_header(AVCodecContext *avctx, if (err < 0) goto fail; - ff_cbs_fragment_reset(priv->cbc, au); + ff_cbs_fragment_reset(au); *type = VAEncPackedHeaderRawData; return 0; @@ -286,7 +285,7 @@ static int vaapi_encode_h264_write_extra_header(AVCodecContext *avctx, } fail: - ff_cbs_fragment_reset(priv->cbc, au); + ff_cbs_fragment_reset(au); return err; } @@ -1242,7 +1241,7 @@ static av_cold int vaapi_encode_h264_close(AVCodecContext *avctx) { VAAPIEncodeH264Context *priv = avctx->priv_data; - ff_cbs_fragment_free(priv->cbc, &priv->current_access_unit); + ff_cbs_fragment_free(&priv->current_access_unit); ff_cbs_close(&priv->cbc); av_freep(&priv->sei_identifier_string); @@ -1351,7 +1350,6 @@ AVCodec ff_h264_vaapi_encoder = { .id = AV_CODEC_ID_H264, .priv_data_size = sizeof(VAAPIEncodeH264Context), .init = &vaapi_encode_h264_init, - .send_frame = &ff_vaapi_encode_send_frame, .receive_packet = &ff_vaapi_encode_receive_packet, .close = &vaapi_encode_h264_close, .priv_class = &vaapi_encode_h264_class, diff --git a/externals/ffmpeg/libavcodec/vaapi_encode_h265.c b/externals/ffmpeg/libavcodec/vaapi_encode_h265.c index 92e051091..045a0261a 100755 --- a/externals/ffmpeg/libavcodec/vaapi_encode_h265.c +++ b/externals/ffmpeg/libavcodec/vaapi_encode_h265.c @@ -116,11 +116,10 @@ static int vaapi_encode_h265_add_nal(AVCodecContext *avctx, CodedBitstreamFragment *au, void *nal_unit) { - VAAPIEncodeH265Context *priv = avctx->priv_data; H265RawNALUnitHeader *header = nal_unit; int err; - err = ff_cbs_insert_unit_content(priv->cbc, au, -1, + err = ff_cbs_insert_unit_content(au, -1, header->nal_unit_type, nal_unit, NULL); if (err < 0) { av_log(avctx, AV_LOG_ERROR, "Failed to add NAL unit: " @@ -159,7 +158,7 @@ static int vaapi_encode_h265_write_sequence_header(AVCodecContext *avctx, err = vaapi_encode_h265_write_access_unit(avctx, data, data_len, au); fail: - ff_cbs_fragment_reset(priv->cbc, au); + ff_cbs_fragment_reset(au); return err; } @@ -185,7 +184,7 @@ static int vaapi_encode_h265_write_slice_header(AVCodecContext *avctx, err = vaapi_encode_h265_write_access_unit(avctx, data, data_len, au); fail: - ff_cbs_fragment_reset(priv->cbc, au); + ff_cbs_fragment_reset(au); return err; } @@ -242,7 +241,7 @@ static int vaapi_encode_h265_write_extra_header(AVCodecContext *avctx, if (err < 0) goto fail; - ff_cbs_fragment_reset(priv->cbc, au); + ff_cbs_fragment_reset(au); *type = VAEncPackedHeaderRawData; return 0; @@ -251,7 +250,7 @@ static int vaapi_encode_h265_write_extra_header(AVCodecContext *avctx, } fail: - ff_cbs_fragment_reset(priv->cbc, au); + ff_cbs_fragment_reset(au); return err; } @@ -1188,7 +1187,7 @@ static av_cold int vaapi_encode_h265_close(AVCodecContext *avctx) { VAAPIEncodeH265Context *priv = avctx->priv_data; - ff_cbs_fragment_free(priv->cbc, &priv->current_access_unit); + ff_cbs_fragment_free(&priv->current_access_unit); ff_cbs_close(&priv->cbc); return ff_vaapi_encode_close(avctx); @@ -1287,7 +1286,6 @@ AVCodec ff_hevc_vaapi_encoder = { .id = AV_CODEC_ID_HEVC, .priv_data_size = sizeof(VAAPIEncodeH265Context), .init = &vaapi_encode_h265_init, - .send_frame = &ff_vaapi_encode_send_frame, .receive_packet = &ff_vaapi_encode_receive_packet, .close = &vaapi_encode_h265_close, .priv_class = &vaapi_encode_h265_class, diff --git a/externals/ffmpeg/libavcodec/vaapi_encode_mjpeg.c b/externals/ffmpeg/libavcodec/vaapi_encode_mjpeg.c index 9f9ed811a..557f59f00 100755 --- a/externals/ffmpeg/libavcodec/vaapi_encode_mjpeg.c +++ b/externals/ffmpeg/libavcodec/vaapi_encode_mjpeg.c @@ -90,34 +90,34 @@ static int vaapi_encode_mjpeg_write_image_header(AVCodecContext *avctx, int err; if (priv->jfif) { - err = ff_cbs_insert_unit_content(priv->cbc, frag, -1, + err = ff_cbs_insert_unit_content(frag, -1, JPEG_MARKER_APPN + 0, &priv->jfif_header, NULL); if (err < 0) goto fail; } - err = ff_cbs_insert_unit_content(priv->cbc, frag, -1, + err = ff_cbs_insert_unit_content(frag, -1, JPEG_MARKER_DQT, &priv->quant_tables, NULL); if (err < 0) goto fail; - err = ff_cbs_insert_unit_content(priv->cbc, frag, -1, + err = ff_cbs_insert_unit_content(frag, -1, JPEG_MARKER_SOF0, &priv->frame_header, NULL); if (err < 0) goto fail; if (priv->huffman) { - err = ff_cbs_insert_unit_content(priv->cbc, frag, -1, + err = ff_cbs_insert_unit_content(frag, -1, JPEG_MARKER_DHT, &priv->huffman_tables, NULL); if (err < 0) goto fail; } - err = ff_cbs_insert_unit_content(priv->cbc, frag, -1, + err = ff_cbs_insert_unit_content(frag, -1, JPEG_MARKER_SOS, &priv->scan, NULL); if (err < 0) @@ -142,7 +142,7 @@ static int vaapi_encode_mjpeg_write_image_header(AVCodecContext *avctx, err = 0; fail: - ff_cbs_fragment_reset(priv->cbc, frag); + ff_cbs_fragment_reset(frag); return err; } @@ -519,7 +519,7 @@ static av_cold int vaapi_encode_mjpeg_close(AVCodecContext *avctx) { VAAPIEncodeMJPEGContext *priv = avctx->priv_data; - ff_cbs_fragment_free(priv->cbc, &priv->current_fragment); + ff_cbs_fragment_free(&priv->current_fragment); ff_cbs_close(&priv->cbc); return ff_vaapi_encode_close(avctx); @@ -559,7 +559,6 @@ AVCodec ff_mjpeg_vaapi_encoder = { .id = AV_CODEC_ID_MJPEG, .priv_data_size = sizeof(VAAPIEncodeMJPEGContext), .init = &vaapi_encode_mjpeg_init, - .send_frame = &ff_vaapi_encode_send_frame, .receive_packet = &ff_vaapi_encode_receive_packet, .close = &vaapi_encode_mjpeg_close, .priv_class = &vaapi_encode_mjpeg_class, diff --git a/externals/ffmpeg/libavcodec/vaapi_encode_mpeg2.c b/externals/ffmpeg/libavcodec/vaapi_encode_mpeg2.c index 02c76552e..b8f1c06d0 100755 --- a/externals/ffmpeg/libavcodec/vaapi_encode_mpeg2.c +++ b/externals/ffmpeg/libavcodec/vaapi_encode_mpeg2.c @@ -93,10 +93,9 @@ static int vaapi_encode_mpeg2_add_header(AVCodecContext *avctx, CodedBitstreamFragment *frag, int type, void *header) { - VAAPIEncodeMPEG2Context *priv = avctx->priv_data; int err; - err = ff_cbs_insert_unit_content(priv->cbc, frag, -1, type, header, NULL); + err = ff_cbs_insert_unit_content(frag, -1, type, header, NULL); if (err < 0) { av_log(avctx, AV_LOG_ERROR, "Failed to add header: " "type = %d.\n", type); @@ -135,7 +134,7 @@ static int vaapi_encode_mpeg2_write_sequence_header(AVCodecContext *avctx, err = vaapi_encode_mpeg2_write_fragment(avctx, data, data_len, frag); fail: - ff_cbs_fragment_reset(priv->cbc, frag); + ff_cbs_fragment_reset(frag); return 0; } @@ -159,7 +158,7 @@ static int vaapi_encode_mpeg2_write_picture_header(AVCodecContext *avctx, err = vaapi_encode_mpeg2_write_fragment(avctx, data, data_len, frag); fail: - ff_cbs_fragment_reset(priv->cbc, frag); + ff_cbs_fragment_reset(frag); return 0; } @@ -633,7 +632,7 @@ static av_cold int vaapi_encode_mpeg2_close(AVCodecContext *avctx) { VAAPIEncodeMPEG2Context *priv = avctx->priv_data; - ff_cbs_fragment_free(priv->cbc, &priv->current_fragment); + ff_cbs_fragment_free(&priv->current_fragment); ff_cbs_close(&priv->cbc); return ff_vaapi_encode_close(avctx); @@ -697,7 +696,6 @@ AVCodec ff_mpeg2_vaapi_encoder = { .id = AV_CODEC_ID_MPEG2VIDEO, .priv_data_size = sizeof(VAAPIEncodeMPEG2Context), .init = &vaapi_encode_mpeg2_init, - .send_frame = &ff_vaapi_encode_send_frame, .receive_packet = &ff_vaapi_encode_receive_packet, .close = &vaapi_encode_mpeg2_close, .priv_class = &vaapi_encode_mpeg2_class, diff --git a/externals/ffmpeg/libavcodec/vaapi_encode_vp8.c b/externals/ffmpeg/libavcodec/vaapi_encode_vp8.c index cff926baa..51039fa19 100755 --- a/externals/ffmpeg/libavcodec/vaapi_encode_vp8.c +++ b/externals/ffmpeg/libavcodec/vaapi_encode_vp8.c @@ -252,7 +252,6 @@ AVCodec ff_vp8_vaapi_encoder = { .id = AV_CODEC_ID_VP8, .priv_data_size = sizeof(VAAPIEncodeVP8Context), .init = &vaapi_encode_vp8_init, - .send_frame = &ff_vaapi_encode_send_frame, .receive_packet = &ff_vaapi_encode_receive_packet, .close = &ff_vaapi_encode_close, .priv_class = &vaapi_encode_vp8_class, diff --git a/externals/ffmpeg/libavcodec/vaapi_encode_vp9.c b/externals/ffmpeg/libavcodec/vaapi_encode_vp9.c index 8514b8599..4f3b55ed2 100755 --- a/externals/ffmpeg/libavcodec/vaapi_encode_vp9.c +++ b/externals/ffmpeg/libavcodec/vaapi_encode_vp9.c @@ -286,7 +286,6 @@ AVCodec ff_vp9_vaapi_encoder = { .id = AV_CODEC_ID_VP9, .priv_data_size = sizeof(VAAPIEncodeVP9Context), .init = &vaapi_encode_vp9_init, - .send_frame = &ff_vaapi_encode_send_frame, .receive_packet = &ff_vaapi_encode_receive_packet, .close = &ff_vaapi_encode_close, .priv_class = &vaapi_encode_vp9_class, diff --git a/externals/ffmpeg/libavcodec/vdpau.c b/externals/ffmpeg/libavcodec/vdpau.c index 167f06d7a..fa10905c7 100755 --- a/externals/ffmpeg/libavcodec/vdpau.c +++ b/externals/ffmpeg/libavcodec/vdpau.c @@ -83,6 +83,8 @@ int av_vdpau_get_surface_parameters(AVCodecContext *avctx, switch (avctx->sw_pix_fmt) { case AV_PIX_FMT_YUV420P: case AV_PIX_FMT_YUVJ420P: + case AV_PIX_FMT_YUV420P10: + case AV_PIX_FMT_YUV420P12: t = VDP_CHROMA_TYPE_420; w = (w + 1) & ~1; h = (h + 3) & ~3; @@ -95,6 +97,8 @@ int av_vdpau_get_surface_parameters(AVCodecContext *avctx, break; case AV_PIX_FMT_YUV444P: case AV_PIX_FMT_YUVJ444P: + case AV_PIX_FMT_YUV444P10: + case AV_PIX_FMT_YUV444P12: t = VDP_CHROMA_TYPE_444; h = (h + 1) & ~1; break; diff --git a/externals/ffmpeg/libavcodec/vdpau_hevc.c b/externals/ffmpeg/libavcodec/vdpau_hevc.c index 29cb2da07..c17de0c5d 100755 --- a/externals/ffmpeg/libavcodec/vdpau_hevc.c +++ b/externals/ffmpeg/libavcodec/vdpau_hevc.c @@ -29,6 +29,8 @@ #include "hwconfig.h" #include "vdpau.h" #include "vdpau_internal.h" +#include "h265_profile_level.h" + static int vdpau_hevc_start_frame(AVCodecContext *avctx, const uint8_t *buffer, uint32_t size) @@ -429,10 +431,93 @@ static int vdpau_hevc_end_frame(AVCodecContext *avctx) return 0; } + + +static int ptl_convert(const PTLCommon *general_ptl, H265RawProfileTierLevel *h265_raw_ptl) +{ + h265_raw_ptl->general_profile_space = general_ptl->profile_space; + h265_raw_ptl->general_tier_flag = general_ptl->tier_flag; + h265_raw_ptl->general_profile_idc = general_ptl->profile_idc; + + memcpy(h265_raw_ptl->general_profile_compatibility_flag, + general_ptl->profile_compatibility_flag, 32 * sizeof(uint8_t)); + +#define copy_field(name) h265_raw_ptl->general_ ## name = general_ptl->name + copy_field(progressive_source_flag); + copy_field(interlaced_source_flag); + copy_field(non_packed_constraint_flag); + copy_field(frame_only_constraint_flag); + copy_field(max_12bit_constraint_flag); + copy_field(max_10bit_constraint_flag); + copy_field(max_8bit_constraint_flag); + copy_field(max_422chroma_constraint_flag); + copy_field(max_420chroma_constraint_flag); + copy_field(max_monochrome_constraint_flag); + copy_field(intra_constraint_flag); + copy_field(one_picture_only_constraint_flag); + copy_field(lower_bit_rate_constraint_flag); + copy_field(max_14bit_constraint_flag); + copy_field(inbld_flag); + copy_field(level_idc); +#undef copy_field + + return 0; +} + +/* + * Find exact vdpau_profile for HEVC Range Extension + */ +static int vdpau_hevc_parse_rext_profile(AVCodecContext *avctx, VdpDecoderProfile *vdp_profile) +{ + const HEVCContext *h = avctx->priv_data; + const HEVCSPS *sps = h->ps.sps; + const PTL *ptl = &sps->ptl; + const PTLCommon *general_ptl = &ptl->general_ptl; + const H265ProfileDescriptor *profile; + H265RawProfileTierLevel h265_raw_ptl = {0}; + + /* convert PTLCommon to H265RawProfileTierLevel */ + ptl_convert(general_ptl, &h265_raw_ptl); + + profile = ff_h265_get_profile(&h265_raw_ptl); + if (!profile) { + av_log(avctx, AV_LOG_WARNING, "HEVC profile is not found.\n"); + if (avctx->hwaccel_flags & AV_HWACCEL_FLAG_ALLOW_PROFILE_MISMATCH) { + // Default to selecting Main profile if profile mismatch is allowed + *vdp_profile = VDP_DECODER_PROFILE_HEVC_MAIN; + return 0; + } else + return AVERROR(ENOTSUP); + } + + if (!strcmp(profile->name, "Main 12") || + !strcmp(profile->name, "Main 12 Intra")) + *vdp_profile = VDP_DECODER_PROFILE_HEVC_MAIN_12; +#ifdef VDP_DECODER_PROFILE_HEVC_MAIN_444 + else if (!strcmp(profile->name, "Main 4:4:4") || + !strcmp(profile->name, "Main 4:4:4 Intra")) + *vdp_profile = VDP_DECODER_PROFILE_HEVC_MAIN_444; +#endif +#ifdef VDP_DECODER_PROFILE_HEVC_MAIN_444_10 + else if (!strcmp(profile->name, "Main 4:4:4 10") || + !strcmp(profile->name, "Main 4:4:4 10 Intra")) + *vdp_profile = VDP_DECODER_PROFILE_HEVC_MAIN_444_10; + else if (!strcmp(profile->name, "Main 4:4:4 12") || + !strcmp(profile->name, "Main 4:4:4 12 Intra")) + *vdp_profile = VDP_DECODER_PROFILE_HEVC_MAIN_444_12; +#endif + else + return AVERROR(ENOTSUP); + + return 0; +} + + static int vdpau_hevc_init(AVCodecContext *avctx) { VdpDecoderProfile profile; uint32_t level = avctx->level; + int ret; switch (avctx->profile) { case FF_PROFILE_HEVC_MAIN: @@ -445,7 +530,9 @@ static int vdpau_hevc_init(AVCodecContext *avctx) profile = VDP_DECODER_PROFILE_HEVC_MAIN_STILL; break; case FF_PROFILE_HEVC_REXT: - profile = VDP_DECODER_PROFILE_HEVC_MAIN_444; + ret = vdpau_hevc_parse_rext_profile(avctx, &profile); + if (ret) + return AVERROR(ENOTSUP); break; default: return AVERROR(ENOTSUP); diff --git a/externals/ffmpeg/libavcodec/version.h b/externals/ffmpeg/libavcodec/version.h index 85fbe24dc..e75891d46 100755 --- a/externals/ffmpeg/libavcodec/version.h +++ b/externals/ffmpeg/libavcodec/version.h @@ -28,7 +28,7 @@ #include "libavutil/version.h" #define LIBAVCODEC_VERSION_MAJOR 58 -#define LIBAVCODEC_VERSION_MINOR 91 +#define LIBAVCODEC_VERSION_MINOR 95 #define LIBAVCODEC_VERSION_MICRO 100 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ diff --git a/externals/ffmpeg/libavcodec/vp9_metadata_bsf.c b/externals/ffmpeg/libavcodec/vp9_metadata_bsf.c index 2ca494e69..00a5580c4 100755 --- a/externals/ffmpeg/libavcodec/vp9_metadata_bsf.c +++ b/externals/ffmpeg/libavcodec/vp9_metadata_bsf.c @@ -98,7 +98,7 @@ static int vp9_metadata_filter(AVBSFContext *bsf, AVPacket *pkt) err = 0; fail: - ff_cbs_fragment_reset(ctx->cbc, frag); + ff_cbs_fragment_reset(frag); if (err < 0) av_packet_unref(pkt); @@ -117,7 +117,7 @@ static void vp9_metadata_close(AVBSFContext *bsf) { VP9MetadataContext *ctx = bsf->priv_data; - ff_cbs_fragment_free(ctx->cbc, &ctx->fragment); + ff_cbs_fragment_free(&ctx->fragment); ff_cbs_close(&ctx->cbc); } diff --git a/externals/ffmpeg/libavcodec/wmv2dec.c b/externals/ffmpeg/libavcodec/wmv2dec.c index afa65478e..a16c4465f 100755 --- a/externals/ffmpeg/libavcodec/wmv2dec.c +++ b/externals/ffmpeg/libavcodec/wmv2dec.c @@ -537,6 +537,7 @@ AVCodec ff_wmv2_decoder = { .close = wmv2_decode_end, .decode = ff_h263_decode_frame, .capabilities = AV_CODEC_CAP_DRAW_HORIZ_BAND | AV_CODEC_CAP_DR1, + .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, .pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE }, }; diff --git a/externals/ffmpeg/libavdevice/Makefile b/externals/ffmpeg/libavdevice/Makefile index 6ea62b914..0dfe47a1f 100755 --- a/externals/ffmpeg/libavdevice/Makefile +++ b/externals/ffmpeg/libavdevice/Makefile @@ -15,6 +15,7 @@ OBJS-$(CONFIG_SHARED) += reverse.o OBJS-$(CONFIG_ALSA_INDEV) += alsa_dec.o alsa.o timefilter.o OBJS-$(CONFIG_ALSA_OUTDEV) += alsa_enc.o alsa.o OBJS-$(CONFIG_ANDROID_CAMERA_INDEV) += android_camera.o +OBJS-$(CONFIG_AUDIOTOOLBOX_OUTDEV) += audiotoolbox.o OBJS-$(CONFIG_AVFOUNDATION_INDEV) += avfoundation.o OBJS-$(CONFIG_BKTR_INDEV) += bktr.o OBJS-$(CONFIG_CACA_OUTDEV) += caca.o diff --git a/externals/ffmpeg/libavdevice/alldevices.c b/externals/ffmpeg/libavdevice/alldevices.c index 863343325..a6f68dd3b 100755 --- a/externals/ffmpeg/libavdevice/alldevices.c +++ b/externals/ffmpeg/libavdevice/alldevices.c @@ -27,6 +27,7 @@ extern AVInputFormat ff_alsa_demuxer; extern AVOutputFormat ff_alsa_muxer; extern AVInputFormat ff_android_camera_demuxer; +extern AVOutputFormat ff_audiotoolbox_muxer; extern AVInputFormat ff_avfoundation_demuxer; extern AVInputFormat ff_bktr_demuxer; extern AVOutputFormat ff_caca_muxer; diff --git a/externals/ffmpeg/libavdevice/audiotoolbox.m b/externals/ffmpeg/libavdevice/audiotoolbox.m new file mode 100755 index 000000000..d8c8312a0 --- /dev/null +++ b/externals/ffmpeg/libavdevice/audiotoolbox.m @@ -0,0 +1,308 @@ +/* + * AudioToolbox output device + * Copyright (c) 2020 Thilo Borgmann + * + * 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 + */ + +/** + * @file + * AudioToolbox output device + * @author Thilo Borgmann + */ + +#import +#include + +#include "libavutil/opt.h" +#include "libavformat/internal.h" +#include "libavutil/internal.h" +#include "avdevice.h" + +typedef struct +{ + AVClass *class; + + AudioQueueBufferRef buffer[2]; + pthread_mutex_t buffer_lock[2]; + int cur_buf; + AudioQueueRef queue; + + int list_devices; + int audio_device_index; + +} ATContext; + +static int check_status(AVFormatContext *avctx, OSStatus *status, const char *msg) +{ + if (*status != noErr) { + av_log(avctx, AV_LOG_ERROR, "Error: %s (%i)\n", msg, *status); + return 1; + } else { + av_log(avctx, AV_LOG_DEBUG, " OK : %s\n", msg); + return 0; + } +} + +static void queue_callback(void* atctx, AudioQueueRef inAQ, + AudioQueueBufferRef inBuffer) +{ + // unlock the buffer that has just been consumed + ATContext *ctx = (ATContext*)atctx; + for (int i = 0; i < 2; i++) { + if (inBuffer == ctx->buffer[i]) { + pthread_mutex_unlock(&ctx->buffer_lock[i]); + } + } +} + +static av_cold int at_write_header(AVFormatContext *avctx) +{ + ATContext *ctx = (ATContext*)avctx->priv_data; + OSStatus err = noErr; + CFStringRef device_UID = NULL; + AudioDeviceID *devices; + int num_devices; + + + // get devices + UInt32 data_size = 0; + AudioObjectPropertyAddress prop; + prop.mSelector = kAudioHardwarePropertyDevices; + prop.mScope = kAudioObjectPropertyScopeGlobal; + prop.mElement = kAudioObjectPropertyElementMaster; + err = AudioObjectGetPropertyDataSize(kAudioObjectSystemObject, &prop, 0, NULL, &data_size); + if (check_status(avctx, &err, "AudioObjectGetPropertyDataSize devices")) + return AVERROR(EINVAL); + + num_devices = data_size / sizeof(AudioDeviceID); + + devices = (AudioDeviceID*)(av_malloc(data_size)); + err = AudioObjectGetPropertyData(kAudioObjectSystemObject, &prop, 0, NULL, &data_size, devices); + if (check_status(avctx, &err, "AudioObjectGetPropertyData devices")) { + av_freep(&devices); + return AVERROR(EINVAL); + } + + // list devices + if (ctx->list_devices) { + CFStringRef device_name = NULL; + prop.mScope = kAudioDevicePropertyScopeInput; + + av_log(ctx, AV_LOG_INFO, "CoreAudio devices:\n"); + for(UInt32 i = 0; i < num_devices; ++i) { + // UID + data_size = sizeof(device_UID); + prop.mSelector = kAudioDevicePropertyDeviceUID; + err = AudioObjectGetPropertyData(devices[i], &prop, 0, NULL, &data_size, &device_UID); + if (check_status(avctx, &err, "AudioObjectGetPropertyData UID")) + continue; + + // name + data_size = sizeof(device_name); + prop.mSelector = kAudioDevicePropertyDeviceNameCFString; + err = AudioObjectGetPropertyData(devices[i], &prop, 0, NULL, &data_size, &device_name); + if (check_status(avctx, &err, "AudioObjecTGetPropertyData name")) + continue; + + av_log(ctx, AV_LOG_INFO, "[%d] %30s, %s\n", i, + CFStringGetCStringPtr(device_name, kCFStringEncodingMacRoman), + CFStringGetCStringPtr(device_UID, kCFStringEncodingMacRoman)); + } + } + + // get user-defined device UID or use default device + // -audio_device_index overrides any URL given + const char *stream_name = avctx->url; + if (stream_name && ctx->audio_device_index == -1) { + sscanf(stream_name, "%d", &ctx->audio_device_index); + } + + if (ctx->audio_device_index >= 0) { + // get UID of selected device + data_size = sizeof(device_UID); + prop.mSelector = kAudioDevicePropertyDeviceUID; + err = AudioObjectGetPropertyData(devices[ctx->audio_device_index], &prop, 0, NULL, &data_size, &device_UID); + if (check_status(avctx, &err, "AudioObjecTGetPropertyData UID")) { + av_freep(&devices); + return AVERROR(EINVAL); + } + } else { + // use default device + device_UID = NULL; + } + + av_log(ctx, AV_LOG_DEBUG, "stream_name: %s\n", stream_name); + av_log(ctx, AV_LOG_DEBUG, "audio_device_idnex: %i\n", ctx->audio_device_index); + av_log(ctx, AV_LOG_DEBUG, "UID: %s\n", CFStringGetCStringPtr(device_UID, kCFStringEncodingMacRoman)); + + // check input stream + if (avctx->nb_streams != 1 || avctx->streams[0]->codecpar->codec_type != AVMEDIA_TYPE_AUDIO) { + av_log(ctx, AV_LOG_ERROR, "Only a single audio stream is supported.\n"); + return AVERROR(EINVAL); + } + + av_freep(&devices); + AVCodecParameters *codecpar = avctx->streams[0]->codecpar; + + // audio format + AudioStreamBasicDescription device_format = {0}; + device_format.mSampleRate = codecpar->sample_rate; + device_format.mFormatID = kAudioFormatLinearPCM; + device_format.mFormatFlags |= (codecpar->format == AV_SAMPLE_FMT_FLT) ? kLinearPCMFormatFlagIsFloat : 0; + device_format.mFormatFlags |= (codecpar->codec_id == AV_CODEC_ID_PCM_S8) ? kLinearPCMFormatFlagIsSignedInteger : 0; + device_format.mFormatFlags |= (codecpar->codec_id == AV_NE(AV_CODEC_ID_PCM_S16BE, AV_CODEC_ID_PCM_S16LE)) ? kLinearPCMFormatFlagIsSignedInteger : 0; + device_format.mFormatFlags |= (codecpar->codec_id == AV_NE(AV_CODEC_ID_PCM_S24BE, AV_CODEC_ID_PCM_S24LE)) ? kLinearPCMFormatFlagIsSignedInteger : 0; + device_format.mFormatFlags |= (codecpar->codec_id == AV_NE(AV_CODEC_ID_PCM_S32BE, AV_CODEC_ID_PCM_S32LE)) ? kLinearPCMFormatFlagIsSignedInteger : 0; + device_format.mFormatFlags |= (av_sample_fmt_is_planar(codecpar->format)) ? kAudioFormatFlagIsNonInterleaved : 0; + device_format.mFormatFlags |= (codecpar->codec_id == AV_CODEC_ID_PCM_F32BE) ? kAudioFormatFlagIsBigEndian : 0; + device_format.mFormatFlags |= (codecpar->codec_id == AV_CODEC_ID_PCM_S16BE) ? kAudioFormatFlagIsBigEndian : 0; + device_format.mFormatFlags |= (codecpar->codec_id == AV_CODEC_ID_PCM_S24BE) ? kAudioFormatFlagIsBigEndian : 0; + device_format.mFormatFlags |= (codecpar->codec_id == AV_CODEC_ID_PCM_S32BE) ? kAudioFormatFlagIsBigEndian : 0; + device_format.mChannelsPerFrame = codecpar->channels; + device_format.mBitsPerChannel = (codecpar->codec_id == AV_NE(AV_CODEC_ID_PCM_S24BE, AV_CODEC_ID_PCM_S24LE)) ? 24 : (av_get_bytes_per_sample(codecpar->format) << 3); + device_format.mBytesPerFrame = (device_format.mBitsPerChannel >> 3) * device_format.mChannelsPerFrame; + device_format.mFramesPerPacket = 1; + device_format.mBytesPerPacket = device_format.mBytesPerFrame * device_format.mFramesPerPacket; + device_format.mReserved = 0; + + av_log(ctx, AV_LOG_DEBUG, "device_format.mSampleRate = %i\n", codecpar->sample_rate); + av_log(ctx, AV_LOG_DEBUG, "device_format.mFormatID = %s\n", "kAudioFormatLinearPCM"); + av_log(ctx, AV_LOG_DEBUG, "device_format.mFormatFlags |= %s\n", (codecpar->format == AV_SAMPLE_FMT_FLT) ? "kLinearPCMFormatFlagIsFloat" : "0"); + av_log(ctx, AV_LOG_DEBUG, "device_format.mFormatFlags |= %s\n", (codecpar->codec_id == AV_CODEC_ID_PCM_S8) ? "kLinearPCMFormatFlagIsSignedInteger" : "0"); + av_log(ctx, AV_LOG_DEBUG, "device_format.mFormatFlags |= %s\n", (codecpar->codec_id == AV_NE(AV_CODEC_ID_PCM_S32BE, AV_CODEC_ID_PCM_S32LE)) ? "kLinearPCMFormatFlagIsSignedInteger" : "0"); + av_log(ctx, AV_LOG_DEBUG, "device_format.mFormatFlags |= %s\n", (codecpar->codec_id == AV_NE(AV_CODEC_ID_PCM_S16BE, AV_CODEC_ID_PCM_S16LE)) ? "kLinearPCMFormatFlagIsSignedInteger" : "0"); + av_log(ctx, AV_LOG_DEBUG, "device_format.mFormatFlags |= %s\n", (codecpar->codec_id == AV_NE(AV_CODEC_ID_PCM_S24BE, AV_CODEC_ID_PCM_S24LE)) ? "kLinearPCMFormatFlagIsSignedInteger" : "0"); + av_log(ctx, AV_LOG_DEBUG, "device_format.mFormatFlags |= %s\n", (av_sample_fmt_is_planar(codecpar->format)) ? "kAudioFormatFlagIsNonInterleaved" : "0"); + av_log(ctx, AV_LOG_DEBUG, "device_format.mFormatFlags |= %s\n", (codecpar->codec_id == AV_CODEC_ID_PCM_F32BE) ? "kAudioFormatFlagIsBigEndian" : "0"); + av_log(ctx, AV_LOG_DEBUG, "device_format.mFormatFlags |= %s\n", (codecpar->codec_id == AV_CODEC_ID_PCM_S16BE) ? "kAudioFormatFlagIsBigEndian" : "0"); + av_log(ctx, AV_LOG_DEBUG, "device_format.mFormatFlags |= %s\n", (codecpar->codec_id == AV_CODEC_ID_PCM_S24BE) ? "kAudioFormatFlagIsBigEndian" : "0"); + av_log(ctx, AV_LOG_DEBUG, "device_format.mFormatFlags |= %s\n", (codecpar->codec_id == AV_CODEC_ID_PCM_S32BE) ? "kAudioFormatFlagIsBigEndian" : "0"); + av_log(ctx, AV_LOG_DEBUG, "device_format.mFormatFlags == %i\n", device_format.mFormatFlags); + av_log(ctx, AV_LOG_DEBUG, "device_format.mChannelsPerFrame = %i\n", codecpar->channels); + av_log(ctx, AV_LOG_DEBUG, "device_format.mBitsPerChannel = %i\n", av_get_bytes_per_sample(codecpar->format) << 3); + av_log(ctx, AV_LOG_DEBUG, "device_format.mBytesPerFrame = %i\n", (device_format.mBitsPerChannel >> 3) * codecpar->channels); + av_log(ctx, AV_LOG_DEBUG, "device_format.mBytesPerPacket = %i\n", device_format.mBytesPerFrame); + av_log(ctx, AV_LOG_DEBUG, "device_format.mFramesPerPacket = %i\n", 1); + av_log(ctx, AV_LOG_DEBUG, "device_format.mReserved = %i\n", 0); + + // create new output queue for the device + err = AudioQueueNewOutput(&device_format, queue_callback, ctx, + NULL, kCFRunLoopCommonModes, + 0, &ctx->queue); + if (check_status(avctx, &err, "AudioQueueNewOutput")) { + if (err == kAudioFormatUnsupportedDataFormatError) + av_log(ctx, AV_LOG_ERROR, "Unsupported output format.\n"); + return AVERROR(EINVAL); + } + + // set user-defined device or leave untouched for default + if (device_UID != NULL) { + err = AudioQueueSetProperty(ctx->queue, kAudioQueueProperty_CurrentDevice, &device_UID, sizeof(device_UID)); + if (check_status(avctx, &err, "AudioQueueSetProperty output UID")) + return AVERROR(EINVAL); + } + + // start the queue + err = AudioQueueStart(ctx->queue, NULL); + if (check_status(avctx, &err, "AudioQueueStart")) + return AVERROR(EINVAL); + + // init the mutexes for double-buffering + pthread_mutex_init(&ctx->buffer_lock[0], NULL); + pthread_mutex_init(&ctx->buffer_lock[1], NULL); + + return 0; +} + +static int at_write_packet(AVFormatContext *avctx, AVPacket *pkt) +{ + ATContext *ctx = (ATContext*)avctx->priv_data; + OSStatus err = noErr; + + // use the other buffer + ctx->cur_buf = !ctx->cur_buf; + + // lock for writing or wait for the buffer to be available + // will be unlocked by queue callback + pthread_mutex_lock(&ctx->buffer_lock[ctx->cur_buf]); + + // (re-)allocate the buffer if not existant or of different size + if (!ctx->buffer[ctx->cur_buf] || ctx->buffer[ctx->cur_buf]->mAudioDataBytesCapacity != pkt->size) { + err = AudioQueueAllocateBuffer(ctx->queue, pkt->size, &ctx->buffer[ctx->cur_buf]); + if (check_status(avctx, &err, "AudioQueueAllocateBuffer")) { + pthread_mutex_unlock(&ctx->buffer_lock[ctx->cur_buf]); + return AVERROR(ENOMEM); + } + } + + AudioQueueBufferRef buf = ctx->buffer[ctx->cur_buf]; + + // copy audio data into buffer and enqueue the buffer + memcpy(buf->mAudioData, pkt->data, buf->mAudioDataBytesCapacity); + buf->mAudioDataByteSize = buf->mAudioDataBytesCapacity; + err = AudioQueueEnqueueBuffer(ctx->queue, buf, 0, NULL); + if (check_status(avctx, &err, "AudioQueueEnqueueBuffer")) { + pthread_mutex_unlock(&ctx->buffer_lock[ctx->cur_buf]); + return AVERROR(EINVAL); + } + + return 0; +} + +static av_cold int at_write_trailer(AVFormatContext *avctx) +{ + ATContext *ctx = (ATContext*)avctx->priv_data; + OSStatus err = noErr; + + pthread_mutex_destroy(&ctx->buffer_lock[0]); + pthread_mutex_destroy(&ctx->buffer_lock[1]); + + err = AudioQueueFlush(ctx->queue); + check_status(avctx, &err, "AudioQueueFlush"); + err = AudioQueueDispose(ctx->queue, true); + check_status(avctx, &err, "AudioQueueDispose"); + + return 0; +} + +static const AVOption options[] = { + { "list_devices", "list available audio devices", offsetof(ATContext, list_devices), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, AV_OPT_FLAG_ENCODING_PARAM }, + { "audio_device_index", "select audio device by index (starts at 0)", offsetof(ATContext, audio_device_index), AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM }, + { NULL }, +}; + +static const AVClass at_class = { + .class_name = "AudioToolbox", + .item_name = av_default_item_name, + .option = options, + .version = LIBAVUTIL_VERSION_INT, + .category = AV_CLASS_CATEGORY_DEVICE_AUDIO_OUTPUT, +}; + +AVOutputFormat ff_audiotoolbox_muxer = { + .name = "audiotoolbox", + .long_name = NULL_IF_CONFIG_SMALL("AudioToolbox output device"), + .priv_data_size = sizeof(ATContext), + .audio_codec = AV_NE(AV_CODEC_ID_PCM_S16BE, AV_CODEC_ID_PCM_S16LE), + .video_codec = AV_CODEC_ID_NONE, + .write_header = at_write_header, + .write_packet = at_write_packet, + .write_trailer = at_write_trailer, + .flags = AVFMT_NOFILE, + .priv_class = &at_class, +}; diff --git a/externals/ffmpeg/libavdevice/decklink_common.h b/externals/ffmpeg/libavdevice/decklink_common.h index 27ce6a8a4..bd68c7ba7 100755 --- a/externals/ffmpeg/libavdevice/decklink_common.h +++ b/externals/ffmpeg/libavdevice/decklink_common.h @@ -120,12 +120,14 @@ struct decklink_ctx { unsigned int dropped; AVStream *audio_st; AVStream *video_st; + AVStream *klv_st; AVStream *teletext_st; uint16_t cdp_sequence_num; /* Options */ int list_devices; int list_formats; + int enable_klv; int64_t teletext_lines; double preroll; int duplex_mode; diff --git a/externals/ffmpeg/libavdevice/decklink_common_c.h b/externals/ffmpeg/libavdevice/decklink_common_c.h index 88b1eae18..a78262aaa 100755 --- a/externals/ffmpeg/libavdevice/decklink_common_c.h +++ b/externals/ffmpeg/libavdevice/decklink_common_c.h @@ -40,6 +40,7 @@ struct decklink_cctx { /* Options */ int list_devices; int list_formats; + int enable_klv; int64_t teletext_lines; double preroll; int audio_channels; diff --git a/externals/ffmpeg/libavdevice/decklink_dec.cpp b/externals/ffmpeg/libavdevice/decklink_dec.cpp index 82106aa69..a499972df 100755 --- a/externals/ffmpeg/libavdevice/decklink_dec.cpp +++ b/externals/ffmpeg/libavdevice/decklink_dec.cpp @@ -22,6 +22,7 @@ */ #include +#include using std::atomic; /* Include internal.h first to avoid conflict between winsock.h (used by @@ -583,6 +584,109 @@ static int avpacket_queue_get(AVPacketQueue *q, AVPacket *pkt, int block) return ret; } +static void handle_klv(AVFormatContext *avctx, decklink_ctx *ctx, IDeckLinkVideoInputFrame *videoFrame, int64_t pts) +{ + const uint8_t KLV_DID = 0x44; + const uint8_t KLV_IN_VANC_SDID = 0x04; + + struct KLVPacket + { + uint16_t sequence_counter; + std::vector data; + }; + + size_t total_size = 0; + std::vector> klv_packets(256); + + IDeckLinkVideoFrameAncillaryPackets *packets = nullptr; + if (videoFrame->QueryInterface(IID_IDeckLinkVideoFrameAncillaryPackets, (void**)&packets) != S_OK) + return; + + IDeckLinkAncillaryPacketIterator *it = nullptr; + if (packets->GetPacketIterator(&it) != S_OK) { + packets->Release(); + return; + } + + IDeckLinkAncillaryPacket *packet = nullptr; + while (it->Next(&packet) == S_OK) { + uint8_t *data = nullptr; + uint32_t size = 0; + + if (packet->GetDID() == KLV_DID && packet->GetSDID() == KLV_IN_VANC_SDID) { + av_log(avctx, AV_LOG_DEBUG, "Found KLV VANC packet on line: %d\n", packet->GetLineNumber()); + + if (packet->GetBytes(bmdAncillaryPacketFormatUInt8, (const void**) &data, &size) == S_OK) { + // MID and PSC + if (size > 3) { + uint8_t mid = data[0]; + uint16_t psc = data[1] << 8 | data[2]; + + av_log(avctx, AV_LOG_DEBUG, "KLV with MID: %d and PSC: %d\n", mid, psc); + + auto& list = klv_packets[mid]; + uint16_t expected_psc = list.size() + 1; + + if (psc == expected_psc) { + uint32_t data_len = size - 3; + total_size += data_len; + + KLVPacket packet{ psc }; + packet.data.resize(data_len); + memcpy(packet.data.data(), data + 3, data_len); + + list.push_back(std::move(packet)); + } else { + av_log(avctx, AV_LOG_WARNING, "Out of order PSC: %d for MID: %d\n", psc, mid); + + if (!list.empty()) { + for (auto& klv : list) + total_size -= klv.data.size(); + + list.clear(); + } + } + } + } + } + + packet->Release(); + } + + it->Release(); + packets->Release(); + + if (total_size > 0) { + std::vector klv; + klv.reserve(total_size); + + for (size_t i = 0; i < klv_packets.size(); ++i) { + auto& list = klv_packets[i]; + + if (list.empty()) + continue; + + av_log(avctx, AV_LOG_DEBUG, "Joining MID: %d\n", (int)i); + + for (auto& packet : list) + klv.insert(klv.end(), packet.data.begin(), packet.data.end()); + } + + AVPacket klv_packet; + av_init_packet(&klv_packet); + klv_packet.pts = pts; + klv_packet.dts = pts; + klv_packet.flags |= AV_PKT_FLAG_KEY; + klv_packet.stream_index = ctx->klv_st->index; + klv_packet.data = klv.data(); + klv_packet.size = klv.size(); + + if (avpacket_queue_put(&ctx->queue, &klv_packet) < 0) { + ++ctx->dropped; + } + } +} + class decklink_input_callback : public IDeckLinkInputCallback { public: @@ -821,6 +925,10 @@ HRESULT decklink_input_callback::VideoInputFrameArrived( uint8_t txt_buf0[3531]; // 35 * 46 bytes decoded teletext lines + 1 byte data_identifier + 1920 bytes OP47 decode buffer uint8_t *txt_buf = txt_buf0; + if (ctx->enable_klv) { + handle_klv(avctx, ctx, videoFrame, pkt.pts); + } + if (videoFrame->GetAncillaryData(&vanc) == S_OK) { int i; int64_t line_mask = 1; @@ -1012,6 +1120,7 @@ av_cold int ff_decklink_read_header(AVFormatContext *avctx) return AVERROR(ENOMEM); ctx->list_devices = cctx->list_devices; ctx->list_formats = cctx->list_formats; + ctx->enable_klv = cctx->enable_klv; ctx->teletext_lines = cctx->teletext_lines; ctx->preroll = cctx->preroll; ctx->duplex_mode = cctx->duplex_mode; @@ -1202,6 +1311,20 @@ av_cold int ff_decklink_read_header(AVFormatContext *avctx) ctx->video_st=st; + if (ctx->enable_klv) { + st = avformat_new_stream(avctx, NULL); + if (!st) { + ret = AVERROR(ENOMEM); + goto error; + } + st->codecpar->codec_type = AVMEDIA_TYPE_DATA; + st->time_base.den = ctx->bmd_tb_den; + st->time_base.num = ctx->bmd_tb_num; + st->codecpar->codec_id = AV_CODEC_ID_SMPTE_KLV; + avpriv_set_pts_info(st, 64, 1, 1000000); /* 64 bits pts in us */ + ctx->klv_st = st; + } + if (ctx->teletext_lines) { st = avformat_new_stream(avctx, NULL); if (!st) { diff --git a/externals/ffmpeg/libavdevice/decklink_dec_c.c b/externals/ffmpeg/libavdevice/decklink_dec_c.c index b59876994..9f4b32088 100755 --- a/externals/ffmpeg/libavdevice/decklink_dec_c.c +++ b/externals/ffmpeg/libavdevice/decklink_dec_c.c @@ -39,6 +39,7 @@ static const AVOption options[] = { { "argb", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 32 }, 0, 0, DEC, "raw_format"}, { "bgra", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MKBETAG('B','G','R','A') }, 0, 0, DEC, "raw_format"}, { "rgb10", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MKBETAG('r','2','1','0') }, 0, 0, DEC, "raw_format"}, + { "enable_klv", "output klv if present in vanc", OFFSET(enable_klv), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, DEC }, { "teletext_lines", "teletext lines bitmask", OFFSET(teletext_lines), AV_OPT_TYPE_INT64, { .i64 = 0 }, 0, 0x7ffffffffLL, DEC, "teletext_lines"}, { "standard", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 0x7fff9fffeLL}, 0, 0, DEC, "teletext_lines"}, { "all", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 0x7ffffffffLL}, 0, 0, DEC, "teletext_lines"}, diff --git a/externals/ffmpeg/libavdevice/version.h b/externals/ffmpeg/libavdevice/version.h index 9ee3d3db4..8ca715b8b 100755 --- a/externals/ffmpeg/libavdevice/version.h +++ b/externals/ffmpeg/libavdevice/version.h @@ -28,8 +28,8 @@ #include "libavutil/version.h" #define LIBAVDEVICE_VERSION_MAJOR 58 -#define LIBAVDEVICE_VERSION_MINOR 10 -#define LIBAVDEVICE_VERSION_MICRO 100 +#define LIBAVDEVICE_VERSION_MINOR 11 +#define LIBAVDEVICE_VERSION_MICRO 101 #define LIBAVDEVICE_VERSION_INT AV_VERSION_INT(LIBAVDEVICE_VERSION_MAJOR, \ LIBAVDEVICE_VERSION_MINOR, \ diff --git a/externals/ffmpeg/libavfilter/Makefile b/externals/ffmpeg/libavfilter/Makefile index 512354065..0dc74f8b7 100755 --- a/externals/ffmpeg/libavfilter/Makefile +++ b/externals/ffmpeg/libavfilter/Makefile @@ -182,6 +182,7 @@ OBJS-$(CONFIG_CAS_FILTER) += vf_cas.o OBJS-$(CONFIG_CHROMABER_VULKAN_FILTER) += vf_chromaber_vulkan.o vulkan.o OBJS-$(CONFIG_CHROMAHOLD_FILTER) += vf_chromakey.o OBJS-$(CONFIG_CHROMAKEY_FILTER) += vf_chromakey.o +OBJS-$(CONFIG_CHROMANR_FILTER) += vf_chromanr.o OBJS-$(CONFIG_CHROMASHIFT_FILTER) += vf_chromashift.o OBJS-$(CONFIG_CIESCOPE_FILTER) += vf_ciescope.o OBJS-$(CONFIG_CODECVIEW_FILTER) += vf_codecview.o diff --git a/externals/ffmpeg/libavfilter/aeval.c b/externals/ffmpeg/libavfilter/aeval.c index 32cd6de04..855dc0009 100755 --- a/externals/ffmpeg/libavfilter/aeval.c +++ b/externals/ffmpeg/libavfilter/aeval.c @@ -416,8 +416,6 @@ static int aeval_config_output(AVFilterLink *outlink) return 0; } -#define TS2T(ts, tb) ((ts) == AV_NOPTS_VALUE ? NAN : (double)(ts)*av_q2d(tb)) - static int filter_frame(AVFilterLink *inlink, AVFrame *in) { EvalContext *eval = inlink->dst->priv; diff --git a/externals/ffmpeg/libavfilter/af_aresample.c b/externals/ffmpeg/libavfilter/af_aresample.c index ef10621c3..fb10bd1c3 100755 --- a/externals/ffmpeg/libavfilter/af_aresample.c +++ b/externals/ffmpeg/libavfilter/af_aresample.c @@ -293,10 +293,19 @@ static int request_frame(AVFilterLink *outlink) return ret; } +#if FF_API_CHILD_CLASS_NEXT static const AVClass *resample_child_class_next(const AVClass *prev) { return prev ? NULL : swr_get_class(); } +#endif + +static const AVClass *resample_child_class_iterate(void **iter) +{ + const AVClass *c = *iter ? NULL : swr_get_class(); + *iter = (void*)(uintptr_t)c; + return c; +} static void *resample_child_next(void *obj, void *prev) { @@ -317,7 +326,10 @@ static const AVClass aresample_class = { .item_name = av_default_item_name, .option = options, .version = LIBAVUTIL_VERSION_INT, +#if FF_API_CHILD_CLASS_NEXT .child_class_next = resample_child_class_next, +#endif + .child_class_iterate = resample_child_class_iterate, .child_next = resample_child_next, }; diff --git a/externals/ffmpeg/libavfilter/af_ladspa.c b/externals/ffmpeg/libavfilter/af_ladspa.c index a8562fc07..ce695db9f 100755 --- a/externals/ffmpeg/libavfilter/af_ladspa.c +++ b/externals/ffmpeg/libavfilter/af_ladspa.c @@ -64,6 +64,9 @@ typedef struct LADSPAContext { int nb_samples; int64_t pts; int64_t duration; + int in_trim; + int out_pad; + int latency; } LADSPAContext; #define OFFSET(x) offsetof(LADSPAContext, x) @@ -81,11 +84,28 @@ static const AVOption ladspa_options[] = { { "n", "set the number of samples per requested frame", OFFSET(nb_samples), AV_OPT_TYPE_INT, {.i64=1024}, 1, INT_MAX, FLAGS }, { "duration", "set audio duration", OFFSET(duration), AV_OPT_TYPE_DURATION, {.i64=-1}, -1, INT64_MAX, FLAGS }, { "d", "set audio duration", OFFSET(duration), AV_OPT_TYPE_DURATION, {.i64=-1}, -1, INT64_MAX, FLAGS }, + { "latency", "enable latency compensation", OFFSET(latency), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS }, + { "l", "enable latency compensation", OFFSET(latency), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS }, { NULL } }; AVFILTER_DEFINE_CLASS(ladspa); +static int find_latency(AVFilterContext *ctx, LADSPAContext *s) +{ + int latency = 0; + + for (int ctl = 0; ctl < s->nb_outputcontrols; ctl++) { + if (av_strcasecmp("latency", s->desc->PortNames[s->ocmap[ctl]])) + continue; + + latency = lrintf(s->octlv[ctl]); + break; + } + + return latency; +} + static void print_ctl_info(AVFilterContext *ctx, int level, LADSPAContext *s, int ctl, unsigned long *map, LADSPA_Data *values, int print) @@ -143,12 +163,13 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) AVFilterContext *ctx = inlink->dst; LADSPAContext *s = ctx->priv; AVFrame *out; - int i, h, p; + int i, h, p, new_out_samples; av_assert0(in->channels == (s->nb_inputs * s->nb_handles)); if (!s->nb_outputs || (av_frame_is_writable(in) && s->nb_inputs == s->nb_outputs && + s->in_trim == 0 && s->out_pad == 0 && !(s->desc->Properties & LADSPA_PROPERTY_INPLACE_BROKEN))) { out = in; } else { @@ -176,6 +197,9 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) } s->desc->run(s->handles[h], in->nb_samples); + if (s->latency) + s->in_trim = s->out_pad = find_latency(ctx, s); + s->latency = 0; } for (i = 0; i < s->nb_outputcontrols; i++) @@ -184,6 +208,25 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) if (out != in) av_frame_free(&in); + new_out_samples = out->nb_samples; + if (s->in_trim > 0) { + int trim = FFMIN(new_out_samples, s->in_trim); + + new_out_samples -= trim; + s->in_trim -= trim; + } + + if (new_out_samples <= 0) { + av_frame_free(&out); + return 0; + } else if (new_out_samples < out->nb_samples) { + int offset = out->nb_samples - new_out_samples; + for (int ch = 0; ch < out->channels; ch++) + memmove(out->extended_data[ch], out->extended_data[ch] + sizeof(float) * offset, + sizeof(float) * new_out_samples); + out->nb_samples = new_out_samples; + } + return ff_filter_frame(ctx->outputs[0], out); } @@ -195,8 +238,19 @@ static int request_frame(AVFilterLink *outlink) int64_t t; int i; - if (ctx->nb_inputs) - return ff_request_frame(ctx->inputs[0]); + if (ctx->nb_inputs) { + int ret = ff_request_frame(ctx->inputs[0]); + + if (ret == AVERROR_EOF && s->out_pad > 0) { + AVFrame *frame = ff_get_audio_buffer(outlink, FFMIN(2048, s->out_pad)); + if (!frame) + return AVERROR(ENOMEM); + + s->out_pad -= frame->nb_samples; + return filter_frame(ctx->inputs[0], frame); + } + return ret; + } t = av_rescale(s->pts, AV_TIME_BASE, s->sample_rate); if (s->duration >= 0 && t >= s->duration) @@ -415,6 +469,7 @@ static av_cold int init(AVFilterContext *ctx) } else { // argument is a shared object name char *paths = av_strdup(getenv("LADSPA_PATH")); + const char *home_path = getenv("HOME"); const char *separator = ":"; if (paths) { @@ -426,7 +481,12 @@ static av_cold int init(AVFilterContext *ctx) } av_free(paths); - if (!s->dl_handle && (paths = av_asprintf("%s/.ladspa/lib", getenv("HOME")))) { + if (!s->dl_handle && home_path && (paths = av_asprintf("%s/.ladspa", home_path))) { + s->dl_handle = try_load(paths, s->dl_name); + av_free(paths); + } + + if (!s->dl_handle && home_path && (paths = av_asprintf("%s/.ladspa/lib", home_path))) { s->dl_handle = try_load(paths, s->dl_name); av_free(paths); } diff --git a/externals/ffmpeg/libavfilter/af_resample.c b/externals/ffmpeg/libavfilter/af_resample.c index e3c6a2069..785cd0c7f 100755 --- a/externals/ffmpeg/libavfilter/af_resample.c +++ b/externals/ffmpeg/libavfilter/af_resample.c @@ -306,10 +306,19 @@ fail: return ret; } +#if FF_API_CHILD_CLASS_NEXT static const AVClass *resample_child_class_next(const AVClass *prev) { return prev ? NULL : avresample_get_class(); } +#endif + +static const AVClass *resample_child_class_iterate(void **iter) +{ + const AVClass *c = *iter ? NULL : avresample_get_class(); + *iter = (void*)(uintptr_t)c; + return c; +} static void *resample_child_next(void *obj, void *prev) { @@ -321,7 +330,10 @@ static const AVClass resample_class = { .class_name = "resample", .item_name = av_default_item_name, .version = LIBAVUTIL_VERSION_INT, +#if FF_API_CHILD_CLASS_NEXT .child_class_next = resample_child_class_next, +#endif + .child_class_iterate = resample_child_class_iterate, .child_next = resample_child_next, }; diff --git a/externals/ffmpeg/libavfilter/af_rubberband.c b/externals/ffmpeg/libavfilter/af_rubberband.c index 1dfd74422..b42e67f09 100755 --- a/externals/ffmpeg/libavfilter/af_rubberband.c +++ b/externals/ffmpeg/libavfilter/af_rubberband.c @@ -212,6 +212,7 @@ static int process_command(AVFilterContext *ctx, const char *cmd, const char *ar rubberband_set_time_ratio(s->rbs, 1. / s->tempo); rubberband_set_pitch_scale(s->rbs, s->pitch); + s->nb_samples = rubberband_get_samples_required(s->rbs); return 0; } diff --git a/externals/ffmpeg/libavfilter/af_volume.c b/externals/ffmpeg/libavfilter/af_volume.c index 213c57195..5fc00d82a 100755 --- a/externals/ffmpeg/libavfilter/af_volume.c +++ b/externals/ffmpeg/libavfilter/af_volume.c @@ -335,10 +335,6 @@ static int process_command(AVFilterContext *ctx, const char *cmd, const char *ar return ret; } -#define D2TS(d) (isnan(d) ? AV_NOPTS_VALUE : (int64_t)(d)) -#define TS2D(ts) ((ts) == AV_NOPTS_VALUE ? NAN : (double)(ts)) -#define TS2T(ts, tb) ((ts) == AV_NOPTS_VALUE ? NAN : (double)(ts)*av_q2d(tb)) - static int filter_frame(AVFilterLink *inlink, AVFrame *buf) { AVFilterContext *ctx = inlink->dst; diff --git a/externals/ffmpeg/libavfilter/allfilters.c b/externals/ffmpeg/libavfilter/allfilters.c index 1183e4026..3f7015398 100755 --- a/externals/ffmpeg/libavfilter/allfilters.c +++ b/externals/ffmpeg/libavfilter/allfilters.c @@ -172,6 +172,7 @@ extern AVFilter ff_vf_bwdif; extern AVFilter ff_vf_cas; extern AVFilter ff_vf_chromahold; extern AVFilter ff_vf_chromakey; +extern AVFilter ff_vf_chromanr; extern AVFilter ff_vf_chromashift; extern AVFilter ff_vf_ciescope; extern AVFilter ff_vf_codecview; diff --git a/externals/ffmpeg/libavfilter/avfilter.c b/externals/ffmpeg/libavfilter/avfilter.c index 394811916..dd8074e46 100755 --- a/externals/ffmpeg/libavfilter/avfilter.c +++ b/externals/ffmpeg/libavfilter/avfilter.c @@ -583,6 +583,7 @@ static void *filter_child_next(void *obj, void *prev) return NULL; } +#if FF_API_CHILD_CLASS_NEXT static const AVClass *filter_child_class_next(const AVClass *prev) { void *opaque = NULL; @@ -604,6 +605,18 @@ static const AVClass *filter_child_class_next(const AVClass *prev) return NULL; } +#endif + +static const AVClass *filter_child_class_iterate(void **iter) +{ + const AVFilter *f; + + while ((f = av_filter_iterate(iter))) + if (f->priv_class) + return f->priv_class; + + return NULL; +} #define OFFSET(x) offsetof(AVFilterContext, x) #define FLAGS AV_OPT_FLAG_FILTERING_PARAM @@ -625,7 +638,10 @@ static const AVClass avfilter_class = { .version = LIBAVUTIL_VERSION_INT, .category = AV_CLASS_CATEGORY_FILTER, .child_next = filter_child_next, +#if FF_API_CHILD_CLASS_NEXT .child_class_next = filter_child_class_next, +#endif + .child_class_iterate = filter_child_class_iterate, .option = avfilter_options, }; diff --git a/externals/ffmpeg/libavfilter/dnn/Makefile b/externals/ffmpeg/libavfilter/dnn/Makefile index bb37298b5..d90137ec4 100755 --- a/externals/ffmpeg/libavfilter/dnn/Makefile +++ b/externals/ffmpeg/libavfilter/dnn/Makefile @@ -9,5 +9,6 @@ OBJS-$(CONFIG_DNN) += dnn/dnn_backend_native_layer_mat OBJS-$(CONFIG_DNN) += dnn/dnn_backend_native_layer_mathunary.o DNN-OBJS-$(CONFIG_LIBTENSORFLOW) += dnn/dnn_backend_tf.o +DNN-OBJS-$(CONFIG_LIBOPENVINO) += dnn/dnn_backend_openvino.o OBJS-$(CONFIG_DNN) += $(DNN-OBJS-yes) diff --git a/externals/ffmpeg/libavfilter/dnn/dnn_backend_native_layer_mathunary.c b/externals/ffmpeg/libavfilter/dnn/dnn_backend_native_layer_mathunary.c index 6f02faef7..c5f0f7ade 100755 --- a/externals/ffmpeg/libavfilter/dnn/dnn_backend_native_layer_mathunary.c +++ b/externals/ffmpeg/libavfilter/dnn/dnn_backend_native_layer_mathunary.c @@ -23,6 +23,8 @@ * DNN native backend implementation. */ +#include + #include "dnn_backend_native.h" #include "libavutil/avassert.h" #include "dnn_backend_native_layer_mathunary.h" @@ -80,6 +82,54 @@ int dnn_execute_layer_math_unary(DnnOperand *operands, const int32_t *input_oper for (int i = 0; i < dims_count; ++i) dst[i] = FFABS(src[i]); return 0; + case DMUO_SIN: + for (int i = 0; i < dims_count; ++i) + dst[i] = sin(src[i]); + return 0; + case DMUO_COS: + for (int i = 0; i < dims_count; ++i) + dst[i] = cos(src[i]); + return 0; + case DMUO_TAN: + for (int i = 0; i < dims_count; ++i) + dst[i] = tan(src[i]); + return 0; + case DMUO_ASIN: + for (int i = 0; i < dims_count; ++i) + dst[i] = asin(src[i]); + return 0; + case DMUO_ACOS: + for (int i = 0; i < dims_count; ++i) + dst[i] = acos(src[i]); + return 0; + case DMUO_ATAN: + for (int i = 0; i < dims_count; ++i) + dst[i] = atan(src[i]); + return 0; + case DMUO_SINH: + for (int i = 0; i < dims_count; ++i) + dst[i] = sinh(src[i]); + return 0; + case DMUO_COSH: + for (int i = 0; i < dims_count; ++i) + dst[i] = cosh(src[i]); + return 0; + case DMUO_TANH: + for (int i = 0; i < dims_count; ++i) + dst[i] = tanh(src[i]); + return 0; + case DMUO_ASINH: + for (int i = 0; i < dims_count; ++i) + dst[i] = asinh(src[i]); + return 0; + case DMUO_ACOSH: + for (int i = 0; i < dims_count; ++i) + dst[i] = acosh(src[i]); + return 0; + case DMUO_ATANH: + for (int i = 0; i < dims_count; ++i) + dst[i] = atanh(src[i]); + return 0; default: return -1; } diff --git a/externals/ffmpeg/libavfilter/dnn/dnn_backend_native_layer_mathunary.h b/externals/ffmpeg/libavfilter/dnn/dnn_backend_native_layer_mathunary.h index a9a8a0d30..8076356ba 100755 --- a/externals/ffmpeg/libavfilter/dnn/dnn_backend_native_layer_mathunary.h +++ b/externals/ffmpeg/libavfilter/dnn/dnn_backend_native_layer_mathunary.h @@ -31,6 +31,18 @@ typedef enum { DMUO_ABS = 0, + DMUO_SIN = 1, + DMUO_COS = 2, + DMUO_TAN = 3, + DMUO_ASIN = 4, + DMUO_ACOS = 5, + DMUO_ATAN = 6, + DMUO_SINH = 7, + DMUO_COSH = 8, + DMUO_TANH = 9, + DMUO_ASINH = 10, + DMUO_ACOSH = 11, + DMUO_ATANH = 12, DMUO_COUNT } DNNMathUnaryOperation; diff --git a/externals/ffmpeg/libavfilter/dnn/dnn_backend_openvino.c b/externals/ffmpeg/libavfilter/dnn/dnn_backend_openvino.c new file mode 100755 index 000000000..f048bc21a --- /dev/null +++ b/externals/ffmpeg/libavfilter/dnn/dnn_backend_openvino.c @@ -0,0 +1,261 @@ +/* + * Copyright (c) 2020 + * + * 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 + */ + +/** + * @file + * DNN OpenVINO backend implementation. + */ + +#include "dnn_backend_openvino.h" +#include "libavformat/avio.h" +#include "libavutil/avassert.h" +#include + +typedef struct OVModel{ + ie_core_t *core; + ie_network_t *network; + ie_executable_network_t *exe_network; + ie_infer_request_t *infer_request; + ie_blob_t *input_blob; + ie_blob_t **output_blobs; + uint32_t nb_output; +} OVModel; + +static DNNDataType precision_to_datatype(precision_e precision) +{ + switch (precision) + { + case FP32: + return DNN_FLOAT; + default: + av_assert0(!"not supported yet."); + return DNN_FLOAT; + } +} + +static DNNReturnType get_input_ov(void *model, DNNData *input, const char *input_name) +{ + OVModel *ov_model = (OVModel *)model; + char *model_input_name = NULL; + IEStatusCode status; + size_t model_input_count = 0; + dimensions_t dims; + precision_e precision; + + status = ie_network_get_inputs_number(ov_model->network, &model_input_count); + if (status != OK) + return DNN_ERROR; + + for (size_t i = 0; i < model_input_count; i++) { + status = ie_network_get_input_name(ov_model->network, i, &model_input_name); + if (status != OK) + return DNN_ERROR; + if (strcmp(model_input_name, input_name) == 0) { + ie_network_name_free(&model_input_name); + status |= ie_network_get_input_dims(ov_model->network, input_name, &dims); + status |= ie_network_get_input_precision(ov_model->network, input_name, &precision); + if (status != OK) + return DNN_ERROR; + + // The order of dims in the openvino is fixed and it is always NCHW for 4-D data. + // while we pass NHWC data from FFmpeg to openvino + status = ie_network_set_input_layout(ov_model->network, input_name, NHWC); + if (status != OK) + return DNN_ERROR; + + input->channels = dims.dims[1]; + input->height = dims.dims[2]; + input->width = dims.dims[3]; + input->dt = precision_to_datatype(precision); + return DNN_SUCCESS; + } + + ie_network_name_free(&model_input_name); + } + + return DNN_ERROR; +} + +static DNNReturnType set_input_output_ov(void *model, DNNData *input, const char *input_name, const char **output_names, uint32_t nb_output) +{ + OVModel *ov_model = (OVModel *)model; + IEStatusCode status; + dimensions_t dims; + precision_e precision; + ie_blob_buffer_t blob_buffer; + + status = ie_exec_network_create_infer_request(ov_model->exe_network, &ov_model->infer_request); + if (status != OK) + goto err; + + status = ie_infer_request_get_blob(ov_model->infer_request, input_name, &ov_model->input_blob); + if (status != OK) + goto err; + + status |= ie_blob_get_dims(ov_model->input_blob, &dims); + status |= ie_blob_get_precision(ov_model->input_blob, &precision); + if (status != OK) + goto err; + + av_assert0(input->channels == dims.dims[1]); + av_assert0(input->height == dims.dims[2]); + av_assert0(input->width == dims.dims[3]); + av_assert0(input->dt == precision_to_datatype(precision)); + + status = ie_blob_get_buffer(ov_model->input_blob, &blob_buffer); + if (status != OK) + goto err; + input->data = blob_buffer.buffer; + + // outputs + ov_model->nb_output = 0; + av_freep(&ov_model->output_blobs); + ov_model->output_blobs = av_mallocz_array(nb_output, sizeof(*ov_model->output_blobs)); + if (!ov_model->output_blobs) + goto err; + + for (int i = 0; i < nb_output; i++) { + const char *output_name = output_names[i]; + status = ie_infer_request_get_blob(ov_model->infer_request, output_name, &(ov_model->output_blobs[i])); + if (status != OK) + goto err; + ov_model->nb_output++; + } + + return DNN_SUCCESS; + +err: + if (ov_model->output_blobs) { + for (uint32_t i = 0; i < ov_model->nb_output; i++) { + ie_blob_free(&(ov_model->output_blobs[i])); + } + av_freep(&ov_model->output_blobs); + } + if (ov_model->input_blob) + ie_blob_free(&ov_model->input_blob); + if (ov_model->infer_request) + ie_infer_request_free(&ov_model->infer_request); + return DNN_ERROR; +} + +DNNModel *ff_dnn_load_model_ov(const char *model_filename) +{ + DNNModel *model = NULL; + OVModel *ov_model = NULL; + IEStatusCode status; + ie_config_t config = {NULL, NULL, NULL}; + + model = av_malloc(sizeof(DNNModel)); + if (!model){ + return NULL; + } + + ov_model = av_mallocz(sizeof(OVModel)); + if (!ov_model) + goto err; + + status = ie_core_create("", &ov_model->core); + if (status != OK) + goto err; + + status = ie_core_read_network(ov_model->core, model_filename, NULL, &ov_model->network); + if (status != OK) + goto err; + + status = ie_core_load_network(ov_model->core, ov_model->network, "CPU", &config, &ov_model->exe_network); + if (status != OK) + goto err; + + model->model = (void *)ov_model; + model->set_input_output = &set_input_output_ov; + model->get_input = &get_input_ov; + + return model; + +err: + if (model) + av_freep(&model); + if (ov_model) { + if (ov_model->exe_network) + ie_exec_network_free(&ov_model->exe_network); + if (ov_model->network) + ie_network_free(&ov_model->network); + if (ov_model->core) + ie_core_free(&ov_model->core); + av_freep(&ov_model); + } + return NULL; +} + +DNNReturnType ff_dnn_execute_model_ov(const DNNModel *model, DNNData *outputs, uint32_t nb_output) +{ + dimensions_t dims; + precision_e precision; + ie_blob_buffer_t blob_buffer; + OVModel *ov_model = (OVModel *)model->model; + uint32_t nb = FFMIN(nb_output, ov_model->nb_output); + IEStatusCode status = ie_infer_request_infer(ov_model->infer_request); + if (status != OK) + return DNN_ERROR; + + for (uint32_t i = 0; i < nb; ++i) { + status = ie_blob_get_buffer(ov_model->output_blobs[i], &blob_buffer); + if (status != OK) + return DNN_ERROR; + + status |= ie_blob_get_dims(ov_model->output_blobs[i], &dims); + status |= ie_blob_get_precision(ov_model->output_blobs[i], &precision); + if (status != OK) + return DNN_ERROR; + + outputs[i].channels = dims.dims[1]; + outputs[i].height = dims.dims[2]; + outputs[i].width = dims.dims[3]; + outputs[i].dt = precision_to_datatype(precision); + outputs[i].data = blob_buffer.buffer; + } + + return DNN_SUCCESS; +} + +void ff_dnn_free_model_ov(DNNModel **model) +{ + if (*model){ + OVModel *ov_model = (OVModel *)(*model)->model; + if (ov_model->output_blobs) { + for (uint32_t i = 0; i < ov_model->nb_output; i++) { + ie_blob_free(&(ov_model->output_blobs[i])); + } + av_freep(&ov_model->output_blobs); + } + if (ov_model->input_blob) + ie_blob_free(&ov_model->input_blob); + if (ov_model->infer_request) + ie_infer_request_free(&ov_model->infer_request); + if (ov_model->exe_network) + ie_exec_network_free(&ov_model->exe_network); + if (ov_model->network) + ie_network_free(&ov_model->network); + if (ov_model->core) + ie_core_free(&ov_model->core); + av_freep(&ov_model); + av_freep(model); + } +} diff --git a/externals/ffmpeg/libavfilter/dnn/dnn_backend_openvino.h b/externals/ffmpeg/libavfilter/dnn/dnn_backend_openvino.h new file mode 100755 index 000000000..397847a78 --- /dev/null +++ b/externals/ffmpeg/libavfilter/dnn/dnn_backend_openvino.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2020 + * + * 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 + */ + +/** + * @file + * DNN inference functions interface for OpenVINO backend. + */ + + +#ifndef AVFILTER_DNN_DNN_BACKEND_OPENVINO_H +#define AVFILTER_DNN_DNN_BACKEND_OPENVINO_H + +#include "../dnn_interface.h" + +DNNModel *ff_dnn_load_model_ov(const char *model_filename); + +DNNReturnType ff_dnn_execute_model_ov(const DNNModel *model, DNNData *outputs, uint32_t nb_output); + +void ff_dnn_free_model_ov(DNNModel **model); + +#endif diff --git a/externals/ffmpeg/libavfilter/dnn/dnn_interface.c b/externals/ffmpeg/libavfilter/dnn/dnn_interface.c index 62da55f43..7973d3e01 100755 --- a/externals/ffmpeg/libavfilter/dnn/dnn_interface.c +++ b/externals/ffmpeg/libavfilter/dnn/dnn_interface.c @@ -26,6 +26,7 @@ #include "../dnn_interface.h" #include "dnn_backend_native.h" #include "dnn_backend_tf.h" +#include "dnn_backend_openvino.h" #include "libavutil/mem.h" DNNModule *ff_get_dnn_module(DNNBackendType backend_type) @@ -53,6 +54,16 @@ DNNModule *ff_get_dnn_module(DNNBackendType backend_type) return NULL; #endif break; + case DNN_OV: + #if (CONFIG_LIBOPENVINO == 1) + dnn_module->load_model = &ff_dnn_load_model_ov; + dnn_module->execute_model = &ff_dnn_execute_model_ov; + dnn_module->free_model = &ff_dnn_free_model_ov; + #else + av_freep(&dnn_module); + return NULL; + #endif + break; default: av_log(NULL, AV_LOG_ERROR, "Module backend_type is not native or tensorflow\n"); av_freep(&dnn_module); diff --git a/externals/ffmpeg/libavfilter/dnn_interface.h b/externals/ffmpeg/libavfilter/dnn_interface.h index b20e5c8fa..f914265c5 100755 --- a/externals/ffmpeg/libavfilter/dnn_interface.h +++ b/externals/ffmpeg/libavfilter/dnn_interface.h @@ -30,7 +30,7 @@ typedef enum {DNN_SUCCESS, DNN_ERROR} DNNReturnType; -typedef enum {DNN_NATIVE, DNN_TF} DNNBackendType; +typedef enum {DNN_NATIVE, DNN_TF, DNN_OV} DNNBackendType; typedef enum {DNN_FLOAT = 1, DNN_UINT8 = 4} DNNDataType; diff --git a/externals/ffmpeg/libavfilter/f_select.c b/externals/ffmpeg/libavfilter/f_select.c index 755e10a39..92938c33a 100755 --- a/externals/ffmpeg/libavfilter/f_select.c +++ b/externals/ffmpeg/libavfilter/f_select.c @@ -325,9 +325,6 @@ static double get_concatdec_select(AVFrame *frame, int64_t pts) return NAN; } -#define D2TS(d) (isnan(d) ? AV_NOPTS_VALUE : (int64_t)(d)) -#define TS2D(ts) ((ts) == AV_NOPTS_VALUE ? NAN : (double)(ts)) - static void select_frame(AVFilterContext *ctx, AVFrame *frame) { SelectContext *select = ctx->priv; diff --git a/externals/ffmpeg/libavfilter/f_sendcmd.c b/externals/ffmpeg/libavfilter/f_sendcmd.c index 0ac87e07e..6b02669af 100755 --- a/externals/ffmpeg/libavfilter/f_sendcmd.c +++ b/externals/ffmpeg/libavfilter/f_sendcmd.c @@ -475,9 +475,6 @@ static av_cold void uninit(AVFilterContext *ctx) av_freep(&s->intervals); } -#define TS2D(ts) ((ts) == AV_NOPTS_VALUE ? NAN : (double)(ts)) -#define TS2T(ts, tb) ((ts) == AV_NOPTS_VALUE ? NAN : (double)(ts)*av_q2d(tb)) - static int filter_frame(AVFilterLink *inlink, AVFrame *ref) { AVFilterContext *ctx = inlink->dst; diff --git a/externals/ffmpeg/libavfilter/framesync.c b/externals/ffmpeg/libavfilter/framesync.c index b32a5cba6..bc6fce81f 100755 --- a/externals/ffmpeg/libavfilter/framesync.c +++ b/externals/ffmpeg/libavfilter/framesync.c @@ -53,6 +53,13 @@ static const AVClass framesync_class = { .parent_log_context_offset = OFFSET(parent), }; +const AVClass *ff_framesync_child_class_iterate(void **iter) +{ + const AVClass *c = *iter ? NULL : &framesync_class; + *iter = (void *)(uintptr_t)c; + return c; +} + enum { STATE_BOF, STATE_RUN, diff --git a/externals/ffmpeg/libavfilter/framesync.h b/externals/ffmpeg/libavfilter/framesync.h index 37743cccb..51bab1628 100755 --- a/externals/ffmpeg/libavfilter/framesync.h +++ b/externals/ffmpeg/libavfilter/framesync.h @@ -297,6 +297,8 @@ int ff_framesync_dualinput_get(FFFrameSync *fs, AVFrame **f0, AVFrame **f1); */ int ff_framesync_dualinput_get_writable(FFFrameSync *fs, AVFrame **f0, AVFrame **f1); +const AVClass *ff_framesync_child_class_iterate(void **iter); + #define FRAMESYNC_DEFINE_CLASS(name, context, field) \ static int name##_framesync_preinit(AVFilterContext *ctx) { \ context *s = ctx->priv; \ @@ -318,6 +320,7 @@ static const AVClass name##_class = { \ .version = LIBAVUTIL_VERSION_INT, \ .category = AV_CLASS_CATEGORY_FILTER, \ .child_class_next = name##_child_class_next, \ + .child_class_iterate = ff_framesync_child_class_iterate, \ .child_next = name##_child_next, \ } diff --git a/externals/ffmpeg/libavfilter/internal.h b/externals/ffmpeg/libavfilter/internal.h index abe7537b5..6cb601f36 100755 --- a/externals/ffmpeg/libavfilter/internal.h +++ b/externals/ffmpeg/libavfilter/internal.h @@ -234,6 +234,10 @@ void ff_avfilter_link_set_out_status(AVFilterLink *link, int status, int64_t pts void ff_command_queue_pop(AVFilterContext *filter); +#define D2TS(d) (isnan(d) ? AV_NOPTS_VALUE : (int64_t)(d)) +#define TS2D(ts) ((ts) == AV_NOPTS_VALUE ? NAN : (double)(ts)) +#define TS2T(ts, tb) ((ts) == AV_NOPTS_VALUE ? NAN : (double)(ts) * av_q2d(tb)) + /* misc trace functions */ #define FF_TPRINTF_START(ctx, func) ff_tlog(NULL, "%-16s: ", #func) diff --git a/externals/ffmpeg/libavfilter/setpts.c b/externals/ffmpeg/libavfilter/setpts.c index c7c383627..6506653c1 100755 --- a/externals/ffmpeg/libavfilter/setpts.c +++ b/externals/ffmpeg/libavfilter/setpts.c @@ -142,10 +142,6 @@ static int config_input(AVFilterLink *inlink) return 0; } -#define D2TS(d) (isnan(d) ? AV_NOPTS_VALUE : (int64_t)(d)) -#define TS2D(ts) ((ts) == AV_NOPTS_VALUE ? NAN : (double)(ts)) -#define TS2T(ts, tb) ((ts) == AV_NOPTS_VALUE ? NAN : (double)(ts)*av_q2d(tb)) - #define BUF_SIZE 64 static inline char *double2int64str(char *buf, double v) diff --git a/externals/ffmpeg/libavfilter/v360.h b/externals/ffmpeg/libavfilter/v360.h index e9a47593c..7fbbecf69 100755 --- a/externals/ffmpeg/libavfilter/v360.h +++ b/externals/ffmpeg/libavfilter/v360.h @@ -51,6 +51,8 @@ enum Projections { BARREL_SPLIT, TSPYRAMID, HEQUIRECTANGULAR, + EQUISOLID, + ORTHOGRAPHIC, NB_PROJECTIONS, }; diff --git a/externals/ffmpeg/libavfilter/version.h b/externals/ffmpeg/libavfilter/version.h index 96b14d679..308fbe07c 100755 --- a/externals/ffmpeg/libavfilter/version.h +++ b/externals/ffmpeg/libavfilter/version.h @@ -30,7 +30,7 @@ #include "libavutil/version.h" #define LIBAVFILTER_VERSION_MAJOR 7 -#define LIBAVFILTER_VERSION_MINOR 85 +#define LIBAVFILTER_VERSION_MINOR 87 #define LIBAVFILTER_VERSION_MICRO 100 diff --git a/externals/ffmpeg/libavfilter/vf_chromanr.c b/externals/ffmpeg/libavfilter/vf_chromanr.c new file mode 100755 index 000000000..7cda8a8a5 --- /dev/null +++ b/externals/ffmpeg/libavfilter/vf_chromanr.c @@ -0,0 +1,257 @@ +/* + * Copyright (c) 2020 Paul B Mahol + * + * 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/avstring.h" +#include "libavutil/imgutils.h" +#include "libavutil/opt.h" +#include "libavutil/pixdesc.h" + +#include "avfilter.h" +#include "formats.h" +#include "internal.h" +#include "video.h" + +typedef struct ChromaNRContext { + const AVClass *class; + + float threshold; + int thres; + int sizew; + int sizeh; + int stepw; + int steph; + int depth; + int chroma_w; + int chroma_h; + int nb_planes; + int linesize[4]; + int planeheight[4]; + int planewidth[4]; + + AVFrame *out; + int (*filter_slice)(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs); +} ChromaNRContext; + +static int query_formats(AVFilterContext *ctx) +{ + static const enum AVPixelFormat pix_fmts[] = { + AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV444P, + AV_PIX_FMT_YUVA420P, AV_PIX_FMT_YUVA422P, AV_PIX_FMT_YUVA444P, + AV_PIX_FMT_YUVJ444P, AV_PIX_FMT_YUVJ440P, AV_PIX_FMT_YUVJ422P, AV_PIX_FMT_YUVJ420P, AV_PIX_FMT_YUVJ411P, + AV_PIX_FMT_YUV420P9, AV_PIX_FMT_YUV422P9, AV_PIX_FMT_YUV444P9, + AV_PIX_FMT_YUV420P10, AV_PIX_FMT_YUV422P10, AV_PIX_FMT_YUV444P10, + AV_PIX_FMT_YUV444P12, AV_PIX_FMT_YUV422P12, AV_PIX_FMT_YUV440P12, AV_PIX_FMT_YUV420P12, + AV_PIX_FMT_YUV444P14, AV_PIX_FMT_YUV422P14, AV_PIX_FMT_YUV420P14, + AV_PIX_FMT_YUV420P16, AV_PIX_FMT_YUV422P16, AV_PIX_FMT_YUV444P16, + 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_YUVA422P12, AV_PIX_FMT_YUVA444P12, + AV_PIX_FMT_YUVA420P16, AV_PIX_FMT_YUVA422P16, AV_PIX_FMT_YUVA444P16, + AV_PIX_FMT_NONE + }; + + AVFilterFormats *fmts_list = ff_make_format_list(pix_fmts); + if (!fmts_list) + return AVERROR(ENOMEM); + return ff_set_common_formats(ctx, fmts_list); +} + +#define FILTER_FUNC(name, type) \ +static int filter_slice##name(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) \ +{ \ + ChromaNRContext *s = ctx->priv; \ + AVFrame *in = arg; \ + AVFrame *out = s->out; \ + const int in_ylinesize = in->linesize[0]; \ + const int in_ulinesize = in->linesize[1]; \ + const int in_vlinesize = in->linesize[2]; \ + const int out_ulinesize = out->linesize[1]; \ + const int out_vlinesize = out->linesize[2]; \ + const int chroma_w = s->chroma_w; \ + const int chroma_h = s->chroma_h; \ + const int stepw = s->stepw; \ + const int steph = s->steph; \ + const int sizew = s->sizew; \ + const int sizeh = s->sizeh; \ + const int thres = s->thres; \ + const int h = s->planeheight[1]; \ + const int w = s->planewidth[1]; \ + const int slice_start = (h * jobnr) / nb_jobs; \ + const int slice_end = (h * (jobnr+1)) / nb_jobs; \ + type *out_uptr = (type *)(out->data[1] + slice_start * out_ulinesize); \ + type *out_vptr = (type *)(out->data[2] + slice_start * out_vlinesize); \ + \ + { \ + const int h = s->planeheight[0]; \ + const int slice_start = (h * jobnr) / nb_jobs; \ + const int slice_end = (h * (jobnr+1)) / nb_jobs; \ + \ + av_image_copy_plane(out->data[0] + slice_start * out->linesize[0], \ + out->linesize[0], \ + in->data[0] + slice_start * in->linesize[0], \ + in->linesize[0], \ + s->linesize[0], slice_end - slice_start); \ + \ + if (s->nb_planes == 4) { \ + av_image_copy_plane(out->data[3] + slice_start * out->linesize[3], \ + out->linesize[3], \ + in->data[3] + slice_start * in->linesize[3], \ + in->linesize[3], \ + s->linesize[3], slice_end - slice_start); \ + } \ + } \ + \ + for (int y = slice_start; y < slice_end; y++) { \ + const type *in_yptr = (const type *)(in->data[0] + y * chroma_h * in_ylinesize); \ + const type *in_uptr = (const type *)(in->data[1] + y * in_ulinesize); \ + const type *in_vptr = (const type *)(in->data[2] + y * in_vlinesize); \ + \ + for (int x = 0; x < w; x++) { \ + const int cy = in_yptr[x * chroma_w]; \ + const int cu = in_uptr[x]; \ + const int cv = in_vptr[x]; \ + int su = cu; \ + int sv = cv; \ + int cn = 1; \ + \ + for (int yy = FFMAX(0, y - sizeh); yy < FFMIN(y + sizeh, h); yy += steph) { \ + const type *in_yptr = (const type *)(in->data[0] + yy * chroma_h * in_ylinesize); \ + const type *in_uptr = (const type *)(in->data[1] + yy * in_ulinesize); \ + const type *in_vptr = (const type *)(in->data[2] + yy * in_vlinesize); \ + \ + for (int xx = FFMAX(0, x - sizew); xx < FFMIN(x + sizew, w); xx += stepw) { \ + const int Y = in_yptr[xx * chroma_w]; \ + const int U = in_uptr[xx]; \ + const int V = in_vptr[xx]; \ + \ + if (FFABS(cu - U) + FFABS(cv - V) + FFABS(cy - Y) < thres && \ + xx != x && yy != y) { \ + su += U; \ + sv += V; \ + cn++; \ + } \ + } \ + } \ + \ + out_uptr[x] = su / cn; \ + out_vptr[x] = sv / cn; \ + } \ + \ + out_uptr += out_ulinesize / sizeof(type); \ + out_vptr += out_vlinesize / sizeof(type); \ + } \ + \ + return 0; \ +} + +FILTER_FUNC(8, uint8_t) +FILTER_FUNC(16, uint16_t) + +static int filter_frame(AVFilterLink *inlink, AVFrame *in) +{ + AVFilterContext *ctx = inlink->dst; + AVFilterLink *outlink = ctx->outputs[0]; + ChromaNRContext *s = ctx->priv; + AVFrame *out; + + out = ff_get_video_buffer(outlink, outlink->w, outlink->h); + if (!out) { + av_frame_free(&in); + return AVERROR(ENOMEM); + } + + av_frame_copy_props(out, in); + s->out = out; + ctx->internal->execute(ctx, s->filter_slice, in, NULL, + FFMIN3(s->planeheight[1], + s->planeheight[2], + ff_filter_get_nb_threads(ctx))); + + av_frame_free(&in); + return ff_filter_frame(outlink, out); +} + +static int config_input(AVFilterLink *inlink) +{ + AVFilterContext *ctx = inlink->dst; + ChromaNRContext *s = ctx->priv; + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format); + int ret; + + s->nb_planes = desc->nb_components; + s->depth = desc->comp[0].depth; + s->thres = s->threshold * (1 << (s->depth - 8)); + s->filter_slice = s->depth <= 8 ? filter_slice8 : filter_slice16; + s->chroma_w = 1 << desc->log2_chroma_w; + s->chroma_h = 1 << desc->log2_chroma_h; + s->planeheight[1] = s->planeheight[2] = AV_CEIL_RSHIFT(inlink->h, desc->log2_chroma_h); + s->planeheight[0] = s->planeheight[3] = inlink->h; + s->planewidth[1] = s->planewidth[2] = AV_CEIL_RSHIFT(inlink->w, desc->log2_chroma_w); + s->planewidth[0] = s->planewidth[3] = inlink->w; + + if ((ret = av_image_fill_linesizes(s->linesize, inlink->format, inlink->w)) < 0) + return ret; + + return 0; +} + +#define OFFSET(x) offsetof(ChromaNRContext, x) +#define VF AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_FILTERING_PARAM | AV_OPT_FLAG_RUNTIME_PARAM + +static const AVOption chromanr_options[] = { + { "thres", "set u/v threshold", OFFSET(threshold), AV_OPT_TYPE_FLOAT, {.dbl=30}, 1, 200, VF }, + { "sizew", "set horizontal size", OFFSET(sizew), AV_OPT_TYPE_INT, {.i64=5}, 1, 100, VF }, + { "sizeh", "set vertical size", OFFSET(sizeh), AV_OPT_TYPE_INT, {.i64=5}, 1, 100, VF }, + { "stepw", "set horizontal step", OFFSET(stepw), AV_OPT_TYPE_INT, {.i64=1}, 1, 50, VF }, + { "steph", "set vertical step", OFFSET(steph), AV_OPT_TYPE_INT, {.i64=1}, 1, 50, VF }, + { NULL } +}; + +static const AVFilterPad inputs[] = { + { + .name = "default", + .type = AVMEDIA_TYPE_VIDEO, + .filter_frame = filter_frame, + .config_props = config_input, + }, + { NULL } +}; + +static const AVFilterPad outputs[] = { + { + .name = "default", + .type = AVMEDIA_TYPE_VIDEO, + }, + { NULL } +}; + +AVFILTER_DEFINE_CLASS(chromanr); + +AVFilter ff_vf_chromanr = { + .name = "chromanr", + .description = NULL_IF_CONFIG_SMALL("Reduce chrominance noise."), + .priv_size = sizeof(ChromaNRContext), + .priv_class = &chromanr_class, + .query_formats = query_formats, + .outputs = outputs, + .inputs = inputs, + .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC | AVFILTER_FLAG_SLICE_THREADS, + .process_command = ff_filter_process_command, +}; diff --git a/externals/ffmpeg/libavfilter/vf_colorbalance.c b/externals/ffmpeg/libavfilter/vf_colorbalance.c index 56f9d5c49..6dc1b2848 100755 --- a/externals/ffmpeg/libavfilter/vf_colorbalance.c +++ b/externals/ffmpeg/libavfilter/vf_colorbalance.c @@ -111,7 +111,7 @@ static float get_component(float v, float l, v += m; v += h; - return av_clipf(v + 0.5f, 0, 1); + return av_clipf(v, 0, 1); } static float hfun(float n, float h, float s, float l) @@ -188,9 +188,9 @@ static int color_balance8_p(AVFilterContext *ctx, void *arg, int jobnr, int nb_j if (s->preserve_lightness) preservel(&r, &g, &b, l); - dstr[j] = av_clip_uint8(r * max); - dstg[j] = av_clip_uint8(g * max); - dstb[j] = av_clip_uint8(b * max); + dstr[j] = av_clip_uint8(lrintf(r * max)); + dstg[j] = av_clip_uint8(lrintf(g * max)); + dstb[j] = av_clip_uint8(lrintf(b * max)); if (in != out && out->linesize[3]) dsta[j] = srca[j]; } @@ -242,9 +242,9 @@ static int color_balance16_p(AVFilterContext *ctx, void *arg, int jobnr, int nb_ if (s->preserve_lightness) preservel(&r, &g, &b, l); - dstr[j] = av_clip_uintp2_c(r * max, depth); - dstg[j] = av_clip_uintp2_c(g * max, depth); - dstb[j] = av_clip_uintp2_c(b * max, depth); + dstr[j] = av_clip_uintp2_c(lrintf(r * max), depth); + dstg[j] = av_clip_uintp2_c(lrintf(g * max), depth); + dstb[j] = av_clip_uintp2_c(lrintf(b * max), depth); if (in != out && out->linesize[3]) dsta[j] = srca[j]; } @@ -299,9 +299,9 @@ static int color_balance8(AVFilterContext *ctx, void *arg, int jobnr, int nb_job if (s->preserve_lightness) preservel(&r, &g, &b, l); - dst[j + roffset] = av_clip_uint8(r * max); - dst[j + goffset] = av_clip_uint8(g * max); - dst[j + boffset] = av_clip_uint8(b * max); + dst[j + roffset] = av_clip_uint8(lrintf(r * max)); + dst[j + goffset] = av_clip_uint8(lrintf(g * max)); + dst[j + boffset] = av_clip_uint8(lrintf(b * max)); if (in != out && step == 4) dst[j + aoffset] = src[j + aoffset]; } @@ -351,9 +351,9 @@ static int color_balance16(AVFilterContext *ctx, void *arg, int jobnr, int nb_jo if (s->preserve_lightness) preservel(&r, &g, &b, l); - dst[j + roffset] = av_clip_uintp2_c(r * max, depth); - dst[j + goffset] = av_clip_uintp2_c(g * max, depth); - dst[j + boffset] = av_clip_uintp2_c(b * max, depth); + dst[j + roffset] = av_clip_uintp2_c(lrintf(r * max), depth); + dst[j + goffset] = av_clip_uintp2_c(lrintf(g * max), depth); + dst[j + boffset] = av_clip_uintp2_c(lrintf(b * max), depth); if (in != out && step == 4) dst[j + aoffset] = src[j + aoffset]; } diff --git a/externals/ffmpeg/libavfilter/vf_delogo.c b/externals/ffmpeg/libavfilter/vf_delogo.c index e55673d5a..6069c3016 100755 --- a/externals/ffmpeg/libavfilter/vf_delogo.c +++ b/externals/ffmpeg/libavfilter/vf_delogo.c @@ -55,7 +55,6 @@ enum var_name { VAR_T, VAR_VARS_NB }; -#define TS2T(ts, tb) ((ts) == AV_NOPTS_VALUE ? NAN : (double)(ts) * av_q2d(tb)) static int set_expr(AVExpr **pexpr, const char *expr, const char *option, void *log_ctx) { diff --git a/externals/ffmpeg/libavfilter/vf_dnn_processing.c b/externals/ffmpeg/libavfilter/vf_dnn_processing.c index cf589aced..4b31808ab 100755 --- a/externals/ffmpeg/libavfilter/vf_dnn_processing.c +++ b/externals/ffmpeg/libavfilter/vf_dnn_processing.c @@ -58,10 +58,13 @@ typedef struct DnnProcessingContext { #define OFFSET(x) offsetof(DnnProcessingContext, x) #define FLAGS AV_OPT_FLAG_FILTERING_PARAM | AV_OPT_FLAG_VIDEO_PARAM static const AVOption dnn_processing_options[] = { - { "dnn_backend", "DNN backend", OFFSET(backend_type), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, FLAGS, "backend" }, + { "dnn_backend", "DNN backend", OFFSET(backend_type), AV_OPT_TYPE_INT, { .i64 = 0 }, INT_MIN, INT_MAX, FLAGS, "backend" }, { "native", "native backend flag", 0, AV_OPT_TYPE_CONST, { .i64 = 0 }, 0, 0, FLAGS, "backend" }, #if (CONFIG_LIBTENSORFLOW == 1) { "tensorflow", "tensorflow backend flag", 0, AV_OPT_TYPE_CONST, { .i64 = 1 }, 0, 0, FLAGS, "backend" }, +#endif +#if (CONFIG_LIBOPENVINO == 1) + { "openvino", "openvino backend flag", 0, AV_OPT_TYPE_CONST, { .i64 = 2 }, 0, 0, FLAGS, "backend" }, #endif { "model", "path to model file", OFFSET(model_filename), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, FLAGS }, { "input", "input name of the model", OFFSET(model_inputname), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, FLAGS }, diff --git a/externals/ffmpeg/libavfilter/vf_edgedetect.c b/externals/ffmpeg/libavfilter/vf_edgedetect.c index a5614ea63..df8afbd53 100755 --- a/externals/ffmpeg/libavfilter/vf_edgedetect.c +++ b/externals/ffmpeg/libavfilter/vf_edgedetect.c @@ -294,7 +294,7 @@ static void double_threshold(int low, int high, int w, int h, continue; } - if ((!i || i == w - 1 || !j || j == h - 1) && + if (!(!i || i == w - 1 || !j || j == h - 1) && src[i] > low && (src[-src_linesize + i-1] > high || src[-src_linesize + i ] > high || diff --git a/externals/ffmpeg/libavfilter/vf_eq.c b/externals/ffmpeg/libavfilter/vf_eq.c index c8c3d5b34..114781fca 100755 --- a/externals/ffmpeg/libavfilter/vf_eq.c +++ b/externals/ffmpeg/libavfilter/vf_eq.c @@ -249,8 +249,6 @@ static int query_formats(AVFilterContext *ctx) return ff_set_common_formats(ctx, fmts_list); } -#define TS2T(ts, tb) ((ts) == AV_NOPTS_VALUE ? NAN : (double)(ts) * av_q2d(tb)) - static int filter_frame(AVFilterLink *inlink, AVFrame *in) { AVFilterContext *ctx = inlink->dst; diff --git a/externals/ffmpeg/libavfilter/vf_hue.c b/externals/ffmpeg/libavfilter/vf_hue.c index b75ef2105..1499c05cb 100755 --- a/externals/ffmpeg/libavfilter/vf_hue.c +++ b/externals/ffmpeg/libavfilter/vf_hue.c @@ -363,9 +363,6 @@ static void apply_lut10(HueContext *s, } } -#define TS2D(ts) ((ts) == AV_NOPTS_VALUE ? NAN : (double)(ts)) -#define TS2T(ts, tb) ((ts) == AV_NOPTS_VALUE ? NAN : (double)(ts) * av_q2d(tb)) - static int filter_frame(AVFilterLink *inlink, AVFrame *inpic) { HueContext *hue = inlink->dst->priv; diff --git a/externals/ffmpeg/libavfilter/vf_overlay.c b/externals/ffmpeg/libavfilter/vf_overlay.c index b5ab5fba5..b3a1ac1a0 100755 --- a/externals/ffmpeg/libavfilter/vf_overlay.c +++ b/externals/ffmpeg/libavfilter/vf_overlay.c @@ -154,6 +154,7 @@ static int process_command(AVFilterContext *ctx, const char *cmd, const char *ar static const enum AVPixelFormat alpha_pix_fmts[] = { AV_PIX_FMT_YUVA420P, AV_PIX_FMT_YUVA422P, AV_PIX_FMT_YUVA444P, + AV_PIX_FMT_YUVA420P10, AV_PIX_FMT_YUVA422P10, AV_PIX_FMT_ARGB, AV_PIX_FMT_ABGR, AV_PIX_FMT_RGBA, AV_PIX_FMT_BGRA, AV_PIX_FMT_GBRAP, AV_PIX_FMT_NONE }; @@ -172,6 +173,14 @@ static int query_formats(AVFilterContext *ctx) AV_PIX_FMT_YUVA420P, AV_PIX_FMT_NONE }; + static const enum AVPixelFormat main_pix_fmts_yuv420p10[] = { + AV_PIX_FMT_YUV420P10, AV_PIX_FMT_YUVA420P10, + AV_PIX_FMT_NONE + }; + static const enum AVPixelFormat overlay_pix_fmts_yuv420p10[] = { + AV_PIX_FMT_YUVA420P10, AV_PIX_FMT_NONE + }; + static const enum AVPixelFormat main_pix_fmts_yuv422[] = { AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUVJ422P, AV_PIX_FMT_YUVA422P, AV_PIX_FMT_NONE }; @@ -179,6 +188,13 @@ static int query_formats(AVFilterContext *ctx) AV_PIX_FMT_YUVA422P, AV_PIX_FMT_NONE }; + static const enum AVPixelFormat main_pix_fmts_yuv422p10[] = { + AV_PIX_FMT_YUV422P10, AV_PIX_FMT_YUVA422P10, AV_PIX_FMT_NONE + }; + static const enum AVPixelFormat overlay_pix_fmts_yuv422p10[] = { + AV_PIX_FMT_YUVA422P10, AV_PIX_FMT_NONE + }; + static const enum AVPixelFormat main_pix_fmts_yuv444[] = { AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUVJ444P, AV_PIX_FMT_YUVA444P, AV_PIX_FMT_NONE }; @@ -217,6 +233,13 @@ static int query_formats(AVFilterContext *ctx) goto fail; } break; + case OVERLAY_FORMAT_YUV420P10: + if (!(main_formats = ff_make_format_list(main_pix_fmts_yuv420p10)) || + !(overlay_formats = ff_make_format_list(overlay_pix_fmts_yuv420p10))) { + ret = AVERROR(ENOMEM); + goto fail; + } + break; case OVERLAY_FORMAT_YUV422: if (!(main_formats = ff_make_format_list(main_pix_fmts_yuv422)) || !(overlay_formats = ff_make_format_list(overlay_pix_fmts_yuv422))) { @@ -224,6 +247,13 @@ static int query_formats(AVFilterContext *ctx) goto fail; } break; + case OVERLAY_FORMAT_YUV422P10: + if (!(main_formats = ff_make_format_list(main_pix_fmts_yuv422p10)) || + !(overlay_formats = ff_make_format_list(overlay_pix_fmts_yuv422p10))) { + ret = AVERROR(ENOMEM); + goto fail; + } + break; case OVERLAY_FORMAT_YUV444: if (!(main_formats = ff_make_format_list(main_pix_fmts_yuv444)) || !(overlay_formats = ff_make_format_list(overlay_pix_fmts_yuv444))) { @@ -441,190 +471,216 @@ static av_always_inline void blend_slice_packed_rgb(AVFilterContext *ctx, } } -static av_always_inline void blend_plane(AVFilterContext *ctx, - AVFrame *dst, const AVFrame *src, - int src_w, int src_h, - int dst_w, int dst_h, - int i, int hsub, int vsub, - int x, int y, - int main_has_alpha, - int dst_plane, - int dst_offset, - int dst_step, - int straight, - int yuv, - int jobnr, - int nb_jobs) -{ - OverlayContext *octx = ctx->priv; - int src_wp = AV_CEIL_RSHIFT(src_w, hsub); - int src_hp = AV_CEIL_RSHIFT(src_h, vsub); - int dst_wp = AV_CEIL_RSHIFT(dst_w, hsub); - int dst_hp = AV_CEIL_RSHIFT(dst_h, vsub); - int yp = y>>vsub; - int xp = x>>hsub; - uint8_t *s, *sp, *d, *dp, *dap, *a, *da, *ap; - int jmax, j, k, kmax; - int slice_start, slice_end; - - j = FFMAX(-yp, 0); - jmax = FFMIN3(-yp + dst_hp, FFMIN(src_hp, dst_hp), yp + src_hp); - - slice_start = j + (jmax * jobnr) / nb_jobs; - slice_end = j + (jmax * (jobnr+1)) / nb_jobs; - - sp = src->data[i] + (slice_start) * src->linesize[i]; - dp = dst->data[dst_plane] - + (yp + slice_start) * dst->linesize[dst_plane] - + dst_offset; - ap = src->data[3] + (slice_start << vsub) * src->linesize[3]; - dap = dst->data[3] + ((yp + slice_start) << vsub) * dst->linesize[3]; - - for (j = slice_start; j < slice_end; j++) { - k = FFMAX(-xp, 0); - d = dp + (xp+k) * dst_step; - s = sp + k; - a = ap + (k<blend_row[i]) { - int c = octx->blend_row[i](d, da, s, a, kmax - k, src->linesize[3]); - - s += c; - d += dst_step * c; - da += (1 << hsub) * c; - a += (1 << hsub) * c; - k += c; - } - for (; k < kmax; k++) { - int alpha_v, alpha_h, alpha; - - // average alpha for color components, improve quality - if (hsub && vsub && j+1 < src_hp && k+1 < src_wp) { - alpha = (a[0] + a[src->linesize[3]] + - a[1] + a[src->linesize[3]+1]) >> 2; - } else if (hsub || vsub) { - alpha_h = hsub && k+1 < src_wp ? - (a[0] + a[1]) >> 1 : a[0]; - alpha_v = vsub && j+1 < src_hp ? - (a[0] + a[src->linesize[3]]) >> 1 : a[0]; - alpha = (alpha_v + alpha_h) >> 1; - } else - alpha = a[0]; - // if the main channel has an alpha channel, alpha has to be calculated - // to create an un-premultiplied (straight) alpha value - if (main_has_alpha && alpha != 0 && alpha != 255) { - // average alpha for color components, improve quality - uint8_t alpha_d; - if (hsub && vsub && j+1 < src_hp && k+1 < src_wp) { - alpha_d = (da[0] + da[dst->linesize[3]] + - da[1] + da[dst->linesize[3]+1]) >> 2; - } else if (hsub || vsub) { - alpha_h = hsub && k+1 < src_wp ? - (da[0] + da[1]) >> 1 : da[0]; - alpha_v = vsub && j+1 < src_hp ? - (da[0] + da[dst->linesize[3]]) >> 1 : da[0]; - alpha_d = (alpha_v + alpha_h) >> 1; - } else - alpha_d = da[0]; - alpha = UNPREMULTIPLY_ALPHA(alpha, alpha_d); - } - if (straight) { - *d = FAST_DIV255(*d * (255 - alpha) + *s * alpha); - } else { - if (i && yuv) - *d = av_clip(FAST_DIV255((*d - 128) * (255 - alpha)) + *s - 128, -128, 128) + 128; - else - *d = FFMIN(FAST_DIV255(*d * (255 - alpha)) + *s, 255); - } - s++; - d += dst_step; - da += 1 << hsub; - a += 1 << hsub; - } - dp += dst->linesize[dst_plane]; - sp += src->linesize[i]; - ap += (1 << vsub) * src->linesize[3]; - dap += (1 << vsub) * dst->linesize[3]; - } +#define DEFINE_BLEND_PLANE(depth, nbits) \ +static av_always_inline void blend_plane_##depth##_##nbits##bits(AVFilterContext *ctx, \ + AVFrame *dst, const AVFrame *src, \ + int src_w, int src_h, \ + int dst_w, int dst_h, \ + int i, int hsub, int vsub, \ + int x, int y, \ + int main_has_alpha, \ + int dst_plane, \ + int dst_offset, \ + int dst_step, \ + int straight, \ + int yuv, \ + int jobnr, \ + int nb_jobs) \ +{ \ + OverlayContext *octx = ctx->priv; \ + int src_wp = AV_CEIL_RSHIFT(src_w, hsub); \ + int src_hp = AV_CEIL_RSHIFT(src_h, vsub); \ + int dst_wp = AV_CEIL_RSHIFT(dst_w, hsub); \ + int dst_hp = AV_CEIL_RSHIFT(dst_h, vsub); \ + int yp = y>>vsub; \ + int xp = x>>hsub; \ + uint##depth##_t *s, *sp, *d, *dp, *dap, *a, *da, *ap; \ + int jmax, j, k, kmax; \ + int slice_start, slice_end; \ + const uint##depth##_t max = (1 << nbits) - 1; \ + const uint##depth##_t mid = (1 << (nbits -1)) ; \ + int bytes = depth / 8; \ + \ + dst_step /= bytes; \ + j = FFMAX(-yp, 0); \ + jmax = FFMIN3(-yp + dst_hp, FFMIN(src_hp, dst_hp), yp + src_hp); \ + \ + slice_start = j + (jmax * jobnr) / nb_jobs; \ + slice_end = j + (jmax * (jobnr+1)) / nb_jobs; \ + \ + sp = (uint##depth##_t *)(src->data[i] + (slice_start) * src->linesize[i]); \ + dp = (uint##depth##_t *)(dst->data[dst_plane] \ + + (yp + slice_start) * dst->linesize[dst_plane] \ + + dst_offset); \ + ap = (uint##depth##_t *)(src->data[3] + (slice_start << vsub) * src->linesize[3]); \ + dap = (uint##depth##_t *)(dst->data[3] + ((yp + slice_start) << vsub) * dst->linesize[3]); \ + \ + for (j = slice_start; j < slice_end; j++) { \ + k = FFMAX(-xp, 0); \ + d = dp + (xp+k) * dst_step; \ + s = sp + k; \ + a = ap + (k<blend_row[i]) { \ + int c = octx->blend_row[i]((uint8_t*)d, (uint8_t*)da, (uint8_t*)s, \ + (uint8_t*)a, kmax - k, src->linesize[3]); \ + \ + s += c; \ + d += dst_step * c; \ + da += (1 << hsub) * c; \ + a += (1 << hsub) * c; \ + k += c; \ + } \ + for (; k < kmax; k++) { \ + int alpha_v, alpha_h, alpha; \ + \ + /* average alpha for color components, improve quality */ \ + if (hsub && vsub && j+1 < src_hp && k+1 < src_wp) { \ + alpha = (a[0] + a[src->linesize[3]] + \ + a[1] + a[src->linesize[3]+1]) >> 2; \ + } else if (hsub || vsub) { \ + alpha_h = hsub && k+1 < src_wp ? \ + (a[0] + a[1]) >> 1 : a[0]; \ + alpha_v = vsub && j+1 < src_hp ? \ + (a[0] + a[src->linesize[3]]) >> 1 : a[0]; \ + alpha = (alpha_v + alpha_h) >> 1; \ + } else \ + alpha = a[0]; \ + /* if the main channel has an alpha channel, alpha has to be calculated */ \ + /* to create an un-premultiplied (straight) alpha value */ \ + if (main_has_alpha && alpha != 0 && alpha != max) { \ + /* average alpha for color components, improve quality */ \ + uint8_t alpha_d; \ + if (hsub && vsub && j+1 < src_hp && k+1 < src_wp) { \ + alpha_d = (da[0] + da[dst->linesize[3]] + \ + da[1] + da[dst->linesize[3]+1]) >> 2; \ + } else if (hsub || vsub) { \ + alpha_h = hsub && k+1 < src_wp ? \ + (da[0] + da[1]) >> 1 : da[0]; \ + alpha_v = vsub && j+1 < src_hp ? \ + (da[0] + da[dst->linesize[3]]) >> 1 : da[0]; \ + alpha_d = (alpha_v + alpha_h) >> 1; \ + } else \ + alpha_d = da[0]; \ + alpha = UNPREMULTIPLY_ALPHA(alpha, alpha_d); \ + } \ + if (straight) { \ + if (nbits > 8) \ + *d = (*d * (max - alpha) + *s * alpha) / max; \ + else \ + *d = FAST_DIV255(*d * (255 - alpha) + *s * alpha); \ + } else { \ + if (nbits > 8) { \ + if (i && yuv) \ + *d = av_clip((*d * (max - alpha) + *s * alpha) / max + *s - mid, -mid, mid) + mid; \ + else \ + *d = FFMIN((*d * (max - alpha) + *s * alpha) / max + *s, max); \ + } else { \ + if (i && yuv) \ + *d = av_clip(FAST_DIV255((*d - mid) * (max - alpha)) + *s - mid, -mid, mid) + mid; \ + else \ + *d = FFMIN(FAST_DIV255(*d * (max - alpha)) + *s, max); \ + } \ + } \ + s++; \ + d += dst_step; \ + da += 1 << hsub; \ + a += 1 << hsub; \ + } \ + dp += dst->linesize[dst_plane] / bytes; \ + sp += src->linesize[i] / bytes; \ + ap += (1 << vsub) * src->linesize[3] / bytes; \ + dap += (1 << vsub) * dst->linesize[3] / bytes; \ + } \ } +DEFINE_BLEND_PLANE(8, 8); +DEFINE_BLEND_PLANE(16, 10); -static inline void alpha_composite(const AVFrame *src, const AVFrame *dst, - int src_w, int src_h, - int dst_w, int dst_h, - int x, int y, - int jobnr, int nb_jobs) -{ - uint8_t alpha; ///< the amount of overlay to blend on to main - uint8_t *s, *sa, *d, *da; - int i, imax, j, jmax; - int slice_start, slice_end; - - imax = FFMIN(-y + dst_h, src_h); - slice_start = (imax * jobnr) / nb_jobs; - slice_end = ((imax * (jobnr+1)) / nb_jobs); - - i = FFMAX(-y, 0); - sa = src->data[3] + (i + slice_start) * src->linesize[3]; - da = dst->data[3] + (y + i + slice_start) * dst->linesize[3]; - - for (i = i + slice_start; i < slice_end; i++) { - j = FFMAX(-x, 0); - s = sa + j; - d = da + x+j; - - for (jmax = FFMIN(-x + dst_w, src_w); j < jmax; j++) { - alpha = *s; - if (alpha != 0 && alpha != 255) { - uint8_t alpha_d = *d; - alpha = UNPREMULTIPLY_ALPHA(alpha, alpha_d); - } - switch (alpha) { - case 0: - break; - case 255: - *d = *s; - break; - default: - // apply alpha compositing: main_alpha += (1-main_alpha) * overlay_alpha - *d += FAST_DIV255((255 - *d) * *s); - } - d += 1; - s += 1; - } - da += dst->linesize[3]; - sa += src->linesize[3]; - } +#define DEFINE_ALPHA_COMPOSITE(depth, nbits) \ +static inline void alpha_composite_##depth##_##nbits##bits(const AVFrame *src, const AVFrame *dst, \ + int src_w, int src_h, \ + int dst_w, int dst_h, \ + int x, int y, \ + int jobnr, int nb_jobs) \ +{ \ + uint##depth##_t alpha; /* the amount of overlay to blend on to main */ \ + uint##depth##_t *s, *sa, *d, *da; \ + int i, imax, j, jmax; \ + int slice_start, slice_end; \ + const uint##depth##_t max = (1 << nbits) - 1; \ + int bytes = depth / 8; \ + \ + imax = FFMIN(-y + dst_h, src_h); \ + slice_start = (imax * jobnr) / nb_jobs; \ + slice_end = ((imax * (jobnr+1)) / nb_jobs); \ + \ + i = FFMAX(-y, 0); \ + sa = (uint##depth##_t *)(src->data[3] + (i + slice_start) * src->linesize[3]); \ + da = (uint##depth##_t *)(dst->data[3] + (y + i + slice_start) * dst->linesize[3]); \ + \ + for (i = i + slice_start; i < slice_end; i++) { \ + j = FFMAX(-x, 0); \ + s = sa + j; \ + d = da + x+j; \ + \ + for (jmax = FFMIN(-x + dst_w, src_w); j < jmax; j++) { \ + alpha = *s; \ + if (alpha != 0 && alpha != max) { \ + uint8_t alpha_d = *d; \ + alpha = UNPREMULTIPLY_ALPHA(alpha, alpha_d); \ + } \ + if (alpha == max) \ + *d = *s; \ + else if (alpha > 0) { \ + /* apply alpha compositing: main_alpha += (1-main_alpha) * overlay_alpha */ \ + if (nbits > 8) \ + *d += (max - *d) * *s / max; \ + else \ + *d += FAST_DIV255((max - *d) * *s); \ + } \ + d += 1; \ + s += 1; \ + } \ + da += dst->linesize[3] / bytes; \ + sa += src->linesize[3] / bytes; \ + } \ } +DEFINE_ALPHA_COMPOSITE(8, 8); +DEFINE_ALPHA_COMPOSITE(16, 10); -static av_always_inline void blend_slice_yuv(AVFilterContext *ctx, - AVFrame *dst, const AVFrame *src, - int hsub, int vsub, - int main_has_alpha, - int x, int y, - int is_straight, - int jobnr, int nb_jobs) -{ - OverlayContext *s = ctx->priv; - const int src_w = src->width; - const int src_h = src->height; - const int dst_w = dst->width; - const int dst_h = dst->height; - - blend_plane(ctx, dst, src, src_w, src_h, dst_w, dst_h, 0, 0, 0, x, y, main_has_alpha, - s->main_desc->comp[0].plane, s->main_desc->comp[0].offset, s->main_desc->comp[0].step, is_straight, 1, - jobnr, nb_jobs); - blend_plane(ctx, dst, src, src_w, src_h, dst_w, dst_h, 1, hsub, vsub, x, y, main_has_alpha, - s->main_desc->comp[1].plane, s->main_desc->comp[1].offset, s->main_desc->comp[1].step, is_straight, 1, - jobnr, nb_jobs); - blend_plane(ctx, dst, src, src_w, src_h, dst_w, dst_h, 2, hsub, vsub, x, y, main_has_alpha, - s->main_desc->comp[2].plane, s->main_desc->comp[2].offset, s->main_desc->comp[2].step, is_straight, 1, - jobnr, nb_jobs); - - if (main_has_alpha) - alpha_composite(src, dst, src_w, src_h, dst_w, dst_h, x, y, jobnr, nb_jobs); +#define DEFINE_BLEND_SLICE_YUV(depth, nbits) \ +static av_always_inline void blend_slice_yuv_##depth##_##nbits##bits(AVFilterContext *ctx, \ + AVFrame *dst, const AVFrame *src, \ + int hsub, int vsub, \ + int main_has_alpha, \ + int x, int y, \ + int is_straight, \ + int jobnr, int nb_jobs) \ +{ \ + OverlayContext *s = ctx->priv; \ + const int src_w = src->width; \ + const int src_h = src->height; \ + const int dst_w = dst->width; \ + const int dst_h = dst->height; \ + \ + blend_plane_##depth##_##nbits##bits(ctx, dst, src, src_w, src_h, dst_w, dst_h, 0, 0, 0, \ + x, y, main_has_alpha, s->main_desc->comp[0].plane, s->main_desc->comp[0].offset, \ + s->main_desc->comp[0].step, is_straight, 1, jobnr, nb_jobs); \ + blend_plane_##depth##_##nbits##bits(ctx, dst, src, src_w, src_h, dst_w, dst_h, 1, hsub, vsub, \ + x, y, main_has_alpha, s->main_desc->comp[1].plane, s->main_desc->comp[1].offset, \ + s->main_desc->comp[1].step, is_straight, 1, jobnr, nb_jobs); \ + blend_plane_##depth##_##nbits##bits(ctx, dst, src, src_w, src_h, dst_w, dst_h, 2, hsub, vsub, \ + x, y, main_has_alpha, s->main_desc->comp[2].plane, s->main_desc->comp[2].offset, \ + s->main_desc->comp[2].step, is_straight, 1, jobnr, nb_jobs); \ + \ + if (main_has_alpha) \ + alpha_composite_##depth##_##nbits##bits(src, dst, src_w, src_h, dst_w, dst_h, x, y, \ + jobnr, nb_jobs); \ } +DEFINE_BLEND_SLICE_YUV(8, 8); +DEFINE_BLEND_SLICE_YUV(16, 10); static av_always_inline void blend_slice_planar_rgb(AVFilterContext *ctx, AVFrame *dst, const AVFrame *src, @@ -641,25 +697,25 @@ static av_always_inline void blend_slice_planar_rgb(AVFilterContext *ctx, const int dst_w = dst->width; const int dst_h = dst->height; - blend_plane(ctx, dst, src, src_w, src_h, dst_w, dst_h, 0, 0, 0, x, y, main_has_alpha, + blend_plane_8_8bits(ctx, dst, src, src_w, src_h, dst_w, dst_h, 0, 0, 0, x, y, main_has_alpha, s->main_desc->comp[1].plane, s->main_desc->comp[1].offset, s->main_desc->comp[1].step, is_straight, 0, jobnr, nb_jobs); - blend_plane(ctx, dst, src, src_w, src_h, dst_w, dst_h, 1, hsub, vsub, x, y, main_has_alpha, + blend_plane_8_8bits(ctx, dst, src, src_w, src_h, dst_w, dst_h, 1, hsub, vsub, x, y, main_has_alpha, s->main_desc->comp[2].plane, s->main_desc->comp[2].offset, s->main_desc->comp[2].step, is_straight, 0, jobnr, nb_jobs); - blend_plane(ctx, dst, src, src_w, src_h, dst_w, dst_h, 2, hsub, vsub, x, y, main_has_alpha, + blend_plane_8_8bits(ctx, dst, src, src_w, src_h, dst_w, dst_h, 2, hsub, vsub, x, y, main_has_alpha, s->main_desc->comp[0].plane, s->main_desc->comp[0].offset, s->main_desc->comp[0].step, is_straight, 0, jobnr, nb_jobs); if (main_has_alpha) - alpha_composite(src, dst, src_w, src_h, dst_w, dst_h, x, y, jobnr, nb_jobs); + alpha_composite_8_8bits(src, dst, src_w, src_h, dst_w, dst_h, x, y, jobnr, nb_jobs); } static int blend_slice_yuv420(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) { OverlayContext *s = ctx->priv; ThreadData *td = arg; - blend_slice_yuv(ctx, td->dst, td->src, 1, 1, 0, s->x, s->y, 1, jobnr, nb_jobs); + blend_slice_yuv_8_8bits(ctx, td->dst, td->src, 1, 1, 0, s->x, s->y, 1, jobnr, nb_jobs); return 0; } @@ -667,7 +723,39 @@ static int blend_slice_yuva420(AVFilterContext *ctx, void *arg, int jobnr, int n { OverlayContext *s = ctx->priv; ThreadData *td = arg; - blend_slice_yuv(ctx, td->dst, td->src, 1, 1, 1, s->x, s->y, 1, jobnr, nb_jobs); + blend_slice_yuv_8_8bits(ctx, td->dst, td->src, 1, 1, 1, s->x, s->y, 1, jobnr, nb_jobs); + return 0; +} + +static int blend_slice_yuv420p10(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) +{ + OverlayContext *s = ctx->priv; + ThreadData *td = arg; + blend_slice_yuv_16_10bits(ctx, td->dst, td->src, 1, 1, 0, s->x, s->y, 1, jobnr, nb_jobs); + return 0; +} + +static int blend_slice_yuva420p10(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) +{ + OverlayContext *s = ctx->priv; + ThreadData *td = arg; + blend_slice_yuv_16_10bits(ctx, td->dst, td->src, 1, 1, 1, s->x, s->y, 1, jobnr, nb_jobs); + return 0; +} + +static int blend_slice_yuv422p10(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) +{ + OverlayContext *s = ctx->priv; + ThreadData *td = arg; + blend_slice_yuv_16_10bits(ctx, td->dst, td->src, 1, 0, 0, s->x, s->y, 1, jobnr, nb_jobs); + return 0; +} + +static int blend_slice_yuva422p10(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) +{ + OverlayContext *s = ctx->priv; + ThreadData *td = arg; + blend_slice_yuv_16_10bits(ctx, td->dst, td->src, 1, 0, 1, s->x, s->y, 1, jobnr, nb_jobs); return 0; } @@ -675,7 +763,7 @@ static int blend_slice_yuv422(AVFilterContext *ctx, void *arg, int jobnr, int nb { OverlayContext *s = ctx->priv; ThreadData *td = arg; - blend_slice_yuv(ctx, td->dst, td->src, 1, 0, 0, s->x, s->y, 1, jobnr, nb_jobs); + blend_slice_yuv_8_8bits(ctx, td->dst, td->src, 1, 0, 0, s->x, s->y, 1, jobnr, nb_jobs); return 0; } @@ -683,7 +771,7 @@ static int blend_slice_yuva422(AVFilterContext *ctx, void *arg, int jobnr, int n { OverlayContext *s = ctx->priv; ThreadData *td = arg; - blend_slice_yuv(ctx, td->dst, td->src, 1, 0, 1, s->x, s->y, 1, jobnr, nb_jobs); + blend_slice_yuv_8_8bits(ctx, td->dst, td->src, 1, 0, 1, s->x, s->y, 1, jobnr, nb_jobs); return 0; } @@ -691,7 +779,7 @@ static int blend_slice_yuv444(AVFilterContext *ctx, void *arg, int jobnr, int nb { OverlayContext *s = ctx->priv; ThreadData *td = arg; - blend_slice_yuv(ctx, td->dst, td->src, 0, 0, 0, s->x, s->y, 1, jobnr, nb_jobs); + blend_slice_yuv_8_8bits(ctx, td->dst, td->src, 0, 0, 0, s->x, s->y, 1, jobnr, nb_jobs); return 0; } @@ -699,7 +787,7 @@ static int blend_slice_yuva444(AVFilterContext *ctx, void *arg, int jobnr, int n { OverlayContext *s = ctx->priv; ThreadData *td = arg; - blend_slice_yuv(ctx, td->dst, td->src, 0, 0, 1, s->x, s->y, 1, jobnr, nb_jobs); + blend_slice_yuv_8_8bits(ctx, td->dst, td->src, 0, 0, 1, s->x, s->y, 1, jobnr, nb_jobs); return 0; } @@ -723,7 +811,7 @@ static int blend_slice_yuv420_pm(AVFilterContext *ctx, void *arg, int jobnr, int { OverlayContext *s = ctx->priv; ThreadData *td = arg; - blend_slice_yuv(ctx, td->dst, td->src, 1, 1, 0, s->x, s->y, 0, jobnr, nb_jobs); + blend_slice_yuv_8_8bits(ctx, td->dst, td->src, 1, 1, 0, s->x, s->y, 0, jobnr, nb_jobs); return 0; } @@ -731,7 +819,7 @@ static int blend_slice_yuva420_pm(AVFilterContext *ctx, void *arg, int jobnr, in { OverlayContext *s = ctx->priv; ThreadData *td = arg; - blend_slice_yuv(ctx, td->dst, td->src, 1, 1, 1, s->x, s->y, 0, jobnr, nb_jobs); + blend_slice_yuv_8_8bits(ctx, td->dst, td->src, 1, 1, 1, s->x, s->y, 0, jobnr, nb_jobs); return 0; } @@ -739,7 +827,7 @@ static int blend_slice_yuv422_pm(AVFilterContext *ctx, void *arg, int jobnr, int { OverlayContext *s = ctx->priv; ThreadData *td = arg; - blend_slice_yuv(ctx, td->dst, td->src, 1, 0, 0, s->x, s->y, 0, jobnr, nb_jobs); + blend_slice_yuv_8_8bits(ctx, td->dst, td->src, 1, 0, 0, s->x, s->y, 0, jobnr, nb_jobs); return 0; } @@ -747,7 +835,7 @@ static int blend_slice_yuva422_pm(AVFilterContext *ctx, void *arg, int jobnr, in { OverlayContext *s = ctx->priv; ThreadData *td = arg; - blend_slice_yuv(ctx, td->dst, td->src, 1, 0, 1, s->x, s->y, 0, jobnr, nb_jobs); + blend_slice_yuv_8_8bits(ctx, td->dst, td->src, 1, 0, 1, s->x, s->y, 0, jobnr, nb_jobs); return 0; } @@ -755,7 +843,7 @@ static int blend_slice_yuv444_pm(AVFilterContext *ctx, void *arg, int jobnr, int { OverlayContext *s = ctx->priv; ThreadData *td = arg; - blend_slice_yuv(ctx, td->dst, td->src, 0, 0, 0, s->x, s->y, 0, jobnr, nb_jobs); + blend_slice_yuv_8_8bits(ctx, td->dst, td->src, 0, 0, 0, s->x, s->y, 0, jobnr, nb_jobs); return 0; } @@ -763,7 +851,7 @@ static int blend_slice_yuva444_pm(AVFilterContext *ctx, void *arg, int jobnr, in { OverlayContext *s = ctx->priv; ThreadData *td = arg; - blend_slice_yuv(ctx, td->dst, td->src, 0, 0, 1, s->x, s->y, 0, jobnr, nb_jobs); + blend_slice_yuv_8_8bits(ctx, td->dst, td->src, 0, 0, 1, s->x, s->y, 0, jobnr, nb_jobs); return 0; } @@ -834,9 +922,15 @@ static int config_input_main(AVFilterLink *inlink) case OVERLAY_FORMAT_YUV420: s->blend_slice = s->main_has_alpha ? blend_slice_yuva420 : blend_slice_yuv420; break; + case OVERLAY_FORMAT_YUV420P10: + s->blend_slice = s->main_has_alpha ? blend_slice_yuva420p10 : blend_slice_yuv420p10; + break; case OVERLAY_FORMAT_YUV422: s->blend_slice = s->main_has_alpha ? blend_slice_yuva422 : blend_slice_yuv422; break; + case OVERLAY_FORMAT_YUV422P10: + s->blend_slice = s->main_has_alpha ? blend_slice_yuva422p10 : blend_slice_yuv422p10; + break; case OVERLAY_FORMAT_YUV444: s->blend_slice = s->main_has_alpha ? blend_slice_yuva444 : blend_slice_yuv444; break; @@ -851,9 +945,15 @@ static int config_input_main(AVFilterLink *inlink) case AV_PIX_FMT_YUVA420P: s->blend_slice = blend_slice_yuva420; break; + case AV_PIX_FMT_YUVA420P10: + s->blend_slice = blend_slice_yuva420p10; + break; case AV_PIX_FMT_YUVA422P: s->blend_slice = blend_slice_yuva422; break; + case AV_PIX_FMT_YUVA422P10: + s->blend_slice = blend_slice_yuva422p10; + break; case AV_PIX_FMT_YUVA444P: s->blend_slice = blend_slice_yuva444; break; @@ -1005,7 +1105,9 @@ static const AVOption overlay_options[] = { { "shortest", "force termination when the shortest input terminates", OFFSET(fs.opt_shortest), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, FLAGS }, { "format", "set output format", OFFSET(format), AV_OPT_TYPE_INT, {.i64=OVERLAY_FORMAT_YUV420}, 0, OVERLAY_FORMAT_NB-1, FLAGS, "format" }, { "yuv420", "", 0, AV_OPT_TYPE_CONST, {.i64=OVERLAY_FORMAT_YUV420}, .flags = FLAGS, .unit = "format" }, + { "yuv420p10", "", 0, AV_OPT_TYPE_CONST, {.i64=OVERLAY_FORMAT_YUV420P10}, .flags = FLAGS, .unit = "format" }, { "yuv422", "", 0, AV_OPT_TYPE_CONST, {.i64=OVERLAY_FORMAT_YUV422}, .flags = FLAGS, .unit = "format" }, + { "yuv422p10", "", 0, AV_OPT_TYPE_CONST, {.i64=OVERLAY_FORMAT_YUV422P10}, .flags = FLAGS, .unit = "format" }, { "yuv444", "", 0, AV_OPT_TYPE_CONST, {.i64=OVERLAY_FORMAT_YUV444}, .flags = FLAGS, .unit = "format" }, { "rgb", "", 0, AV_OPT_TYPE_CONST, {.i64=OVERLAY_FORMAT_RGB}, .flags = FLAGS, .unit = "format" }, { "gbrp", "", 0, AV_OPT_TYPE_CONST, {.i64=OVERLAY_FORMAT_GBRP}, .flags = FLAGS, .unit = "format" }, diff --git a/externals/ffmpeg/libavfilter/vf_overlay.h b/externals/ffmpeg/libavfilter/vf_overlay.h index 98b06eaac..30a1a7371 100755 --- a/externals/ffmpeg/libavfilter/vf_overlay.h +++ b/externals/ffmpeg/libavfilter/vf_overlay.h @@ -41,7 +41,9 @@ enum var_name { enum OverlayFormat { OVERLAY_FORMAT_YUV420, + OVERLAY_FORMAT_YUV420P10, OVERLAY_FORMAT_YUV422, + OVERLAY_FORMAT_YUV422P10, OVERLAY_FORMAT_YUV444, OVERLAY_FORMAT_RGB, OVERLAY_FORMAT_GBRP, diff --git a/externals/ffmpeg/libavfilter/vf_rotate.c b/externals/ffmpeg/libavfilter/vf_rotate.c index 02f56c6eb..65c6cc411 100755 --- a/externals/ffmpeg/libavfilter/vf_rotate.c +++ b/externals/ffmpeg/libavfilter/vf_rotate.c @@ -415,8 +415,6 @@ static av_always_inline void simple_rotate(uint8_t *dst, const uint8_t *src, int } } -#define TS2T(ts, tb) ((ts) == AV_NOPTS_VALUE ? NAN : (double)(ts)*av_q2d(tb)) - static int filter_slice(AVFilterContext *ctx, void *arg, int job, int nb_jobs) { ThreadData *td = arg; diff --git a/externals/ffmpeg/libavfilter/vf_scale.c b/externals/ffmpeg/libavfilter/vf_scale.c index 0348f19d3..ff69bb138 100755 --- a/externals/ffmpeg/libavfilter/vf_scale.c +++ b/externals/ffmpeg/libavfilter/vf_scale.c @@ -647,8 +647,6 @@ static int scale_slice(AVFilterLink *link, AVFrame *out_buf, AVFrame *cur_pic, s out,out_stride); } -#define TS2T(ts, tb) ((ts) == AV_NOPTS_VALUE ? NAN : (double)(ts) * av_q2d(tb)) - static int scale_frame(AVFilterLink *link, AVFrame *in, AVFrame **frame_out) { AVFilterContext *ctx = link->dst; @@ -882,10 +880,19 @@ static int process_command(AVFilterContext *ctx, const char *cmd, const char *ar return ret; } +#if FF_API_CHILD_CLASS_NEXT static const AVClass *child_class_next(const AVClass *prev) { return prev ? NULL : sws_get_class(); } +#endif + +static const AVClass *child_class_iterate(void **iter) +{ + const AVClass *c = *iter ? NULL : sws_get_class(); + *iter = (void*)(uintptr_t)c; + return c; +} #define OFFSET(x) offsetof(ScaleContext, x) #define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM @@ -944,7 +951,10 @@ static const AVClass scale_class = { .option = scale_options, .version = LIBAVUTIL_VERSION_INT, .category = AV_CLASS_CATEGORY_FILTER, +#if FF_API_CHILD_CLASS_NEXT .child_class_next = child_class_next, +#endif + .child_class_iterate = child_class_iterate, }; static const AVFilterPad avfilter_vf_scale_inputs[] = { @@ -984,7 +994,10 @@ static const AVClass scale2ref_class = { .option = scale_options, .version = LIBAVUTIL_VERSION_INT, .category = AV_CLASS_CATEGORY_FILTER, +#if FF_API_CHILD_CLASS_NEXT .child_class_next = child_class_next, +#endif + .child_class_iterate = child_class_iterate, }; static const AVFilterPad avfilter_vf_scale2ref_inputs[] = { diff --git a/externals/ffmpeg/libavfilter/vf_showinfo.c b/externals/ffmpeg/libavfilter/vf_showinfo.c index 5d4aee416..1be939614 100755 --- a/externals/ffmpeg/libavfilter/vf_showinfo.c +++ b/externals/ffmpeg/libavfilter/vf_showinfo.c @@ -64,7 +64,7 @@ static void dump_spherical(AVFilterContext *ctx, AVFrame *frame, AVFrameSideData av_log(ctx, AV_LOG_INFO, "spherical information: "); if (sd->size < sizeof(*spherical)) { - av_log(ctx, AV_LOG_ERROR, "invalid data"); + av_log(ctx, AV_LOG_ERROR, "invalid data\n"); return; } @@ -75,7 +75,7 @@ static void dump_spherical(AVFilterContext *ctx, AVFrame *frame, AVFrameSideData else if (spherical->projection == AV_SPHERICAL_EQUIRECTANGULAR_TILE) av_log(ctx, AV_LOG_INFO, "tiled equirectangular "); else { - av_log(ctx, AV_LOG_WARNING, "unknown"); + av_log(ctx, AV_LOG_WARNING, "unknown\n"); return; } @@ -102,7 +102,7 @@ static void dump_stereo3d(AVFilterContext *ctx, AVFrameSideData *sd) av_log(ctx, AV_LOG_INFO, "stereoscopic information: "); if (sd->size < sizeof(*stereo)) { - av_log(ctx, AV_LOG_ERROR, "invalid data"); + av_log(ctx, AV_LOG_ERROR, "invalid data\n"); return; } @@ -114,6 +114,22 @@ static void dump_stereo3d(AVFilterContext *ctx, AVFrameSideData *sd) av_log(ctx, AV_LOG_INFO, " (inverted)"); } +static void dump_s12m_timecode(AVFilterContext *ctx, AVFrameSideData *sd) +{ + const uint32_t *tc = (const uint32_t *)sd->data; + + if ((sd->size != sizeof(uint32_t) * 4) || (tc[0] > 3)) { + av_log(ctx, AV_LOG_ERROR, "invalid data\n"); + return; + } + + for (int j = 1; j <= tc[0]; j++) { + char tcbuf[AV_TIMECODE_STR_SIZE]; + av_timecode_make_smpte_tc_string(tcbuf, tc[j], 0); + av_log(ctx, AV_LOG_INFO, "timecode - %s%s", tcbuf, j != tc[0] ? ", " : ""); + } +} + static void dump_roi(AVFilterContext *ctx, AVFrameSideData *sd) { int nb_rois; @@ -123,7 +139,7 @@ static void dump_roi(AVFilterContext *ctx, AVFrameSideData *sd) roi = (const AVRegionOfInterest *)sd->data; roi_size = roi->self_size; if (!roi_size || sd->size % roi_size != 0) { - av_log(ctx, AV_LOG_ERROR, "Invalid AVRegionOfInterest.self_size."); + av_log(ctx, AV_LOG_ERROR, "Invalid AVRegionOfInterest.self_size.\n"); return; } nb_rois = sd->size / roi_size; @@ -142,7 +158,7 @@ static void dump_mastering_display(AVFilterContext *ctx, AVFrameSideData *sd) av_log(ctx, AV_LOG_INFO, "mastering display: "); if (sd->size < sizeof(*mastering_display)) { - av_log(ctx, AV_LOG_ERROR, "invalid data"); + av_log(ctx, AV_LOG_ERROR, "invalid data\n"); return; } @@ -190,6 +206,33 @@ static void dump_video_enc_params(AVFilterContext *ctx, AVFrameSideData *sd) av_log(ctx, AV_LOG_INFO, "%u blocks; ", par->nb_blocks); } +static void dump_sei_unregistered_metadata(AVFilterContext *ctx, AVFrameSideData *sd) +{ + const int uuid_size = 16; + uint8_t *user_data = sd->data; + int i; + + if (sd->size < uuid_size) { + av_log(ctx, AV_LOG_ERROR, "invalid data(%d < UUID(%d-bytes))\n", sd->size, uuid_size); + return; + } + + av_log(ctx, AV_LOG_INFO, "User Data Unregistered:\n"); + av_log(ctx, AV_LOG_INFO, "UUID="); + for (i = 0; i < uuid_size; i++) { + av_log(ctx, AV_LOG_INFO, "%02x", user_data[i]); + if (i == 3 || i == 5 || i == 7 || i == 9) + av_log(ctx, AV_LOG_INFO, "-"); + } + av_log(ctx, AV_LOG_INFO, "\n"); + + av_log(ctx, AV_LOG_INFO, "User Data="); + for (; i < sd->size; i++) { + av_log(ctx, AV_LOG_INFO, "%02x", user_data[i]); + } + av_log(ctx, AV_LOG_INFO, "\n"); +} + static void dump_color_property(AVFilterContext *ctx, AVFrame *frame) { const char *color_range_str = av_color_range_name(frame->color_range); @@ -337,17 +380,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *frame) dump_stereo3d(ctx, sd); break; case AV_FRAME_DATA_S12M_TIMECODE: { - uint32_t *tc = (uint32_t*)sd->data; - int m = FFMIN(tc[0],3); - if (sd->size != 16) { - av_log(ctx, AV_LOG_ERROR, "invalid data"); - break; - } - for (int j = 1; j <= m; j++) { - char tcbuf[AV_TIMECODE_STR_SIZE]; - av_timecode_make_smpte_tc_string(tcbuf, tc[j], 0); - av_log(ctx, AV_LOG_INFO, "timecode - %s%s", tcbuf, j != m ? ", " : ""); - } + dump_s12m_timecode(ctx, sd); break; } case AV_FRAME_DATA_DISPLAYMATRIX: @@ -375,8 +408,11 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *frame) case AV_FRAME_DATA_VIDEO_ENC_PARAMS: dump_video_enc_params(ctx, sd); break; + case AV_FRAME_DATA_SEI_UNREGISTERED: + dump_sei_unregistered_metadata(ctx, sd); + break; default: - av_log(ctx, AV_LOG_WARNING, "unknown side data type %d (%d bytes)", + av_log(ctx, AV_LOG_WARNING, "unknown side data type %d (%d bytes)\n", sd->type, sd->size); break; } diff --git a/externals/ffmpeg/libavfilter/vf_showpalette.c b/externals/ffmpeg/libavfilter/vf_showpalette.c index 5b0772bc0..f715d6bc2 100755 --- a/externals/ffmpeg/libavfilter/vf_showpalette.c +++ b/externals/ffmpeg/libavfilter/vf_showpalette.c @@ -76,7 +76,7 @@ static int config_output(AVFilterLink *outlink) return 0; } -static int disp_palette(AVFrame *out, const AVFrame *in, int size) +static void disp_palette(AVFrame *out, const AVFrame *in, int size) { int x, y, i, j; uint32_t *dst = (uint32_t *)out->data[0]; @@ -88,12 +88,10 @@ static int disp_palette(AVFrame *out, const AVFrame *in, int size) for (j = 0; j < size; j++) for (i = 0; i < size; i++) dst[(y*dst_linesize + x) * size + j*dst_linesize + i] = pal[y*16 + x]; - return 0; } static int filter_frame(AVFilterLink *inlink, AVFrame *in) { - int ret; AVFrame *out; AVFilterContext *ctx = inlink->dst; const ShowPaletteContext *s = ctx->priv; @@ -105,9 +103,9 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) return AVERROR(ENOMEM); } av_frame_copy_props(out, in); - ret = disp_palette(out, in, s->size); + disp_palette(out, in, s->size); av_frame_free(&in); - return ret < 0 ? ret : ff_filter_frame(outlink, out); + return ff_filter_frame(outlink, out); } static const AVFilterPad showpalette_inputs[] = { diff --git a/externals/ffmpeg/libavfilter/vf_spp.c b/externals/ffmpeg/libavfilter/vf_spp.c index a83b1195c..4bcc6429e 100755 --- a/externals/ffmpeg/libavfilter/vf_spp.c +++ b/externals/ffmpeg/libavfilter/vf_spp.c @@ -44,10 +44,19 @@ enum mode { NB_MODES }; +#if FF_API_CHILD_CLASS_NEXT static const AVClass *child_class_next(const AVClass *prev) { return prev ? NULL : avcodec_dct_get_class(); } +#endif + +static const AVClass *child_class_iterate(void **iter) +{ + const AVClass *c = *iter ? NULL : avcodec_dct_get_class(); + *iter = (void*)(uintptr_t)c; + return c; +} static void *child_next(void *obj, void *prev) { @@ -74,7 +83,10 @@ static const AVClass spp_class = { .option = spp_options, .version = LIBAVUTIL_VERSION_INT, .category = AV_CLASS_CATEGORY_FILTER, +#if FF_API_CHILD_CLASS_NEXT .child_class_next = child_class_next, +#endif + .child_class_iterate = child_class_iterate, .child_next = child_next, }; diff --git a/externals/ffmpeg/libavfilter/vf_subtitles.c b/externals/ffmpeg/libavfilter/vf_subtitles.c index a3b4029af..1bd42391e 100755 --- a/externals/ffmpeg/libavfilter/vf_subtitles.c +++ b/externals/ffmpeg/libavfilter/vf_subtitles.c @@ -478,7 +478,6 @@ static av_cold int init_subtitles(AVFilterContext *ctx) end: av_dict_free(&codec_opts); - avcodec_close(dec_ctx); avcodec_free_context(&dec_ctx); avformat_close_input(&fmt); return ret; diff --git a/externals/ffmpeg/libavfilter/vf_uspp.c b/externals/ffmpeg/libavfilter/vf_uspp.c index da4029f4b..f6fb19343 100755 --- a/externals/ffmpeg/libavfilter/vf_uspp.c +++ b/externals/ffmpeg/libavfilter/vf_uspp.c @@ -468,10 +468,8 @@ static av_cold void uninit(AVFilterContext *ctx) av_freep(&uspp->src[i]); } - for (i = 0; i < (1 << uspp->log2_count); i++) { - avcodec_close(uspp->avctx_enc[i]); - av_freep(&uspp->avctx_enc[i]); - } + for (i = 0; i < (1 << uspp->log2_count); i++) + avcodec_free_context(&uspp->avctx_enc[i]); av_freep(&uspp->non_b_qp_table); av_freep(&uspp->outbuf); diff --git a/externals/ffmpeg/libavfilter/vf_v360.c b/externals/ffmpeg/libavfilter/vf_v360.c index e9457d940..c021724fa 100755 --- a/externals/ffmpeg/libavfilter/vf_v360.c +++ b/externals/ffmpeg/libavfilter/vf_v360.c @@ -81,6 +81,8 @@ static const AVOption v360_options[] = { { "tsp", "truncated square pyramid", 0, AV_OPT_TYPE_CONST, {.i64=TSPYRAMID}, 0, 0, FLAGS, "in" }, { "hequirect", "half equirectangular", 0, AV_OPT_TYPE_CONST, {.i64=HEQUIRECTANGULAR},0, 0, FLAGS, "in" }, { "he", "half equirectangular", 0, AV_OPT_TYPE_CONST, {.i64=HEQUIRECTANGULAR},0, 0, FLAGS, "in" }, + { "equisolid", "equisolid", 0, AV_OPT_TYPE_CONST, {.i64=EQUISOLID}, 0, 0, FLAGS, "in" }, + { "og", "orthographic", 0, AV_OPT_TYPE_CONST, {.i64=ORTHOGRAPHIC}, 0, 0, FLAGS, "in" }, { "output", "set output projection", OFFSET(out), AV_OPT_TYPE_INT, {.i64=CUBEMAP_3_2}, 0, NB_PROJECTIONS-1, FLAGS, "out" }, { "e", "equirectangular", 0, AV_OPT_TYPE_CONST, {.i64=EQUIRECTANGULAR}, 0, 0, FLAGS, "out" }, { "equirect", "equirectangular", 0, AV_OPT_TYPE_CONST, {.i64=EQUIRECTANGULAR}, 0, 0, FLAGS, "out" }, @@ -108,6 +110,8 @@ static const AVOption v360_options[] = { { "tsp", "truncated square pyramid", 0, AV_OPT_TYPE_CONST, {.i64=TSPYRAMID}, 0, 0, FLAGS, "out" }, { "hequirect", "half equirectangular", 0, AV_OPT_TYPE_CONST, {.i64=HEQUIRECTANGULAR},0, 0, FLAGS, "out" }, { "he", "half equirectangular", 0, AV_OPT_TYPE_CONST, {.i64=HEQUIRECTANGULAR},0, 0, FLAGS, "out" }, + { "equisolid", "equisolid", 0, AV_OPT_TYPE_CONST, {.i64=EQUISOLID}, 0, 0, FLAGS, "out" }, + { "og", "orthographic", 0, AV_OPT_TYPE_CONST, {.i64=ORTHOGRAPHIC}, 0, 0, FLAGS, "out" }, { "interp", "set interpolation method", OFFSET(interp), AV_OPT_TYPE_INT, {.i64=BILINEAR}, 0, NB_INTERP_METHODS-1, FLAGS, "interp" }, { "near", "nearest neighbour", 0, AV_OPT_TYPE_CONST, {.i64=NEAREST}, 0, 0, FLAGS, "interp" }, { "nearest", "nearest neighbour", 0, AV_OPT_TYPE_CONST, {.i64=NEAREST}, 0, 0, FLAGS, "interp" }, @@ -1819,6 +1823,217 @@ static int xyz_to_stereographic(const V360Context *s, return visible; } +/** + * Prepare data for processing equisolid output format. + * + * @param ctx filter context + * + * @return error code + */ +static int prepare_equisolid_out(AVFilterContext *ctx) +{ + V360Context *s = ctx->priv; + + s->flat_range[0] = sinf(s->h_fov * M_PI / 720.f); + s->flat_range[1] = sinf(s->v_fov * M_PI / 720.f); + + return 0; +} + +/** + * Calculate 3D coordinates on sphere for corresponding frame position in equisolid format. + * + * @param s filter private context + * @param i horizontal position on frame [0, width) + * @param j vertical position on frame [0, height) + * @param width frame width + * @param height frame height + * @param vec coordinates on sphere + */ +static int equisolid_to_xyz(const V360Context *s, + int i, int j, int width, int height, + float *vec) +{ + const float x = ((2.f * i + 1.f) / width - 1.f) * s->flat_range[0]; + const float y = ((2.f * j + 1.f) / height - 1.f) * s->flat_range[1]; + const float r = hypotf(x, y); + const float theta = asinf(r) * 2.f; + const float sin_theta = sinf(theta); + + vec[0] = x / r * sin_theta; + vec[1] = y / r * sin_theta; + vec[2] = cosf(theta); + + normalize_vector(vec); + + return 1; +} + +/** + * Prepare data for processing equisolid input format. + * + * @param ctx filter context + * + * @return error code + */ +static int prepare_equisolid_in(AVFilterContext *ctx) +{ + V360Context *s = ctx->priv; + + s->iflat_range[0] = sinf(FFMIN(s->ih_fov, 359.f) * M_PI / 720.f); + s->iflat_range[1] = sinf(FFMIN(s->iv_fov, 359.f) * M_PI / 720.f); + + return 0; +} + +/** + * Calculate frame position in equisolid format for corresponding 3D coordinates on sphere. + * + * @param s filter private context + * @param vec coordinates on sphere + * @param width frame width + * @param height frame height + * @param us horizontal coordinates for interpolation window + * @param vs vertical coordinates for interpolation window + * @param du horizontal relative coordinate + * @param dv vertical relative coordinate + */ +static int xyz_to_equisolid(const V360Context *s, + const float *vec, int width, int height, + int16_t us[4][4], int16_t vs[4][4], float *du, float *dv) +{ + const float theta = acosf(vec[2]); + const float r = sinf(theta * 0.5f); + const float c = r / hypotf(vec[0], vec[1]); + const float x = vec[0] * c / s->iflat_range[0] * s->input_mirror_modifier[0]; + const float y = vec[1] * c / s->iflat_range[1] * s->input_mirror_modifier[1]; + + const float uf = (x + 1.f) * width / 2.f; + const float vf = (y + 1.f) * height / 2.f; + + const int ui = floorf(uf); + const int vi = floorf(vf); + + const int visible = isfinite(x) && isfinite(y) && vi >= 0 && vi < height && ui >= 0 && ui < width; + + *du = visible ? uf - ui : 0.f; + *dv = visible ? vf - vi : 0.f; + + for (int i = 0; i < 4; i++) { + for (int j = 0; j < 4; j++) { + us[i][j] = visible ? av_clip(ui + j - 1, 0, width - 1) : 0; + vs[i][j] = visible ? av_clip(vi + i - 1, 0, height - 1) : 0; + } + } + + return visible; +} + +/** + * Prepare data for processing orthographic output format. + * + * @param ctx filter context + * + * @return error code + */ +static int prepare_orthographic_out(AVFilterContext *ctx) +{ + V360Context *s = ctx->priv; + + s->flat_range[0] = sinf(FFMIN(s->h_fov, 180.f) * M_PI / 360.f); + s->flat_range[1] = sinf(FFMIN(s->v_fov, 180.f) * M_PI / 360.f); + + return 0; +} + +/** + * Calculate 3D coordinates on sphere for corresponding frame position in orthographic format. + * + * @param s filter private context + * @param i horizontal position on frame [0, width) + * @param j vertical position on frame [0, height) + * @param width frame width + * @param height frame height + * @param vec coordinates on sphere + */ +static int orthographic_to_xyz(const V360Context *s, + int i, int j, int width, int height, + float *vec) +{ + const float x = ((2.f * i + 1.f) / width - 1.f) * s->flat_range[0]; + const float y = ((2.f * j + 1.f) / height - 1.f) * s->flat_range[1]; + const float r = hypotf(x, y); + const float theta = asinf(r); + + vec[0] = x; + vec[1] = y; + vec[2] = cosf(theta); + + normalize_vector(vec); + + return 1; +} + +/** + * Prepare data for processing orthographic input format. + * + * @param ctx filter context + * + * @return error code + */ +static int prepare_orthographic_in(AVFilterContext *ctx) +{ + V360Context *s = ctx->priv; + + s->iflat_range[0] = sinf(FFMIN(s->ih_fov, 180.f) * M_PI / 360.f); + s->iflat_range[1] = sinf(FFMIN(s->iv_fov, 180.f) * M_PI / 360.f); + + return 0; +} + +/** + * Calculate frame position in orthographic format for corresponding 3D coordinates on sphere. + * + * @param s filter private context + * @param vec coordinates on sphere + * @param width frame width + * @param height frame height + * @param us horizontal coordinates for interpolation window + * @param vs vertical coordinates for interpolation window + * @param du horizontal relative coordinate + * @param dv vertical relative coordinate + */ +static int xyz_to_orthographic(const V360Context *s, + const float *vec, int width, int height, + int16_t us[4][4], int16_t vs[4][4], float *du, float *dv) +{ + const float theta = acosf(vec[2]); + const float r = sinf(theta); + const float c = r / hypotf(vec[0], vec[1]); + const float x = vec[0] * c / s->iflat_range[0] * s->input_mirror_modifier[0]; + const float y = vec[1] * c / s->iflat_range[1] * s->input_mirror_modifier[1]; + + const float uf = (x + 1.f) * width / 2.f; + const float vf = (y + 1.f) * height / 2.f; + + const int ui = floorf(uf); + const int vi = floorf(vf); + + const int visible = vec[2] >= 0.f && isfinite(x) && isfinite(y) && vi >= 0 && vi < height && ui >= 0 && ui < width; + + *du = visible ? uf - ui : 0.f; + *dv = visible ? vf - vi : 0.f; + + for (int i = 0; i < 4; i++) { + for (int j = 0; j < 4; j++) { + us[i][j] = visible ? av_clip(ui + j - 1, 0, width - 1) : 0; + vs[i][j] = visible ? av_clip(vi + i - 1, 0, height - 1) : 0; + } + } + + return visible; +} + /** * Calculate frame position in equirectangular format for corresponding 3D coordinates on sphere. * @@ -3644,6 +3859,29 @@ static int allocate_plane(V360Context *s, int sizeof_uv, int sizeof_ker, int siz static void fov_from_dfov(int format, float d_fov, float w, float h, float *h_fov, float *v_fov) { switch (format) { + case ORTHOGRAPHIC: + { + const float d = 0.5f * hypotf(w, h); + const float l = sinf(d_fov * M_PI / 360.f) / d; + + *h_fov = asinf(w * 0.5 * l) * 360.f / M_PI; + *v_fov = asinf(h * 0.5 * l) * 360.f / M_PI; + + if (d_fov > 180.f) { + *h_fov = 180.f - *h_fov; + *v_fov = 180.f - *v_fov; + } + } + break; + case EQUISOLID: + { + const float d = 0.5f * hypotf(w, h); + const float l = d / (sinf(d_fov * M_PI / 720.f)); + + *h_fov = 2.f * asinf(w * 0.5f / l) * 360.f / M_PI; + *v_fov = 2.f * asinf(h * 0.5f / l) * 360.f / M_PI; + } + break; case STEREOGRAPHIC: { const float d = 0.5f * hypotf(w, h); @@ -4014,6 +4252,18 @@ static int config_output(AVFilterLink *outlink) wf = w * 2.f; hf = h; break; + case EQUISOLID: + s->in_transform = xyz_to_equisolid; + err = prepare_equisolid_in(ctx); + wf = w; + hf = h / 2.f; + break; + case ORTHOGRAPHIC: + s->in_transform = xyz_to_orthographic; + err = prepare_orthographic_in(ctx); + wf = w; + hf = h / 2.f; + break; default: av_log(ctx, AV_LOG_ERROR, "Specified input format is not handled.\n"); return AVERROR_BUG; @@ -4150,6 +4400,18 @@ static int config_output(AVFilterLink *outlink) w = lrintf(wf / 2.f); h = lrintf(hf); break; + case EQUISOLID: + s->out_transform = equisolid_to_xyz; + prepare_out = prepare_equisolid_out; + w = lrintf(wf); + h = lrintf(hf * 2.f); + break; + case ORTHOGRAPHIC: + s->out_transform = orthographic_to_xyz; + prepare_out = prepare_orthographic_out; + w = lrintf(wf); + h = lrintf(hf * 2.f); + break; default: av_log(ctx, AV_LOG_ERROR, "Specified output format is not handled.\n"); return AVERROR_BUG; @@ -4231,8 +4493,11 @@ static int config_output(AVFilterLink *outlink) s->map[1] = s->map[2] = 1; } - for (int i = 0; i < s->nb_allocated; i++) - allocate_plane(s, sizeof_uv, sizeof_ker, sizeof_mask * have_alpha * s->alpha, i); + for (int i = 0; i < s->nb_allocated; i++) { + err = allocate_plane(s, sizeof_uv, sizeof_ker, sizeof_mask * have_alpha * s->alpha, i); + if (err < 0) + return err; + } calculate_rotation_matrix(s->yaw, s->pitch, s->roll, s->rot_mat, s->rotation_order); set_mirror_modifier(s->h_flip, s->v_flip, s->d_flip, s->output_mirror_modifier); diff --git a/externals/ffmpeg/libavfilter/vf_vaguedenoiser.c b/externals/ffmpeg/libavfilter/vf_vaguedenoiser.c index 49b338ff9..b510cdd62 100755 --- a/externals/ffmpeg/libavfilter/vf_vaguedenoiser.c +++ b/externals/ffmpeg/libavfilter/vf_vaguedenoiser.c @@ -71,7 +71,7 @@ static const AVOption vaguedenoiser_options[] = { { "method", "set filtering method", OFFSET(method), AV_OPT_TYPE_INT, {.i64=2 }, 0, 2, FLAGS, "method" }, { "hard", "hard thresholding", 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, FLAGS, "method" }, { "soft", "soft thresholding", 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, FLAGS, "method" }, - { "garrote", "garotte thresholding", 0, AV_OPT_TYPE_CONST, {.i64=2}, 0, 0, FLAGS, "method" }, + { "garrote", "garrote thresholding", 0, AV_OPT_TYPE_CONST, {.i64=2}, 0, 0, FLAGS, "method" }, { "nsteps", "set number of steps", OFFSET(nsteps), AV_OPT_TYPE_INT, {.i64=6 }, 1, 32, FLAGS }, { "percent", "set percent of full denoising", OFFSET(percent),AV_OPT_TYPE_FLOAT, {.dbl=85}, 0,100, FLAGS }, { "planes", "set planes to filter", OFFSET(planes), AV_OPT_TYPE_INT, {.i64=15 }, 0, 15, FLAGS }, diff --git a/externals/ffmpeg/libavfilter/vf_vignette.c b/externals/ffmpeg/libavfilter/vf_vignette.c index 47b59e5ba..ecb04a964 100755 --- a/externals/ffmpeg/libavfilter/vf_vignette.c +++ b/externals/ffmpeg/libavfilter/vf_vignette.c @@ -155,9 +155,6 @@ static double get_natural_factor(const VignetteContext *s, int x, int y) } } -#define TS2D(ts) ((ts) == AV_NOPTS_VALUE ? NAN : (double)(ts)) -#define TS2T(ts, tb) ((ts) == AV_NOPTS_VALUE ? NAN : (double)(ts) * av_q2d(tb)) - static void update_context(VignetteContext *s, AVFilterLink *inlink, AVFrame *frame) { int x, y; diff --git a/externals/ffmpeg/libavfilter/vf_zoompan.c b/externals/ffmpeg/libavfilter/vf_zoompan.c index 59c9b19ec..d9d53decf 100755 --- a/externals/ffmpeg/libavfilter/vf_zoompan.c +++ b/externals/ffmpeg/libavfilter/vf_zoompan.c @@ -38,7 +38,8 @@ static const char *const var_names[] = { "on", "duration", "pduration", - "time", + "in_time", "it", + "out_time", "time", "ot", "frame", "zoom", "pzoom", @@ -61,7 +62,8 @@ enum var_name { VAR_ON, VAR_DURATION, VAR_PDURATION, - VAR_TIME, + VAR_IN_TIME, VAR_IT, + VAR_TIME, VAR_OUT_TIME, VAR_OT, VAR_FRAME, VAR_ZOOM, VAR_PZOOM, @@ -155,6 +157,7 @@ static int output_single_frame(AVFilterContext *ctx, AVFrame *in, double *var_va { ZPContext *s = ctx->priv; AVFilterLink *outlink = ctx->outputs[0]; + AVFilterLink *inlink = ctx->inputs[0]; int64_t pts = s->frame_count; int k, x, y, w, h, ret = 0; uint8_t *input[4]; @@ -165,7 +168,10 @@ static int output_single_frame(AVFilterContext *ctx, AVFrame *in, double *var_va var_values[VAR_PY] = s->y; var_values[VAR_PZOOM] = s->prev_zoom; var_values[VAR_PDURATION] = s->prev_nb_frames; - var_values[VAR_TIME] = pts * av_q2d(outlink->time_base); + var_values[VAR_IN_TIME] = var_values[VAR_IT] = in->pts == AV_NOPTS_VALUE ? + NAN : in->pts * av_q2d(inlink->time_base); + var_values[VAR_OUT_TIME] = pts * av_q2d(outlink->time_base); + var_values[VAR_TIME] = var_values[VAR_OT] = var_values[VAR_OUT_TIME]; var_values[VAR_FRAME] = i; var_values[VAR_ON] = outlink->frame_count_in; diff --git a/externals/ffmpeg/libavformat/Makefile b/externals/ffmpeg/libavformat/Makefile index 0658fa371..26af859a2 100755 --- a/externals/ffmpeg/libavformat/Makefile +++ b/externals/ffmpeg/libavformat/Makefile @@ -303,6 +303,7 @@ OBJS-$(CONFIG_MATROSKA_MUXER) += matroskaenc.o matroska.o \ av1.o avc.o hevc.o \ flacenc_header.o avlanguage.o \ vorbiscomment.o wv.o +OBJS-$(CONFIG_MCC_DEMUXER) += mccdec.o subtitles.o OBJS-$(CONFIG_MD5_MUXER) += hashenc.o OBJS-$(CONFIG_MGSTS_DEMUXER) += mgsts.o OBJS-$(CONFIG_MICRODVD_DEMUXER) += microdvddec.o subtitles.o diff --git a/externals/ffmpeg/libavformat/adtsenc.c b/externals/ffmpeg/libavformat/adtsenc.c index d937e2bea..9e285752e 100755 --- a/externals/ffmpeg/libavformat/adtsenc.c +++ b/externals/ffmpeg/libavformat/adtsenc.c @@ -169,7 +169,7 @@ static int adts_write_packet(AVFormatContext *s, AVPacket *pkt) return 0; if (!par->extradata_size) { uint8_t *side_data; - int side_data_size = 0, ret; + int side_data_size, ret; side_data = av_packet_get_side_data(pkt, AV_PKT_DATA_NEW_EXTRADATA, &side_data_size); diff --git a/externals/ffmpeg/libavformat/allformats.c b/externals/ffmpeg/libavformat/allformats.c index a7c5c9db8..f8527b1fd 100755 --- a/externals/ffmpeg/libavformat/allformats.c +++ b/externals/ffmpeg/libavformat/allformats.c @@ -230,6 +230,7 @@ extern AVInputFormat ff_lvf_demuxer; extern AVInputFormat ff_lxf_demuxer; extern AVInputFormat ff_m4v_demuxer; extern AVOutputFormat ff_m4v_muxer; +extern AVInputFormat ff_mcc_demuxer; extern AVOutputFormat ff_md5_muxer; extern AVInputFormat ff_matroska_demuxer; extern AVOutputFormat ff_matroska_muxer; @@ -487,6 +488,7 @@ extern AVInputFormat ff_image_pbm_pipe_demuxer; extern AVInputFormat ff_image_pcx_pipe_demuxer; extern AVInputFormat ff_image_pgmyuv_pipe_demuxer; extern AVInputFormat ff_image_pgm_pipe_demuxer; +extern AVInputFormat ff_image_pgx_pipe_demuxer; extern AVInputFormat ff_image_pictor_pipe_demuxer; extern AVInputFormat ff_image_png_pipe_demuxer; extern AVInputFormat ff_image_ppm_pipe_demuxer; diff --git a/externals/ffmpeg/libavformat/apm.c b/externals/ffmpeg/libavformat/apm.c index 9d2a856cc..dc59c1656 100755 --- a/externals/ffmpeg/libavformat/apm.c +++ b/externals/ffmpeg/libavformat/apm.c @@ -29,6 +29,7 @@ #define APM_VS12_CHUNK_SIZE 76 #define APM_MAX_READ_SIZE 4096 +#define APM_TAG_CODEC 0x2000 #define APM_TAG_VS12 MKTAG('v', 's', '1', '2') #define APM_TAG_DATA MKTAG('D', 'A', 'T', 'A') @@ -74,6 +75,9 @@ static void apm_parse_vs12(APMVS12Chunk *vs12, const uint8_t *buf) static int apm_probe(const AVProbeData *p) { + if (AV_RL16(p->buf) != APM_TAG_CODEC) + return 0; + if (p->buf_size < 100) return 0; @@ -103,7 +107,7 @@ static int apm_read_header(AVFormatContext *s) if (st->codecpar->bits_per_coded_sample != 4) return AVERROR_INVALIDDATA; - if (st->codecpar->codec_tag != 0x2000) + if (st->codecpar->codec_tag != APM_TAG_CODEC) return AVERROR_INVALIDDATA; /* ff_get_wav_header() does most of the work, but we need to fix a few things. */ diff --git a/externals/ffmpeg/libavformat/apngenc.c b/externals/ffmpeg/libavformat/apngenc.c index 88cd8054d..7ad6a923d 100755 --- a/externals/ffmpeg/libavformat/apngenc.c +++ b/externals/ffmpeg/libavformat/apngenc.c @@ -119,7 +119,7 @@ static int flush_packet(AVFormatContext *format_context, AVPacket *packet) AVIOContext *io_context = format_context->pb; AVStream *codec_stream = format_context->streams[0]; uint8_t *side_data = NULL; - int side_data_size = 0; + int side_data_size; av_assert0(apng->prev_packet); diff --git a/externals/ffmpeg/libavformat/au.c b/externals/ffmpeg/libavformat/au.c index 4afee85a9..f92863e40 100755 --- a/externals/ffmpeg/libavformat/au.c +++ b/externals/ffmpeg/libavformat/au.c @@ -81,7 +81,7 @@ static int au_read_annotation(AVFormatContext *s, int size) AVBPrint bprint; char * key = NULL; char * value = NULL; - int i; + int ret, i; av_bprint_init(&bprint, 64, AV_BPRINT_SIZE_UNLIMITED); @@ -92,7 +92,9 @@ static int au_read_annotation(AVFormatContext *s, int size) if (c == '\0') { state = PARSE_FINISHED; } else if (c == '=') { - av_bprint_finalize(&bprint, &key); + ret = av_bprint_finalize(&bprint, &key); + if (ret < 0) + return ret; av_bprint_init(&bprint, 64, AV_BPRINT_SIZE_UNLIMITED); state = PARSE_VALUE; } else { @@ -143,6 +145,7 @@ static int au_read_header(AVFormatContext *s) int bps, ba = 0; enum AVCodecID codec; AVStream *st; + int ret; tag = avio_rl32(pb); if (tag != MKTAG('.', 's', 'n', 'd')) @@ -161,7 +164,9 @@ static int au_read_header(AVFormatContext *s) if (size > 24) { /* parse annotation field to get metadata */ - au_read_annotation(s, size - 24); + ret = au_read_annotation(s, size - 24); + if (ret < 0) + return ret; } codec = ff_codec_get_id(codec_au_tags, id); diff --git a/externals/ffmpeg/libavformat/av1.c b/externals/ffmpeg/libavformat/av1.c index 1e7a67d2f..0cbffb1fd 100755 --- a/externals/ffmpeg/libavformat/av1.c +++ b/externals/ffmpeg/libavformat/av1.c @@ -363,11 +363,11 @@ int ff_av1_parse_seq_header(AV1SequenceParameters *seq, const uint8_t *buf, int int ff_isom_write_av1c(AVIOContext *pb, const uint8_t *buf, int size) { - AVIOContext *seq_pb = NULL, *meta_pb = NULL; + AVIOContext *meta_pb; AV1SequenceParameters seq_params; PutBitContext pbc; - uint8_t header[4]; - uint8_t *seq, *meta; + uint8_t header[4], *meta; + const uint8_t *seq; int64_t obu_size; int start_pos, type, temporal_id, spatial_id; int ret, nb_seq = 0, seq_size, meta_size; @@ -375,12 +375,9 @@ int ff_isom_write_av1c(AVIOContext *pb, const uint8_t *buf, int size) if (size <= 0) return AVERROR_INVALIDDATA; - ret = avio_open_dyn_buf(&seq_pb); - if (ret < 0) - return ret; ret = avio_open_dyn_buf(&meta_pb); if (ret < 0) - goto fail; + return ret; while (size > 0) { int len = parse_obu_header(buf, size, &obu_size, &start_pos, @@ -401,7 +398,8 @@ int ff_isom_write_av1c(AVIOContext *pb, const uint8_t *buf, int size) if (ret < 0) goto fail; - avio_write(seq_pb, buf, len); + seq = buf; + seq_size = len; break; case AV1_OBU_METADATA: if (!obu_size) { @@ -417,8 +415,7 @@ int ff_isom_write_av1c(AVIOContext *pb, const uint8_t *buf, int size) buf += len; } - seq_size = avio_get_dyn_buf(seq_pb, &seq); - if (!seq_size) { + if (!nb_seq) { ret = AVERROR_INVALIDDATA; goto fail; } @@ -447,7 +444,6 @@ int ff_isom_write_av1c(AVIOContext *pb, const uint8_t *buf, int size) avio_write(pb, meta, meta_size); fail: - ffio_free_dyn_buf(&seq_pb); ffio_free_dyn_buf(&meta_pb); return ret; diff --git a/externals/ffmpeg/libavformat/avc.c b/externals/ffmpeg/libavformat/avc.c index cc452d71a..b5e292138 100755 --- a/externals/ffmpeg/libavformat/avc.c +++ b/externals/ffmpeg/libavformat/avc.c @@ -27,7 +27,7 @@ #include "avc.h" #include "avio_internal.h" -static const uint8_t *ff_avc_find_startcode_internal(const uint8_t *p, const uint8_t *end) +static const uint8_t *avc_find_startcode_internal(const uint8_t *p, const uint8_t *end) { const uint8_t *a = p + 4 - ((intptr_t)p & 3); @@ -65,7 +65,7 @@ static const uint8_t *ff_avc_find_startcode_internal(const uint8_t *p, const uin } const uint8_t *ff_avc_find_startcode(const uint8_t *p, const uint8_t *end){ - const uint8_t *out= ff_avc_find_startcode_internal(p, end); + const uint8_t *out = avc_find_startcode_internal(p, end); if(popaque; } +#if FF_API_CHILD_CLASS_NEXT static const AVClass *ff_avio_child_class_next(const AVClass *prev) { return prev ? NULL : &ffurl_context_class; } +#endif + +static const AVClass *child_class_iterate(void **iter) +{ + const AVClass *c = *iter ? NULL : &ffurl_context_class; + *iter = (void*)(uintptr_t)c; + return c; +} #define OFFSET(x) offsetof(AVIOContext,x) #define E AV_OPT_FLAG_ENCODING_PARAM @@ -67,7 +76,10 @@ const AVClass ff_avio_class = { .version = LIBAVUTIL_VERSION_INT, .option = ff_avio_options, .child_next = ff_avio_child_next, +#if FF_API_CHILD_CLASS_NEXT .child_class_next = ff_avio_child_class_next, +#endif + .child_class_iterate = child_class_iterate, }; static void fill_buffer(AVIOContext *s); @@ -696,7 +708,7 @@ int avio_read_partial(AVIOContext *s, unsigned char *buf, int size) int len; if (size < 0) - return -1; + return AVERROR(EINVAL); if (s->read_packet && s->write_flag) { len = read_packet_wrapper(s, buf, size); @@ -1272,22 +1284,21 @@ typedef struct DynBuffer { static int dyn_buf_write(void *opaque, uint8_t *buf, int buf_size) { DynBuffer *d = opaque; - unsigned new_size, new_allocated_size; + unsigned new_size; /* reallocate buffer if needed */ new_size = (unsigned)d->pos + buf_size; - new_allocated_size = d->allocated_size; - if (new_size < d->pos || new_size > INT_MAX/2) - return -1; - while (new_size > new_allocated_size) { - if (!new_allocated_size) - new_allocated_size = new_size; - else - new_allocated_size += new_allocated_size / 2 + 1; - } - - if (new_allocated_size > d->allocated_size) { + if (new_size < d->pos || new_size > INT_MAX) + return AVERROR(ERANGE); + if (new_size > d->allocated_size) { + unsigned new_allocated_size = d->allocated_size ? d->allocated_size + : new_size; int err; + while (new_size > new_allocated_size) + new_allocated_size += new_allocated_size / 2 + 1; + + new_allocated_size = FFMIN(new_allocated_size, INT_MAX); + if ((err = av_reallocp(&d->buffer, new_allocated_size)) < 0) { d->allocated_size = 0; d->size = 0; @@ -1325,8 +1336,10 @@ static int64_t dyn_buf_seek(void *opaque, int64_t offset, int whence) offset += d->pos; else if (whence == SEEK_END) offset += d->size; - if (offset < 0 || offset > 0x7fffffffLL) - return -1; + if (offset < 0) + return AVERROR(EINVAL); + if (offset > INT_MAX) + return AVERROR(ERANGE); d->pos = offset; return 0; } @@ -1337,7 +1350,7 @@ static int url_open_dyn_buf_internal(AVIOContext **s, int max_packet_size) unsigned io_buffer_size = max_packet_size ? max_packet_size : 1024; if (sizeof(DynBuffer) + io_buffer_size < io_buffer_size) - return -1; + return AVERROR(ERANGE); d = av_mallocz(sizeof(DynBuffer) + io_buffer_size); if (!d) return AVERROR(ENOMEM); @@ -1361,7 +1374,7 @@ int avio_open_dyn_buf(AVIOContext **s) int ffio_open_dyn_packet_buf(AVIOContext **s, int max_packet_size) { if (max_packet_size <= 0) - return -1; + return AVERROR(EINVAL); return url_open_dyn_buf_internal(s, max_packet_size); } diff --git a/externals/ffmpeg/libavformat/dashdec.c b/externals/ffmpeg/libavformat/dashdec.c index ec2aadcee..694782c82 100755 --- a/externals/ffmpeg/libavformat/dashdec.c +++ b/externals/ffmpeg/libavformat/dashdec.c @@ -2001,6 +2001,20 @@ static int open_demux_for_component(AVFormatContext *s, struct representation *p st->id = i; avcodec_parameters_copy(st->codecpar, ist->codecpar); avpriv_set_pts_info(st, ist->pts_wrap_bits, ist->time_base.num, ist->time_base.den); + + // copy disposition + st->disposition = ist->disposition; + + // copy side data + for (int i = 0; i < ist->nb_side_data; i++) { + const AVPacketSideData *sd_src = &ist->side_data[i]; + uint8_t *dst_data; + + dst_data = av_stream_new_side_data(st, sd_src->type, sd_src->size); + if (!dst_data) + return AVERROR(ENOMEM); + memcpy(dst_data, sd_src->data, sd_src->size); + } } return 0; diff --git a/externals/ffmpeg/libavformat/dashenc.c b/externals/ffmpeg/libavformat/dashenc.c index 00a37b175..dc3306a56 100755 --- a/externals/ffmpeg/libavformat/dashenc.c +++ b/externals/ffmpeg/libavformat/dashenc.c @@ -115,6 +115,7 @@ typedef struct OutputStream { int64_t last_dts, last_pts; int last_flags; int bit_rate; + int first_segment_bit_rate; SegmentType segment_type; /* segment type selected for this particular stream */ const char *format_name; const char *extension_name; @@ -171,6 +172,7 @@ typedef struct DASHContext { const char *user_agent; AVDictionary *http_opts; int hls_playlist; + const char *hls_master_name; int http_persistent; int master_playlist_created; AVIOContext *mpd_out; @@ -196,6 +198,7 @@ typedef struct DASHContext { int target_latency_refid; AVRational min_playback_rate; AVRational max_playback_rate; + int64_t update_period; } DASHContext; static struct codec_string { @@ -839,8 +842,12 @@ static int write_adaptation_set(AVFormatContext *s, AVIOContext *out, int as_ind continue; if (os->bit_rate > 0) - snprintf(bandwidth_str, sizeof(bandwidth_str), " bandwidth=\"%d\"", - os->bit_rate); + snprintf(bandwidth_str, sizeof(bandwidth_str), " bandwidth=\"%d\"", os->bit_rate); + else if (final) { + int average_bit_rate = os->pos * 8 * AV_TIME_BASE / c->total_duration; + snprintf(bandwidth_str, sizeof(bandwidth_str), " bandwidth=\"%d\"", average_bit_rate); + } else if (os->first_segment_bit_rate > 0) + snprintf(bandwidth_str, sizeof(bandwidth_str), " bandwidth=\"%d\"", os->first_segment_bit_rate); if (as->media_type == AVMEDIA_TYPE_VIDEO) { avio_printf(out, "\t\t\tuse_template && !c->use_timeline) update_period = 500; + if (c->update_period) + update_period = c->update_period; avio_printf(out, "\tminimumUpdatePeriod=\"PT%"PRId64"S\"\n", update_period); if (!c->ldash) avio_printf(out, "\tsuggestedPresentationDelay=\"PT%"PRId64"S\"\n", c->last_duration / AV_TIME_BASE); @@ -1261,9 +1270,9 @@ static int write_manifest(AVFormatContext *s, int final) return 0; if (*c->dirname) - snprintf(filename_hls, sizeof(filename_hls), "%smaster.m3u8", c->dirname); + snprintf(filename_hls, sizeof(filename_hls), "%s%s", c->dirname, c->hls_master_name); else - snprintf(filename_hls, sizeof(filename_hls), "master.m3u8"); + snprintf(filename_hls, sizeof(filename_hls), "%s", c->hls_master_name); snprintf(temp_filename, sizeof(temp_filename), use_rename ? "%s.tmp" : "%s", filename_hls); @@ -1304,7 +1313,13 @@ static int write_manifest(AVFormatContext *s, int final) OutputStream *os = &c->streams[i]; char *agroup = NULL; char *codec_str_ptr = NULL; - int stream_bitrate = st->codecpar->bit_rate + os->muxer_overhead; + int stream_bitrate = os->muxer_overhead; + if (os->bit_rate > 0) + stream_bitrate += os->bit_rate; + else if (final) + stream_bitrate += os->pos * 8 * AV_TIME_BASE / c->total_duration; + else if (os->first_segment_bit_rate > 0) + stream_bitrate += os->first_segment_bit_rate; if (st->codecpar->codec_type != AVMEDIA_TYPE_VIDEO) continue; if (os->segment_type != SEGMENT_TYPE_MP4) @@ -1957,11 +1972,8 @@ static int dash_flush(AVFormatContext *s, int final, int stream) os->total_pkt_size = 0; os->total_pkt_duration = 0; - if (!os->bit_rate) { - // calculate average bitrate of first segment - int64_t bitrate = (int64_t) range_length * 8 * (c->use_timeline ? os->ctx->streams[0]->time_base.den : AV_TIME_BASE) / duration; - if (bitrate >= 0) - os->bit_rate = bitrate; + if (!os->bit_rate && !os->first_segment_bit_rate) { + os->first_segment_bit_rate = (int64_t) range_length * 8 * AV_TIME_BASE / duration; } add_segment(os, os->filename, os->start_pts, os->max_pts - os->start_pts, os->pos, range_length, index_length, next_exp_index); av_log(s, AV_LOG_VERBOSE, "Representation %d media segment %d written to: %s\n", i, os->segment_index, os->full_path); @@ -2292,7 +2304,7 @@ static int dash_write_trailer(AVFormatContext *s) if (c->hls_playlist && c->master_playlist_created) { char filename[1024]; - snprintf(filename, sizeof(filename), "%smaster.m3u8", c->dirname); + snprintf(filename, sizeof(filename), "%s%s", c->dirname, c->hls_master_name); dashenc_delete_file(s, filename); } } @@ -2349,6 +2361,7 @@ static const AVOption options[] = { { "http_user_agent", "override User-Agent field in HTTP header", OFFSET(user_agent), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, E}, { "http_persistent", "Use persistent HTTP connections", OFFSET(http_persistent), AV_OPT_TYPE_BOOL, {.i64 = 0 }, 0, 1, E }, { "hls_playlist", "Generate HLS playlist files(master.m3u8, media_%d.m3u8)", OFFSET(hls_playlist), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, E }, + { "hls_master_name", "HLS master playlist name", OFFSET(hls_master_name), AV_OPT_TYPE_STRING, {.str = "master.m3u8"}, 0, 0, E }, { "streaming", "Enable/Disable streaming mode of output. Each frame will be moof fragment", OFFSET(streaming), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, E }, { "timeout", "set timeout for socket I/O operations", OFFSET(timeout), AV_OPT_TYPE_DURATION, { .i64 = -1 }, -1, INT_MAX, .flags = E }, { "index_correction", "Enable/Disable segment index correction logic", OFFSET(index_correction), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, E }, @@ -2370,6 +2383,7 @@ static const AVOption options[] = { { "target_latency", "Set desired target latency for Low-latency dash", OFFSET(target_latency), AV_OPT_TYPE_DURATION, { .i64 = 0 }, 0, INT_MAX, E }, { "min_playback_rate", "Set desired minimum playback rate", OFFSET(min_playback_rate), AV_OPT_TYPE_RATIONAL, { .dbl = 1.0 }, 0.5, 1.5, E }, { "max_playback_rate", "Set desired maximum playback rate", OFFSET(max_playback_rate), AV_OPT_TYPE_RATIONAL, { .dbl = 1.0 }, 0.5, 1.5, E }, + { "update_period", "Set the mpd update interval", OFFSET(update_period), AV_OPT_TYPE_INT64, {.i64 = 0}, 0, INT64_MAX, E}, { NULL }, }; diff --git a/externals/ffmpeg/libavformat/dump.c b/externals/ffmpeg/libavformat/dump.c index 06bafc272..aacc0c111 100755 --- a/externals/ffmpeg/libavformat/dump.c +++ b/externals/ffmpeg/libavformat/dump.c @@ -131,10 +131,10 @@ static void print_fps(double d, const char *postfix) av_log(NULL, AV_LOG_INFO, "%1.0fk %s", d / 1000, postfix); } -static void dump_metadata(void *ctx, AVDictionary *m, const char *indent) +static void dump_metadata(void *ctx, const AVDictionary *m, const char *indent) { if (m && !(av_dict_count(m) == 1 && av_dict_get(m, "language", NULL, 0))) { - AVDictionaryEntry *tag = NULL; + const AVDictionaryEntry *tag = NULL; av_log(ctx, AV_LOG_INFO, "%sMetadata:\n", indent); while ((tag = av_dict_get(m, "", tag, AV_DICT_IGNORE_SUFFIX))) @@ -158,7 +158,7 @@ static void dump_metadata(void *ctx, AVDictionary *m, const char *indent) } /* param change side data*/ -static void dump_paramchange(void *ctx, AVPacketSideData *sd) +static void dump_paramchange(void *ctx, const AVPacketSideData *sd) { int size = sd->size; const uint8_t *data = sd->data; @@ -211,7 +211,7 @@ static void dump_paramchange(void *ctx, AVPacketSideData *sd) return; fail: - av_log(ctx, AV_LOG_ERROR, "unknown param"); + av_log(ctx, AV_LOG_ERROR, "unknown param\n"); } /* replaygain side data*/ @@ -235,15 +235,15 @@ static void print_peak(void *ctx, const char *str, uint32_t peak) av_log(ctx, AV_LOG_INFO, ", "); } -static void dump_replaygain(void *ctx, AVPacketSideData *sd) +static void dump_replaygain(void *ctx, const AVPacketSideData *sd) { - AVReplayGain *rg; + const AVReplayGain *rg; if (sd->size < sizeof(*rg)) { - av_log(ctx, AV_LOG_ERROR, "invalid data"); + av_log(ctx, AV_LOG_ERROR, "invalid data\n"); return; } - rg = (AVReplayGain*)sd->data; + rg = (const AVReplayGain *)sd->data; print_gain(ctx, "track gain", rg->track_gain); print_peak(ctx, "track peak", rg->track_peak); @@ -251,16 +251,16 @@ static void dump_replaygain(void *ctx, AVPacketSideData *sd) print_peak(ctx, "album peak", rg->album_peak); } -static void dump_stereo3d(void *ctx, AVPacketSideData *sd) +static void dump_stereo3d(void *ctx, const AVPacketSideData *sd) { - AVStereo3D *stereo; + const AVStereo3D *stereo; if (sd->size < sizeof(*stereo)) { - av_log(ctx, AV_LOG_ERROR, "invalid data"); + av_log(ctx, AV_LOG_ERROR, "invalid data\n"); return; } - stereo = (AVStereo3D *)sd->data; + stereo = (const AVStereo3D *)sd->data; av_log(ctx, AV_LOG_INFO, "%s", av_stereo3d_type_name(stereo->type)); @@ -268,12 +268,12 @@ static void dump_stereo3d(void *ctx, AVPacketSideData *sd) av_log(ctx, AV_LOG_INFO, " (inverted)"); } -static void dump_audioservicetype(void *ctx, AVPacketSideData *sd) +static void dump_audioservicetype(void *ctx, const AVPacketSideData *sd) { - enum AVAudioServiceType *ast = (enum AVAudioServiceType *)sd->data; + const enum AVAudioServiceType *ast = (const enum AVAudioServiceType *)sd->data; if (sd->size < sizeof(*ast)) { - av_log(ctx, AV_LOG_ERROR, "invalid data"); + av_log(ctx, AV_LOG_ERROR, "invalid data\n"); return; } @@ -311,12 +311,12 @@ static void dump_audioservicetype(void *ctx, AVPacketSideData *sd) } } -static void dump_cpb(void *ctx, AVPacketSideData *sd) +static void dump_cpb(void *ctx, const AVPacketSideData *sd) { - AVCPBProperties *cpb = (AVCPBProperties *)sd->data; + const AVCPBProperties *cpb = (const AVCPBProperties *)sd->data; if (sd->size < sizeof(*cpb)) { - av_log(ctx, AV_LOG_ERROR, "invalid data"); + av_log(ctx, AV_LOG_ERROR, "invalid data\n"); return; } @@ -334,8 +334,10 @@ static void dump_cpb(void *ctx, AVPacketSideData *sd) av_log(ctx, AV_LOG_INFO, "vbv_delay: %"PRIu64"", cpb->vbv_delay); } -static void dump_mastering_display_metadata(void *ctx, AVPacketSideData* sd) { - AVMasteringDisplayMetadata* metadata = (AVMasteringDisplayMetadata*)sd->data; +static void dump_mastering_display_metadata(void *ctx, const AVPacketSideData *sd) +{ + const AVMasteringDisplayMetadata *metadata = + (const AVMasteringDisplayMetadata *)sd->data; av_log(ctx, AV_LOG_INFO, "Mastering Display Metadata, " "has_primaries:%d has_luminance:%d " "r(%5.4f,%5.4f) g(%5.4f,%5.4f) b(%5.4f %5.4f) wp(%5.4f, %5.4f) " @@ -351,21 +353,23 @@ static void dump_mastering_display_metadata(void *ctx, AVPacketSideData* sd) { av_q2d(metadata->min_luminance), av_q2d(metadata->max_luminance)); } -static void dump_content_light_metadata(void *ctx, AVPacketSideData* sd) +static void dump_content_light_metadata(void *ctx, const AVPacketSideData *sd) { - AVContentLightMetadata* metadata = (AVContentLightMetadata*)sd->data; + const AVContentLightMetadata *metadata = + (const AVContentLightMetadata *)sd->data; av_log(ctx, AV_LOG_INFO, "Content Light Level Metadata, " "MaxCLL=%d, MaxFALL=%d", metadata->MaxCLL, metadata->MaxFALL); } -static void dump_spherical(void *ctx, AVCodecParameters *par, AVPacketSideData *sd) +static void dump_spherical(void *ctx, const AVCodecParameters *par, + const AVPacketSideData *sd) { - AVSphericalMapping *spherical = (AVSphericalMapping *)sd->data; + const AVSphericalMapping *spherical = (const AVSphericalMapping *)sd->data; double yaw, pitch, roll; if (sd->size < sizeof(*spherical)) { - av_log(ctx, AV_LOG_ERROR, "invalid data"); + av_log(ctx, AV_LOG_ERROR, "invalid data\n"); return; } @@ -388,9 +392,10 @@ static void dump_spherical(void *ctx, AVCodecParameters *par, AVPacketSideData * } } -static void dump_dovi_conf(void *ctx, AVPacketSideData* sd) +static void dump_dovi_conf(void *ctx, const AVPacketSideData *sd) { - AVDOVIDecoderConfigurationRecord *dovi = (AVDOVIDecoderConfigurationRecord *)sd->data; + const AVDOVIDecoderConfigurationRecord *dovi = + (const AVDOVIDecoderConfigurationRecord *)sd->data; av_log(ctx, AV_LOG_INFO, "version: %d.%d, profile: %d, level: %d, " "rpu flag: %d, el flag: %d, bl flag: %d, compatibility id: %d", @@ -402,7 +407,7 @@ static void dump_dovi_conf(void *ctx, AVPacketSideData* sd) dovi->dv_bl_signal_compatibility_id); } -static void dump_sidedata(void *ctx, AVStream *st, const char *indent) +static void dump_sidedata(void *ctx, const AVStream *st, const char *indent) { int i; @@ -410,10 +415,10 @@ static void dump_sidedata(void *ctx, AVStream *st, const char *indent) av_log(ctx, AV_LOG_INFO, "%sSide data:\n", indent); for (i = 0; i < st->nb_side_data; i++) { - AVPacketSideData sd = st->side_data[i]; + const AVPacketSideData *sd = &st->side_data[i]; av_log(ctx, AV_LOG_INFO, "%s ", indent); - switch (sd.type) { + switch (sd->type) { case AV_PKT_DATA_PALETTE: av_log(ctx, AV_LOG_INFO, "palette"); break; @@ -422,55 +427,55 @@ static void dump_sidedata(void *ctx, AVStream *st, const char *indent) break; case AV_PKT_DATA_PARAM_CHANGE: av_log(ctx, AV_LOG_INFO, "paramchange: "); - dump_paramchange(ctx, &sd); + dump_paramchange(ctx, sd); break; case AV_PKT_DATA_H263_MB_INFO: av_log(ctx, AV_LOG_INFO, "H.263 macroblock info"); break; case AV_PKT_DATA_REPLAYGAIN: av_log(ctx, AV_LOG_INFO, "replaygain: "); - dump_replaygain(ctx, &sd); + dump_replaygain(ctx, sd); break; case AV_PKT_DATA_DISPLAYMATRIX: av_log(ctx, AV_LOG_INFO, "displaymatrix: rotation of %.2f degrees", - av_display_rotation_get((int32_t *)sd.data)); + av_display_rotation_get((const int32_t *)sd->data)); break; case AV_PKT_DATA_STEREO3D: av_log(ctx, AV_LOG_INFO, "stereo3d: "); - dump_stereo3d(ctx, &sd); + dump_stereo3d(ctx, sd); break; case AV_PKT_DATA_AUDIO_SERVICE_TYPE: av_log(ctx, AV_LOG_INFO, "audio service type: "); - dump_audioservicetype(ctx, &sd); + dump_audioservicetype(ctx, sd); break; case AV_PKT_DATA_QUALITY_STATS: av_log(ctx, AV_LOG_INFO, "quality factor: %"PRId32", pict_type: %c", - AV_RL32(sd.data), av_get_picture_type_char(sd.data[4])); + AV_RL32(sd->data), av_get_picture_type_char(sd->data[4])); break; case AV_PKT_DATA_CPB_PROPERTIES: av_log(ctx, AV_LOG_INFO, "cpb: "); - dump_cpb(ctx, &sd); + dump_cpb(ctx, sd); break; case AV_PKT_DATA_MASTERING_DISPLAY_METADATA: - dump_mastering_display_metadata(ctx, &sd); + dump_mastering_display_metadata(ctx, sd); break; case AV_PKT_DATA_SPHERICAL: av_log(ctx, AV_LOG_INFO, "spherical: "); - dump_spherical(ctx, st->codecpar, &sd); + dump_spherical(ctx, st->codecpar, sd); break; case AV_PKT_DATA_CONTENT_LIGHT_LEVEL: - dump_content_light_metadata(ctx, &sd); + dump_content_light_metadata(ctx, sd); break; case AV_PKT_DATA_ICC_PROFILE: av_log(ctx, AV_LOG_INFO, "ICC Profile"); break; case AV_PKT_DATA_DOVI_CONF: av_log(ctx, AV_LOG_INFO, "DOVI configuration record: "); - dump_dovi_conf(ctx, &sd); + dump_dovi_conf(ctx, sd); break; default: av_log(ctx, AV_LOG_INFO, - "unknown side data type %d (%d bytes)", sd.type, sd.size); + "unknown side data type %d (%d bytes)", sd->type, sd->size); break; } @@ -479,14 +484,14 @@ static void dump_sidedata(void *ctx, AVStream *st, const char *indent) } /* "user interface" functions */ -static void dump_stream_format(AVFormatContext *ic, int i, +static void dump_stream_format(const AVFormatContext *ic, int i, int index, int is_output) { char buf[256]; int flags = (is_output ? ic->oformat->flags : ic->iformat->flags); - AVStream *st = ic->streams[i]; - AVDictionaryEntry *lang = av_dict_get(st->metadata, "language", NULL, 0); - char *separator = ic->dump_separator; + const AVStream *st = ic->streams[i]; + const AVDictionaryEntry *lang = av_dict_get(st->metadata, "language", NULL, 0); + const char *separator = ic->dump_separator; AVCodecContext *avctx; int ret; @@ -500,6 +505,8 @@ static void dump_stream_format(AVFormatContext *ic, int i, return; } +#if FF_API_LAVF_AVCTX +FF_DISABLE_DEPRECATION_WARNINGS // Fields which are missing from AVCodecParameters need to be taken from the AVCodecContext avctx->properties = st->codec->properties; avctx->codec = st->codec->codec; @@ -507,6 +514,8 @@ static void dump_stream_format(AVFormatContext *ic, int i, avctx->qmax = st->codec->qmax; avctx->coded_width = st->codec->coded_width; avctx->coded_height = st->codec->coded_height; +FF_ENABLE_DEPRECATION_WARNINGS +#endif if (separator) av_opt_set(avctx, "dump_separator", separator, 0); @@ -541,7 +550,13 @@ static void dump_stream_format(AVFormatContext *ic, int i, int fps = st->avg_frame_rate.den && st->avg_frame_rate.num; int tbr = st->r_frame_rate.den && st->r_frame_rate.num; int tbn = st->time_base.den && st->time_base.num; +#if FF_API_LAVF_AVCTX +FF_DISABLE_DEPRECATION_WARNINGS int tbc = st->codec->time_base.den && st->codec->time_base.num; +FF_ENABLE_DEPRECATION_WARNINGS +#else + int tbc = 0; +#endif if (fps || tbr || tbn || tbc) av_log(NULL, AV_LOG_INFO, "%s", separator); @@ -552,8 +567,12 @@ static void dump_stream_format(AVFormatContext *ic, int i, print_fps(av_q2d(st->r_frame_rate), tbn || tbc ? "tbr, " : "tbr"); if (tbn) print_fps(1 / av_q2d(st->time_base), tbc ? "tbn, " : "tbn"); +#if FF_API_LAVF_AVCTX +FF_DISABLE_DEPRECATION_WARNINGS if (tbc) print_fps(1 / av_q2d(st->codec->time_base), "tbc"); +FF_ENABLE_DEPRECATION_WARNINGS +#endif } if (st->disposition & AV_DISPOSITION_DEFAULT) @@ -647,7 +666,7 @@ void av_dump_format(AVFormatContext *ic, int index, } for (i = 0; i < ic->nb_chapters; i++) { - AVChapter *ch = ic->chapters[i]; + const AVChapter *ch = ic->chapters[i]; av_log(NULL, AV_LOG_INFO, " Chapter #%d:%d: ", index, i); av_log(NULL, AV_LOG_INFO, "start %f, ", ch->start * av_q2d(ch->time_base)); @@ -660,17 +679,18 @@ void av_dump_format(AVFormatContext *ic, int index, if (ic->nb_programs) { int j, k, total = 0; for (j = 0; j < ic->nb_programs; j++) { - AVDictionaryEntry *name = av_dict_get(ic->programs[j]->metadata, - "name", NULL, 0); - av_log(NULL, AV_LOG_INFO, " Program %d %s\n", ic->programs[j]->id, + const AVProgram *program = ic->programs[j]; + const AVDictionaryEntry *name = av_dict_get(program->metadata, + "name", NULL, 0); + av_log(NULL, AV_LOG_INFO, " Program %d %s\n", program->id, name ? name->value : ""); - dump_metadata(NULL, ic->programs[j]->metadata, " "); - for (k = 0; k < ic->programs[j]->nb_stream_indexes; k++) { - dump_stream_format(ic, ic->programs[j]->stream_index[k], + dump_metadata(NULL, program->metadata, " "); + for (k = 0; k < program->nb_stream_indexes; k++) { + dump_stream_format(ic, program->stream_index[k], index, is_output); - printed[ic->programs[j]->stream_index[k]] = 1; + printed[program->stream_index[k]] = 1; } - total += ic->programs[j]->nb_stream_indexes; + total += program->nb_stream_indexes; } if (total < ic->nb_streams) av_log(NULL, AV_LOG_INFO, " No Program\n"); diff --git a/externals/ffmpeg/libavformat/dvenc.c b/externals/ffmpeg/libavformat/dvenc.c index c71e53277..b04d6044d 100755 --- a/externals/ffmpeg/libavformat/dvenc.c +++ b/externals/ffmpeg/libavformat/dvenc.c @@ -406,9 +406,10 @@ static int dv_write_packet(struct AVFormatContext *s, AVPacket *pkt) fsize = dv_assemble_frame(s, s->priv_data, s->streams[pkt->stream_index], pkt->data, pkt->size, &frame); - if (fsize > 0) { - avio_write(s->pb, frame, fsize); + if (fsize < 0) { + return fsize; } + avio_write(s->pb, frame, fsize); return 0; } diff --git a/externals/ffmpeg/libavformat/fifo.c b/externals/ffmpeg/libavformat/fifo.c index d11dc6626..17748e94c 100755 --- a/externals/ffmpeg/libavformat/fifo.c +++ b/externals/ffmpeg/libavformat/fifo.c @@ -19,6 +19,8 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include + #include "libavutil/avassert.h" #include "libavutil/opt.h" #include "libavutil/time.h" @@ -77,6 +79,9 @@ typedef struct FifoContext { /* Value > 0 signals queue overflow */ volatile uint8_t overflow_flag; + atomic_int_least64_t queue_duration; + int64_t last_sent_dts; + int64_t timeshift; } FifoContext; typedef struct FifoThreadContext { @@ -98,9 +103,12 @@ typedef struct FifoThreadContext { * so finalization by calling write_trailer and ff_io_close must be done * before exiting / reinitialization of underlying muxer */ uint8_t header_written; + + int64_t last_received_dts; } FifoThreadContext; typedef enum FifoMessageType { + FIFO_NOOP, FIFO_WRITE_HEADER, FIFO_WRITE_PACKET, FIFO_FLUSH_OUTPUT @@ -159,6 +167,15 @@ static int fifo_thread_flush_output(FifoThreadContext *ctx) return av_write_frame(avf2, NULL); } +static int64_t next_duration(AVFormatContext *avf, AVPacket *pkt, int64_t *last_dts) +{ + AVStream *st = avf->streams[pkt->stream_index]; + int64_t dts = av_rescale_q(pkt->dts, st->time_base, AV_TIME_BASE_Q); + int64_t duration = (*last_dts == AV_NOPTS_VALUE ? 0 : dts - *last_dts); + *last_dts = dts; + return duration; +} + static int fifo_thread_write_packet(FifoThreadContext *ctx, AVPacket *pkt) { AVFormatContext *avf = ctx->avf; @@ -167,6 +184,9 @@ static int fifo_thread_write_packet(FifoThreadContext *ctx, AVPacket *pkt) AVRational src_tb, dst_tb; int ret, s_idx; + if (fifo->timeshift && pkt->dts != AV_NOPTS_VALUE) + atomic_fetch_sub_explicit(&fifo->queue_duration, next_duration(avf, pkt, &ctx->last_received_dts), memory_order_relaxed); + if (ctx->drop_until_keyframe) { if (pkt->flags & AV_PKT_FLAG_KEY) { ctx->drop_until_keyframe = 0; @@ -209,6 +229,9 @@ static int fifo_thread_dispatch_message(FifoThreadContext *ctx, FifoMessage *msg { int ret = AVERROR(EINVAL); + if (msg->type == FIFO_NOOP) + return 0; + if (!ctx->header_written) { ret = fifo_thread_write_header(ctx); if (ret < 0) @@ -390,12 +413,13 @@ static void *fifo_consumer_thread(void *data) AVFormatContext *avf = data; FifoContext *fifo = avf->priv_data; AVThreadMessageQueue *queue = fifo->queue; - FifoMessage msg = {FIFO_WRITE_HEADER, {0}}; + FifoMessage msg = {fifo->timeshift ? FIFO_NOOP : FIFO_WRITE_HEADER, {0}}; int ret; FifoThreadContext fifo_thread_ctx; memset(&fifo_thread_ctx, 0, sizeof(FifoThreadContext)); fifo_thread_ctx.avf = avf; + fifo_thread_ctx.last_received_dts = AV_NOPTS_VALUE; while (1) { uint8_t just_flushed = 0; @@ -429,6 +453,10 @@ static void *fifo_consumer_thread(void *data) if (just_flushed) av_log(avf, AV_LOG_INFO, "FIFO queue flushed\n"); + if (fifo->timeshift) + while (atomic_load_explicit(&fifo->queue_duration, memory_order_relaxed) < fifo->timeshift) + av_usleep(10000); + ret = av_thread_message_queue_recv(queue, &msg, 0); if (ret < 0) { av_thread_message_queue_set_err_send(queue, ret); @@ -488,6 +516,8 @@ static int fifo_init(AVFormatContext *avf) " only when drop_pkts_on_overflow is also turned on\n"); return AVERROR(EINVAL); } + atomic_init(&fifo->queue_duration, 0); + fifo->last_sent_dts = AV_NOPTS_VALUE; oformat = av_guess_format(fifo->format, avf->url, NULL); if (!oformat) { @@ -563,6 +593,9 @@ static int fifo_write_packet(AVFormatContext *avf, AVPacket *pkt) goto fail; } + if (fifo->timeshift && pkt->dts != AV_NOPTS_VALUE) + atomic_fetch_add_explicit(&fifo->queue_duration, next_duration(avf, pkt, &fifo->last_sent_dts), memory_order_relaxed); + return ret; fail: if (pkt) @@ -576,6 +609,27 @@ static int fifo_write_trailer(AVFormatContext *avf) int ret; av_thread_message_queue_set_err_recv(fifo->queue, AVERROR_EOF); + if (fifo->timeshift) { + int64_t now = av_gettime_relative(); + int64_t elapsed = 0; + FifoMessage msg = {FIFO_NOOP}; + do { + int64_t delay = av_gettime_relative() - now; + if (delay < 0) { // Discontinuity? + delay = 10000; + now = av_gettime_relative(); + } else { + now += delay; + } + atomic_fetch_add_explicit(&fifo->queue_duration, delay, memory_order_relaxed); + elapsed += delay; + if (elapsed > fifo->timeshift) + break; + av_usleep(10000); + ret = av_thread_message_queue_send(fifo->queue, &msg, AV_THREAD_MESSAGE_NONBLOCK); + } while (ret >= 0 || ret == AVERROR(EAGAIN)); + atomic_store(&fifo->queue_duration, INT64_MAX); + } ret = pthread_join(fifo->writer_thread, NULL); if (ret < 0) { @@ -630,6 +684,9 @@ static const AVOption options[] = { {"recover_any_error", "Attempt recovery regardless of type of the error", OFFSET(recover_any_error), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, AV_OPT_FLAG_ENCODING_PARAM}, + {"timeshift", "Delay fifo output", OFFSET(timeshift), + AV_OPT_TYPE_DURATION, {.i64 = 0}, 0, INT64_MAX, AV_OPT_FLAG_ENCODING_PARAM}, + {NULL}, }; diff --git a/externals/ffmpeg/libavformat/flvdec.c b/externals/ffmpeg/libavformat/flvdec.c index 957acedf3..08622739f 100755 --- a/externals/ffmpeg/libavformat/flvdec.c +++ b/externals/ffmpeg/libavformat/flvdec.c @@ -514,8 +514,7 @@ static int amf_parse_object(AVFormatContext *s, AVStream *astream, if (key && (ioc->seekable & AVIO_SEEKABLE_NORMAL) && !strcmp(KEYFRAMES_TAG, key) && depth == 1) - if (parse_keyframes_index(s, ioc, - max_pos) < 0) + if (parse_keyframes_index(s, ioc, max_pos) < 0) av_log(s, AV_LOG_ERROR, "Keyframe index parsing failed\n"); else add_keyframes_index(s); @@ -732,8 +731,7 @@ static int flv_read_metabody(AVFormatContext *s, int64_t next_pos) astream = stream; if (flv->last_keyframe_stream_index == -1) flv->last_keyframe_stream_index = i; - } - else if (stream->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE) + } else if (stream->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE) dstream = stream; } @@ -1058,8 +1056,7 @@ retry: if (type == 0 && dts == 0 || type < 0) { if (type < 0 && flv->validate_count && flv->validate_index[0].pos > next && - flv->validate_index[0].pos - 4 < next - ) { + flv->validate_index[0].pos - 4 < next) { av_log(s, AV_LOG_WARNING, "Adjusting next position due to index mismatch\n"); next = flv->validate_index[0].pos - 4; } @@ -1120,7 +1117,6 @@ skip: st = create_stream(s, stream_types[stream_type]); if (!st) return AVERROR(ENOMEM); - } av_log(s, AV_LOG_TRACE, "%d %X %d \n", stream_type, flags, st->discard); @@ -1133,10 +1129,9 @@ skip: stream_type == FLV_STREAM_TYPE_AUDIO)) av_add_index_entry(st, pos, dts, size, 0, AVINDEX_KEYFRAME); - if ( (st->discard >= AVDISCARD_NONKEY && !((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_KEY || (stream_type == FLV_STREAM_TYPE_AUDIO))) - ||(st->discard >= AVDISCARD_BIDIR && ((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_DISP_INTER && (stream_type == FLV_STREAM_TYPE_VIDEO))) - || st->discard >= AVDISCARD_ALL - ) { + if ((st->discard >= AVDISCARD_NONKEY && !((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_KEY || stream_type == FLV_STREAM_TYPE_AUDIO)) || + (st->discard >= AVDISCARD_BIDIR && ((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_DISP_INTER && stream_type == FLV_STREAM_TYPE_VIDEO)) || + st->discard >= AVDISCARD_ALL) { avio_seek(s->pb, next, SEEK_SET); ret = FFERROR_REDO; goto leave; @@ -1299,10 +1294,10 @@ retry_duration: ff_add_param_change(pkt, channels, 0, sample_rate, 0, 0); } - if ( stream_type == FLV_STREAM_TYPE_AUDIO || - ((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_KEY) || - stream_type == FLV_STREAM_TYPE_SUBTITLE || - stream_type == FLV_STREAM_TYPE_DATA) + if (stream_type == FLV_STREAM_TYPE_AUDIO || + (flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_KEY || + stream_type == FLV_STREAM_TYPE_SUBTITLE || + stream_type == FLV_STREAM_TYPE_DATA) pkt->flags |= AV_PKT_FLAG_KEY; leave: diff --git a/externals/ffmpeg/libavformat/flvenc.c b/externals/ffmpeg/libavformat/flvenc.c index 5cf3ce8a1..1cfcdc639 100755 --- a/externals/ffmpeg/libavformat/flvenc.c +++ b/externals/ffmpeg/libavformat/flvenc.c @@ -902,7 +902,7 @@ static int flv_write_packet(AVFormatContext *s, AVPacket *pkt) if (par->codec_id == AV_CODEC_ID_AAC || par->codec_id == AV_CODEC_ID_H264 || par->codec_id == AV_CODEC_ID_MPEG4) { - int side_size = 0; + int side_size; uint8_t *side = av_packet_get_side_data(pkt, AV_PKT_DATA_NEW_EXTRADATA, &side_size); if (side && side_size > 0 && (side_size != par->extradata_size || memcmp(side, par->extradata, side_size))) { ret = ff_alloc_extradata(par, side_size); diff --git a/externals/ffmpeg/libavformat/gifdec.c b/externals/ffmpeg/libavformat/gifdec.c index a31644c2a..d617de5f4 100755 --- a/externals/ffmpeg/libavformat/gifdec.c +++ b/externals/ffmpeg/libavformat/gifdec.c @@ -144,7 +144,7 @@ static int gif_read_header(AVFormatContext *s) AVBPrint bp; int block_size; - av_bprint_init(&bp, 0, -1); + av_bprint_init(&bp, 0, AV_BPRINT_SIZE_UNLIMITED); while ((block_size = avio_r8(pb)) != 0) { avio_read_to_bprint(pb, &bp, block_size); } diff --git a/externals/ffmpeg/libavformat/hevc.c b/externals/ffmpeg/libavformat/hevc.c index f621cb2f1..94eb3a9cb 100755 --- a/externals/ffmpeg/libavformat/hevc.c +++ b/externals/ffmpeg/libavformat/hevc.c @@ -1068,29 +1068,27 @@ int ff_hevc_annexb2mp4_buf(const uint8_t *buf_in, uint8_t **buf_out, int ff_isom_write_hvcc(AVIOContext *pb, const uint8_t *data, int size, int ps_array_completeness) { - int ret = 0; - uint8_t *buf, *end, *start = NULL; HEVCDecoderConfigurationRecord hvcc; - - hvcc_init(&hvcc); + uint8_t *buf, *end, *start; + int ret; if (size < 6) { /* We can't write a valid hvcC from the provided data */ - ret = AVERROR_INVALIDDATA; - goto end; + return AVERROR_INVALIDDATA; } else if (*data == 1) { /* Data is already hvcC-formatted */ avio_write(pb, data, size); - goto end; + return 0; } else if (!(AV_RB24(data) == 1 || AV_RB32(data) == 1)) { /* Not a valid Annex B start code prefix */ - ret = AVERROR_INVALIDDATA; - goto end; + return AVERROR_INVALIDDATA; } ret = ff_avc_parse_nal_units_buf(data, &start, &size); if (ret < 0) - goto end; + return ret; + + hvcc_init(&hvcc); buf = start; end = start + size; diff --git a/externals/ffmpeg/libavformat/hls.c b/externals/ffmpeg/libavformat/hls.c index 3c7e197ce..ba17c4ed9 100755 --- a/externals/ffmpeg/libavformat/hls.c +++ b/externals/ffmpeg/libavformat/hls.c @@ -1768,6 +1768,20 @@ static int set_stream_info_from_input_stream(AVStream *st, struct playlist *pls, else avpriv_set_pts_info(st, ist->pts_wrap_bits, ist->time_base.num, ist->time_base.den); + // copy disposition + st->disposition = ist->disposition; + + // copy side data + for (int i = 0; i < ist->nb_side_data; i++) { + const AVPacketSideData *sd_src = &ist->side_data[i]; + uint8_t *dst_data; + + dst_data = av_stream_new_side_data(st, sd_src->type, sd_src->size); + if (!dst_data) + return AVERROR(ENOMEM); + memcpy(dst_data, sd_src->data, sd_src->size); + } + st->internal->need_context_update = 1; return 0; diff --git a/externals/ffmpeg/libavformat/hlsenc.c b/externals/ffmpeg/libavformat/hlsenc.c index 71fa3db06..df84e6487 100755 --- a/externals/ffmpeg/libavformat/hlsenc.c +++ b/externals/ffmpeg/libavformat/hlsenc.c @@ -365,11 +365,11 @@ fail: static int replace_str_data_in_filename(char **s, const char *filename, char placeholder, const char *datastring) { const char *p; - char *new_filename; char c; int addchar_count; int found_count = 0; AVBPrint buf; + int ret; av_bprint_init(&buf, 0, AV_BPRINT_SIZE_UNLIMITED); @@ -395,22 +395,21 @@ static int replace_str_data_in_filename(char **s, const char *filename, char pla } if (!av_bprint_is_complete(&buf)) { av_bprint_finalize(&buf, NULL); - return -1; + return AVERROR(ENOMEM); } - if (av_bprint_finalize(&buf, &new_filename) < 0 || !new_filename) - return -1; - *s = new_filename; + if ((ret = av_bprint_finalize(&buf, s)) < 0) + return ret; return found_count; } static int replace_int_data_in_filename(char **s, const char *filename, char placeholder, int64_t number) { const char *p; - char *new_filename; char c; int nd, addchar_count; int found_count = 0; AVBPrint buf; + int ret; av_bprint_init(&buf, 0, AV_BPRINT_SIZE_UNLIMITED); @@ -444,11 +443,10 @@ static int replace_int_data_in_filename(char **s, const char *filename, char pla } if (!av_bprint_is_complete(&buf)) { av_bprint_finalize(&buf, NULL); - return -1; + return AVERROR(ENOMEM); } - if (av_bprint_finalize(&buf, &new_filename) < 0 || !new_filename) - return -1; - *s = new_filename; + if ((ret = av_bprint_finalize(&buf, s)) < 0) + return ret; return found_count; } @@ -2392,7 +2390,7 @@ static int hls_write_packet(AVFormatContext *s, AVPacket *pkt) && (hls->flags & HLS_TEMP_FILE); } - if ((hls->max_seg_size > 0 && (vs->size >= hls->max_seg_size)) || !byterange_mode) { + if ((hls->max_seg_size > 0 && (vs->size + vs->start_pos >= hls->max_seg_size)) || !byterange_mode) { AVDictionary *options = NULL; char *filename = NULL; if (hls->key_info_file || hls->encrypt) { @@ -2487,14 +2485,15 @@ static int hls_write_packet(AVFormatContext *s, AVPacket *pkt) if (hls->flags & HLS_SINGLE_FILE) { vs->start_pos += vs->size; } else if (hls->max_seg_size > 0) { - vs->start_pos = new_start_pos; - if (vs->size >= hls->max_seg_size) { + if (vs->size + vs->start_pos >= hls->max_seg_size) { vs->sequence++; sls_flag_file_rename(hls, vs, old_filename); ret = hls_start(s, vs); vs->start_pos = 0; /* When split segment by byte, the duration is short than hls_time, * so it is not enough one segment duration as hls_time, */ + } else { + vs->start_pos = new_start_pos; } } else { vs->start_pos = new_start_pos; @@ -2631,7 +2630,6 @@ static int hls_write_trailer(struct AVFormatContext *s) goto failed; vs->size = range_length; - hlsenc_io_close(s, &vs->out, filename); ret = hlsenc_io_close(s, &vs->out, filename); if (ret < 0) { av_log(s, AV_LOG_WARNING, "upload segment failed, will retry with a new http session.\n"); diff --git a/externals/ffmpeg/libavformat/icecast.c b/externals/ffmpeg/libavformat/icecast.c index 38af16b99..b06c53cab 100755 --- a/externals/ffmpeg/libavformat/icecast.c +++ b/externals/ffmpeg/libavformat/icecast.c @@ -43,6 +43,7 @@ typedef struct IcecastContext { int public; char *url; char *user_agent; + int tls; } IcecastContext; #define DEFAULT_ICE_USER "source" @@ -62,6 +63,7 @@ static const AVOption options[] = { { "password", "set password", OFFSET(pass), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, E }, { "content_type", "set content-type, MUST be set if not audio/mpeg", OFFSET(content_type), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, E }, { "legacy_icecast", "use legacy SOURCE method, for Icecast < v2.4", OFFSET(legacy_icecast), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, E }, + { "tls", "use a TLS connection", OFFSET(tls), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, E }, { NULL } }; @@ -162,7 +164,9 @@ static int icecast_open(URLContext *h, const char *uri, int flags) } // Build new URI for passing to http protocol - ff_url_join(h_url, sizeof(h_url), "http", auth, host, port, "%s", path); + ff_url_join(h_url, sizeof(h_url), + s->tls ? "https" : "http", + auth, host, port, "%s", path); // Finally open http proto handler ret = ffurl_open_whitelist(&s->hd, h_url, AVIO_FLAG_READ_WRITE, NULL, &opt_dict, h->protocol_whitelist, h->protocol_blacklist, h); diff --git a/externals/ffmpeg/libavformat/img2dec.c b/externals/ffmpeg/libavformat/img2dec.c index ee7ceed08..a7e89cd05 100755 --- a/externals/ffmpeg/libavformat/img2dec.c +++ b/externals/ffmpeg/libavformat/img2dec.c @@ -1000,6 +1000,14 @@ static int pgmyuv_probe(const AVProbeData *p) // custom FFmpeg format recognized return ret && av_match_ext(p->filename, "pgmyuv") ? ret : 0; } +static int pgx_probe(const AVProbeData *p) +{ + const uint8_t *b = p->buf; + if (!memcmp(b, "PG ML ", 6)) + return AVPROBE_SCORE_EXTENSION + 1; + return 0; +} + static int ppm_probe(const AVProbeData *p) { return pnm_magic_check(p, 3) || pnm_magic_check(p, 6) ? pnm_probe(p) : 0; @@ -1094,6 +1102,7 @@ IMAGEAUTO_DEMUXER(pbm, AV_CODEC_ID_PBM) IMAGEAUTO_DEMUXER(pcx, AV_CODEC_ID_PCX) IMAGEAUTO_DEMUXER(pgm, AV_CODEC_ID_PGM) IMAGEAUTO_DEMUXER(pgmyuv, AV_CODEC_ID_PGMYUV) +IMAGEAUTO_DEMUXER(pgx, AV_CODEC_ID_PGX) IMAGEAUTO_DEMUXER(pictor, AV_CODEC_ID_PICTOR) IMAGEAUTO_DEMUXER(png, AV_CODEC_ID_PNG) IMAGEAUTO_DEMUXER(ppm, AV_CODEC_ID_PPM) diff --git a/externals/ffmpeg/libavformat/isom.c b/externals/ffmpeg/libavformat/isom.c index 44c7b1303..209bbac5d 100755 --- a/externals/ffmpeg/libavformat/isom.c +++ b/externals/ffmpeg/libavformat/isom.c @@ -395,25 +395,145 @@ const AVCodecTag ff_codec_movdata_tags[] = { /* http://developer.apple.com/documentation/mac/Text/Text-368.html */ /* deprecated by putting the code as 3*5 bits ASCII */ static const char mov_mdhd_language_map[][4] = { - /* 0-9 */ - "eng", "fra", "ger", "ita", "dut", "sve", "spa", "dan", "por", "nor", - "heb", "jpn", "ara", "fin", "gre", "ice", "mlt", "tur", "hr "/*scr*/, "chi"/*ace?*/, - "urd", "hin", "tha", "kor", "lit", "pol", "hun", "est", "lav", "", - "fo ", "", "rus", "chi", "", "iri", "alb", "ron", "ces", "slk", - "slv", "yid", "sr ", "mac", "bul", "ukr", "bel", "uzb", "kaz", "aze", - /*?*/ - "aze", "arm", "geo", "mol", "kir", "tgk", "tuk", "mon", "", "pus", - "kur", "kas", "snd", "tib", "nep", "san", "mar", "ben", "asm", "guj", - "pa ", "ori", "mal", "kan", "tam", "tel", "", "bur", "khm", "lao", - /* roman? arabic? */ - "vie", "ind", "tgl", "may", "may", "amh", "tir", "orm", "som", "swa", - /*==rundi?*/ - "", "run", "", "mlg", "epo", "", "", "", "", "", - /* 100 */ - "", "", "", "", "", "", "", "", "", "", - "", "", "", "", "", "", "", "", "", "", - "", "", "", "", "", "", "", "", "wel", "baq", - "cat", "lat", "que", "grn", "aym", "tat", "uig", "dzo", "jav" + "eng", /* 0 English */ + "fra", /* 1 French */ + "ger", /* 2 German */ + "ita", /* 3 Italian */ + "dut", /* 4 Dutch */ + "sve", /* 5 Swedish */ + "spa", /* 6 Spanish */ + "dan", /* 7 Danish */ + "por", /* 8 Portuguese */ + "nor", /* 9 Norwegian */ + "heb", /* 10 Hebrew */ + "jpn", /* 11 Japanese */ + "ara", /* 12 Arabic */ + "fin", /* 13 Finnish */ + "gre", /* 14 Greek */ + "ice", /* 15 Icelandic */ + "mlt", /* 16 Maltese */ + "tur", /* 17 Turkish */ + "hr ", /* 18 Croatian */ + "chi", /* 19 Traditional Chinese */ + "urd", /* 20 Urdu */ + "hin", /* 21 Hindi */ + "tha", /* 22 Thai */ + "kor", /* 23 Korean */ + "lit", /* 24 Lithuanian */ + "pol", /* 25 Polish */ + "hun", /* 26 Hungarian */ + "est", /* 27 Estonian */ + "lav", /* 28 Latvian */ + "", /* 29 Sami */ + "fo ", /* 30 Faroese */ + "", /* 31 Farsi */ + "rus", /* 32 Russian */ + "chi", /* 33 Simplified Chinese */ + "", /* 34 Flemish */ + "iri", /* 35 Irish */ + "alb", /* 36 Albanian */ + "ron", /* 37 Romanian */ + "ces", /* 38 Czech */ + "slk", /* 39 Slovak */ + "slv", /* 40 Slovenian */ + "yid", /* 41 Yiddish */ + "sr ", /* 42 Serbian */ + "mac", /* 43 Macedonian */ + "bul", /* 44 Bulgarian */ + "ukr", /* 45 Ukrainian */ + "bel", /* 46 Belarusian */ + "uzb", /* 47 Uzbek */ + "kaz", /* 48 Kazakh */ + "aze", /* 49 Azerbaijani */ + "aze", /* 50 AzerbaijanAr */ + "arm", /* 51 Armenian */ + "geo", /* 52 Georgian */ + "mol", /* 53 Moldavian */ + "kir", /* 54 Kirghiz */ + "tgk", /* 55 Tajiki */ + "tuk", /* 56 Turkmen */ + "mon", /* 57 Mongolian */ + "", /* 58 MongolianCyr */ + "pus", /* 59 Pashto */ + "kur", /* 60 Kurdish */ + "kas", /* 61 Kashmiri */ + "snd", /* 62 Sindhi */ + "tib", /* 63 Tibetan */ + "nep", /* 64 Nepali */ + "san", /* 65 Sanskrit */ + "mar", /* 66 Marathi */ + "ben", /* 67 Bengali */ + "asm", /* 68 Assamese */ + "guj", /* 69 Gujarati */ + "pa ", /* 70 Punjabi */ + "ori", /* 71 Oriya */ + "mal", /* 72 Malayalam */ + "kan", /* 73 Kannada */ + "tam", /* 74 Tamil */ + "tel", /* 75 Telugu */ + "", /* 76 Sinhala */ + "bur", /* 77 Burmese */ + "khm", /* 78 Khmer */ + "lao", /* 79 Lao */ + "vie", /* 80 Vietnamese */ + "ind", /* 81 Indonesian */ + "tgl", /* 82 Tagalog */ + "may", /* 83 MalayRoman */ + "may", /* 84 MalayArabic */ + "amh", /* 85 Amharic */ + "tir", /* 86 Galla */ + "orm", /* 87 Oromo */ + "som", /* 88 Somali */ + "swa", /* 89 Swahili */ + "", /* 90 Kinyarwanda */ + "run", /* 91 Rundi */ + "", /* 92 Nyanja */ + "mlg", /* 93 Malagasy */ + "epo", /* 94 Esperanto */ + "", /* 95 */ + "", /* 96 */ + "", /* 97 */ + "", /* 98 */ + "", /* 99 */ + "", /* 100 */ + "", /* 101 */ + "", /* 102 */ + "", /* 103 */ + "", /* 104 */ + "", /* 105 */ + "", /* 106 */ + "", /* 107 */ + "", /* 108 */ + "", /* 109 */ + "", /* 110 */ + "", /* 111 */ + "", /* 112 */ + "", /* 113 */ + "", /* 114 */ + "", /* 115 */ + "", /* 116 */ + "", /* 117 */ + "", /* 118 */ + "", /* 119 */ + "", /* 120 */ + "", /* 121 */ + "", /* 122 */ + "", /* 123 */ + "", /* 124 */ + "", /* 125 */ + "", /* 126 */ + "", /* 127 */ + "wel", /* 128 Welsh */ + "baq", /* 129 Basque */ + "cat", /* 130 Catalan */ + "lat", /* 131 Latin */ + "que", /* 132 Quechua */ + "grn", /* 133 Guarani */ + "aym", /* 134 Aymara */ + "tat", /* 135 Tatar */ + "uig", /* 136 Uighur */ + "dzo", /* 137 Dzongkha */ + "jav", /* 138 JavaneseRom */ }; int ff_mov_iso639_to_lang(const char lang[4], int mp4) diff --git a/externals/ffmpeg/libavformat/latmenc.c b/externals/ffmpeg/libavformat/latmenc.c index 5ae677f5d..72b7f72f2 100755 --- a/externals/ffmpeg/libavformat/latmenc.c +++ b/externals/ffmpeg/libavformat/latmenc.c @@ -165,7 +165,7 @@ static int latm_write_packet(AVFormatContext *s, AVPacket *pkt) return ff_raw_write_packet(s, pkt); else { uint8_t *side_data; - int side_data_size = 0, ret; + int side_data_size, ret; side_data = av_packet_get_side_data(pkt, AV_PKT_DATA_NEW_EXTRADATA, &side_data_size); diff --git a/externals/ffmpeg/libavformat/libamqp.c b/externals/ffmpeg/libavformat/libamqp.c index aaf0e5115..81df724a6 100755 --- a/externals/ffmpeg/libavformat/libamqp.c +++ b/externals/ffmpeg/libavformat/libamqp.c @@ -39,6 +39,7 @@ typedef struct AMQPContext { int pkt_size; int64_t connection_timeout; int pkt_size_overflow; + int delivery_mode; } AMQPContext; #define STR_LEN 1024 @@ -52,6 +53,9 @@ static const AVOption options[] = { { "exchange", "Exchange to send/read packets", OFFSET(exchange), AV_OPT_TYPE_STRING, { .str = "amq.direct" }, 0, 0, .flags = D | E }, { "routing_key", "Key to filter streams", OFFSET(routing_key), AV_OPT_TYPE_STRING, { .str = "amqp" }, 0, 0, .flags = D | E }, { "connection_timeout", "Initial connection timeout", OFFSET(connection_timeout), AV_OPT_TYPE_DURATION, { .i64 = -1 }, -1, INT64_MAX, .flags = D | E}, + { "delivery_mode", "Delivery mode", OFFSET(delivery_mode), AV_OPT_TYPE_INT, { .i64 = AMQP_DELIVERY_PERSISTENT }, 1, 2, .flags = E, "delivery_mode"}, + { "persistent", "Persistent delivery mode", 0, AV_OPT_TYPE_CONST, { .i64 = AMQP_DELIVERY_PERSISTENT }, 0, 0, E, "delivery_mode" }, + { "non-persistent", "Non-persistent delivery mode", 0, AV_OPT_TYPE_CONST, { .i64 = AMQP_DELIVERY_NONPERSISTENT }, 0, 0, E, "delivery_mode" }, { NULL } }; @@ -222,7 +226,7 @@ static int amqp_proto_write(URLContext *h, const unsigned char *buf, int size) props._flags = AMQP_BASIC_CONTENT_TYPE_FLAG | AMQP_BASIC_DELIVERY_MODE_FLAG; props.content_type = amqp_cstring_bytes("octet/stream"); - props.delivery_mode = 2; /* persistent delivery mode */ + props.delivery_mode = s->delivery_mode; ret = amqp_basic_publish(s->conn, DEFAULT_CHANNEL, amqp_cstring_bytes(s->exchange), amqp_cstring_bytes(s->routing_key), 0, 0, diff --git a/externals/ffmpeg/libavformat/matroskaenc.c b/externals/ffmpeg/libavformat/matroskaenc.c index eaed02bc9..105ed5197 100755 --- a/externals/ffmpeg/libavformat/matroskaenc.c +++ b/externals/ffmpeg/libavformat/matroskaenc.c @@ -2007,7 +2007,7 @@ static int mkv_write_block(AVFormatContext *s, AVIOContext *pb, AVCodecParameters *par = s->streams[pkt->stream_index]->codecpar; mkv_track *track = &mkv->tracks[pkt->stream_index]; uint8_t *data = NULL, *side_data = NULL; - int err = 0, offset = 0, size = pkt->size, side_data_size = 0; + int err = 0, offset = 0, size = pkt->size, side_data_size; int64_t ts = track->write_dts ? pkt->dts : pkt->pts; uint64_t additional_id; int64_t discard_padding = 0; @@ -2122,12 +2122,10 @@ static int mkv_write_vtt_blocks(AVFormatContext *s, AVIOContext *pb, const AVPac int64_t ts = track->write_dts ? pkt->dts : pkt->pts; const int flags = 0; - id_size = 0; id = av_packet_get_side_data(pkt, AV_PKT_DATA_WEBVTT_IDENTIFIER, &id_size); id = id ? id : ""; - settings_size = 0; settings = av_packet_get_side_data(pkt, AV_PKT_DATA_WEBVTT_SETTINGS, &settings_size); settings = settings ? settings : ""; @@ -2184,7 +2182,7 @@ static int mkv_check_new_extra_data(AVFormatContext *s, const AVPacket *pkt) mkv_track *track = &mkv->tracks[pkt->stream_index]; AVCodecParameters *par = s->streams[pkt->stream_index]->codecpar; uint8_t *side_data; - int side_data_size = 0, ret; + int side_data_size, ret; side_data = av_packet_get_side_data(pkt, AV_PKT_DATA_NEW_EXTRADATA, &side_data_size); diff --git a/externals/ffmpeg/libavformat/mccdec.c b/externals/ffmpeg/libavformat/mccdec.c new file mode 100755 index 000000000..874ff45cd --- /dev/null +++ b/externals/ffmpeg/libavformat/mccdec.c @@ -0,0 +1,238 @@ +/* + * MCC subtitle demuxer + * Copyright (c) 2020 Paul B Mahol + * + * 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 "avformat.h" +#include "internal.h" +#include "subtitles.h" +#include "libavutil/avstring.h" +#include "libavutil/bprint.h" +#include "libavutil/intreadwrite.h" + +typedef struct MCCContext { + FFDemuxSubtitlesQueue q; +} MCCContext; + +static int mcc_probe(const AVProbeData *p) +{ + char buf[28]; + FFTextReader tr; + + ff_text_init_buf(&tr, p->buf, p->buf_size); + + while (ff_text_peek_r8(&tr) == '\r' || ff_text_peek_r8(&tr) == '\n') + ff_text_r8(&tr); + + ff_text_read(&tr, buf, sizeof(buf)); + + if (!memcmp(buf, "File Format=MacCaption_MCC V", 28)) + return AVPROBE_SCORE_MAX; + + return 0; +} + +static int convert(uint8_t x) +{ + if (x >= 'a') + x -= 87; + else if (x >= 'A') + x -= 55; + else + x -= '0'; + return x; +} + +typedef struct alias { + uint8_t key; + int len; + const char *value; +} alias; + +static const alias aliases[20] = { + { .key = 16, .len = 3, .value = "\xFA\x0\x0", }, + { .key = 17, .len = 6, .value = "\xFA\x0\x0\xFA\x0\x0", }, + { .key = 18, .len = 9, .value = "\xFA\x0\x0\xFA\x0\x0\xFA\x0\x0", }, + { .key = 19, .len = 12, .value = "\xFA\x0\x0\xFA\x0\x0\xFA\x0\x0\xFA\x0\x0", }, + { .key = 20, .len = 15, .value = "\xFA\x0\x0\xFA\x0\x0\xFA\x0\x0\xFA\x0\x0\xFA\x0\x0", }, + { .key = 21, .len = 18, .value = "\xFA\x0\x0\xFA\x0\x0\xFA\x0\x0\xFA\x0\x0\xFA\x0\x0\xFA\x0\x0", }, + { .key = 22, .len = 21, .value = "\xFA\x0\x0\xFA\x0\x0\xFA\x0\x0\xFA\x0\x0\xFA\x0\x0\xFA\x0\x0\xFA\x0\x0", }, + { .key = 23, .len = 24, .value = "\xFA\x0\x0\xFA\x0\x0\xFA\x0\x0\xFA\x0\x0\xFA\x0\x0\xFA\x0\x0\xFA\x0\x0\xFA\x0\x0", }, + { .key = 24, .len = 27, .value = "\xFA\x0\x0\xFA\x0\x0\xFA\x0\x0\xFA\x0\x0\xFA\x0\x0\xFA\x0\x0\xFA\x0\x0\xFA\x0\x0\xFA\x0\x0", }, + { .key = 25, .len = 3, .value = "\xFB\x80\x80", }, + { .key = 26, .len = 3, .value = "\xFC\x80\x80", }, + { .key = 27, .len = 3, .value = "\xFD\x80\x80", }, + { .key = 28, .len = 2, .value = "\x96\x69", }, + { .key = 29, .len = 2, .value = "\x61\x01", }, + { .key = 30, .len = 3, .value = "\xFC\x80\x80", }, + { .key = 31, .len = 3, .value = "\xFC\x80\x80", }, + { .key = 32, .len = 4, .value = "\xE1\x00\x00\x00", }, + { .key = 33, .len = 0, .value = NULL, }, + { .key = 34, .len = 0, .value = NULL, }, + { .key = 35, .len = 1, .value = "\x0", }, +}; + +static int mcc_read_header(AVFormatContext *s) +{ + MCCContext *mcc = s->priv_data; + AVStream *st = avformat_new_stream(s, NULL); + AVRational rate; + int64_t ts, pos; + uint8_t out[4096]; + char line[4096]; + FFTextReader tr; + int ret = 0; + + ff_text_init_avio(s, &tr, s->pb); + + if (!st) + return AVERROR(ENOMEM); + st->codecpar->codec_type = AVMEDIA_TYPE_SUBTITLE; + st->codecpar->codec_id = AV_CODEC_ID_EIA_608; + avpriv_set_pts_info(st, 64, 1, 30); + + while (!ff_text_eof(&tr)) { + int hh, mm, ss, fs, i = 0, j = 0; + int start = 12, count = 0; + AVPacket *sub; + char *lline; + + ff_subtitles_read_line(&tr, line, sizeof(line)); + if (!strncmp(line, "File Format=MacCaption_MCC V", 28)) + continue; + if (!strncmp(line, "//", 2)) + continue; + if (!strncmp(line, "Time Code Rate=", 15)) { + char *rate_str = line + 15; + char *df = NULL; + int num = -1, den = -1; + + if (rate_str[0]) { + num = strtol(rate_str, &df, 10); + den = 1; + if (df && !av_strncasecmp(df, "DF", 2)) { + num *= 1000; + den = 1001; + } + } + + if (num > 0 && den > 0) { + rate = av_make_q(num, den); + avpriv_set_pts_info(st, 64, rate.den, rate.num); + } + continue; + } + + if (av_sscanf(line, "%d:%d:%d:%d", &hh, &mm, &ss, &fs) != 4) + continue; + + ts = av_rescale(hh * 3600LL + mm * 60LL + ss, rate.num, rate.den) + fs; + + lline = (char *)&line; + lline += 12; + pos = ff_text_pos(&tr); + + while (lline[i]) { + uint8_t v = convert(lline[i]); + + if (v >= 16 && v <= 35) { + int idx = v - 16; + if (aliases[idx].len) { + if (j >= sizeof(out) - 1 - aliases[idx].len) { + j = 0; + break; + } + memcpy(out + j, aliases[idx].value, aliases[idx].len); + j += aliases[idx].len; + } + } else { + uint8_t vv; + + if (i + 13 >= sizeof(line) - 1) + break; + vv = convert(lline[i + 1]); + if (j >= sizeof(out) - 1) { + j = 0; + break; + } + out[j++] = vv | (v << 4); + i++; + } + + i++; + } + out[j] = 0; + + if (out[7] & 0x80) + start += 4; + count = (out[11] & 0x1f) * 3; + if (j < start + count + 1) + continue; + + if (!count) + continue; + sub = ff_subtitles_queue_insert(&mcc->q, out + start, count, 0); + if (!sub) + goto fail; + + sub->pos = pos; + sub->pts = ts; + sub->duration = 1; + } + + ff_subtitles_queue_finalize(s, &mcc->q); + + return ret; +fail: + ff_subtitles_queue_clean(&mcc->q); + return AVERROR(ENOMEM); +} + +static int mcc_read_packet(AVFormatContext *s, AVPacket *pkt) +{ + MCCContext *mcc = s->priv_data; + return ff_subtitles_queue_read_packet(&mcc->q, pkt); +} + +static int mcc_read_seek(AVFormatContext *s, int stream_index, + int64_t min_ts, int64_t ts, int64_t max_ts, int flags) +{ + MCCContext *mcc = s->priv_data; + return ff_subtitles_queue_seek(&mcc->q, s, stream_index, + min_ts, ts, max_ts, flags); +} + +static int mcc_read_close(AVFormatContext *s) +{ + MCCContext *mcc = s->priv_data; + ff_subtitles_queue_clean(&mcc->q); + return 0; +} + +AVInputFormat ff_mcc_demuxer = { + .name = "mcc", + .long_name = NULL_IF_CONFIG_SMALL("MacCaption"), + .priv_data_size = sizeof(MCCContext), + .read_probe = mcc_probe, + .read_header = mcc_read_header, + .read_packet = mcc_read_packet, + .read_seek2 = mcc_read_seek, + .read_close = mcc_read_close, + .extensions = "mcc", +}; diff --git a/externals/ffmpeg/libavformat/mm.c b/externals/ffmpeg/libavformat/mm.c index 02ffbcd82..d40fd12ac 100755 --- a/externals/ffmpeg/libavformat/mm.c +++ b/externals/ffmpeg/libavformat/mm.c @@ -175,8 +175,6 @@ static int read_packet(AVFormatContext *s, return 0; case MM_TYPE_AUDIO : - if (s->nb_streams < 2) - return AVERROR_INVALIDDATA; if ((ret = av_get_packet(s->pb, pkt, length)) < 0) return ret; pkt->stream_index = 1; diff --git a/externals/ffmpeg/libavformat/mov.c b/externals/ffmpeg/libavformat/mov.c index dfb41b93b..da438e4e2 100755 --- a/externals/ffmpeg/libavformat/mov.c +++ b/externals/ffmpeg/libavformat/mov.c @@ -181,7 +181,6 @@ static int mov_read_mac_string(MOVContext *c, AVIOContext *pb, int len, static int mov_read_covr(MOVContext *c, AVIOContext *pb, int type, int len) { - AVPacket pkt; AVStream *st; MOVStreamContext *sc; enum AVCodecID id; @@ -205,12 +204,12 @@ static int mov_read_covr(MOVContext *c, AVIOContext *pb, int type, int len) return AVERROR(ENOMEM); st->priv_data = sc; - ret = av_get_packet(pb, &pkt, len); + ret = av_get_packet(pb, &st->attached_pic, len); if (ret < 0) return ret; - if (pkt.size >= 8 && id != AV_CODEC_ID_BMP) { - if (AV_RB64(pkt.data) == 0x89504e470d0a1a0a) { + if (st->attached_pic.size >= 8 && id != AV_CODEC_ID_BMP) { + if (AV_RB64(st->attached_pic.data) == 0x89504e470d0a1a0a) { id = AV_CODEC_ID_PNG; } else { id = AV_CODEC_ID_MJPEG; @@ -219,7 +218,6 @@ static int mov_read_covr(MOVContext *c, AVIOContext *pb, int type, int len) st->disposition |= AV_DISPOSITION_ATTACHED_PIC; - st->attached_pic = pkt; st->attached_pic.stream_index = st->index; st->attached_pic.flags |= AV_PKT_FLAG_KEY; @@ -646,7 +644,7 @@ static int mov_read_dref(MOVContext *c, AVIOContext *pb, MOVAtom atom) avio_skip(pb, 16); for (type = 0; type != -1 && avio_tell(pb) < next; ) { - if(avio_feof(pb)) + if (avio_feof(pb)) return AVERROR_EOF; type = avio_rb16(pb); len = avio_rb16(pb); @@ -859,26 +857,20 @@ static int mov_read_dec3(MOVContext *c, AVIOContext *pb, MOVAtom atom) static int mov_read_ddts(MOVContext *c, AVIOContext *pb, MOVAtom atom) { - const uint32_t ddts_size = 20; +#define DDTS_SIZE 20 + uint8_t buf[DDTS_SIZE + AV_INPUT_BUFFER_PADDING_SIZE]; AVStream *st = NULL; - uint8_t *buf = NULL; uint32_t frame_duration_code = 0; uint32_t channel_layout_code = 0; GetBitContext gb; + int ret; - buf = av_malloc(ddts_size + AV_INPUT_BUFFER_PADDING_SIZE); - if (!buf) { - return AVERROR(ENOMEM); - } - if (avio_read(pb, buf, ddts_size) < ddts_size) { - av_free(buf); - return AVERROR_INVALIDDATA; - } + if ((ret = ffio_read_size(pb, buf, DDTS_SIZE)) < 0) + return ret; - init_get_bits(&gb, buf, 8*ddts_size); + init_get_bits(&gb, buf, 8 * DDTS_SIZE); if (c->fc->nb_streams < 1) { - av_free(buf); return 0; } st = c->fc->streams[c->fc->nb_streams-1]; @@ -886,7 +878,6 @@ static int mov_read_ddts(MOVContext *c, AVIOContext *pb, MOVAtom atom) st->codecpar->sample_rate = get_bits_long(&gb, 32); if (st->codecpar->sample_rate <= 0) { av_log(c->fc, AV_LOG_ERROR, "Invalid sample rate %d\n", st->codecpar->sample_rate); - av_free(buf); return AVERROR_INVALIDDATA; } skip_bits_long(&gb, 32); /* max bitrate */ @@ -914,7 +905,6 @@ static int mov_read_ddts(MOVContext *c, AVIOContext *pb, MOVAtom atom) ((channel_layout_code & 0x8) ? AV_CH_LOW_FREQUENCY : 0); st->codecpar->channels = av_get_channel_layout_nb_channels(st->codecpar->channel_layout); - av_free(buf); return 0; } @@ -1318,7 +1308,7 @@ static int update_frag_index(MOVContext *c, int64_t offset) &c->frag_index.allocated_size, (c->frag_index.nb_items + 1) * sizeof(*c->frag_index.item)); - if(!item) + if (!item) return -1; c->frag_index.item = item; @@ -1402,7 +1392,7 @@ static int mov_read_moof(MOVContext *c, AVIOContext *pb, MOVAtom atom) static void mov_metadata_creation_time(AVDictionary **metadata, int64_t time, void *logctx) { if (time) { - if(time >= 2082844800) + if (time >= 2082844800) time -= 2082844800; /* seconds between 1904-01-01 and Epoch */ if ((int64_t)(time * 1000000ULL) / 1000000 != time) { @@ -1576,8 +1566,7 @@ static int mov_read_colr(MOVContext *c, AVIOContext *pb, MOVAtom atom) ret = ffio_read_size(pb, icc_profile, atom.size - 4); if (ret < 0) return ret; - } - else { + } else { color_primaries = avio_rb16(pb); color_trc = avio_rb16(pb); color_matrix = avio_rb16(pb); @@ -1730,7 +1719,7 @@ static int mov_read_dpxe(MOVContext *c, AVIOContext *pb, MOVAtom atom) static int mov_read_avid(MOVContext *c, AVIOContext *pb, MOVAtom atom) { int ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_AVUI); - if(ret == 0) + if (!ret) ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_DNXHD); return ret; } @@ -2342,18 +2331,15 @@ FF_ENABLE_DEPRECATION_WARNINGS uint32_t format = AV_RB32(st->codecpar->extradata + 22); if (format == AV_RB32("name") && (int64_t)size >= (int64_t)len + 18) { uint16_t str_size = AV_RB16(st->codecpar->extradata + 26); /* string length */ - if (str_size > 0 && size >= (int)str_size + 30) { + if (str_size > 0 && size >= (int)str_size + 30 && + st->codecpar->extradata[30] /* Don't add empty string */) { char *reel_name = av_malloc(str_size + 1); if (!reel_name) return AVERROR(ENOMEM); memcpy(reel_name, st->codecpar->extradata + 30, str_size); reel_name[str_size] = 0; /* Add null terminator */ - /* don't add reel_name if emtpy string */ - if (*reel_name == 0) { - av_free(reel_name); - } else { - av_dict_set(&st->metadata, "reel_name", reel_name, AV_DICT_DONT_STRDUP_VAL); - } + av_dict_set(&st->metadata, "reel_name", reel_name, + AV_DICT_DONT_STRDUP_VAL); } } } @@ -2550,11 +2536,8 @@ int ff_mov_read_stsd_entries(MOVContext *c, AVIOContext *pb, int entries) /* Move the current stream extradata to the stream context one. */ sc->extradata_size[pseudo_stream_id] = extra_size; - sc->extradata[pseudo_stream_id] = av_malloc(extra_size + AV_INPUT_BUFFER_PADDING_SIZE); - if (!sc->extradata[pseudo_stream_id]) - return AVERROR(ENOMEM); - memcpy(sc->extradata[pseudo_stream_id], st->codecpar->extradata, extra_size); - av_freep(&st->codecpar->extradata); + sc->extradata[pseudo_stream_id] = st->codecpar->extradata; + st->codecpar->extradata = NULL; st->codecpar->extradata_size = 0; } sc->stsd_count++; @@ -2781,8 +2764,7 @@ static int mov_read_stss(MOVContext *c, AVIOContext *pb, MOVAtom atom) av_log(c->fc, AV_LOG_TRACE, "keyframe_count = %u\n", entries); - if (!entries) - { + if (!entries) { sc->keyframe_absent = 1; if (!st->need_parsing && st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) st->need_parsing = AVSTREAM_PARSE_HEADERS; @@ -2910,8 +2892,8 @@ static int mov_read_stts(MOVContext *c, AVIOContext *pb, MOVAtom atom) AVStream *st; MOVStreamContext *sc; unsigned int i, entries, alloc_size = 0; - int64_t duration=0; - int64_t total_sample_count=0; + int64_t duration = 0; + int64_t total_sample_count = 0; if (c->fc->nb_streams < 1) return 0; @@ -2946,7 +2928,7 @@ static int mov_read_stts(MOVContext *c, AVIOContext *pb, MOVAtom atom) sc->stts_count = min_entries; sc->stts_data = stts_data; - sample_count=avio_rb32(pb); + sample_count = avio_rb32(pb); sample_duration = avio_rb32(pb); sc->stts_data[i].count= sample_count; @@ -2963,8 +2945,7 @@ static int mov_read_stts(MOVContext *c, AVIOContext *pb, MOVAtom atom) if (duration > 0 && duration <= INT64_MAX - sc->duration_for_fps && - total_sample_count <= INT_MAX - sc->nb_frames_for_fps - ) { + total_sample_count <= INT_MAX - sc->nb_frames_for_fps) { sc->duration_for_fps += duration; sc->nb_frames_for_fps += total_sample_count; } @@ -3053,8 +3034,8 @@ static int mov_read_ctts(MOVContext *c, AVIOContext *pb, MOVAtom atom) return AVERROR(ENOMEM); for (i = 0; i < entries && !pb->eof_reached; i++) { - int count =avio_rb32(pb); - int duration =avio_rb32(pb); + int count = avio_rb32(pb); + int duration = avio_rb32(pb); if (count <= 0) { av_log(c->fc, AV_LOG_TRACE, @@ -3294,13 +3275,13 @@ static int64_t add_index_entry(AVStream *st, int64_t pos, int64_t timestamp, FFMAX(min_size_needed, 2 * st->index_entries_allocated_size) : min_size_needed; - if((unsigned)st->nb_index_entries + 1 >= UINT_MAX / sizeof(AVIndexEntry)) + if (st->nb_index_entries + 1U >= UINT_MAX / sizeof(AVIndexEntry)) return -1; entries = av_fast_realloc(st->index_entries, &st->index_entries_allocated_size, requested_size); - if(!entries) + if (!entries) return -1; st->index_entries= entries; @@ -3345,12 +3326,12 @@ static int64_t add_ctts_entry(MOVStts** ctts_data, unsigned int* ctts_count, uns FFMAX(min_size_needed, 2 * (*allocated_size)) : min_size_needed; - if((unsigned)(*ctts_count) >= UINT_MAX / sizeof(MOVStts) - 1) + if ((unsigned)(*ctts_count) >= UINT_MAX / sizeof(MOVStts) - 1) return -1; ctts_buf_new = av_fast_realloc(*ctts_data, allocated_size, requested_size); - if(!ctts_buf_new) + if (!ctts_buf_new) return -1; *ctts_data = ctts_buf_new; @@ -3363,7 +3344,8 @@ static int64_t add_ctts_entry(MOVStts** ctts_data, unsigned int* ctts_count, uns } #define MAX_REORDER_DELAY 16 -static void mov_estimate_video_delay(MOVContext *c, AVStream* st) { +static void mov_estimate_video_delay(MOVContext *c, AVStream* st) +{ MOVStreamContext *msc = st->priv_data; int ind; int ctts_ind = 0; @@ -3378,7 +3360,7 @@ static void mov_estimate_video_delay(MOVContext *c, AVStream* st) { if (st->codecpar->video_delay <= 0 && msc->ctts_data && st->codecpar->codec_id == AV_CODEC_ID_H264) { st->codecpar->video_delay = 0; - for(ind = 0; ind < st->nb_index_entries && ctts_ind < msc->ctts_count; ++ind) { + for (ind = 0; ind < st->nb_index_entries && ctts_ind < msc->ctts_count; ++ind) { // Point j to the last elem of the buffer and insert the current pts there. j = buf_start; buf_start = (buf_start + 1); @@ -4176,10 +4158,10 @@ static int mov_open_dref(MOVContext *c, AVIOContext **pb, const char *src, MOVDr return AVERROR(ENOENT); } - if(strstr(ref->path + l + 1, "..") || - strstr(ref->path + l + 1, ":") || - (ref->nlvl_from > 1 && same_origin < 0) || - (filename[0] == '/' && src_path == src)) + if (strstr(ref->path + l + 1, "..") || + strstr(ref->path + l + 1, ":") || + (ref->nlvl_from > 1 && same_origin < 0) || + (filename[0] == '/' && src_path == src)) return AVERROR(ENOENT); } @@ -4813,8 +4795,7 @@ static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom) if (flags & MOV_TRUN_FIRST_SAMPLE_FLAGS) first_sample_flags = avio_rb32(pb); frag_stream_info = get_current_frag_stream_info(&c->frag_index); - if (frag_stream_info) - { + if (frag_stream_info) { if (frag_stream_info->next_trun_dts != AV_NOPTS_VALUE) { dts = frag_stream_info->next_trun_dts - sc->time_offset; } else if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE && @@ -4863,7 +4844,7 @@ static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom) new_entries = av_fast_realloc(st->index_entries, &st->index_entries_allocated_size, requested_size); - if(!new_entries) + if (!new_entries) return AVERROR(ENOMEM); st->index_entries= new_entries; @@ -5773,12 +5754,9 @@ static int mov_read_uuid(MOVContext *c, AVIOContext *pb, MOVAtom atom) st = c->fc->streams[c->fc->nb_streams - 1]; sc = st->priv_data; - ret = avio_read(pb, uuid, sizeof(uuid)); - if (ret < 0) { + ret = ffio_read_size(pb, uuid, sizeof(uuid)); + if (ret < 0) return ret; - } else if (ret != sizeof(uuid)) { - return AVERROR_INVALIDDATA; - } if (!memcmp(uuid, uuid_isml_manifest, sizeof(uuid))) { uint8_t *buffer, *ptr; char *endptr; @@ -5794,13 +5772,10 @@ static int mov_read_uuid(MOVContext *c, AVIOContext *pb, MOVAtom atom) if (!buffer) { return AVERROR(ENOMEM); } - ret = avio_read(pb, buffer, len); + ret = ffio_read_size(pb, buffer, len); if (ret < 0) { av_free(buffer); return ret; - } else if (ret != len) { - av_free(buffer); - return AVERROR_INVALIDDATA; } ptr = buffer; @@ -5831,13 +5806,10 @@ static int mov_read_uuid(MOVContext *c, AVIOContext *pb, MOVAtom atom) if (!buffer) { return AVERROR(ENOMEM); } - ret = avio_read(pb, buffer, len); + ret = ffio_read_size(pb, buffer, len); if (ret < 0) { av_free(buffer); return ret; - } else if (ret != len) { - av_free(buffer); - return AVERROR_INVALIDDATA; } buffer[len] = '\0'; av_dict_set(&c->fc->metadata, "xmp", @@ -5981,7 +5953,7 @@ static int get_current_encryption_info(MOVContext *c, MOVEncryptionIndex **encry static int mov_read_sample_encryption_info(MOVContext *c, AVIOContext *pb, MOVStreamContext *sc, AVEncryptionInfo **sample, int use_subsamples) { - int i; + int i, ret; unsigned int subsample_count; AVSubsampleEncryptionInfo *subsamples; @@ -5995,11 +5967,11 @@ static int mov_read_sample_encryption_info(MOVContext *c, AVIOContext *pb, MOVSt return AVERROR(ENOMEM); if (sc->cenc.per_sample_iv_size != 0) { - if (avio_read(pb, (*sample)->iv, sc->cenc.per_sample_iv_size) != sc->cenc.per_sample_iv_size) { + if ((ret = ffio_read_size(pb, (*sample)->iv, sc->cenc.per_sample_iv_size)) < 0) { av_log(c->fc, AV_LOG_ERROR, "failed to read the initialization vector\n"); av_encryption_info_free(*sample); *sample = NULL; - return AVERROR_INVALIDDATA; + return ret; } } @@ -6367,9 +6339,8 @@ static int mov_read_pssh(MOVContext *c, AVIOContext *pb, MOVAtom atom) if (!info) return AVERROR(ENOMEM); - if (avio_read(pb, info->system_id, 16) != 16) { + if ((ret = ffio_read_size(pb, info->system_id, 16)) < 0) { av_log(c->fc, AV_LOG_ERROR, "Failed to read the system id\n"); - ret = AVERROR_INVALIDDATA; goto finish; } @@ -6397,9 +6368,8 @@ static int mov_read_pssh(MOVContext *c, AVIOContext *pb, MOVAtom atom) } info->num_key_ids = i + 1; - if (avio_read(pb, info->key_ids[i], 16) != 16) { + if ((ret = ffio_read_size(pb, info->key_ids[i], 16)) < 0) { av_log(c->fc, AV_LOG_ERROR, "Failed to read the key id\n"); - ret = AVERROR_INVALIDDATA; goto finish; } } @@ -6618,15 +6588,13 @@ static int cenc_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *s av_aes_ctr_set_full_iv(sc->cenc.aes_ctr, sample->iv); - if (!sample->subsample_count) - { + if (!sample->subsample_count) { /* decrypt the whole packet */ av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, size); return 0; } - for (i = 0; i < sample->subsample_count; i++) - { + for (i = 0; i < sample->subsample_count; i++) { if (sample->subsamples[i].bytes_of_clear_data + sample->subsamples[i].bytes_of_protected_data > size) { av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n"); return AVERROR_INVALIDDATA; @@ -6988,10 +6956,9 @@ static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom) } } if (atom.type != MKTAG('r','o','o','t') && - atom.type != MKTAG('m','o','o','v')) - { - if (a.type == MKTAG('t','r','a','k') || a.type == MKTAG('m','d','a','t')) - { + atom.type != MKTAG('m','o','o','v')) { + if (a.type == MKTAG('t','r','a','k') || + a.type == MKTAG('m','d','a','t')) { av_log(c->fc, AV_LOG_ERROR, "Broken file, trak/mdat not at top-level\n"); avio_skip(pb, -8); c->atom_depth --; @@ -7131,25 +7098,26 @@ static int mov_probe(const AVProbeData *p) offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset; } } - if(score > AVPROBE_SCORE_MAX - 50 && moov_offset != -1) { + if (score > AVPROBE_SCORE_MAX - 50 && moov_offset != -1) { /* moov atom in the header - we should make sure that this is not a * MOV-packed MPEG-PS */ offset = moov_offset; - while(offset < (p->buf_size - 16)){ /* Sufficient space */ + while (offset < (p->buf_size - 16)) { /* Sufficient space */ /* We found an actual hdlr atom */ - if(AV_RL32(p->buf + offset ) == MKTAG('h','d','l','r') && - AV_RL32(p->buf + offset + 8) == MKTAG('m','h','l','r') && - AV_RL32(p->buf + offset + 12) == MKTAG('M','P','E','G')){ + if (AV_RL32(p->buf + offset ) == MKTAG('h','d','l','r') && + AV_RL32(p->buf + offset + 8) == MKTAG('m','h','l','r') && + AV_RL32(p->buf + offset + 12) == MKTAG('M','P','E','G')) { av_log(NULL, AV_LOG_WARNING, "Found media data tag MPEG indicating this is a MOV-packed MPEG-PS.\n"); /* We found a media handler reference atom describing an * MPEG-PS-in-MOV, return a * low score to force expanding the probe window until * mpegps_probe finds what it needs */ return 5; - }else + } else { /* Keep looking */ - offset+=2; + offset += 2; + } } } @@ -7186,17 +7154,15 @@ static void mov_read_chapters(AVFormatContext *s) st->disposition |= AV_DISPOSITION_ATTACHED_PIC | AV_DISPOSITION_TIMED_THUMBNAILS; if (st->nb_index_entries) { // Retrieve the first frame, if possible - AVPacket pkt; AVIndexEntry *sample = &st->index_entries[0]; if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) { av_log(s, AV_LOG_ERROR, "Failed to retrieve first frame\n"); goto finish; } - if (av_get_packet(sc->pb, &pkt, sample->size) < 0) + if (av_get_packet(sc->pb, &st->attached_pic, sample->size) < 0) goto finish; - st->attached_pic = pkt; st->attached_pic.stream_index = st->index; st->attached_pic.flags |= AV_PKT_FLAG_KEY; } @@ -7627,7 +7593,8 @@ static int mov_read_header(AVFormatContext *s) AVStream *st = s->streams[i]; MOVStreamContext *sc = st->priv_data; fix_timescale(mov, sc); - if(st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && st->codecpar->codec_id == AV_CODEC_ID_AAC) { + if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && + st->codecpar->codec_id == AV_CODEC_ID_AAC) { st->skip_samples = sc->start_pad; } if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && sc->nb_frames_for_fps > 0 && sc->duration_for_fps > 0) @@ -7645,8 +7612,7 @@ static int mov_read_header(AVFormatContext *s) } if (mov->handbrake_version && mov->handbrake_version <= 1000000*0 + 1000*10 + 2 && // 0.10.2 - st->codecpar->codec_id == AV_CODEC_ID_MP3 - ) { + st->codecpar->codec_id == AV_CODEC_ID_MP3) { av_log(s, AV_LOG_VERBOSE, "Forcing full parsing for mp3 stream\n"); st->need_parsing = AVSTREAM_PARSE_FULL; } @@ -7700,9 +7666,8 @@ static int mov_read_header(AVFormatContext *s) switch (st->codecpar->codec_type) { case AVMEDIA_TYPE_AUDIO: err = ff_replaygain_export(st, s->metadata); - if (err < 0) { + if (err < 0) goto fail; - } break; case AVMEDIA_TYPE_VIDEO: if (sc->display_matrix) { @@ -7856,6 +7821,27 @@ static int mov_change_extradata(MOVStreamContext *sc, AVPacket *pkt) return 0; } +static int get_eia608_packet(AVIOContext *pb, AVPacket *pkt, int size) +{ + int new_size, ret; + + if (size <= 8) + return AVERROR_INVALIDDATA; + new_size = ((size - 8) / 2) * 3; + ret = av_new_packet(pkt, new_size); + if (ret < 0) + return ret; + + avio_skip(pb, 8); + for (int j = 0; j < new_size; j += 3) { + pkt->data[j] = 0xFC; + pkt->data[j+1] = avio_r8(pb); + pkt->data[j+2] = avio_r8(pb); + } + + return 0; +} + static int mov_read_packet(AVFormatContext *s, AVPacket *pkt) { MOVContext *mov = s->priv_data; @@ -7895,12 +7881,15 @@ static int mov_read_packet(AVFormatContext *s, AVPacket *pkt) return AVERROR_INVALIDDATA; } - if( st->discard == AVDISCARD_NONKEY && 0==(sample->flags & AVINDEX_KEYFRAME) ) { + if (st->discard == AVDISCARD_NONKEY && !(sample->flags & AVINDEX_KEYFRAME)) { av_log(mov->fc, AV_LOG_DEBUG, "Nonkey frame from stream %d discarded due to AVDISCARD_NONKEY\n", sc->ffindex); goto retry; } - ret = av_get_packet(sc->pb, pkt, sample->size); + if (st->codecpar->codec_id == AV_CODEC_ID_EIA_608 && sample->size > 8) + ret = get_eia608_packet(sc->pb, pkt, sample->size); + else + ret = av_get_packet(sc->pb, pkt, sample->size); if (ret < 0) { if (should_retry(sc->pb, ret)) { mov_current_sample_dec(sc); @@ -8056,17 +8045,17 @@ static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp, /* adjust stsd index */ if (sc->chunk_count) { - time_sample = 0; - for (i = 0; i < sc->stsc_count; i++) { - int64_t next = time_sample + mov_get_stsc_samples(sc, i); - if (next > sc->current_sample) { - sc->stsc_index = i; - sc->stsc_sample = sc->current_sample - time_sample; - break; + time_sample = 0; + for (i = 0; i < sc->stsc_count; i++) { + int64_t next = time_sample + mov_get_stsc_samples(sc, i); + if (next > sc->current_sample) { + sc->stsc_index = i; + sc->stsc_sample = sc->current_sample - time_sample; + break; + } + av_assert0(next == (int)next); + time_sample = next; } - av_assert0(next == (int)next); - time_sample = next; - } } return sample; diff --git a/externals/ffmpeg/libavformat/movenc.c b/externals/ffmpeg/libavformat/movenc.c index 5d8dc4fd5..7db2e2884 100755 --- a/externals/ffmpeg/libavformat/movenc.c +++ b/externals/ffmpeg/libavformat/movenc.c @@ -4798,28 +4798,40 @@ static int mov_write_tfra_tag(AVIOContext *pb, MOVTrack *track) static int mov_write_mfra_tag(AVIOContext *pb, MOVMuxContext *mov) { - int64_t pos = avio_tell(pb); - int i; + AVIOContext *mfra_pb; + int i, ret, sz; + uint8_t *buf; - avio_wb32(pb, 0); /* size placeholder */ - ffio_wfourcc(pb, "mfra"); + ret = avio_open_dyn_buf(&mfra_pb); + if (ret < 0) + return ret; + + avio_wb32(mfra_pb, 0); /* size placeholder */ + ffio_wfourcc(mfra_pb, "mfra"); /* An empty mfra atom is enough to indicate to the publishing point that * the stream has ended. */ if (mov->flags & FF_MOV_FLAG_ISML) - return update_size(pb, pos); + goto done_mfra; for (i = 0; i < mov->nb_streams; i++) { MOVTrack *track = &mov->tracks[i]; if (track->nb_frag_info) - mov_write_tfra_tag(pb, track); + mov_write_tfra_tag(mfra_pb, track); } - avio_wb32(pb, 16); - ffio_wfourcc(pb, "mfro"); - avio_wb32(pb, 0); /* version + flags */ - avio_wb32(pb, avio_tell(pb) + 4 - pos); + avio_wb32(mfra_pb, 16); + ffio_wfourcc(mfra_pb, "mfro"); + avio_wb32(mfra_pb, 0); /* version + flags */ + avio_wb32(mfra_pb, avio_tell(mfra_pb) + 4); - return update_size(pb, pos); +done_mfra: + + sz = update_size(mfra_pb, 0); + ret = avio_get_dyn_buf(mfra_pb, &buf); + avio_write(pb, buf, ret); + ffio_free_dyn_buf(&mfra_pb); + + return sz; } static int mov_write_mdat_tag(AVIOContext *pb, MOVMuxContext *mov) @@ -4875,7 +4887,7 @@ static int mov_write_ftyp_tag(AVIOContext *pb, AVFormatContext *s) { MOVMuxContext *mov = s->priv_data; int64_t pos = avio_tell(pb); - int has_h264 = 0, has_video = 0; + int has_h264 = 0, has_av1 = 0, has_video = 0; int i; for (i = 0; i < s->nb_streams; i++) { @@ -4886,6 +4898,8 @@ static int mov_write_ftyp_tag(AVIOContext *pb, AVFormatContext *s) has_video = 1; if (st->codecpar->codec_id == AV_CODEC_ID_H264) has_h264 = 1; + if (st->codecpar->codec_id == AV_CODEC_ID_AV1) + has_av1 = 1; } avio_wb32(pb, 0); /* size */ @@ -4909,6 +4923,8 @@ static int mov_write_ftyp_tag(AVIOContext *pb, AVFormatContext *s) ffio_wfourcc(pb, "cmfc"); if (mov->flags & FF_MOV_FLAG_FRAGMENT && !(mov->flags & FF_MOV_FLAG_NEGATIVE_CTS_OFFSETS)) ffio_wfourcc(pb, "iso6"); + if (has_av1) + ffio_wfourcc(pb, "av01"); } else { if (mov->flags & FF_MOV_FLAG_FRAGMENT) ffio_wfourcc(pb, "iso6"); @@ -5582,6 +5598,22 @@ int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt) goto end; avio_write(pb, pkt->data, size); #endif + } else if (par->codec_id == AV_CODEC_ID_EIA_608) { + size = 8; + + for (int i = 0; i < pkt->size; i += 3) { + if (pkt->data[i] == 0xFC) { + size += 2; + } + } + avio_wb32(pb, size); + ffio_wfourcc(pb, "cdat"); + for (int i = 0; i < pkt->size; i += 3) { + if (pkt->data[i] == 0xFC) { + avio_w8(pb, pkt->data[i + 1]); + avio_w8(pb, pkt->data[i + 2]); + } + } } else { if (trk->cenc.aes_ctr) { if (par->codec_id == AV_CODEC_ID_H264 && par->extradata_size > 4) { @@ -5768,7 +5800,7 @@ static int mov_write_single_packet(AVFormatContext *s, AVPacket *pkt) trk->par->codec_id == AV_CODEC_ID_AAC || trk->par->codec_id == AV_CODEC_ID_AV1 || trk->par->codec_id == AV_CODEC_ID_FLAC) { - int side_size = 0; + int side_size; uint8_t *side = av_packet_get_side_data(pkt, AV_PKT_DATA_NEW_EXTRADATA, &side_size); if (side && side_size > 0 && (side_size != par->extradata_size || memcmp(side, par->extradata, side_size))) { void *newextra = av_mallocz(side_size + AV_INPUT_BUFFER_PADDING_SIZE); @@ -6967,7 +6999,9 @@ static int mov_write_trailer(AVFormatContext *s) } if (!(mov->flags & FF_MOV_FLAG_SKIP_TRAILER)) { avio_write_marker(s->pb, AV_NOPTS_VALUE, AVIO_DATA_MARKER_TRAILER); - mov_write_mfra_tag(pb, mov); + res = mov_write_mfra_tag(pb, mov); + if (res < 0) + return res; } } diff --git a/externals/ffmpeg/libavformat/mp3enc.c b/externals/ffmpeg/libavformat/mp3enc.c index 14d4b6e0a..a3586e1f8 100755 --- a/externals/ffmpeg/libavformat/mp3enc.c +++ b/externals/ffmpeg/libavformat/mp3enc.c @@ -354,7 +354,7 @@ static int mp3_write_audio_packet(AVFormatContext *s, AVPacket *pkt) if (mp3->xing_offset) { uint8_t *side_data = NULL; - int side_data_size = 0; + int side_data_size; mp3_xing_add_frame(mp3, pkt); mp3->audio_size += pkt->size; diff --git a/externals/ffmpeg/libavformat/mpegts.h b/externals/ffmpeg/libavformat/mpegts.h index 059b693f0..fe10b3869 100755 --- a/externals/ffmpeg/libavformat/mpegts.h +++ b/externals/ffmpeg/libavformat/mpegts.h @@ -137,6 +137,13 @@ #define STREAM_TYPE_AUDIO_TRUEHD 0x83 #define STREAM_TYPE_AUDIO_EAC3 0x87 +/* ISO/IEC 13818-1 Table 2-22 */ +#define STREAM_ID_PRIVATE_STREAM_1 0xbd +#define STREAM_ID_AUDIO_STREAM_0 0xc0 +#define STREAM_ID_VIDEO_STREAM_0 0xe0 +#define STREAM_ID_METADATA_STREAM 0xfc +#define STREAM_ID_EXTENDED_STREAM_ID 0xfd + typedef struct MpegTSContext MpegTSContext; MpegTSContext *avpriv_mpegts_parse_open(AVFormatContext *s); diff --git a/externals/ffmpeg/libavformat/mpegtsenc.c b/externals/ffmpeg/libavformat/mpegtsenc.c index b5ee48d01..d827ba3e2 100755 --- a/externals/ffmpeg/libavformat/mpegtsenc.c +++ b/externals/ffmpeg/libavformat/mpegtsenc.c @@ -1382,28 +1382,28 @@ static void mpegts_write_pes(AVFormatContext *s, AVStream *st, is_dvb_teletext = 0; if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) { if (st->codecpar->codec_id == AV_CODEC_ID_DIRAC) - *q++ = 0xfd; + *q++ = STREAM_ID_EXTENDED_STREAM_ID; else - *q++ = 0xe0; + *q++ = STREAM_ID_VIDEO_STREAM_0; } else if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && (st->codecpar->codec_id == AV_CODEC_ID_MP2 || st->codecpar->codec_id == AV_CODEC_ID_MP3 || st->codecpar->codec_id == AV_CODEC_ID_AAC)) { - *q++ = 0xc0; + *q++ = STREAM_ID_AUDIO_STREAM_0; } else if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && st->codecpar->codec_id == AV_CODEC_ID_AC3 && ts->m2ts_mode) { - *q++ = 0xfd; + *q++ = STREAM_ID_EXTENDED_STREAM_ID; } else if (st->codecpar->codec_type == AVMEDIA_TYPE_DATA && st->codecpar->codec_id == AV_CODEC_ID_TIMED_ID3) { - *q++ = 0xbd; + *q++ = STREAM_ID_PRIVATE_STREAM_1; } else if (st->codecpar->codec_type == AVMEDIA_TYPE_DATA) { - *q++ = stream_id != -1 ? stream_id : 0xfc; + *q++ = stream_id != -1 ? stream_id : STREAM_ID_METADATA_STREAM; - if (stream_id == 0xbd) /* asynchronous KLV */ + if (stream_id == STREAM_ID_PRIVATE_STREAM_1) /* asynchronous KLV */ pts = dts = AV_NOPTS_VALUE; } else { - *q++ = 0xbd; + *q++ = STREAM_ID_PRIVATE_STREAM_1; if (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE) { if (st->codecpar->codec_id == AV_CODEC_ID_DVB_SUBTITLE) { is_dvb_subtitle = 1; diff --git a/externals/ffmpeg/libavformat/mpl2dec.c b/externals/ffmpeg/libavformat/mpl2dec.c index bea258d9e..38445c7aa 100755 --- a/externals/ffmpeg/libavformat/mpl2dec.c +++ b/externals/ffmpeg/libavformat/mpl2dec.c @@ -83,7 +83,6 @@ static int mpl2_read_header(AVFormatContext *s) { MPL2Context *mpl2 = s->priv_data; AVStream *st = avformat_new_stream(s, NULL); - int res = 0; if (!st) return AVERROR(ENOMEM); @@ -122,7 +121,7 @@ static int mpl2_read_header(AVFormatContext *s) } ff_subtitles_queue_finalize(s, &mpl2->q); - return res; + return 0; } static int mpl2_read_packet(AVFormatContext *s, AVPacket *pkt) diff --git a/externals/ffmpeg/libavformat/options.c b/externals/ffmpeg/libavformat/options.c index e14510504..3160904fd 100755 --- a/externals/ffmpeg/libavformat/options.c +++ b/externals/ffmpeg/libavformat/options.c @@ -21,6 +21,7 @@ #include "avio_internal.h" #include "internal.h" +#include "libavutil/avassert.h" #include "libavutil/internal.h" #include "libavutil/opt.h" @@ -53,6 +54,8 @@ static void *format_child_next(void *obj, void *prev) return NULL; } +#if FF_API_CHILD_CLASS_NEXT +FF_DISABLE_DEPRECATION_WARNINGS static const AVClass *format_child_class_next(const AVClass *prev) { AVInputFormat *ifmt = NULL; @@ -80,6 +83,64 @@ static const AVClass *format_child_class_next(const AVClass *prev) return NULL; } +FF_ENABLE_DEPRECATION_WARNINGS +#endif + +enum { + CHILD_CLASS_ITER_AVIO = 0, + CHILD_CLASS_ITER_MUX, + CHILD_CLASS_ITER_DEMUX, + CHILD_CLASS_ITER_DONE, + +}; + +#define ITER_STATE_SHIFT 16 + +static const AVClass *format_child_class_iterate(void **iter) +{ + // we use the low 16 bits of iter as the value to be passed to + // av_(de)muxer_iterate() + void *val = (void*)(((uintptr_t)*iter) & ((1 << ITER_STATE_SHIFT) - 1)); + unsigned int state = ((uintptr_t)*iter) >> ITER_STATE_SHIFT; + const AVClass *ret = NULL; + + if (state == CHILD_CLASS_ITER_AVIO) { + ret = &ff_avio_class; + state++; + goto finish; + } + + if (state == CHILD_CLASS_ITER_MUX) { + const AVOutputFormat *ofmt; + + while ((ofmt = av_muxer_iterate(&val))) { + ret = ofmt->priv_class; + if (ret) + goto finish; + } + + val = NULL; + state++; + } + + if (state == CHILD_CLASS_ITER_DEMUX) { + const AVInputFormat *ifmt; + + while ((ifmt = av_demuxer_iterate(&val))) { + ret = ifmt->priv_class; + if (ret) + goto finish; + } + val = NULL; + state++; + } + +finish: + // make sure none av_(de)muxer_iterate does not set the high bits of val + av_assert0(!((uintptr_t)val >> ITER_STATE_SHIFT)); + *iter = (void*)((uintptr_t)val | (state << ITER_STATE_SHIFT)); + return ret; +} static AVClassCategory get_category(void *ptr) { @@ -94,7 +155,10 @@ static const AVClass av_format_context_class = { .option = avformat_options, .version = LIBAVUTIL_VERSION_INT, .child_next = format_child_next, +#if FF_API_CHILD_CLASS_NEXT .child_class_next = format_child_class_next, +#endif + .child_class_iterate = format_child_class_iterate, .category = AV_CLASS_CATEGORY_MUXER, .get_category = get_category, }; diff --git a/externals/ffmpeg/libavformat/pjsdec.c b/externals/ffmpeg/libavformat/pjsdec.c index e30c23d83..1f1d51c40 100755 --- a/externals/ffmpeg/libavformat/pjsdec.c +++ b/externals/ffmpeg/libavformat/pjsdec.c @@ -67,7 +67,6 @@ static int pjs_read_header(AVFormatContext *s) { PJSContext *pjs = s->priv_data; AVStream *st = avformat_new_stream(s, NULL); - int res = 0; if (!st) return AVERROR(ENOMEM); @@ -105,7 +104,7 @@ static int pjs_read_header(AVFormatContext *s) } ff_subtitles_queue_finalize(s, &pjs->q); - return res; + return 0; } static int pjs_read_packet(AVFormatContext *s, AVPacket *pkt) diff --git a/externals/ffmpeg/libavformat/protocols.c b/externals/ffmpeg/libavformat/protocols.c index f1b8eab0f..7df18fbb3 100755 --- a/externals/ffmpeg/libavformat/protocols.c +++ b/externals/ffmpeg/libavformat/protocols.c @@ -73,6 +73,7 @@ extern const URLProtocol ff_libzmq_protocol; #include "libavformat/protocol_list.c" +#if FF_API_CHILD_CLASS_NEXT const AVClass *ff_urlcontext_child_class_next(const AVClass *prev) { int i; @@ -91,7 +92,22 @@ const AVClass *ff_urlcontext_child_class_next(const AVClass *prev) return url_protocols[i]->priv_data_class; return NULL; } +#endif +const AVClass *ff_urlcontext_child_class_iterate(void **iter) +{ + const AVClass *ret = NULL; + uintptr_t i; + + for (i = (uintptr_t)*iter; url_protocols[i]; i++) { + ret = url_protocols[i]->priv_data_class; + if (ret) + break; + } + + *iter = (void*)(uintptr_t)(url_protocols[i] ? i + 1 : i); + return ret; +} const char *avio_enum_protocols(void **opaque, int output) { diff --git a/externals/ffmpeg/libavformat/rtpenc.c b/externals/ffmpeg/libavformat/rtpenc.c index 63047becc..9ef7e9094 100755 --- a/externals/ffmpeg/libavformat/rtpenc.c +++ b/externals/ffmpeg/libavformat/rtpenc.c @@ -589,7 +589,7 @@ static int rtp_write_packet(AVFormatContext *s1, AVPacket *pkt) break; case AV_CODEC_ID_H263: if (s->flags & FF_RTP_FLAG_RFC2190) { - int mb_info_size = 0; + int mb_info_size; const uint8_t *mb_info = av_packet_get_side_data(pkt, AV_PKT_DATA_H263_MB_INFO, &mb_info_size); diff --git a/externals/ffmpeg/libavformat/sccdec.c b/externals/ffmpeg/libavformat/sccdec.c index df4c94a6e..751dee7c6 100755 --- a/externals/ffmpeg/libavformat/sccdec.c +++ b/externals/ffmpeg/libavformat/sccdec.c @@ -63,10 +63,9 @@ static int scc_read_header(AVFormatContext *s) { SCCContext *scc = s->priv_data; AVStream *st = avformat_new_stream(s, NULL); - char line[4096], line2[4096]; - int64_t ts_start, ts_end; - int count = 0, ret = 0; - ptrdiff_t len2, len; + char line2[4096], line[4096]; + int64_t pos, ts, next_ts = AV_NOPTS_VALUE; + ptrdiff_t len; uint8_t out[4096]; FFTextReader tr; @@ -78,83 +77,104 @@ static int scc_read_header(AVFormatContext *s) st->codecpar->codec_type = AVMEDIA_TYPE_SUBTITLE; st->codecpar->codec_id = AV_CODEC_ID_EIA_608; - while (!ff_text_eof(&tr)) { - int64_t current_pos, next_pos; + while (!ff_text_eof(&tr) || next_ts == AV_NOPTS_VALUE || line2[0]) { char *saveptr = NULL, *lline; - int hh1, mm1, ss1, fs1, i; - int hh2, mm2, ss2, fs2; + int hh, mm, ss, fs, i; AVPacket *sub; - if (count == 0) { - current_pos = ff_text_pos(&tr); + if (next_ts == AV_NOPTS_VALUE) { while (!ff_text_eof(&tr)) { len = ff_subtitles_read_line(&tr, line, sizeof(line)); - if (len > 13) + if (len <= 13) + continue; + if (!strncmp(line, "Scenarist_SCC V1.0", 18)) + continue; + if (av_sscanf(line, "%d:%d:%d%*[:;]%d", &hh, &mm, &ss, &fs) == 4) + break; + } + + ts = (hh * 3600LL + mm * 60LL + ss) * 1000LL + fs * 33; + + while (!ff_text_eof(&tr)) { + len = ff_subtitles_read_line(&tr, line2, sizeof(line2)); + if (len <= 13) + continue; + + if (av_sscanf(line2, "%d:%d:%d%*[:;]%d", &hh, &mm, &ss, &fs) == 4) + break; + } + } else { + memmove(line, line2, sizeof(line)); + line2[0] = 0; + + while (!ff_text_eof(&tr)) { + len = ff_subtitles_read_line(&tr, line2, sizeof(line2)); + if (len <= 13) + continue; + + if (av_sscanf(line2, "%d:%d:%d%*[:;]%d", &hh, &mm, &ss, &fs) == 4) break; } } - if (!strncmp(line, "Scenarist_SCC V1.0", 18)) - continue; - if (av_sscanf(line, "%d:%d:%d%*[:;]%d", &hh1, &mm1, &ss1, &fs1) != 4) - continue; + next_ts = (hh * 3600LL + mm * 60LL + ss) * 1000LL + fs * 33; - ts_start = (hh1 * 3600LL + mm1 * 60LL + ss1) * 1000LL + fs1 * 33; - - next_pos = ff_text_pos(&tr); - while (!ff_text_eof(&tr)) { - len2 = ff_subtitles_read_line(&tr, line2, sizeof(line2)); - if (len2 > 13) - break; - } - if (av_sscanf(line2, "%d:%d:%d%*[:;]%d", &hh2, &mm2, &ss2, &fs2) != 4) - continue; - - ts_end = (hh2 * 3600LL + mm2 * 60LL + ss2) * 1000LL + fs2 * 33; - count++; - -try_again: + pos = ff_text_pos(&tr); lline = (char *)&line; lline += 12; for (i = 0; i < 4095; i += 3) { char *ptr = av_strtok(lline, " ", &saveptr); char c1, c2, c3, c4; + uint8_t o1, o2; if (!ptr) break; if (av_sscanf(ptr, "%c%c%c%c", &c1, &c2, &c3, &c4) != 4) break; + o1 = convert(c2) | (convert(c1) << 4); + o2 = convert(c4) | (convert(c3) << 4); lline = NULL; + + if (i > 12 && o1 == 0x94 && o2 == 0x20 && saveptr && + (av_strncasecmp(saveptr, "942f", 4) && !av_strncasecmp(saveptr, "942c", 4))) { + + out[i] = 0; + + sub = ff_subtitles_queue_insert(&scc->q, out, i, 0); + if (!sub) + goto fail; + + sub->pos = pos; + pos += i; + sub->pts = ts; + sub->duration = i * 11; + ts += sub->duration; + i = 0; + } + out[i+0] = 0xfc; - out[i+1] = convert(c2) | (convert(c1) << 4); - out[i+2] = convert(c4) | (convert(c3) << 4); + out[i+1] = o1; + out[i+2] = o2; } + out[i] = 0; sub = ff_subtitles_queue_insert(&scc->q, out, i, 0); if (!sub) goto fail; - sub->pos = current_pos; - sub->pts = ts_start; - sub->duration = ts_end - ts_start; - memmove(line, line2, sizeof(line)); - current_pos = next_pos; - line2[0] = 0; - } - - if (line[0]) { - ts_start = ts_end; - ts_end += 1200; - goto try_again; + sub->pos = pos; + sub->pts = ts; + sub->duration = next_ts - ts; + ts = next_ts; } ff_subtitles_queue_finalize(s, &scc->q); - return ret; + return 0; fail: ff_subtitles_queue_clean(&scc->q); return AVERROR(ENOMEM); diff --git a/externals/ffmpeg/libavformat/sdp.c b/externals/ffmpeg/libavformat/sdp.c index 2ce1a6226..34e9839b6 100755 --- a/externals/ffmpeg/libavformat/sdp.c +++ b/externals/ffmpeg/libavformat/sdp.c @@ -212,7 +212,7 @@ static char *extradata2psets(AVFormatContext *s, AVCodecParameters *par) p += strlen(p); r = r1; } - if (sps && sps_end - sps >= 4 && p - psets <= MAX_PSET_SIZE - strlen(profile_string) - 7) { + if (sps && sps_end - sps >= 4) { memcpy(p, profile_string, strlen(profile_string)); p += strlen(p); ff_data_to_hex(p, sps + 1, 3, 0); diff --git a/externals/ffmpeg/libavformat/segment.c b/externals/ffmpeg/libavformat/segment.c index 2ff2b5372..f67456fa5 100755 --- a/externals/ffmpeg/libavformat/segment.c +++ b/externals/ffmpeg/libavformat/segment.c @@ -873,7 +873,7 @@ static int seg_write_packet(AVFormatContext *s, AVPacket *pkt) return AVERROR(EINVAL); if (!st->codecpar->extradata_size) { - int pkt_extradata_size = 0; + int pkt_extradata_size; uint8_t *pkt_extradata = av_packet_get_side_data(pkt, AV_PKT_DATA_NEW_EXTRADATA, &pkt_extradata_size); if (pkt_extradata && pkt_extradata_size > 0) { ret = ff_alloc_extradata(st->codecpar, pkt_extradata_size); diff --git a/externals/ffmpeg/libavformat/smacker.c b/externals/ffmpeg/libavformat/smacker.c index 8b1e18581..0ca5a87b8 100755 --- a/externals/ffmpeg/libavformat/smacker.c +++ b/externals/ffmpeg/libavformat/smacker.c @@ -48,16 +48,16 @@ typedef struct SmackerContext { uint32_t *frm_size; uint8_t *frm_flags; /* internal variables */ + int64_t next_frame_pos; int cur_frame; - /* current frame for demuxing */ - uint8_t pal[768]; - int indexes[7]; int videoindex; - uint8_t *bufs[7]; - int buf_sizes[7]; - int stream_id[7]; - int curstream; - int64_t nextpos; + int indexes[7]; + /* current frame for demuxing */ + uint32_t frame_size; + int flags; + int next_audio_index; + int new_palette; + uint8_t pal[768]; int64_t aud_pts[7]; } SmackerContext; @@ -205,85 +205,75 @@ static int smacker_read_header(AVFormatContext *s) avio_rl32(pb); /* padding */ /* setup data */ - smk->frm_size = av_malloc_array(smk->frames, sizeof(*smk->frm_size)); - smk->frm_flags = av_malloc(smk->frames); - if (!smk->frm_size || !smk->frm_flags) { - av_freep(&smk->frm_size); - av_freep(&smk->frm_flags); + st->priv_data = av_malloc_array(smk->frames, sizeof(*smk->frm_size) + + sizeof(*smk->frm_flags)); + if (!st->priv_data) return AVERROR(ENOMEM); - } + smk->frm_size = st->priv_data; + smk->frm_flags = (void*)(smk->frm_size + smk->frames); /* read frame info */ for (i = 0; i < smk->frames; i++) { smk->frm_size[i] = avio_rl32(pb); } - for (i = 0; i < smk->frames; i++) { - smk->frm_flags[i] = avio_r8(pb); + if ((ret = ffio_read_size(pb, smk->frm_flags, smk->frames)) < 0 || + /* load trees to extradata, they will be unpacked by decoder */ + (ret = ffio_read_size(pb, par->extradata + 16, + par->extradata_size - 16)) < 0) { + return ret; } - /* load trees to extradata, they will be unpacked by decoder */ - ret = avio_read(pb, par->extradata + 16, par->extradata_size - 16); - if (ret != par->extradata_size - 16) { - av_freep(&smk->frm_size); - av_freep(&smk->frm_flags); - return AVERROR(EIO); - } - - smk->curstream = -1; - smk->nextpos = avio_tell(pb); - return 0; } - static int smacker_read_packet(AVFormatContext *s, AVPacket *pkt) { SmackerContext *smk = s->priv_data; int flags; int ret; - int i; - int frame_size = 0; - int palchange = 0; if (avio_feof(s->pb) || smk->cur_frame >= smk->frames) return AVERROR_EOF; /* if we demuxed all streams, pass another frame */ - if(smk->curstream < 0) { - avio_seek(s->pb, smk->nextpos, 0); - frame_size = smk->frm_size[smk->cur_frame] & (~3); + if (!smk->next_audio_index) { + smk->frame_size = smk->frm_size[smk->cur_frame] & (~3); + smk->next_frame_pos = avio_tell(s->pb) + smk->frame_size; flags = smk->frm_flags[smk->cur_frame]; + smk->flags = flags >> 1; /* handle palette change event */ - if(flags & SMACKER_PAL){ + if (flags & SMACKER_PAL) { int size, sz, t, off, j, pos; uint8_t *pal = smk->pal; uint8_t oldpal[768]; memcpy(oldpal, pal, 768); size = avio_r8(s->pb); - size = size * 4 - 1; - if(size + 1 > frame_size) - return AVERROR_INVALIDDATA; - frame_size -= size; - frame_size--; + size = size * 4; + if (size > smk->frame_size) { + ret = AVERROR_INVALIDDATA; + goto next_frame; + } + smk->frame_size -= size--; sz = 0; pos = avio_tell(s->pb) + size; - while(sz < 256){ + while (sz < 256) { t = avio_r8(s->pb); - if(t & 0x80){ /* skip palette entries */ - sz += (t & 0x7F) + 1; + if (t & 0x80) { /* skip palette entries */ + sz += (t & 0x7F) + 1; pal += ((t & 0x7F) + 1) * 3; - } else if(t & 0x40){ /* copy with offset */ + } else if (t & 0x40) { /* copy with offset */ off = avio_r8(s->pb); j = (t & 0x3F) + 1; if (off + j > 0x100) { av_log(s, AV_LOG_ERROR, "Invalid palette update, offset=%d length=%d extends beyond palette size\n", off, j); - return AVERROR_INVALIDDATA; + ret = AVERROR_INVALIDDATA; + goto next_frame; } off *= 3; - while(j-- && sz < 256) { + while (j-- && sz < 256) { *pal++ = oldpal[off + 0]; *pal++ = oldpal[off + 1]; *pal++ = oldpal[off + 2]; @@ -298,79 +288,65 @@ static int smacker_read_packet(AVFormatContext *s, AVPacket *pkt) } } avio_seek(s->pb, pos, 0); - palchange |= 1; + smk->new_palette = 1; } - flags >>= 1; - smk->curstream = -1; - /* if audio chunks are present, put them to stack and retrieve later */ - for(i = 0; i < 7; i++) { - if(flags & 1) { - uint32_t size; - int err; - - size = avio_rl32(s->pb) - 4; - if (!size || size + 4LL > frame_size) { - av_log(s, AV_LOG_ERROR, "Invalid audio part size\n"); - return AVERROR_INVALIDDATA; - } - frame_size -= size; - frame_size -= 4; - smk->curstream++; - if ((err = av_reallocp(&smk->bufs[smk->curstream], size)) < 0) { - smk->buf_sizes[smk->curstream] = 0; - return err; - } - smk->buf_sizes[smk->curstream] = size; - ret = avio_read(s->pb, smk->bufs[smk->curstream], size); - if(ret != size) - return AVERROR(EIO); - smk->stream_id[smk->curstream] = smk->indexes[i]; - } - flags >>= 1; - } - if (frame_size < 0 || frame_size >= INT_MAX/2) - return AVERROR_INVALIDDATA; - if ((ret = av_new_packet(pkt, frame_size + 769)) < 0) - return ret; - if(smk->frm_size[smk->cur_frame] & 1) - palchange |= 2; - pkt->data[0] = palchange; - memcpy(pkt->data + 1, smk->pal, 768); - ret = avio_read(s->pb, pkt->data + 769, frame_size); - if(ret != frame_size) - return AVERROR(EIO); - pkt->stream_index = smk->videoindex; - pkt->pts = smk->cur_frame; - pkt->size = ret + 769; - smk->cur_frame++; - smk->nextpos = avio_tell(s->pb); - } else { - if (smk->stream_id[smk->curstream] < 0 || !smk->bufs[smk->curstream]) - return AVERROR_INVALIDDATA; - if ((ret = av_new_packet(pkt, smk->buf_sizes[smk->curstream])) < 0) - return ret; - memcpy(pkt->data, smk->bufs[smk->curstream], smk->buf_sizes[smk->curstream]); - pkt->size = smk->buf_sizes[smk->curstream]; - pkt->stream_index = smk->stream_id[smk->curstream]; - pkt->pts = smk->aud_pts[smk->curstream]; - smk->aud_pts[smk->curstream] += AV_RL32(pkt->data); - smk->curstream--; } - return 0; -} + for (int i = smk->next_audio_index; i < 7; i++) { + if (smk->flags & (1 << i)) { + uint32_t size; -static int smacker_read_close(AVFormatContext *s) -{ - SmackerContext *smk = s->priv_data; - int i; + size = avio_rl32(s->pb); + if ((int)size < 8 || size > smk->frame_size) { + av_log(s, AV_LOG_ERROR, "Invalid audio part size\n"); + ret = AVERROR_INVALIDDATA; + goto next_frame; + } + smk->frame_size -= size; + size -= 4; - for(i = 0; i < 7; i++) - av_freep(&smk->bufs[i]); - av_freep(&smk->frm_size); - av_freep(&smk->frm_flags); + if (smk->indexes[i] < 0) { + avio_skip(s->pb, size); + continue; + } + if ((ret = av_get_packet(s->pb, pkt, size)) != size) { + ret = ret < 0 ? ret : AVERROR_INVALIDDATA; + goto next_frame; + } + pkt->stream_index = smk->indexes[i]; + pkt->pts = smk->aud_pts[i]; + smk->aud_pts[i] += AV_RL32(pkt->data); + smk->next_audio_index = i + 1; + return 0; + } + } + + if (smk->frame_size >= INT_MAX/2) { + ret = AVERROR_INVALIDDATA; + goto next_frame; + } + if ((ret = av_new_packet(pkt, smk->frame_size + 769)) < 0) + goto next_frame; + flags = smk->new_palette; + if (smk->frm_size[smk->cur_frame] & 1) + flags |= 2; + pkt->data[0] = flags; + memcpy(pkt->data + 1, smk->pal, 768); + ret = ffio_read_size(s->pb, pkt->data + 769, smk->frame_size); + if (ret < 0) + goto next_frame; + pkt->stream_index = smk->videoindex; + pkt->pts = smk->cur_frame; + smk->next_audio_index = 0; + smk->new_palette = 0; + smk->cur_frame++; return 0; +next_frame: + avio_seek(s->pb, smk->next_frame_pos, SEEK_SET); + smk->next_audio_index = 0; + smk->cur_frame++; + return ret; } AVInputFormat ff_smacker_demuxer = { @@ -380,5 +356,4 @@ AVInputFormat ff_smacker_demuxer = { .read_probe = smacker_probe, .read_header = smacker_read_header, .read_packet = smacker_read_packet, - .read_close = smacker_read_close, }; diff --git a/externals/ffmpeg/libavformat/smoothstreamingenc.c b/externals/ffmpeg/libavformat/smoothstreamingenc.c index 33bb404f4..ba5cc27ca 100755 --- a/externals/ffmpeg/libavformat/smoothstreamingenc.c +++ b/externals/ffmpeg/libavformat/smoothstreamingenc.c @@ -49,7 +49,6 @@ typedef struct Fragment { typedef struct OutputStream { AVFormatContext *ctx; - int ctx_inited; char dirname[1024]; uint8_t iobuf[32768]; URLContext *out; // Current output stream where all output is written @@ -173,8 +172,6 @@ static void ism_free(AVFormatContext *s) ffurl_closep(&os->out); ffurl_closep(&os->out2); ffurl_closep(&os->tail_out); - if (os->ctx && os->ctx_inited) - av_write_trailer(os->ctx); if (os->ctx && os->ctx->pb) avio_context_free(&os->ctx->pb); avformat_free_context(os->ctx); @@ -289,21 +286,18 @@ static int ism_write_header(AVFormatContext *s) ff_const59 AVOutputFormat *oformat; if (mkdir(s->url, 0777) == -1 && errno != EEXIST) { - ret = AVERROR(errno); av_log(s, AV_LOG_ERROR, "mkdir failed\n"); - goto fail; + return AVERROR(errno); } oformat = av_guess_format("ismv", NULL, NULL); if (!oformat) { - ret = AVERROR_MUXER_NOT_FOUND; - goto fail; + return AVERROR_MUXER_NOT_FOUND; } c->streams = av_mallocz_array(s->nb_streams, sizeof(*c->streams)); if (!c->streams) { - ret = AVERROR(ENOMEM); - goto fail; + return AVERROR(ENOMEM); } for (i = 0; i < s->nb_streams; i++) { @@ -321,22 +315,21 @@ static int ism_write_header(AVFormatContext *s) } if (mkdir(os->dirname, 0777) == -1 && errno != EEXIST) { - ret = AVERROR(errno); av_log(s, AV_LOG_ERROR, "mkdir failed\n"); - goto fail; + return AVERROR(errno); } os->ctx = ctx = avformat_alloc_context(); - if (!ctx || ff_copy_whiteblacklists(ctx, s) < 0) { - ret = AVERROR(ENOMEM); - goto fail; + if (!ctx) { + return AVERROR(ENOMEM); } + if ((ret = ff_copy_whiteblacklists(ctx, s)) < 0) + return ret; ctx->oformat = oformat; ctx->interrupt_callback = s->interrupt_callback; if (!(st = avformat_new_stream(ctx, NULL))) { - ret = AVERROR(ENOMEM); - goto fail; + return AVERROR(ENOMEM); } avcodec_parameters_copy(st->codecpar, s->streams[i]->codecpar); st->sample_aspect_ratio = s->streams[i]->sample_aspect_ratio; @@ -344,8 +337,7 @@ static int ism_write_header(AVFormatContext *s) ctx->pb = avio_alloc_context(os->iobuf, sizeof(os->iobuf), AVIO_FLAG_WRITE, os, NULL, ism_write, ism_seek); if (!ctx->pb) { - ret = AVERROR(ENOMEM); - goto fail; + return AVERROR(ENOMEM); } av_dict_set_int(&opts, "ism_lookahead", c->lookahead_count, 0); @@ -353,9 +345,8 @@ static int ism_write_header(AVFormatContext *s) ret = avformat_write_header(ctx, &opts); av_dict_free(&opts); if (ret < 0) { - goto fail; + return ret; } - os->ctx_inited = 1; avio_flush(ctx->pb); s->streams[i]->time_base = st->time_base; if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) { @@ -367,8 +358,7 @@ static int ism_write_header(AVFormatContext *s) os->fourcc = "WVC1"; } else { av_log(s, AV_LOG_ERROR, "Unsupported video codec\n"); - ret = AVERROR(EINVAL); - goto fail; + return AVERROR(EINVAL); } } else { c->has_audio = 1; @@ -381,8 +371,7 @@ static int ism_write_header(AVFormatContext *s) os->audio_tag = 0x0162; } else { av_log(s, AV_LOG_ERROR, "Unsupported audio codec\n"); - ret = AVERROR(EINVAL); - goto fail; + return AVERROR(EINVAL); } os->packet_size = st->codecpar->block_align ? st->codecpar->block_align : 4; } @@ -391,15 +380,13 @@ static int ism_write_header(AVFormatContext *s) if (!c->has_video && c->min_frag_duration <= 0) { av_log(s, AV_LOG_WARNING, "no video stream and no min frag duration set\n"); - ret = AVERROR(EINVAL); - goto fail; + return AVERROR(EINVAL); } ret = write_manifest(s, 0); + if (ret < 0) + return ret; -fail: - if (ret) - ism_free(s); - return ret; + return 0; } static int parse_fragment(AVFormatContext *s, const char *filename, int64_t *start_ts, int64_t *duration, int64_t *moof_size, int64_t size) @@ -628,7 +615,6 @@ static int ism_write_trailer(AVFormatContext *s) rmdir(s->url); } - ism_free(s); return 0; } @@ -661,5 +647,6 @@ AVOutputFormat ff_smoothstreaming_muxer = { .write_header = ism_write_header, .write_packet = ism_write_packet, .write_trailer = ism_write_trailer, + .deinit = ism_free, .priv_class = &ism_class, }; diff --git a/externals/ffmpeg/libavformat/url.h b/externals/ffmpeg/libavformat/url.h index 4750bfff8..de0d30aca 100755 --- a/externals/ffmpeg/libavformat/url.h +++ b/externals/ffmpeg/libavformat/url.h @@ -322,7 +322,11 @@ void ff_make_absolute_url(char *buf, int size, const char *base, */ AVIODirEntry *ff_alloc_dir_entry(void); +#if FF_API_CHILD_CLASS_NEXT const AVClass *ff_urlcontext_child_class_next(const AVClass *prev); +#endif + +const AVClass *ff_urlcontext_child_class_iterate(void **iter); /** * Construct a list of protocols matching a given whitelist and/or blacklist. diff --git a/externals/ffmpeg/libavformat/utils.c b/externals/ffmpeg/libavformat/utils.c index ba8aaebfb..807d9f10c 100755 --- a/externals/ffmpeg/libavformat/utils.c +++ b/externals/ffmpeg/libavformat/utils.c @@ -4132,8 +4132,8 @@ FF_ENABLE_DEPRECATION_WARNINGS avcodec_string(buf, sizeof(buf), st->internal->avctx, 0); av_log(ic, AV_LOG_WARNING, "Could not find codec parameters for stream %d (%s): %s\n" - "Consider increasing the value for the 'analyzeduration' and 'probesize' options\n", - i, buf, errmsg); + "Consider increasing the value for the 'analyzeduration' (%"PRId64") and 'probesize' (%"PRId64") options\n", + i, buf, errmsg, ic->max_analyze_duration, ic->probesize); } else { ret = 0; } diff --git a/externals/ffmpeg/libavformat/version.h b/externals/ffmpeg/libavformat/version.h index 13c8a615a..75c03fde0 100755 --- a/externals/ffmpeg/libavformat/version.h +++ b/externals/ffmpeg/libavformat/version.h @@ -32,7 +32,7 @@ // Major bumping may affect Ticket5467, 5421, 5451(compatibility with Chromium) // Also please add any ticket numbers that you believe might be affected here #define LIBAVFORMAT_VERSION_MAJOR 58 -#define LIBAVFORMAT_VERSION_MINOR 45 +#define LIBAVFORMAT_VERSION_MINOR 48 #define LIBAVFORMAT_VERSION_MICRO 100 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ diff --git a/externals/ffmpeg/libavformat/webvttdec.c b/externals/ffmpeg/libavformat/webvttdec.c index bd3d45b38..8d2fdfed3 100755 --- a/externals/ffmpeg/libavformat/webvttdec.c +++ b/externals/ffmpeg/libavformat/webvttdec.c @@ -125,7 +125,7 @@ static int webvtt_read_header(AVFormatContext *s) break; /* optional cue settings */ - p += strcspn(p, "\n\t "); + p += strcspn(p, "\n\r\t "); while (*p == '\t' || *p == ' ') p++; settings = p; diff --git a/externals/ffmpeg/libavutil/frame.c b/externals/ffmpeg/libavutil/frame.c index 2e952edd2..9884eae05 100755 --- a/externals/ffmpeg/libavutil/frame.c +++ b/externals/ffmpeg/libavutil/frame.c @@ -851,6 +851,7 @@ const char *av_frame_side_data_name(enum AVFrameSideDataType type) case AV_FRAME_DATA_DYNAMIC_HDR_PLUS: return "HDR Dynamic Metadata SMPTE2094-40 (HDR10+)"; case AV_FRAME_DATA_REGIONS_OF_INTEREST: return "Regions Of Interest"; case AV_FRAME_DATA_VIDEO_ENC_PARAMS: return "Video encoding parameters"; + case AV_FRAME_DATA_SEI_UNREGISTERED: return "H.26[45] User Data Unregistered SEI message"; } return NULL; } diff --git a/externals/ffmpeg/libavutil/frame.h b/externals/ffmpeg/libavutil/frame.h index fc67db0f6..3fb8c56be 100755 --- a/externals/ffmpeg/libavutil/frame.h +++ b/externals/ffmpeg/libavutil/frame.h @@ -184,6 +184,14 @@ enum AVFrameSideDataType { * Encoding parameters for a video frame, as described by AVVideoEncParams. */ AV_FRAME_DATA_VIDEO_ENC_PARAMS, + + /** + * User data unregistered metadata associated with a video frame. + * This is the H.26[45] UDU SEI message, and shouldn't be used for any other purpose + * The data is stored as uint8_t in AVFrameSideData.data which is 16 bytes of + * uuid_iso_iec_11578 followed by AVFrameSideData.size - 16 bytes of user_data_payload_byte. + */ + AV_FRAME_DATA_SEI_UNREGISTERED, }; enum AVActiveFormatDescription { diff --git a/externals/ffmpeg/libavutil/hwcontext_vaapi.c b/externals/ffmpeg/libavutil/hwcontext_vaapi.c index 5c4f5de04..b31cf9585 100755 --- a/externals/ffmpeg/libavutil/hwcontext_vaapi.c +++ b/externals/ffmpeg/libavutil/hwcontext_vaapi.c @@ -136,6 +136,9 @@ static const VAAPIFormatDescriptor vaapi_format_map[] = { #endif MAP(ARGB, RGB32, ARGB, 0), MAP(XRGB, RGB32, 0RGB, 0), +#ifdef VA_FOURCC_X2R10G10B10 + MAP(X2R10G10B10, RGB32_10, X2RGB10, 0), +#endif }; #undef MAP diff --git a/externals/ffmpeg/libavutil/hwcontext_vdpau.c b/externals/ffmpeg/libavutil/hwcontext_vdpau.c index 6b8c1d5f7..dbef5495a 100755 --- a/externals/ffmpeg/libavutil/hwcontext_vdpau.c +++ b/externals/ffmpeg/libavutil/hwcontext_vdpau.c @@ -39,8 +39,8 @@ typedef struct VDPAUDeviceContext { VdpVideoSurfaceCreate *surf_create; VdpVideoSurfaceDestroy *surf_destroy; - enum AVPixelFormat *pix_fmts[3]; - int nb_pix_fmts[3]; + enum AVPixelFormat *pix_fmts[8]; + int nb_pix_fmts[8]; } VDPAUDeviceContext; typedef struct VDPAUFramesContext { @@ -61,6 +61,10 @@ typedef struct VDPAUPixFmtMap { static const VDPAUPixFmtMap pix_fmts_420[] = { { VDP_YCBCR_FORMAT_NV12, AV_PIX_FMT_NV12 }, { VDP_YCBCR_FORMAT_YV12, AV_PIX_FMT_YUV420P }, +#ifdef VDP_YCBCR_FORMAT_P016 + { VDP_YCBCR_FORMAT_P016, AV_PIX_FMT_P016 }, + { VDP_YCBCR_FORMAT_P010, AV_PIX_FMT_P010 }, +#endif { 0, AV_PIX_FMT_NONE, }, }; @@ -75,6 +79,9 @@ static const VDPAUPixFmtMap pix_fmts_422[] = { static const VDPAUPixFmtMap pix_fmts_444[] = { #ifdef VDP_YCBCR_FORMAT_Y_U_V_444 { VDP_YCBCR_FORMAT_Y_U_V_444, AV_PIX_FMT_YUV444P }, +#endif +#ifdef VDP_YCBCR_FORMAT_P016 + {VDP_YCBCR_FORMAT_Y_U_V_444_16, AV_PIX_FMT_YUV444P16}, #endif { 0, AV_PIX_FMT_NONE, }, }; @@ -87,6 +94,13 @@ static const struct { { VDP_CHROMA_TYPE_420, AV_PIX_FMT_YUV420P, pix_fmts_420 }, { VDP_CHROMA_TYPE_422, AV_PIX_FMT_YUV422P, pix_fmts_422 }, { VDP_CHROMA_TYPE_444, AV_PIX_FMT_YUV444P, pix_fmts_444 }, +#ifdef VDP_YCBCR_FORMAT_P016 + { VDP_CHROMA_TYPE_420_16, AV_PIX_FMT_YUV420P10, pix_fmts_420 }, + { VDP_CHROMA_TYPE_420_16, AV_PIX_FMT_YUV420P12, pix_fmts_420 }, + { VDP_CHROMA_TYPE_422_16, AV_PIX_FMT_YUV422P10, pix_fmts_422 }, + { VDP_CHROMA_TYPE_444_16, AV_PIX_FMT_YUV444P10, pix_fmts_444 }, + { VDP_CHROMA_TYPE_444_16, AV_PIX_FMT_YUV444P12, pix_fmts_444 }, +#endif }; static int count_pixfmts(const VDPAUPixFmtMap *map) @@ -354,6 +368,9 @@ static int vdpau_transfer_data_from(AVHWFramesContext *ctx, AVFrame *dst, if ((vdpau_format == VDP_YCBCR_FORMAT_YV12) #ifdef VDP_YCBCR_FORMAT_Y_U_V_444 || (vdpau_format == VDP_YCBCR_FORMAT_Y_U_V_444) +#endif +#ifdef VDP_YCBCR_FORMAT_P016 + || (vdpau_format == VDP_YCBCR_FORMAT_Y_U_V_444_16) #endif ) FFSWAP(void*, data[1], data[2]); diff --git a/externals/ffmpeg/libavutil/internal.h b/externals/ffmpeg/libavutil/internal.h index 4acbcf56c..12f824d97 100755 --- a/externals/ffmpeg/libavutil/internal.h +++ b/externals/ffmpeg/libavutil/internal.h @@ -137,41 +137,8 @@ # define LOCAL_ALIGNED_32(t, v, ...) E1(LOCAL_ALIGNED_A(32, t, v, __VA_ARGS__,,)) #endif -#define FF_ALLOC_OR_GOTO(ctx, p, size, label)\ -{\ - p = av_malloc(size);\ - if (!(p) && (size) != 0) {\ - av_log(ctx, AV_LOG_ERROR, "Cannot allocate memory.\n");\ - goto label;\ - }\ -} - -#define FF_ALLOCZ_OR_GOTO(ctx, p, size, label)\ -{\ - p = av_mallocz(size);\ - if (!(p) && (size) != 0) {\ - av_log(ctx, AV_LOG_ERROR, "Cannot allocate memory.\n");\ - goto label;\ - }\ -} - -#define FF_ALLOC_ARRAY_OR_GOTO(ctx, p, nelem, elsize, label)\ -{\ - p = av_malloc_array(nelem, elsize);\ - if (!p) {\ - av_log(ctx, AV_LOG_ERROR, "Cannot allocate memory.\n");\ - goto label;\ - }\ -} - -#define FF_ALLOCZ_ARRAY_OR_GOTO(ctx, p, nelem, elsize, label)\ -{\ - p = av_mallocz_array(nelem, elsize);\ - if (!p) {\ - av_log(ctx, AV_LOG_ERROR, "Cannot allocate memory.\n");\ - goto label;\ - }\ -} +#define FF_ALLOC_TYPED_ARRAY(p, nelem) (p = av_malloc_array(nelem, sizeof(*p))) +#define FF_ALLOCZ_TYPED_ARRAY(p, nelem) (p = av_mallocz_array(nelem, sizeof(*p))) #include "libm.h" @@ -353,7 +320,8 @@ void ff_check_pixfmt_descriptors(void); /** * Set a dictionary value to an ISO-8601 compliant timestamp string. * - * @param s AVFormatContext + * @param dict pointer to a pointer to a dictionary struct. If *dict is NULL + * a dictionary struct is allocated and put in *dict. * @param key metadata key * @param timestamp unix timestamp in microseconds * @return <0 on error diff --git a/externals/ffmpeg/libavutil/log.h b/externals/ffmpeg/libavutil/log.h index 9c14188a9..8edd6bbf2 100755 --- a/externals/ffmpeg/libavutil/log.h +++ b/externals/ffmpeg/libavutil/log.h @@ -112,6 +112,7 @@ typedef struct AVClass { */ void* (*child_next)(void *obj, void *prev); +#if FF_API_CHILD_CLASS_NEXT /** * Return an AVClass corresponding to the next potential * AVOptions-enabled child. @@ -120,7 +121,9 @@ typedef struct AVClass { * child_next iterates over _already existing_ objects, while * child_class_next iterates over _all possible_ children. */ + attribute_deprecated const struct AVClass* (*child_class_next)(const struct AVClass *prev); +#endif /** * Category used for visualization (like color) @@ -140,6 +143,21 @@ typedef struct AVClass { * available since version (52.12) */ int (*query_ranges)(struct AVOptionRanges **, void *obj, const char *key, int flags); + + /** + * Iterate over the AVClasses corresponding to potential AVOptions-enabled + * children. + * + * @param iter pointer to opaque iteration state. The caller must initialize + * *iter to NULL before the first call. + * @return AVClass for the next AVOptions-enabled child or NULL if there are + * no more such children. + * + * @note The difference between child_next and this is that child_next + * iterates over _already existing_ objects, while child_class_iterate + * iterates over _all possible_ children. + */ + const struct AVClass* (*child_class_iterate)(void **iter); } AVClass; /** diff --git a/externals/ffmpeg/libavutil/opt.c b/externals/ffmpeg/libavutil/opt.c index 423313bce..c8413fa5e 100755 --- a/externals/ffmpeg/libavutil/opt.c +++ b/externals/ffmpeg/libavutil/opt.c @@ -1679,8 +1679,9 @@ const AVOption *av_opt_find2(void *obj, const char *name, const char *unit, if (search_flags & AV_OPT_SEARCH_CHILDREN) { if (search_flags & AV_OPT_SEARCH_FAKE_OBJ) { - const AVClass *child = NULL; - while (child = av_opt_child_class_next(c, child)) + void *iter = NULL; + const AVClass *child; + while (child = av_opt_child_class_iterate(c, &iter)) if (o = av_opt_find2(&child, name, unit, opt_flags, search_flags, NULL)) return o; } else { @@ -1715,12 +1716,31 @@ void *av_opt_child_next(void *obj, void *prev) return NULL; } +#if FF_API_CHILD_CLASS_NEXT +FF_DISABLE_DEPRECATION_WARNINGS const AVClass *av_opt_child_class_next(const AVClass *parent, const AVClass *prev) { if (parent->child_class_next) return parent->child_class_next(prev); return NULL; } +FF_ENABLE_DEPRECATION_WARNINGS +#endif + +const AVClass *av_opt_child_class_iterate(const AVClass *parent, void **iter) +{ + if (parent->child_class_iterate) + return parent->child_class_iterate(iter); +#if FF_API_CHILD_CLASS_NEXT +FF_DISABLE_DEPRECATION_WARNINGS + if (parent->child_class_next) { + *iter = parent->child_class_next(*iter); + return *iter; + } +FF_ENABLE_DEPRECATION_WARNINGS +#endif + return NULL; +} void *av_opt_ptr(const AVClass *class, void *obj, const char *name) { @@ -2100,6 +2120,8 @@ int av_opt_serialize(void *obj, int opt_flags, int flags, char **buffer, av_freep(&buf); } } - av_bprint_finalize(&bprint, buffer); + ret = av_bprint_finalize(&bprint, buffer); + if (ret < 0) + return ret; return 0; } diff --git a/externals/ffmpeg/libavutil/opt.h b/externals/ffmpeg/libavutil/opt.h index e46119572..8dc020a82 100755 --- a/externals/ffmpeg/libavutil/opt.h +++ b/externals/ffmpeg/libavutil/opt.h @@ -114,7 +114,7 @@ * libavcodec exports generic options, while its priv_data field exports * codec-specific options). In such a case, it is possible to set up the * parent struct to export a child's options. To do that, simply - * implement AVClass.child_next() and AVClass.child_class_next() in the + * implement AVClass.child_next() and AVClass.child_class_iterate() in the * parent struct's AVClass. * Assuming that the test_struct from above now also contains a * child_struct field: @@ -143,23 +143,25 @@ * return t->child_struct; * return NULL * } - * const AVClass child_class_next(const AVClass *prev) + * const AVClass child_class_iterate(void **iter) * { - * return prev ? NULL : &child_class; + * const AVClass *c = *iter ? NULL : &child_class; + * *iter = (void*)(uintptr_t)c; + * return c; * } * @endcode - * Putting child_next() and child_class_next() as defined above into + * Putting child_next() and child_class_iterate() as defined above into * test_class will now make child_struct's options accessible through * test_struct (again, proper setup as described above needs to be done on * child_struct right after it is created). * * From the above example it might not be clear why both child_next() - * and child_class_next() are needed. The distinction is that child_next() - * iterates over actually existing objects, while child_class_next() + * and child_class_iterate() are needed. The distinction is that child_next() + * iterates over actually existing objects, while child_class_iterate() * iterates over all possible child classes. E.g. if an AVCodecContext * was initialized to use a codec which has private options, then its * child_next() will return AVCodecContext.priv_data and finish - * iterating. OTOH child_class_next() on AVCodecContext.av_class will + * iterating. OTOH child_class_iterate() on AVCodecContext.av_class will * iterate over all available codecs with private options. * * @subsection avoptions_implement_named_constants Named constants @@ -194,7 +196,7 @@ * For enumerating there are basically two cases. The first is when you want to * get all options that may potentially exist on the struct and its children * (e.g. when constructing documentation). In that case you should call - * av_opt_child_class_next() recursively on the parent struct's AVClass. The + * av_opt_child_class_iterate() recursively on the parent struct's AVClass. The * second case is when you have an already initialized struct with all its * children and you want to get all options that can be actually written or read * from it. In that case you should call av_opt_child_next() recursively (and @@ -646,13 +648,26 @@ const AVOption *av_opt_next(const void *obj, const AVOption *prev); */ void *av_opt_child_next(void *obj, void *prev); +#if FF_API_CHILD_CLASS_NEXT /** * Iterate over potential AVOptions-enabled children of parent. * * @param prev result of a previous call to this function or NULL * @return AVClass corresponding to next potential child or NULL + * + * @deprecated use av_opt_child_class_iterate */ +attribute_deprecated const AVClass *av_opt_child_class_next(const AVClass *parent, const AVClass *prev); +#endif + +/** + * Iterate over potential AVOptions-enabled children of parent. + * + * @param iter a pointer where iteration state is stored. + * @return AVClass corresponding to next potential child or NULL + */ +const AVClass *av_opt_child_class_iterate(const AVClass *parent, void **iter); /** * @defgroup opt_set_funcs Option setting functions diff --git a/externals/ffmpeg/libavutil/pixdesc.c b/externals/ffmpeg/libavutil/pixdesc.c index 9d61c5256..827471322 100755 --- a/externals/ffmpeg/libavutil/pixdesc.c +++ b/externals/ffmpeg/libavutil/pixdesc.c @@ -252,6 +252,30 @@ static const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = { }, .flags = AV_PIX_FMT_FLAG_RGB, }, + [AV_PIX_FMT_X2RGB10LE] = { + .name = "x2rgb10le", + .nb_components= 3, + .log2_chroma_w= 0, + .log2_chroma_h= 0, + .comp = { + { 0, 4, 2, 4, 10, 3, 9, 2 }, /* R */ + { 0, 4, 1, 2, 10, 3, 9, 3 }, /* G */ + { 0, 4, 0, 0, 10, 3, 9, 4 }, /* B */ + }, + .flags = AV_PIX_FMT_FLAG_RGB, + }, + [AV_PIX_FMT_X2RGB10BE] = { + .name = "x2rgb10be", + .nb_components= 3, + .log2_chroma_w= 0, + .log2_chroma_h= 0, + .comp = { + { 0, 4, 0, 4, 10, 3, 9, 2 }, /* R */ + { 0, 4, 1, 2, 10, 3, 9, 3 }, /* G */ + { 0, 4, 2, 0, 10, 3, 9, 4 }, /* B */ + }, + .flags = AV_PIX_FMT_FLAG_RGB | AV_PIX_FMT_FLAG_BE, + }, [AV_PIX_FMT_YUV422P] = { .name = "yuv422p", .nb_components = 3, diff --git a/externals/ffmpeg/libavutil/pixfmt.h b/externals/ffmpeg/libavutil/pixfmt.h index 1c625cfc8..a46acf3c5 100755 --- a/externals/ffmpeg/libavutil/pixfmt.h +++ b/externals/ffmpeg/libavutil/pixfmt.h @@ -358,6 +358,8 @@ enum AVPixelFormat { 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 + 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 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 }; @@ -447,6 +449,7 @@ enum AVPixelFormat { #define AV_PIX_FMT_P016 AV_PIX_FMT_NE(P016BE, P016LE) #define AV_PIX_FMT_Y210 AV_PIX_FMT_NE(Y210BE, Y210LE) +#define AV_PIX_FMT_X2RGB10 AV_PIX_FMT_NE(X2RGB10BE, X2RGB10LE) /** * Chromaticity coordinates of the source primaries. diff --git a/externals/ffmpeg/libavutil/timecode.c b/externals/ffmpeg/libavutil/timecode.c index 60077ba0c..cca53d73c 100755 --- a/externals/ffmpeg/libavutil/timecode.c +++ b/externals/ffmpeg/libavutil/timecode.c @@ -81,6 +81,38 @@ uint32_t av_timecode_get_smpte_from_framenum(const AVTimecode *tc, int framenum) (hh % 10); // units of hours } +uint32_t av_timecode_get_smpte(AVRational rate, int drop, int hh, int mm, int ss, int ff) +{ + uint32_t tc = 0; + uint32_t frames; + + /* For SMPTE 12-M timecodes, frame count is a special case if > 30 FPS. + See SMPTE ST 12-1:2014 Sec 12.1 for more info. */ + if (av_cmp_q(rate, (AVRational) {30, 1}) == 1) { + frames = ff / 2; + if (ff % 2 == 1) { + if (av_cmp_q(rate, (AVRational) {50, 1}) == 0) + tc |= (1 << 7); + else + tc |= (1 << 23); + } + } else { + frames = ff; + } + + tc |= drop << 30; + tc |= (frames / 10) << 28; + tc |= (frames % 10) << 24; + tc |= (ss / 10) << 20; + tc |= (ss % 10) << 16; + tc |= (mm / 10) << 12; + tc |= (mm % 10) << 8; + tc |= (hh / 10) << 4; + tc |= (hh % 10); + + return tc; +} + char *av_timecode_make_string(const AVTimecode *tc, char *buf, int framenum) { int fps = tc->fps; diff --git a/externals/ffmpeg/libavutil/timecode.h b/externals/ffmpeg/libavutil/timecode.h index 37c1361bc..ab38e661f 100755 --- a/externals/ffmpeg/libavutil/timecode.h +++ b/externals/ffmpeg/libavutil/timecode.h @@ -70,6 +70,19 @@ int av_timecode_adjust_ntsc_framenum2(int framenum, int fps); */ uint32_t av_timecode_get_smpte_from_framenum(const AVTimecode *tc, int framenum); +/** + * Convert sei info to SMPTE 12M binary representation. + * + * @param rate frame rate in rational form + * @param drop drop flag + * @param hh hour + * @param mm minute + * @param ss second + * @param ff frame number + * @return the SMPTE binary representation + */ +uint32_t av_timecode_get_smpte(AVRational rate, int drop, int hh, int mm, int ss, int ff); + /** * Load timecode string in buf. * diff --git a/externals/ffmpeg/libavutil/version.h b/externals/ffmpeg/libavutil/version.h index 0ff722fbf..3ce9b1831 100755 --- a/externals/ffmpeg/libavutil/version.h +++ b/externals/ffmpeg/libavutil/version.h @@ -79,7 +79,7 @@ */ #define LIBAVUTIL_VERSION_MAJOR 56 -#define LIBAVUTIL_VERSION_MINOR 51 +#define LIBAVUTIL_VERSION_MINOR 55 #define LIBAVUTIL_VERSION_MICRO 100 #define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ @@ -129,7 +129,9 @@ #ifndef FF_API_PSEUDOPAL #define FF_API_PSEUDOPAL (LIBAVUTIL_VERSION_MAJOR < 57) #endif - +#ifndef FF_API_CHILD_CLASS_NEXT +#define FF_API_CHILD_CLASS_NEXT (LIBAVUTIL_VERSION_MAJOR < 57) +#endif /** * @} diff --git a/externals/ffmpeg/libpostproc/version.h b/externals/ffmpeg/libpostproc/version.h index e5de9aefb..9cb610068 100755 --- a/externals/ffmpeg/libpostproc/version.h +++ b/externals/ffmpeg/libpostproc/version.h @@ -29,7 +29,7 @@ #include "libavutil/avutil.h" #define LIBPOSTPROC_VERSION_MAJOR 55 -#define LIBPOSTPROC_VERSION_MINOR 7 +#define LIBPOSTPROC_VERSION_MINOR 8 #define LIBPOSTPROC_VERSION_MICRO 100 #define LIBPOSTPROC_VERSION_INT AV_VERSION_INT(LIBPOSTPROC_VERSION_MAJOR, \ diff --git a/externals/ffmpeg/libswresample/version.h b/externals/ffmpeg/libswresample/version.h index 257739195..fed4fa1fd 100755 --- a/externals/ffmpeg/libswresample/version.h +++ b/externals/ffmpeg/libswresample/version.h @@ -29,7 +29,7 @@ #include "libavutil/avutil.h" #define LIBSWRESAMPLE_VERSION_MAJOR 3 -#define LIBSWRESAMPLE_VERSION_MINOR 7 +#define LIBSWRESAMPLE_VERSION_MINOR 8 #define LIBSWRESAMPLE_VERSION_MICRO 100 #define LIBSWRESAMPLE_VERSION_INT AV_VERSION_INT(LIBSWRESAMPLE_VERSION_MAJOR, \ diff --git a/externals/ffmpeg/libswscale/aarch64/swscale_unscaled.c b/externals/ffmpeg/libswscale/aarch64/swscale_unscaled.c index 551daad9e..c7a2a1037 100755 --- a/externals/ffmpeg/libswscale/aarch64/swscale_unscaled.c +++ b/externals/ffmpeg/libswscale/aarch64/swscale_unscaled.c @@ -42,15 +42,14 @@ static int ifmt##_to_##ofmt##_neon_wrapper(SwsContext *c, const uint8_t *src[], uint8_t *dst[], int dstStride[]) { \ const int16_t yuv2rgb_table[] = { YUV_TO_RGB_TABLE }; \ \ - ff_##ifmt##_to_##ofmt##_neon(c->srcW, srcSliceH, \ - dst[0] + srcSliceY * dstStride[0], dstStride[0], \ - src[0], srcStride[0], \ - src[1], srcStride[1], \ - src[2], srcStride[2], \ - yuv2rgb_table, \ - c->yuv2rgb_y_offset >> 6, \ - c->yuv2rgb_y_coeff); \ - return 0; \ + return ff_##ifmt##_to_##ofmt##_neon(c->srcW, srcSliceH, \ + dst[0] + srcSliceY * dstStride[0], dstStride[0], \ + src[0], srcStride[0], \ + src[1], srcStride[1], \ + src[2], srcStride[2], \ + yuv2rgb_table, \ + c->yuv2rgb_y_offset >> 6, \ + c->yuv2rgb_y_coeff); \ } \ #define DECLARE_FF_YUVX_TO_ALL_RGBX_FUNCS(yuvx) \ @@ -76,14 +75,12 @@ static int ifmt##_to_##ofmt##_neon_wrapper(SwsContext *c, const uint8_t *src[], uint8_t *dst[], int dstStride[]) { \ const int16_t yuv2rgb_table[] = { YUV_TO_RGB_TABLE }; \ \ - ff_##ifmt##_to_##ofmt##_neon(c->srcW, srcSliceH, \ - dst[0] + srcSliceY * dstStride[0], dstStride[0], \ - src[0], srcStride[0], src[1], srcStride[1], \ - yuv2rgb_table, \ - c->yuv2rgb_y_offset >> 6, \ - c->yuv2rgb_y_coeff); \ - \ - return 0; \ + return ff_##ifmt##_to_##ofmt##_neon(c->srcW, srcSliceH, \ + dst[0] + srcSliceY * dstStride[0], dstStride[0], \ + src[0], srcStride[0], src[1], srcStride[1], \ + yuv2rgb_table, \ + c->yuv2rgb_y_offset >> 6, \ + c->yuv2rgb_y_coeff); \ } \ #define DECLARE_FF_NVX_TO_ALL_RGBX_FUNCS(nvx) \ diff --git a/externals/ffmpeg/libswscale/aarch64/yuv2rgb_neon.S b/externals/ffmpeg/libswscale/aarch64/yuv2rgb_neon.S index b7446aa10..f4b220fb6 100755 --- a/externals/ffmpeg/libswscale/aarch64/yuv2rgb_neon.S +++ b/externals/ffmpeg/libswscale/aarch64/yuv2rgb_neon.S @@ -142,6 +142,7 @@ .macro declare_func ifmt ofmt function ff_\ifmt\()_to_\ofmt\()_neon, export=1 load_args_\ifmt + mov w9, w1 1: mov w8, w0 // w8 = width 2: @@ -193,6 +194,7 @@ function ff_\ifmt\()_to_\ofmt\()_neon, export=1 increment_\ifmt subs w1, w1, #1 // height -= 1 b.gt 1b + mov w0, w9 ret endfunc .endm diff --git a/externals/ffmpeg/libswscale/input.c b/externals/ffmpeg/libswscale/input.c index e74cf0413..0bd1aa7bc 100755 --- a/externals/ffmpeg/libswscale/input.c +++ b/externals/ffmpeg/libswscale/input.c @@ -244,7 +244,8 @@ rgb48funcs(bgr, BE, AV_PIX_FMT_BGR48BE) #define input_pixel(i) ((origin == AV_PIX_FMT_RGBA || \ origin == AV_PIX_FMT_BGRA || \ origin == AV_PIX_FMT_ARGB || \ - origin == AV_PIX_FMT_ABGR) \ + origin == AV_PIX_FMT_ABGR || \ + origin == AV_PIX_FMT_X2RGB10) \ ? AV_RN32A(&src[(i) * 4]) \ : (isBE(origin) ? AV_RB16(&src[(i) * 2]) \ : AV_RL16(&src[(i) * 2]))) @@ -391,6 +392,7 @@ rgb16_32_wrapper(AV_PIX_FMT_BGR444BE, bgr12be, 0, 0, 0, 0, 0x000F, 0x00F0, rgb16_32_wrapper(AV_PIX_FMT_RGB565BE, rgb16be, 0, 0, 0, 0, 0xF800, 0x07E0, 0x001F, 0, 5, 11, RGB2YUV_SHIFT + 8) rgb16_32_wrapper(AV_PIX_FMT_RGB555BE, rgb15be, 0, 0, 0, 0, 0x7C00, 0x03E0, 0x001F, 0, 5, 10, RGB2YUV_SHIFT + 7) rgb16_32_wrapper(AV_PIX_FMT_RGB444BE, rgb12be, 0, 0, 0, 0, 0x0F00, 0x00F0, 0x000F, 0, 4, 8, RGB2YUV_SHIFT + 4) +rgb16_32_wrapper(AV_PIX_FMT_X2RGB10LE, rgb30le, 16, 6, 0, 0, 0x3FF00000, 0xFFC00, 0x3FF, 0, 0, 4, RGB2YUV_SHIFT + 6) static void gbr24pToUV_half_c(uint8_t *_dstU, uint8_t *_dstV, const uint8_t *gsrc, const uint8_t *bsrc, const uint8_t *rsrc, @@ -1341,6 +1343,9 @@ av_cold void ff_sws_init_input_funcs(SwsContext *c) case AV_PIX_FMT_RGB444BE: c->chrToYV12 = rgb12beToUV_half_c; break; + case AV_PIX_FMT_X2RGB10LE: + c->chrToYV12 = rgb30leToUV_half_c; + break; } } else { switch (srcFormat) { @@ -1422,6 +1427,9 @@ av_cold void ff_sws_init_input_funcs(SwsContext *c) case AV_PIX_FMT_RGB444BE: c->chrToYV12 = rgb12beToUV_c; break; + case AV_PIX_FMT_X2RGB10LE: + c->chrToYV12 = rgb30leToUV_c; + break; } } @@ -1701,6 +1709,9 @@ av_cold void ff_sws_init_input_funcs(SwsContext *c) case AV_PIX_FMT_Y210LE: c->lumToYV12 = y210le_Y_c; break; + case AV_PIX_FMT_X2RGB10LE: + c->lumToYV12 =rgb30leToY_c; + break; } if (c->needAlpha) { if (is16BPS(srcFormat) || isNBPS(srcFormat)) { diff --git a/externals/ffmpeg/libswscale/output.c b/externals/ffmpeg/libswscale/output.c index e864e515d..4ef436e7e 100755 --- a/externals/ffmpeg/libswscale/output.c +++ b/externals/ffmpeg/libswscale/output.c @@ -180,7 +180,8 @@ yuv2planeX_16_c_template(const int16_t *filter, int filterSize, } } -static void yuv2p016cX_c(SwsContext *c, const int16_t *chrFilter, int chrFilterSize, +static void yuv2p016cX_c(enum AVPixelFormat dstFormat, const uint8_t *chrDither, + const int16_t *chrFilter, int chrFilterSize, const int16_t **chrUSrc, const int16_t **chrVSrc, uint8_t *dest8, int chrDstW) { @@ -188,7 +189,7 @@ static void yuv2p016cX_c(SwsContext *c, const int16_t *chrFilter, int chrFilterS const int32_t **uSrc = (const int32_t **)chrUSrc; const int32_t **vSrc = (const int32_t **)chrVSrc; int shift = 15; - int big_endian = c->dstFormat == AV_PIX_FMT_P016BE; + int big_endian = dstFormat == AV_PIX_FMT_P016BE; int i, j; for (i = 0; i < chrDstW; i++) { @@ -402,12 +403,11 @@ static void yuv2plane1_8_c(const int16_t *src, uint8_t *dest, int dstW, } } -static void yuv2nv12cX_c(SwsContext *c, const int16_t *chrFilter, int chrFilterSize, - const int16_t **chrUSrc, const int16_t **chrVSrc, - uint8_t *dest, int chrDstW) +static void yuv2nv12cX_c(enum AVPixelFormat dstFormat, const uint8_t *chrDither, + const int16_t *chrFilter, int chrFilterSize, + const int16_t **chrUSrc, const int16_t **chrVSrc, + uint8_t *dest, int chrDstW) { - enum AVPixelFormat dstFormat = c->dstFormat; - const uint8_t *chrDither = c->chrDither8; int i; if (dstFormat == AV_PIX_FMT_NV12 || @@ -477,13 +477,14 @@ static void yuv2p010lX_c(const int16_t *filter, int filterSize, } } -static void yuv2p010cX_c(SwsContext *c, const int16_t *chrFilter, int chrFilterSize, +static void yuv2p010cX_c(enum AVPixelFormat dstFormat, const uint8_t *chrDither, + const int16_t *chrFilter, int chrFilterSize, const int16_t **chrUSrc, const int16_t **chrVSrc, uint8_t *dest8, int chrDstW) { uint16_t *dest = (uint16_t*)dest8; int shift = 17; - int big_endian = c->dstFormat == AV_PIX_FMT_P010BE; + int big_endian = dstFormat == AV_PIX_FMT_P010BE; int i, j; for (i = 0; i < chrDstW; i++) { @@ -1602,6 +1603,13 @@ yuv2rgb_write(uint8_t *_dest, int i, int Y1, int Y2, dest[i * 2 + 0] = r[Y1 + dr1] + g[Y1 + dg1] + b[Y1 + db1]; dest[i * 2 + 1] = r[Y2 + dr2] + g[Y2 + dg2] + b[Y2 + db2]; + } else if (target == AV_PIX_FMT_X2RGB10) { + uint32_t *dest = (uint32_t *) _dest; + const uint32_t *r = (const uint32_t *) _r; + const uint32_t *g = (const uint32_t *) _g; + const uint32_t *b = (const uint32_t *) _b; + dest[i * 2 + 0] = r[Y1] + g[Y1] + b[Y1]; + dest[i * 2 + 1] = r[Y2] + g[Y2] + b[Y2]; } else /* 8/4 bits */ { uint8_t *dest = (uint8_t *) _dest; const uint8_t *r = (const uint8_t *) _r; @@ -1839,6 +1847,7 @@ YUV2RGBWRAPPER(yuv2rgb,, 12, AV_PIX_FMT_RGB444, 0) YUV2RGBWRAPPER(yuv2rgb,, 8, AV_PIX_FMT_RGB8, 0) YUV2RGBWRAPPER(yuv2rgb,, 4, AV_PIX_FMT_RGB4, 0) YUV2RGBWRAPPER(yuv2rgb,, 4b, AV_PIX_FMT_RGB4_BYTE, 0) +YUV2RGBWRAPPER(yuv2, rgb, x2rgb10, AV_PIX_FMT_X2RGB10, 0) static av_always_inline void yuv2rgb_write_full(SwsContext *c, uint8_t *dest, int i, int Y, int A, int U, int V, @@ -2974,6 +2983,12 @@ av_cold void ff_sws_init_output_funcs(SwsContext *c, *yuv2packed2 = yuv2rgb4b_2_c; *yuv2packedX = yuv2rgb4b_X_c; break; + case AV_PIX_FMT_X2RGB10LE: + case AV_PIX_FMT_X2RGB10BE: + *yuv2packed1 = yuv2x2rgb10_1_c; + *yuv2packed2 = yuv2x2rgb10_2_c; + *yuv2packedX = yuv2x2rgb10_X_c; + break; } } switch (dstFormat) { diff --git a/externals/ffmpeg/libswscale/swscale_internal.h b/externals/ffmpeg/libswscale/swscale_internal.h index ee46092ff..1a1b6f0de 100755 --- a/externals/ffmpeg/libswscale/swscale_internal.h +++ b/externals/ffmpeg/libswscale/swscale_internal.h @@ -119,7 +119,8 @@ typedef void (*yuv2planarX_fn)(const int16_t *filter, int filterSize, * Write one line of horizontally scaled chroma to interleaved output * with multi-point vertical scaling between input pixels. * - * @param c SWS scaling context + * @param dstFormat destination pixel format + * @param chrDither ordered dither array of type uint8_t and size 8 * @param chrFilter vertical chroma scaling coefficients, 12 bits [0,4096] * @param chrUSrc scaled chroma (U) source data, 15 bits for 8-10-bit * output, 19 bits for 16-bit output (in int32_t) @@ -130,7 +131,8 @@ typedef void (*yuv2planarX_fn)(const int16_t *filter, int filterSize, * output, this is in uint16_t * @param dstW width of chroma planes */ -typedef void (*yuv2interleavedX_fn)(struct SwsContext *c, +typedef void (*yuv2interleavedX_fn)(enum AVPixelFormat dstFormat, + const uint8_t *chrDither, const int16_t *chrFilter, int chrFilterSize, const int16_t **chrUSrc, diff --git a/externals/ffmpeg/libswscale/tests/swscale.c b/externals/ffmpeg/libswscale/tests/swscale.c index 19878a787..693f439bf 100755 --- a/externals/ffmpeg/libswscale/tests/swscale.c +++ b/externals/ffmpeg/libswscale/tests/swscale.c @@ -422,7 +422,9 @@ bad_option: for (y = 0; y < H; y++) for (x = 0; x < W * 4; x++) rgb_data[ x + y * 4 * W] = av_lfg_get(&rand); - sws_scale(sws, rgb_src, rgb_stride, 0, H / 12, (uint8_t * const *) src, stride); + res = sws_scale(sws, rgb_src, rgb_stride, 0, H / 12, (uint8_t * const *) src, stride); + if (res < 0 || res != (H / 12)) + goto error; sws_freeContext(sws); av_free(rgb_data); diff --git a/externals/ffmpeg/libswscale/utils.c b/externals/ffmpeg/libswscale/utils.c index 111062e91..dcd1dbaa7 100755 --- a/externals/ffmpeg/libswscale/utils.c +++ b/externals/ffmpeg/libswscale/utils.c @@ -271,6 +271,7 @@ static const FormatEntry format_entries[] = { [AV_PIX_FMT_NV24] = { 1, 1 }, [AV_PIX_FMT_NV42] = { 1, 1 }, [AV_PIX_FMT_Y210LE] = { 1, 0 }, + [AV_PIX_FMT_X2RGB10LE] = { 1, 1 }, }; int sws_isSupportedInput(enum AVPixelFormat pix_fmt) @@ -352,13 +353,14 @@ static av_cold int initFilter(int16_t **outFilter, int32_t **filterPos, emms_c(); // FIXME should not be required but IS (even for non-MMX versions) // NOTE: the +3 is for the MMX(+1) / SSE(+3) scaler which reads over the end - FF_ALLOC_ARRAY_OR_GOTO(NULL, *filterPos, (dstW + 3), sizeof(**filterPos), fail); + if (!FF_ALLOC_TYPED_ARRAY(*filterPos, dstW + 3)) + goto nomem; if (FFABS(xInc - 0x10000) < 10 && srcPos == dstPos) { // unscaled int i; filterSize = 1; - FF_ALLOCZ_ARRAY_OR_GOTO(NULL, filter, - dstW, sizeof(*filter) * filterSize, fail); + if (!FF_ALLOCZ_TYPED_ARRAY(filter, dstW * filterSize)) + goto nomem; for (i = 0; i < dstW; i++) { filter[i * filterSize] = fone; @@ -368,8 +370,8 @@ static av_cold int initFilter(int16_t **outFilter, int32_t **filterPos, int i; int64_t xDstInSrc; filterSize = 1; - FF_ALLOC_ARRAY_OR_GOTO(NULL, filter, - dstW, sizeof(*filter) * filterSize, fail); + if (!FF_ALLOC_TYPED_ARRAY(filter, dstW * filterSize)) + goto nomem; xDstInSrc = ((dstPos*(int64_t)xInc)>>8) - ((srcPos*0x8000LL)>>7); for (i = 0; i < dstW; i++) { @@ -384,8 +386,8 @@ static av_cold int initFilter(int16_t **outFilter, int32_t **filterPos, int i; int64_t xDstInSrc; filterSize = 2; - FF_ALLOC_ARRAY_OR_GOTO(NULL, filter, - dstW, sizeof(*filter) * filterSize, fail); + if (!FF_ALLOC_TYPED_ARRAY(filter, dstW * filterSize)) + goto nomem; xDstInSrc = ((dstPos*(int64_t)xInc)>>8) - ((srcPos*0x8000LL)>>7); for (i = 0; i < dstW; i++) { @@ -425,9 +427,8 @@ static av_cold int initFilter(int16_t **outFilter, int32_t **filterPos, filterSize = FFMIN(filterSize, srcW - 2); filterSize = FFMAX(filterSize, 1); - FF_ALLOC_ARRAY_OR_GOTO(NULL, filter, - dstW, sizeof(*filter) * filterSize, fail); - + if (!FF_ALLOC_TYPED_ARRAY(filter, dstW * filterSize)) + goto nomem; xDstInSrc = ((dstPos*(int64_t)xInc)>>7) - ((srcPos*0x10000LL)>>7); for (i = 0; i < dstW; i++) { int xx = (xDstInSrc - (filterSize - 2) * (1LL<<16)) / (1 << 17); @@ -525,8 +526,8 @@ static av_cold int initFilter(int16_t **outFilter, int32_t **filterPos, if (dstFilter) filter2Size += dstFilter->length - 1; av_assert0(filter2Size > 0); - FF_ALLOCZ_ARRAY_OR_GOTO(NULL, filter2, dstW, filter2Size * sizeof(*filter2), fail); - + if (!FF_ALLOCZ_TYPED_ARRAY(filter2, dstW * filter2Size)) + goto nomem; for (i = 0; i < dstW; i++) { int j, k; @@ -611,7 +612,7 @@ static av_cold int initFilter(int16_t **outFilter, int32_t **filterPos, av_assert0(filterSize > 0); filter = av_malloc_array(dstW, filterSize * sizeof(*filter)); if (!filter) - goto fail; + goto nomem; if (filterSize >= MAX_FILTER_SIZE * 16 / ((flags & SWS_ACCURATE_RND) ? APCK_SIZE : 16)) { ret = RETCODE_USE_CASCADE; @@ -684,8 +685,8 @@ static av_cold int initFilter(int16_t **outFilter, int32_t **filterPos, // Note the +1 is for the MMX scaler which reads over the end /* align at 16 for AltiVec (needed by hScale_altivec_real) */ - FF_ALLOCZ_ARRAY_OR_GOTO(NULL, *outFilter, - (dstW + 3), *outFilterSize * sizeof(int16_t), fail); + if (!FF_ALLOCZ_TYPED_ARRAY(*outFilter, *outFilterSize * (dstW + 3))) + goto nomem; /* normalize & store in outFilter */ for (i = 0; i < dstW; i++) { @@ -721,10 +722,13 @@ static av_cold int initFilter(int16_t **outFilter, int32_t **filterPos, } ret = 0; - + goto done; +nomem: + ret = AVERROR(ENOMEM); fail: if(ret < 0) av_log(NULL, ret == RETCODE_USE_CASCADE ? AV_LOG_DEBUG : AV_LOG_ERROR, "sws: initFilter failed\n"); +done: av_free(filter); av_free(filter2); return ret; @@ -1417,7 +1421,8 @@ av_cold int sws_init_context(SwsContext *c, SwsFilter *srcFilter, c->chrDstW = AV_CEIL_RSHIFT(dstW, c->chrDstHSubSample); c->chrDstH = AV_CEIL_RSHIFT(dstH, c->chrDstVSubSample); - FF_ALLOCZ_OR_GOTO(c, c->formatConvBuffer, FFALIGN(srcW*2+78, 16) * 2, fail); + if (!FF_ALLOCZ_TYPED_ARRAY(c->formatConvBuffer, FFALIGN(srcW * 2 + 78, 16) * 2)) + goto nomem; c->srcBpc = desc_src->comp[0].depth; if (c->srcBpc < 8) @@ -1486,7 +1491,7 @@ av_cold int sws_init_context(SwsContext *c, SwsFilter *srcFilter, srcW, srcH, tmpFmt, flags, NULL, NULL, c->param); if (!c->cascaded_context[0]) { - return -1; + return AVERROR(ENOMEM); } c->cascaded_context[1] = sws_getContext(srcW, srcH, tmpFmt, @@ -1494,7 +1499,7 @@ av_cold int sws_init_context(SwsContext *c, SwsFilter *srcFilter, flags, srcFilter, dstFilter, c->param); if (!c->cascaded_context[1]) - return -1; + return AVERROR(ENOMEM); c2 = c->cascaded_context[1]; c2->is_internal_gamma = 1; @@ -1507,10 +1512,10 @@ av_cold int sws_init_context(SwsContext *c, SwsFilter *srcFilter, // to properly create the gamma convert FilterDescriptor // we have to re-initialize it ff_free_filters(c2); - if (ff_init_filters(c2) < 0) { + if ((ret = ff_init_filters(c2)) < 0) { sws_freeContext(c2); c->cascaded_context[1] = NULL; - return -1; + return ret; } c->cascaded_context[2] = NULL; @@ -1524,7 +1529,7 @@ av_cold int sws_init_context(SwsContext *c, SwsFilter *srcFilter, dstW, dstH, dstFormat, flags, NULL, NULL, c->param); if (!c->cascaded_context[2]) - return -1; + return AVERROR(ENOMEM); } return 0; } @@ -1543,13 +1548,13 @@ av_cold int sws_init_context(SwsContext *c, SwsFilter *srcFilter, srcW, srcH, tmpFormat, flags, srcFilter, NULL, c->param); if (!c->cascaded_context[0]) - return -1; + return AVERROR(ENOMEM); c->cascaded_context[1] = sws_getContext(srcW, srcH, tmpFormat, dstW, dstH, dstFormat, flags, NULL, dstFilter, c->param); if (!c->cascaded_context[1]) - return -1; + return AVERROR(ENOMEM); return 0; } } @@ -1570,41 +1575,42 @@ av_cold int sws_init_context(SwsContext *c, SwsFilter *srcFilter, if (CONFIG_SWSCALE_ALPHA && isALPHA(srcFormat) && !isALPHA(dstFormat)) { enum AVPixelFormat tmpFormat = alphaless_fmt(srcFormat); - if (tmpFormat != AV_PIX_FMT_NONE && c->alphablend != SWS_ALPHA_BLEND_NONE) - if (!unscaled || - dstFormat != tmpFormat || - usesHFilter || usesVFilter || - c->srcRange != c->dstRange - ) { - c->cascaded_mainindex = 1; - ret = av_image_alloc(c->cascaded_tmp, c->cascaded_tmpStride, - srcW, srcH, tmpFormat, 64); - if (ret < 0) - return ret; + if (tmpFormat != AV_PIX_FMT_NONE && c->alphablend != SWS_ALPHA_BLEND_NONE) { + if (!unscaled || + dstFormat != tmpFormat || + usesHFilter || usesVFilter || + c->srcRange != c->dstRange + ) { + c->cascaded_mainindex = 1; + ret = av_image_alloc(c->cascaded_tmp, c->cascaded_tmpStride, + srcW, srcH, tmpFormat, 64); + if (ret < 0) + return ret; - c->cascaded_context[0] = sws_alloc_set_opts(srcW, srcH, srcFormat, - srcW, srcH, tmpFormat, - flags, c->param); - if (!c->cascaded_context[0]) - return -1; - c->cascaded_context[0]->alphablend = c->alphablend; - ret = sws_init_context(c->cascaded_context[0], NULL , NULL); - if (ret < 0) - return ret; + c->cascaded_context[0] = sws_alloc_set_opts(srcW, srcH, srcFormat, + srcW, srcH, tmpFormat, + flags, c->param); + if (!c->cascaded_context[0]) + return AVERROR(EINVAL); + c->cascaded_context[0]->alphablend = c->alphablend; + ret = sws_init_context(c->cascaded_context[0], NULL , NULL); + if (ret < 0) + return ret; - c->cascaded_context[1] = sws_alloc_set_opts(srcW, srcH, tmpFormat, - dstW, dstH, dstFormat, - flags, c->param); - if (!c->cascaded_context[1]) - return -1; + c->cascaded_context[1] = sws_alloc_set_opts(srcW, srcH, tmpFormat, + dstW, dstH, dstFormat, + flags, c->param); + if (!c->cascaded_context[1]) + return AVERROR(EINVAL); - c->cascaded_context[1]->srcRange = c->srcRange; - c->cascaded_context[1]->dstRange = c->dstRange; - ret = sws_init_context(c->cascaded_context[1], srcFilter , dstFilter); - if (ret < 0) - return ret; + c->cascaded_context[1]->srcRange = c->srcRange; + c->cascaded_context[1]->dstRange = c->dstRange; + ret = sws_init_context(c->cascaded_context[1], srcFilter , dstFilter); + if (ret < 0) + return ret; - return 0; + return 0; + } } } @@ -1657,10 +1663,11 @@ av_cold int sws_init_context(SwsContext *c, SwsFilter *srcFilter, return AVERROR(ENOMEM); } - FF_ALLOCZ_OR_GOTO(c, c->hLumFilter, (dstW / 8 + 8) * sizeof(int16_t), fail); - FF_ALLOCZ_OR_GOTO(c, c->hChrFilter, (c->chrDstW / 4 + 8) * sizeof(int16_t), fail); - FF_ALLOCZ_OR_GOTO(c, c->hLumFilterPos, (dstW / 2 / 8 + 8) * sizeof(int32_t), fail); - FF_ALLOCZ_OR_GOTO(c, c->hChrFilterPos, (c->chrDstW / 2 / 4 + 8) * sizeof(int32_t), fail); + if (!FF_ALLOCZ_TYPED_ARRAY(c->hLumFilter, dstW / 8 + 8) || + !FF_ALLOCZ_TYPED_ARRAY(c->hChrFilter, c->chrDstW / 4 + 8) || + !FF_ALLOCZ_TYPED_ARRAY(c->hLumFilterPos, dstW / 2 / 8 + 8) || + !FF_ALLOCZ_TYPED_ARRAY(c->hChrFilterPos, c->chrDstW / 2 / 4 + 8)) + goto nomem; ff_init_hscaler_mmxext( dstW, c->lumXInc, c->lumMmxextFilterCode, c->hLumFilter, (uint32_t*)c->hLumFilterPos, 8); @@ -1671,6 +1678,7 @@ av_cold int sws_init_context(SwsContext *c, SwsFilter *srcFilter, if ( mprotect(c->lumMmxextFilterCode, c->lumMmxextFilterCodeSize, PROT_EXEC | PROT_READ) == -1 || mprotect(c->chrMmxextFilterCode, c->chrMmxextFilterCodeSize, PROT_EXEC | PROT_READ) == -1) { av_log(c, AV_LOG_ERROR, "mprotect failed, cannot use fast bilinear scaler\n"); + ret = AVERROR(EINVAL); goto fail; } #endif @@ -1728,8 +1736,9 @@ av_cold int sws_init_context(SwsContext *c, SwsFilter *srcFilter, goto fail; #if HAVE_ALTIVEC - FF_ALLOC_OR_GOTO(c, c->vYCoeffsBank, sizeof(vector signed short) * c->vLumFilterSize * c->dstH, fail); - FF_ALLOC_OR_GOTO(c, c->vCCoeffsBank, sizeof(vector signed short) * c->vChrFilterSize * c->chrDstH, fail); + if (!FF_ALLOC_TYPED_ARRAY(c->vYCoeffsBank, c->vLumFilterSize * c->dstH) || + !FF_ALLOC_TYPED_ARRAY(c->vCCoeffsBank, c->vChrFilterSize * c->chrDstH)) + goto nomem; for (i = 0; i < c->vLumFilterSize * c->dstH; i++) { int j; @@ -1748,7 +1757,8 @@ av_cold int sws_init_context(SwsContext *c, SwsFilter *srcFilter, } for (i = 0; i < 4; i++) - FF_ALLOCZ_OR_GOTO(c, c->dither_error[i], (c->dstW+2) * sizeof(int), fail); + if (!FF_ALLOCZ_TYPED_ARRAY(c->dither_error[i], c->dstW + 2)) + goto nomem; c->needAlpha = (CONFIG_SWSCALE_ALPHA && isALPHA(c->srcFormat) && isALPHA(c->dstFormat)) ? 1 : 0; @@ -1838,6 +1848,8 @@ av_cold int sws_init_context(SwsContext *c, SwsFilter *srcFilter, c->swscale = ff_getSwsFunc(c); return ff_init_filters(c); +nomem: + ret = AVERROR(ENOMEM); fail: // FIXME replace things by appropriate error codes if (ret == RETCODE_USE_CASCADE) { int tmpW = sqrt(srcW * (int64_t)dstW); @@ -1859,16 +1871,16 @@ fail: // FIXME replace things by appropriate error codes tmpW, tmpH, tmpFormat, flags, srcFilter, NULL, c->param); if (!c->cascaded_context[0]) - return -1; + return AVERROR(ENOMEM); c->cascaded_context[1] = sws_getContext(tmpW, tmpH, tmpFormat, dstW, dstH, dstFormat, flags, NULL, dstFilter, c->param); if (!c->cascaded_context[1]) - return -1; + return AVERROR(ENOMEM); return 0; } - return -1; + return ret; } SwsContext *sws_alloc_set_opts(int srcW, int srcH, enum AVPixelFormat srcFormat, diff --git a/externals/ffmpeg/libswscale/version.h b/externals/ffmpeg/libswscale/version.h index 3aec51f1b..2b9ea1be9 100755 --- a/externals/ffmpeg/libswscale/version.h +++ b/externals/ffmpeg/libswscale/version.h @@ -27,7 +27,7 @@ #include "libavutil/version.h" #define LIBSWSCALE_VERSION_MAJOR 5 -#define LIBSWSCALE_VERSION_MINOR 7 +#define LIBSWSCALE_VERSION_MINOR 8 #define LIBSWSCALE_VERSION_MICRO 100 #define LIBSWSCALE_VERSION_INT AV_VERSION_INT(LIBSWSCALE_VERSION_MAJOR, \ diff --git a/externals/ffmpeg/libswscale/vscale.c b/externals/ffmpeg/libswscale/vscale.c index 9ed227e90..500217239 100755 --- a/externals/ffmpeg/libswscale/vscale.c +++ b/externals/ffmpeg/libswscale/vscale.c @@ -92,7 +92,7 @@ static int chr_planar_vscale(SwsContext *c, SwsFilterDescriptor *desc, int slice uint16_t *filter = inst->filter[0] + (inst->isMMX ? 0 : chrSliceY * inst->filter_size); if (c->yuv2nv12cX) { - inst->pfn.yuv2interleavedX(c, filter, inst->filter_size, (const int16_t**)src1, (const int16_t**)src2, dst1[0], dstW); + inst->pfn.yuv2interleavedX(c->dstFormat, c->chrDither8, filter, inst->filter_size, (const int16_t**)src1, (const int16_t**)src2, dst1[0], dstW); } else if (inst->filter_size == 1) { inst->pfn.yuv2planar1((const int16_t*)src1[0], dst1[0], dstW, c->chrDither8, 0); inst->pfn.yuv2planar1((const int16_t*)src2[0], dst2[0], dstW, c->chrDither8, 3); diff --git a/externals/ffmpeg/libswscale/x86/output.asm b/externals/ffmpeg/libswscale/x86/output.asm index db3e9934f..7f82665e1 100755 --- a/externals/ffmpeg/libswscale/x86/output.asm +++ b/externals/ffmpeg/libswscale/x86/output.asm @@ -2,6 +2,7 @@ ;* x86-optimized vertical line scaling functions ;* Copyright (c) 2011 Ronald S. Bultje ;* Kieran Kunhya +;* (c) 2020 Nelson Gomez ;* ;* This file is part of FFmpeg. ;* @@ -22,7 +23,7 @@ %include "libavutil/x86/x86util.asm" -SECTION_RODATA +SECTION_RODATA 32 minshort: times 8 dw 0x8000 yuv2yuvX_16_start: times 4 dd 0x4000 - 0x40000000 @@ -34,9 +35,20 @@ pd_4: times 4 dd 4 pd_4min0x40000:times 4 dd 4 - (0x40000) pw_16: times 8 dw 16 pw_32: times 8 dw 32 +pd_255: times 8 dd 255 pw_512: times 8 dw 512 pw_1024: times 8 dw 1024 +yuv2nv12_shuffle_mask: times 2 db 0, 4, 8, 12, \ + -1, -1, -1, -1, \ + -1, -1, -1, -1, \ + -1, -1, -1, -1 +yuv2nv21_shuffle_mask: times 2 db 4, 0, 12, 8, \ + -1, -1, -1, -1, \ + -1, -1, -1, -1, \ + -1, -1, -1, -1 +yuv2nv12_permute_mask: dd 0, 4, 1, 2, 3, 5, 6, 7 + SECTION .text ;----------------------------------------------------------------------------- @@ -423,3 +435,115 @@ yuv2plane1_fn 9, 5, 3 yuv2plane1_fn 10, 5, 3 yuv2plane1_fn 16, 5, 3 %endif + +%undef movsx + +;----------------------------------------------------------------------------- +; AVX2 yuv2nv12cX implementation +; +; void ff_yuv2nv12cX_avx2(enum AVPixelFormat format, const uint8_t *dither, +; const int16_t *filter, int filterSize, +; const int16_t **u, const int16_t **v, +; uint8_t *dst, int dstWidth) +; +; void ff_yuv2nv21cX_avx2(enum AVPixelFormat format, const uint8_t *dither, +; const int16_t *filter, int filterSize, +; const int16_t **u, const int16_t **v, +; uint8_t *dst, int dstWidth) +;----------------------------------------------------------------------------- + +%if ARCH_X86_64 +%macro yuv2nv12cX_fn 1 +cglobal %1cX, 8, 11, 13, tmp1, dither, filter, filterSize, u, v, dst, dstWidth + + mov tmp1q, qword [ditherq] + movq xm0, tmp1q + ror tmp1q, 24 + movq xm1, tmp1q + + pmovzxbd m0, xm0 + pslld m0, m0, 12 ; ditherLo + pmovzxbd m1, xm1 + pslld m1, m1, 12 ; ditherHi + + pxor m9, m9 ; uint8_min dwords + mova m10, [pd_255] ; uint8_max dwords + mova m11, [%1_shuffle_mask] ; shuffle_mask + mova m12, [yuv2nv12_permute_mask] ; permute mask + + DEFINE_ARGS tmp1, tmp2, filter, filterSize, u, v, dst, dstWidth + + xor r8q, r8q + +nv12_outer_%1: + mova m2, m0 ; resultLo + mova m3, m1 ; resultHi + xor r9q, r9q + +nv12_inner_%1: + movsx r10d, word [filterq + (2 * r9q)] + movd xm4, r10d + vpbroadcastd m4, xm4 ; filter + + mov tmp1q, [uq + (gprsize * r9q)] + mova xm7, oword [tmp1q + 2 * r8q] + + mov tmp2q, [vq + (gprsize * r9q)] + mova xm8, oword [tmp2q + 2 * r8q] + + punpcklwd xm5, xm7, xm8 + pmovsxwd m5, xm5 ; multiplicandsLo + punpckhwd xm6, xm7, xm8 + pmovsxwd m6, xm6 ; multiplicandsHi + + pmulld m7, m5, m4 ; mulResultLo + pmulld m8, m6, m4 ; mulResultHi + paddd m2, m2, m7 ; resultLo += mulResultLo + paddd m3, m3, m8 ; resultHi += mulResultHi + + inc r9d + cmp r9d, filterSized + jl nv12_inner_%1 + ; end of inner loop + + psrad m2, m2, 19 + psrad m3, m3, 19 + + ; Vectorized av_clip_uint8 + pmaxsd m2, m2, m9 + pmaxsd m3, m3, m9 + pminsd m2, m2, m10 + pminsd m3, m3, m10 + + ; At this point we have clamped uint8s arranged in this order: + ; m2: u1 0 0 0 v1 0 0 0 [...] + ; m3: u5 0 0 0 v5 0 0 0 [...] + ; + ; First, we shuffle the bytes to make the bytes semi-contiguous. + ; AVX-2 doesn't have cross-lane shuffling, so we'll end up with: + ; m2: u1 v1 u2 v2 0 0 0 0 0 0 0 0 u3 v3 u4 v4 + ; m3: u5 v5 u6 v6 0 0 0 0 0 0 0 0 u7 v7 u8 v8 + pshufb m2, m2, m11 + pshufb m3, m3, m11 + + ; To fix the cross-lane shuffling issue, we'll then use cross-lane + ; permutation to combine the two segments + vpermd m2, m12, m2 + vpermd m3, m12, m3 + + ; Now we have the final results in the lower 8 bytes of each register + movq [dstq], xm2 + movq [dstq + 8], xm3 + + add r8d, 8 + add dstq, 16 + + cmp r8d, dstWidthd + jl nv12_outer_%1 + RET +%endmacro + +INIT_YMM avx2 +yuv2nv12cX_fn yuv2nv12 +yuv2nv12cX_fn yuv2nv21 +%endif ; ARCH_X86_64 diff --git a/externals/ffmpeg/libswscale/x86/swscale.c b/externals/ffmpeg/libswscale/x86/swscale.c index 61110839e..3160fedf0 100755 --- a/externals/ffmpeg/libswscale/x86/swscale.c +++ b/externals/ffmpeg/libswscale/x86/swscale.c @@ -380,6 +380,17 @@ INPUT_FUNCS(sse2); INPUT_FUNCS(ssse3); INPUT_FUNCS(avx); +#if ARCH_X86_64 +#define YUV2NV_DECL(fmt, opt) \ +void ff_yuv2 ## fmt ## cX_ ## opt(enum AVPixelFormat format, const uint8_t *dither, \ + const int16_t *filter, int filterSize, \ + const int16_t **u, const int16_t **v, \ + uint8_t *dst, int dstWidth) + +YUV2NV_DECL(nv12, avx2); +YUV2NV_DECL(nv21, avx2); +#endif + av_cold void ff_sws_init_swscale_x86(SwsContext *c) { int cpu_flags = av_get_cpu_flags(); @@ -580,4 +591,21 @@ switch(c->dstBpc){ \ break; } } + +#if ARCH_X86_64 + if (EXTERNAL_AVX2_FAST(cpu_flags)) { + switch (c->dstFormat) { + case AV_PIX_FMT_NV12: + case AV_PIX_FMT_NV24: + c->yuv2nv12cX = ff_yuv2nv12cX_avx2; + break; + case AV_PIX_FMT_NV21: + case AV_PIX_FMT_NV42: + c->yuv2nv12cX = ff_yuv2nv21cX_avx2; + break; + default: + break; + } + } +#endif } diff --git a/externals/ffmpeg/libswscale/yuv2rgb.c b/externals/ffmpeg/libswscale/yuv2rgb.c index 588462504..71d4b90ba 100755 --- a/externals/ffmpeg/libswscale/yuv2rgb.c +++ b/externals/ffmpeg/libswscale/yuv2rgb.c @@ -965,6 +965,28 @@ av_cold int ff_yuv2rgb_c_init_tables(SwsContext *c, const int inv_table[4], fill_table(c->table_bU, 1, cbu, y_table + yoffs); fill_gv_table(c->table_gV, 1, cgv); break; + case 30: + rbase = 20; + gbase = 10; + bbase = 0; + needAlpha = CONFIG_SWSCALE_ALPHA && isALPHA(c->srcFormat); + if (!needAlpha) + abase = 30; + ALLOC_YUV_TABLE(table_plane_size * 3 * 4); + y_table32 = c->yuvTable; + yb = -(384 << 16) - YUVRGB_TABLE_LUMA_HEADROOM*cy - oy; + for (i = 0; i < table_plane_size; i++) { + unsigned yval = av_clip_uint8((yb + 0x8000) >> 16); + y_table32[i]= (yval << rbase) + (needAlpha ? 0 : (255u << abase)); + y_table32[i + table_plane_size] = yval << gbase; + y_table32[i + 2 * table_plane_size] = yval << bbase; + yb += cy; + } + fill_table(c->table_rV, 4, crv, y_table32 + yoffs); + fill_table(c->table_gU, 4, cgu, y_table32 + yoffs + table_plane_size); + fill_table(c->table_bU, 4, cbu, y_table32 + yoffs + 2 * table_plane_size); + fill_gv_table(c->table_gV, 4, cgv); + break; case 32: case 64: base = (c->dstFormat == AV_PIX_FMT_RGB32_1 || diff --git a/externals/ffmpeg/tests/api/api-band-test.c b/externals/ffmpeg/tests/api/api-band-test.c index a84f6b7e5..257e74169 100755 --- a/externals/ffmpeg/tests/api/api-band-test.c +++ b/externals/ffmpeg/tests/api/api-band-test.c @@ -198,7 +198,6 @@ static int video_decode(const char *input_filename) av_packet_unref(&pkt); av_frame_free(&fr); - avcodec_close(ctx); avformat_close_input(&fmt_ctx); avcodec_free_context(&ctx); av_freep(&byte_buffer); diff --git a/externals/ffmpeg/tests/api/api-flac-test.c b/externals/ffmpeg/tests/api/api-flac-test.c index ae6a9316d..3fea3258f 100755 --- a/externals/ffmpeg/tests/api/api-flac-test.c +++ b/externals/ffmpeg/tests/api/api-flac-test.c @@ -223,20 +223,6 @@ static int run_test(AVCodec *enc, AVCodec *dec, AVCodecContext *enc_ctx, return 0; } -static int close_encoder(AVCodecContext **enc_ctx) -{ - avcodec_close(*enc_ctx); - av_freep(enc_ctx); - return 0; -} - -static int close_decoder(AVCodecContext **dec_ctx) -{ - avcodec_close(*dec_ctx); - av_freep(dec_ctx); - return 0; -} - int main(void) { AVCodec *enc = NULL, *dec = NULL; @@ -265,8 +251,8 @@ int main(void) return 1; if (run_test(enc, dec, enc_ctx, dec_ctx) != 0) return 1; - close_encoder(&enc_ctx); - close_decoder(&dec_ctx); + avcodec_free_context(&enc_ctx); + avcodec_free_context(&dec_ctx); } } diff --git a/externals/ffmpeg/tests/api/api-h264-test.c b/externals/ffmpeg/tests/api/api-h264-test.c index 60a3ae5ef..678a1ea16 100755 --- a/externals/ffmpeg/tests/api/api-h264-test.c +++ b/externals/ffmpeg/tests/api/api-h264-test.c @@ -144,7 +144,6 @@ static int video_decode_example(const char *input_filename) av_packet_unref(&pkt); av_frame_free(&fr); - avcodec_close(ctx); avformat_close_input(&fmt_ctx); avcodec_free_context(&ctx); av_freep(&byte_buffer); diff --git a/externals/ffmpeg/tests/api/api-seek-test.c b/externals/ffmpeg/tests/api/api-seek-test.c index d0531a2f7..ae3358124 100755 --- a/externals/ffmpeg/tests/api/api-seek-test.c +++ b/externals/ffmpeg/tests/api/api-seek-test.c @@ -266,7 +266,6 @@ end: av_freep(&crc_array); av_freep(&pts_array); av_frame_free(&fr); - avcodec_close(ctx); avformat_close_input(&fmt_ctx); avcodec_free_context(&ctx); return result; diff --git a/externals/ffmpeg/tests/dnn/dnn-layer-mathunary-test.c b/externals/ffmpeg/tests/dnn/dnn-layer-mathunary-test.c index f032ca068..5afc5c157 100755 --- a/externals/ffmpeg/tests/dnn/dnn-layer-mathunary-test.c +++ b/externals/ffmpeg/tests/dnn/dnn-layer-mathunary-test.c @@ -32,6 +32,30 @@ static float get_expected(float f, DNNMathUnaryOperation op) { case DMUO_ABS: return (f >= 0) ? f : -f; + case DMUO_SIN: + return sin(f); + case DMUO_COS: + return cos(f); + case DMUO_TAN: + return tan(f); + case DMUO_ASIN: + return asin(f); + case DMUO_ACOS: + return acos(f); + case DMUO_ATAN: + return atan(f); + case DMUO_SINH: + return sinh(f); + case DMUO_COSH: + return cosh(f); + case DMUO_TANH: + return tanh(f); + case DMUO_ASINH: + return asinh(f); + case DMUO_ACOSH: + return acosh(f); + case DMUO_ATANH: + return atanh(f); default: av_assert0(!"not supported yet"); return 0.f; @@ -43,8 +67,8 @@ static int test(DNNMathUnaryOperation op) DnnLayerMathUnaryParams params; DnnOperand operands[2]; int32_t input_indexes[1]; - float input[1*1*2*3] = { - -3, 2.5, 2, -2.1, 7.8, 100}; + float input[1*1*3*3] = { + 0.1, 0.5, 0.75, -3, 2.5, 2, -2.1, 7.8, 100}; float *output; params.un_op = op; @@ -52,7 +76,7 @@ static int test(DNNMathUnaryOperation op) operands[0].data = input; operands[0].dims[0] = 1; operands[0].dims[1] = 1; - operands[0].dims[2] = 2; + operands[0].dims[2] = 3; operands[0].dims[3] = 3; operands[1].data = NULL; @@ -62,7 +86,10 @@ static int test(DNNMathUnaryOperation op) output = operands[1].data; for (int i = 0; i < sizeof(input) / sizeof(float); ++i) { float expected_output = get_expected(input[i], op); - if(fabs(output[i] - expected_output) > EPS) { + int output_nan = isnan(output[i]); + int expected_nan = isnan(expected_output); + if ((!output_nan && !expected_nan && fabs(output[i] - expected_output) > EPS) || + (output_nan && !expected_nan) || (!output_nan && expected_nan)) { printf("at index %d, output: %f, expected_output: %f\n", i, output[i], expected_output); av_freep(&output); return 1; @@ -77,5 +104,29 @@ int main(int agrc, char **argv) { if (test(DMUO_ABS)) return 1; + if (test(DMUO_SIN)) + return 1; + if (test(DMUO_COS)) + return 1; + if (test(DMUO_TAN)) + return 1; + if (test(DMUO_ASIN)) + return 1; + if (test(DMUO_ACOS)) + return 1; + if (test(DMUO_ATAN)) + return 1; + if (test(DMUO_SINH)) + return 1; + if (test(DMUO_COSH)) + return 1; + if (test(DMUO_TANH)) + return 1; + if (test(DMUO_ASINH)) + return 1; + if (test(DMUO_ACOSH)) + return 1; + if (test(DMUO_ATANH)) + return 1; return 0; } diff --git a/externals/ffmpeg/tests/fate-run.sh b/externals/ffmpeg/tests/fate-run.sh index 002944b01..414ac6f82 100755 --- a/externals/ffmpeg/tests/fate-run.sh +++ b/externals/ffmpeg/tests/fate-run.sh @@ -89,6 +89,10 @@ probefmt(){ run ffprobe${PROGSUF}${EXECSUF} -show_entries format=format_name -print_format default=nw=1:nk=1 -v 0 "$@" } +probeaudiostream(){ + run ffprobe${PROGSUF}${EXECSUF} -show_entries stream=codec_name,codec_time_base,sample_fmt,channels,channel_layout -v 0 "$@" +} + probetags(){ run ffprobe${PROGSUF}${EXECSUF} -show_entries format_tags -v 0 "$@" } diff --git a/externals/ffmpeg/tests/fate/filter-video.mak b/externals/ffmpeg/tests/fate/filter-video.mak index cfeb53e53..18fe4f701 100755 --- a/externals/ffmpeg/tests/fate/filter-video.mak +++ b/externals/ffmpeg/tests/fate/filter-video.mak @@ -223,6 +223,10 @@ FATE_FILTER_VSYNTH-$(call ALLYES, SPLIT_FILTER SCALE_FILTER PAD_FILTER OVERLAY_F fate-filter-overlay_yuv420: tests/data/filtergraphs/overlay_yuv420 fate-filter-overlay_yuv420: CMD = framecrc -c:v pgmyuv -i $(SRC) -filter_complex_script $(TARGET_PATH)/tests/data/filtergraphs/overlay_yuv420 +FATE_FILTER_VSYNTH-$(call ALLYES, SPLIT_FILTER SCALE_FILTER PAD_FILTER OVERLAY_FILTER) += fate-filter-overlay_yuv420p10 +fate-filter-overlay_yuv420p10: tests/data/filtergraphs/overlay_yuv420p10 +fate-filter-overlay_yuv420p10: CMD = framecrc -c:v pgmyuv -i $(SRC) -filter_complex_script $(TARGET_PATH)/tests/data/filtergraphs/overlay_yuv420p10 -pix_fmt yuv420p10le -frames:v 3 + FATE_FILTER_VSYNTH-$(call ALLYES, SPLIT_FILTER SCALE_FILTER PAD_FILTER OVERLAY_FILTER) += fate-filter-overlay_nv12 fate-filter-overlay_nv12: tests/data/filtergraphs/overlay_nv12 fate-filter-overlay_nv12: CMD = framecrc -c:v pgmyuv -i $(SRC) -filter_complex_script $(TARGET_PATH)/tests/data/filtergraphs/overlay_nv12 @@ -237,6 +241,10 @@ FATE_FILTER_VSYNTH-$(call ALLYES, SPLIT_FILTER SCALE_FILTER PAD_FILTER OVERLAY_F fate-filter-overlay_yuv422: tests/data/filtergraphs/overlay_yuv422 fate-filter-overlay_yuv422: CMD = framecrc -c:v pgmyuv -i $(SRC) -filter_complex_script $(TARGET_PATH)/tests/data/filtergraphs/overlay_yuv422 +FATE_FILTER_VSYNTH-$(call ALLYES, SPLIT_FILTER SCALE_FILTER PAD_FILTER OVERLAY_FILTER) += fate-filter-overlay_yuv422p10 +fate-filter-overlay_yuv422p10: tests/data/filtergraphs/overlay_yuv422p10 +fate-filter-overlay_yuv422p10: CMD = framecrc -c:v pgmyuv -i $(SRC) -filter_complex_script $(TARGET_PATH)/tests/data/filtergraphs/overlay_yuv422p10 -pix_fmt yuv422p10le -frames:v 3 + FATE_FILTER_VSYNTH-$(call ALLYES, SPLIT_FILTER SCALE_FILTER PAD_FILTER OVERLAY_FILTER) += fate-filter-overlay_yuv444 fate-filter-overlay_yuv444: tests/data/filtergraphs/overlay_yuv444 fate-filter-overlay_yuv444: CMD = framecrc -c:v pgmyuv -i $(SRC) -filter_complex_script $(TARGET_PATH)/tests/data/filtergraphs/overlay_yuv444 diff --git a/externals/ffmpeg/tests/fate/hlsenc.mak b/externals/ffmpeg/tests/fate/hlsenc.mak index 43f93c8c5..c56a541f4 100755 --- a/externals/ffmpeg/tests/fate/hlsenc.mak +++ b/externals/ffmpeg/tests/fate/hlsenc.mak @@ -97,5 +97,17 @@ FATE_HLSENC-$(call ALLYES, HLS_DEMUXER MPEGTS_MUXER MPEGTS_DEMUXER AEVALSRC_FILT fate-hls-fmp4: tests/data/hls_segment_type_fmp4.m3u8 fate-hls-fmp4: CMD = framecrc -flags +bitexact -i $(TARGET_PATH)/tests/data/hls_fmp4.m3u8 -vf setpts=N*23 -FATE_FFMPEG += $(FATE_HLSENC-yes) +tests/data/hls_fmp4_ac3.m3u8: TAG = GEN +tests/data/hls_fmp4_ac3.m3u8: ffmpeg$(PROGSSUF)$(EXESUF) | tests/data + $(M)$(TARGET_EXEC) $(TARGET_PATH)/$< \ + -stream_loop 4 -i $(SAMPLES)/ac3/monsters_inc_5.1_448_small.ac3 -c copy -map 0 \ + -hls_segment_type fmp4 -hls_fmp4_init_filename now.mp4 -hls_list_size 0 \ + -hls_time 2 -hls_segment_filename "$(TARGET_PATH)/tests/data/hls_fmp4_%d.m4s" \ + $(TARGET_PATH)/tests/data/hls_fmp4_ac3.m3u8 2>/dev/null + +FATE_HLSENC-$(call ALLYES, HLS_DEMUXER EAC3_DEMUXER) += fate-hls-fmp4_ac3 +fate-hls-fmp4_ac3: tests/data/hls_fmp4_ac3.m3u8 +fate-hls-fmp4_ac3: CMD = probeaudiostream $(TARGET_PATH)/tests/data/now.mp4 + +FATE_SAMPLES_FFMPEG += $(FATE_HLSENC-yes) fate-hlsenc: $(FATE_HLSENC-yes) diff --git a/externals/ffmpeg/tests/filtergraphs/overlay_yuv420p10 b/externals/ffmpeg/tests/filtergraphs/overlay_yuv420p10 new file mode 100755 index 000000000..d946d3c52 --- /dev/null +++ b/externals/ffmpeg/tests/filtergraphs/overlay_yuv420p10 @@ -0,0 +1,5 @@ +sws_flags=+accurate_rnd+bitexact; +split [main][over]; +[over] scale=88:72, format=yuv420p10, pad=96:80:4:4 [overf]; +[main] format=yuv420p10 [mainf]; +[mainf][overf] overlay=240:16:format=yuv420p10 diff --git a/externals/ffmpeg/tests/filtergraphs/overlay_yuv422p10 b/externals/ffmpeg/tests/filtergraphs/overlay_yuv422p10 new file mode 100755 index 000000000..5753ba6c9 --- /dev/null +++ b/externals/ffmpeg/tests/filtergraphs/overlay_yuv422p10 @@ -0,0 +1,5 @@ +sws_flags=+accurate_rnd+bitexact; +split [main][over]; +[over] scale=88:72, format=yuv420p10, pad=96:80:4:4 [overf]; +[main] format=yuv420p10 [mainf]; +[mainf][overf] overlay=240:16:format=yuv422p10 diff --git a/externals/ffmpeg/tests/ref/fate/adtstoasc_ticket3715 b/externals/ffmpeg/tests/ref/fate/adtstoasc_ticket3715 index 49fa3eb8d..3b473ee99 100755 --- a/externals/ffmpeg/tests/ref/fate/adtstoasc_ticket3715 +++ b/externals/ffmpeg/tests/ref/fate/adtstoasc_ticket3715 @@ -1,4 +1,4 @@ -4110be924e21846d0e174fac679b062e *tests/data/fate/adtstoasc_ticket3715.mov +3e63cbb6bb6ec756d79fab2632fef305 *tests/data/fate/adtstoasc_ticket3715.mov 33324 tests/data/fate/adtstoasc_ticket3715.mov #extradata 0: 2, 0x00340022 #tb 0: 1/44100 diff --git a/externals/ffmpeg/tests/ref/fate/filter-colorbalance b/externals/ffmpeg/tests/ref/fate/filter-colorbalance index 0be1f1c85..15491fe67 100755 --- a/externals/ffmpeg/tests/ref/fate/filter-colorbalance +++ b/externals/ffmpeg/tests/ref/fate/filter-colorbalance @@ -3,6 +3,6 @@ #codec_id 0: rawvideo #dimensions 0: 352x288 #sar 0: 0/1 -0, 0, 0, 1, 304128, 0x3451c8eb -0, 1, 1, 1, 304128, 0x2107daa0 -0, 2, 2, 1, 304128, 0xcda7aa33 +0, 0, 0, 1, 304128, 0xf68fadfd +0, 1, 1, 1, 304128, 0xa6302d9a +0, 2, 2, 1, 304128, 0x758d165a diff --git a/externals/ffmpeg/tests/ref/fate/filter-colorbalance-gbrap b/externals/ffmpeg/tests/ref/fate/filter-colorbalance-gbrap index 2e9960182..2d76c7d08 100755 --- a/externals/ffmpeg/tests/ref/fate/filter-colorbalance-gbrap +++ b/externals/ffmpeg/tests/ref/fate/filter-colorbalance-gbrap @@ -3,6 +3,6 @@ #codec_id 0: rawvideo #dimensions 0: 352x288 #sar 0: 0/1 -0, 0, 0, 1, 405504, 0xad0f2d82 -0, 1, 1, 1, 405504, 0x81d7d31f -0, 2, 2, 1, 405504, 0x40c5e836 +0, 0, 0, 1, 405504, 0xdcc71df0 +0, 1, 1, 1, 405504, 0x48d56675 +0, 2, 2, 1, 405504, 0x68058bf0 diff --git a/externals/ffmpeg/tests/ref/fate/filter-colorbalance-gbrap-16 b/externals/ffmpeg/tests/ref/fate/filter-colorbalance-gbrap-16 index 4ce323557..2ab96ad70 100755 --- a/externals/ffmpeg/tests/ref/fate/filter-colorbalance-gbrap-16 +++ b/externals/ffmpeg/tests/ref/fate/filter-colorbalance-gbrap-16 @@ -3,6 +3,6 @@ #codec_id 0: rawvideo #dimensions 0: 352x288 #sar 0: 0/1 -0, 0, 0, 1, 405504, 0xa97c136c -0, 1, 1, 1, 405504, 0x0a120697 -0, 2, 2, 1, 405504, 0x85b133ff +0, 0, 0, 1, 405504, 0xa497ca1b +0, 1, 1, 1, 405504, 0x92c24b0e +0, 2, 2, 1, 405504, 0x965270bd diff --git a/externals/ffmpeg/tests/ref/fate/filter-colorbalance-rgba64 b/externals/ffmpeg/tests/ref/fate/filter-colorbalance-rgba64 index f6fcfee25..605860dee 100755 --- a/externals/ffmpeg/tests/ref/fate/filter-colorbalance-rgba64 +++ b/externals/ffmpeg/tests/ref/fate/filter-colorbalance-rgba64 @@ -3,6 +3,6 @@ #codec_id 0: rawvideo #dimensions 0: 352x288 #sar 0: 0/1 -0, 0, 0, 1, 811008, 0xa67db91d -0, 1, 1, 1, 811008, 0x0846578a -0, 2, 2, 1, 811008, 0x77af61f8 +0, 0, 0, 1, 811008, 0xc5f7e6ba +0, 1, 1, 1, 811008, 0x266955bf +0, 2, 2, 1, 811008, 0x55360c6e diff --git a/externals/ffmpeg/tests/ref/fate/filter-edgedetect b/externals/ffmpeg/tests/ref/fate/filter-edgedetect index 23c9953e6..e49639afa 100755 --- a/externals/ffmpeg/tests/ref/fate/filter-edgedetect +++ b/externals/ffmpeg/tests/ref/fate/filter-edgedetect @@ -1 +1 @@ -edgedetect 93ceace33f6636bcdbeb037317c65745 +edgedetect 04ff46bb35edff3dbad4102391516d25 diff --git a/externals/ffmpeg/tests/ref/fate/filter-edgedetect-colormix b/externals/ffmpeg/tests/ref/fate/filter-edgedetect-colormix index e828c6bd1..0df17344b 100755 --- a/externals/ffmpeg/tests/ref/fate/filter-edgedetect-colormix +++ b/externals/ffmpeg/tests/ref/fate/filter-edgedetect-colormix @@ -1 +1 @@ -edgedetect-colormix 1b8658252e2f03fbae30e6d63dd24c7c +edgedetect-colormix 9f50c5586f899a8f5a10059154d64bde diff --git a/externals/ffmpeg/tests/ref/fate/filter-overlay_yuv420p10 b/externals/ffmpeg/tests/ref/fate/filter-overlay_yuv420p10 new file mode 100755 index 000000000..b431dc6cc --- /dev/null +++ b/externals/ffmpeg/tests/ref/fate/filter-overlay_yuv420p10 @@ -0,0 +1,8 @@ +#tb 0: 1/25 +#media_type 0: video +#codec_id 0: rawvideo +#dimensions 0: 352x288 +#sar 0: 0/1 +0, 0, 0, 1, 304128, 0x29a6ca86 +0, 1, 1, 1, 304128, 0x82950e6f +0, 2, 2, 1, 304128, 0x8363d1d8 diff --git a/externals/ffmpeg/tests/ref/fate/filter-overlay_yuv422p10 b/externals/ffmpeg/tests/ref/fate/filter-overlay_yuv422p10 new file mode 100755 index 000000000..393c08169 --- /dev/null +++ b/externals/ffmpeg/tests/ref/fate/filter-overlay_yuv422p10 @@ -0,0 +1,8 @@ +#tb 0: 1/25 +#media_type 0: video +#codec_id 0: rawvideo +#dimensions 0: 352x288 +#sar 0: 0/1 +0, 0, 0, 1, 405504, 0x11108b36 +0, 1, 1, 1, 405504, 0x9d5f7c2a +0, 2, 2, 1, 405504, 0x25373098 diff --git a/externals/ffmpeg/tests/ref/fate/filter-pixdesc-x2rgb10le b/externals/ffmpeg/tests/ref/fate/filter-pixdesc-x2rgb10le new file mode 100755 index 000000000..94c8640a5 --- /dev/null +++ b/externals/ffmpeg/tests/ref/fate/filter-pixdesc-x2rgb10le @@ -0,0 +1 @@ +pixdesc-x2rgb10le 98d697ed4668daf535163d5e08c903bb diff --git a/externals/ffmpeg/tests/ref/fate/filter-pixfmts-copy b/externals/ffmpeg/tests/ref/fate/filter-pixfmts-copy index 45fe1be21..1d7657c2a 100755 --- a/externals/ffmpeg/tests/ref/fate/filter-pixfmts-copy +++ b/externals/ffmpeg/tests/ref/fate/filter-pixfmts-copy @@ -80,6 +80,7 @@ rgba b6e1b441c365e03b5ffdf9b7b68d9a0c rgba64be ae2ae04b5efedca3505f47c4dd6ea6ea rgba64le b91e1d77f799eb92241a2d2d28437b15 uyvy422 3bcf3c80047592f2211fae3260b1b65d +x2rgb10le b0a0c8056521beeaa3fea4985ca87176 xyz12be a1ef56bf746d71f59669c28e48fc8450 xyz12le 831ff03c1ba4ef19374686f16a064d8c ya16be 37c07787e544f900c87b853253bfc8dd diff --git a/externals/ffmpeg/tests/ref/fate/filter-pixfmts-crop b/externals/ffmpeg/tests/ref/fate/filter-pixfmts-crop index 430e90e19..8fc761419 100755 --- a/externals/ffmpeg/tests/ref/fate/filter-pixfmts-crop +++ b/externals/ffmpeg/tests/ref/fate/filter-pixfmts-crop @@ -77,6 +77,7 @@ rgb8 9b364a8f112ad9459fec47a51cc03b30 rgba 9488ac85abceaf99a9309eac5a87697e rgba64be 89910046972ab3c68e2a348302cc8ca9 rgba64le fea8ebfc869b52adf353778f29eac7a7 +x2rgb10le 5c0789f76a713f343c2ed42a371d441d xyz12be cb4571f9aaa7b59f999ef327276104b7 xyz12le cd6aae8d26b18bdb4b9d068586276d91 ya16be a3d18014454942a96f15a49947c0c55d diff --git a/externals/ffmpeg/tests/ref/fate/filter-pixfmts-field b/externals/ffmpeg/tests/ref/fate/filter-pixfmts-field index b5f7013af..ce8e53571 100755 --- a/externals/ffmpeg/tests/ref/fate/filter-pixfmts-field +++ b/externals/ffmpeg/tests/ref/fate/filter-pixfmts-field @@ -80,6 +80,7 @@ rgba ee616262ca6d67b7ecfba4b36c602ce3 rgba64be 23c8c0edaabe3eaec89ce69633fb0048 rgba64le dfdba4de4a7cac9abf08852666c341d3 uyvy422 1c49e44ab3f060e85fc4a3a9464f045e +x2rgb10le a7a5dcdfe1d4b6bd71e40b01c735f144 xyz12be d2fa69ec91d3ed862f2dac3f8e7a3437 xyz12le 02bccd5e0b6824779a1f848b0ea3e3b5 ya16be 40403b5277364777e0671da4d38e01ac diff --git a/externals/ffmpeg/tests/ref/fate/filter-pixfmts-fieldorder b/externals/ffmpeg/tests/ref/fate/filter-pixfmts-fieldorder index dfc464ff8..90d36add8 100755 --- a/externals/ffmpeg/tests/ref/fate/filter-pixfmts-fieldorder +++ b/externals/ffmpeg/tests/ref/fate/filter-pixfmts-fieldorder @@ -71,6 +71,7 @@ rgba 1fdf872a087a32cd35b80cc7be399578 rgba64be 5598f44514d122b9a57c5c92c20bbc61 rgba64le b34e6e30621ae579519a2d91a96a0acf uyvy422 75de70e31c435dde878002d3f22b238a +x2rgb10le 636c90498c64abba1cc0624c5209a61f xyz12be 15f5cda71de5fef9cec5e75e3833b6bc xyz12le 7be6c8781f38c21a6b8f602f62ca31e6 ya16be 0f13e0f52586d172aaa07710fa3e8f31 diff --git a/externals/ffmpeg/tests/ref/fate/filter-pixfmts-hflip b/externals/ffmpeg/tests/ref/fate/filter-pixfmts-hflip index 8b8c659fc..0d40b93e9 100755 --- a/externals/ffmpeg/tests/ref/fate/filter-pixfmts-hflip +++ b/externals/ffmpeg/tests/ref/fate/filter-pixfmts-hflip @@ -77,6 +77,7 @@ rgb8 68a3a575badadd9e4f90226209f11699 rgba 51961c723ea6707e0a410cd3f21f15d3 rgba64be c910444019f4cfbf4d995227af55da8d rgba64le 0c810d8b3a6bca10321788e1cb145340 +x2rgb10le 9f99dce306383daf25cd1542b2517fef xyz12be 25f90259ff8a226befdaec3dfe82996e xyz12le 926c0791d59aaff61b2778e8ada3316d ya16be d5b342355bdd9e3197e01b13b7c6301e diff --git a/externals/ffmpeg/tests/ref/fate/filter-pixfmts-il b/externals/ffmpeg/tests/ref/fate/filter-pixfmts-il index 1c7e94643..d1bc86695 100755 --- a/externals/ffmpeg/tests/ref/fate/filter-pixfmts-il +++ b/externals/ffmpeg/tests/ref/fate/filter-pixfmts-il @@ -79,6 +79,7 @@ rgba 625d8f4bd39c4bdbf61eb5e4713aecc9 rgba64be db70d33aa6c06f3e0a1c77bd11284261 rgba64le a8a2daae04374a27219bc1c890204007 uyvy422 d6ee3ca43356d08c392382b24b22cda5 +x2rgb10le a01ea7dd339e028780e04971012d826d xyz12be 7c7d54c55f136cbbc50b18029f3be0b3 xyz12le 090ba6b1170baf2b1358b43b971d33b0 ya16be 7bc720918bc0132e9717acbde89874e0 diff --git a/externals/ffmpeg/tests/ref/fate/filter-pixfmts-null b/externals/ffmpeg/tests/ref/fate/filter-pixfmts-null index 45fe1be21..1d7657c2a 100755 --- a/externals/ffmpeg/tests/ref/fate/filter-pixfmts-null +++ b/externals/ffmpeg/tests/ref/fate/filter-pixfmts-null @@ -80,6 +80,7 @@ rgba b6e1b441c365e03b5ffdf9b7b68d9a0c rgba64be ae2ae04b5efedca3505f47c4dd6ea6ea rgba64le b91e1d77f799eb92241a2d2d28437b15 uyvy422 3bcf3c80047592f2211fae3260b1b65d +x2rgb10le b0a0c8056521beeaa3fea4985ca87176 xyz12be a1ef56bf746d71f59669c28e48fc8450 xyz12le 831ff03c1ba4ef19374686f16a064d8c ya16be 37c07787e544f900c87b853253bfc8dd diff --git a/externals/ffmpeg/tests/ref/fate/filter-pixfmts-pad b/externals/ffmpeg/tests/ref/fate/filter-pixfmts-pad index 56482cf89..9a5db8254 100755 --- a/externals/ffmpeg/tests/ref/fate/filter-pixfmts-pad +++ b/externals/ffmpeg/tests/ref/fate/filter-pixfmts-pad @@ -28,6 +28,7 @@ nv42 1738ad3c31c6c16e17679f5b09ce4677 rgb0 78d500c8361ab6423a4826a00268c908 rgb24 17f9e2e0c609009acaf2175c42d4a2a5 rgba b157c90191463d34fb3ce77b36c96386 +x2rgb10le c240f8a8dfa647c57c0974d061c9652a xyz12le 85abf80b77a9236a76ba0b00fcbdea2d ya16le 940fafa240b9916de5f73cb20a552f24 ya8 5fc0f471207ddf7aa01b07027d56b672 diff --git a/externals/ffmpeg/tests/ref/fate/filter-pixfmts-scale b/externals/ffmpeg/tests/ref/fate/filter-pixfmts-scale index 1e5c7db3d..d7020ad2c 100755 --- a/externals/ffmpeg/tests/ref/fate/filter-pixfmts-scale +++ b/externals/ffmpeg/tests/ref/fate/filter-pixfmts-scale @@ -80,6 +80,7 @@ rgba 85bb5d03cea1c6e8002ced3373904336 rgba64be ee73e57923af984b31cc7795d13929da rgba64le 783d2779adfafe3548bdb671ec0de69e uyvy422 aeb4ba4f9f003ae21f6d18089198244f +x2rgb10le 591fe7942544c8fc40e5d30e0e589f49 xyz12be c7ba8345998c0141ddc079cdd29b1a40 xyz12le 95f5d3a0de834cc495c9032a14987cde ya16be 20d4842899d61068f5fb6af478bf26a6 diff --git a/externals/ffmpeg/tests/ref/fate/filter-pixfmts-transpose b/externals/ffmpeg/tests/ref/fate/filter-pixfmts-transpose index e194c335c..0a8542b2a 100755 --- a/externals/ffmpeg/tests/ref/fate/filter-pixfmts-transpose +++ b/externals/ffmpeg/tests/ref/fate/filter-pixfmts-transpose @@ -76,6 +76,7 @@ rgb8 c90feb30c3c9391ef5f470209d7b7a15 rgba 4d76a9542143752a4ac30f82f88f68f1 rgba64be a60041217f4c0cd796d19d3940a12a41 rgba64le ad47197774858858ae7b0c177dffa459 +x2rgb10le a64d4d901b09bea9d59eda58be5e88ff xyz12be 68e5cba640f6e4ef72dff950e88b5342 xyz12le 8b6b6a6db4d7561e80db88ccaecce7a9 ya16be 3e161cb5f225922a80fefdc9cc02a4f9 diff --git a/externals/ffmpeg/tests/ref/fate/filter-pixfmts-vflip b/externals/ffmpeg/tests/ref/fate/filter-pixfmts-vflip index 6d0f9eecc..732db8d33 100755 --- a/externals/ffmpeg/tests/ref/fate/filter-pixfmts-vflip +++ b/externals/ffmpeg/tests/ref/fate/filter-pixfmts-vflip @@ -80,6 +80,7 @@ rgba c1a5908572737f2ae1e5d8218af65f4b rgba64be 17e6273323b5779b5f3f775f150c1011 rgba64le 48f45b10503b7dd140329c3dd0d54c98 uyvy422 3a237e8376264e0cfa78f8a3fdadec8a +x2rgb10le 332a6f5f5012008a562cb031836da028 xyz12be 810644e008deb231850d779aaa27cc7e xyz12le 829701db461b43533cf9241e0743bc61 ya16be 55b1dbbe4d56ed0d22461685ce85520d diff --git a/externals/ffmpeg/tests/ref/fate/hevc-monochrome-crop b/externals/ffmpeg/tests/ref/fate/hevc-monochrome-crop index 4e45412ac..384404da6 100755 --- a/externals/ffmpeg/tests/ref/fate/hevc-monochrome-crop +++ b/externals/ffmpeg/tests/ref/fate/hevc-monochrome-crop @@ -1,6 +1,9 @@ [FRAME] width=384 height=240 +[SIDE_DATA] +side_data_type=H.26[45] User Data Unregistered SEI message +[/SIDE_DATA] [/FRAME] [STREAM] width=384 diff --git a/externals/ffmpeg/tests/ref/fate/hls-fmp4_ac3 b/externals/ffmpeg/tests/ref/fate/hls-fmp4_ac3 new file mode 100755 index 000000000..1f45172a0 --- /dev/null +++ b/externals/ffmpeg/tests/ref/fate/hls-fmp4_ac3 @@ -0,0 +1,9 @@ +[STREAM] +codec_name=ac3 +codec_time_base=1/48000 +sample_fmt=fltp +channels=6 +channel_layout=5.1(side) +[SIDE_DATA] +[/SIDE_DATA] +[/STREAM] diff --git a/externals/ffmpeg/tests/ref/fate/mov-zombie b/externals/ffmpeg/tests/ref/fate/mov-zombie index 445f92128..1a6625bc8 100755 --- a/externals/ffmpeg/tests/ref/fate/mov-zombie +++ b/externals/ffmpeg/tests/ref/fate/mov-zombie @@ -1,133 +1,198 @@ packet|codec_type=video|stream_index=0|pts=0|pts_time=0.000000|dts=-3004|dts_time=-0.033378|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=4133|pos=11309|flags=K_ packet|codec_type=video|stream_index=0|pts=5440|pts_time=0.060444|dts=-567|dts_time=-0.006300|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=1077|pos=15442|flags=__ -frame|media_type=video|stream_index=0|key_frame=1|pkt_pts=0|pkt_pts_time=0.000000|pkt_dts=-567|pkt_dts_time=-0.006300|best_effort_timestamp=0|best_effort_timestamp_time=0.000000|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=11309|pkt_size=4133|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=I|coded_picture_number=0|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft +frame|media_type=video|stream_index=0|key_frame=1|pkt_pts=0|pkt_pts_time=0.000000|pkt_dts=-567|pkt_dts_time=-0.006300|best_effort_timestamp=0|best_effort_timestamp_time=0.000000|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=11309|pkt_size=4133|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=I|coded_picture_number=0|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleftside_data|side_data_type=H.26[45] User Data Unregistered SEI message + packet|codec_type=video|stream_index=0|pts=2437|pts_time=0.027078|dts=2436|dts_time=0.027067|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=355|pos=16519|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=2437|pkt_pts_time=0.027078|pkt_dts=2436|pkt_dts_time=0.027067|best_effort_timestamp=2437|best_effort_timestamp_time=0.027078|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=16519|pkt_size=355|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=2|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=2437|pkt_pts_time=0.027078|pkt_dts=2436|pkt_dts_time=0.027067|best_effort_timestamp=2437|best_effort_timestamp_time=0.027078|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=16519|pkt_size=355|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=2|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleftside_data|side_data_type=H.26[45] User Data Unregistered SEI message + packet|codec_type=video|stream_index=0|pts=11446|pts_time=0.127178|dts=5439|dts_time=0.060433|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=1110|pos=16874|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=5440|pkt_pts_time=0.060444|pkt_dts=5439|pkt_dts_time=0.060433|best_effort_timestamp=5440|best_effort_timestamp_time=0.060444|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=15442|pkt_size=1077|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=1|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=5440|pkt_pts_time=0.060444|pkt_dts=5439|pkt_dts_time=0.060433|best_effort_timestamp=5440|best_effort_timestamp_time=0.060444|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=15442|pkt_size=1077|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=1|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleftside_data|side_data_type=H.26[45] User Data Unregistered SEI message + packet|codec_type=video|stream_index=0|pts=8443|pts_time=0.093811|dts=8442|dts_time=0.093800|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=430|pos=17984|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=8443|pkt_pts_time=0.093811|pkt_dts=8442|pkt_dts_time=0.093800|best_effort_timestamp=8443|best_effort_timestamp_time=0.093811|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=17984|pkt_size=430|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=4|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=8443|pkt_pts_time=0.093811|pkt_dts=8442|pkt_dts_time=0.093800|best_effort_timestamp=8443|best_effort_timestamp_time=0.093811|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=17984|pkt_size=430|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=4|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleftside_data|side_data_type=H.26[45] User Data Unregistered SEI message + packet|codec_type=video|stream_index=0|pts=17452|pts_time=0.193911|dts=11445|dts_time=0.127167|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=1485|pos=18414|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=11446|pkt_pts_time=0.127178|pkt_dts=11445|pkt_dts_time=0.127167|best_effort_timestamp=11446|best_effort_timestamp_time=0.127178|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=16874|pkt_size=1110|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=3|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=11446|pkt_pts_time=0.127178|pkt_dts=11445|pkt_dts_time=0.127167|best_effort_timestamp=11446|best_effort_timestamp_time=0.127178|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=16874|pkt_size=1110|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=3|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleftside_data|side_data_type=H.26[45] User Data Unregistered SEI message + packet|codec_type=video|stream_index=0|pts=14449|pts_time=0.160544|dts=14448|dts_time=0.160533|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=1005|pos=19899|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=14449|pkt_pts_time=0.160544|pkt_dts=14448|pkt_dts_time=0.160533|best_effort_timestamp=14449|best_effort_timestamp_time=0.160544|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=19899|pkt_size=1005|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=6|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=14449|pkt_pts_time=0.160544|pkt_dts=14448|pkt_dts_time=0.160533|best_effort_timestamp=14449|best_effort_timestamp_time=0.160544|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=19899|pkt_size=1005|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=6|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleftside_data|side_data_type=H.26[45] User Data Unregistered SEI message + packet|codec_type=video|stream_index=0|pts=23458|pts_time=0.260644|dts=17451|dts_time=0.193900|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=1976|pos=20904|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=17452|pkt_pts_time=0.193911|pkt_dts=17451|pkt_dts_time=0.193900|best_effort_timestamp=17452|best_effort_timestamp_time=0.193911|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=18414|pkt_size=1485|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=5|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=17452|pkt_pts_time=0.193911|pkt_dts=17451|pkt_dts_time=0.193900|best_effort_timestamp=17452|best_effort_timestamp_time=0.193911|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=18414|pkt_size=1485|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=5|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleftside_data|side_data_type=H.26[45] User Data Unregistered SEI message + packet|codec_type=video|stream_index=0|pts=20455|pts_time=0.227278|dts=20454|dts_time=0.227267|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=904|pos=22880|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=20455|pkt_pts_time=0.227278|pkt_dts=20454|pkt_dts_time=0.227267|best_effort_timestamp=20455|best_effort_timestamp_time=0.227278|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=22880|pkt_size=904|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=8|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=20455|pkt_pts_time=0.227278|pkt_dts=20454|pkt_dts_time=0.227267|best_effort_timestamp=20455|best_effort_timestamp_time=0.227278|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=22880|pkt_size=904|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=8|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleftside_data|side_data_type=H.26[45] User Data Unregistered SEI message + packet|codec_type=video|stream_index=0|pts=29464|pts_time=0.327378|dts=23457|dts_time=0.260633|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=1254|pos=23784|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=23458|pkt_pts_time=0.260644|pkt_dts=23457|pkt_dts_time=0.260633|best_effort_timestamp=23458|best_effort_timestamp_time=0.260644|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=20904|pkt_size=1976|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=7|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=23458|pkt_pts_time=0.260644|pkt_dts=23457|pkt_dts_time=0.260633|best_effort_timestamp=23458|best_effort_timestamp_time=0.260644|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=20904|pkt_size=1976|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=7|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleftside_data|side_data_type=H.26[45] User Data Unregistered SEI message + packet|codec_type=video|stream_index=0|pts=26461|pts_time=0.294011|dts=26460|dts_time=0.294000|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=700|pos=25038|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=26461|pkt_pts_time=0.294011|pkt_dts=26460|pkt_dts_time=0.294000|best_effort_timestamp=26461|best_effort_timestamp_time=0.294011|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=25038|pkt_size=700|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=10|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=26461|pkt_pts_time=0.294011|pkt_dts=26460|pkt_dts_time=0.294000|best_effort_timestamp=26461|best_effort_timestamp_time=0.294011|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=25038|pkt_size=700|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=10|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleftside_data|side_data_type=H.26[45] User Data Unregistered SEI message + packet|codec_type=video|stream_index=0|pts=35470|pts_time=0.394111|dts=29463|dts_time=0.327367|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=1311|pos=25738|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=29464|pkt_pts_time=0.327378|pkt_dts=29463|pkt_dts_time=0.327367|best_effort_timestamp=29464|best_effort_timestamp_time=0.327378|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=23784|pkt_size=1254|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=9|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=29464|pkt_pts_time=0.327378|pkt_dts=29463|pkt_dts_time=0.327367|best_effort_timestamp=29464|best_effort_timestamp_time=0.327378|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=23784|pkt_size=1254|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=9|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleftside_data|side_data_type=H.26[45] User Data Unregistered SEI message + packet|codec_type=video|stream_index=0|pts=32467|pts_time=0.360744|dts=32466|dts_time=0.360733|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=631|pos=27049|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=32467|pkt_pts_time=0.360744|pkt_dts=32466|pkt_dts_time=0.360733|best_effort_timestamp=32467|best_effort_timestamp_time=0.360744|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=27049|pkt_size=631|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=12|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=32467|pkt_pts_time=0.360744|pkt_dts=32466|pkt_dts_time=0.360733|best_effort_timestamp=32467|best_effort_timestamp_time=0.360744|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=27049|pkt_size=631|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=12|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleftside_data|side_data_type=H.26[45] User Data Unregistered SEI message + packet|codec_type=video|stream_index=0|pts=41476|pts_time=0.460844|dts=35469|dts_time=0.394100|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=1296|pos=27680|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=35470|pkt_pts_time=0.394111|pkt_dts=35469|pkt_dts_time=0.394100|best_effort_timestamp=35470|best_effort_timestamp_time=0.394111|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=25738|pkt_size=1311|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=11|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=35470|pkt_pts_time=0.394111|pkt_dts=35469|pkt_dts_time=0.394100|best_effort_timestamp=35470|best_effort_timestamp_time=0.394111|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=25738|pkt_size=1311|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=11|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleftside_data|side_data_type=H.26[45] User Data Unregistered SEI message + packet|codec_type=video|stream_index=0|pts=38473|pts_time=0.427478|dts=38472|dts_time=0.427467|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=466|pos=28976|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=38473|pkt_pts_time=0.427478|pkt_dts=38472|pkt_dts_time=0.427467|best_effort_timestamp=38473|best_effort_timestamp_time=0.427478|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=28976|pkt_size=466|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=14|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=38473|pkt_pts_time=0.427478|pkt_dts=38472|pkt_dts_time=0.427467|best_effort_timestamp=38473|best_effort_timestamp_time=0.427478|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=28976|pkt_size=466|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=14|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleftside_data|side_data_type=H.26[45] User Data Unregistered SEI message + packet|codec_type=video|stream_index=0|pts=47482|pts_time=0.527578|dts=41475|dts_time=0.460833|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=1638|pos=29442|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=41476|pkt_pts_time=0.460844|pkt_dts=41475|pkt_dts_time=0.460833|best_effort_timestamp=41476|best_effort_timestamp_time=0.460844|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=27680|pkt_size=1296|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=13|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=41476|pkt_pts_time=0.460844|pkt_dts=41475|pkt_dts_time=0.460833|best_effort_timestamp=41476|best_effort_timestamp_time=0.460844|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=27680|pkt_size=1296|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=13|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleftside_data|side_data_type=H.26[45] User Data Unregistered SEI message + packet|codec_type=video|stream_index=0|pts=44479|pts_time=0.494211|dts=44478|dts_time=0.494200|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=907|pos=31080|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=44479|pkt_pts_time=0.494211|pkt_dts=44478|pkt_dts_time=0.494200|best_effort_timestamp=44479|best_effort_timestamp_time=0.494211|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=31080|pkt_size=907|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=16|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=44479|pkt_pts_time=0.494211|pkt_dts=44478|pkt_dts_time=0.494200|best_effort_timestamp=44479|best_effort_timestamp_time=0.494211|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=31080|pkt_size=907|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=16|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleftside_data|side_data_type=H.26[45] User Data Unregistered SEI message + packet|codec_type=video|stream_index=0|pts=53488|pts_time=0.594311|dts=47481|dts_time=0.527567|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=1362|pos=31987|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=47482|pkt_pts_time=0.527578|pkt_dts=47481|pkt_dts_time=0.527567|best_effort_timestamp=47482|best_effort_timestamp_time=0.527578|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=29442|pkt_size=1638|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=15|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=47482|pkt_pts_time=0.527578|pkt_dts=47481|pkt_dts_time=0.527567|best_effort_timestamp=47482|best_effort_timestamp_time=0.527578|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=29442|pkt_size=1638|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=15|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleftside_data|side_data_type=H.26[45] User Data Unregistered SEI message + packet|codec_type=video|stream_index=0|pts=50485|pts_time=0.560944|dts=50484|dts_time=0.560933|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=682|pos=33349|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=50485|pkt_pts_time=0.560944|pkt_dts=50484|pkt_dts_time=0.560933|best_effort_timestamp=50485|best_effort_timestamp_time=0.560944|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=33349|pkt_size=682|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=18|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=50485|pkt_pts_time=0.560944|pkt_dts=50484|pkt_dts_time=0.560933|best_effort_timestamp=50485|best_effort_timestamp_time=0.560944|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=33349|pkt_size=682|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=18|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleftside_data|side_data_type=H.26[45] User Data Unregistered SEI message + packet|codec_type=video|stream_index=0|pts=59494|pts_time=0.661044|dts=53487|dts_time=0.594300|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=2917|pos=34031|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=53488|pkt_pts_time=0.594311|pkt_dts=53487|pkt_dts_time=0.594300|best_effort_timestamp=53488|best_effort_timestamp_time=0.594311|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=31987|pkt_size=1362|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=17|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=53488|pkt_pts_time=0.594311|pkt_dts=53487|pkt_dts_time=0.594300|best_effort_timestamp=53488|best_effort_timestamp_time=0.594311|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=31987|pkt_size=1362|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=17|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleftside_data|side_data_type=H.26[45] User Data Unregistered SEI message + packet|codec_type=video|stream_index=0|pts=56491|pts_time=0.627678|dts=56490|dts_time=0.627667|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=1174|pos=36948|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=56491|pkt_pts_time=0.627678|pkt_dts=56490|pkt_dts_time=0.627667|best_effort_timestamp=56491|best_effort_timestamp_time=0.627678|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=36948|pkt_size=1174|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=20|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=56491|pkt_pts_time=0.627678|pkt_dts=56490|pkt_dts_time=0.627667|best_effort_timestamp=56491|best_effort_timestamp_time=0.627678|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=36948|pkt_size=1174|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=20|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleftside_data|side_data_type=H.26[45] User Data Unregistered SEI message + packet|codec_type=video|stream_index=0|pts=65500|pts_time=0.727778|dts=59493|dts_time=0.661033|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=1748|pos=38122|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=59494|pkt_pts_time=0.661044|pkt_dts=59493|pkt_dts_time=0.661033|best_effort_timestamp=59494|best_effort_timestamp_time=0.661044|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=34031|pkt_size=2917|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=19|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=59494|pkt_pts_time=0.661044|pkt_dts=59493|pkt_dts_time=0.661033|best_effort_timestamp=59494|best_effort_timestamp_time=0.661044|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=34031|pkt_size=2917|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=19|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleftside_data|side_data_type=H.26[45] User Data Unregistered SEI message + packet|codec_type=video|stream_index=0|pts=62497|pts_time=0.694411|dts=62496|dts_time=0.694400|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=926|pos=39870|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=62497|pkt_pts_time=0.694411|pkt_dts=62496|pkt_dts_time=0.694400|best_effort_timestamp=62497|best_effort_timestamp_time=0.694411|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=39870|pkt_size=926|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=22|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=62497|pkt_pts_time=0.694411|pkt_dts=62496|pkt_dts_time=0.694400|best_effort_timestamp=62497|best_effort_timestamp_time=0.694411|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=39870|pkt_size=926|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=22|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleftside_data|side_data_type=H.26[45] User Data Unregistered SEI message + packet|codec_type=video|stream_index=0|pts=68503|pts_time=0.761144|dts=65499|dts_time=0.727767|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=918|pos=40796|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=65500|pkt_pts_time=0.727778|pkt_dts=65499|pkt_dts_time=0.727767|best_effort_timestamp=65500|best_effort_timestamp_time=0.727778|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=38122|pkt_size=1748|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=21|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=65500|pkt_pts_time=0.727778|pkt_dts=65499|pkt_dts_time=0.727767|best_effort_timestamp=65500|best_effort_timestamp_time=0.727778|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=38122|pkt_size=1748|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=21|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleftside_data|side_data_type=H.26[45] User Data Unregistered SEI message + packet|codec_type=video|stream_index=0|pts=71506|pts_time=0.794511|dts=68502|dts_time=0.761133|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=3846|pos=41714|flags=K_ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=68503|pkt_pts_time=0.761144|pkt_dts=68502|pkt_dts_time=0.761133|best_effort_timestamp=68503|best_effort_timestamp_time=0.761144|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=40796|pkt_size=918|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=23|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=68503|pkt_pts_time=0.761144|pkt_dts=68502|pkt_dts_time=0.761133|best_effort_timestamp=68503|best_effort_timestamp_time=0.761144|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=40796|pkt_size=918|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=23|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleftside_data|side_data_type=H.26[45] User Data Unregistered SEI message + packet|codec_type=video|stream_index=0|pts=77512|pts_time=0.861244|dts=71505|dts_time=0.794500|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=1932|pos=45560|flags=__ -frame|media_type=video|stream_index=0|key_frame=1|pkt_pts=71506|pkt_pts_time=0.794511|pkt_dts=71505|pkt_dts_time=0.794500|best_effort_timestamp=71506|best_effort_timestamp_time=0.794511|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=41714|pkt_size=3846|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=I|coded_picture_number=24|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft +frame|media_type=video|stream_index=0|key_frame=1|pkt_pts=71506|pkt_pts_time=0.794511|pkt_dts=71505|pkt_dts_time=0.794500|best_effort_timestamp=71506|best_effort_timestamp_time=0.794511|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=41714|pkt_size=3846|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=I|coded_picture_number=24|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleftside_data|side_data_type=H.26[45] User Data Unregistered SEI message + packet|codec_type=video|stream_index=0|pts=74509|pts_time=0.827878|dts=74508|dts_time=0.827867|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=1159|pos=47492|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=74509|pkt_pts_time=0.827878|pkt_dts=74508|pkt_dts_time=0.827867|best_effort_timestamp=74509|best_effort_timestamp_time=0.827878|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=47492|pkt_size=1159|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=26|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=74509|pkt_pts_time=0.827878|pkt_dts=74508|pkt_dts_time=0.827867|best_effort_timestamp=74509|best_effort_timestamp_time=0.827878|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=47492|pkt_size=1159|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=26|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleftside_data|side_data_type=H.26[45] User Data Unregistered SEI message + packet|codec_type=video|stream_index=0|pts=83518|pts_time=0.927978|dts=77511|dts_time=0.861233|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=1522|pos=48651|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=77512|pkt_pts_time=0.861244|pkt_dts=77511|pkt_dts_time=0.861233|best_effort_timestamp=77512|best_effort_timestamp_time=0.861244|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=45560|pkt_size=1932|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=25|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=77512|pkt_pts_time=0.861244|pkt_dts=77511|pkt_dts_time=0.861233|best_effort_timestamp=77512|best_effort_timestamp_time=0.861244|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=45560|pkt_size=1932|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=25|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleftside_data|side_data_type=H.26[45] User Data Unregistered SEI message + packet|codec_type=video|stream_index=0|pts=80515|pts_time=0.894611|dts=80514|dts_time=0.894600|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=719|pos=50173|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=80515|pkt_pts_time=0.894611|pkt_dts=80514|pkt_dts_time=0.894600|best_effort_timestamp=80515|best_effort_timestamp_time=0.894611|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=50173|pkt_size=719|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=28|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=80515|pkt_pts_time=0.894611|pkt_dts=80514|pkt_dts_time=0.894600|best_effort_timestamp=80515|best_effort_timestamp_time=0.894611|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=50173|pkt_size=719|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=28|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleftside_data|side_data_type=H.26[45] User Data Unregistered SEI message + packet|codec_type=video|stream_index=0|pts=89524|pts_time=0.994711|dts=83517|dts_time=0.927967|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=1700|pos=50892|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=83518|pkt_pts_time=0.927978|pkt_dts=83517|pkt_dts_time=0.927967|best_effort_timestamp=83518|best_effort_timestamp_time=0.927978|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=48651|pkt_size=1522|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=27|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=83518|pkt_pts_time=0.927978|pkt_dts=83517|pkt_dts_time=0.927967|best_effort_timestamp=83518|best_effort_timestamp_time=0.927978|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=48651|pkt_size=1522|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=27|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleftside_data|side_data_type=H.26[45] User Data Unregistered SEI message + packet|codec_type=video|stream_index=0|pts=86521|pts_time=0.961344|dts=86520|dts_time=0.961333|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=1099|pos=52592|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=86521|pkt_pts_time=0.961344|pkt_dts=86520|pkt_dts_time=0.961333|best_effort_timestamp=86521|best_effort_timestamp_time=0.961344|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=52592|pkt_size=1099|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=30|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=86521|pkt_pts_time=0.961344|pkt_dts=86520|pkt_dts_time=0.961333|best_effort_timestamp=86521|best_effort_timestamp_time=0.961344|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=52592|pkt_size=1099|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=30|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleftside_data|side_data_type=H.26[45] User Data Unregistered SEI message + packet|codec_type=video|stream_index=0|pts=95530|pts_time=1.061444|dts=89523|dts_time=0.994700|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=2558|pos=53691|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=89524|pkt_pts_time=0.994711|pkt_dts=89523|pkt_dts_time=0.994700|best_effort_timestamp=89524|best_effort_timestamp_time=0.994711|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=50892|pkt_size=1700|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=29|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=89524|pkt_pts_time=0.994711|pkt_dts=89523|pkt_dts_time=0.994700|best_effort_timestamp=89524|best_effort_timestamp_time=0.994711|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=50892|pkt_size=1700|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=29|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleftside_data|side_data_type=H.26[45] User Data Unregistered SEI message + packet|codec_type=video|stream_index=0|pts=92527|pts_time=1.028078|dts=92526|dts_time=1.028067|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=1008|pos=56249|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=92527|pkt_pts_time=1.028078|pkt_dts=92526|pkt_dts_time=1.028067|best_effort_timestamp=92527|best_effort_timestamp_time=1.028078|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=56249|pkt_size=1008|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=32|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=92527|pkt_pts_time=1.028078|pkt_dts=92526|pkt_dts_time=1.028067|best_effort_timestamp=92527|best_effort_timestamp_time=1.028078|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=56249|pkt_size=1008|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=32|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleftside_data|side_data_type=H.26[45] User Data Unregistered SEI message + packet|codec_type=video|stream_index=0|pts=101536|pts_time=1.128178|dts=95529|dts_time=1.061433|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=1236|pos=57257|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=95530|pkt_pts_time=1.061444|pkt_dts=95529|pkt_dts_time=1.061433|best_effort_timestamp=95530|best_effort_timestamp_time=1.061444|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=53691|pkt_size=2558|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=31|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=95530|pkt_pts_time=1.061444|pkt_dts=95529|pkt_dts_time=1.061433|best_effort_timestamp=95530|best_effort_timestamp_time=1.061444|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=53691|pkt_size=2558|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=31|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleftside_data|side_data_type=H.26[45] User Data Unregistered SEI message + packet|codec_type=video|stream_index=0|pts=98533|pts_time=1.094811|dts=98532|dts_time=1.094800|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=607|pos=58493|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=98533|pkt_pts_time=1.094811|pkt_dts=98532|pkt_dts_time=1.094800|best_effort_timestamp=98533|best_effort_timestamp_time=1.094811|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=58493|pkt_size=607|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=34|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=98533|pkt_pts_time=1.094811|pkt_dts=98532|pkt_dts_time=1.094800|best_effort_timestamp=98533|best_effort_timestamp_time=1.094811|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=58493|pkt_size=607|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=34|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleftside_data|side_data_type=H.26[45] User Data Unregistered SEI message + packet|codec_type=video|stream_index=0|pts=107542|pts_time=1.194911|dts=101535|dts_time=1.128167|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=1883|pos=59100|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=101536|pkt_pts_time=1.128178|pkt_dts=101535|pkt_dts_time=1.128167|best_effort_timestamp=101536|best_effort_timestamp_time=1.128178|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=57257|pkt_size=1236|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=33|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=101536|pkt_pts_time=1.128178|pkt_dts=101535|pkt_dts_time=1.128167|best_effort_timestamp=101536|best_effort_timestamp_time=1.128178|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=57257|pkt_size=1236|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=33|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleftside_data|side_data_type=H.26[45] User Data Unregistered SEI message + packet|codec_type=video|stream_index=0|pts=104539|pts_time=1.161544|dts=104538|dts_time=1.161533|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=893|pos=60983|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=104539|pkt_pts_time=1.161544|pkt_dts=104538|pkt_dts_time=1.161533|best_effort_timestamp=104539|best_effort_timestamp_time=1.161544|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=60983|pkt_size=893|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=36|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=104539|pkt_pts_time=1.161544|pkt_dts=104538|pkt_dts_time=1.161533|best_effort_timestamp=104539|best_effort_timestamp_time=1.161544|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=60983|pkt_size=893|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=36|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleftside_data|side_data_type=H.26[45] User Data Unregistered SEI message + packet|codec_type=video|stream_index=0|pts=113548|pts_time=1.261644|dts=107541|dts_time=1.194900|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=1305|pos=61876|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=107542|pkt_pts_time=1.194911|pkt_dts=107541|pkt_dts_time=1.194900|best_effort_timestamp=107542|best_effort_timestamp_time=1.194911|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=59100|pkt_size=1883|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=35|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=107542|pkt_pts_time=1.194911|pkt_dts=107541|pkt_dts_time=1.194900|best_effort_timestamp=107542|best_effort_timestamp_time=1.194911|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=59100|pkt_size=1883|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=35|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleftside_data|side_data_type=H.26[45] User Data Unregistered SEI message + packet|codec_type=video|stream_index=0|pts=110545|pts_time=1.228278|dts=110544|dts_time=1.228267|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=472|pos=63181|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=110545|pkt_pts_time=1.228278|pkt_dts=110544|pkt_dts_time=1.228267|best_effort_timestamp=110545|best_effort_timestamp_time=1.228278|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=63181|pkt_size=472|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=38|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=110545|pkt_pts_time=1.228278|pkt_dts=110544|pkt_dts_time=1.228267|best_effort_timestamp=110545|best_effort_timestamp_time=1.228278|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=63181|pkt_size=472|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=38|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleftside_data|side_data_type=H.26[45] User Data Unregistered SEI message + packet|codec_type=video|stream_index=0|pts=119554|pts_time=1.328378|dts=113547|dts_time=1.261633|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=1411|pos=63653|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=113548|pkt_pts_time=1.261644|pkt_dts=113547|pkt_dts_time=1.261633|best_effort_timestamp=113548|best_effort_timestamp_time=1.261644|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=61876|pkt_size=1305|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=37|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=113548|pkt_pts_time=1.261644|pkt_dts=113547|pkt_dts_time=1.261633|best_effort_timestamp=113548|best_effort_timestamp_time=1.261644|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=61876|pkt_size=1305|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=37|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleftside_data|side_data_type=H.26[45] User Data Unregistered SEI message + packet|codec_type=video|stream_index=0|pts=116551|pts_time=1.295011|dts=116550|dts_time=1.295000|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=616|pos=65064|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=116551|pkt_pts_time=1.295011|pkt_dts=116550|pkt_dts_time=1.295000|best_effort_timestamp=116551|best_effort_timestamp_time=1.295011|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=65064|pkt_size=616|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=40|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=116551|pkt_pts_time=1.295011|pkt_dts=116550|pkt_dts_time=1.295000|best_effort_timestamp=116551|best_effort_timestamp_time=1.295011|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=65064|pkt_size=616|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=40|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleftside_data|side_data_type=H.26[45] User Data Unregistered SEI message + packet|codec_type=video|stream_index=0|pts=125560|pts_time=1.395111|dts=119553|dts_time=1.328367|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=1291|pos=65680|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=119554|pkt_pts_time=1.328378|pkt_dts=119553|pkt_dts_time=1.328367|best_effort_timestamp=119554|best_effort_timestamp_time=1.328378|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=63653|pkt_size=1411|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=39|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=119554|pkt_pts_time=1.328378|pkt_dts=119553|pkt_dts_time=1.328367|best_effort_timestamp=119554|best_effort_timestamp_time=1.328378|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=63653|pkt_size=1411|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=39|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleftside_data|side_data_type=H.26[45] User Data Unregistered SEI message + packet|codec_type=video|stream_index=0|pts=122557|pts_time=1.361744|dts=122556|dts_time=1.361733|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=470|pos=66971|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=122557|pkt_pts_time=1.361744|pkt_dts=122556|pkt_dts_time=1.361733|best_effort_timestamp=122557|best_effort_timestamp_time=1.361744|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=66971|pkt_size=470|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=42|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=122557|pkt_pts_time=1.361744|pkt_dts=122556|pkt_dts_time=1.361733|best_effort_timestamp=122557|best_effort_timestamp_time=1.361744|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=66971|pkt_size=470|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=42|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleftside_data|side_data_type=H.26[45] User Data Unregistered SEI message + packet|codec_type=video|stream_index=0|pts=131566|pts_time=1.461844|dts=125559|dts_time=1.395100|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=1977|pos=67441|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=125560|pkt_pts_time=1.395111|pkt_dts=125559|pkt_dts_time=1.395100|best_effort_timestamp=125560|best_effort_timestamp_time=1.395111|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=65680|pkt_size=1291|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=41|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=125560|pkt_pts_time=1.395111|pkt_dts=125559|pkt_dts_time=1.395100|best_effort_timestamp=125560|best_effort_timestamp_time=1.395111|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=65680|pkt_size=1291|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=41|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleftside_data|side_data_type=H.26[45] User Data Unregistered SEI message + packet|codec_type=video|stream_index=0|pts=128563|pts_time=1.428478|dts=128562|dts_time=1.428467|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=436|pos=69418|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=128563|pkt_pts_time=1.428478|pkt_dts=128562|pkt_dts_time=1.428467|best_effort_timestamp=128563|best_effort_timestamp_time=1.428478|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=69418|pkt_size=436|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=44|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=128563|pkt_pts_time=1.428478|pkt_dts=128562|pkt_dts_time=1.428467|best_effort_timestamp=128563|best_effort_timestamp_time=1.428478|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=69418|pkt_size=436|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=44|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleftside_data|side_data_type=H.26[45] User Data Unregistered SEI message + packet|codec_type=video|stream_index=0|pts=137572|pts_time=1.528578|dts=131565|dts_time=1.461833|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=2566|pos=69854|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=131566|pkt_pts_time=1.461844|pkt_dts=131565|pkt_dts_time=1.461833|best_effort_timestamp=131566|best_effort_timestamp_time=1.461844|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=67441|pkt_size=1977|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=43|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=131566|pkt_pts_time=1.461844|pkt_dts=131565|pkt_dts_time=1.461833|best_effort_timestamp=131566|best_effort_timestamp_time=1.461844|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=67441|pkt_size=1977|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=43|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleftside_data|side_data_type=H.26[45] User Data Unregistered SEI message + packet|codec_type=video|stream_index=0|pts=134569|pts_time=1.495211|dts=134568|dts_time=1.495200|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=886|pos=72420|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=134569|pkt_pts_time=1.495211|pkt_dts=134568|pkt_dts_time=1.495200|best_effort_timestamp=134569|best_effort_timestamp_time=1.495211|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=72420|pkt_size=886|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=46|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=134569|pkt_pts_time=1.495211|pkt_dts=134568|pkt_dts_time=1.495200|best_effort_timestamp=134569|best_effort_timestamp_time=1.495211|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=72420|pkt_size=886|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=46|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleftside_data|side_data_type=H.26[45] User Data Unregistered SEI message + packet|codec_type=video|stream_index=0|pts=140575|pts_time=1.561944|dts=137571|dts_time=1.528567|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=1330|pos=73306|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=137572|pkt_pts_time=1.528578|pkt_dts=137571|pkt_dts_time=1.528567|best_effort_timestamp=137572|best_effort_timestamp_time=1.528578|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=69854|pkt_size=2566|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=45|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=137572|pkt_pts_time=1.528578|pkt_dts=137571|pkt_dts_time=1.528567|best_effort_timestamp=137572|best_effort_timestamp_time=1.528578|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=69854|pkt_size=2566|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=45|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleftside_data|side_data_type=H.26[45] User Data Unregistered SEI message + packet|codec_type=video|stream_index=0|pts=143578|pts_time=1.595311|dts=140574|dts_time=1.561933|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=2227|pos=74636|flags=K_ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=140575|pkt_pts_time=1.561944|pkt_dts=140574|pkt_dts_time=1.561933|best_effort_timestamp=140575|best_effort_timestamp_time=1.561944|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=73306|pkt_size=1330|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=47|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=140575|pkt_pts_time=1.561944|pkt_dts=140574|pkt_dts_time=1.561933|best_effort_timestamp=140575|best_effort_timestamp_time=1.561944|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=73306|pkt_size=1330|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=47|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleftside_data|side_data_type=H.26[45] User Data Unregistered SEI message + packet|codec_type=video|stream_index=0|pts=149584|pts_time=1.662044|dts=143577|dts_time=1.595300|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=2210|pos=76863|flags=__ -frame|media_type=video|stream_index=0|key_frame=1|pkt_pts=143578|pkt_pts_time=1.595311|pkt_dts=143577|pkt_dts_time=1.595300|best_effort_timestamp=143578|best_effort_timestamp_time=1.595311|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=74636|pkt_size=2227|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=I|coded_picture_number=48|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft +frame|media_type=video|stream_index=0|key_frame=1|pkt_pts=143578|pkt_pts_time=1.595311|pkt_dts=143577|pkt_dts_time=1.595300|best_effort_timestamp=143578|best_effort_timestamp_time=1.595311|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=74636|pkt_size=2227|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=I|coded_picture_number=48|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleftside_data|side_data_type=H.26[45] User Data Unregistered SEI message + packet|codec_type=video|stream_index=0|pts=146581|pts_time=1.628678|dts=146580|dts_time=1.628667|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=1498|pos=79073|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=146581|pkt_pts_time=1.628678|pkt_dts=146580|pkt_dts_time=1.628667|best_effort_timestamp=146581|best_effort_timestamp_time=1.628678|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=79073|pkt_size=1498|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=50|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=146581|pkt_pts_time=1.628678|pkt_dts=146580|pkt_dts_time=1.628667|best_effort_timestamp=146581|best_effort_timestamp_time=1.628678|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=79073|pkt_size=1498|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=50|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleftside_data|side_data_type=H.26[45] User Data Unregistered SEI message + packet|codec_type=video|stream_index=0|pts=155590|pts_time=1.728778|dts=149583|dts_time=1.662033|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=1721|pos=80571|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=149584|pkt_pts_time=1.662044|pkt_dts=149583|pkt_dts_time=1.662033|best_effort_timestamp=149584|best_effort_timestamp_time=1.662044|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=76863|pkt_size=2210|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=49|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=149584|pkt_pts_time=1.662044|pkt_dts=149583|pkt_dts_time=1.662033|best_effort_timestamp=149584|best_effort_timestamp_time=1.662044|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=76863|pkt_size=2210|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=49|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleftside_data|side_data_type=H.26[45] User Data Unregistered SEI message + packet|codec_type=video|stream_index=0|pts=152587|pts_time=1.695411|dts=152586|dts_time=1.695400|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=1238|pos=82292|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=152587|pkt_pts_time=1.695411|pkt_dts=152586|pkt_dts_time=1.695400|best_effort_timestamp=152587|best_effort_timestamp_time=1.695411|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=82292|pkt_size=1238|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=52|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=152587|pkt_pts_time=1.695411|pkt_dts=152586|pkt_dts_time=1.695400|best_effort_timestamp=152587|best_effort_timestamp_time=1.695411|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=82292|pkt_size=1238|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=52|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleftside_data|side_data_type=H.26[45] User Data Unregistered SEI message + packet|codec_type=video|stream_index=0|pts=161596|pts_time=1.795511|dts=155589|dts_time=1.728767|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=1753|pos=83530|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=155590|pkt_pts_time=1.728778|pkt_dts=155589|pkt_dts_time=1.728767|best_effort_timestamp=155590|best_effort_timestamp_time=1.728778|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=80571|pkt_size=1721|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=51|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=155590|pkt_pts_time=1.728778|pkt_dts=155589|pkt_dts_time=1.728767|best_effort_timestamp=155590|best_effort_timestamp_time=1.728778|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=80571|pkt_size=1721|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=51|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleftside_data|side_data_type=H.26[45] User Data Unregistered SEI message + packet|codec_type=video|stream_index=0|pts=158593|pts_time=1.762144|dts=158592|dts_time=1.762133|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=1014|pos=85283|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=158593|pkt_pts_time=1.762144|pkt_dts=158592|pkt_dts_time=1.762133|best_effort_timestamp=158593|best_effort_timestamp_time=1.762144|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=85283|pkt_size=1014|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=54|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=158593|pkt_pts_time=1.762144|pkt_dts=158592|pkt_dts_time=1.762133|best_effort_timestamp=158593|best_effort_timestamp_time=1.762144|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=85283|pkt_size=1014|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=54|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleftside_data|side_data_type=H.26[45] User Data Unregistered SEI message + packet|codec_type=video|stream_index=0|pts=167602|pts_time=1.862244|dts=161595|dts_time=1.795500|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=2408|pos=86297|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=161596|pkt_pts_time=1.795511|pkt_dts=161595|pkt_dts_time=1.795500|best_effort_timestamp=161596|best_effort_timestamp_time=1.795511|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=83530|pkt_size=1753|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=53|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=161596|pkt_pts_time=1.795511|pkt_dts=161595|pkt_dts_time=1.795500|best_effort_timestamp=161596|best_effort_timestamp_time=1.795511|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=83530|pkt_size=1753|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=53|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleftside_data|side_data_type=H.26[45] User Data Unregistered SEI message + packet|codec_type=video|stream_index=0|pts=164599|pts_time=1.828878|dts=164598|dts_time=1.828867|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=1727|pos=88705|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=164599|pkt_pts_time=1.828878|pkt_dts=164598|pkt_dts_time=1.828867|best_effort_timestamp=164599|best_effort_timestamp_time=1.828878|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=88705|pkt_size=1727|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=56|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=164599|pkt_pts_time=1.828878|pkt_dts=164598|pkt_dts_time=1.828867|best_effort_timestamp=164599|best_effort_timestamp_time=1.828878|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=88705|pkt_size=1727|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=56|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleftside_data|side_data_type=H.26[45] User Data Unregistered SEI message + packet|codec_type=video|stream_index=0|pts=173608|pts_time=1.928978|dts=167601|dts_time=1.862233|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=1504|pos=90432|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=167602|pkt_pts_time=1.862244|pkt_dts=167601|pkt_dts_time=1.862233|best_effort_timestamp=167602|best_effort_timestamp_time=1.862244|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=86297|pkt_size=2408|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=55|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=167602|pkt_pts_time=1.862244|pkt_dts=167601|pkt_dts_time=1.862233|best_effort_timestamp=167602|best_effort_timestamp_time=1.862244|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=86297|pkt_size=2408|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=55|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleftside_data|side_data_type=H.26[45] User Data Unregistered SEI message + packet|codec_type=video|stream_index=0|pts=170605|pts_time=1.895611|dts=170604|dts_time=1.895600|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=957|pos=91936|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=170605|pkt_pts_time=1.895611|pkt_dts=170604|pkt_dts_time=1.895600|best_effort_timestamp=170605|best_effort_timestamp_time=1.895611|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=91936|pkt_size=957|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=58|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=170605|pkt_pts_time=1.895611|pkt_dts=170604|pkt_dts_time=1.895600|best_effort_timestamp=170605|best_effort_timestamp_time=1.895611|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=91936|pkt_size=957|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=58|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleftside_data|side_data_type=H.26[45] User Data Unregistered SEI message + packet|codec_type=video|stream_index=0|pts=179614|pts_time=1.995711|dts=173607|dts_time=1.928967|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=1890|pos=92893|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=173608|pkt_pts_time=1.928978|pkt_dts=173607|pkt_dts_time=1.928967|best_effort_timestamp=173608|best_effort_timestamp_time=1.928978|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=90432|pkt_size=1504|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=57|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=173608|pkt_pts_time=1.928978|pkt_dts=173607|pkt_dts_time=1.928967|best_effort_timestamp=173608|best_effort_timestamp_time=1.928978|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=90432|pkt_size=1504|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=57|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleftside_data|side_data_type=H.26[45] User Data Unregistered SEI message + packet|codec_type=video|stream_index=0|pts=176611|pts_time=1.962344|dts=176610|dts_time=1.962333|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=1239|pos=94783|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=176611|pkt_pts_time=1.962344|pkt_dts=176610|pkt_dts_time=1.962333|best_effort_timestamp=176611|best_effort_timestamp_time=1.962344|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=94783|pkt_size=1239|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=60|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=176611|pkt_pts_time=1.962344|pkt_dts=176610|pkt_dts_time=1.962333|best_effort_timestamp=176611|best_effort_timestamp_time=1.962344|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=94783|pkt_size=1239|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=60|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleftside_data|side_data_type=H.26[45] User Data Unregistered SEI message + packet|codec_type=video|stream_index=0|pts=185620|pts_time=2.062444|dts=179613|dts_time=1.995700|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=1856|pos=96022|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=179614|pkt_pts_time=1.995711|pkt_dts=179613|pkt_dts_time=1.995700|best_effort_timestamp=179614|best_effort_timestamp_time=1.995711|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=92893|pkt_size=1890|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=59|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=179614|pkt_pts_time=1.995711|pkt_dts=179613|pkt_dts_time=1.995700|best_effort_timestamp=179614|best_effort_timestamp_time=1.995711|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=92893|pkt_size=1890|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=59|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleftside_data|side_data_type=H.26[45] User Data Unregistered SEI message + packet|codec_type=video|stream_index=0|pts=182617|pts_time=2.029078|dts=182616|dts_time=2.029067|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=1302|pos=97878|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=182617|pkt_pts_time=2.029078|pkt_dts=182616|pkt_dts_time=2.029067|best_effort_timestamp=182617|best_effort_timestamp_time=2.029078|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=97878|pkt_size=1302|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=62|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=182617|pkt_pts_time=2.029078|pkt_dts=182616|pkt_dts_time=2.029067|best_effort_timestamp=182617|best_effort_timestamp_time=2.029078|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=97878|pkt_size=1302|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=62|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleftside_data|side_data_type=H.26[45] User Data Unregistered SEI message + packet|codec_type=video|stream_index=0|pts=191626|pts_time=2.129178|dts=185619|dts_time=2.062433|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=1666|pos=99180|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=185620|pkt_pts_time=2.062444|pkt_dts=185619|pkt_dts_time=2.062433|best_effort_timestamp=185620|best_effort_timestamp_time=2.062444|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=96022|pkt_size=1856|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=61|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=185620|pkt_pts_time=2.062444|pkt_dts=185619|pkt_dts_time=2.062433|best_effort_timestamp=185620|best_effort_timestamp_time=2.062444|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=96022|pkt_size=1856|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=61|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleftside_data|side_data_type=H.26[45] User Data Unregistered SEI message + packet|codec_type=video|stream_index=0|pts=188623|pts_time=2.095811|dts=188622|dts_time=2.095800|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=974|pos=100846|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=188623|pkt_pts_time=2.095811|pkt_dts=188622|pkt_dts_time=2.095800|best_effort_timestamp=188623|best_effort_timestamp_time=2.095811|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=100846|pkt_size=974|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=64|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=188623|pkt_pts_time=2.095811|pkt_dts=188622|pkt_dts_time=2.095800|best_effort_timestamp=188623|best_effort_timestamp_time=2.095811|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=100846|pkt_size=974|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=B|coded_picture_number=64|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleftside_data|side_data_type=H.26[45] User Data Unregistered SEI message + packet|codec_type=video|stream_index=0|pts=197632|pts_time=2.195911|dts=191625|dts_time=2.129167|duration=3003|duration_time=0.033367|convergence_duration=N/A|convergence_duration_time=N/A|size=580|pos=101820|flags=__ -frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=191626|pkt_pts_time=2.129178|pkt_dts=N/A|pkt_dts_time=N/A|best_effort_timestamp=191626|best_effort_timestamp_time=2.129178|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=99180|pkt_size=1666|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=63|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleft +frame|media_type=video|stream_index=0|key_frame=0|pkt_pts=191626|pkt_pts_time=2.129178|pkt_dts=N/A|pkt_dts_time=N/A|best_effort_timestamp=191626|best_effort_timestamp_time=2.129178|pkt_duration=3003|pkt_duration_time=0.033367|pkt_pos=99180|pkt_size=1666|width=160|height=240|pix_fmt=yuv420p|sample_aspect_ratio=2:1|pict_type=P|coded_picture_number=63|display_picture_number=0|interlaced_frame=0|top_field_first=0|repeat_pict=0|color_range=tv|color_space=smpte170m|color_primaries=smpte170m|color_transfer=bt709|chroma_location=topleftside_data|side_data_type=H.26[45] User Data Unregistered SEI message + stream|index=0|codec_name=h264|profile=77|codec_type=video|codec_time_base=212521/12744000|codec_tag_string=avc1|codec_tag=0x31637661|width=160|height=240|coded_width=160|coded_height=240|closed_captions=0|has_b_frames=1|sample_aspect_ratio=2:1|display_aspect_ratio=4:3|pix_fmt=yuv420p|level=12|color_range=tv|color_space=smpte170m|color_transfer=bt709|color_primaries=smpte170m|chroma_location=topleft|field_order=unknown|timecode=N/A|refs=2|is_avc=true|nal_length_size=4|id=N/A|r_frame_rate=30000/1001|avg_frame_rate=6372000/212521|time_base=1/90000|start_pts=0|start_time=0.000000|duration_ts=2125200|duration=23.613333|bit_rate=333874|max_bit_rate=N/A|bits_per_raw_sample=8|nb_frames=708|nb_read_frames=65|nb_read_packets=66|disposition:default=1|disposition:dub=0|disposition:original=0|disposition:comment=0|disposition:lyrics=0|disposition:karaoke=0|disposition:forced=0|disposition:hearing_impaired=0|disposition:visual_impaired=0|disposition:clean_effects=0|disposition:attached_pic=0|disposition:timed_thumbnails=0|tag:rotate=0|tag:creation_time=2008-05-12T20:59:27.000000Z|tag:language=eng|tag:handler_name=Apple Video Media Handler|tag:encoder=H.264 side_data|side_data_type=Display Matrix|displaymatrix=\n00000000: 131072 0 0\n00000001: 0 65536 0\n00000002: 0 0 1073741824\n|rotation=0 diff --git a/externals/ffmpeg/tests/ref/fate/sws-pixdesc-query b/externals/ffmpeg/tests/ref/fate/sws-pixdesc-query index bc9a0d874..c3cccfa49 100755 --- a/externals/ffmpeg/tests/ref/fate/sws-pixdesc-query +++ b/externals/ffmpeg/tests/ref/fate/sws-pixdesc-query @@ -57,6 +57,8 @@ isNBPS: nv20le p010be p010le + x2rgb10be + x2rgb10le xyz12be xyz12le y210be @@ -141,6 +143,7 @@ isBE: rgb555be rgb565be rgba64be + x2rgb10be xyz12be y210be ya16be @@ -436,6 +439,8 @@ isRGB: rgb8 rgba64be rgba64le + x2rgb10be + x2rgb10le Gray: gray @@ -582,6 +587,8 @@ AnyRGB: rgb8 rgba64be rgba64le + x2rgb10be + x2rgb10le ALPHA: ayuv64be @@ -689,6 +696,8 @@ Packed: rgba64le uyvy422 uyyvyy411 + x2rgb10be + x2rgb10le xyz12be xyz12le y210be @@ -853,6 +862,8 @@ PackedRGB: rgb8 rgba64be rgba64le + x2rgb10be + x2rgb10le PlanarRGB: gbrap diff --git a/externals/ffmpeg/tests/ref/lavf-fate/av1.mp4 b/externals/ffmpeg/tests/ref/lavf-fate/av1.mp4 index 38d2a80af..c8dc8e9a1 100755 --- a/externals/ffmpeg/tests/ref/lavf-fate/av1.mp4 +++ b/externals/ffmpeg/tests/ref/lavf-fate/av1.mp4 @@ -1,3 +1,3 @@ -0388467214421a19ba65d10a74dc35c0 *tests/data/lavf-fate/lavf.av1.mp4 -55936 tests/data/lavf-fate/lavf.av1.mp4 +4eed679a1d3e18edfd95b268167d8060 *tests/data/lavf-fate/lavf.av1.mp4 +55940 tests/data/lavf-fate/lavf.av1.mp4 tests/data/lavf-fate/lavf.av1.mp4 CRC=0x7c27cc15 diff --git a/externals/ffmpeg/tools/python/convert_from_tensorflow.py b/externals/ffmpeg/tools/python/convert_from_tensorflow.py index 8c0a9be7b..85db7bf71 100755 --- a/externals/ffmpeg/tools/python/convert_from_tensorflow.py +++ b/externals/ffmpeg/tools/python/convert_from_tensorflow.py @@ -72,7 +72,7 @@ class TFConverter: self.conv2d_scopename_inputname_dict = {} self.op2code = {'Conv2D':1, 'DepthToSpace':2, 'MirrorPad':3, 'Maximum':4, 'MathBinary':5, 'MathUnary':6} self.mathbin2code = {'Sub':0, 'Add':1, 'Mul':2, 'RealDiv':3, 'Minimum':4} - self.mathun2code = {'Abs':0} + self.mathun2code = {'Abs':0, 'Sin':1, 'Cos':2, 'Tan':3, 'Asin':4, 'Acos':5, 'Atan':6, 'Sinh':7, 'Cosh':8, 'Tanh':9, 'Asinh':10, 'Acosh':11, 'Atanh':12} self.mirrorpad_mode = {'CONSTANT':0, 'REFLECT':1, 'SYMMETRIC':2} self.name_operand_dict = {} diff --git a/externals/ffmpeg/tools/python/convert_header.py b/externals/ffmpeg/tools/python/convert_header.py index ad4491729..9851d8414 100755 --- a/externals/ffmpeg/tools/python/convert_header.py +++ b/externals/ffmpeg/tools/python/convert_header.py @@ -23,4 +23,4 @@ str = 'FFMPEGDNNNATIVE' major = 1 # increase minor when we don't have to re-convert the model file -minor = 6 +minor = 18 diff --git a/externals/ffmpeg/tools/target_dec_fuzzer.c b/externals/ffmpeg/tools/target_dec_fuzzer.c index 66ee99a91..1ecafb9c0 100755 --- a/externals/ffmpeg/tools/target_dec_fuzzer.c +++ b/externals/ffmpeg/tools/target_dec_fuzzer.c @@ -159,6 +159,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { case AV_CODEC_ID_HNM4_VIDEO: maxpixels /= 128; break; case AV_CODEC_ID_IFF_ILBM: maxpixels /= 128; break; case AV_CODEC_ID_INDEO4: maxpixels /= 128; break; + case AV_CODEC_ID_LAGARITH: maxpixels /= 1024; break; case AV_CODEC_ID_LSCR: maxpixels /= 16; break; case AV_CODEC_ID_MOTIONPIXELS:maxpixels /= 256; break; case AV_CODEC_ID_MP4ALS: maxsamples /= 65536; break; diff --git a/externals/ffmpeg/tools/target_dem_fuzzer.c b/externals/ffmpeg/tools/target_dem_fuzzer.c index cc097da0d..b8356c5aa 100755 --- a/externals/ffmpeg/tools/target_dem_fuzzer.c +++ b/externals/ffmpeg/tools/target_dem_fuzzer.c @@ -18,6 +18,7 @@ #include "config.h" #include "libavutil/avassert.h" +#include "libavutil/avstring.h" #include "libavcodec/avcodec.h" #include "libavcodec/bytestream.h" @@ -110,14 +111,38 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { error("Failed avformat_alloc_context()"); if (size > 2048) { + int flags; + char extension[64]; + GetByteContext gbc; memcpy (filename, data + size - 1024, 1024); bytestream2_init(&gbc, data + size - 2048, 1024); size -= 2048; io_buffer_size = bytestream2_get_le32(&gbc) & 0xFFFFFFF; - seekable = bytestream2_get_byte(&gbc) & 1; + flags = bytestream2_get_byte(&gbc); + seekable = flags & 1; filesize = bytestream2_get_le64(&gbc) & 0x7FFFFFFFFFFFFFFF; + + if ((flags & 2) && strlen(filename) < sizeof(filename) / 2) { + AVInputFormat *avif = NULL; + int avif_count = 0; + while ((avif = av_iformat_next(avif))) { + if (avif->extensions) + avif_count ++; + } + avif_count = bytestream2_get_le32(&gbc) % avif_count; + + while ((avif = av_iformat_next(avif))) { + if (avif->extensions) + if (!avif_count--) + break; + } + av_strlcpy(extension, avif->extensions, sizeof(extension)); + if (strchr(extension, ',')) + *strchr(extension, ',') = 0; + av_strlcatf(filename, sizeof(filename), ".%s", extension); + } } io_buffer = av_malloc(io_buffer_size); if (!io_buffer)