You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

165 lines
4.1KB

  1. /*
  2. * YUV4MPEG format
  3. * Copyright (c) 2001, 2002, 2003 Fabrice Bellard.
  4. *
  5. * This library is free software; you can redistribute it and/or
  6. * modify it under the terms of the GNU Lesser General Public
  7. * License as published by the Free Software Foundation; either
  8. * version 2 of the License, or (at your option) any later version.
  9. *
  10. * This library is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  13. * Lesser General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU Lesser General Public
  16. * License along with this library; if not, write to the Free Software
  17. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  18. */
  19. #include "avformat.h"
  20. #define Y4M_MAGIC "YUV4MPEG2"
  21. #define Y4M_FRAME_MAGIC "FRAME"
  22. #define Y4M_LINE_MAX 256
  23. static int yuv4_write_header(AVFormatContext *s)
  24. {
  25. AVStream *st;
  26. int width, height;
  27. int raten, rated, aspectn, aspectd, fps, fps1, n;
  28. char buf[Y4M_LINE_MAX+1];
  29. if (s->nb_streams != 1)
  30. return -EIO;
  31. st = s->streams[0];
  32. width = st->codec.width;
  33. height = st->codec.height;
  34. fps = st->codec.frame_rate;
  35. fps1 = (((float)fps / FRAME_RATE_BASE) * 1000);
  36. /* Sorry about this messy code, but mpeg2enc is very picky about
  37. * the framerates it accepts. */
  38. switch(fps1) {
  39. case 23976:
  40. raten = 24000; /* turn the framerate into a ratio */
  41. rated = 1001;
  42. break;
  43. case 29970:
  44. raten = 30000;
  45. rated = 1001;
  46. break;
  47. case 25000:
  48. raten = 25;
  49. rated = 1;
  50. break;
  51. case 30000:
  52. raten = 30;
  53. rated = 1;
  54. break;
  55. case 24000:
  56. raten = 24;
  57. rated = 1;
  58. break;
  59. case 50000:
  60. raten = 50;
  61. rated = 1;
  62. break;
  63. case 59940:
  64. raten = 60000;
  65. rated = 1001;
  66. break;
  67. case 60000:
  68. raten = 60;
  69. rated = 1;
  70. break;
  71. default:
  72. raten = fps1; /* this setting should work, but often doesn't */
  73. rated = 1000;
  74. break;
  75. }
  76. aspectn = 1;
  77. aspectd = 1; /* ffmpeg always uses a 1:1 aspect ratio */
  78. /* construct stream header, if this is the first frame */
  79. n = snprintf(buf, sizeof(buf), "%s W%d H%d F%d:%d I%s A%d:%d\n",
  80. Y4M_MAGIC,
  81. width,
  82. height,
  83. raten, rated,
  84. "p", /* ffmpeg seems to only output progressive video */
  85. aspectn, aspectd);
  86. if (n < 0) {
  87. fprintf(stderr, "Error. YUV4MPEG stream header write failed.\n");
  88. return -EIO;
  89. } else {
  90. put_buffer(&s->pb, buf, strlen(buf));
  91. }
  92. return 0;
  93. }
  94. static int yuv4_write_packet(AVFormatContext *s, int stream_index,
  95. UINT8 *buf, int size, int force_pts)
  96. {
  97. AVStream *st = s->streams[stream_index];
  98. ByteIOContext *pb = &s->pb;
  99. AVPicture *picture;
  100. int width, height;
  101. int i, m;
  102. char buf1[20];
  103. UINT8 *ptr, *ptr1, *ptr2;
  104. picture = (AVPicture *)buf;
  105. /* construct frame header */
  106. m = snprintf(buf1, sizeof(buf1), "%s \n", Y4M_FRAME_MAGIC);
  107. put_buffer(pb, buf1, strlen(buf1));
  108. width = st->codec.width;
  109. height = st->codec.height;
  110. ptr = picture->data[0];
  111. for(i=0;i<height;i++) {
  112. put_buffer(pb, ptr, width);
  113. ptr += picture->linesize[0];
  114. }
  115. height >>= 1;
  116. width >>= 1;
  117. ptr1 = picture->data[1];
  118. ptr2 = picture->data[2];
  119. for(i=0;i<height;i++) { /* Cb */
  120. put_buffer(pb, ptr1, width);
  121. ptr1 += picture->linesize[1];
  122. }
  123. for(i=0;i<height;i++) { /* Cr */
  124. put_buffer(pb, ptr2, width);
  125. ptr2 += picture->linesize[2];
  126. }
  127. put_flush_packet(pb);
  128. return 0;
  129. }
  130. static int yuv4_write_trailer(AVFormatContext *s)
  131. {
  132. return 0;
  133. }
  134. AVOutputFormat yuv4mpegpipe_oformat = {
  135. "yuv4mpegpipe",
  136. "YUV4MPEG pipe format",
  137. "",
  138. "yuv4mpeg",
  139. 0,
  140. CODEC_ID_NONE,
  141. CODEC_ID_RAWVIDEO,
  142. yuv4_write_header,
  143. yuv4_write_packet,
  144. yuv4_write_trailer,
  145. .flags = AVFMT_RAWPICTURE,
  146. };