web-dev-qa-db-fra.com

Comprendre PTS et DTS dans les images vidéo

J'ai eu des problèmes de fps lors du transcodage d'avi vers mp4 (x264). Finalement, le problème était dans PTS et DTS, donc les lignes 12-15 ont été ajoutées avant la fonction av_interleaved_write_frame:

1.  AVFormatContext* outContainer = NULL;
2.  avformat_alloc_output_context2(&outContainer, NULL, "mp4", "c:\\test.mp4";
3.  AVCodec *encoder = avcodec_find_encoder(AV_CODEC_ID_H264);
4.  AVStream *outStream = avformat_new_stream(outContainer, encoder);
5.  // outStream->codec initiation
6.  // ...
7.  avformat_write_header(outContainer, NULL);

8.  // reading and decoding packet
9.  // ...
10. avcodec_encode_video2(outStream->codec, &encodedPacket, decodedFrame, &got_frame)
11. 
12. if (encodedPacket.pts != AV_NOPTS_VALUE)
13.     encodedPacket.pts =  av_rescale_q(encodedPacket.pts, outStream->codec->time_base, outStream->time_base);
14. if (encodedPacket.dts != AV_NOPTS_VALUE)
15.     encodedPacket.dts = av_rescale_q(encodedPacket.dts, outStream->codec->time_base, outStream->time_base);
16. 
17. av_interleaved_write_frame(outContainer, &encodedPacket)

Après avoir lu de nombreux articles, je ne comprends toujours pas:

  1. outStream->codec->time_base = 1/25 et outStream->time_base = 1/12800. Le premier a été défini par moi, mais je ne peux pas comprendre pourquoi et qui a défini 12800? J'ai remarqué qu'avant la ligne (7) outStream->time_base = 1/90000 et juste après, il devient 1/12800, pourquoi? Lorsque je transcode d'avi en avi, ce qui signifie changer la ligne (2) en avformat_alloc_output_context2(&outContainer, NULL, "avi", "c:\\test.avi";, donc avant et après la ligne (7) outStream->time_base reste toujours 1/25 et pas comme dans le cas de mp4, pourquoi?
  2. Quelle est la différence entre la base de temps de outStream->codec et outStream?
  3. Pour calculer les pts av_rescale_q does: prend 2 time_base, multiplie leurs fractions en croix puis calcule les pts. Pourquoi fait-il cela de cette façon? Pendant que je déboguais, le encodedPacket.pts a une valeur incrémentielle de 1, alors pourquoi la changer si elle a de la valeur?
  4. Au début, la valeur dts est -2 et après chaque redimensionnement, elle a toujours un nombre négatif, mais malgré cela, la vidéo a été lue correctement! Cela ne devrait-il pas être positif?
23
theateist
  1. La base de temps est juste une nité de mesure. Différentes unités peuvent être utilisées pour représenter les mêmes temps (approximativement, si ce ne sont pas des multiples exacts). Dans certains cas, un format de conteneur nécessite une certaine base de temps et il sera défini par le multiplexeur. Dans d'autres cas, le conteneur ne nécessite une base de temps mais il a une valeur par défaut que vous devrez peut-être remplacer. Je ne suis pas sûr du 1/12800 en particulier, je sais que 1/600 est une valeur spéciale dans les spécifications mp4.

  2. Les deux bases de temps sont les unités de mesure du temps pour le codec et pour le conteneur. Si vous utilisez des fps constants, l'unité de mesure du codec est généralement définie sur l'intervalle entre chaque trame et la suivante (la durée d'affichage de chaque trame), de sorte que les temps de trame sont des entiers successifs. Cependant, il n'est pas nécessaire de le régler à 1/fps, tant que les temps pts sont corrects quelles que soient les unités utilisées.

  3. Ce que vous décrivez est simplement ce qu'il faudrait faire pour passer d'une unité à une autre. (c.-à-d. multiplier par l'ancienne unité, diviser par la nouvelle). Un temps t en unités de a/b Peut être converti en unités c/d Sous la forme t*(a*d)/(b*c).

  4. La séquence dts peut commencer à partir de n'importe quelle valeur, il n'y a pas de signification particulière pour dts 0. Au début de la lecture, la différence entre l'heure de l'horloge murale et les dts de départ est calculée, et tous les futurs dts sont convertis en horloge murale en utilisant cela. Un flux vidéo avec dts = -10, -9, -8, ... est parfaitement correct. La différence entre les dts successifs est ce qui est utilisé, les valeurs absolues n'ont pas d'importance.

37
Alex I