ENCODAGE VIDÉO EN TEMPS RÉEL: TAVIWRITER

Nicolas___ Messages postés 992 Date d'inscription jeudi 2 novembre 2000 Statut Membre Dernière intervention 24 avril 2013 - 3 mai 2006 à 21:08
cs_Forman Messages postés 600 Date d'inscription samedi 8 juin 2002 Statut Membre Dernière intervention 6 avril 2010 - 24 mars 2010 à 12:38
Cette discussion concerne un article du site. Pour la consulter dans son contexte d'origine, cliquez sur le lien ci-dessous.

https://codes-sources.commentcamarche.net/source/37415-encodage-video-en-temps-reel-taviwriter

cs_Forman Messages postés 600 Date d'inscription samedi 8 juin 2002 Statut Membre Dernière intervention 6 avril 2010 1
24 mars 2010 à 12:38
Ricquet: il faut regarder les deux fichiers SimpleCompressorDialogFormUnit.pas et ExtendedCompressorDialogFormUnit.pas qui implémentent toutes deux une procédure similaire:

function ExecuteSimpleCompressorDialog(ABIH:TBitmapInfoHeader;AMode:Cardinal;var Quality,DataRate,FrameRate,MaxFramesBetweenKeys:Cardinal;var AutoKeyFrames:Boolean):HIC;

function ExecuteExtendedCompressorDialog(ABIH:TBitmapInfoHeader;AMode:Cardinal;var Quality,DataRate,FrameRate,MaxFramesBetweenKeys:Cardinal;var AutoKeyFrames:Boolean):HIC;

Dans ces deux cas, le résultat de la fonction correspond à la variable SelectedIC qui doit être renvoyée par l'événement custom. Il faut entre autres utiliser les API ICOpen, ICGetInfo, ICCompressQuery et ICInfo pour obtenir la liste des codecs installés ainsi que leurs propriétés, et renvoyer un handle dans SelectedIC . Pour cela, j'ai peur qu'il faille aller lire les doc MSDN correspondantes...

philgeorges: ça viendra quand j'aurai le temps. En ce moment ça n'est pas vraiment d'actualité, j'ai trop de boulot!

Il faudrait modifier procedure TAVIWriter.AddFrame: à la place de AVIStreamWrite(...) il faudrait envoyer les données sur un socket. Ca c'est facile. Ce qui est plus difficile, c'est de décompresser à l'autre bout du socket (entre autres, il faut que l'IC soit ouvert avec exactement les mêmes paramètres).
philgeorges Messages postés 4 Date d'inscription samedi 5 novembre 2005 Statut Membre Dernière intervention 24 mars 2010
24 mars 2010 à 12:04
J'attends avec une grande impatience la version avec flux TCP/IP !! Là, le composant sera au top de ce que l'on peut souhaiter !! merci encore !
cs_Ricquet Messages postés 20 Date d'inscription mardi 13 février 2007 Statut Membre Dernière intervention 30 novembre 2010
24 mars 2010 à 12:00
Ok : Donc la variable AviDataRate non gérable => Initialisation à zéro.
M'intéressant de prêt à ton composant que j'aimerais faire évoluer vers l'adjonction d'audio, j'ai plein de questions en devenirs...
pour le moment j'examine la propriété CompressorSelection qui permet de choisir un mode de sélection .
Si je choisis aviwriter1.CompressorSelection:= csmcustom alors :
il faut renseigner l'événement OnCustomSelectCompressor
qui contient n variables :
SelectedIC,Mode,Quality,DataRate,FrameRate,MaxFramesBetweenKeys
et AutoKeyFrames
comment s'y prend t-on ?
(Je n'ai que microsoft Video 1 qui fonctionne proprement)
cs_Forman Messages postés 600 Date d'inscription samedi 8 juin 2002 Statut Membre Dernière intervention 6 avril 2010 1
24 mars 2010 à 11:35
Au fait, correction par rapport à ce que j'avais écrit précédemment: la propriété AVIMaxFramesBetweenKeys est bel et bien supportée. C'est le nombre de frames entre chaque keyframes. C'est un peu technique, mais généralement, plus le fichier final a de keyframe, plus le seeking dans le fichier sera précis. S'il n'y a que deux keyframes (au début et au milieu par exemple), on ne pourra commencer la lecture du fichier qu'au début ou au milieu du film. Moi j'utilise en gros la valeur 20 (grosso modo, une keyframe toutes les secondes). Cette propriété n'est utilisée que si AVIAutoKeyFrames vaut true. Là encore, certains compresseurs ont leur propre gestion des keyframes (dans ce cas, utiliser AVIAutoKeyFrames:=False).
cs_Forman Messages postés 600 Date d'inscription samedi 8 juin 2002 Statut Membre Dernière intervention 6 avril 2010 1
24 mars 2010 à 09:59
En fait, AviDataRate correspond à une taille fichier moyenne des frames sur 1000 secondes (même unité que AVIFrameRate).

Ton calcul plus bas est faux, car il faut donc multiplier par 1000. En outre, ça n'aurait aucun sens car les frames ne seraient pas compressées!

Le paramètre AviDataRate n'est pas le seul à déterminer la taille du fichier final. Il y a aussi le paramètre de qualité, qui est supporté par la plupart des compresseurs (beaucoup plus souvent que le datarate).
cs_Ricquet Messages postés 20 Date d'inscription mardi 13 février 2007 Statut Membre Dernière intervention 30 novembre 2010
23 mars 2010 à 13:46
merci Forman pour cette réponse rapide et claire !
Donc pour résumer avec AviDataRate qui correspond à une taille fichier moyenne des frames sur 1000 ms (1 sec) c.à.d. 50 frames. (NbFramePerSec = 25)si je transmet du bitmap en 32 bits (4 octets) en 800*600 pixels, je dois faire : AviDataRate:800*600*50*4 96 000 000 octets
Est-ce juste ?
Tu me conseilles de mettre AviDataRate:= 0, dans ce cas la valeur par défaut du compresseur ne va t-elle pas planter la procédure si fichier trop grand (image full HD) ?
Merci de tes éclaircissements.
cs_Forman Messages postés 600 Date d'inscription samedi 8 juin 2002 Statut Membre Dernière intervention 6 avril 2010 1
23 mars 2010 à 11:36
L'unité de temps est définie à 1000 secondes. Donc pour un AVI à 24 images par secondes, il faut utiliser AviFrameRate=24000.

Idem pour AviDataRate, qui correspond à la taille moyenne (en octets) occupée par 1000 secondes d'AVI. Cette propriété n'a rien à voir avec le framerate, et peut être ou non supportée par le compresseur. Si c'est le cas, et si le nombre de frames est connu elle peut être utilisée pour fixer une taille approximative au fichier final à générer (je crois qu'il faut utiliser datarate := taillefinaledésirée * framerate / nombredeframes ). Ce paramètre n'est pas à modifier à la légère pour certains compresseurs. S'il est égal zéro, la valeur par défaut du compresseur est utilisée (recommandé).

La propriété AVIMaxFramesBetweenKeys n'est pas supportée car je ne sais pas comment transmettre le paramètre au compresseur. Mais elle peut pourrait être supportée en implémentant une boîte de dialogue spéciale (OnCustomSelectCompressor).

Dans la plupart des cas, il est préférable de faire appel à la boîte de dialogue du compresseur pour changer les paramètres plutôt que de le faire manuellement.
cs_Ricquet Messages postés 20 Date d'inscription mardi 13 février 2007 Statut Membre Dernière intervention 30 novembre 2010
23 mars 2010 à 09:49
Bonjour et bravo pour ce composant mais absence de tutoriel !
Merci de m'orienter : J'ai des plantages inexpliqués selon paramétrage AviWriter1 !
il y a un paramètre que je ne maitrise pas : AviDataRate (le pb est peut être là ?)
(si AviFrameRate trop grand, ou si les images sont trop grandes : format HD par exemple )
mettons que mon Avilength = 2000 ( 2000 frames en tout)
Si par exemple je veux 25 images / sec (je pose NbFramePerSec = 25)
Dans ce cas, Questions :AVIWriter1.AVIFrameRate :2000*25 50000 ou est ce l'échelle de temps : 1000*25 ?
Puisque AVIWriter1.AviDataRate est une variable, quel est le rapport avec NbFramePerSec ?
Enfin, AVIWriter1.AVIMaxFramesBetweenKeys:= NbFramePerSec est elle à modifier ?
merci
cs_Forman Messages postés 600 Date d'inscription samedi 8 juin 2002 Statut Membre Dernière intervention 6 avril 2010 1
5 déc. 2007 à 21:26
Bonjour,

désolé mais en ce moment je suis vraiment très pris par mon occupation professionnelle, je n'ai plus le temps de programmer autant qu'avant. Mais ça devrait se calmer un peu d'ici un ou deux mois... du moins je l'espère! Donc je n'ai pas trop pu avancer là-dessus pour l'instant.

Ceci dit le sujet m'intéresse toujours, quand j'aurai le temps je m'y mettrai sérieusement, et je donnerai des nouvelles ici.
philgeorges Messages postés 4 Date d'inscription samedi 5 novembre 2005 Statut Membre Dernière intervention 24 mars 2010
5 déc. 2007 à 15:24
Bonjour,

Avez vous avancé sur ce projet de transmission vidéo TCP/IP ? J'ai essayé pas mal de choses de mon côté, mais je n'ai pas vos compétences en Video. Si vous avez avancé dans ce sens, ce serait gentil de donner quelques infos, et peut être même quelques code sources....

Bon courage !
cs_Forman Messages postés 600 Date d'inscription samedi 8 juin 2002 Statut Membre Dernière intervention 6 avril 2010 1
6 sept. 2007 à 11:59
Merci pour le lien, j'ai regardé rapidement le code et il a l'air très bien écrit et très propre. Ceci dit, je pense vraiment que le plus dur n'est pas d'envoyer/recevoir les données, mais de décompresser le flux qui arrive (j'avais déjà un peu regardé sur MSDN, apparemment ça a l'air plus dur que pour compresser).
philgeorges Messages postés 4 Date d'inscription samedi 5 novembre 2005 Statut Membre Dernière intervention 24 mars 2010
6 sept. 2007 à 11:31
Oui, on peut envoyer le son séparément, voire même n'envoyer que le son si la bande passante est limitée. Je pense qu'avec les composants Indy, ce serait plus simple pour streamer. Il faut créer des "paquets" pour les envoyer et les recevoir sur TCP.

Sur ce lien :
http://leenover.homeip.net/isapi/pas2html.dll/pas2html?File=/delphi/Projects/VideoCoDecDemo/

Il y a deja du travail de fait, mais les routines ne sont pas fiables pour l'instant, mais cela peut déja donner une idée. Sur ce code source les classes de base manquantes pour le streaming peuvent je pense être reprises. J'ai fait des essais, mais sans vraiment y arriver.
cs_Forman Messages postés 600 Date d'inscription samedi 8 juin 2002 Statut Membre Dernière intervention 6 avril 2010 1
21 août 2007 à 17:02
Oui mais pour ça il faudrait d'abord écrire un composant TAVIReader qui permettrait de lire à la volée (c'est à dire sans passer par un fichier). Il faudrait aussi un peu modifier TAVIWriter pour qu'il n'écrive pas dans un fichier mais dans un flux TCP/IP (ça ne devrait pas être le plus dur, ceci dit).

L'idée est très intéressante, je vais y réfléchir (mais pas avant le mois prochain, je suis beaucoup trop occupé en ce moment). A priori, je pense qu'il faudrait faire une classe de base (par exemple TCustomAviWriter/TCustomAVIReader) avec des méthodes virtuelles pour l'écriture/lecture dans/depuis un flux, et on pourrait en faire descendre les classes TFileAviWriter (l'équivalent de mon composant actuel)/TFileAviReader, ainsi que TTCPAviWriter/TTCPAviReader.

Avec cette approche, on pourrait aussi donner la possibilité d'inclure du son, mais c'est vrai que ça pose tout de suite des problèmes de synchronisation. Ceci dit, pour un système de vidéoconférence, il pourrait être plus judicieux de l'envoyer séparément, voire même de façon "prioritaire" par rapport à la vidéo en cas de bande passante limitée (c'est plus grave que le son soit saccadé par rapport à l'image).
philgeorges Messages postés 4 Date d'inscription samedi 5 novembre 2005 Statut Membre Dernière intervention 24 mars 2010
21 août 2007 à 12:50
Il serait judicieux d'ajouter la possibilité de transmettre un flux par TCP/IP.

On peut en effet penser à un logiciel de video conférence !

Philippe
cs_Forman Messages postés 600 Date d'inscription samedi 8 juin 2002 Statut Membre Dernière intervention 6 avril 2010 1
12 juin 2007 à 18:02
Hi
No problem, that's what this site is about.

I'm looking forward to see if you find something, I'm also curious about these codecs.
cs_pea Messages postés 3 Date d'inscription dimanche 27 mai 2007 Statut Membre Dernière intervention 12 juin 2007
12 juin 2007 à 00:22
Hi Forman. Thank you for going to the effort of doing that.

I'll do some general searching on the MP4 codecs, as I am sure the problem is with them and not your code, because Indeo Video works ok for me too. I'll add a note here when I find the solution.

Thank you!
cs_Forman Messages postés 600 Date d'inscription samedi 8 juin 2002 Statut Membre Dernière intervention 6 avril 2010 1
12 juin 2007 à 00:16
Hmm...

I've read my code again (I wrote it quite a while ago) and it looks like I already took care of the ICGetInfo properties. That means, codecs which do not explicity support the data rate/quality settings wont have the 2 corresponding trackbars shown on the right of the window (when using cmsExtendedDialog).

Now that would mean they simply do not support the feature as they are supposed to... Maybe that could have something to do with the keyframes (try enabling auto keyframe in the dialog box). I tried with a popular codec named "Indeo Video" and it works (setting the quality to 10% will give a file 10 times smaller than 100%). Have you tried turning on the "double pass" feature (using XVid for instance)? Maybe that could help, too.

All I can say for sure is that I spent lot of time making my code 100% compliant with the specifications written in the MSDN (which is not easy since there are a lot of obvious mistakes in it). But, that doesnt mean codecs are also compliant... In fact, most codecs have specific proprietary features which cant be accessed through the standard VFW API's alone (you need to directly interface your code with the DLL implementing the codec to access these features).

Popular programs (like VirtualDub, etc...), when using these codecs are aware of these properties and try using it in this non-standard manner. Moreover, some codecs are designed to work with DirectDraw, and do not focus on being totally compatible with VFW anymore (even if they still support it "a little").

Maybe that could explain why you are experiencing this problem.
cs_pea Messages postés 3 Date d'inscription dimanche 27 mai 2007 Statut Membre Dernière intervention 12 juin 2007
11 juin 2007 à 23:30
Thanks for your help, forman. I will have a look at the ICGetInfo function.

Just a note: even changing the settings in the configuration dialog of the codec (Microsoft MP4 v1,2 and 3, and XVid) does not change the quality and datarate, and the file size of the final avi is exactly the same no matter what I do.
cs_Forman Messages postés 600 Date d'inscription samedi 8 juin 2002 Statut Membre Dernière intervention 6 avril 2010 1
11 juin 2007 à 13:19
Hi.

There can be several reasons why a given codec cant support DataRate or Quality settings:

-some codecs cannot intrinsequely support them. When you have a valid HIC to a system codec (that is, some kind of Windows handle) you can call the API ICGetInfo which returns the TICInfo for that codec. The Flag member of this sctructure indicate the capabilities of the codec: VIDCF_CRUNCH for the ability to set the data rate, and VIDCF_QUALITY for the ability to set quality factor. Also, using the codec in Real Time mode (fast compress) can prevent these settings to work properly.

-some codecs may need "multiple passes" (that's the case of XVID for instance) to be 100% efficient. You can use this feature through the configuration dialog box of the codec (no general support is provided for it anyway, it depends on the implementation of the codec itself). Using multiple passes can drasticaly improve the quality of the generated AVI file, and its size/datarate.

Hope this helps...
cs_pea Messages postés 3 Date d'inscription dimanche 27 mai 2007 Statut Membre Dernière intervention 12 juin 2007
11 juin 2007 à 11:15
Hello. I apologise for writing in english. I am from New Zealand and am afraid I don't know any French.

I am using this component in my program, and it is great! There is one problem I have encountered:

When using any Microsoft MP4 codec, or XVid, changing the AVIDataRate and the AVIQuality have no affect at all. If I use the cmsExtendedDialog and change the settings, it also does not have any effect, and the video is of poor quality.

Do you know why this might be?
porcher_laurent Messages postés 1 Date d'inscription vendredi 7 juillet 2006 Statut Membre Dernière intervention 21 février 2007
21 févr. 2007 à 15:18
Salut je suis laurent un nouveau sur delphi
j'ai telechargé Aviwriter et à partir de la demo,
j'ai realisé un petit programme sympa!
Enfin j'ai ajouté ,le son (dans un flux séparé)
,une horloge pour syncroniser les flux
,une saisie visuel de la zone à capturer
,une fenetre de visualisation de la capturer
,l'audio est capturer à partir de la carte son,(canal à régler et volume)
,Je multiplex les flux avec "Avidemux"
,Le son peut étre capturé en wav 11,22,44 kh et Mp3<- à bas framerate grosse configuration exigé !
,sur ma machine "atlon64 3400+ radeon X800 xl" j'encode en xvid en 720 576 à 25 i/s et audio 22 kh 16 bit st
Si cela interesse quelqu'un je peut envoyer mon code,je cherche à multiplexer mes fux.
Pour info le logiciel Media player classic Syncronise automatiquement l'audio et la vidéo
A plus Laurent.p
cs_Forman Messages postés 600 Date d'inscription samedi 8 juin 2002 Statut Membre Dernière intervention 6 avril 2010 1
14 mai 2006 à 13:02
Hehe...

Ceci dit, je me demandais sous quelle forme importer les données audio. Il y a plusieurs possibilités:
-ajoutter un son wave. Inconvénient: il faut que les 2 flux (audio+vidéo) aient la même durée.
-faire un système de streaming pour le son aussi, qui ajoutte les données depuis la carte son. Inconvénient: difficile de contrôler exactement quand l'enregistrement du son commence et quand il finit.
Filipe35 Messages postés 470 Date d'inscription vendredi 14 novembre 2003 Statut Membre Dernière intervention 23 octobre 2007 1
13 mai 2006 à 00:06
Je garde en favorie en attendant une version audio+video ;)
Nicolas___ Messages postés 992 Date d'inscription jeudi 2 novembre 2000 Statut Membre Dernière intervention 24 avril 2013 1
4 mai 2006 à 20:23
Salut, merci je teste !
cs_Forman Messages postés 600 Date d'inscription samedi 8 juin 2002 Statut Membre Dernière intervention 6 avril 2010 1
3 mai 2006 à 21:25
Salut,

Effectivement, le composant est de moi ;-)

Pour l'installer sans virer GlScene, tu peux aller dans le menu Component->Install package et décocher la case de GlScene dans la liste, ça va juste le désactiver sans le désinstaller. Il te suffira de le recocher (après avoir décoché ou désinstallé le mien) pour l'utiliser de nouveau.
Nicolas___ Messages postés 992 Date d'inscription jeudi 2 novembre 2000 Statut Membre Dernière intervention 24 avril 2013 1
3 mai 2006 à 21:08
Salut ,
ton code a l'air super mais ton composant Aviwriter( c'est le tien n'est ce pas ???) utilise un nom deja connu ( ce qui pose pas mal de merde pour l'installer).
Une fois le Taviwriter(un compo que j'avais sur mon pc) viré, je me dis :
" chouette je vais pouvoir installer le tiens " ... mais non !!!
Prq ?

ben Glscene : un compo aussi de ce nom existe et donc ca ne veut pas installer mon paquet...

( et j'ai pas envie de virer Glscene,Connais tu un autre moyen ???)

dommage ta source a l'air chouette ...

Ciao
Rejoignez-nous