Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
Jérôme Martinez authored on 2018/02/01 21:11:53... | ... |
@@ -336,14 +336,16 @@ static int decode_slice(AVCodecContext *c, void *arg) |
336 | 336 |
decode_plane(fs, p->data[0] + ps*x + y*p->linesize[0] , width, height, p->linesize[0], 0, 2); |
337 | 337 |
decode_plane(fs, p->data[0] + ps*x + y*p->linesize[0] + 1, width, height, p->linesize[0], 1, 2); |
338 | 338 |
} else if (f->use32bit) { |
339 |
- uint8_t *planes[3] = { p->data[0] + ps * x + y * p->linesize[0], |
|
339 |
+ uint8_t *planes[4] = { p->data[0] + ps * x + y * p->linesize[0], |
|
340 | 340 |
p->data[1] + ps * x + y * p->linesize[1], |
341 |
- p->data[2] + ps * x + y * p->linesize[2] }; |
|
341 |
+ p->data[2] + ps * x + y * p->linesize[2], |
|
342 |
+ p->data[3] + ps * x + y * p->linesize[3] }; |
|
342 | 343 |
decode_rgb_frame32(fs, planes, width, height, p->linesize); |
343 | 344 |
} else { |
344 |
- uint8_t *planes[3] = { p->data[0] + ps * x + y * p->linesize[0], |
|
345 |
+ uint8_t *planes[4] = { p->data[0] + ps * x + y * p->linesize[0], |
|
345 | 346 |
p->data[1] + ps * x + y * p->linesize[1], |
346 |
- p->data[2] + ps * x + y * p->linesize[2] }; |
|
347 |
+ p->data[2] + ps * x + y * p->linesize[2], |
|
348 |
+ p->data[3] + ps * x + y * p->linesize[3] }; |
|
347 | 349 |
decode_rgb_frame(fs, planes, width, height, p->linesize); |
348 | 350 |
} |
349 | 351 |
if (fs->ac != AC_GOLOMB_RICE && f->version > 2) { |
... | ... |
@@ -694,6 +696,10 @@ static int read_header(FFV1Context *f) |
694 | 694 |
f->avctx->pix_fmt = AV_PIX_FMT_GBRP16; |
695 | 695 |
f->use32bit = 1; |
696 | 696 |
} |
697 |
+ else if (f->avctx->bits_per_raw_sample == 16 && f->transparency) { |
|
698 |
+ f->avctx->pix_fmt = AV_PIX_FMT_GBRAP16; |
|
699 |
+ f->use32bit = 1; |
|
700 |
+ } |
|
697 | 701 |
} else { |
698 | 702 |
av_log(f->avctx, AV_LOG_ERROR, "colorspace not supported\n"); |
699 | 703 |
return AVERROR(ENOSYS); |
... | ... |
@@ -107,13 +107,14 @@ static av_always_inline int RENAME(decode_line)(FFV1Context *s, int w, |
107 | 107 |
return 0; |
108 | 108 |
} |
109 | 109 |
|
110 |
-static void RENAME(decode_rgb_frame)(FFV1Context *s, uint8_t *src[3], int w, int h, int stride[3]) |
|
110 |
+static void RENAME(decode_rgb_frame)(FFV1Context *s, uint8_t *src[4], int w, int h, int stride[4]) |
|
111 | 111 |
{ |
112 | 112 |
int x, y, p; |
113 | 113 |
TYPE *sample[4][2]; |
114 | 114 |
int lbd = s->avctx->bits_per_raw_sample <= 8; |
115 | 115 |
int bits = s->avctx->bits_per_raw_sample > 0 ? s->avctx->bits_per_raw_sample : 8; |
116 | 116 |
int offset = 1 << bits; |
117 |
+ int transparency = s->transparency; |
|
117 | 118 |
|
118 | 119 |
for (x = 0; x < 4; x++) { |
119 | 120 |
sample[x][0] = RENAME(s->sample_buffer) + x * 2 * (w + 6) + 3; |
... | ... |
@@ -125,7 +126,7 @@ static void RENAME(decode_rgb_frame)(FFV1Context *s, uint8_t *src[3], int w, int |
125 | 125 |
memset(RENAME(s->sample_buffer), 0, 8 * (w + 6) * sizeof(*RENAME(s->sample_buffer))); |
126 | 126 |
|
127 | 127 |
for (y = 0; y < h; y++) { |
128 |
- for (p = 0; p < 3 + s->transparency; p++) { |
|
128 |
+ for (p = 0; p < 3 + transparency; p++) { |
|
129 | 129 |
TYPE *temp = sample[p][0]; // FIXME: try a normal buffer |
130 | 130 |
|
131 | 131 |
sample[p][0] = sample[p][1]; |
... | ... |
@@ -158,10 +159,14 @@ static void RENAME(decode_rgb_frame)(FFV1Context *s, uint8_t *src[3], int w, int |
158 | 158 |
*((uint16_t*)(src[0] + x*2 + stride[0]*y)) = g; |
159 | 159 |
*((uint16_t*)(src[1] + x*2 + stride[1]*y)) = b; |
160 | 160 |
*((uint16_t*)(src[2] + x*2 + stride[2]*y)) = r; |
161 |
+ if (transparency) |
|
162 |
+ *((uint16_t*)(src[3] + x*2 + stride[3]*y)) = a; |
|
161 | 163 |
} else { |
162 | 164 |
*((uint16_t*)(src[0] + x*2 + stride[0]*y)) = b; |
163 | 165 |
*((uint16_t*)(src[1] + x*2 + stride[1]*y)) = g; |
164 | 166 |
*((uint16_t*)(src[2] + x*2 + stride[2]*y)) = r; |
167 |
+ if (transparency) |
|
168 |
+ *((uint16_t*)(src[3] + x*2 + stride[3]*y)) = a; |
|
165 | 169 |
} |
166 | 170 |
} |
167 | 171 |
} |
... | ... |
@@ -624,6 +624,14 @@ FF_ENABLE_DEPRECATION_WARNINGS |
624 | 624 |
s->chroma_planes = 1; |
625 | 625 |
s->bits_per_raw_sample = 8; |
626 | 626 |
break; |
627 |
+ case AV_PIX_FMT_RGBA64: |
|
628 |
+ s->colorspace = 1; |
|
629 |
+ s->transparency = 1; |
|
630 |
+ s->chroma_planes = 1; |
|
631 |
+ s->bits_per_raw_sample = 16; |
|
632 |
+ s->use32bit = 1; |
|
633 |
+ s->version = FFMAX(s->version, 1); |
|
634 |
+ break; |
|
627 | 635 |
case AV_PIX_FMT_RGB48: |
628 | 636 |
s->colorspace = 1; |
629 | 637 |
s->chroma_planes = 1; |
... | ... |
@@ -649,10 +657,12 @@ FF_ENABLE_DEPRECATION_WARNINGS |
649 | 649 |
if (!avctx->bits_per_raw_sample && !s->bits_per_raw_sample) |
650 | 650 |
s->bits_per_raw_sample = 14; |
651 | 651 |
case AV_PIX_FMT_GBRP16: |
652 |
+ case AV_PIX_FMT_GBRAP16: |
|
652 | 653 |
if (!avctx->bits_per_raw_sample && !s->bits_per_raw_sample) |
653 | 654 |
s->bits_per_raw_sample = 16; |
654 | 655 |
else if (!s->bits_per_raw_sample) |
655 | 656 |
s->bits_per_raw_sample = avctx->bits_per_raw_sample; |
657 |
+ s->transparency = desc->nb_components == 4 || desc->nb_components == 2; |
|
656 | 658 |
s->colorspace = 1; |
657 | 659 |
s->chroma_planes = 1; |
658 | 660 |
if (s->bits_per_raw_sample >= 16) { |
... | ... |
@@ -1024,9 +1034,10 @@ static int encode_slice(AVCodecContext *c, void *arg) |
1024 | 1024 |
const int ps = av_pix_fmt_desc_get(c->pix_fmt)->comp[0].step; |
1025 | 1025 |
int ret; |
1026 | 1026 |
RangeCoder c_bak = fs->c; |
1027 |
- const uint8_t *planes[3] = {p->data[0] + ps*x + y*p->linesize[0], |
|
1027 |
+ const uint8_t *planes[4] = {p->data[0] + ps*x + y*p->linesize[0], |
|
1028 | 1028 |
p->data[1] ? p->data[1] + ps*x + y*p->linesize[1] : NULL, |
1029 |
- p->data[2] ? p->data[2] + ps*x + y*p->linesize[2] : NULL}; |
|
1029 |
+ p->data[2] ? p->data[2] + ps*x + y*p->linesize[2] : NULL, |
|
1030 |
+ p->data[3] ? p->data[3] + ps*x + y*p->linesize[3] : NULL}; |
|
1030 | 1031 |
|
1031 | 1032 |
fs->slice_coding_mode = 0; |
1032 | 1033 |
if (f->version > 3) { |
... | ... |
@@ -1318,6 +1329,7 @@ AVCodec ff_ffv1_encoder = { |
1318 | 1318 |
AV_PIX_FMT_YA8, |
1319 | 1319 |
AV_PIX_FMT_GRAY10, AV_PIX_FMT_GRAY12, |
1320 | 1320 |
AV_PIX_FMT_GBRP16, AV_PIX_FMT_RGB48, |
1321 |
+ AV_PIX_FMT_GBRAP16, AV_PIX_FMT_RGBA64, |
|
1321 | 1322 |
AV_PIX_FMT_NONE |
1322 | 1323 |
|
1323 | 1324 |
}, |
... | ... |
@@ -122,8 +122,8 @@ static av_always_inline int RENAME(encode_line)(FFV1Context *s, int w, |
122 | 122 |
return 0; |
123 | 123 |
} |
124 | 124 |
|
125 |
-static int RENAME(encode_rgb_frame)(FFV1Context *s, const uint8_t *src[3], |
|
126 |
- int w, int h, const int stride[3]) |
|
125 |
+static int RENAME(encode_rgb_frame)(FFV1Context *s, const uint8_t *src[4], |
|
126 |
+ int w, int h, const int stride[4]) |
|
127 | 127 |
{ |
128 | 128 |
int x, y, p, i; |
129 | 129 |
const int ring_size = s->context_model ? 3 : 2; |
... | ... |
@@ -132,6 +132,8 @@ static int RENAME(encode_rgb_frame)(FFV1Context *s, const uint8_t *src[3], |
132 | 132 |
int packed = !src[1]; |
133 | 133 |
int bits = s->bits_per_raw_sample > 0 ? s->bits_per_raw_sample : 8; |
134 | 134 |
int offset = 1 << bits; |
135 |
+ int transparency = s->transparency; |
|
136 |
+ int packed_size = (3 + transparency)*2; |
|
135 | 137 |
|
136 | 138 |
s->run_index = 0; |
137 | 139 |
|
... | ... |
@@ -152,14 +154,18 @@ static int RENAME(encode_rgb_frame)(FFV1Context *s, const uint8_t *src[3], |
152 | 152 |
r = (v >> 16) & 0xFF; |
153 | 153 |
a = v >> 24; |
154 | 154 |
} else if (packed) { |
155 |
- const uint16_t *p = ((const uint16_t*)(src[0] + x*6 + stride[0]*y)); |
|
155 |
+ const uint16_t *p = ((const uint16_t*)(src[0] + x*packed_size + stride[0]*y)); |
|
156 | 156 |
r = p[0]; |
157 | 157 |
g = p[1]; |
158 | 158 |
b = p[2]; |
159 |
+ if (transparency) |
|
160 |
+ a = p[3]; |
|
159 | 161 |
} else if (sizeof(TYPE) == 4) { |
160 | 162 |
g = *((const uint16_t *)(src[0] + x*2 + stride[0]*y)); |
161 | 163 |
b = *((const uint16_t *)(src[1] + x*2 + stride[1]*y)); |
162 | 164 |
r = *((const uint16_t *)(src[2] + x*2 + stride[2]*y)); |
165 |
+ if (transparency) |
|
166 |
+ a = *((const uint16_t *)(src[3] + x*2 + stride[3]*y)); |
|
163 | 167 |
} else { |
164 | 168 |
b = *((const uint16_t *)(src[0] + x*2 + stride[0]*y)); |
165 | 169 |
g = *((const uint16_t *)(src[1] + x*2 + stride[1]*y)); |
... | ... |
@@ -179,7 +185,7 @@ static int RENAME(encode_rgb_frame)(FFV1Context *s, const uint8_t *src[3], |
179 | 179 |
sample[2][0][x] = r; |
180 | 180 |
sample[3][0][x] = a; |
181 | 181 |
} |
182 |
- for (p = 0; p < 3 + s->transparency; p++) { |
|
182 |
+ for (p = 0; p < 3 + transparency; p++) { |
|
183 | 183 |
int ret; |
184 | 184 |
sample[p][0][-1] = sample[p][1][0 ]; |
185 | 185 |
sample[p][1][ w] = sample[p][1][w-1]; |