Created
August 30, 2022 11:58
-
-
Save Kamino666/09f878289e1e6dc13b0a3b2b508d68a5 to your computer and use it in GitHub Desktop.
针对Python中各种读取视频库的比较
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"cells": [ | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"id": "dNF-t2FO1M6r" | |
}, | |
"source": [ | |
"# Benchmark of Video Reader in Python\n", | |
"\n", | |
"比较Python中的各种读取视频的实现\n", | |
"\n", | |
"This notebook compares several video reader in Python.\n", | |
"\n", | |
"1. OpenCV(cv2)\n", | |
"2. Decord\n", | |
"3. MMCV\n", | |
"4. pyAV" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"source": [ | |
"安装一个新版本的ffmpeg" | |
], | |
"metadata": { | |
"id": "v3mbqj2_50BR" | |
} | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 1, | |
"metadata": { | |
"colab": { | |
"base_uri": "https://localhost:8080/" | |
}, | |
"id": "hDsdrVMS_YFX", | |
"outputId": "ad257ab8-daad-4b61-e9e7-bf58d2c3713c" | |
}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"name": "stdout", | |
"text": [ | |
"Cloning into 'ffmpeg-colab'...\n", | |
"remote: Enumerating objects: 19, done.\u001b[K\n", | |
"remote: Counting objects: 100% (5/5), done.\u001b[K\n", | |
"remote: Compressing objects: 100% (5/5), done.\u001b[K\n", | |
"remote: Total 19 (delta 3), reused 0 (delta 0), pack-reused 14\u001b[K\n", | |
"Unpacking objects: 100% (19/19), done.\n", | |
"FFmpeg was found at /usr/bin/ffmpeg\n", | |
"Removing old FFmpeg\n", | |
"Done\n", | |
"Moving new ffmpeg to /usr/bin\n", | |
"FFmpeg was successfully installed\n" | |
] | |
} | |
], | |
"source": [ | |
"!git clone https://github.com/XniceCraft/ffmpeg-colab.git\n", | |
"!sudo bash ./ffmpeg-colab/install" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"source": [ | |
"安装各种库" | |
], | |
"metadata": { | |
"id": "wvM7RzXW5zU6" | |
} | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 2, | |
"metadata": { | |
"colab": { | |
"base_uri": "https://localhost:8080/" | |
}, | |
"id": "zc3_BslhGo7k", | |
"outputId": "3f8237e7-036a-4eaf-8eae-607ececf2f2b" | |
}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"name": "stdout", | |
"text": [ | |
"Looking in indexes: https://pypi.org/simple, https://us-python.pkg.dev/colab-wheels/public/simple/\n", | |
"Collecting youtube-dl\n", | |
" Downloading youtube_dl-2021.12.17-py2.py3-none-any.whl (1.9 MB)\n", | |
"\u001b[K |████████████████████████████████| 1.9 MB 7.3 MB/s \n", | |
"\u001b[?25hInstalling collected packages: youtube-dl\n", | |
"Successfully installed youtube-dl-2021.12.17\n", | |
"Looking in indexes: https://pypi.org/simple, https://us-python.pkg.dev/colab-wheels/public/simple/\n", | |
"Collecting memory_profiler\n", | |
" Downloading memory_profiler-0.60.0.tar.gz (38 kB)\n", | |
"Requirement already satisfied: psutil in /usr/local/lib/python3.7/dist-packages (from memory_profiler) (5.4.8)\n", | |
"Building wheels for collected packages: memory-profiler\n", | |
" Building wheel for memory-profiler (setup.py) ... \u001b[?25l\u001b[?25hdone\n", | |
" Created wheel for memory-profiler: filename=memory_profiler-0.60.0-py3-none-any.whl size=31284 sha256=1da91e7a81ad45b33dbf0306f36d941dfc2ac8a7053756787e1292632a13ce6c\n", | |
" Stored in directory: /root/.cache/pip/wheels/67/2b/fb/326e30d638c538e69a5eb0aa47f4223d979f502bbdb403950f\n", | |
"Successfully built memory-profiler\n", | |
"Installing collected packages: memory-profiler\n", | |
"Successfully installed memory-profiler-0.60.0\n", | |
"Looking in indexes: https://pypi.org/simple, https://us-python.pkg.dev/colab-wheels/public/simple/\n", | |
"Collecting mmcv\n", | |
" Downloading mmcv-1.6.1.tar.gz (563 kB)\n", | |
"\u001b[K |████████████████████████████████| 563 kB 7.2 MB/s \n", | |
"\u001b[?25hCollecting addict\n", | |
" Downloading addict-2.4.0-py3-none-any.whl (3.8 kB)\n", | |
"Requirement already satisfied: numpy in /usr/local/lib/python3.7/dist-packages (from mmcv) (1.21.6)\n", | |
"Requirement already satisfied: packaging in /usr/local/lib/python3.7/dist-packages (from mmcv) (21.3)\n", | |
"Requirement already satisfied: Pillow in /usr/local/lib/python3.7/dist-packages (from mmcv) (7.1.2)\n", | |
"Requirement already satisfied: pyyaml in /usr/local/lib/python3.7/dist-packages (from mmcv) (6.0)\n", | |
"Collecting yapf\n", | |
" Downloading yapf-0.32.0-py2.py3-none-any.whl (190 kB)\n", | |
"\u001b[K |████████████████████████████████| 190 kB 63.5 MB/s \n", | |
"\u001b[?25hRequirement already satisfied: pyparsing!=3.0.5,>=2.0.2 in /usr/local/lib/python3.7/dist-packages (from packaging->mmcv) (3.0.9)\n", | |
"Building wheels for collected packages: mmcv\n", | |
" Building wheel for mmcv (setup.py) ... \u001b[?25l\u001b[?25hdone\n", | |
" Created wheel for mmcv: filename=mmcv-1.6.1-py2.py3-none-any.whl size=860296 sha256=9fc51c5967cfe708fa7b505cbbbbdfbc8508540ec00591aafc79f17ab0d34d1e\n", | |
" Stored in directory: /root/.cache/pip/wheels/e0/43/68/40160e8aa085d474903f0ad3764bac92e698936bfcf8a5454b\n", | |
"Successfully built mmcv\n", | |
"Installing collected packages: yapf, addict, mmcv\n", | |
"Successfully installed addict-2.4.0 mmcv-1.6.1 yapf-0.32.0\n", | |
"Looking in indexes: https://pypi.org/simple, https://us-python.pkg.dev/colab-wheels/public/simple/\n", | |
"Collecting av\n", | |
" Downloading av-9.2.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (28.2 MB)\n", | |
"\u001b[K |████████████████████████████████| 28.2 MB 1.5 MB/s \n", | |
"\u001b[?25hInstalling collected packages: av\n", | |
"Successfully installed av-9.2.0\n" | |
] | |
} | |
], | |
"source": [ | |
"!sudo -H pip install --upgrade youtube-dl\n", | |
"!pip install -U memory_profiler\n", | |
"# !pip install decord\n", | |
"!pip install mmcv\n", | |
"!pip install av" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"source": [ | |
"安装GPU版本的Decord" | |
], | |
"metadata": { | |
"id": "1NGuLGJOWyuH" | |
} | |
}, | |
{ | |
"cell_type": "code", | |
"source": [ | |
"!sudo apt-get update\n", | |
"!sudo apt-get install -y build-essential python3-dev python3-setuptools make cmake\n", | |
"!sudo apt-get install -y libavcodec-dev libavfilter-dev libavformat-dev libavutil-dev\n", | |
"!git clone --recursive https://github.com/dmlc/decord\n", | |
"%cd decord\n", | |
"!mkdir build\n", | |
"%cd build\n", | |
"!cmake .. -DUSE_CUDA=ON -DCMAKE_BUILD_TYPE=Release \n", | |
"!make\n", | |
"%cd /content/decord/python\n", | |
"!python setup.py install --user\n", | |
"%cd /content" | |
], | |
"metadata": { | |
"id": "OBEihCBlSbSF", | |
"colab": { | |
"base_uri": "https://localhost:8080/" | |
}, | |
"outputId": "f55a8ee4-5222-4f85-e4f8-5bfb6663f0d0" | |
}, | |
"execution_count": 3, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"name": "stdout", | |
"text": [ | |
"\r0% [Working]\r \rGet:1 https://cloud.r-project.org/bin/linux/ubuntu bionic-cran40/ InRelease [3,626 B]\n", | |
"\r0% [Connecting to archive.ubuntu.com (185.125.190.36)] [Connecting to security.\r0% [Connecting to archive.ubuntu.com (185.125.190.36)] [Connecting to security.\r0% [1 InRelease gpgv 3,626 B] [Connecting to archive.ubuntu.com (185.125.190.36\r \rIgn:2 https://developer.download.nvidia.com/compute/machine-learning/repos/ubuntu1804/x86_64 InRelease\n", | |
"\r0% [1 InRelease gpgv 3,626 B] [Connecting to archive.ubuntu.com (185.125.190.36\r \rGet:3 https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64 InRelease [1,581 B]\n", | |
"Hit:4 https://developer.download.nvidia.com/compute/machine-learning/repos/ubuntu1804/x86_64 Release\n", | |
"Get:5 http://security.ubuntu.com/ubuntu bionic-security InRelease [88.7 kB]\n", | |
"Get:6 https://cloud.r-project.org/bin/linux/ubuntu bionic-cran40/ Packages [91.1 kB]\n", | |
"Get:7 https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64 Packages [912 kB]\n", | |
"Hit:8 http://archive.ubuntu.com/ubuntu bionic InRelease\n", | |
"Get:9 http://ppa.launchpad.net/c2d4u.team/c2d4u4.0+/ubuntu bionic InRelease [15.9 kB]\n", | |
"Get:11 http://archive.ubuntu.com/ubuntu bionic-updates InRelease [88.7 kB]\n", | |
"Get:12 http://security.ubuntu.com/ubuntu bionic-security/main amd64 Packages [2,939 kB]\n", | |
"Hit:13 http://ppa.launchpad.net/cran/libgit2/ubuntu bionic InRelease\n", | |
"Get:14 http://archive.ubuntu.com/ubuntu bionic-backports InRelease [74.6 kB]\n", | |
"Hit:15 http://ppa.launchpad.net/deadsnakes/ppa/ubuntu bionic InRelease\n", | |
"Hit:16 http://ppa.launchpad.net/graphics-drivers/ppa/ubuntu bionic InRelease\n", | |
"Get:17 http://security.ubuntu.com/ubuntu bionic-security/universe amd64 Packages [1,534 kB]\n", | |
"Get:18 http://archive.ubuntu.com/ubuntu bionic-updates/universe amd64 Packages [2,311 kB]\n", | |
"Get:19 http://ppa.launchpad.net/c2d4u.team/c2d4u4.0+/ubuntu bionic/main Sources [2,094 kB]\n", | |
"Get:20 http://archive.ubuntu.com/ubuntu bionic-updates/main amd64 Packages [3,369 kB]\n", | |
"Get:21 http://ppa.launchpad.net/c2d4u.team/c2d4u4.0+/ubuntu bionic/main amd64 Packages [1,073 kB]\n", | |
"Fetched 14.6 MB in 4s (4,064 kB/s)\n", | |
"Reading package lists... Done\n", | |
"Reading package lists... Done\n", | |
"Building dependency tree \n", | |
"Reading state information... Done\n", | |
"build-essential is already the newest version (12.4ubuntu1).\n", | |
"make is already the newest version (4.1-9.1ubuntu1).\n", | |
"make set to manually installed.\n", | |
"cmake is already the newest version (3.10.2-1ubuntu2.18.04.2).\n", | |
"python3-dev is already the newest version (3.6.7-1~18.04).\n", | |
"python3-dev set to manually installed.\n", | |
"The following package was automatically installed and is no longer required:\n", | |
" libnvidia-common-460\n", | |
"Use 'sudo apt autoremove' to remove it.\n", | |
"The following additional packages will be installed:\n", | |
" python3-pkg-resources\n", | |
"Suggested packages:\n", | |
" python-setuptools-doc\n", | |
"The following NEW packages will be installed:\n", | |
" python3-pkg-resources python3-setuptools\n", | |
"0 upgraded, 2 newly installed, 0 to remove and 43 not upgraded.\n", | |
"Need to get 346 kB of archives.\n", | |
"After this operation, 1,848 kB of additional disk space will be used.\n", | |
"Get:1 http://archive.ubuntu.com/ubuntu bionic/main amd64 python3-pkg-resources all 39.0.1-2 [98.8 kB]\n", | |
"Get:2 http://archive.ubuntu.com/ubuntu bionic/main amd64 python3-setuptools all 39.0.1-2 [248 kB]\n", | |
"Fetched 346 kB in 1s (653 kB/s)\n", | |
"debconf: unable to initialize frontend: Dialog\n", | |
"debconf: (No usable dialog-like program is installed, so the dialog based frontend cannot be used. at /usr/share/perl5/Debconf/FrontEnd/Dialog.pm line 76, <> line 2.)\n", | |
"debconf: falling back to frontend: Readline\n", | |
"debconf: unable to initialize frontend: Readline\n", | |
"debconf: (This frontend requires a controlling tty.)\n", | |
"debconf: falling back to frontend: Teletype\n", | |
"dpkg-preconfigure: unable to re-open stdin: \n", | |
"Selecting previously unselected package python3-pkg-resources.\n", | |
"(Reading database ... 155676 files and directories currently installed.)\n", | |
"Preparing to unpack .../python3-pkg-resources_39.0.1-2_all.deb ...\n", | |
"Unpacking python3-pkg-resources (39.0.1-2) ...\n", | |
"Selecting previously unselected package python3-setuptools.\n", | |
"Preparing to unpack .../python3-setuptools_39.0.1-2_all.deb ...\n", | |
"Unpacking python3-setuptools (39.0.1-2) ...\n", | |
"Setting up python3-pkg-resources (39.0.1-2) ...\n", | |
"Setting up python3-setuptools (39.0.1-2) ...\n", | |
"Reading package lists... Done\n", | |
"Building dependency tree \n", | |
"Reading state information... Done\n", | |
"libavcodec-dev is already the newest version (7:3.4.11-0ubuntu0.1).\n", | |
"libavcodec-dev set to manually installed.\n", | |
"libavformat-dev is already the newest version (7:3.4.11-0ubuntu0.1).\n", | |
"libavformat-dev set to manually installed.\n", | |
"libavutil-dev is already the newest version (7:3.4.11-0ubuntu0.1).\n", | |
"libavutil-dev set to manually installed.\n", | |
"The following package was automatically installed and is no longer required:\n", | |
" libnvidia-common-460\n", | |
"Use 'sudo apt autoremove' to remove it.\n", | |
"The following additional packages will be installed:\n", | |
" libpostproc-dev\n", | |
"The following NEW packages will be installed:\n", | |
" libavfilter-dev libpostproc-dev\n", | |
"0 upgraded, 2 newly installed, 0 to remove and 43 not upgraded.\n", | |
"Need to get 1,067 kB of archives.\n", | |
"After this operation, 5,019 kB of additional disk space will be used.\n", | |
"Get:1 http://archive.ubuntu.com/ubuntu bionic-updates/universe amd64 libpostproc-dev amd64 7:3.4.11-0ubuntu0.1 [51.0 kB]\n", | |
"Get:2 http://archive.ubuntu.com/ubuntu bionic-updates/universe amd64 libavfilter-dev amd64 7:3.4.11-0ubuntu0.1 [1,016 kB]\n", | |
"Fetched 1,067 kB in 1s (1,714 kB/s)\n", | |
"debconf: unable to initialize frontend: Dialog\n", | |
"debconf: (No usable dialog-like program is installed, so the dialog based frontend cannot be used. at /usr/share/perl5/Debconf/FrontEnd/Dialog.pm line 76, <> line 2.)\n", | |
"debconf: falling back to frontend: Readline\n", | |
"debconf: unable to initialize frontend: Readline\n", | |
"debconf: (This frontend requires a controlling tty.)\n", | |
"debconf: falling back to frontend: Teletype\n", | |
"dpkg-preconfigure: unable to re-open stdin: \n", | |
"Selecting previously unselected package libpostproc-dev:amd64.\n", | |
"(Reading database ... 155789 files and directories currently installed.)\n", | |
"Preparing to unpack .../libpostproc-dev_7%3a3.4.11-0ubuntu0.1_amd64.deb ...\n", | |
"Unpacking libpostproc-dev:amd64 (7:3.4.11-0ubuntu0.1) ...\n", | |
"Selecting previously unselected package libavfilter-dev:amd64.\n", | |
"Preparing to unpack .../libavfilter-dev_7%3a3.4.11-0ubuntu0.1_amd64.deb ...\n", | |
"Unpacking libavfilter-dev:amd64 (7:3.4.11-0ubuntu0.1) ...\n", | |
"Setting up libpostproc-dev:amd64 (7:3.4.11-0ubuntu0.1) ...\n", | |
"Setting up libavfilter-dev:amd64 (7:3.4.11-0ubuntu0.1) ...\n", | |
"Cloning into 'decord'...\n", | |
"remote: Enumerating objects: 3211, done.\u001b[K\n", | |
"remote: Counting objects: 100% (300/300), done.\u001b[K\n", | |
"remote: Compressing objects: 100% (169/169), done.\u001b[K\n", | |
"remote: Total 3211 (delta 130), reused 256 (delta 103), pack-reused 2911\u001b[K\n", | |
"Receiving objects: 100% (3211/3211), 20.70 MiB | 29.89 MiB/s, done.\n", | |
"Resolving deltas: 100% (1941/1941), done.\n", | |
"Submodule '3rdparty/dlpack' (https://github.com/dmlc/dlpack) registered for path '3rdparty/dlpack'\n", | |
"Submodule '3rdparty/dmlc-core' (https://github.com/dmlc/dmlc-core) registered for path '3rdparty/dmlc-core'\n", | |
"Cloning into '/content/decord/3rdparty/dlpack'...\n", | |
"remote: Enumerating objects: 437, done. \n", | |
"remote: Counting objects: 100% (106/106), done. \n", | |
"remote: Compressing objects: 100% (43/43), done. \n", | |
"remote: Total 437 (delta 78), reused 68 (delta 61), pack-reused 331 \n", | |
"Receiving objects: 100% (437/437), 1.69 MiB | 7.53 MiB/s, done.\n", | |
"Resolving deltas: 100% (148/148), done.\n", | |
"Cloning into '/content/decord/3rdparty/dmlc-core'...\n", | |
"remote: Enumerating objects: 6284, done. \n", | |
"remote: Counting objects: 100% (148/148), done. \n", | |
"remote: Compressing objects: 100% (108/108), done. \n", | |
"remote: Total 6284 (delta 54), reused 74 (delta 24), pack-reused 6136 \n", | |
"Receiving objects: 100% (6284/6284), 1.68 MiB | 10.37 MiB/s, done.\n", | |
"Resolving deltas: 100% (3800/3800), done.\n", | |
"Submodule path '3rdparty/dlpack': checked out '5c792cef3aee54ad8b7000111c9dc1797f327b59'\n", | |
"Submodule path '3rdparty/dmlc-core': checked out 'd07fb7a443b5db8a89d65a15a024af6a425615a5'\n", | |
"/content/decord\n", | |
"/content/decord/build\n", | |
"-- The C compiler identification is GNU 7.5.0\n", | |
"-- The CXX compiler identification is GNU 7.5.0\n", | |
"-- Detecting C compiler ABI info\n", | |
"-- Detecting C compiler ABI info - done\n", | |
"-- Check for working C compiler: /usr/bin/cc - skipped\n", | |
"-- Detecting C compile features\n", | |
"-- Detecting C compile features - done\n", | |
"-- Detecting CXX compiler ABI info\n", | |
"-- Detecting CXX compiler ABI info - done\n", | |
"-- Check for working CXX compiler: /usr/bin/c++ - skipped\n", | |
"-- Detecting CXX compile features\n", | |
"-- Detecting CXX compile features - done\n", | |
"-- Found PkgConfig: /usr/bin/pkg-config (found version \"0.29.1\") \n", | |
"-- Checking for module 'libavcodec'\n", | |
"-- Found libavcodec, version 57.107.100\n", | |
"-- Checking for module 'libavformat'\n", | |
"-- Found libavformat, version 57.83.100\n", | |
"-- Checking for module 'libavutil'\n", | |
"-- Found libavutil, version 55.78.100\n", | |
"-- Checking for module 'libavdevice'\n", | |
"-- No package 'libavdevice' found\n", | |
"-- Checking for module 'libavfilter'\n", | |
"-- Found libavfilter, version 6.107.100\n", | |
"-- Checking for module 'libswresample'\n", | |
"-- Found libswresample, version 2.9.100\n", | |
"-- Unable to find libavdevice, device input API will not work!\n", | |
"-- Found FFMPEG or Libav: /usr/lib/x86_64-linux-gnu/libavformat.so;/usr/lib/x86_64-linux-gnu/libavfilter.so;/usr/lib/x86_64-linux-gnu/libavcodec.so;/usr/lib/x86_64-linux-gnu/libavutil.so;/usr/lib/x86_64-linux-gnu/libswresample.so, /usr/include/x86_64-linux-gnu\n", | |
"-- The CUDA compiler identification is NVIDIA 11.1.105\n", | |
"-- Detecting CUDA compiler ABI info\n", | |
"-- Detecting CUDA compiler ABI info - done\n", | |
"-- Check for working CUDA compiler: /usr/local/cuda/bin/nvcc - skipped\n", | |
"-- Detecting CUDA compile features\n", | |
"-- Detecting CUDA compile features - done\n", | |
"-- Performing Test SUPPORT_CXX11\n", | |
"-- Performing Test SUPPORT_CXX11 - Success\n", | |
"\u001b[0mFFMPEG_INCLUDE_DIR = /usr/include/x86_64-linux-gnu \u001b[0m\n", | |
"\u001b[0mFFMPEG_LIBRARIES = /usr/lib/x86_64-linux-gnu/libavformat.so;/usr/lib/x86_64-linux-gnu/libavfilter.so;/usr/lib/x86_64-linux-gnu/libavcodec.so;/usr/lib/x86_64-linux-gnu/libavutil.so;/usr/lib/x86_64-linux-gnu/libswresample.so \u001b[0m\n", | |
"-- Looking for pthread.h\n", | |
"-- Looking for pthread.h - found\n", | |
"-- Performing Test CMAKE_HAVE_LIBC_PTHREAD\n", | |
"-- Performing Test CMAKE_HAVE_LIBC_PTHREAD - Failed\n", | |
"-- Looking for pthread_create in pthreads\n", | |
"-- Looking for pthread_create in pthreads - not found\n", | |
"-- Looking for pthread_create in pthread\n", | |
"-- Looking for pthread_create in pthread - found\n", | |
"-- Found Threads: TRUE \n", | |
"-- Found CUDA_TOOLKIT_ROOT_DIR=/usr/local/cuda\n", | |
"-- Found CUDA_CUDA_LIBRARY=/usr/local/cuda/targets/x86_64-linux/lib/stubs/libcuda.so\n", | |
"-- Found CUDA_CUDART_LIBRARY=/usr/local/cuda/lib64/libcudart.so\n", | |
"-- Found CUDA_NVRTC_LIBRARY=/usr/local/cuda/lib64/libnvrtc.so\n", | |
"-- Found CUDA_CUDNN_LIBRARY=/usr/lib/x86_64-linux-gnu/libcudnn.so\n", | |
"-- Found CUDA_CUBLAS_LIBRARY=/usr/lib/x86_64-linux-gnu/libcublas.so\n", | |
"-- Found CUDA_NVIDIA_ML_LIBRARY=/usr/local/cuda/targets/x86_64-linux/lib/stubs/libnvidia-ml.so\n", | |
"-- Found CUDA_NVCUVID_LIBRARY=/usr/lib/x86_64-linux-gnu/libnvcuvid.so\n", | |
"-- Build with CUDA support\n", | |
"-- Configuring done\n", | |
"\u001b[33mCMake Warning (dev) in CMakeLists.txt:\n", | |
" Policy CMP0104 is not set: CMAKE_CUDA_ARCHITECTURES now detected for NVCC,\n", | |
" empty CUDA_ARCHITECTURES not allowed. Run \"cmake --help-policy CMP0104\"\n", | |
" for policy details. Use the cmake_policy command to set the policy and\n", | |
" suppress this warning.\n", | |
"\n", | |
" CUDA_ARCHITECTURES is empty for target \"decord\".\n", | |
"This warning is for project developers. Use -Wno-dev to suppress it.\n", | |
"\u001b[0m\n", | |
"-- Generating done\n", | |
"-- Build files have been written to: /content/decord/build\n", | |
"[ 2%] \u001b[32mBuilding CXX object CMakeFiles/decord.dir/src/audio/audio_interface.cc.o\u001b[0m\n", | |
"[ 5%] \u001b[32mBuilding CXX object CMakeFiles/decord.dir/src/audio/audio_reader.cc.o\u001b[0m\n", | |
"[ 8%] \u001b[32mBuilding CXX object CMakeFiles/decord.dir/src/runtime/c_runtime_api.cc.o\u001b[0m\n", | |
"[ 10%] \u001b[32mBuilding CXX object CMakeFiles/decord.dir/src/runtime/cpu_device_api.cc.o\u001b[0m\n", | |
"[ 13%] \u001b[32mBuilding CXX object CMakeFiles/decord.dir/src/runtime/dso_module.cc.o\u001b[0m\n", | |
"[ 16%] \u001b[32mBuilding CXX object CMakeFiles/decord.dir/src/runtime/file_util.cc.o\u001b[0m\n", | |
"[ 18%] \u001b[32mBuilding CXX object CMakeFiles/decord.dir/src/runtime/module.cc.o\u001b[0m\n", | |
"[ 21%] \u001b[32mBuilding CXX object CMakeFiles/decord.dir/src/runtime/module_util.cc.o\u001b[0m\n", | |
"[ 24%] \u001b[32mBuilding CXX object CMakeFiles/decord.dir/src/runtime/ndarray.cc.o\u001b[0m\n", | |
"[ 27%] \u001b[32mBuilding CXX object CMakeFiles/decord.dir/src/runtime/registry.cc.o\u001b[0m\n", | |
"[ 29%] \u001b[32mBuilding CXX object CMakeFiles/decord.dir/src/runtime/str_util.cc.o\u001b[0m\n", | |
"[ 32%] \u001b[32mBuilding CXX object CMakeFiles/decord.dir/src/runtime/system_lib_module.cc.o\u001b[0m\n", | |
"[ 35%] \u001b[32mBuilding CXX object CMakeFiles/decord.dir/src/runtime/thread_pool.cc.o\u001b[0m\n", | |
"[ 37%] \u001b[32mBuilding CXX object CMakeFiles/decord.dir/src/runtime/threading_backend.cc.o\u001b[0m\n", | |
"[ 40%] \u001b[32mBuilding CXX object CMakeFiles/decord.dir/src/runtime/workspace_pool.cc.o\u001b[0m\n", | |
"[ 43%] \u001b[32mBuilding CXX object CMakeFiles/decord.dir/src/sampler/random_file_order_sampler.cc.o\u001b[0m\n", | |
"[ 45%] \u001b[32mBuilding CXX object CMakeFiles/decord.dir/src/sampler/random_sampler.cc.o\u001b[0m\n", | |
"[ 48%] \u001b[32mBuilding CXX object CMakeFiles/decord.dir/src/sampler/sequential_sampler.cc.o\u001b[0m\n", | |
"[ 51%] \u001b[32mBuilding CXX object CMakeFiles/decord.dir/src/sampler/smart_random_sampler.cc.o\u001b[0m\n", | |
"[ 54%] \u001b[32mBuilding CXX object CMakeFiles/decord.dir/src/video/logging.cc.o\u001b[0m\n", | |
"[ 56%] \u001b[32mBuilding CXX object CMakeFiles/decord.dir/src/video/storage_pool.cc.o\u001b[0m\n", | |
"[ 59%] \u001b[32mBuilding CXX object CMakeFiles/decord.dir/src/video/video_interface.cc.o\u001b[0m\n", | |
"[ 62%] \u001b[32mBuilding CXX object CMakeFiles/decord.dir/src/video/video_loader.cc.o\u001b[0m\n", | |
"[ 64%] \u001b[32mBuilding CXX object CMakeFiles/decord.dir/src/video/video_reader.cc.o\u001b[0m\n", | |
"[ 67%] \u001b[32mBuilding CXX object CMakeFiles/decord.dir/src/video/ffmpeg/filter_graph.cc.o\u001b[0m\n", | |
"[ 70%] \u001b[32mBuilding CXX object CMakeFiles/decord.dir/src/video/ffmpeg/threaded_decoder.cc.o\u001b[0m\n", | |
"[ 72%] \u001b[32mBuilding CXX object CMakeFiles/decord.dir/src/video/nvcodec/cuda_context.cc.o\u001b[0m\n", | |
"[ 75%] \u001b[32mBuilding CXX object CMakeFiles/decord.dir/src/video/nvcodec/cuda_decoder_impl.cc.o\u001b[0m\n", | |
"[ 78%] \u001b[32mBuilding CXX object CMakeFiles/decord.dir/src/video/nvcodec/cuda_mapped_frame.cc.o\u001b[0m\n", | |
"[ 81%] \u001b[32mBuilding CXX object CMakeFiles/decord.dir/src/video/nvcodec/cuda_parser.cc.o\u001b[0m\n", | |
"[ 83%] \u001b[32mBuilding CXX object CMakeFiles/decord.dir/src/video/nvcodec/cuda_stream.cc.o\u001b[0m\n", | |
"[ 86%] \u001b[32mBuilding CXX object CMakeFiles/decord.dir/src/video/nvcodec/cuda_texture.cc.o\u001b[0m\n", | |
"[ 89%] \u001b[32mBuilding CXX object CMakeFiles/decord.dir/src/video/nvcodec/cuda_threaded_decoder.cc.o\u001b[0m\n", | |
"[ 91%] \u001b[32mBuilding CXX object CMakeFiles/decord.dir/src/runtime/cuda/cuda_device_api.cc.o\u001b[0m\n", | |
"[ 94%] \u001b[32mBuilding CXX object CMakeFiles/decord.dir/src/runtime/cuda/cuda_module.cc.o\u001b[0m\n", | |
"[ 97%] \u001b[32mBuilding CUDA object CMakeFiles/decord.dir/src/improc/improc.cu.o\u001b[0m\n", | |
"[100%] \u001b[32m\u001b[1mLinking CXX shared library libdecord.so\u001b[0m\n", | |
"[100%] Built target decord\n", | |
"/content/decord/python\n", | |
"running install\n", | |
"running bdist_egg\n", | |
"running egg_info\n", | |
"creating decord.egg-info\n", | |
"writing decord.egg-info/PKG-INFO\n", | |
"writing dependency_links to decord.egg-info/dependency_links.txt\n", | |
"writing requirements to decord.egg-info/requires.txt\n", | |
"writing top-level names to decord.egg-info/top_level.txt\n", | |
"writing manifest file 'decord.egg-info/SOURCES.txt'\n", | |
"writing manifest file 'decord.egg-info/SOURCES.txt'\n", | |
"installing library code to build/bdist.linux-x86_64/egg\n", | |
"running install_lib\n", | |
"running build_py\n", | |
"creating build\n", | |
"creating build/lib\n", | |
"creating build/lib/decord\n", | |
"copying decord/__init__.py -> build/lib/decord\n", | |
"copying decord/audio_reader.py -> build/lib/decord\n", | |
"copying decord/av_reader.py -> build/lib/decord\n", | |
"copying decord/ndarray.py -> build/lib/decord\n", | |
"copying decord/video_reader.py -> build/lib/decord\n", | |
"copying decord/base.py -> build/lib/decord\n", | |
"copying decord/logging.py -> build/lib/decord\n", | |
"copying decord/video_loader.py -> build/lib/decord\n", | |
"copying decord/_api_internal.py -> build/lib/decord\n", | |
"creating build/lib/decord/function\n", | |
"copying decord/function/__init__.py -> build/lib/decord/function\n", | |
"copying decord/function/base.py -> build/lib/decord/function\n", | |
"creating build/lib/decord/data\n", | |
"copying decord/data/__init__.py -> build/lib/decord/data\n", | |
"copying decord/data/dataloader.py -> build/lib/decord/data\n", | |
"copying decord/data/base_action.py -> build/lib/decord/data\n", | |
"creating build/lib/decord/bridge\n", | |
"copying decord/bridge/__init__.py -> build/lib/decord/bridge\n", | |
"copying decord/bridge/torchdl.py -> build/lib/decord/bridge\n", | |
"copying decord/bridge/tvm.py -> build/lib/decord/bridge\n", | |
"copying decord/bridge/utils.py -> build/lib/decord/bridge\n", | |
"copying decord/bridge/mxnet.py -> build/lib/decord/bridge\n", | |
"copying decord/bridge/tf.py -> build/lib/decord/bridge\n", | |
"creating build/lib/decord/_ffi\n", | |
"copying decord/_ffi/function.py -> build/lib/decord/_ffi\n", | |
"copying decord/_ffi/runtime_ctypes.py -> build/lib/decord/_ffi\n", | |
"copying decord/_ffi/__init__.py -> build/lib/decord/_ffi\n", | |
"copying decord/_ffi/ndarray.py -> build/lib/decord/_ffi\n", | |
"copying decord/_ffi/libinfo.py -> build/lib/decord/_ffi\n", | |
"copying decord/_ffi/base.py -> build/lib/decord/_ffi\n", | |
"creating build/lib/decord/data/kinetics\n", | |
"copying decord/data/kinetics/__init__.py -> build/lib/decord/data/kinetics\n", | |
"copying decord/data/kinetics/kinetics400_action.py -> build/lib/decord/data/kinetics\n", | |
"creating build/lib/decord/data/transforms\n", | |
"copying decord/data/transforms/__init__.py -> build/lib/decord/data/transforms\n", | |
"copying decord/data/transforms/action.py -> build/lib/decord/data/transforms\n", | |
"creating build/lib/decord/_ffi/_cy2\n", | |
"copying decord/_ffi/_cy2/__init__.py -> build/lib/decord/_ffi/_cy2\n", | |
"creating build/lib/decord/_ffi/_ctypes\n", | |
"copying decord/_ffi/_ctypes/function.py -> build/lib/decord/_ffi/_ctypes\n", | |
"copying decord/_ffi/_ctypes/__init__.py -> build/lib/decord/_ffi/_ctypes\n", | |
"copying decord/_ffi/_ctypes/ndarray.py -> build/lib/decord/_ffi/_ctypes\n", | |
"copying decord/_ffi/_ctypes/types.py -> build/lib/decord/_ffi/_ctypes\n", | |
"creating build/lib/decord/_ffi/_cy3\n", | |
"copying decord/_ffi/_cy3/__init__.py -> build/lib/decord/_ffi/_cy3\n", | |
"copying decord/_ffi/README.md -> build/lib/decord/_ffi\n", | |
"creating build/lib/decord/_ffi/_cython\n", | |
"copying decord/_ffi/_cython/.gitignore -> build/lib/decord/_ffi/_cython\n", | |
"copying decord/_ffi/_cython/base.pxi -> build/lib/decord/_ffi/_cython\n", | |
"copying decord/_ffi/_cython/core.pyx -> build/lib/decord/_ffi/_cython\n", | |
"copying decord/_ffi/_cython/function.pxi -> build/lib/decord/_ffi/_cython\n", | |
"copying decord/_ffi/_cython/ndarray.pxi -> build/lib/decord/_ffi/_cython\n", | |
"copying decord/_ffi/_cython/node.pxi -> build/lib/decord/_ffi/_cython\n", | |
"running build_ext\n", | |
"creating build/bdist.linux-x86_64\n", | |
"creating build/bdist.linux-x86_64/egg\n", | |
"creating build/bdist.linux-x86_64/egg/decord\n", | |
"copying build/lib/decord/__init__.py -> build/bdist.linux-x86_64/egg/decord\n", | |
"creating build/bdist.linux-x86_64/egg/decord/function\n", | |
"copying build/lib/decord/function/__init__.py -> build/bdist.linux-x86_64/egg/decord/function\n", | |
"copying build/lib/decord/function/base.py -> build/bdist.linux-x86_64/egg/decord/function\n", | |
"copying build/lib/decord/audio_reader.py -> build/bdist.linux-x86_64/egg/decord\n", | |
"copying build/lib/decord/av_reader.py -> build/bdist.linux-x86_64/egg/decord\n", | |
"copying build/lib/decord/ndarray.py -> build/bdist.linux-x86_64/egg/decord\n", | |
"copying build/lib/decord/video_reader.py -> build/bdist.linux-x86_64/egg/decord\n", | |
"creating build/bdist.linux-x86_64/egg/decord/data\n", | |
"copying build/lib/decord/data/__init__.py -> build/bdist.linux-x86_64/egg/decord/data\n", | |
"copying build/lib/decord/data/dataloader.py -> build/bdist.linux-x86_64/egg/decord/data\n", | |
"copying build/lib/decord/data/base_action.py -> build/bdist.linux-x86_64/egg/decord/data\n", | |
"creating build/bdist.linux-x86_64/egg/decord/data/kinetics\n", | |
"copying build/lib/decord/data/kinetics/__init__.py -> build/bdist.linux-x86_64/egg/decord/data/kinetics\n", | |
"copying build/lib/decord/data/kinetics/kinetics400_action.py -> build/bdist.linux-x86_64/egg/decord/data/kinetics\n", | |
"creating build/bdist.linux-x86_64/egg/decord/data/transforms\n", | |
"copying build/lib/decord/data/transforms/__init__.py -> build/bdist.linux-x86_64/egg/decord/data/transforms\n", | |
"copying build/lib/decord/data/transforms/action.py -> build/bdist.linux-x86_64/egg/decord/data/transforms\n", | |
"creating build/bdist.linux-x86_64/egg/decord/bridge\n", | |
"copying build/lib/decord/bridge/__init__.py -> build/bdist.linux-x86_64/egg/decord/bridge\n", | |
"copying build/lib/decord/bridge/torchdl.py -> build/bdist.linux-x86_64/egg/decord/bridge\n", | |
"copying build/lib/decord/bridge/tvm.py -> build/bdist.linux-x86_64/egg/decord/bridge\n", | |
"copying build/lib/decord/bridge/utils.py -> build/bdist.linux-x86_64/egg/decord/bridge\n", | |
"copying build/lib/decord/bridge/mxnet.py -> build/bdist.linux-x86_64/egg/decord/bridge\n", | |
"copying build/lib/decord/bridge/tf.py -> build/bdist.linux-x86_64/egg/decord/bridge\n", | |
"copying build/lib/decord/base.py -> build/bdist.linux-x86_64/egg/decord\n", | |
"copying build/lib/decord/logging.py -> build/bdist.linux-x86_64/egg/decord\n", | |
"creating build/bdist.linux-x86_64/egg/decord/_ffi\n", | |
"copying build/lib/decord/_ffi/function.py -> build/bdist.linux-x86_64/egg/decord/_ffi\n", | |
"copying build/lib/decord/_ffi/runtime_ctypes.py -> build/bdist.linux-x86_64/egg/decord/_ffi\n", | |
"copying build/lib/decord/_ffi/__init__.py -> build/bdist.linux-x86_64/egg/decord/_ffi\n", | |
"copying build/lib/decord/_ffi/ndarray.py -> build/bdist.linux-x86_64/egg/decord/_ffi\n", | |
"copying build/lib/decord/_ffi/libinfo.py -> build/bdist.linux-x86_64/egg/decord/_ffi\n", | |
"creating build/bdist.linux-x86_64/egg/decord/_ffi/_cy2\n", | |
"copying build/lib/decord/_ffi/_cy2/__init__.py -> build/bdist.linux-x86_64/egg/decord/_ffi/_cy2\n", | |
"creating build/bdist.linux-x86_64/egg/decord/_ffi/_ctypes\n", | |
"copying build/lib/decord/_ffi/_ctypes/function.py -> build/bdist.linux-x86_64/egg/decord/_ffi/_ctypes\n", | |
"copying build/lib/decord/_ffi/_ctypes/__init__.py -> build/bdist.linux-x86_64/egg/decord/_ffi/_ctypes\n", | |
"copying build/lib/decord/_ffi/_ctypes/ndarray.py -> build/bdist.linux-x86_64/egg/decord/_ffi/_ctypes\n", | |
"copying build/lib/decord/_ffi/_ctypes/types.py -> build/bdist.linux-x86_64/egg/decord/_ffi/_ctypes\n", | |
"copying build/lib/decord/_ffi/base.py -> build/bdist.linux-x86_64/egg/decord/_ffi\n", | |
"creating build/bdist.linux-x86_64/egg/decord/_ffi/_cython\n", | |
"copying build/lib/decord/_ffi/_cython/base.pxi -> build/bdist.linux-x86_64/egg/decord/_ffi/_cython\n", | |
"copying build/lib/decord/_ffi/_cython/node.pxi -> build/bdist.linux-x86_64/egg/decord/_ffi/_cython\n", | |
"copying build/lib/decord/_ffi/_cython/ndarray.pxi -> build/bdist.linux-x86_64/egg/decord/_ffi/_cython\n", | |
"copying build/lib/decord/_ffi/_cython/function.pxi -> build/bdist.linux-x86_64/egg/decord/_ffi/_cython\n", | |
"copying build/lib/decord/_ffi/_cython/core.pyx -> build/bdist.linux-x86_64/egg/decord/_ffi/_cython\n", | |
"copying build/lib/decord/_ffi/_cython/.gitignore -> build/bdist.linux-x86_64/egg/decord/_ffi/_cython\n", | |
"copying build/lib/decord/_ffi/README.md -> build/bdist.linux-x86_64/egg/decord/_ffi\n", | |
"creating build/bdist.linux-x86_64/egg/decord/_ffi/_cy3\n", | |
"copying build/lib/decord/_ffi/_cy3/__init__.py -> build/bdist.linux-x86_64/egg/decord/_ffi/_cy3\n", | |
"copying build/lib/decord/video_loader.py -> build/bdist.linux-x86_64/egg/decord\n", | |
"copying build/lib/decord/_api_internal.py -> build/bdist.linux-x86_64/egg/decord\n", | |
"byte-compiling build/bdist.linux-x86_64/egg/decord/__init__.py to __init__.cpython-37.pyc\n", | |
"byte-compiling build/bdist.linux-x86_64/egg/decord/function/__init__.py to __init__.cpython-37.pyc\n", | |
"byte-compiling build/bdist.linux-x86_64/egg/decord/function/base.py to base.cpython-37.pyc\n", | |
"byte-compiling build/bdist.linux-x86_64/egg/decord/audio_reader.py to audio_reader.cpython-37.pyc\n", | |
"byte-compiling build/bdist.linux-x86_64/egg/decord/av_reader.py to av_reader.cpython-37.pyc\n", | |
"byte-compiling build/bdist.linux-x86_64/egg/decord/ndarray.py to ndarray.cpython-37.pyc\n", | |
"byte-compiling build/bdist.linux-x86_64/egg/decord/video_reader.py to video_reader.cpython-37.pyc\n", | |
"byte-compiling build/bdist.linux-x86_64/egg/decord/data/__init__.py to __init__.cpython-37.pyc\n", | |
"byte-compiling build/bdist.linux-x86_64/egg/decord/data/dataloader.py to dataloader.cpython-37.pyc\n", | |
"byte-compiling build/bdist.linux-x86_64/egg/decord/data/base_action.py to base_action.cpython-37.pyc\n", | |
"byte-compiling build/bdist.linux-x86_64/egg/decord/data/kinetics/__init__.py to __init__.cpython-37.pyc\n", | |
"byte-compiling build/bdist.linux-x86_64/egg/decord/data/kinetics/kinetics400_action.py to kinetics400_action.cpython-37.pyc\n", | |
"byte-compiling build/bdist.linux-x86_64/egg/decord/data/transforms/__init__.py to __init__.cpython-37.pyc\n", | |
"byte-compiling build/bdist.linux-x86_64/egg/decord/data/transforms/action.py to action.cpython-37.pyc\n", | |
"byte-compiling build/bdist.linux-x86_64/egg/decord/bridge/__init__.py to __init__.cpython-37.pyc\n", | |
"byte-compiling build/bdist.linux-x86_64/egg/decord/bridge/torchdl.py to torchdl.cpython-37.pyc\n", | |
"byte-compiling build/bdist.linux-x86_64/egg/decord/bridge/tvm.py to tvm.cpython-37.pyc\n", | |
"byte-compiling build/bdist.linux-x86_64/egg/decord/bridge/utils.py to utils.cpython-37.pyc\n", | |
"byte-compiling build/bdist.linux-x86_64/egg/decord/bridge/mxnet.py to mxnet.cpython-37.pyc\n", | |
"byte-compiling build/bdist.linux-x86_64/egg/decord/bridge/tf.py to tf.cpython-37.pyc\n", | |
"byte-compiling build/bdist.linux-x86_64/egg/decord/base.py to base.cpython-37.pyc\n", | |
"byte-compiling build/bdist.linux-x86_64/egg/decord/logging.py to logging.cpython-37.pyc\n", | |
"byte-compiling build/bdist.linux-x86_64/egg/decord/_ffi/function.py to function.cpython-37.pyc\n", | |
"byte-compiling build/bdist.linux-x86_64/egg/decord/_ffi/runtime_ctypes.py to runtime_ctypes.cpython-37.pyc\n", | |
"byte-compiling build/bdist.linux-x86_64/egg/decord/_ffi/__init__.py to __init__.cpython-37.pyc\n", | |
"byte-compiling build/bdist.linux-x86_64/egg/decord/_ffi/ndarray.py to ndarray.cpython-37.pyc\n", | |
"byte-compiling build/bdist.linux-x86_64/egg/decord/_ffi/libinfo.py to libinfo.cpython-37.pyc\n", | |
"byte-compiling build/bdist.linux-x86_64/egg/decord/_ffi/_cy2/__init__.py to __init__.cpython-37.pyc\n", | |
"byte-compiling build/bdist.linux-x86_64/egg/decord/_ffi/_ctypes/function.py to function.cpython-37.pyc\n", | |
"byte-compiling build/bdist.linux-x86_64/egg/decord/_ffi/_ctypes/__init__.py to __init__.cpython-37.pyc\n", | |
"byte-compiling build/bdist.linux-x86_64/egg/decord/_ffi/_ctypes/ndarray.py to ndarray.cpython-37.pyc\n", | |
"byte-compiling build/bdist.linux-x86_64/egg/decord/_ffi/_ctypes/types.py to types.cpython-37.pyc\n", | |
"byte-compiling build/bdist.linux-x86_64/egg/decord/_ffi/base.py to base.cpython-37.pyc\n", | |
"byte-compiling build/bdist.linux-x86_64/egg/decord/_ffi/_cy3/__init__.py to __init__.cpython-37.pyc\n", | |
"byte-compiling build/bdist.linux-x86_64/egg/decord/video_loader.py to video_loader.cpython-37.pyc\n", | |
"byte-compiling build/bdist.linux-x86_64/egg/decord/_api_internal.py to _api_internal.cpython-37.pyc\n", | |
"installing package data to build/bdist.linux-x86_64/egg\n", | |
"running install_data\n", | |
"copying ../build/libdecord.so -> build/bdist.linux-x86_64/egg/decord\n", | |
"creating build/bdist.linux-x86_64/egg/EGG-INFO\n", | |
"copying decord.egg-info/PKG-INFO -> build/bdist.linux-x86_64/egg/EGG-INFO\n", | |
"copying decord.egg-info/SOURCES.txt -> build/bdist.linux-x86_64/egg/EGG-INFO\n", | |
"copying decord.egg-info/dependency_links.txt -> build/bdist.linux-x86_64/egg/EGG-INFO\n", | |
"copying decord.egg-info/not-zip-safe -> build/bdist.linux-x86_64/egg/EGG-INFO\n", | |
"copying decord.egg-info/requires.txt -> build/bdist.linux-x86_64/egg/EGG-INFO\n", | |
"copying decord.egg-info/top_level.txt -> build/bdist.linux-x86_64/egg/EGG-INFO\n", | |
"creating dist\n", | |
"creating 'dist/decord-0.6.0-py3.7-linux-x86_64.egg' and adding 'build/bdist.linux-x86_64/egg' to it\n", | |
"removing 'build/bdist.linux-x86_64/egg' (and everything under it)\n", | |
"Processing decord-0.6.0-py3.7-linux-x86_64.egg\n", | |
"creating /root/.local/lib/python3.7/site-packages/decord-0.6.0-py3.7-linux-x86_64.egg\n", | |
"Extracting decord-0.6.0-py3.7-linux-x86_64.egg to /root/.local/lib/python3.7/site-packages\n", | |
"Adding decord 0.6.0 to easy-install.pth file\n", | |
"\n", | |
"Installed /root/.local/lib/python3.7/site-packages/decord-0.6.0-py3.7-linux-x86_64.egg\n", | |
"Processing dependencies for decord==0.6.0\n", | |
"Searching for numpy==1.21.6\n", | |
"Best match: numpy 1.21.6\n", | |
"Adding numpy 1.21.6 to easy-install.pth file\n", | |
"Installing f2py script to /root/.local/bin\n", | |
"Installing f2py3 script to /root/.local/bin\n", | |
"Installing f2py3.7 script to /root/.local/bin\n", | |
"\n", | |
"Using /usr/local/lib/python3.7/dist-packages\n", | |
"Finished processing dependencies for decord==0.6.0\n", | |
"/content\n" | |
] | |
} | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"source": [ | |
"获取一些样例视频" | |
], | |
"metadata": { | |
"id": "g0NcyvNuW7gs" | |
} | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 4, | |
"metadata": { | |
"id": "BPo1CIVsG3DB" | |
}, | |
"outputs": [], | |
"source": [ | |
"# 提前在Drive里准备好的一个视频 50M 30min\n", | |
"!cp ./drive/MyDrive/sample_videos/long.mp4 ." | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 5, | |
"metadata": { | |
"colab": { | |
"base_uri": "https://localhost:8080/" | |
}, | |
"id": "2s8pQRYZIr93", | |
"outputId": "2d346604-7674-4180-eed5-08d038da976e" | |
}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"name": "stdout", | |
"text": [ | |
"[youtube] jNQXAC9IVRw: Downloading webpage\n", | |
"[download] Destination: short.f133.mp4\n", | |
"\u001b[K[download] 100% of 200.32KiB in 00:03\n", | |
"[download] Destination: short.mp4.f140\n", | |
"\u001b[K[download] 100% of 301.95KiB in 00:04\n", | |
"[ffmpeg] Merging formats into \"short.mp4\"\n", | |
"Deleting original file short.f133.mp4 (pass -k to keep)\n", | |
"Deleting original file short.mp4.f140 (pass -k to keep)\n" | |
] | |
} | |
], | |
"source": [ | |
"# 从youtube上下载一个短视频\n", | |
"!youtube-dl 'https://www.youtube.com/watch?v=jNQXAC9IVRw' -o short.mp4 -f 'bestvideo[ext=mp4]+bestaudio[ext=m4a]/best[ext=mp4]/best'" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"source": [ | |
"# 从filesamples上下载一个4K视频 126M\n", | |
"!curl -O https://filesamples.com/samples/video/mp4/sample_3840x2160.mp4 # 126M 4k vid\n", | |
"!mv sample_3840x2160.mp4 big.mp4" | |
], | |
"metadata": { | |
"colab": { | |
"base_uri": "https://localhost:8080/" | |
}, | |
"id": "b4qxV7iTq1ZK", | |
"outputId": "c7e2b6b3-3439-4fe6-a55f-cd07abb84d5b" | |
}, | |
"execution_count": 6, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"name": "stdout", | |
"text": [ | |
" % Total % Received % Xferd Average Speed Time Time Time Current\n", | |
" Dload Upload Total Spent Left Speed\n", | |
"100 126M 0 126M 0 0 89.0M 0 --:--:-- 0:00:01 --:--:-- 89.0M\n" | |
] | |
} | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"source": [ | |
"## 内存使用分析\n", | |
"\n", | |
"+ `decord`的内存占用一般,不会把所有数据都载入,GPU版本和CPU版本在视频长度不同的情况下内存占用表现不一样。总体来说可以接受。\n", | |
"+ `mmcv`一导入就占据了很多内存(这个库重点不在读取视频,所以会加载很多其他的),初始化的时候不会占用很多内存,但是每读取一帧就增加一点内存?\n", | |
"+ `pyAV`和`OpenCV`差不多,内存使用不多" | |
], | |
"metadata": { | |
"id": "Tu3zzFXDW-gI" | |
} | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 14, | |
"metadata": { | |
"colab": { | |
"base_uri": "https://localhost:8080/" | |
}, | |
"id": "pKcgK6D4Kys_", | |
"outputId": "0ce271a0-9f98-4931-8f45-9b9a6544d80d" | |
}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"name": "stdout", | |
"text": [ | |
"Filename: tmp.py\n", | |
"\n", | |
"Line # Mem usage Increment Occurrences Line Contents\n", | |
"=============================================================\n", | |
" 4 76.219 MiB 76.219 MiB 1 @profile\n", | |
" 5 def my_func():\n", | |
" 6 107.246 MiB 31.027 MiB 1 vr = VideoReader('big.mp4', ctx=cpu(0))\n", | |
" 7 369.172 MiB 261.926 MiB 1 img = vr[0]\n", | |
" 8 421.359 MiB 52.188 MiB 1 img = vr[1]\n", | |
" 9 421.359 MiB 0.000 MiB 1 img = vr[2]\n", | |
" 10 425.477 MiB 4.117 MiB 1 img = vr[3]\n", | |
" 11 425.477 MiB 0.000 MiB 1 img = vr[4]\n", | |
" 12 437.328 MiB 11.852 MiB 1 img = vr[5]\n", | |
" 13 437.328 MiB 0.000 MiB 1 img = vr[6]\n", | |
" 14 438.352 MiB 1.023 MiB 1 img = vr[7]\n", | |
" 15 438.352 MiB 0.000 MiB 1 img = vr[8]\n", | |
" 16 438.352 MiB 0.000 MiB 1 img = vr[9]\n", | |
"\n", | |
"\n", | |
"CPU times: user 13.2 ms, sys: 30.3 ms, total: 43.5 ms\n", | |
"Wall time: 1.66 s\n" | |
] | |
} | |
], | |
"source": [ | |
"code = \"\"\"\n", | |
"from decord import VideoReader\n", | |
"from decord import cpu\n", | |
"@profile\n", | |
"def my_func():\n", | |
" vr = VideoReader('big.mp4', ctx=cpu(0))\n", | |
" img = vr[0]\n", | |
" img = vr[1]\n", | |
" img = vr[2]\n", | |
" img = vr[3]\n", | |
" img = vr[4]\n", | |
" img = vr[5]\n", | |
" img = vr[6]\n", | |
" img = vr[7]\n", | |
" img = vr[8]\n", | |
" img = vr[9]\n", | |
"\n", | |
"if __name__ == '__main__':\n", | |
" my_func()\n", | |
"\"\"\"\n", | |
"with open(\"tmp.py\", \"w+\") as f:\n", | |
" f.write(code)\n", | |
"%time !python -m memory_profiler tmp.py" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 15, | |
"metadata": { | |
"colab": { | |
"base_uri": "https://localhost:8080/" | |
}, | |
"outputId": "9983ce8c-fdee-4313-8024-56fbfa7661ba", | |
"id": "SfxIAFYYu_Un" | |
}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"name": "stdout", | |
"text": [ | |
"Filename: tmp.py\n", | |
"\n", | |
"Line # Mem usage Increment Occurrences Line Contents\n", | |
"=============================================================\n", | |
" 4 76.250 MiB 76.250 MiB 1 @profile\n", | |
" 5 def my_func():\n", | |
" 6 198.934 MiB 122.684 MiB 1 vr = VideoReader('big.mp4', ctx=gpu(0))\n", | |
" 7 263.465 MiB 64.531 MiB 1 img = vr[0]\n", | |
" 8 263.465 MiB 0.000 MiB 1 img = vr[1]\n", | |
" 9 263.465 MiB 0.000 MiB 1 img = vr[2]\n", | |
" 10 263.465 MiB 0.000 MiB 1 img = vr[3]\n", | |
" 11 263.465 MiB 0.000 MiB 1 img = vr[4]\n", | |
" 12 263.465 MiB 0.000 MiB 1 img = vr[5]\n", | |
" 13 263.465 MiB 0.000 MiB 1 img = vr[6]\n", | |
" 14 263.465 MiB 0.000 MiB 1 img = vr[7]\n", | |
" 15 263.465 MiB 0.000 MiB 1 img = vr[8]\n", | |
" 16 263.465 MiB 0.000 MiB 1 img = vr[9]\n", | |
"\n", | |
"\n", | |
"CPU times: user 14.2 ms, sys: 34.4 ms, total: 48.6 ms\n", | |
"Wall time: 1.16 s\n" | |
] | |
} | |
], | |
"source": [ | |
"code = \"\"\"\n", | |
"from decord import VideoReader\n", | |
"from decord import gpu\n", | |
"@profile\n", | |
"def my_func():\n", | |
" vr = VideoReader('big.mp4', ctx=gpu(0))\n", | |
" img = vr[0]\n", | |
" img = vr[1]\n", | |
" img = vr[2]\n", | |
" img = vr[3]\n", | |
" img = vr[4]\n", | |
" img = vr[5]\n", | |
" img = vr[6]\n", | |
" img = vr[7]\n", | |
" img = vr[8]\n", | |
" img = vr[9]\n", | |
"\n", | |
"if __name__ == '__main__':\n", | |
" my_func()\n", | |
"\"\"\"\n", | |
"with open(\"tmp.py\", \"w+\") as f:\n", | |
" f.write(code)\n", | |
"%time !python -m memory_profiler tmp.py" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 16, | |
"metadata": { | |
"colab": { | |
"base_uri": "https://localhost:8080/" | |
}, | |
"id": "KuNbH-OMVHOY", | |
"outputId": "7c1c8043-f6c2-41f0-cf78-711c1890e544" | |
}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"name": "stdout", | |
"text": [ | |
"Filename: tmp.py\n", | |
"\n", | |
"Line # Mem usage Increment Occurrences Line Contents\n", | |
"=============================================================\n", | |
" 3 281.496 MiB 281.496 MiB 1 @profile\n", | |
" 4 def my_func():\n", | |
" 5 308.559 MiB 27.062 MiB 1 v = VideoReader('big.mp4')\n", | |
" 6 411.469 MiB 102.910 MiB 1 img = next(v)\n", | |
" 7 451.512 MiB 40.043 MiB 1 img = next(v)\n", | |
" 8 479.375 MiB 27.863 MiB 1 img = next(v)\n", | |
" 9 503.137 MiB 23.762 MiB 1 img = next(v)\n", | |
" 10 526.883 MiB 23.746 MiB 1 img = next(v)\n", | |
" 11 562.488 MiB 35.605 MiB 1 img = next(v)\n", | |
" 12 586.500 MiB 24.012 MiB 1 img = next(v)\n", | |
" 13 610.258 MiB 23.758 MiB 1 img = next(v)\n", | |
" 14 638.711 MiB 28.453 MiB 1 img = next(v)\n", | |
" 15 662.793 MiB 24.082 MiB 1 img = next(v)\n", | |
"\n", | |
"\n", | |
"CPU times: user 27 ms, sys: 25.4 ms, total: 52.4 ms\n", | |
"Wall time: 2.86 s\n" | |
] | |
} | |
], | |
"source": [ | |
"code = \"\"\"\n", | |
"from mmcv import VideoReader\n", | |
"@profile\n", | |
"def my_func():\n", | |
" v = VideoReader('big.mp4')\n", | |
" img = next(v)\n", | |
" img = next(v)\n", | |
" img = next(v)\n", | |
" img = next(v)\n", | |
" img = next(v)\n", | |
" img = next(v)\n", | |
" img = next(v)\n", | |
" img = next(v)\n", | |
" img = next(v)\n", | |
" img = next(v)\n", | |
"\n", | |
"if __name__ == '__main__':\n", | |
" my_func()\n", | |
"\"\"\"\n", | |
"with open(\"tmp.py\", \"w+\") as f:\n", | |
" f.write(code)\n", | |
"%time !python -m memory_profiler tmp.py" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 17, | |
"metadata": { | |
"colab": { | |
"base_uri": "https://localhost:8080/" | |
}, | |
"id": "xwAh-RAHV57N", | |
"outputId": "17dd0271-78ad-4f01-e05f-f3b4b1587ff7" | |
}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"name": "stdout", | |
"text": [ | |
"Filename: tmp.py\n", | |
"\n", | |
"Line # Mem usage Increment Occurrences Line Contents\n", | |
"=============================================================\n", | |
" 3 76.363 MiB 76.363 MiB 1 @profile\n", | |
" 4 def my_func():\n", | |
" 5 104.723 MiB 28.359 MiB 1 cap = cv2.VideoCapture(\"big.mp4\")\n", | |
" 6 208.176 MiB 103.453 MiB 1 frame_exists, rgb = cap.read()\n", | |
" 7 247.961 MiB 39.785 MiB 1 frame_exists, rgb = cap.read()\n", | |
" 8 271.719 MiB 23.758 MiB 1 frame_exists, rgb = cap.read()\n", | |
" 9 271.719 MiB 0.000 MiB 1 frame_exists, rgb = cap.read()\n", | |
" 10 271.719 MiB 0.000 MiB 1 frame_exists, rgb = cap.read()\n", | |
" 11 271.719 MiB 0.000 MiB 1 frame_exists, rgb = cap.read()\n", | |
" 12 271.719 MiB 0.000 MiB 1 frame_exists, rgb = cap.read()\n", | |
" 13 271.719 MiB 0.000 MiB 1 frame_exists, rgb = cap.read()\n", | |
" 14 271.719 MiB 0.000 MiB 1 frame_exists, rgb = cap.read()\n", | |
" 15 271.969 MiB 0.250 MiB 1 frame_exists, rgb = cap.read()\n", | |
"\n", | |
"\n", | |
"CPU times: user 12.1 ms, sys: 32.3 ms, total: 44.4 ms\n", | |
"Wall time: 1.46 s\n" | |
] | |
} | |
], | |
"source": [ | |
"code = \"\"\"\n", | |
"import cv2\n", | |
"@profile\n", | |
"def my_func():\n", | |
" cap = cv2.VideoCapture(\"big.mp4\")\n", | |
" frame_exists, rgb = cap.read()\n", | |
" frame_exists, rgb = cap.read()\n", | |
" frame_exists, rgb = cap.read()\n", | |
" frame_exists, rgb = cap.read()\n", | |
" frame_exists, rgb = cap.read()\n", | |
" frame_exists, rgb = cap.read()\n", | |
" frame_exists, rgb = cap.read()\n", | |
" frame_exists, rgb = cap.read()\n", | |
" frame_exists, rgb = cap.read()\n", | |
" frame_exists, rgb = cap.read()\n", | |
"\n", | |
"if __name__ == '__main__':\n", | |
" my_func()\n", | |
"\"\"\"\n", | |
"with open(\"tmp.py\", \"w+\") as f:\n", | |
" f.write(code)\n", | |
"%time !python -m memory_profiler tmp.py" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 18, | |
"metadata": { | |
"colab": { | |
"base_uri": "https://localhost:8080/" | |
}, | |
"outputId": "ceaed6d9-1c17-4501-e295-7419f82db73f", | |
"id": "gejDzyu9r608" | |
}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"name": "stdout", | |
"text": [ | |
"Filename: tmp.py\n", | |
"\n", | |
"Line # Mem usage Increment Occurrences Line Contents\n", | |
"=============================================================\n", | |
" 4 55.141 MiB 55.141 MiB 1 @profile\n", | |
" 5 def my_func():\n", | |
" 6 81.105 MiB 25.965 MiB 1 with av.open(\"big.mp4\") as container:\n", | |
" 7 81.105 MiB 0.000 MiB 1 stream = container.streams.video[0]\n", | |
" 8 81.105 MiB 0.000 MiB 1 decoder = container.decode(stream)\n", | |
" 9 151.891 MiB 70.785 MiB 1 array = next(decoder).to_ndarray(format=\"rgb24\")\n", | |
" 10 192.848 MiB 40.957 MiB 1 array = next(decoder).to_ndarray(format=\"rgb24\")\n", | |
" 11 216.438 MiB 23.590 MiB 1 array = next(decoder).to_ndarray(format=\"rgb24\")\n", | |
" 12 216.672 MiB 0.234 MiB 1 array = next(decoder).to_ndarray(format=\"rgb24\")\n", | |
" 13 216.688 MiB 0.016 MiB 1 array = next(decoder).to_ndarray(format=\"rgb24\")\n", | |
" 14 216.688 MiB 0.000 MiB 1 array = next(decoder).to_ndarray(format=\"rgb24\")\n", | |
" 15 216.695 MiB 0.008 MiB 1 array = next(decoder).to_ndarray(format=\"rgb24\")\n", | |
" 16 216.695 MiB 0.000 MiB 1 array = next(decoder).to_ndarray(format=\"rgb24\")\n", | |
" 17 216.695 MiB 0.000 MiB 1 array = next(decoder).to_ndarray(format=\"rgb24\")\n", | |
" 18 216.703 MiB 0.008 MiB 1 array = next(decoder).to_ndarray(format=\"rgb24\")\n", | |
"\n", | |
"\n" | |
] | |
} | |
], | |
"source": [ | |
"code = \"\"\"\n", | |
"import av\n", | |
"\n", | |
"@profile\n", | |
"def my_func():\n", | |
" with av.open(\"big.mp4\") as container:\n", | |
" stream = container.streams.video[0]\n", | |
" decoder = container.decode(stream)\n", | |
" array = next(decoder).to_ndarray(format=\"rgb24\")\n", | |
" array = next(decoder).to_ndarray(format=\"rgb24\")\n", | |
" array = next(decoder).to_ndarray(format=\"rgb24\")\n", | |
" array = next(decoder).to_ndarray(format=\"rgb24\")\n", | |
" array = next(decoder).to_ndarray(format=\"rgb24\")\n", | |
" array = next(decoder).to_ndarray(format=\"rgb24\")\n", | |
" array = next(decoder).to_ndarray(format=\"rgb24\")\n", | |
" array = next(decoder).to_ndarray(format=\"rgb24\")\n", | |
" array = next(decoder).to_ndarray(format=\"rgb24\")\n", | |
" array = next(decoder).to_ndarray(format=\"rgb24\")\n", | |
"if __name__ == '__main__':\n", | |
" my_func()\n", | |
"\"\"\"\n", | |
"with open(\"tmp.py\", \"w+\") as f:\n", | |
" f.write(code)\n", | |
"!python -m memory_profiler tmp.py" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"source": [ | |
"## 接口比较\n", | |
"\n", | |
"每个方法都实现顺序读取视频和随机读取视频。\n", | |
"\n", | |
"+ `decord`和`mmcv`提供的接口很方便,面向对象,基本没有什么门槛。\n", | |
"+ `OpenCV`提供的接口没有那么方便,和c更接近一些,获取一些属性要先翻文档,\n", | |
"+ `pyAV`太底层了,是ffmpeg的python包装,更擅长处理不同格式视频流,不是很方便。由于其seek方法是基于时间的,没有找到基于帧序号的……" | |
], | |
"metadata": { | |
"id": "-ZQsW1QP8aPl" | |
} | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 4, | |
"metadata": { | |
"id": "O1D5SFpNu2eU" | |
}, | |
"outputs": [], | |
"source": [ | |
"import decord\n", | |
"import mmcv\n", | |
"import cv2\n", | |
"import time\n", | |
"import random\n", | |
"from tqdm import tqdm\n", | |
"from decord import cpu, gpu\n", | |
"import av\n", | |
"def seq_read_decord(path, use_tqdm=True):\n", | |
" vr = decord.VideoReader(path, ctx=cpu(0))\n", | |
" for i in tqdm(range(len(vr)), disable=not use_tqdm):\n", | |
" img = vr[i]\n", | |
"def random_read_decord(path, random_num=100, use_tqdm=True):\n", | |
" vr = decord.VideoReader(path, ctx=cpu(0))\n", | |
" vl = len(vr)\n", | |
" for _ in tqdm(range(random_num), disable=not use_tqdm):\n", | |
" i = random.randrange(0, vl)\n", | |
" frame = vr[i]\n", | |
"\n", | |
"def seq_read_decord_gpu(path, use_tqdm=True):\n", | |
" vr = decord.VideoReader(path, ctx=gpu(0))\n", | |
" for i in tqdm(range(len(vr)), disable=not use_tqdm):\n", | |
" img = vr[i]\n", | |
"def random_read_decord_gpu(path, random_num=100, use_tqdm=True):\n", | |
" vr = decord.VideoReader(path, ctx=gpu(0))\n", | |
" vl = len(vr)\n", | |
" for _ in tqdm(range(random_num), disable=not use_tqdm):\n", | |
" i = random.randrange(0, vl)\n", | |
" frame = vr[i]\n", | |
"\n", | |
"def seq_read_mmcv(path, use_tqdm=True):\n", | |
" vr = mmcv.VideoReader(path)\n", | |
" for img in tqdm(vr, disable=not use_tqdm):\n", | |
" frame = img\n", | |
"def random_read_mmcv(path, random_num=100, use_tqdm=True):\n", | |
" vr = mmcv.VideoReader(path)\n", | |
" vl = len(vr)\n", | |
" for _ in tqdm(range(random_num), disable=not use_tqdm):\n", | |
" i = random.randrange(0, vl)\n", | |
" frame = vr[i]\n", | |
"\n", | |
"def seq_read_cv2(path, use_tqdm=True):\n", | |
" cap = cv2.VideoCapture(path)\n", | |
" pbar = tqdm(total=cap.get(cv2.CAP_PROP_FRAME_COUNT), disable=not use_tqdm)\n", | |
" while cap.isOpened():\n", | |
" frame_exists, rgb = cap.read()\n", | |
" pbar.update(1)\n", | |
" if frame_exists:\n", | |
" rgb = cv2.cvtColor(rgb, cv2.COLOR_BGR2RGB) # we need rgb numpy\n", | |
" else:\n", | |
" cap.release()\n", | |
" pbar.close()\n", | |
" break\n", | |
"def random_read_cv2(path, random_num=100, use_tqdm=True):\n", | |
" cap = cv2.VideoCapture(path)\n", | |
" vl = cap.get(cv2.CAP_PROP_FRAME_COUNT)\n", | |
" for _ in tqdm(range(random_num), disable=not use_tqdm):\n", | |
" i = random.randrange(0, vl)\n", | |
" cap.set(cv2.CAP_PROP_POS_FRAMES, i)\n", | |
" frame_exists, rgb = cap.read()\n", | |
" if frame_exists:\n", | |
" rgb = cv2.cvtColor(rgb, cv2.COLOR_BGR2RGB)\n", | |
" else:\n", | |
" cap.release()\n", | |
" break\n", | |
"\n", | |
"def seq_read_av(path, use_tqdm=True):\n", | |
" with av.open(path) as container:\n", | |
" stream = container.streams.video[0]\n", | |
" for frame in tqdm(container.decode(stream), disable=not use_tqdm):\n", | |
" array = frame.to_ndarray(format=\"rgb24\")\n", | |
" # print(type(array), array.dtype, array.shape)\n", | |
"\n", | |
"def random_read_av(path, random_num=100, use_tqdm=True):\n", | |
" # 要获取特定的第n帧太难了……\n", | |
" pass\n" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"source": [ | |
"## 进行速度测试\n", | |
"\n", | |
"`OpenCV`在各方面表现都不错,可以作为一个基准进行比较。\n", | |
"\n", | |
"`decord`的GPU版本可能是在读取视频的时候要用GPU初始化,比较耗时,所以处理短视频较慢,而在长视频和4K视频中比其他方法强很多。其CPU版本比`OpenCV`略差一些。\n", | |
"\n", | |
"`mmcv`和`OpenCV`基本一致,在长视频和4K视频的顺序读取略强,在4K视频的随机读取略弱。\n", | |
"\n", | |
"`pyAV`在测试中没有表现出特点,结果都是较慢。\n", | |
"\n", | |
"> 由于时间原因,可能比较不是特别全面,多次运行可能会得到不同的结果,但是比较明显的结论不会改变:GPU版本的decord在处理数据量更大的视频时优势很明显。\n", | |
"\n", | |
"![临时算IO榜单_00.png](data:image/png;base64,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HiOAkOFMGpfIqvcLCRoyjrEXXhniZO/WnZSb+zEtq3+Tz4+aozPJGvYG2/K2s/XobQxMrbdUV95/0iMYfr/fv3//flJSUrBa2/yItEj35a3h1PETlDoNQiLj6RUX1uQZCW9NCceKyvDYYumdHH3JszZ4qiguLKbCbSUyoTfx4U2sxVNHVZ1BSPilEx6c5yo/zrFTTuzxfUiMsILXSXUd2MOa/84lZa0t4+SpMmrcZkJjE0l0NHWe1k1NxRmsjrDWn8X11nLqeBGldWCP7kVSbGg3fidSPd2ujbioPHmS0hoftuhe9GrQPtrRLqCLtw0XNZVugiJCGx0Auqiu9BAcEdLocw+1lU5MoWHYzIFcR8PvNV9Hly5bXVEHdgdhXXUWfW8Np44XcbrGiyUslsTEGEIu2S8u9rz6H/zXhzbm//rnzE+q4XhBCc6QOPokOpqf/KWl+G0u5jy1VDpNhDYZVz2hftrSF3gpev//8e+vHGH4w7/l+9OiLv7FWUW1JxjH5X68p5aKGj8hjsbxA113/0l35XK5OHLkCNHR0UqwREREpCtrlGD10805nYbnMG/94ue8VTKWb/7220zpAheuRdqrfoKlSS5EREREJOBcB9aw/rCXyJHjGaXkSnoQneYRERGRLsxM7OCpzPZaGRipw5rOxOmNZfjsW0i9djSaRF16Et0iKCIiIiIicgV0i6CIiIiIiMjnQAmWiIiIiIhIgCjBEhERERERCRAlWCIiIiIiIgGiBEtERERERCRAlGCJiIiIiIgEiBIsERERERGRAFGCJSIiIiIiEiBKsERERERERAJECZaIiIiIiEiAKMESEREREREJECVYIiIiIiIiAaIES0REREREJECUYImIiIiIiASIEiwREREREZEAUYIlIiIiIiISIEqwREREREREAkQJloiIiIiISIAowRIREREREQkQJVgiIiIiIiIBYjn/j9OnT2OxWC63rIiIiIiIiDTidrsv/PtCRlVZWdkhhREREREREekOLBYL/x8Knd8yu/jirwAAAABJRU5ErkJggg==)" | |
], | |
"metadata": { | |
"id": "CfPLa5oE921n" | |
} | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 5, | |
"metadata": { | |
"id": "-DdP0tMYwYdB" | |
}, | |
"outputs": [], | |
"source": [ | |
"def seq_read(func, path, repeat, use_tqdm=True):\n", | |
" start_time = time.time()\n", | |
" for _ in range(repeat):\n", | |
" func(path, use_tqdm=use_tqdm)\n", | |
" end_time = time.time()\n", | |
" return end_time - start_time\n", | |
"def random_read(func, path, repeat, random_num, use_tqdm=True):\n", | |
" start_time = time.time()\n", | |
" for _ in range(repeat):\n", | |
" func(path, random_num, use_tqdm=use_tqdm)\n", | |
" end_time = time.time()\n", | |
" return end_time - start_time" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": { | |
"colab": { | |
"base_uri": "https://localhost:8080/" | |
}, | |
"id": "rG1e_z5fz-dv", | |
"outputId": "1da3281d-2df3-4d27-d94b-d6614548ff8f" | |
}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"name": "stdout", | |
"text": [ | |
"For short video: \n", | |
"Sequential Read[100x]:\n", | |
"Decord GPU: 19.576740026474\n", | |
"Decord: 14.319761991500854\n", | |
"MMCV: 11.701236248016357\n", | |
"OpenCV: 11.556411266326904\n", | |
"PyAV: 17.922401189804077\n", | |
"Random Read[1x]:\n" | |
] | |
} | |
], | |
"source": [ | |
"seq_repeat = 100\n", | |
"path = \"short.mp4\"\n", | |
"print(f\"For short video: \")\n", | |
"print(f\"Sequential Read[{seq_repeat}x]:\")\n", | |
"print(f\"Decord GPU: {seq_read(seq_read_decord_gpu, path, seq_repeat, use_tqdm=False)}\")\n", | |
"print(f\"Decord: {seq_read(seq_read_decord, path, seq_repeat, use_tqdm=False)}\")\n", | |
"print(f\"MMCV: {seq_read(seq_read_mmcv, path, seq_repeat, use_tqdm=False)}\")\n", | |
"print(f\"OpenCV: {seq_read(seq_read_cv2, path, seq_repeat, use_tqdm=False)}\")\n", | |
"print(f\"PyAV: {seq_read(seq_read_av, path, seq_repeat, use_tqdm=False)}\")" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"source": [ | |
"path = \"short.mp4\"\n", | |
"random_repeat = 1\n", | |
"random_num = 100\n", | |
"print(f\"Random Read[{random_repeat}x]:\")\n", | |
"print(f\"Decord GPU: {random_read(random_read_decord_gpu, path, random_repeat, random_num, use_tqdm=False)}\")\n", | |
"print(f\"Decord: {random_read(random_read_decord, path, random_repeat, random_num, use_tqdm=False)}\")\n", | |
"print(f\"MMCV: {random_read(random_read_mmcv, path, random_repeat, random_num, use_tqdm=False)}\")\n", | |
"print(f\"OpenCV: {random_read(random_read_cv2, path, random_repeat, random_num, use_tqdm=False)}\")" | |
], | |
"metadata": { | |
"colab": { | |
"base_uri": "https://localhost:8080/" | |
}, | |
"id": "97Y6UaXYe6pV", | |
"outputId": "bb893fa8-6b9f-4c69-8aec-a6992231e24a" | |
}, | |
"execution_count": 7, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"name": "stdout", | |
"text": [ | |
"Random Read[1x]:\n", | |
"Decord GPU: 5.913957834243774\n", | |
"Decord: 1.5877439975738525\n", | |
"MMCV: 1.6674537658691406\n", | |
"OpenCV: 1.8470497131347656\n" | |
] | |
} | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 11, | |
"metadata": { | |
"colab": { | |
"base_uri": "https://localhost:8080/" | |
}, | |
"id": "JR5XFOCEz_sh", | |
"outputId": "4233be5d-50e3-49bc-df3d-4e35a64cb972" | |
}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"name": "stdout", | |
"text": [ | |
"For long video: \n", | |
"Sequential Read[1x]:\n" | |
] | |
}, | |
{ | |
"output_type": "stream", | |
"name": "stderr", | |
"text": [ | |
"100%|██████████| 45000/45000 [01:13<00:00, 614.93it/s]\n" | |
] | |
}, | |
{ | |
"output_type": "stream", | |
"name": "stdout", | |
"text": [ | |
"Decord GPU: 73.3991289138794\n" | |
] | |
}, | |
{ | |
"output_type": "stream", | |
"name": "stderr", | |
"text": [ | |
"100%|██████████| 45000/45000 [04:22<00:00, 171.58it/s]\n" | |
] | |
}, | |
{ | |
"output_type": "stream", | |
"name": "stdout", | |
"text": [ | |
"Decord: 262.47067618370056\n" | |
] | |
}, | |
{ | |
"output_type": "stream", | |
"name": "stderr", | |
"text": [ | |
"100%|█████████▉| 44998/45000 [03:33<00:00, 210.65it/s]\n" | |
] | |
}, | |
{ | |
"output_type": "stream", | |
"name": "stdout", | |
"text": [ | |
"MMCV: 213.643714427948\n" | |
] | |
}, | |
{ | |
"output_type": "stream", | |
"name": "stderr", | |
"text": [ | |
"100%|█████████▉| 44999/45000.0 [04:15<00:00, 175.97it/s]\n" | |
] | |
}, | |
{ | |
"output_type": "stream", | |
"name": "stdout", | |
"text": [ | |
"OpenCV: 255.74768257141113\n" | |
] | |
}, | |
{ | |
"output_type": "stream", | |
"name": "stderr", | |
"text": [ | |
"44998it [03:46, 198.68it/s]\n" | |
] | |
}, | |
{ | |
"output_type": "stream", | |
"name": "stdout", | |
"text": [ | |
"PyAV: 226.53186297416687\n", | |
"Random Read[5x]:\n" | |
] | |
}, | |
{ | |
"output_type": "stream", | |
"name": "stderr", | |
"text": [ | |
"100%|██████████| 100/100 [00:18<00:00, 5.52it/s]\n", | |
"100%|██████████| 100/100 [00:17<00:00, 5.59it/s]\n", | |
"100%|██████████| 100/100 [00:16<00:00, 6.02it/s]\n", | |
"100%|██████████| 100/100 [00:18<00:00, 5.40it/s]\n", | |
"100%|██████████| 100/100 [00:18<00:00, 5.32it/s]\n" | |
] | |
}, | |
{ | |
"output_type": "stream", | |
"name": "stdout", | |
"text": [ | |
"Decord GPU: 90.98765110969543\n" | |
] | |
}, | |
{ | |
"output_type": "stream", | |
"name": "stderr", | |
"text": [ | |
"100%|██████████| 100/100 [00:41<00:00, 2.39it/s]\n", | |
"100%|██████████| 100/100 [00:41<00:00, 2.42it/s]\n", | |
"100%|██████████| 100/100 [00:41<00:00, 2.39it/s]\n", | |
"100%|██████████| 100/100 [00:44<00:00, 2.22it/s]\n", | |
"100%|██████████| 100/100 [00:41<00:00, 2.39it/s]\n" | |
] | |
}, | |
{ | |
"output_type": "stream", | |
"name": "stdout", | |
"text": [ | |
"Decord: 212.76363229751587\n" | |
] | |
}, | |
{ | |
"output_type": "stream", | |
"name": "stderr", | |
"text": [ | |
"100%|██████████| 100/100 [00:34<00:00, 2.92it/s]\n", | |
"100%|██████████| 100/100 [00:34<00:00, 2.88it/s]\n", | |
"100%|██████████| 100/100 [00:37<00:00, 2.64it/s]\n", | |
"100%|██████████| 100/100 [00:36<00:00, 2.73it/s]\n", | |
"100%|██████████| 100/100 [00:34<00:00, 2.91it/s]\n" | |
] | |
}, | |
{ | |
"output_type": "stream", | |
"name": "stdout", | |
"text": [ | |
"MMCV: 178.0106749534607\n" | |
] | |
}, | |
{ | |
"output_type": "stream", | |
"name": "stderr", | |
"text": [ | |
"100%|██████████| 100/100 [00:34<00:00, 2.90it/s]\n", | |
"100%|██████████| 100/100 [00:33<00:00, 2.96it/s]\n", | |
"100%|██████████| 100/100 [00:33<00:00, 3.00it/s]\n", | |
"100%|██████████| 100/100 [00:35<00:00, 2.81it/s]\n", | |
"100%|██████████| 100/100 [00:37<00:00, 2.63it/s]" | |
] | |
}, | |
{ | |
"output_type": "stream", | |
"name": "stdout", | |
"text": [ | |
"OpenCV: 175.26724076271057\n" | |
] | |
}, | |
{ | |
"output_type": "stream", | |
"name": "stderr", | |
"text": [ | |
"\n" | |
] | |
} | |
], | |
"source": [ | |
"seq_repeat = 1\n", | |
"random_repeat = 5\n", | |
"random_num = 100\n", | |
"path = \"long.mp4\"\n", | |
"print(f\"For long video: \")\n", | |
"print(f\"Sequential Read[{seq_repeat}x]:\")\n", | |
"print(f\"Decord GPU: {seq_read(seq_read_decord_gpu, path, seq_repeat, use_tqdm=True)}\")\n", | |
"print(f\"Decord: {seq_read(seq_read_decord, path, seq_repeat, use_tqdm=True)}\")\n", | |
"print(f\"MMCV: {seq_read(seq_read_mmcv, path, seq_repeat, use_tqdm=True)}\")\n", | |
"print(f\"OpenCV: {seq_read(seq_read_cv2, path, seq_repeat, use_tqdm=True)}\")\n", | |
"print(f\"PyAV: {seq_read(seq_read_av, path, seq_repeat, use_tqdm=True)}\")\n", | |
"\n", | |
"print(f\"Random Read[{random_repeat}x]:\")\n", | |
"print(f\"Decord GPU: {random_read(random_read_decord_gpu, path, random_repeat, random_num, use_tqdm=True)}\")\n", | |
"print(f\"Decord: {random_read(random_read_decord, path, random_repeat, random_num, use_tqdm=True)}\")\n", | |
"print(f\"MMCV: {random_read(random_read_mmcv, path, random_repeat, random_num, use_tqdm=True)}\")\n", | |
"print(f\"OpenCV: {random_read(random_read_cv2, path, random_repeat, random_num, use_tqdm=True)}\")" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 8, | |
"metadata": { | |
"colab": { | |
"base_uri": "https://localhost:8080/", | |
"height": 991 | |
}, | |
"outputId": "5cfbeae0-858a-4df6-bb52-81068752deff", | |
"id": "cDlitQxS_RDn" | |
}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"name": "stdout", | |
"text": [ | |
"For big video: \n", | |
"Sequential Read[5x]:\n" | |
] | |
}, | |
{ | |
"output_type": "stream", | |
"name": "stderr", | |
"text": [ | |
"100%|██████████| 677/677 [00:04<00:00, 155.42it/s]\n", | |
"100%|██████████| 677/677 [00:04<00:00, 162.28it/s]\n", | |
"100%|██████████| 677/677 [00:04<00:00, 165.06it/s]\n", | |
"100%|██████████| 677/677 [00:04<00:00, 160.76it/s]\n", | |
"100%|██████████| 677/677 [00:04<00:00, 161.86it/s]\n" | |
] | |
}, | |
{ | |
"output_type": "stream", | |
"name": "stdout", | |
"text": [ | |
"Decord GPU: 22.91811966896057\n" | |
] | |
}, | |
{ | |
"output_type": "stream", | |
"name": "stderr", | |
"text": [ | |
"100%|██████████| 677/677 [00:41<00:00, 16.45it/s]\n", | |
"100%|██████████| 677/677 [00:37<00:00, 18.08it/s]\n", | |
"100%|██████████| 677/677 [00:37<00:00, 18.22it/s]\n", | |
"100%|██████████| 677/677 [00:38<00:00, 17.36it/s]\n", | |
"100%|██████████| 677/677 [00:36<00:00, 18.37it/s]\n" | |
] | |
}, | |
{ | |
"output_type": "stream", | |
"name": "stdout", | |
"text": [ | |
"Decord: 192.9010877609253\n" | |
] | |
}, | |
{ | |
"output_type": "stream", | |
"name": "stderr", | |
"text": [ | |
"100%|██████████| 677/677 [00:35<00:00, 19.27it/s]\n", | |
"100%|██████████| 677/677 [00:34<00:00, 19.46it/s]\n", | |
"100%|██████████| 677/677 [00:36<00:00, 18.55it/s]\n", | |
"100%|██████████| 677/677 [00:34<00:00, 19.42it/s]\n", | |
"100%|██████████| 677/677 [00:34<00:00, 19.45it/s]\n" | |
] | |
}, | |
{ | |
"output_type": "stream", | |
"name": "stdout", | |
"text": [ | |
"MMCV: 176.829448223114\n" | |
] | |
}, | |
{ | |
"output_type": "stream", | |
"name": "stderr", | |
"text": [ | |
"678it [00:38, 17.81it/s] \n", | |
"678it [00:39, 17.19it/s] \n", | |
"678it [00:37, 17.86it/s] \n", | |
"678it [00:37, 17.85it/s] \n", | |
"678it [00:39, 17.11it/s] \n" | |
] | |
}, | |
{ | |
"output_type": "stream", | |
"name": "stdout", | |
"text": [ | |
"OpenCV: 193.79467034339905\n" | |
] | |
}, | |
{ | |
"output_type": "stream", | |
"name": "stderr", | |
"text": [ | |
"677it [00:39, 17.21it/s]\n", | |
"677it [00:39, 17.23it/s]\n", | |
"677it [00:41, 16.46it/s]\n", | |
"677it [00:39, 17.01it/s]\n", | |
"677it [00:40, 16.89it/s]\n" | |
] | |
}, | |
{ | |
"output_type": "stream", | |
"name": "stdout", | |
"text": [ | |
"PyAV: 200.42598056793213\n", | |
"Random Read[5x]:\n" | |
] | |
}, | |
{ | |
"output_type": "stream", | |
"name": "stderr", | |
"text": [ | |
" 28%|██▊ | 28/100 [00:19<00:48, 1.47it/s]\n" | |
] | |
}, | |
{ | |
"output_type": "error", | |
"ename": "DECORDError", | |
"evalue": "ignored", | |
"traceback": [ | |
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", | |
"\u001b[0;31mDECORDError\u001b[0m Traceback (most recent call last)", | |
"\u001b[0;32m<ipython-input-8-54aa6a942424>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[1;32m 12\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 13\u001b[0m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34mf\"Random Read[{random_repeat}x]:\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 14\u001b[0;31m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34mf\"Decord GPU: {random_read(random_read_decord_gpu, path, random_repeat, random_num, use_tqdm=True)}\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 15\u001b[0m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34mf\"Decord: {random_read(random_read_decord, path, random_repeat, random_num, use_tqdm=True)}\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 16\u001b[0m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34mf\"MMCV: {random_read(random_read_mmcv, path, random_repeat, random_num, use_tqdm=True)}\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", | |
"\u001b[0;32m<ipython-input-2-976d9979c9a7>\u001b[0m in \u001b[0;36mrandom_read\u001b[0;34m(func, path, repeat, random_num, use_tqdm)\u001b[0m\n\u001b[1;32m 8\u001b[0m \u001b[0mstart_time\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mtime\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mtime\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 9\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0m_\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mrange\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mrepeat\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 10\u001b[0;31m \u001b[0mfunc\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mpath\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mrandom_num\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0muse_tqdm\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0muse_tqdm\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 11\u001b[0m \u001b[0mend_time\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mtime\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mtime\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 12\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mend_time\u001b[0m \u001b[0;34m-\u001b[0m \u001b[0mstart_time\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", | |
"\u001b[0;32m<ipython-input-1-f86f577dfcde>\u001b[0m in \u001b[0;36mrandom_read_decord_gpu\u001b[0;34m(path, random_num, use_tqdm)\u001b[0m\n\u001b[1;32m 27\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0m_\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mtqdm\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mrange\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mrandom_num\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdisable\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mnot\u001b[0m \u001b[0muse_tqdm\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 28\u001b[0m \u001b[0mi\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mrandom\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mrandrange\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mvl\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 29\u001b[0;31m \u001b[0mframe\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mvr\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mi\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 30\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 31\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mseq_read_mmcv\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mpath\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0muse_tqdm\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mTrue\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", | |
"\u001b[0;32m~/.local/lib/python3.7/site-packages/decord-0.6.0-py3.7-linux-x86_64.egg/decord/video_reader.py\u001b[0m in \u001b[0;36m__getitem__\u001b[0;34m(self, idx)\u001b[0m\n\u001b[1;32m 103\u001b[0m \u001b[0;32mraise\u001b[0m \u001b[0mIndexError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"Index: {} out of bound: {}\"\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mformat\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0midx\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_num_frame\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 104\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mseek_accurate\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0midx\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 105\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mnext\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 106\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 107\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mnext\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", | |
"\u001b[0;32m~/.local/lib/python3.7/site-packages/decord-0.6.0-py3.7-linux-x86_64.egg/decord/video_reader.py\u001b[0m in \u001b[0;36mnext\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 115\u001b[0m \"\"\"\n\u001b[1;32m 116\u001b[0m \u001b[0;32massert\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_handle\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 117\u001b[0;31m \u001b[0marr\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0m_CAPI_VideoReaderNextFrame\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_handle\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 118\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0marr\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mshape\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 119\u001b[0m \u001b[0;32mraise\u001b[0m \u001b[0mStopIteration\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", | |
"\u001b[0;32m~/.local/lib/python3.7/site-packages/decord-0.6.0-py3.7-linux-x86_64.egg/decord/_ffi/_ctypes/function.py\u001b[0m in \u001b[0;36m__call__\u001b[0;34m(self, *args)\u001b[0m\n\u001b[1;32m 173\u001b[0m check_call(_LIB.DECORDFuncCall(\n\u001b[1;32m 174\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mhandle\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mvalues\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mtcodes\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mctypes\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mc_int\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mnum_args\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 175\u001b[0;31m ctypes.byref(ret_val), ctypes.byref(ret_tcode)))\n\u001b[0m\u001b[1;32m 176\u001b[0m \u001b[0m_\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mtemp_args\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 177\u001b[0m \u001b[0m_\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0margs\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", | |
"\u001b[0;32m~/.local/lib/python3.7/site-packages/decord-0.6.0-py3.7-linux-x86_64.egg/decord/_ffi/base.py\u001b[0m in \u001b[0;36mcheck_call\u001b[0;34m(ret)\u001b[0m\n\u001b[1;32m 76\u001b[0m \u001b[0merr_str\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0merr_str\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msplit\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'Stack trace'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mstrip\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 77\u001b[0m \u001b[0;32mraise\u001b[0m \u001b[0mDECORDLimitReachedError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0merr_str\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 78\u001b[0;31m \u001b[0;32mraise\u001b[0m \u001b[0mDECORDError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0merr_str\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 79\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 80\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", | |
"\u001b[0;31mDECORDError\u001b[0m: [11:33:47] /content/decord/src/video/video_reader.cc:444: [big.mp4]Unable to handle EOF because it takes too long to retrieve last few frames and `DECORD_EOF_RETRY_MAX=10240`. You may override the limit by `export DECORD_EOF_RETRY_MAX=20480` for example to allow more EOF retry attempts, exit..." | |
] | |
} | |
], | |
"source": [ | |
"seq_repeat = 5\n", | |
"random_repeat = 1\n", | |
"random_num = 100\n", | |
"path = \"big.mp4\"\n", | |
"print(f\"For big video: \")\n", | |
"print(f\"Sequential Read[{seq_repeat}x]:\")\n", | |
"print(f\"Decord GPU: {seq_read(seq_read_decord_gpu, path, seq_repeat, use_tqdm=True)}\")\n", | |
"print(f\"Decord: {seq_read(seq_read_decord, path, seq_repeat, use_tqdm=True)}\")\n", | |
"print(f\"MMCV: {seq_read(seq_read_mmcv, path, seq_repeat, use_tqdm=True)}\")\n", | |
"print(f\"OpenCV: {seq_read(seq_read_cv2, path, seq_repeat, use_tqdm=True)}\")\n", | |
"print(f\"PyAV: {seq_read(seq_read_av, path, seq_repeat, use_tqdm=True)}\")" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"source": [ | |
"import os\n", | |
"os.environ['DECORD_EOF_RETRY_MAX'] = \"20480\"\n", | |
"random_repeat = 1\n", | |
"random_num = 20\n", | |
"path = \"big.mp4\"\n", | |
"print(f\"Random Read[{random_repeat}x]:\")\n", | |
"print(f\"Decord GPU: {random_read(random_read_decord_gpu, path, random_repeat, random_num, use_tqdm=True)}\")\n", | |
"print(f\"Decord: {random_read(random_read_decord, path, random_repeat, random_num, use_tqdm=True)}\")\n", | |
"print(f\"MMCV: {random_read(random_read_mmcv, path, random_repeat, random_num, use_tqdm=True)}\")\n", | |
"print(f\"OpenCV: {random_read(random_read_cv2, path, random_repeat, random_num, use_tqdm=True)}\")" | |
], | |
"metadata": { | |
"colab": { | |
"base_uri": "https://localhost:8080/" | |
}, | |
"id": "0hiaQ2y1h4tZ", | |
"outputId": "64547c42-be3a-4f73-bcc7-0ef43e861fde" | |
}, | |
"execution_count": 8, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"name": "stdout", | |
"text": [ | |
"Random Read[1x]:\n" | |
] | |
}, | |
{ | |
"output_type": "stream", | |
"name": "stderr", | |
"text": [ | |
"100%|██████████| 20/20 [00:11<00:00, 1.74it/s]\n" | |
] | |
}, | |
{ | |
"output_type": "stream", | |
"name": "stdout", | |
"text": [ | |
"Decord GPU: 12.417755365371704\n" | |
] | |
}, | |
{ | |
"output_type": "stream", | |
"name": "stderr", | |
"text": [ | |
"100%|██████████| 20/20 [01:22<00:00, 4.12s/it]\n" | |
] | |
}, | |
{ | |
"output_type": "stream", | |
"name": "stdout", | |
"text": [ | |
"Decord: 82.7718915939331\n" | |
] | |
}, | |
{ | |
"output_type": "stream", | |
"name": "stderr", | |
"text": [ | |
"100%|██████████| 20/20 [02:02<00:00, 6.13s/it]\n" | |
] | |
}, | |
{ | |
"output_type": "stream", | |
"name": "stdout", | |
"text": [ | |
"MMCV: 122.92250633239746\n" | |
] | |
}, | |
{ | |
"output_type": "stream", | |
"name": "stderr", | |
"text": [ | |
"100%|██████████| 20/20 [01:45<00:00, 5.28s/it]" | |
] | |
}, | |
{ | |
"output_type": "stream", | |
"name": "stdout", | |
"text": [ | |
"OpenCV: 105.77272725105286\n" | |
] | |
}, | |
{ | |
"output_type": "stream", | |
"name": "stderr", | |
"text": [ | |
"\n" | |
] | |
} | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"source": [ | |
"## Bug分析\n", | |
"\n", | |
"Decord有的时候会遇到奇奇怪怪的bug(如上),尤其是GPU版本。" | |
], | |
"metadata": { | |
"id": "xewGJujBkcSY" | |
} | |
}, | |
{ | |
"cell_type": "markdown", | |
"source": [ | |
"## 总结\n", | |
"\n", | |
"假如要高效处理数据量大的视频,选用`Decord`的GPU版本。假如项目中其他地方会用到`mmcv`,那就用mmcv的VideoReader。其他情况假如想代码更易懂,则使用`Decord`,否则使用`OpenCV`。" | |
], | |
"metadata": { | |
"id": "X7F_7dDAmqxo" | |
} | |
}, | |
{ | |
"cell_type": "code", | |
"source": [], | |
"metadata": { | |
"id": "QmaRCGRLeih8" | |
}, | |
"execution_count": null, | |
"outputs": [] | |
} | |
], | |
"metadata": { | |
"colab": { | |
"collapsed_sections": [], | |
"name": "Benchmark of Video Reader in Python.ipynb", | |
"provenance": [] | |
}, | |
"kernelspec": { | |
"display_name": "Python 3", | |
"name": "python3" | |
}, | |
"language_info": { | |
"name": "python" | |
}, | |
"accelerator": "GPU", | |
"gpuClass": "standard" | |
}, | |
"nbformat": 4, | |
"nbformat_minor": 0 | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment