J'ai besoin d'extraire des cadres d'une vidéo dans mon application basée sur qt. Utilisation des bibliothèques FFMPEG, je suis capable d'aller chercher des images en tant qu'avifframmes que je dois convertir en qimage à utiliser dans d'autres parties de mon application. Cette conversion doit être efficace. Jusqu'à présent, il semble sws_scale () code> est la bonne fonction à utiliser, mais je ne suis pas sûr des formats de pixels de source et de destination à spécifier. P>
6 Réponses :
est venu avec le processus en deux étapes suivant qui convertit d'abord un Si vous trouvez une approche plus efficace, laissez-moi savoir dans les commentaires p> p> AVFame décodé code> vers un autre
avrada code> dans l'espace de courant RVB, puis sur
qImage code>. Cela fonctionne et est raisonnablement rapide.
Vous pouvez simplement copier les données de votre pfraRergB dans un nouveau QImage (RGB888) et faire la conversion en interne
Je sais, il est trop tard, mais peut-être que quelqu'un le trouvera utile. De ici j'ai eu l'idée de faire la même chose Conversion, qui a l'air un peu plus court.
J'ai donc créé qimage qui est réutilisé pour chaque cadre décodé: p> créé Framergb: P> if( 1 == framesFinished && nullptr != imgConvertCtx )
{
//conversion frame to frameRGB
sws_scale(imgConvertCtx, frame->data, frame->linesize, 0, codecContext->height, frameRGB->data, frameRGB->linesize);
//setting QImage from frameRGB
for( int y = 0; y < height; ++y )
memcpy( img.scanLine(y), frameRGB->data[0]+y * frameRGB->linesize[0], mWidth * 3 );
}
Qui a l'air mieux ... Je ne voudrais pas remplacer mawidth * 3 par Framergb-> Lignesize [0]
Cela semble beaucoup concis par rapport à ma réponse précédente. Marquage comme la meilleure réponse.
Je viens de découvrir que Scanline recherche juste à travers la mémoire tampon .. Tout ce dont vous avez besoin est d'utiliser av_pix_fmt_rgb32 pour l'avantarme et qimage :: Format_rgb32 pour le QImage. P>
Puis après décodage, faites un memcpy p>
memcpy (img.scanline (0), pfrramergb-> Data [0], pfraRegB-> LIGNEZE [0] * PFORMERGB-> Hauteur ()); Code> P>
Aujourd'hui, j'ai testé passer directement strud> le image
swscale code> et enfin ça marche, donc il ne fonctionne pas. besoin de copier en mémoire. Par exemple:
C'est génial, surtout si vous devez convertir en RVB de toute façon. A pris demi-temps pour un cadre FHD! (8ms -> 4ms)
Une approche plus simple, je pense:
Bienvenue à Stackoverflow! Bien que le code fourni dans votre réponse soit la solution à la question, c'est toujours une bonne idée d'inclure une brève explication de votre code.
Cela semble éviter de copier également, la performance est égale à la solution de @Mike_wei.
J'ai eu des problèmes avec les autres solutions proposées comme: p>
J'ai énuméré le problème dans une autre question Conversion d'une avantage à QImage avec la conversion du format pixel et à la fin a trouvé un Solution utilisant un tampon temporaire, qui pourrait être copiée sur le QImage, puis libérée en toute sécurité. P>
Voir ma réponse à une réponse entièrement travaillée, efficace et sans appels de fonction obsolète, mise en œuvre: https://stackoverflow.com / A / 68212609/7360943 p>
La conversion en qimage ne sera pas très efficace ... qtcentre.org/ Threads / 9935-QIMAGE-DATA-DATA-FFMPEG