3 * Copyright (c) 2017 Paul B Mahol
5 * This file is part of FFmpeg.
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.
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.
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
25 #include "libavutil/cpu.h"
26 #include "libavutil/mem.h"
27 #include "libavutil/opt.h"
28 #include "libavutil/pixdesc.h"
29 #include "libavutil/qsort.h"
32 #include "bytestream.h"
33 #include "codec_internal.h"
36 #include "lossless_videoencdsp.h"
38 #define MAGICYUV_EXTRADATA_SIZE 32
40 typedef enum Prediction
{
46 typedef struct HuffEntry
{
51 typedef struct PTable
{
52 int value
; ///< input value
53 int64_t prob
; ///< number of occurences of this value in input
56 typedef struct Slice
{
64 typedef struct MagicYUVContext
{
74 unsigned bitslice_size
;
75 uint8_t *decorrelate_buf
[2];
78 LLVidEncDSPContext llvidencdsp
;
79 void (*predict
)(struct MagicYUVContext
*s
, const uint8_t *src
, uint8_t *dst
,
80 ptrdiff_t stride
, int width
, int height
);
83 static void left_predict(MagicYUVContext
*s
,
84 const uint8_t *src
, uint8_t *dst
, ptrdiff_t stride
,
85 int width
, int height
)
90 for (i
= 0; i
< width
; i
++) {
91 dst
[i
] = src
[i
] - prev
;
96 for (j
= 1; j
< height
; j
++) {
98 for (i
= 0; i
< width
; i
++) {
99 dst
[i
] = src
[i
] - prev
;
107 static void gradient_predict(MagicYUVContext
*s
,
108 const uint8_t *src
, uint8_t *dst
, ptrdiff_t stride
,
109 int width
, int height
)
111 int left
= 0, top
, lefttop
;
114 for (i
= 0; i
< width
; i
++) {
115 dst
[i
] = src
[i
] - left
;
120 for (j
= 1; j
< height
; j
++) {
124 for (i
= 1; i
< width
; i
++) {
125 top
= src
[i
- stride
];
126 lefttop
= src
[i
- (stride
+ 1)];
128 dst
[i
] = (src
[i
] - top
) - left
+ lefttop
;
135 static void median_predict(MagicYUVContext
*s
,
136 const uint8_t *src
, uint8_t *dst
, ptrdiff_t stride
,
137 int width
, int height
)
139 int left
= 0, lefttop
;
142 for (i
= 0; i
< width
; i
++) {
143 dst
[i
] = src
[i
] - left
;
148 for (j
= 1; j
< height
; j
++) {
149 left
= lefttop
= src
[-stride
];
150 s
->llvidencdsp
.sub_median_pred(dst
, src
- stride
, src
, width
, &left
, &lefttop
);
156 static av_cold
int magy_encode_init(AVCodecContext
*avctx
)
158 MagicYUVContext
*s
= avctx
->priv_data
;
161 switch (avctx
->pix_fmt
) {
162 case AV_PIX_FMT_GBRP
:
163 avctx
->codec_tag
= MKTAG('M', '8', 'R', 'G');
167 case AV_PIX_FMT_GBRAP
:
168 avctx
->codec_tag
= MKTAG('M', '8', 'R', 'A');
172 case AV_PIX_FMT_YUV420P
:
173 avctx
->codec_tag
= MKTAG('M', '8', 'Y', '0');
180 case AV_PIX_FMT_YUV422P
:
181 avctx
->codec_tag
= MKTAG('M', '8', 'Y', '2');
186 case AV_PIX_FMT_YUV444P
:
187 avctx
->codec_tag
= MKTAG('M', '8', 'Y', '4');
190 case AV_PIX_FMT_YUVA444P
:
191 avctx
->codec_tag
= MKTAG('M', '8', 'Y', 'A');
194 case AV_PIX_FMT_GRAY8
:
195 avctx
->codec_tag
= MKTAG('M', '8', 'G', '0');
200 ff_llvidencdsp_init(&s
->llvidencdsp
);
202 s
->planes
= av_pix_fmt_count_planes(avctx
->pix_fmt
);
204 s
->nb_slices
= (avctx
->slices
<= 0) ? av_cpu_count() : avctx
->slices
;
205 s
->nb_slices
= FFMIN(s
->nb_slices
, avctx
->height
>> s
->vshift
[1]);
206 s
->nb_slices
= FFMAX(1, s
->nb_slices
);
207 s
->slice_height
= FFALIGN((avctx
->height
+ s
->nb_slices
- 1) / s
->nb_slices
, 1 << s
->vshift
[1]);
208 s
->nb_slices
= (avctx
->height
+ s
->slice_height
- 1) / s
->slice_height
;
209 s
->slices
= av_calloc(s
->nb_slices
* s
->planes
, sizeof(*s
->slices
));
211 return AVERROR(ENOMEM
);
214 size_t max_align
= av_cpu_max_align();
215 size_t aligned_width
= FFALIGN(avctx
->width
, max_align
);
216 s
->decorrelate_buf
[0] = av_calloc(2U * (s
->nb_slices
* s
->slice_height
),
218 if (!s
->decorrelate_buf
[0])
219 return AVERROR(ENOMEM
);
220 s
->decorrelate_buf
[1] = s
->decorrelate_buf
[0] + (s
->nb_slices
* s
->slice_height
) * aligned_width
;
223 s
->bitslice_size
= avctx
->width
* s
->slice_height
+ 2;
224 for (int n
= 0; n
< s
->nb_slices
; n
++) {
225 for (int i
= 0; i
< s
->planes
; i
++) {
226 Slice
*sl
= &s
->slices
[n
* s
->planes
+ i
];
228 sl
->bitslice
= av_malloc(s
->bitslice_size
+ AV_INPUT_BUFFER_PADDING_SIZE
);
229 sl
->slice
= av_malloc(avctx
->width
* (s
->slice_height
+ 2) +
230 AV_INPUT_BUFFER_PADDING_SIZE
);
231 if (!sl
->slice
|| !sl
->bitslice
) {
232 av_log(avctx
, AV_LOG_ERROR
, "Cannot allocate temporary buffer.\n");
233 return AVERROR(ENOMEM
);
238 switch (s
->frame_pred
) {
239 case LEFT
: s
->predict
= left_predict
; break;
240 case GRADIENT
: s
->predict
= gradient_predict
; break;
241 case MEDIAN
: s
->predict
= median_predict
; break;
244 avctx
->extradata_size
= MAGICYUV_EXTRADATA_SIZE
;
246 avctx
->extradata
= av_mallocz(avctx
->extradata_size
+
247 AV_INPUT_BUFFER_PADDING_SIZE
);
249 if (!avctx
->extradata
) {
250 av_log(avctx
, AV_LOG_ERROR
, "Could not allocate extradata.\n");
251 return AVERROR(ENOMEM
);
254 bytestream2_init_writer(&pb
, avctx
->extradata
, MAGICYUV_EXTRADATA_SIZE
);
255 bytestream2_put_le32(&pb
, MKTAG('M', 'A', 'G', 'Y'));
256 bytestream2_put_le32(&pb
, 32);
257 bytestream2_put_byte(&pb
, 7);
258 bytestream2_put_byte(&pb
, s
->format
);
259 bytestream2_put_byte(&pb
, 12);
260 bytestream2_put_byte(&pb
, 0);
262 bytestream2_put_byte(&pb
, 0);
263 bytestream2_put_byte(&pb
, 0);
264 bytestream2_put_byte(&pb
, 32);
265 bytestream2_put_byte(&pb
, 0);
267 bytestream2_put_le32(&pb
, avctx
->width
);
268 bytestream2_put_le32(&pb
, avctx
->height
);
269 bytestream2_put_le32(&pb
, avctx
->width
);
270 bytestream2_put_le32(&pb
, avctx
->height
);
275 static void calculate_codes(HuffEntry
*he
, uint16_t codes_count
[33])
277 for (unsigned i
= 32, nb_codes
= 0; i
> 0; i
--) {
278 uint16_t curr
= codes_count
[i
]; // # of leafs of length i
279 codes_count
[i
] = nb_codes
/ 2; // # of non-leaf nodes on level i
280 nb_codes
= codes_count
[i
] + curr
; // # of nodes on level i
283 for (unsigned i
= 0; i
< 256; i
++) {
284 he
[i
].code
= codes_count
[he
[i
].len
];
285 codes_count
[he
[i
].len
]++;
289 static void count_usage(const uint8_t *src
, int width
,
290 int height
, PTable
*counts
)
292 for (int j
= 0; j
< height
; j
++) {
293 for (int i
= 0; i
< width
; i
++)
294 counts
[src
[i
]].prob
++;
299 typedef struct PackageMergerList
{
300 int nitems
; ///< number of items in the list and probability ex. 4
301 int item_idx
[515]; ///< index range for each item in items 0, 2, 5, 9, 13
302 int probability
[514]; ///< probability of each item 3, 8, 18, 46
303 int items
[257 * 16]; ///< chain of all individual values that make up items A, B, A, B, C, A, B, C, D, C, D, D, E
306 static int compare_by_prob(const void *a
, const void *b
)
308 const PTable
*a2
= a
;
309 const PTable
*b2
= b
;
310 return a2
->prob
- b2
->prob
;
313 static void magy_huffman_compute_bits(PTable
*prob_table
, HuffEntry
*distincts
,
314 uint16_t codes_counts
[33],
315 int size
, int max_length
)
317 PackageMergerList list_a
, list_b
, *to
= &list_a
, *from
= &list_b
, *temp
;
319 int nbits
[257] = {0};
322 av_assert0(max_length
> 0);
327 from
->item_idx
[0] = 0;
328 AV_QSORT(prob_table
, size
, PTable
, compare_by_prob
);
330 for (times
= 0; times
<= max_length
; times
++) {
337 if (times
< max_length
) {
340 while (i
< size
|| j
+ 1 < from
->nitems
) {
342 to
->item_idx
[to
->nitems
] = to
->item_idx
[to
->nitems
- 1];
344 (j
+ 1 >= from
->nitems
||
346 from
->probability
[j
] + from
->probability
[j
+ 1])) {
347 to
->items
[to
->item_idx
[to
->nitems
]++] = prob_table
[i
].value
;
348 to
->probability
[to
->nitems
- 1] = prob_table
[i
].prob
;
351 for (k
= from
->item_idx
[j
]; k
< from
->item_idx
[j
+ 2]; k
++) {
352 to
->items
[to
->item_idx
[to
->nitems
]++] = from
->items
[k
];
354 to
->probability
[to
->nitems
- 1] =
355 from
->probability
[j
] + from
->probability
[j
+ 1];
364 min
= (size
- 1 < from
->nitems
) ? size
- 1 : from
->nitems
;
365 for (i
= 0; i
< from
->item_idx
[min
]; i
++) {
366 nbits
[from
->items
[i
]]++;
369 for (i
= 0; i
< size
; i
++) {
370 distincts
[i
].len
= nbits
[i
];
371 codes_counts
[nbits
[i
]]++;
375 static int count_plane_slice(AVCodecContext
*avctx
, int n
, int plane
)
377 MagicYUVContext
*s
= avctx
->priv_data
;
378 Slice
*sl
= &s
->slices
[n
* s
->planes
+ plane
];
379 const uint8_t *dst
= sl
->slice
;
380 PTable
*counts
= sl
->counts
;
381 const int slice_height
= s
->slice_height
;
382 const int last_height
= FFMIN(slice_height
, avctx
->height
- n
* slice_height
);
383 const int height
= (n
< (s
->nb_slices
- 1)) ? slice_height
: last_height
;
385 memset(counts
, 0, sizeof(sl
->counts
));
387 count_usage(dst
, AV_CEIL_RSHIFT(avctx
->width
, s
->hshift
[plane
]),
388 AV_CEIL_RSHIFT(height
, s
->vshift
[plane
]), counts
);
393 static int encode_table(AVCodecContext
*avctx
,
394 PutBitContext
*pb
, HuffEntry
*he
, int plane
)
396 MagicYUVContext
*s
= avctx
->priv_data
;
397 PTable counts
[256] = { {0} };
398 uint16_t codes_counts
[33] = { 0 };
400 for (int n
= 0; n
< s
->nb_slices
; n
++) {
401 Slice
*sl
= &s
->slices
[n
* s
->planes
+ plane
];
402 PTable
*slice_counts
= sl
->counts
;
404 for (int i
= 0; i
< 256; i
++)
405 counts
[i
].prob
= slice_counts
[i
].prob
;
408 for (int i
= 0; i
< 256; i
++) {
413 magy_huffman_compute_bits(counts
, he
, codes_counts
, 256, 12);
415 calculate_codes(he
, codes_counts
);
417 for (int i
= 0; i
< 256; i
++) {
419 put_bits(pb
, 7, he
[i
].len
);
425 static int encode_plane_slice_raw(const uint8_t *src
, uint8_t *dst
, unsigned dst_size
,
426 int width
, int height
, int prediction
)
428 unsigned count
= width
* height
;
433 memcpy(dst
+ 2, src
, count
);
435 AV_WN32(dst
+ count
, 0);
437 count
+= 4 - (count
& 3);
442 static int encode_plane_slice(const uint8_t *src
, uint8_t *dst
, unsigned dst_size
,
443 int width
, int height
, HuffEntry
*he
, int prediction
)
445 const uint8_t *osrc
= src
;
449 init_put_bits(&pb
, dst
, dst_size
);
452 put_bits(&pb
, 8, prediction
);
454 for (int j
= 0; j
< height
; j
++) {
455 for (int i
= 0; i
< width
; i
++) {
456 const int idx
= src
[i
];
457 const int len
= he
[idx
].len
;
458 if (put_bits_left(&pb
) < len
+ 32)
459 return encode_plane_slice_raw(osrc
, dst
, dst_size
, width
, height
, prediction
);
460 put_bits(&pb
, len
, he
[idx
].code
);
466 count
= put_bits_count(&pb
) & 0x1F;
469 put_bits(&pb
, 32 - count
, 0);
473 return put_bytes_output(&pb
);
476 static int encode_slice(AVCodecContext
*avctx
, void *tdata
,
479 MagicYUVContext
*s
= avctx
->priv_data
;
480 const int slice_height
= s
->slice_height
;
481 const int last_height
= FFMIN(slice_height
, avctx
->height
- n
* slice_height
);
482 const int height
= (n
< (s
->nb_slices
- 1)) ? slice_height
: last_height
;
484 for (int i
= 0; i
< s
->planes
; i
++) {
485 Slice
*sl
= &s
->slices
[n
* s
->planes
+ i
];
488 encode_plane_slice(sl
->slice
,
491 AV_CEIL_RSHIFT(avctx
->width
, s
->hshift
[i
]),
492 AV_CEIL_RSHIFT(height
, s
->vshift
[i
]),
493 s
->he
[i
], s
->frame_pred
);
499 static int predict_slice(AVCodecContext
*avctx
, void *tdata
,
502 size_t max_align
= av_cpu_max_align();
503 const int aligned_width
= FFALIGN(avctx
->width
, max_align
);
504 MagicYUVContext
*s
= avctx
->priv_data
;
505 const int slice_height
= s
->slice_height
;
506 const int last_height
= FFMIN(slice_height
, avctx
->height
- n
* slice_height
);
507 const int height
= (n
< (s
->nb_slices
- 1)) ? slice_height
: last_height
;
508 const int width
= avctx
->width
;
509 AVFrame
*frame
= tdata
;
512 uint8_t *decorrelated
[2] = { s
->decorrelate_buf
[0] + n
* slice_height
* aligned_width
,
513 s
->decorrelate_buf
[1] + n
* slice_height
* aligned_width
};
514 const int decorrelate_linesize
= aligned_width
;
515 const uint8_t *const data
[4] = { decorrelated
[0], frame
->data
[0] + n
* slice_height
* frame
->linesize
[0],
516 decorrelated
[1], s
->planes
== 4 ? frame
->data
[3] + n
* slice_height
* frame
->linesize
[3] : NULL
};
517 const uint8_t *r
, *g
, *b
;
518 const int linesize
[4] = { decorrelate_linesize
, frame
->linesize
[0],
519 decorrelate_linesize
, frame
->linesize
[3] };
521 g
= frame
->data
[0] + n
* slice_height
* frame
->linesize
[0];
522 b
= frame
->data
[1] + n
* slice_height
* frame
->linesize
[1];
523 r
= frame
->data
[2] + n
* slice_height
* frame
->linesize
[2];
525 for (int i
= 0; i
< height
; i
++) {
526 s
->llvidencdsp
.diff_bytes(decorrelated
[0], b
, g
, width
);
527 s
->llvidencdsp
.diff_bytes(decorrelated
[1], r
, g
, width
);
528 g
+= frame
->linesize
[0];
529 b
+= frame
->linesize
[1];
530 r
+= frame
->linesize
[2];
531 decorrelated
[0] += decorrelate_linesize
;
532 decorrelated
[1] += decorrelate_linesize
;
535 for (int i
= 0; i
< s
->planes
; i
++) {
536 Slice
*sl
= &s
->slices
[n
* s
->planes
+ i
];
538 s
->predict(s
, data
[i
], sl
->slice
, linesize
[i
],
539 frame
->width
, height
);
542 for (int i
= 0; i
< s
->planes
; i
++) {
543 Slice
*sl
= &s
->slices
[n
* s
->planes
+ i
];
545 s
->predict(s
, frame
->data
[i
] + n
* (slice_height
>> s
->vshift
[i
]) * frame
->linesize
[i
],
548 AV_CEIL_RSHIFT(frame
->width
, s
->hshift
[i
]),
549 AV_CEIL_RSHIFT(height
, s
->vshift
[i
]));
553 for (int p
= 0; p
< s
->planes
; p
++)
554 count_plane_slice(avctx
, n
, p
);
559 static int magy_encode_frame(AVCodecContext
*avctx
, AVPacket
*pkt
,
560 const AVFrame
*frame
, int *got_packet
)
562 MagicYUVContext
*s
= avctx
->priv_data
;
563 const int width
= avctx
->width
, height
= avctx
->height
;
564 const int slice_height
= s
->slice_height
;
565 unsigned tables_size
;
570 ret
= ff_alloc_packet(avctx
, pkt
, (256 + 4 * s
->nb_slices
+ width
* height
) *
575 bytestream2_init_writer(&pb
, pkt
->data
, pkt
->size
);
576 bytestream2_put_le32(&pb
, MKTAG('M', 'A', 'G', 'Y'));
577 bytestream2_put_le32(&pb
, 32); // header size
578 bytestream2_put_byte(&pb
, 7); // version
579 bytestream2_put_byte(&pb
, s
->format
);
580 bytestream2_put_byte(&pb
, 12); // max huffman length
581 bytestream2_put_byte(&pb
, 0);
583 bytestream2_put_byte(&pb
, 0);
584 bytestream2_put_byte(&pb
, 0);
585 bytestream2_put_byte(&pb
, 32); // coder type
586 bytestream2_put_byte(&pb
, 0);
588 bytestream2_put_le32(&pb
, avctx
->width
);
589 bytestream2_put_le32(&pb
, avctx
->height
);
590 bytestream2_put_le32(&pb
, avctx
->width
);
591 bytestream2_put_le32(&pb
, slice_height
);
592 bytestream2_put_le32(&pb
, 0);
594 for (int i
= 0; i
< s
->planes
; i
++) {
595 bytestream2_put_le32(&pb
, 0);
596 for (int j
= 1; j
< s
->nb_slices
; j
++)
597 bytestream2_put_le32(&pb
, 0);
600 bytestream2_put_byte(&pb
, s
->planes
);
602 for (int i
= 0; i
< s
->planes
; i
++) {
603 for (int n
= 0; n
< s
->nb_slices
; n
++)
604 bytestream2_put_byte(&pb
, n
* s
->planes
+ i
);
607 avctx
->execute2(avctx
, predict_slice
, (void *)frame
, NULL
, s
->nb_slices
);
609 init_put_bits(&pbit
, pkt
->data
+ bytestream2_tell_p(&pb
), bytestream2_get_bytes_left_p(&pb
));
611 for (int i
= 0; i
< s
->planes
; i
++)
612 encode_table(avctx
, &pbit
, s
->he
[i
], i
);
614 tables_size
= put_bytes_count(&pbit
, 1);
615 bytestream2_skip_p(&pb
, tables_size
);
617 avctx
->execute2(avctx
, encode_slice
, NULL
, NULL
, s
->nb_slices
);
619 for (int n
= 0; n
< s
->nb_slices
; n
++) {
620 for (int i
= 0; i
< s
->planes
; i
++) {
621 Slice
*sl
= &s
->slices
[n
* s
->planes
+ i
];
623 sl
->pos
= bytestream2_tell_p(&pb
);
625 bytestream2_put_buffer(&pb
, sl
->bitslice
, sl
->size
);
629 pos
= bytestream2_tell_p(&pb
);
630 bytestream2_seek_p(&pb
, 32, SEEK_SET
);
631 bytestream2_put_le32(&pb
, s
->slices
[0].pos
- 32);
632 for (int i
= 0; i
< s
->planes
; i
++) {
633 for (int n
= 0; n
< s
->nb_slices
; n
++) {
634 Slice
*sl
= &s
->slices
[n
* s
->planes
+ i
];
636 bytestream2_put_le32(&pb
, sl
->pos
- 32);
639 bytestream2_seek_p(&pb
, pos
, SEEK_SET
);
641 pkt
->size
= bytestream2_tell_p(&pb
);
648 static av_cold
int magy_encode_close(AVCodecContext
*avctx
)
650 MagicYUVContext
*s
= avctx
->priv_data
;
652 for (int i
= 0; i
< s
->planes
* s
->nb_slices
&& s
->slices
; i
++) {
653 Slice
*sl
= &s
->slices
[i
];
655 av_freep(&sl
->slice
);
656 av_freep(&sl
->bitslice
);
658 av_freep(&s
->slices
);
659 av_freep(&s
->decorrelate_buf
);
664 #define OFFSET(x) offsetof(MagicYUVContext, x)
665 #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
666 static const AVOption options
[] = {
667 { "pred", "Prediction method", OFFSET(frame_pred
), AV_OPT_TYPE_INT
, {.i64
=LEFT
}, LEFT
, MEDIAN
, VE
, .unit
= "pred" },
668 { "left", NULL
, 0, AV_OPT_TYPE_CONST
, { .i64
= LEFT
}, 0, 0, VE
, .unit
= "pred" },
669 { "gradient", NULL
, 0, AV_OPT_TYPE_CONST
, { .i64
= GRADIENT
}, 0, 0, VE
, .unit
= "pred" },
670 { "median", NULL
, 0, AV_OPT_TYPE_CONST
, { .i64
= MEDIAN
}, 0, 0, VE
, .unit
= "pred" },
674 static const AVClass magicyuv_class
= {
675 .class_name
= "magicyuv",
676 .item_name
= av_default_item_name
,
678 .version
= LIBAVUTIL_VERSION_INT
,
681 const FFCodec ff_magicyuv_encoder
= {
682 .p
.name
= "magicyuv",
683 CODEC_LONG_NAME("MagicYUV video"),
684 .p
.type
= AVMEDIA_TYPE_VIDEO
,
685 .p
.id
= AV_CODEC_ID_MAGICYUV
,
686 .p
.capabilities
= AV_CODEC_CAP_DR1
| AV_CODEC_CAP_FRAME_THREADS
|
687 AV_CODEC_CAP_SLICE_THREADS
|
688 AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE
,
689 .priv_data_size
= sizeof(MagicYUVContext
),
690 .p
.priv_class
= &magicyuv_class
,
691 .init
= magy_encode_init
,
692 .close
= magy_encode_close
,
693 FF_CODEC_ENCODE_CB(magy_encode_frame
),
694 .p
.pix_fmts
= (const enum AVPixelFormat
[]) {
695 AV_PIX_FMT_GBRP
, AV_PIX_FMT_GBRAP
, AV_PIX_FMT_YUV422P
,
696 AV_PIX_FMT_YUV420P
, AV_PIX_FMT_YUV444P
, AV_PIX_FMT_YUVA444P
, AV_PIX_FMT_GRAY8
,
699 .color_ranges
= AVCOL_RANGE_MPEG
, /* FIXME: implement tagging */
700 .caps_internal
= FF_CODEC_CAP_INIT_CLEANUP
,