opencv / opencv_contrib

Repository for OpenCV's extra modules
Apache License 2.0
9.34k stars 5.75k forks source link

cudacodec writer output video with invalid frame count using python #3556

Closed zhupengjia closed 11 months ago

zhupengjia commented 1 year ago

System information (version)

General configuration for OpenCV 4.8.0 =====================================
  Version control:               4.8.0                                                                                                                                                                                                                                                                                    Extra modules:                                                                                                                                                Location (extra):            /root/opencv-python/opencv_contrib/modules                                                                                     Version control (extra):     4.8.0

  Platform:                                                                                                                                                     Timestamp:                   2023-08-30T00:38:34Z                                                                                                           Host:                        Linux 6.4.4-arch1-1 x86_64                                                                                                     CMake:                       3.27.2
    CMake generator:             Ninja                                                                                                                          CMake build tool:            /usr/bin/ninja                                                                                                                 Configuration:               RELEASE                                                                                                                                                                                                                                                                                  CPU/HW features:                                                                                                                                              Baseline:                    SSE SSE2 SSE3                                                                                                                    requested:                 SSE3
    Dispatched code generation:  SSE4_1 SSE4_2 FP16 AVX AVX2 AVX512_SKX                                                                                           requested:                 SSE4_1 SSE4_2 AVX FP16 AVX2 AVX512_SKX                                                                                           SSE4_1 (13 files):         + SSSE3 SSE4_1
      SSE4_2 (1 files):          + SSSE3 SSE4_1 POPCNT SSE4_2                                                                                                     FP16 (0 files):            + SSSE3 SSE4_1 POPCNT SSE4_2 FP16 AVX
      AVX (3 files):             + SSSE3 SSE4_1 POPCNT SSE4_2 AVX                                                                                                 AVX2 (25 files):           + SSSE3 SSE4_1 POPCNT SSE4_2 FP16 FMA3 AVX AVX2                                                                                  AVX512_SKX (2 files):      + SSSE3 SSE4_1 POPCNT SSE4_2 FP16 FMA3 AVX AVX2 AVX_512F AVX512_COMMON AVX512_SKX                                             
  C/C++:                                                                                                                                           [70/1946]    Built as dynamic libs?:      NO
    C++ standard:                11
    C++ Compiler:                /usr/bin/g++-10  (ver 10.5.0)
    C++ flags (Release):         -fsigned-char -W -Wall -Wreturn-type -Wnon-virtual-dtor -Waddress -Wsequence-point -Wformat -Wformat-security -Wmissing-declarations -Wundef -Winit-self -Wpointer-arith -Wshadow -Wsign-promo -Wuninitialized -Wsuggest-override -Wno-delete-non-virtual-dtor -Wno-comment -Wimplicit-fallthrough=3 -Wno-strict-overflow -fdiagnostics-show-option -Wno-long-long -pthread -fomit-frame-pointer -ffunction-sections -fdata-sections  -msse -msse2 -msse3 -fvisibility=hidden -fvisibility-inlines-hidden -O3 -DNDEBUG  -DNDEBUG
    C++ flags (Debug):           -fsigned-char -W -Wall -Wreturn-type -Wnon-virtual-dtor -Waddress -Wsequence-point -Wformat -Wformat-security -Wmissing-declarations -Wundef -Winit-self -Wpointer-arith -Wshadow -Wsign-promo -Wuninitialized -Wsuggest-override -Wno-delete-non-virtual-dtor -Wno-comment -Wimplicit-fallthrough=3 -Wno-strict-overflow -fdiagnostics-show-option -Wno-long-long -pthread -fomit-frame-pointer -ffunction-sections -fdata-sections  -msse -msse2 -msse3 -fvisibility=hidden -fvisibility-inlines-hidden -g  -O0 -DDEBUG -D_DEBUG
    C Compiler:                  /usr/bin/gcc-10
    C flags (Release):           -fsigned-char -W -Wall -Wreturn-type -Waddress -Wsequence-point -Wformat -Wformat-security -Wmissing-declarations -Wmissing-prototypes -Wstrict-prototypes -Wundef -Winit-self -Wpointer-arith -Wshadow -Wuninitialized -Wno-comment -Wimplicit-fallthrough=3 -Wno-strict-overflow -fdiagnostics-show-option -Wno-long-long -pthread -fomit-frame-pointer -ffunction-sections -fdata-sections  -msse -msse2 -msse3 -fvisibility=hidden -O3 -DNDEBUG  -DNDEBUG
    C flags (Debug):             -fsigned-char -W -Wall -Wreturn-type -Waddress -Wsequence-point -Wformat -Wformat-security -Wmissing-declarations -Wmissing-prototypes -Wstrict-prototypes -Wundef -Winit-self -Wpointer-arith -Wshadow -Wuninitialized -Wno-comment -Wimplicit-fallthrough=3 -Wno-strict-overflow -fdiagnostics-show-option -Wno-long-long -pthread -fomit-frame-pointer -ffunction-sections -fdata-sections  -msse -msse2 -msse3 -fvisibility=hidden -g  -O0 -DDEBUG -D_DEBUG
    Linker flags (Release):      -Wl,--exclude-libs,libippicv.a -Wl,--exclude-libs,libippiw.a   -Wl,--gc-sections -Wl,--as-needed -Wl,--no-undefined
    Linker flags (Debug):        -Wl,--exclude-libs,libippicv.a -Wl,--exclude-libs,libippiw.a   -Wl,--gc-sections -Wl,--as-needed -Wl,--no-undefined
    ccache:                      NO
    Precompiled headers:         NO
    Extra dependencies:          va va-drm /usr/lib/x86_64-linux-gnu/libjpeg.so /usr/lib/x86_64-linux-gnu/libpng.so /usr/lib/x86_64-linux-gnu/libz.so /usr/lib/x86_64-linux-gnu/libcuda.so /usr/lib/libnvcuvid.so /usr/lib/libnvidia-encode.so m pthread cudart_static dl rt nppc nppial nppicc nppidei nppif nppig nppim nppist nppisu nppitc npps cublas cudnn cufft -L/usr/lib/x86_64-linux-gnu
    3rdparty dependencies:       ittnotify libwebp libtiff libopenjp2 IlmImf ippiw ippicv

  OpenCV modules:                                                                                                                                               To be built:                 core cudaarithm cudacodec cudaimgproc cudawarping cudev highgui imgcodecs imgproc python3 video videoio                        Disabled:                    freetype world
    Disabled by dependency:      aruco bgsegm bioinspired calib3d ccalib cudabgsegm cudafeatures2d cudafilters cudalegacy cudaobjdetect cudaoptflow cudastereo datasets dnn dnn_objdetect dnn_superres dpm face features2d flann fuzzy gapi hfs img_hash intensity_transform java_bindings_generator js_bindings_generator line_descriptor mcc ml objc_bindings_generator objdetect optflow phase_unwrapping photo plot python_tests quality rapid reg rgbd saliency shape stereo stitching structured_light superres surface_matching text tracking videostab wechat_qrcode xfeatures2d ximgproc xobjdetect xphoto
    Unavailable:                 alphamat cvv hdf java julia matlab ovis python2 sfm ts viz
    Applications:                -
    Documentation:               NO
    Non-free algorithms:         YES

  GUI:                           NONE
    VTK support:                 NO

  Media I/O:
    ZLib:                        /usr/lib/x86_64-linux-gnu/libz.so (ver 1.2.11)
    JPEG:                        /usr/lib/x86_64-linux-gnu/libjpeg.so (ver 80)
    WEBP:                        build (ver encoder: 0x020f)
    PNG:                         /usr/lib/x86_64-linux-gnu/libpng.so (ver 1.6.37)
    TIFF:                        build (ver 42 - 4.2.0)
    JPEG 2000:                   build (ver 2.5.0)
    OpenEXR:                     build (ver 2.3.0)
    HDR:                         YES
    SUNRASTER:                   YES
    PXM:                         YES
    PFM:                         YES
  Video I/O:
    DC1394:                      YES (2.2.6)
    FFMPEG:                      YES
      avcodec:                   YES (58.134.100)
      avformat:                  YES (58.76.100)
      avutil:                    YES (56.70.100)
      swscale:                   YES (5.9.100)
      avresample:                NO
    GStreamer:                   NO
    v4l/v4l2:                    YES (linux/videodev2.h)

  Parallel framework:            TBB (ver 2021.5 interface 12050)

  Trace:                         YES (with Intel ITT)

  Other third-party libraries:
    Intel IPP:                   2021.8 [2021.8.0]
           at:                   /root/opencv-python/_skbuild/linux-x86_64-3.10/cmake-build/3rdparty/ippicv/ippicv_lnx/icv
    Intel IPP IW:                sources (2021.8.0)
              at:                /root/opencv-python/_skbuild/linux-x86_64-3.10/cmake-build/3rdparty/ippicv/ippicv_lnx/iw
    VA:                          YES
    Lapack:                      NO
    Eigen:                       NO
    Custom HAL:                  NO
    Protobuf:                    build (3.19.1)
    Flatbuffers:                 builtin/3rdparty (23.5.9)

  NVIDIA CUDA:                   YES (ver 11.5, CUFFT CUBLAS NVCUVID NVCUVENC)
    NVIDIA GPU arch:             75
    NVIDIA PTX archs:

  cuDNN:                         YES (ver 8.2.4)

  OpenCL:                        YES (INTELVA)
    Include path:                /root/opencv-python/opencv/3rdparty/include/opencl/1.2
    Link libraries:              Dynamic load

  Python 3:
    Interpreter:                 /usr/bin/python3 (ver 3.10.12)
    Libraries:                   /usr/lib/x86_64-linux-gnu/libpython3.10.so (ver 3.10.12)
    numpy:                       /tmp/pip-build-env-1zh6oawl/overlay/local/lib/python3.10/dist-packages/numpy/core/include (ver 1.21.2)
    install path:                python/cv2/python-3

  Python (for build):            /usr/bin/python3

  Install to:                    /root/opencv-python/_skbuild/linux-x86_64-3.10/cmake-install

Detailed description

The output video from cudacodec writer has invalid frame count, which caused failed to open by some video players like VLC.

Steps to reproduce

Install dependencies in ubuntu-22.04:

apt-get update
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends gcc-10 g++-10 nvidia-driver-535 nvidia-cuda-toolkit nvidia-cudnn git libx264-dev libx265-dev cmake wget unzip yasm pkg-config libswscale-dev libtbb2 libtbb-dev libjpeg-dev libpng-dev libavformat-dev libpq-dev libass-dev libdc1394-dev libfreetype6-dev libva-dev libvdpau-dev libvorbis-dev libxcb1-dev libxcb-shm0-dev libxcb-xfixes0-dev libsdl2-dev liblapack-dev libblas-dev ninja-build
DEBIAN_FRONTEND=noninteractive /usr/sbin/update-nvidia-cudnn -u

Download Video_Codec_SDK_12.1.14.zip from nvidia website, copy .so and .h file to /usr/lib and /usr/include/

Compile with opencv-python, and latest opencv and opencv_contrib code

    git clone https://github.com/opencv/opencv-python.git
    git checkout tags/76 -b 4.8.0.76
    cd opencv-python
    sed -i -e "133,134d;153,154d" setup.py
    git submodule update --init --recursive --depth=1
    cd opencv
    git checkout 4.x
    git pull
    cd opencv_contrib
    git checkout 4.x
    git pull
    export CC="gcc-10"
    export CXX="g++-10"
    export ENABLE_HEADLESS=1
    export ENABLE_CONTRIB=1
    export CMAKE_ARGS="-DCMAKE_BUILD_PARALLEL_LEVEL=8 -DCMAKE_BUILD_TYPE=RELEASE -DWITH_CUDA=ON -DWITH_CUDNN=ON -DCUDA_ARCH_BIN=7.5 -DWITH_CUBLAS=ON -DWITH_TBB=ON -DOPENCV_DNN_CUDA=ON -DWITH_NVCUVID=ON -DWITH_NVCUVENC=ON -DOPENCV_ENABLE_NONFREE=ON -DWITH_FFMPEG=ON -DINSTALL_C_EXAMPLES=OFF -DBUILD_EXAMPLES=OFF -DBUILD_PERF_TESTS=OFF -DBUILD_TESTS=OFF -DBUILD_JAVA=OFF -DBUILD_OBJC=OFF -DPYTHON3_LIMITED_API=ON -DBUILD_LIST=core,imgcodecs,videoio,cudaarithm,cudaimgproc,cudawarping,cudev,cudacodec,video,highgui,python3,python_bindings_generator"
    python3 -m pip wheel . --verbose

Download testing video:

wget https://sample-videos.com/video123/mp4/720/big_buck_bunny_720p_10mb.mp4

Testing code named as test_opencv_gpu.py

import cv2
import sys
import ipdb
import time

t1 = time.time()
codec = cv2.cudacodec.H264
color_format = cv2.cudacodec.COLOR_FORMAT_BGR

reader = cv2.VideoCapture(sys.argv[1])
print("input_fps", reader.get(cv2.CAP_PROP_FPS))
print("input_frame_count", reader.get(cv2.CAP_PROP_FRAME_COUNT))
reader.release()

reader = cv2.cudacodec.createVideoReader(sys.argv[1])
reader.set(color_format)
format = reader.format()
fps = format.fps
height = format.height
width = format.width

assert fps != 0, "FPS of input video is 0"

encoder_params_in = cv2.cudacodec.EncoderParams()
stream = cv2.cuda.Stream()

out_path = sys.argv[1][:-4] + "_gpu_out.mp4"
writer = cv2.cudacodec.createVideoWriter(out_path, (width, height), codec, fps=fps, colorFormat=color_format, params=encoder_params_in, stream=stream)

while True:
    ret, frame = reader.nextFrame()
    if not ret or frame is None:
        break
    writer.write(frame)

writer.release()

del reader

reader = cv2.VideoCapture(out_path)
print("fps", reader.get(cv2.CAP_PROP_FPS))
print("frame_count", reader.get(cv2.CAP_PROP_FRAME_COUNT))
reader.release()

print(time.time() - t1)

Run the testing code:

./test_opencv_gpu.py big_buck_bunny_720p_10mb.mp4

The frame_count for output video is -192153584101141.0 -->

Issue submission checklist

cudawarped commented 1 year ago

Currently only raw (cv2.cudacodec.H264, cv2.cudacodec.H265) output is supported in cudacodec::VideoWriter.

Raw files don't have any information regarding the number of frames. You need to place it in a container format to get that information.

zhupengjia commented 1 year ago

Currently only raw (cv2.cudacodec.H264, cv2.cudacodec.H265) output is supported in cudacodec::VideoWriter.

Raw files don't have any information regarding the number of frames. You need to place it in a container format to get that information.

Thank you for the clarification. Given this, we can now close the issue.