6
votes

Conversion efficace de l'avafame vers QImage

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 () est la bonne fonction à utiliser, mais je ne suis pas sûr des formats de pixels de source et de destination à spécifier.


1 commentaires

La conversion en qimage ne sera pas très efficace ... qtcentre.org/ Threads / 9935-QIMAGE-DATA-DATA-FFMPEG


6 Réponses :


5
votes

est venu avec le processus en deux étapes suivant qui convertit d'abord un AVFame décodé vers un autre avrada dans l'espace de courant RVB, puis sur qImage . Cela fonctionne et est raisonnablement rapide. XXX

Si vous trouvez une approche plus efficace, laissez-moi savoir dans les commentaires


1 commentaires

Vous pouvez simplement copier les données de votre pfraRergB dans un nouveau QImage (RGB888) et faire la conversion en interne



4
votes

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> xxx pré>

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 );
}


2 commentaires

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.



0
votes

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.

Puis après décodage, faites un memcpy

memcpy (img.scanline (0), pfrramergb-> Data [0], pfraRegB-> LIGNEZE [0] * PFORMERGB-> Hauteur ());


0 commentaires

1
votes

Aujourd'hui, j'ai testé passer directement le image à swscale et enfin ça marche, donc il ne fonctionne pas. besoin de copier en mémoire. Par exemple: xxx


1 commentaires

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)



4
votes

Une approche plus simple, je pense: xxx


2 commentaires

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.



0
votes

J'ai eu des problèmes avec les autres solutions proposées comme:

  • Ils n'ont pas mentionné libérer de l'avantalge, SWSContext ou les tampons alloués, qui ont causé des fuites de mémoire massives (j'ai eu des milliers de cadres à gérer). Ces problèmes ne pouvaient pas tous être résolus facilement, car Qimage repose sur les données sous-jacentes et ne le copie pas. Si vous libérez le tampon directement, les points QIMAGE pour libérer des données et des ruptures. Cela pourrait être résolu en utilisant la fonction de nettoyage de Qimage pour libérer le tampon une fois que l'image n'est plus nécessaire, mais avec d'autres problèmes, ce n'était pas bon de toute façon.
  • Dans certains cas, une des suggestions, de passer qimage.bits directement à SWS_SCALE, ne fonctionnerait pas comme QIMAGE est minimum 32 bits aligné. Par conséquent, pour certaines dimensions, il ne correspondrait pas à la largeur attendue de SWS_SCALE et de produire chaque ligne décalée un peu.
  • Un troisième problème est qu'ils ont utilisé des éléments d'avpicture obsolètes.

    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é.

    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


0 commentaires