Créer un film avec Quicktime... sans Cocoa !
Chacha
Membre
Salut,
Oui, je sais, ce n'est pas forcément le bon forum, mais ça vaut le coup d'essayer ! Je dois utiliser Quicktime sous Windows pour créer des séquences à partir d'images. Il n'y a aucun affichage, je n'ai donc pas de soucis d'interfaçage avec le système, par contre, je suis restreint à l'API procédurale et pas Cocoa. Du coup, point de QTMovie et addFrame...
Je cherche des pistes pour réaliser cela. La documentation est infâme, les tutoriaux sont généralement vieux (ne tiennent pas compte de Quicktime 7) et introduisent des GWorld dont je n'ai pas grand chose à faire hors écran. Bref, je nage.
Je sais vaguement ce qu'il faut faire :
EnterMovies()
NewMovieFromProperties()
NewMovieTrack ()
NewTrackMedia()
BeginMediaEdits();
AddMediaSample()
EndMediaEdits();
InsertMediaIntoTrack()
Sauf que 90% du temps, je ne comprends rien aux paramètres. Handle, Ptr, structures opaques, codec...
Si quelqu'un en connait un peu plus que moi, je suis preneur de toute aide.
Merci
+
Chacha
Oui, je sais, ce n'est pas forcément le bon forum, mais ça vaut le coup d'essayer ! Je dois utiliser Quicktime sous Windows pour créer des séquences à partir d'images. Il n'y a aucun affichage, je n'ai donc pas de soucis d'interfaçage avec le système, par contre, je suis restreint à l'API procédurale et pas Cocoa. Du coup, point de QTMovie et addFrame...
Je cherche des pistes pour réaliser cela. La documentation est infâme, les tutoriaux sont généralement vieux (ne tiennent pas compte de Quicktime 7) et introduisent des GWorld dont je n'ai pas grand chose à faire hors écran. Bref, je nage.
Je sais vaguement ce qu'il faut faire :
EnterMovies()
NewMovieFromProperties()
NewMovieTrack ()
NewTrackMedia()
BeginMediaEdits();
AddMediaSample()
EndMediaEdits();
InsertMediaIntoTrack()
Sauf que 90% du temps, je ne comprends rien aux paramètres. Handle, Ptr, structures opaques, codec...
Si quelqu'un en connait un peu plus que moi, je suis preneur de toute aide.
Merci
+
Chacha
Connectez-vous ou Inscrivez-vous pour répondre.
Réponses
Je précise que j'ai posté une demande similaire sur lists.apple.com/quicktime-api, mais pour l'instant ça ne m'est pas d'un grand secours.
Je vous livre quand même le code que j'ai pondu, mais qui ne marche pas. Si quelqu'un a une idée...
J'essaye de créer un film d'une frame, cette frame était un buffer RGB. Pour faire simple, je calcule ce buffer à partir d'une image (avec un peu de code Cocoa). Le fichier .mov est créé, il a une piste vidéo... mais il n'affiche rien !
+
Chacha
Après j'ai jamais utilisé donc je sais pas si ça te sera utile oiu te suffira mais bon, apparament les paramètres sont un peu décrits...
Bon, en fait j'ai réussi à m'en sortir... Apparemment, il fallait que j'appelle mon fichier .mp4 et pas .mov, sinon on ne pouvait pas voir le film. Je ne sais pas trop pourquoi. J'ai maintenant une structure de code qui marche (avec des BeginCompressionSequence et tout le tintouin)
Je fignole tout ça et je vous en fait part.
+
Chacha
Désolé de déterrer ce vieux sujet qui te rappelle peut-être de mauvais souvenirs...
Déjà : "merci"! Ton code m'a bien aidé alors que je m'étais empêtré dans les différents samples.
J'ai une question à laquelle tu aura peut-être du mal à répondre toi-même (ça commence à dater) :
Ton code produit une vidéo de 1h49m13s avec un IPS de 10.
Autant la notion d'IPS est claire pour moi : timeScale (600) / durationPerSample (60), autant je n'arrive pas à comprendre à quoi est dûe la durée de la vidéo.
Si j'utilise 200 images que je compresse à l'aide de SCCompressSequenceFrame avec un timeScale de 2997 et une durationPerSample de 100, j'obtiens bien un IPS (donc framerate) de 29,97 (parfait!) mais le mediaDuration sera alors de 100*200 (jusque là c'est relativement logique) et la durée de la vidéo sera de plus de 121h!
Pour résumer : je ne m'en sors pas avec ces paramètres (et peut-être en ai-je raté un autre) et ne comprend pas comment est définie la durée de la vidéo.
Toute explication me sera bénéfique. Merci d'avance.
EDIT : problème résolu en remplaçant
par
C'est assez perturbant mais le fait est que la movie, le track et le media n'ont pas forcément les mêmes timeScale, en cas de problème il faut donc bien vérifier les durations de chacun après les AddMediaSample et InsertMediaIntoTrack.
Je m'inspire très largement du code donné par Chacha sauf que je récupère directement les données de buffer et de bytesPerRow et que je fais un SCCompressSequenceFrame.
Pour chaque image je fais donc :
Pour le reste, c'est relativement identique.
Mon (nouveau) problème est que la vidéo obtenue est découpée ainsi :
- dans la moitié haute la vidéo est en double (à gauche et à droite) et violacée
- dans la moitié basse c'est blanc
ça donne :
|vidéo|vidéo|
| blanc |
Donc, déjà elle n'est pas à la bonne taille, en plus elle est dupliquée, et pour finir elle est violacée!
Ca me dépasse. Si par hasard vous aviez des pistes de recherche... :-*
EDIT : Ok, cette fois c'est mon pixelFormat qui ne collait pas car il était en 32bits alors qu'il me fallait du 16bits.
Résolu : la vidéo prend bien tout l'écran.
Problème : je ne trouve pas un pixelFormat 16bits qui soit accepté sous Mac et qui me rende correctement les couleurs.
EDIT2 : Je suis parti sur une valeur de 16 dans pixelFormat.
En fait, ce ne sont pas simplement les couleurs qui sont dégradées, l'image ressemble un peu à une chaà®ne cryptée. :P
Une piste?
Or, le buffer que je récupère depuis l'autre bout (lointain) de mon code est en YUV.
La solution est donc...roulement de tambour... :
remplacer
par
Eh oui, je me suis pris la tête toute la journée pour...2 lettres!
D'où d'ailleurs le "422" dans le nom du codec (pour 4 pixels Y, 2 pixels Cr et 2 pixels Cb)
Le tout représenté dans le flux en couches (d'abord les Y, puis les Cr puis les Cb), ce qui explique que tu avais un quart supérieur gauche avec ta vidéo (tous les pixels de la couche Cr, 2x moins nombreux que les Y), un quart supérieur droit avec une vidéo très ressemblante (tous les pixels de la couche Cb, idem), et la moitié inférieure avec que les pixels Y (luminosité), et que les deux quarts supérieurs soient volacés (composantes Cr et Cb sans l'influence du Y)
CQFD.
T'as vu, je me met au dev' Mac, c'est fou hein! :P Comme quoi, tout peut arriver!
En fait pour mon premier problème (celui avec mon fantastique schéma de découpe) je pense que ça venait aussi du fait que le depth ne collait pas. Du coup il devait remplir les lignes...
J'étais au point sur la théorie mais je n'ai pas tilté car dans mes réflexions je n'avais pas constaté que mon lointain décodeur me rendait du YCbCr et pas du RGB. C'est le problème quand le code se complexifie, on a tendance à se focaliser sur la petite portion de code qu'on a sous les yeux.
En tout cas le problème est résolu, je comprend bien ce que je fais et ce qui se passe, c'est cool.
Au fait, il n'y a pas de moyens plus à jour pour faire de la compression vidéo que les méthodes SC et l'utilisation des Gworld?
C'est peu documenté et souvent marqué comme déprécié!
Chacha ne pouvait pas l'utiliser parce qu'il avait besoin d'un code portable sous Windows.
J'en profite pour poser une petite question (que j'espère pas trop bête) :
Actuellement je manipule des objets QuickDraw (tels que les GWorld) pour utiliser les librairies QuickTime et faire de la compression vidéo.
Or, si j'ai bien compris QuickDraw n'est pas compatible 64bits, ce qui promet à mon code une évolutivité (il semblerait que ce mot n'existe pas...) restreinte. Il me semble avoir compris que QuickDraw et Quartz étaient très proches et que le second était censé remplacer le premier. J'ai également en tête que QuickDraw utilise Carbon alors que Quartz utilise Cocoa (ou l'inverse..?).
Puisque Quartz est compatible 64bits, y a-t-il moyen de l'utiliser avec les librairies QuickTime de compression vidéo? ???
Je ne suis pas convaincu que ma question soit très claire (ni que je ne raconte pas trop de bêtises ) car tout ça est "un peu" confus en moi.
Au contraire, ils sont très éloignés. Quartz (Core Graphics) n'est pas une évolution, c'est une réécriture complète. Ses interfaces de programmation sont modernes et son rendu meilleur que celui de QuickDraw.
Carbon est une suite d'API en langage C pour programmer l'interface utilisateur. L'AppKit (l'une des moitiés de Cocoa) repose donc en partie dessus, par exemple pour afficher les fenêtres ou récupérer les évènements.
Apple a toujours eu une communication ambiguë à propos de Carbon, avec son histoire de Carbonisation des appli Classic. En fait, certaines API de Classic ont été intégrées à Carbon pour permettre d'utiliser les applications Classic en n'en réécrivant que certaines portions. Il me semble qu'il suffisait la plupart du temps de modifier la boucle d'évènements et d'utiliser les nouveaux dialogues d'ouvertures des fichiers. Certaines applis, qui utilisaient par exemple le Sound Manager ont du être réécrites plus en profondeur.
Depuis 10.3, je crois, Apple a déprécié QuickDraw. Les développeurs ont alors adaptés leur programmes pour utiliser Core Graphics à la place (donc, QuickDraw n'a jamais existé sur une machine 64 bits).
Depuis toujours, AppKit utilise Core Graphics pour dessiner.
Ce n'est pas la question puisque ce n'est pas le moteur graphique qui fait la compression ou la décrompression. Ton problème est que tu ne comprends pas ce qu'est un GWorld: en fait c'est une destination pour le dessin. Le GWorld peut représenter une fenêtre Mac OS X ou Classic ou encore Windows ou même un tampon mémoire. C'est une abstraction. En général, sous Mac OS X, il s'agit d'une fenêtre au sens où le Window Manager l'entend.
Ce que je voulais dire, c'est qu'ils ne sont aucunement complémentaires mais visent à rendre les mêmes services (mais en mieux pour Quartz). C'est bien ça?
Je te remercie pour tous tes éclaircissements. Ce sont des questions que je n'ai jamais réellement eu à me poser auparavant pour le dev' iPhone, je nage donc pas mal.
Pour en revenir à ma compression, je tente à présent d'ajouter une track audio à ma vidéo mais en vain.
J'ai d'abord tenté quelque chose de très proche de ce qui est fait pour la vidéo mais je ne vois pas comment utiliser le AddMediaSample avec mes données (NSData*).
J'ai donc crée une Track et un Media :
mais lors du AddMediaSample je me prend une erreur de paramètres et je ne sais quoi passer comme Handle et comme description.
Ensuite j'aurais bien vu :
Devant tous ces échecs je me suis demandé si c'était la bonne façon de faire, et me suis tourné vers CoreAudio mais c'est un vrai labyrinthe je trouve.
Dois-je insister vers CoreAudio ou y a-t-il une solution toute simple à mon problème de AddMediaSample?
EDIT : Je vais tenter quelque chose comme ça :
http://www.mailinglistarchive.com/quicktime-api@lists.apple.com/msg03504.html
EDIT2 : Ouf! Succeeded!
J'ai bien compris le rôle des GWorld, mon problème est ailleurs. En fait, je ne sais créer un Gworld qu'avec QuickDraw (QTNewGWorldFromPtr) pour ensuite faire la compression en utilisant le QT SDK (compatible 32 bits uniquement).
J'aimerais que mon application soit 64bits, je sais qu'il y a moyen de créer des buffers offscreen avec Quartz, mais je ne vois pas comment faire de la compression au niveau buffer avec QTKit...? ???
Il va falloir poser ta question sur la mailing list d'Apple dédiée à QuickTime.
Je suis d'accord avec toi mais c'est déjà fait depuis un moment et ça ne donne rien.
Tant pis...je n'insiste pas plus ici.
Mais c'est vrai que:
1/ Proposer des mailing lists plutôt que des forums en 2010, il faut le faire.
2/ Les ingés d'Apple répondent "bénévolement", pour ainsi dire jamais.