Directorio de artículos
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
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
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.
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
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