c++ - tipos - que es una libreria en programacion y para que sirve
C++: ¿Cuál es la biblioteca más fácil de abrir archivo de video (7)
Actualmente estos son los marcos de video más populares disponibles en las plataformas Win32:
Video para Windows: el viejo marco de Windows viene de la era de Win95 pero aún se usa ampliamente porque es muy fácil de usar. Desafortunadamente solo admite archivos AVI para los que se ha instalado el códec VFW adecuado.
DirectShow: marco WinXP estándar, básicamente puede cargar todos los formatos que puede jugar con Windows Media Player. Bastante difícil de usar
Ffmpeg : más precisamente libavcodec y libavformat que viene con la utilidad multimedia de código abierto Ffmpeg. Es extremadamente potente y puede leer muchos formatos (casi todo lo que puede jugar con VLC ), incluso si no tiene el códec instalado en el sistema. Es bastante complicado de usar, pero siempre puedes inspirarte con el código de ffplay que viene con él o con otras implementaciones en software de código abierto. De todos modos, creo que es mucho más fácil de usar que DS (y mucho más rápido). Tiene que estar configurado por MinGW en Windows, pero todos los pasos se explican muy bien aquí (en este momento el enlace está inactivo, espero que no esté muerto).
QuickTime : el marco de trabajo de Apple no es la mejor solución para la plataforma de Windows, ya que necesita la aplicación QuickTime para ser instalada y también el códec QuickTime adecuado para cada formato; no es compatible con muchos formatos, pero es bastante común en el campo profesional (por lo que algunos códecs son en realidad solo para QuickTime). No debería ser demasiado difícil de implementar.
Gstreamer : último marco de código abierto. No sé mucho al respecto, supongo que abarca algunos de los otros sistemas (pero no estoy seguro).
Todos estos marcos se han implementado como back-end en OpenCv Highgui, excepto para DirectShow. El marco predeterminado para Win32 OpenCV es usar VFW (y por lo tanto solo puede abrir algunos archivos AVI), si quieres usar los demás, debes descargar el CVS en lugar de la versión oficial y aún así piratear el código y de todos modos no demasiado completo, por ejemplo, el backend FFMPEG no permite buscar en la transmisión. Si desea utilizar QuickTime con OpenCV, esto puede ayudarlo.
Me gustaría abrir un pequeño archivo de video y mapear cada cuadro en la memoria (para aplicar algún filtro personalizado). No quiero manejar el códec de video, prefiero dejar que la biblioteca maneje eso para mí.
Intenté usar Direct Show con el filtro SampleGrabber (usando este ejemplo http://msdn.microsoft.com/en-us/library/ms787867(VS.85).aspx ), pero solo logré tomar algunos fotogramas (¡no en todos los cuadros!). Soy bastante nuevo en la programación de software de video, tal vez no estoy usando la mejor biblioteca, o lo estoy haciendo mal.
He pegado una parte de mi código (principalmente un copiar / pegar modificado del ejemplo msdn), desafortunadamente no alcanza los 25 primeros fotogramas como se esperaba ...
[...]
hr = pGrabber->SetOneShot(TRUE);
hr = pGrabber->SetBufferSamples(TRUE);
pControl->Run(); // Run the graph.
pEvent->WaitForCompletion(INFINITE, &evCode); // Wait till it''s done.
// Find the required buffer size.
long cbBuffer = 0;
hr = pGrabber->GetCurrentBuffer(&cbBuffer, NULL);
for( int i = 0 ; i < 25 ; ++i )
{
pControl->Run(); // Run the graph.
pEvent->WaitForCompletion(INFINITE, &evCode); // Wait till it''s done.
char *pBuffer = new char[cbBuffer];
hr = pGrabber->GetCurrentBuffer(&cbBuffer, (long*)pBuffer);
AM_MEDIA_TYPE mt;
hr = pGrabber->GetConnectedMediaType(&mt);
VIDEOINFOHEADER *pVih;
pVih = (VIDEOINFOHEADER*)mt.pbFormat;
[...]
}
[...]
¿Hay alguien con experiencia en software de video que pueda aconsejarme sobre el código u otra biblioteca más simple?
Gracias
Editar: los enlaces Msdn parecen no funcionar ( ver el error )
El uso del modelo "Devolución de llamada" de SampleGrabber puede brindarle mejores resultados. Vea el ejemplo en Samples / C ++ / DirectShow / Editing / GrabBitmaps.
También hay mucha información en Samples / C ++ / DirectShow / Filters / Grabber2 / grabber_text.txt y readme.txt.
He usado OpenCV para cargar archivos de video y procesarlos. También es útil para muchos tipos de procesamiento de video, incluidos los útiles para la visión por computadora.
OpenCV es la mejor solución si el video en su caso solo necesita generar una secuencia de imágenes. Si estás dispuesto a hacer un procesamiento de video real, por lo que ViDeo es igual a "Visual Audio", necesitas seguir el ritmo de los que ofrece "martjno". Las nuevas soluciones de Windows también para Win7 incluyen 3 nuevas posibilidades, además:
- Windows Media Foundation: sucesor de DirectShow; interfaz limpiada
- Windows Media Encoder 9: no solo incluye el programa, también envía bibliotecas para codificar
- Expresión de Windows 4: Sucesor de 2.
Los últimos 2 son soluciones solo comerciales, pero el primero es gratis. Para codificar WMF, debe instalar el SDK de Windows.
Sé que es muy tentador en C ++ obtener un desglose adecuado de los archivos de video y simplemente hágalo usted mismo. Pero a pesar de que la información está disponible, es un proceso tan largo construir clases para entregar cada formato de archivo, y hacerlo fácilmente modificable para tener en cuenta los futuros cambios de estructura, que francamente no vale la pena el esfuerzo.
En cambio, recomiendo ffmpeg. Recibió una mención anterior, pero dice que es difícil, no es difícil. Hay muchas más opciones de las que la mayoría de las personas necesitarían, lo que hace que parezca más difícil de lo que es. Para la mayoría de las operaciones, puedes dejar que ffmpeg lo resuelva solo.
Por ejemplo, una conversión de archivo ffmpeg -i inputFile.mp4 outputFile.avi
Decida desde el principio que las operaciones de ffmpeg se ejecutarán en un hilo, o más precisamente, en una biblioteca de hilos. Pero haz que tu propia clase de subprocesos lo ajuste para que puedas tener tus propios EventAgs y los métodos para verificar el hilo hayan finalizado. Algo como :-
ThreadLibManager()
{
List<MyThreads> listOfActiveThreads;
public AddThread(MyThreads);
}
Your thread class is something like:-
class MyThread
{
public Thread threadForThisInstance { get; set; }
public MyFFMpegTools mpegTools { get; set; }
}
MyFFMpegTools performs many different video operations, so you want your own event
args to tell your parent code precisely what type of operation has just raised and
event.
enum MyFmpegArgs
{
public int thisThreadID { get; set; } //Set as a new MyThread is added to the List<>
public MyFfmpegType operationType {get; set;}
//output paths etc that the parent handler will need to find output files
}
enum MyFfmpegType
{
FF_CONVERTFILE = 0, FF_CREATETHUMBNAIL, FF_EXTRACTFRAMES ...
}
Aquí hay un pequeño fragmento de mi clase de herramienta ffmpeg, esta parte recopila información sobre un video. Puse FFmpeg en una ubicación particular, y al inicio del software que se ejecuta, se asegura de que esté allí. Para esta versión la he movido al escritorio, estoy bastante seguro de haber escrito la ruta correcta para ti (realmente odio el sistema de carpetas especiales de MS, así que lo ignoro tanto como puedo).
De todos modos, es un ejemplo de usar ffmpeg sin ventanas.
public string GetVideoInfo(FileInfo fi)
{
outputBuilder.Clear();
string strCommand = string.Concat(" -i /"", fi.FullName, "/"");
string ffPath =
System.Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + "//ffmpeg.exe";
string oStr = "";
try
{
Process build = new Process();
//build.StartInfo.WorkingDirectory = @"dir";
build.StartInfo.Arguments = strCommand;
build.StartInfo.FileName = ffPath;
build.StartInfo.UseShellExecute = false;
build.StartInfo.RedirectStandardOutput = true;
build.StartInfo.RedirectStandardError = true;
build.StartInfo.CreateNoWindow = true;
build.ErrorDataReceived += build_ErrorDataReceived;
build.OutputDataReceived += build_ErrorDataReceived;
build.EnableRaisingEvents = true;
build.Start();
build.BeginOutputReadLine();
build.BeginErrorReadLine();
build.WaitForExit();
string findThis = "start";
int offset = 0;
foreach (string str in outputBuilder)
{
if (str.Contains("Duration"))
{
offset = str.IndexOf(findThis);
oStr = str.Substring(0, offset);
}
}
}
catch
{
oStr = "Error collecting file information";
}
return oStr;
}
private void build_ErrorDataReceived(object sender, DataReceivedEventArgs e)
{
string strMessage = e.Data;
if (outputBuilder != null && strMessage != null)
{
outputBuilder.Add(string.Concat(strMessage, "/n"));
}
}
Si se trata de archivos AVI, leería los datos del archivo AVI y extraería los marcos. Ahora usa el administrador de compresión de video para descomprimirlo.
El formato de archivo AVI es muy simple, consulte: http://msdn.microsoft.com/en-us/library/dd318187(VS.85).aspx (y use google).
Una vez que tenga el archivo abierto, simplemente extraiga cada cuadro y páselo a ICDecompress () para descomprimirlo.
Parece mucho trabajo, pero es la forma más confiable.
Si eso es demasiado trabajo, o si quieres más que archivos AVI, utiliza ffmpeg.