videoconvert: add an ffmpeg based video converter

To activate:

PIPEWIRE_PROPS='{ video.adapt.converter = video.convert.ffmpeg }' build/src/examples/video-play

This makes it possible to start firefox with mjpg capture and then
video-play and it will decode the mjpeg transparently. Works for other
incompatible video formats as well, as long as they can be mmapped.

Ideally this should use something GPU accelerated and this is what the
vulkan converter will do.
This commit is contained in:
Wim Taymans 2024-09-06 12:26:14 +02:00
parent b57375ba85
commit 2cbcdbc579
4 changed files with 1958 additions and 5 deletions

View file

@ -310,7 +310,8 @@ ffmpeg = get_option('ffmpeg')
if pw_cat_ffmpeg.allowed() or ffmpeg.allowed() if pw_cat_ffmpeg.allowed() or ffmpeg.allowed()
avcodec_dep = dependency('libavcodec', required: pw_cat_ffmpeg.enabled() or ffmpeg.enabled()) avcodec_dep = dependency('libavcodec', required: pw_cat_ffmpeg.enabled() or ffmpeg.enabled())
avformat_dep = dependency('libavformat', required: pw_cat_ffmpeg.enabled()) avformat_dep = dependency('libavformat', required: pw_cat_ffmpeg.enabled())
avutil_dep = dependency('libavutil', required: pw_cat_ffmpeg.enabled()) avutil_dep = dependency('libavutil', required: pw_cat_ffmpeg.enabled() or ffmpeg.enabled())
swscale_dep = dependency('libswscale', required: pw_cat_ffmpeg.enabled() or ffmpeg.enabled())
else else
avcodec_dep = dependency('', required: false) avcodec_dep = dependency('', required: false)
endif endif

View file

@ -4,13 +4,23 @@ videoconvert_sources = [
'plugin.c' 'plugin.c'
] ]
simd_cargs = [] extra_cargs = []
simd_dependencies = [] extra_dependencies = []
if avcodec_dep.found() and avutil_dep.found() and swscale_dep.found()
videoconvert_ffmpeg = static_library('videoconvert_fmmpeg',
['videoconvert-ffmpeg.c' ],
dependencies : [ spa_dep, avcodec_dep, avutil_dep, swscale_dep ],
install : false
)
extra_cargs += '-D HAVE_VIDEOCONVERT_FFMPEG'
extra_dependencies += videoconvert_ffmpeg
endif
videoconvertlib = shared_library('spa-videoconvert', videoconvertlib = shared_library('spa-videoconvert',
videoconvert_sources, videoconvert_sources,
c_args : simd_cargs, c_args : extra_cargs,
dependencies : [ spa_dep, mathlib ], dependencies : [ spa_dep, mathlib ],
link_with : simd_dependencies, link_with : extra_dependencies,
install : true, install : true,
install_dir : spa_plugindir / 'videoconvert') install_dir : spa_plugindir / 'videoconvert')

View file

@ -9,6 +9,9 @@
extern const struct spa_handle_factory spa_videoadapter_factory; extern const struct spa_handle_factory spa_videoadapter_factory;
extern const struct spa_handle_factory spa_videoconvert_dummy_factory; extern const struct spa_handle_factory spa_videoconvert_dummy_factory;
#if HAVE_VIDEOCONVERT_FFMPEG
extern const struct spa_handle_factory spa_videoconvert_ffmpeg_factory;
#endif
SPA_LOG_TOPIC_ENUM_DEFINE_REGISTERED; SPA_LOG_TOPIC_ENUM_DEFINE_REGISTERED;
@ -25,6 +28,11 @@ int spa_handle_factory_enum(const struct spa_handle_factory **factory, uint32_t
case 1: case 1:
*factory = &spa_videoconvert_dummy_factory; *factory = &spa_videoconvert_dummy_factory;
break; break;
#if HAVE_VIDEOCONVERT_FFMPEG
case 2:
*factory = &spa_videoconvert_ffmpeg_factory;
break;
#endif
default: default:
return 0; return 0;
} }

File diff suppressed because it is too large Load diff