-
-
Save JeromeMartinez/d75739988eb698a6a232e25ca6de7d8d to your computer and use it in GitHub Desktop.
FFV1-CFA
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 | 3 +++ | |
libavcodec/ffv1.h | 3 +++ | |
libavcodec/ffv1dec.c | 32 +++++++++++++++++++++++++++++++- | |
libavcodec/ffv1dec_template.c | 18 +++++++++++++++++- | |
libavcodec/ffv1enc.c | 39 ++++++++++++++++++++++++++++++++++++++- | |
libavcodec/ffv1enc_template.c | 18 +++++++++++++++++- | |
6 files changed, 109 insertions(+), 4 deletions(-) | |
diff --git a/libavcodec/ffv1.c b/libavcodec/ffv1.c | |
index a14dd2aab2..7286f821d9 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]; | |
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..a936b10beb 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..b304dcfd30 100644 | |
--- a/libavcodec/ffv1dec_template.c | |
+++ b/libavcodec/ffv1dec_template.c | |
@@ -115,6 +115,7 @@ 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; | |
@@ -156,7 +157,22 @@ static int RENAME(decode_rgb_frame)(FFV1Context *s, uint8_t *src[4], int w, int | |
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 + g - offset; | |
+ 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..90bb2e707b 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 = 1; | |
+ 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); | |
} | |
@@ -1345,6 +1381,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..5009f0f8d0 100644 | |
--- a/libavcodec/ffv1enc_template.c | |
+++ b/libavcodec/ffv1enc_template.c | |
@@ -134,6 +134,7 @@ 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; | |
@@ -147,7 +148,22 @@ static int RENAME(encode_rgb_frame)(FFV1Context *s, const uint8_t *src[4], | |
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] - g + offset; | |
+ break; | |
+ } | |
+ } | |
+ else if (lbd) { | |
unsigned v = *((const uint32_t*)(src[0] + x*4 + stride[0]*y)); | |
b = v & 0xFF; | |
g = (v >> 8) & 0xFF; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment