-
-
Save JeromeMartinez/7751c50ba72988c6c53938e830bd784d to your computer and use it in GitHub Desktop.
FFV1-CFA-test_mergedG1G2
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
libavcodec/ffv1.c | 5 ++++- | |
libavcodec/ffv1.h | 3 +++ | |
libavcodec/ffv1dec.c | 32 +++++++++++++++++++++++++++++- | |
libavcodec/ffv1dec_template.c | 36 +++++++++++++++++++++++++--------- | |
libavcodec/ffv1enc.c | 45 ++++++++++++++++++++++++++++++++++++++++++- | |
libavcodec/ffv1enc_template.c | 35 +++++++++++++++++++++++++-------- | |
6 files changed, 136 insertions(+), 20 deletions(-) | |
diff --git a/libavcodec/ffv1.c b/libavcodec/ffv1.c | |
index a14dd2aab2..4e750620bb 100644 | |
--- a/libavcodec/ffv1.c | |
+++ b/libavcodec/ffv1.c | |
@@ -70,6 +70,9 @@ av_cold int ff_ffv1_init_slice_state(FFV1Context *f, FFV1Context *fs) | |
fs->plane_count = f->plane_count; | |
fs->transparency = f->transparency; | |
+ fs->bayer_code = f->bayer_code; | |
+ fs->width_scale = f->width_scale; | |
+ fs->height_scale = f->height_scale; | |
for (j = 0; j < f->plane_count; j++) { | |
PlaneContext *const p = &fs->plane[j]; | |
@@ -142,7 +145,7 @@ av_cold int ff_ffv1_init_slice_contexts(FFV1Context *f) | |
fs->slice_x = sxs; | |
fs->slice_y = sys; | |
- fs->sample_buffer = av_malloc_array((fs->width + 6), 3 * MAX_PLANES * | |
+ fs->sample_buffer = av_malloc_array((fs->width*2 + 6), 3 * MAX_PLANES * | |
sizeof(*fs->sample_buffer)); | |
fs->sample_buffer32 = av_malloc_array((fs->width + 6), 3 * MAX_PLANES * | |
sizeof(*fs->sample_buffer32)); | |
diff --git a/libavcodec/ffv1.h b/libavcodec/ffv1.h | |
index 653138b070..a40201995b 100644 | |
--- a/libavcodec/ffv1.h | |
+++ b/libavcodec/ffv1.h | |
@@ -93,6 +93,9 @@ typedef struct FFV1Context { | |
int flags; | |
int picture_number; | |
int key_frame; | |
+ int bayer_code; | |
+ int width_scale; | |
+ int height_scale; | |
ThreadFrame picture, last_picture; | |
struct FFV1Context *fsrc; | |
diff --git a/libavcodec/ffv1dec.c b/libavcodec/ffv1dec.c | |
index 261e0cf70c..440284e1ca 100644 | |
--- a/libavcodec/ffv1dec.c | |
+++ b/libavcodec/ffv1dec.c | |
@@ -340,7 +340,7 @@ static int decode_slice(AVCodecContext *c, void *arg) | |
p->data[1] + ps * x + y * p->linesize[1], | |
p->data[2] + ps * x + y * p->linesize[2], | |
p->data[3] + ps * x + y * p->linesize[3] }; | |
- decode_rgb_frame32(fs, planes, width, height, p->linesize); | |
+ decode_rgb_frame32(fs, planes, width/f->width_scale, height/f->height_scale, p->linesize); | |
} else { | |
uint8_t *planes[4] = { p->data[0] + ps * x + y * p->linesize[0], | |
p->data[1] + ps * x + y * p->linesize[1], | |
@@ -443,6 +443,13 @@ static int read_extra_header(FFV1Context *f) | |
} | |
f->colorspace = get_symbol(c, state, 0); //YUV cs type | |
+ if (f->colorspace == 2) { | |
+ get_symbol(c, state, 0); | |
+ get_symbol(c, state, 0); | |
+ get_symbol(c, state, 0); | |
+ get_symbol(c, state, 0); | |
+ f->bayer_code = 1; | |
+ } | |
f->avctx->bits_per_raw_sample = get_symbol(c, state, 0); | |
f->chroma_planes = get_rac(c, state); | |
f->chroma_h_shift = get_symbol(c, state, 0); | |
@@ -557,6 +564,13 @@ static int read_header(FFV1Context *f) | |
} | |
colorspace = get_symbol(c, state, 0); //YUV cs type | |
+ if (colorspace == 2) { | |
+ get_symbol(c, state, 0); | |
+ get_symbol(c, state, 0); | |
+ get_symbol(c, state, 0); | |
+ get_symbol(c, state, 0); | |
+ f->bayer_code = 1; | |
+ } | |
bits_per_raw_sample = f->version > 0 ? get_symbol(c, state, 0) : f->avctx->bits_per_raw_sample; | |
chroma_planes = get_rac(c, state); | |
chroma_h_shift = get_symbol(c, state, 0); | |
@@ -722,6 +736,19 @@ static int read_header(FFV1Context *f) | |
f->avctx->pix_fmt = AV_PIX_FMT_GBRAP16; | |
f->use32bit = 1; | |
} | |
+ } else if (f->colorspace == 2) { | |
+ if (f->chroma_h_shift || f->chroma_v_shift) { | |
+ av_log(f->avctx, AV_LOG_ERROR, | |
+ "chroma subsampling not supported in this colorspace\n"); | |
+ return AVERROR(ENOSYS); | |
+ } | |
+ if ( f->avctx->bits_per_raw_sample == 16 && !f->transparency) { | |
+ f->avctx->pix_fmt = AV_PIX_FMT_BAYER_RGGB16LE; | |
+ f->bayer_code = 1; | |
+ f->width_scale = 2; | |
+ f->height_scale = 2; | |
+ f->use32bit = 1; | |
+ } | |
} else { | |
av_log(f->avctx, AV_LOG_ERROR, "colorspace not supported\n"); | |
return AVERROR(ENOSYS); | |
@@ -1021,6 +1048,9 @@ static void copy_fields(FFV1Context *fsdst, FFV1Context *fssrc, FFV1Context *fsr | |
fsdst->plane_count = fsrc->plane_count; | |
fsdst->ac = fsrc->ac; | |
fsdst->colorspace = fsrc->colorspace; | |
+ fsdst->bayer_code = fsrc->bayer_code; | |
+ fsdst->width_scale = fsrc->width_scale; | |
+ fsdst->height_scale = fsrc->height_scale; | |
fsdst->ec = fsrc->ec; | |
fsdst->intra = fsrc->intra; | |
diff --git a/libavcodec/ffv1dec_template.c b/libavcodec/ffv1dec_template.c | |
index fecdbd0025..445ca1367f 100644 | |
--- a/libavcodec/ffv1dec_template.c | |
+++ b/libavcodec/ffv1dec_template.c | |
@@ -115,15 +115,16 @@ static int RENAME(decode_rgb_frame)(FFV1Context *s, uint8_t *src[4], int w, int | |
int bits = s->avctx->bits_per_raw_sample > 0 ? s->avctx->bits_per_raw_sample : 8; | |
int offset = 1 << bits; | |
int transparency = s->transparency; | |
+ int bayer_code = s->bayer_code; | |
for (x = 0; x < 4; x++) { | |
- sample[x][0] = RENAME(s->sample_buffer) + x * 2 * (w + 6) + 3; | |
- sample[x][1] = RENAME(s->sample_buffer) + (x * 2 + 1) * (w + 6) + 3; | |
+ sample[x][0] = RENAME(s->sample_buffer) + x * 2 * (w*2 + 6) + 3; | |
+ sample[x][1] = RENAME(s->sample_buffer) + (x * 2 + 1) * (w*2 + 6) + 3; | |
} | |
s->run_index = 0; | |
- memset(RENAME(s->sample_buffer), 0, 8 * (w + 6) * sizeof(*RENAME(s->sample_buffer))); | |
+ memset(RENAME(s->sample_buffer), 0, 8 * (w*2 + 6) * sizeof(*RENAME(s->sample_buffer))); | |
for (y = 0; y < h; y++) { | |
for (p = 0; p < 3 + transparency; p++) { | |
@@ -134,20 +135,21 @@ static int RENAME(decode_rgb_frame)(FFV1Context *s, uint8_t *src[4], int w, int | |
sample[p][1] = temp; | |
sample[p][1][-1]= sample[p][0][0 ]; | |
- sample[p][0][ w]= sample[p][0][w-1]; | |
+ sample[p][0][ w*(p?1:2)]= sample[p][0][w*(p?1:2)-1]; | |
if (lbd && s->slice_coding_mode == 0) | |
ret = RENAME(decode_line)(s, w, sample[p], (p + 1)/2, 9); | |
else | |
- ret = RENAME(decode_line)(s, w, sample[p], (p + 1)/2, bits + (s->slice_coding_mode != 1)); | |
+ ret = RENAME(decode_line)(s, w*(p?1:2), sample[p], (p + 1)/2, bits + (s->slice_coding_mode != 1)); | |
if (ret < 0) | |
return ret; | |
} | |
for (x = 0; x < w; x++) { | |
- int g = sample[0][1][x]; | |
+ int a = sample[0][1][x*2]; | |
int b = sample[1][1][x]; | |
int r = sample[2][1][x]; | |
- int a = sample[3][1][x]; | |
+ int g = sample[0][1][x*2+1]; | |
+ /* | |
if (s->slice_coding_mode != 1) { | |
b -= offset; | |
r -= offset; | |
@@ -155,8 +157,24 @@ static int RENAME(decode_rgb_frame)(FFV1Context *s, uint8_t *src[4], int w, int | |
b += g; | |
r += g; | |
} | |
- | |
- if (lbd) | |
+ */ | |
+ | |
+ if (bayer_code) | |
+ { | |
+ uint16_t *bayer[2]; | |
+ bayer[0] = ((uint16_t*)(src[0] + (x*2 + stride[0]*y) * 2)); | |
+ bayer[1] = ((uint16_t*)((uint8_t*)bayer[0] + stride[0])); | |
+ switch (bayer_code) | |
+ { | |
+ case 1 : | |
+ bayer[0][0] = r; | |
+ bayer[0][1] = g; | |
+ bayer[1][1] = b; | |
+ bayer[1][0] = a; | |
+ break; | |
+ } | |
+ } | |
+ else if (lbd) | |
*((uint32_t*)(src[0] + x*4 + stride[0]*y)) = b + ((unsigned)g<<8) + ((unsigned)r<<16) + ((unsigned)a<<24); | |
else if (sizeof(TYPE) == 4 || transparency) { | |
*((uint16_t*)(src[0] + x*2 + stride[0]*y)) = g; | |
diff --git a/libavcodec/ffv1enc.c b/libavcodec/ffv1enc.c | |
index f5eb0feb4e..a953c0237a 100644 | |
--- a/libavcodec/ffv1enc.c | |
+++ b/libavcodec/ffv1enc.c | |
@@ -351,6 +351,17 @@ static void write_header(FFV1Context *f) | |
f->state_transition[i] - c->one_state[i], 1); | |
} | |
put_symbol(c, state, f->colorspace, 0); //YUV cs type | |
+ if (f->colorspace == 2) { | |
+ switch (f->bayer_code) | |
+ { | |
+ case 1: // RGGB | |
+ put_symbol(c, state, 0, 0); // R | |
+ put_symbol(c, state, 1, 0); // G | |
+ put_symbol(c, state, 1, 0); // G | |
+ put_symbol(c, state, 2, 0); // B | |
+ break; | |
+ } | |
+ } | |
if (f->version > 0) | |
put_symbol(c, state, f->bits_per_raw_sample, 0); | |
put_rac(c, state, f->chroma_planes); | |
@@ -415,6 +426,17 @@ static int write_extradata(FFV1Context *f) | |
put_symbol(c, state, f->state_transition[i] - c->one_state[i], 1); | |
put_symbol(c, state, f->colorspace, 0); // YUV cs type | |
+ if (f->colorspace == 2) { | |
+ switch (f->bayer_code) | |
+ { | |
+ case 1: // RGGB | |
+ put_symbol(c, state, 0, 0); // R | |
+ put_symbol(c, state, 1, 0); // G | |
+ put_symbol(c, state, 1, 0); // G | |
+ put_symbol(c, state, 2, 0); // B | |
+ break; | |
+ } | |
+ } | |
put_symbol(c, state, f->bits_per_raw_sample, 0); | |
put_rac(c, state, f->chroma_planes); | |
put_symbol(c, state, f->chroma_h_shift, 0); | |
@@ -561,6 +583,9 @@ FF_ENABLE_DEPRECATION_WARNINGS | |
s->ac = AC_RANGE_DEFAULT_TAB; | |
s->plane_count = 3; | |
+ s->bayer_code = 0; | |
+ s->width_scale = 1; | |
+ s->height_scale = 1; | |
switch(avctx->pix_fmt) { | |
case AV_PIX_FMT_GRAY9: | |
case AV_PIX_FMT_YUV444P9: | |
@@ -684,6 +709,17 @@ FF_ENABLE_DEPRECATION_WARNINGS | |
} | |
s->version = FFMAX(s->version, 1); | |
break; | |
+ case AV_PIX_FMT_BAYER_RGGB16LE: | |
+ s->bits_per_raw_sample = 16; | |
+ s->transparency = 0; | |
+ s->colorspace = 2; | |
+ s->bayer_code = 1; | |
+ s->width_scale = 2; | |
+ s->height_scale = 2; | |
+ s->chroma_planes = 1; | |
+ s->use32bit = 1; | |
+ s->version = FFMAX(s->version, 1); | |
+ break; | |
default: | |
av_log(avctx, AV_LOG_ERROR, "format not supported\n"); | |
return AVERROR(ENOSYS); | |
@@ -1091,7 +1127,7 @@ retry: | |
ret = encode_plane(fs, p->data[0] + ps*x + y*p->linesize[0], width, height, p->linesize[0], 0, 2); | |
ret |= encode_plane(fs, p->data[0] + 1 + ps*x + y*p->linesize[0], width, height, p->linesize[0], 1, 2); | |
} else if (f->use32bit) { | |
- ret = encode_rgb_frame32(fs, planes, width, height, p->linesize); | |
+ ret = encode_rgb_frame32(fs, planes, width/f->width_scale, height/f->height_scale, p->linesize); | |
} else { | |
ret = encode_rgb_frame(fs, planes, width, height, p->linesize); | |
} | |
@@ -1174,6 +1210,12 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, | |
maxsize = AV_INPUT_BUFFER_MIN_SIZE + avctx->width*avctx->height*3LL*4; | |
if (maxsize > INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE - 32) { | |
+ printf("*** %lli\n", AV_INPUT_BUFFER_MIN_SIZE); | |
+ printf("*** %lli\n", avctx->width); | |
+ printf("*** %lli\n", avctx->height); | |
+ printf("*** %lli\n", maxsize); | |
+ printf("*** %lli\n", INT_MAX); | |
+ printf("*** %lli\n", AV_INPUT_BUFFER_PADDING_SIZE); | |
av_log(avctx, AV_LOG_WARNING, "Cannot allocate worst case packet size, the encoding could fail\n"); | |
maxsize = INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE - 32; | |
} | |
@@ -1345,6 +1387,7 @@ AVCodec ff_ffv1_encoder = { | |
AV_PIX_FMT_GRAY9, | |
AV_PIX_FMT_YUV420P14, AV_PIX_FMT_YUV422P14, AV_PIX_FMT_YUV444P14, | |
AV_PIX_FMT_YUV440P10, AV_PIX_FMT_YUV440P12, | |
+ AV_PIX_FMT_BAYER_RGGB16LE, | |
AV_PIX_FMT_NONE | |
}, | |
diff --git a/libavcodec/ffv1enc_template.c b/libavcodec/ffv1enc_template.c | |
index bc0add5ed7..05a5dd065d 100644 | |
--- a/libavcodec/ffv1enc_template.c | |
+++ b/libavcodec/ffv1enc_template.c | |
@@ -134,20 +134,36 @@ static int RENAME(encode_rgb_frame)(FFV1Context *s, const uint8_t *src[4], | |
int offset = 1 << bits; | |
int transparency = s->transparency; | |
int packed_size = (3 + transparency)*2; | |
+ int bayer_code = s->bayer_code; | |
s->run_index = 0; | |
memset(RENAME(s->sample_buffer), 0, ring_size * MAX_PLANES * | |
- (w + 6) * sizeof(*RENAME(s->sample_buffer))); | |
+ (w*2 + 6) * sizeof(*RENAME(s->sample_buffer))); | |
for (y = 0; y < h; y++) { | |
for (i = 0; i < ring_size; i++) | |
for (p = 0; p < MAX_PLANES; p++) | |
- sample[p][i]= RENAME(s->sample_buffer) + p*ring_size*(w+6) + ((h+i-y)%ring_size)*(w+6) + 3; | |
+ sample[p][i]= RENAME(s->sample_buffer) + p*ring_size*(w*2+6) + ((h+i-y)%ring_size)*(w*2+6) + 3; | |
for (x = 0; x < w; x++) { | |
int b, g, r, av_uninit(a); | |
- if (lbd) { | |
+ if (bayer_code) | |
+ { | |
+ uint16_t *bayer[2]; | |
+ bayer[0] = ((uint16_t*)(src[0] + (x*2 + stride[0]*y) *2)); | |
+ bayer[1] = ((uint16_t*)((uint8_t*)bayer[0] + stride[0])); | |
+ switch (bayer_code) | |
+ { | |
+ case 1 : | |
+ r = bayer[0][0]; | |
+ g = bayer[0][1]; | |
+ b = bayer[1][1]; | |
+ a = bayer[1][0]; | |
+ break; | |
+ } | |
+ } | |
+ else if (lbd) { | |
unsigned v = *((const uint32_t*)(src[0] + x*4 + stride[0]*y)); | |
b = v & 0xFF; | |
g = (v >> 8) & 0xFF; | |
@@ -172,6 +188,7 @@ static int RENAME(encode_rgb_frame)(FFV1Context *s, const uint8_t *src[4], | |
r = *((const uint16_t *)(src[2] + x*2 + stride[2]*y)); | |
} | |
+ /* | |
if (s->slice_coding_mode != 1) { | |
b -= g; | |
r -= g; | |
@@ -179,20 +196,22 @@ static int RENAME(encode_rgb_frame)(FFV1Context *s, const uint8_t *src[4], | |
b += offset; | |
r += offset; | |
} | |
+ */ | |
- sample[0][0][x] = g; | |
+ sample[0][0][x*2] = a; | |
+ sample[0][0][x*2+1] = g; | |
sample[1][0][x] = b; | |
sample[2][0][x] = r; | |
- sample[3][0][x] = a; | |
+ sample[3][0][x] = 0; | |
} | |
for (p = 0; p < 3 + transparency; p++) { | |
int ret; | |
sample[p][0][-1] = sample[p][1][0 ]; | |
- sample[p][1][ w] = sample[p][1][w-1]; | |
+ sample[p][1][ w*(p?1:2)] = sample[p][1][w*(p?1:2)-1]; | |
if (lbd && s->slice_coding_mode == 0) | |
- ret = RENAME(encode_line)(s, w, sample[p], (p + 1) / 2, 9); | |
+ ret = RENAME(encode_line)(s, w*(p?1:2), sample[p], (p + 1) / 2, 9); | |
else | |
- ret = RENAME(encode_line)(s, w, sample[p], (p + 1) / 2, bits + (s->slice_coding_mode != 1)); | |
+ ret = RENAME(encode_line)(s, w*(p?1:2), sample[p], (p + 1) / 2, bits + (s->slice_coding_mode != 1)); | |
if (ret < 0) | |
return ret; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment