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.

305 lines
9.4KB

  1. /*
  2. * YUV4MPEG muxer
  3. * Copyright (c) 2001, 2002, 2003 Fabrice Bellard
  4. *
  5. * This file is part of FFmpeg.
  6. *
  7. * FFmpeg is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU Lesser General Public
  9. * License as published by the Free Software Foundation; either
  10. * version 2.1 of the License, or (at your option) any later version.
  11. *
  12. * FFmpeg is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. * Lesser General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU Lesser General Public
  18. * License along with FFmpeg; if not, write to the Free Software
  19. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  20. */
  21. #include "libavutil/pixdesc.h"
  22. #include "avformat.h"
  23. #include "internal.h"
  24. #include "yuv4mpeg.h"
  25. #define Y4M_LINE_MAX 256
  26. static int yuv4_generate_header(AVFormatContext *s, char* buf)
  27. {
  28. AVStream *st;
  29. int width, height;
  30. int raten, rated, aspectn, aspectd, n;
  31. char inter;
  32. const char *colorspace = "";
  33. st = s->streams[0];
  34. width = st->codec->width;
  35. height = st->codec->height;
  36. // TODO: should be avg_frame_rate
  37. av_reduce(&raten, &rated, st->time_base.den,
  38. st->time_base.num, (1UL << 31) - 1);
  39. aspectn = st->sample_aspect_ratio.num;
  40. aspectd = st->sample_aspect_ratio.den;
  41. if (aspectn == 0 && aspectd == 1)
  42. aspectd = 0; // 0:0 means unknown
  43. switch (st->codec->field_order) {
  44. case AV_FIELD_TB:
  45. case AV_FIELD_TT: inter = 't'; break;
  46. case AV_FIELD_BT:
  47. case AV_FIELD_BB: inter = 'b'; break;
  48. default: inter = 'p'; break;
  49. }
  50. switch (st->codec->pix_fmt) {
  51. case AV_PIX_FMT_GRAY8:
  52. colorspace = " Cmono";
  53. break;
  54. case AV_PIX_FMT_GRAY16:
  55. colorspace = " Cmono16";
  56. break;
  57. case AV_PIX_FMT_YUV411P:
  58. colorspace = " C411 XYSCSS=411";
  59. break;
  60. case AV_PIX_FMT_YUV420P:
  61. switch (st->codec->chroma_sample_location) {
  62. case AVCHROMA_LOC_TOPLEFT: colorspace = " C420paldv XYSCSS=420PALDV"; break;
  63. case AVCHROMA_LOC_LEFT: colorspace = " C420mpeg2 XYSCSS=420MPEG2"; break;
  64. default: colorspace = " C420jpeg XYSCSS=420JPEG"; break;
  65. }
  66. break;
  67. case AV_PIX_FMT_YUV422P:
  68. colorspace = " C422 XYSCSS=422";
  69. break;
  70. case AV_PIX_FMT_YUV444P:
  71. colorspace = " C444 XYSCSS=444";
  72. break;
  73. case AV_PIX_FMT_YUV420P9:
  74. colorspace = " C420p9 XYSCSS=420P9";
  75. break;
  76. case AV_PIX_FMT_YUV422P9:
  77. colorspace = " C422p9 XYSCSS=422P9";
  78. break;
  79. case AV_PIX_FMT_YUV444P9:
  80. colorspace = " C444p9 XYSCSS=444P9";
  81. break;
  82. case AV_PIX_FMT_YUV420P10:
  83. colorspace = " C420p10 XYSCSS=420P10";
  84. break;
  85. case AV_PIX_FMT_YUV422P10:
  86. colorspace = " C422p10 XYSCSS=422P10";
  87. break;
  88. case AV_PIX_FMT_YUV444P10:
  89. colorspace = " C444p10 XYSCSS=444P10";
  90. break;
  91. case AV_PIX_FMT_YUV420P12:
  92. colorspace = " C420p12 XYSCSS=420P12";
  93. break;
  94. case AV_PIX_FMT_YUV422P12:
  95. colorspace = " C422p12 XYSCSS=422P12";
  96. break;
  97. case AV_PIX_FMT_YUV444P12:
  98. colorspace = " C444p12 XYSCSS=444P12";
  99. break;
  100. case AV_PIX_FMT_YUV420P14:
  101. colorspace = " C420p14 XYSCSS=420P14";
  102. break;
  103. case AV_PIX_FMT_YUV422P14:
  104. colorspace = " C422p14 XYSCSS=422P14";
  105. break;
  106. case AV_PIX_FMT_YUV444P14:
  107. colorspace = " C444p14 XYSCSS=444P14";
  108. break;
  109. case AV_PIX_FMT_YUV420P16:
  110. colorspace = " C420p16 XYSCSS=420P16";
  111. break;
  112. case AV_PIX_FMT_YUV422P16:
  113. colorspace = " C422p16 XYSCSS=422P16";
  114. break;
  115. case AV_PIX_FMT_YUV444P16:
  116. colorspace = " C444p16 XYSCSS=444P16";
  117. break;
  118. }
  119. /* construct stream header, if this is the first frame */
  120. n = snprintf(buf, Y4M_LINE_MAX, "%s W%d H%d F%d:%d I%c A%d:%d%s\n",
  121. Y4M_MAGIC, width, height, raten, rated, inter,
  122. aspectn, aspectd, colorspace);
  123. return n;
  124. }
  125. static int yuv4_write_packet(AVFormatContext *s, AVPacket *pkt)
  126. {
  127. AVStream *st = s->streams[pkt->stream_index];
  128. AVIOContext *pb = s->pb;
  129. AVFrame *frame;
  130. int* first_pkt = s->priv_data;
  131. int width, height, h_chroma_shift, v_chroma_shift;
  132. int i;
  133. char buf2[Y4M_LINE_MAX + 1];
  134. uint8_t *ptr, *ptr1, *ptr2;
  135. frame = (AVFrame *)pkt->data;
  136. /* for the first packet we have to output the header as well */
  137. if (*first_pkt) {
  138. *first_pkt = 0;
  139. if (yuv4_generate_header(s, buf2) < 0) {
  140. av_log(s, AV_LOG_ERROR,
  141. "Error. YUV4MPEG stream header write failed.\n");
  142. return AVERROR(EIO);
  143. } else {
  144. avio_write(pb, buf2, strlen(buf2));
  145. }
  146. }
  147. /* construct frame header */
  148. avio_printf(s->pb, "%s\n", Y4M_FRAME_MAGIC);
  149. width = st->codec->width;
  150. height = st->codec->height;
  151. ptr = frame->data[0];
  152. switch (st->codec->pix_fmt) {
  153. case AV_PIX_FMT_GRAY8:
  154. case AV_PIX_FMT_YUV411P:
  155. case AV_PIX_FMT_YUV420P:
  156. case AV_PIX_FMT_YUV422P:
  157. case AV_PIX_FMT_YUV444P:
  158. break;
  159. case AV_PIX_FMT_GRAY16:
  160. case AV_PIX_FMT_YUV420P9:
  161. case AV_PIX_FMT_YUV422P9:
  162. case AV_PIX_FMT_YUV444P9:
  163. case AV_PIX_FMT_YUV420P10:
  164. case AV_PIX_FMT_YUV422P10:
  165. case AV_PIX_FMT_YUV444P10:
  166. case AV_PIX_FMT_YUV420P12:
  167. case AV_PIX_FMT_YUV422P12:
  168. case AV_PIX_FMT_YUV444P12:
  169. case AV_PIX_FMT_YUV420P14:
  170. case AV_PIX_FMT_YUV422P14:
  171. case AV_PIX_FMT_YUV444P14:
  172. case AV_PIX_FMT_YUV420P16:
  173. case AV_PIX_FMT_YUV422P16:
  174. case AV_PIX_FMT_YUV444P16:
  175. width *= 2;
  176. break;
  177. default:
  178. av_log(s, AV_LOG_ERROR, "The pixel format '%s' is not supported.\n",
  179. av_get_pix_fmt_name(st->codec->pix_fmt));
  180. return AVERROR(EINVAL);
  181. }
  182. for (i = 0; i < height; i++) {
  183. avio_write(pb, ptr, width);
  184. ptr += frame->linesize[0];
  185. }
  186. if (st->codec->pix_fmt != AV_PIX_FMT_GRAY8 &&
  187. st->codec->pix_fmt != AV_PIX_FMT_GRAY16) {
  188. // Adjust for smaller Cb and Cr planes
  189. av_pix_fmt_get_chroma_sub_sample(st->codec->pix_fmt, &h_chroma_shift,
  190. &v_chroma_shift);
  191. // Shift right, rounding up
  192. width = AV_CEIL_RSHIFT(width, h_chroma_shift);
  193. height = AV_CEIL_RSHIFT(height, v_chroma_shift);
  194. ptr1 = frame->data[1];
  195. ptr2 = frame->data[2];
  196. for (i = 0; i < height; i++) { /* Cb */
  197. avio_write(pb, ptr1, width);
  198. ptr1 += frame->linesize[1];
  199. }
  200. for (i = 0; i < height; i++) { /* Cr */
  201. avio_write(pb, ptr2, width);
  202. ptr2 += frame->linesize[2];
  203. }
  204. }
  205. return 0;
  206. }
  207. static int yuv4_write_header(AVFormatContext *s)
  208. {
  209. int *first_pkt = s->priv_data;
  210. if (s->nb_streams != 1)
  211. return AVERROR(EIO);
  212. if (s->streams[0]->codec->codec_id != AV_CODEC_ID_WRAPPED_AVFRAME) {
  213. av_log(s, AV_LOG_ERROR, "ERROR: Codec not supported.\n");
  214. return AVERROR_INVALIDDATA;
  215. }
  216. switch (s->streams[0]->codec->pix_fmt) {
  217. case AV_PIX_FMT_YUV411P:
  218. av_log(s, AV_LOG_WARNING, "Warning: generating rarely used 4:1:1 YUV "
  219. "stream, some mjpegtools might not work.\n");
  220. break;
  221. case AV_PIX_FMT_GRAY8:
  222. case AV_PIX_FMT_GRAY16:
  223. case AV_PIX_FMT_YUV420P:
  224. case AV_PIX_FMT_YUV422P:
  225. case AV_PIX_FMT_YUV444P:
  226. break;
  227. case AV_PIX_FMT_YUV420P9:
  228. case AV_PIX_FMT_YUV422P9:
  229. case AV_PIX_FMT_YUV444P9:
  230. case AV_PIX_FMT_YUV420P10:
  231. case AV_PIX_FMT_YUV422P10:
  232. case AV_PIX_FMT_YUV444P10:
  233. case AV_PIX_FMT_YUV420P12:
  234. case AV_PIX_FMT_YUV422P12:
  235. case AV_PIX_FMT_YUV444P12:
  236. case AV_PIX_FMT_YUV420P14:
  237. case AV_PIX_FMT_YUV422P14:
  238. case AV_PIX_FMT_YUV444P14:
  239. case AV_PIX_FMT_YUV420P16:
  240. case AV_PIX_FMT_YUV422P16:
  241. case AV_PIX_FMT_YUV444P16:
  242. if (s->strict_std_compliance >= FF_COMPLIANCE_NORMAL) {
  243. av_log(s, AV_LOG_ERROR, "'%s' is not an official yuv4mpegpipe pixel format. "
  244. "Use '-strict -1' to encode to this pixel format.\n",
  245. av_get_pix_fmt_name(s->streams[0]->codec->pix_fmt));
  246. return AVERROR(EINVAL);
  247. }
  248. av_log(s, AV_LOG_WARNING, "Warning: generating non standard YUV stream. "
  249. "Mjpegtools will not work.\n");
  250. break;
  251. default:
  252. av_log(s, AV_LOG_ERROR, "ERROR: yuv4mpeg can only handle "
  253. "yuv444p, yuv422p, yuv420p, yuv411p and gray8 pixel formats. "
  254. "And using 'strict -1' also yuv444p9, yuv422p9, yuv420p9, "
  255. "yuv444p10, yuv422p10, yuv420p10, "
  256. "yuv444p12, yuv422p12, yuv420p12, "
  257. "yuv444p14, yuv422p14, yuv420p14, "
  258. "yuv444p16, yuv422p16, yuv420p16 "
  259. "and gray16 pixel formats. "
  260. "Use -pix_fmt to select one.\n");
  261. return AVERROR(EIO);
  262. }
  263. *first_pkt = 1;
  264. return 0;
  265. }
  266. AVOutputFormat ff_yuv4mpegpipe_muxer = {
  267. .name = "yuv4mpegpipe",
  268. .long_name = NULL_IF_CONFIG_SMALL("YUV4MPEG pipe"),
  269. .extensions = "y4m",
  270. .priv_data_size = sizeof(int),
  271. .audio_codec = AV_CODEC_ID_NONE,
  272. .video_codec = AV_CODEC_ID_WRAPPED_AVFRAME,
  273. .write_header = yuv4_write_header,
  274. .write_packet = yuv4_write_packet,
  275. };