2015-12-18 2 views
0

Mon projet utilise libavformat pour se connecter aux URL rtsp://. Il est important de définir un délai d'attente de socket et de se reconnecter en cas d'erreur. Malheureusement, l'option ouverte stimeout pour cela n'existe que dans ffmpeg (et en particulier, ses versions libavformat> = 55.1.100), pas le projet concurrent libav (toute version). Et certains systèmes que je voudrais prendre en charge (comme Raspbian Jessie) sont toujours livrés avec libav. Donc, je pense que ma meilleure option est de détecter si j'ai une version appropriée en utilisant cmake, et installez ffmpeg in-tree si ce n'est pas le cas. Je pense que je devrais être en mesure de le faire via quelque chose comme:Comment puis-je détecter ffmpeg vs libav dans CMake?

pkg_check_modules(FFMPEG libavutil libavcodec libavformat) 

if(not FFMPEG_FOUND or FFMPEG_VERSION VERSION_LESS 55.1.101) 
    ExternalProject_Add(
    FfmpegProject 
    URL "http://ffmpeg.org/releases/ffmpeg-2.8.3.tar.xz" 
    URL_HASH "SHA1=a6f39efe1bea9a9b271c903d3c1dcb940a510c87" 
    INSTALL_COMMAND "") 
    ...set up flags and such to use this in-tree version... 
endif() 

sauf que je ne sais pas comment détecter libav vs ffmpeg. Je ne vois rien dans les trucs pkgconfig ou libavformat/version.h pour les distinguer. Les numéros de version qu'ils utilisent semblent se chevaucher. Ce n'est pas évident pour moi de savoir comment faire la différence par programmation, et encore moins de le faire avec une règle de cmake pas si étrange. Des idées?

+0

Vous pouvez exécuter 'ffmpeg' et utiliser' stimeout' pour voir s'il le supporte. – arrowd

+0

@arrowd Je ne suis pas sûr que la bibliothèque que j'utilise soit la même que celle utilisée par ffmpeg, par exemple. Je voudrais détecter de manière fiable ce que j'utilise réellement. –

+0

Je suppose qu'une possibilité est d'écrire un programme qui appelle 'avformat_open_input' et renvoie une erreur si' stimeout' est encore laissé dans le dict 'options' après (signifiant qu'il a été ignoré). Il pourrait utiliser une URL bidon qui échouera toujours rapidement, comme peut-être "rtsp: //0.0.0.0: 0 /". Je suppose que cmake a cette construction [try_run] (https://cmake.org/cmake/help/v3.0/command/try_run.html) pour faire quelque chose comme ça. –

Répondre

5

Pour répondre précisément à votre question, utilisez ce code:

#include <stdio.h> 
#include "libavutil/opt.h" 
#include "libavformat/avformat.h" 

int main(int argc, char *argv[]) { 
    av_register_all(); 
    AVInputFormat *input = av_find_input_format("rtsp"); 
    const AVClass *klass = input->priv_class; 
    const AVOption *opt = av_opt_find2(&klass, argv[1], NULL, 0, AV_OPT_SEARCH_FAKE_OBJ, NULL); 
    printf("%p\n", opt); 
    return 0; 
} 

Cela peut faire la détection d'exécution, et voici comment cela fonctionne:

bash-3.2$ /tmp/test hi 
0x0 
bash-3.2$ /tmp/test stimeout 
0x103420100 

Pour votre autre question, la détection Libav contre FFmpeg peut être fait en regardant la version micro de la bibliothèque. Pour FFmpeg, ils commencent tous à 100 (par exemple libavformat 55.1.100), alors que pour Libav, ils commencent à 0. Donc, si micro < 100, c'est Libav, sinon c'est FFmpeg. Pour obtenir la version micro libavformat à l'exécution, utilisez avformat_version() & 0xff ou LIBAVFORMAT_VERSION_MICRO au moment de la compilation.