summaryrefslogtreecommitdiffstats
path: root/drivers/media/platform/vicodec/vicodec-codec.c
diff options
context:
space:
mode:
authorHans Verkuil2018-08-19 16:58:55 +0200
committerMauro Carvalho Chehab2018-08-31 14:11:33 +0200
commit29a7a5e99080fead74d5172053b2f22f7004eb93 (patch)
tree155ceffad3b03d643b5f194a725d46a70afca412 /drivers/media/platform/vicodec/vicodec-codec.c
parentmedia: vicodec: add QP controls (diff)
downloadkernel-qcow2-linux-29a7a5e99080fead74d5172053b2f22f7004eb93.tar.gz
kernel-qcow2-linux-29a7a5e99080fead74d5172053b2f22f7004eb93.tar.xz
kernel-qcow2-linux-29a7a5e99080fead74d5172053b2f22f7004eb93.zip
media: vicodec: add support for more pixel formats
Add support for 4:2:2, 4:4:4 and RGB 24/32 bits formats. This makes it a lot more useful, esp. as a simple video compression codec for use with v4l2-ctl/qvidcap. Note that it does not do any conversion between e.g. 4:2:2 and 4:2:0 or RGB and YUV: it still just compresses planes be they Y/U/V or R/G/B. Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com> Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
Diffstat (limited to 'drivers/media/platform/vicodec/vicodec-codec.c')
-rw-r--r--drivers/media/platform/vicodec/vicodec-codec.c62
1 files changed, 50 insertions, 12 deletions
diff --git a/drivers/media/platform/vicodec/vicodec-codec.c b/drivers/media/platform/vicodec/vicodec-codec.c
index 7163f11b7ee8..7bd11a974db0 100644
--- a/drivers/media/platform/vicodec/vicodec-codec.c
+++ b/drivers/media/platform/vicodec/vicodec-codec.c
@@ -229,7 +229,8 @@ static void fwht(const u8 *block, s16 *output_block, unsigned int stride,
stride *= input_step;
for (i = 0; i < 8; i++, tmp += stride, out += 8) {
- if (input_step == 1) {
+ switch (input_step) {
+ case 1:
workspace1[0] = tmp[0] + tmp[1] - add;
workspace1[1] = tmp[0] - tmp[1];
@@ -241,7 +242,8 @@ static void fwht(const u8 *block, s16 *output_block, unsigned int stride,
workspace1[6] = tmp[6] + tmp[7] - add;
workspace1[7] = tmp[6] - tmp[7];
- } else {
+ break;
+ case 2:
workspace1[0] = tmp[0] + tmp[2] - add;
workspace1[1] = tmp[0] - tmp[2];
@@ -253,6 +255,33 @@ static void fwht(const u8 *block, s16 *output_block, unsigned int stride,
workspace1[6] = tmp[12] + tmp[14] - add;
workspace1[7] = tmp[12] - tmp[14];
+ break;
+ case 3:
+ workspace1[0] = tmp[0] + tmp[3] - add;
+ workspace1[1] = tmp[0] - tmp[3];
+
+ workspace1[2] = tmp[6] + tmp[9] - add;
+ workspace1[3] = tmp[6] - tmp[9];
+
+ workspace1[4] = tmp[12] + tmp[15] - add;
+ workspace1[5] = tmp[12] - tmp[15];
+
+ workspace1[6] = tmp[18] + tmp[21] - add;
+ workspace1[7] = tmp[18] - tmp[21];
+ break;
+ default:
+ workspace1[0] = tmp[0] + tmp[4] - add;
+ workspace1[1] = tmp[0] - tmp[4];
+
+ workspace1[2] = tmp[8] + tmp[12] - add;
+ workspace1[3] = tmp[8] - tmp[12];
+
+ workspace1[4] = tmp[16] + tmp[20] - add;
+ workspace1[5] = tmp[16] - tmp[20];
+
+ workspace1[6] = tmp[24] + tmp[28] - add;
+ workspace1[7] = tmp[24] - tmp[28];
+ break;
}
/* stage 2 */
@@ -704,25 +733,28 @@ u32 encode_frame(struct raw_frame *frm, struct raw_frame *ref_frm,
__be16 *rlco = cf->rlc_data;
__be16 *rlco_max;
u32 encoding;
+ u32 chroma_h = frm->height / frm->height_div;
+ u32 chroma_w = frm->width / frm->width_div;
+ unsigned int chroma_size = chroma_h * chroma_w;
rlco_max = rlco + size / 2 - 256;
encoding = encode_plane(frm->luma, ref_frm->luma, &rlco, rlco_max, cf,
- frm->height, frm->width,
- 1, is_intra, next_is_intra);
+ frm->height, frm->width,
+ frm->luma_step, is_intra, next_is_intra);
if (encoding & FRAME_UNENCODED)
encoding |= LUMA_UNENCODED;
encoding &= ~FRAME_UNENCODED;
- rlco_max = rlco + size / 8 - 256;
+ rlco_max = rlco + chroma_size / 2 - 256;
encoding |= encode_plane(frm->cb, ref_frm->cb, &rlco, rlco_max, cf,
- frm->height / 2, frm->width / 2,
- frm->chroma_step, is_intra, next_is_intra);
+ chroma_h, chroma_w,
+ frm->chroma_step, is_intra, next_is_intra);
if (encoding & FRAME_UNENCODED)
encoding |= CB_UNENCODED;
encoding &= ~FRAME_UNENCODED;
- rlco_max = rlco + size / 8 - 256;
+ rlco_max = rlco + chroma_size / 2 - 256;
encoding |= encode_plane(frm->cr, ref_frm->cr, &rlco, rlco_max, cf,
- frm->height / 2, frm->width / 2,
- frm->chroma_step, is_intra, next_is_intra);
+ chroma_h, chroma_w,
+ frm->chroma_step, is_intra, next_is_intra);
if (encoding & FRAME_UNENCODED)
encoding |= CR_UNENCODED;
encoding &= ~FRAME_UNENCODED;
@@ -786,11 +818,17 @@ static void decode_plane(struct cframe *cf, const __be16 **rlco, u8 *ref,
void decode_frame(struct cframe *cf, struct raw_frame *ref, u32 hdr_flags)
{
const __be16 *rlco = cf->rlc_data;
+ u32 h = cf->height / 2;
+ u32 w = cf->width / 2;
+ if (hdr_flags & VICODEC_FL_CHROMA_FULL_HEIGHT)
+ h *= 2;
+ if (hdr_flags & VICODEC_FL_CHROMA_FULL_WIDTH)
+ w *= 2;
decode_plane(cf, &rlco, ref->luma, cf->height, cf->width,
hdr_flags & VICODEC_FL_LUMA_IS_UNCOMPRESSED);
- decode_plane(cf, &rlco, ref->cb, cf->height / 2, cf->width / 2,
+ decode_plane(cf, &rlco, ref->cb, h, w,
hdr_flags & VICODEC_FL_CB_IS_UNCOMPRESSED);
- decode_plane(cf, &rlco, ref->cr, cf->height / 2, cf->width / 2,
+ decode_plane(cf, &rlco, ref->cr, h, w,
hdr_flags & VICODEC_FL_CR_IS_UNCOMPRESSED);
}