Solución al "Protocolo no encontrado" de ffmpeg en Windows

1. Descripción del problema

Llame a la biblioteca ffmpeg, si usa avformat_open_input para abrir el retorno -1330794744, use av_strerror

	 char buf[1024]={
    
    0};

 	int result = avformat_open_input(&pAVFormatContext, _url.toStdString().c_str(), nullptr, nullptr);
    if(result < 0)
    {
    
    
         av_strerror(result,buf,sizeof(buf));
        qDebug() << "open video "<< _url <<"failure" <<QString(buf);
        return false;
    }

La solución general en Internet requiere dos pasos:

  • Cuando se inicializa el código, se registran todos los protocolos
	av_register_all();
  • Para compilar la biblioteca dinámica ffmpeg, debe agregar la opción –enable-protocols

Pero mi problema es bastante extraño.Usando el mismo conjunto de código en Qt 5.12.6 bajo windwos, funciona normalmente en un proyecto de prueba simple, pero sale mal cuando se integra en un proyecto formal a gran escala. Además, cuando se reemplaza el compilador en el proyecto de prueba, ya sea que se use MinGW 64 o VS2017 de 64 bits, se ejecuta normalmente y se excluye el motivo del compilador.

2. Registros de métodos de solución de problemas

2.1 Comprobar si el codificador está instalado en el código

En el código exitoso, el codificador abierto con éxito se imprime como h264. El código que cometí un error al principio puede usar el siguiente recorrido para imprimir todos los codificadores, que contiene h264. Es decir, el código av_register_all() ha surtido efecto.

void QFFmpeg::showAll()
{
    
    
    //输出所有支持的解码器名称
    QStringList listCodeName;
    AVCodec *code = av_codec_next(NULL);
    while (code != NULL) {
    
    
        listCodeName << code->name;
        //if(::strcmp("h264",code->name)==0)
          qDebug() << "ffmpeg Codec "<< code->name <<", type "<<code->type;
        code = code->next;

    }

  //  qDebug() << __func__ << listCodeName;
}

2.2 Determinar el número de versión de ffmpeg

Intento compilar ffmpeg, antes que nada, necesito asegurarme de usar la versión ffmpeg, aunque la biblioteca dinámica dice 56, pero el código debe imprimir la versión exacta, y ffmpeg no tiene un número de versión general, generalmente determinado por la versión de libavutil, puede usar el siguiente código para imprimir

 //获取avutil数字版本号
    unsigned int version = avutil_version();
    //获取avutil三个子版本号
    int a = version / (int) pow(2, 16);
    int b = (int) (version - a * pow(2, 16)) / (int) pow(2, 8);
    int c = version % (int) pow(2, 8);
    //拼接avutil完整版本号

    qDebug()  << "MeidaPlayer ffmpeg/avutil version:("<<version<<")="<<a<<"."<<b<<"."<<c ;

Ejecutar este código imprime tres números 56. 51. 100

Para descargar la página web según el sitio web oficial, se puede determinar que es FFmpeg 4.3.5

inserte la descripción de la imagen aquí

Se necesita una gran cantidad de trabajo para descargar el código fuente y enviar el código. Quería volver a escribir el proyecto de importación qt.pri para la depuración, pero descubrí que se requieren configurar los parámetros de compilación y se requiere una serie de configuraciones. Alguien en el Internet proporcionó una plantilla, pero cada dll debe reescribirse manualmente, lo cual es muy doloroso.

2.3 Imprimir parámetros de compilación

Pero todavía hay descubrimientos útiles en el código fuente.Encontré la siguiente función, que obviamente se usa para imprimir los parámetros de configuración en tiempo de compilación

const char *avformat_configuration(void)
{
    
    
    return FFMPEG_CONFIGURATION;
}

Entonces imprimí los parámetros de compilación en los proyectos exitosos y fallidos respectivamente

Proyectos fallidos, mostrar claramente --disable-protocols

–prefix='c:/proyectos/repos/cerbero.git/1.18/build/dist/msvc_x86_64' --libdir='c:/proyectos/repos/cerbero.git/1.18/build/dist/msvc_x86_64/lib' --ar=x86_64-w64-mingw32-ar --as=x86_64-w64-mingw32-gcc --cc=x86_64-w64-mingw32-gcc --ld=x86_64-w64 -mingw32-gcc --nm=x86_64-w64-mingw32-nm --ranlib=x86_64-w64-mingw32-ranlib --strip=x86_64-w64-mingw32-strip --windres=x86_64-w64-mingw32-windres -- enable-static --enable-pic --enable-shared --disable-avdevice --disable-postproc --disable-swscale --disable-programs --disable-ffplay --disable-ffprobe --disable-ffmpeg -- deshabilitar codificador=flac --deshabilitar-protocolos --deshabilitar-dispositivos --deshabilitar-red --deshabilitar-hwaccels --deshabilitar-dxva2 --deshabilitar-vdpau --deshabilitar-filtros --habilitar-filtro=yadif --deshabilitar -doc --disable-d3d11va --disable-audiotoolbox --disable-videoprtoolbox --disable-vaapi --disable-crystalhd --disable-mediacodec --disable-mediafoundation --disable-nvenc --disable-mmal --disable -omx --disable-omx-rpi --disable-cuda--disable-cuvid --disable-libmfx --disable-libnpp --disable-iconv --disable-jni --disable-v4l2_m2m --disable-vulkan --disable-large-tests --disable-stripping --enable -optimizaciones --disable-nonfree --disable-version3 --enable-cross-compile --target-os=mingw32 --arch=x86_64 --cross-prefix=x86_64-w64-mingw32-

proyectos exitosos, los dos son marcadamente diferentes

configure --disable-static --enable-shared --enable-gpl --enable-version3 --disable-w32threads --enable-avisynth --enable-bzlib --enable-fontconfig --enable-frei0r --enable- gnutls --enable-iconv --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libfreetype --enable-libgme --enable-libgsm --enable-libilbc --enable- libmodplug --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libopus --enable-librtmp --enable-libschroedinger --enable-libsoxr --enable-libspeex --enable-libtheora --enable-libtwolame --enable-libvidstab --enable-libvo-aacenc --enable-libvo-amrwbenc --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp - -habilitar-libx264 --habilitar-libx265 --habilitar-libxavs --habilitar-libxvid --habilitar-lzma --habilitar-decklink --habilitar-zlib

Es decir, es probable que dos aplicaciones llamen a diferentes versiones de dll

2.4 Ver la dll llamante en funcionamiento

Gestión de tareas oficiales

La aplicación fallida usa avutils-56.dll. Esta versión desactiva toda la compatibilidad con protocolos durante la compilación, por lo que indicará que no se encontró el protocolo cuando se ejecute. La
Por favor agregue una descripción de la imagen
aplicación exitosa llama a la versión de avutils-54.dll. Esta versión habilita toda la compatibilidad con protocolos. Por lo tanto, no se informará ningún error.
Por favor agregue una descripción de la imagen

descubrimiento adicional

Porque uso tanto GStreamer como mi propio ffmpeg en mi proyecto, y GStreamer tiene una versión superior dentro de sí mismo, pero la versión que no puede funcionar normalmente entra en conflicto con el ffmpeg que traje

Por favor agregue una descripción de la imagen

La solución final es reemplazar los archivos de encabezado, las bibliotecas y las bibliotecas dinámicas de ffmpeg en GStreamer 1.0 con bibliotecas dinámicas de versión baja. Yo uso las bibliotecas internas directamente.

Coloque la versión correcta de ffmpeg dynamic en el directorio y elimine la biblioteca dinámica incorrecta, puede

Supongo que te gusta

Origin blog.csdn.net/qq_16504163/article/details/130500369
Recomendado
Clasificación