From e8a946fa27c2234602b39e00a9a78772ee879a81 Mon Sep 17 00:00:00 2001 From: Yong Tang Date: Mon, 25 Feb 2019 05:49:52 +0000 Subject: [PATCH] Use dlopen to resolve ffmpeg symbols at runtime. Signed-off-by: Yong Tang --- .../video/python/ops/video_dataset_ops.py | 50 ++++++++++++++++--- 1 file changed, 43 insertions(+), 7 deletions(-) diff --git a/tensorflow_io/video/python/ops/video_dataset_ops.py b/tensorflow_io/video/python/ops/video_dataset_ops.py index 22ba6b7df..23dab3876 100644 --- a/tensorflow_io/video/python/ops/video_dataset_ops.py +++ b/tensorflow_io/video/python/ops/video_dataset_ops.py @@ -18,20 +18,56 @@ from __future__ import print_function import os +import ctypes +import _ctypes import tensorflow from tensorflow import dtypes from tensorflow import errors from tensorflow.compat.v1 import data from tensorflow_io import _load_library -video_ops = None -for f in ['_video_ops_ffmpeg_3.4.so', '_video_ops_ffmpeg_2.8.so', '_video_ops_libav_9.20.so']: - try: - video_ops = _load_library(f) - break; - except NotImplementedError as e: - print(e) +def load_dependency_and_library(p): + for library in p: + # First try load all dependencies with RTLD_LOCAL + entries = [] + for dependency in p[library]: + try: + entries.append(ctypes.CDLL(dependency)) + except OSError as e: + pass + if len(entries) == len(p[library]): + # Dependencies has been satisfied, load dependencies again with RTLD_GLOBAL, no error is expected + for dependency in p[library]: + ctypes.CDLL(dependency, mode=ctypes.RTLD_GLOBAL) + # Load video_op + return _load_library(library) + # Otherwise we dlclose and retry + entries.reverse() + for entry in entries: + _ctypes.dlclose(entry._handle) + raise NotImplementedError("could not find ffmpeg after search through ", p) + +video_ops = load_dependency_and_library({ + '_video_ops_ffmpeg_3.4.so' : [ + "libavformat.so.57", + "libavformat.so.57", + "libavutil.so.55", + "libswscale.so.4", + ], + '_video_ops_ffmpeg_2.8.so' : [ + "libavformat-ffmpeg.so.56", + "libavcodec-ffmpeg.so.56", + "libavutil-ffmpeg.so.54", + "libswscale-ffmpeg.so.3", + ], + '_video_ops_libav_9.20.so' : [ + "libavformat.so.54", + "libavcodec.so.54", + "libavutil.so.52", + "libswscale.so.2", + ], +}) class VideoDataset(data.Dataset): """A Video File Dataset that reads the video file."""