diff options
Diffstat (limited to 'drivers/media/platform/vicodec/codec-v4l2-fwht.c')
-rw-r--r-- | drivers/media/platform/vicodec/codec-v4l2-fwht.c | 122 |
1 files changed, 92 insertions, 30 deletions
diff --git a/drivers/media/platform/vicodec/codec-v4l2-fwht.c b/drivers/media/platform/vicodec/codec-v4l2-fwht.c index e5b68fb38aac..8cb0212df67f 100644 --- a/drivers/media/platform/vicodec/codec-v4l2-fwht.c +++ b/drivers/media/platform/vicodec/codec-v4l2-fwht.c @@ -11,27 +11,30 @@ #include "codec-v4l2-fwht.h" static const struct v4l2_fwht_pixfmt_info v4l2_fwht_pixfmts[] = { - { V4L2_PIX_FMT_YUV420, 1, 3, 2, 1, 1, 2, 2 }, - { V4L2_PIX_FMT_YVU420, 1, 3, 2, 1, 1, 2, 2 }, - { V4L2_PIX_FMT_YUV422P, 1, 2, 1, 1, 1, 2, 1 }, - { V4L2_PIX_FMT_NV12, 1, 3, 2, 1, 2, 2, 2 }, - { V4L2_PIX_FMT_NV21, 1, 3, 2, 1, 2, 2, 2 }, - { V4L2_PIX_FMT_NV16, 1, 2, 1, 1, 2, 2, 1 }, - { V4L2_PIX_FMT_NV61, 1, 2, 1, 1, 2, 2, 1 }, - { V4L2_PIX_FMT_NV24, 1, 3, 1, 1, 2, 1, 1 }, - { V4L2_PIX_FMT_NV42, 1, 3, 1, 1, 2, 1, 1 }, - { V4L2_PIX_FMT_YUYV, 2, 2, 1, 2, 4, 2, 1 }, - { V4L2_PIX_FMT_YVYU, 2, 2, 1, 2, 4, 2, 1 }, - { V4L2_PIX_FMT_UYVY, 2, 2, 1, 2, 4, 2, 1 }, - { V4L2_PIX_FMT_VYUY, 2, 2, 1, 2, 4, 2, 1 }, - { V4L2_PIX_FMT_BGR24, 3, 3, 1, 3, 3, 1, 1 }, - { V4L2_PIX_FMT_RGB24, 3, 3, 1, 3, 3, 1, 1 }, - { V4L2_PIX_FMT_HSV24, 3, 3, 1, 3, 3, 1, 1 }, - { V4L2_PIX_FMT_BGR32, 4, 4, 1, 4, 4, 1, 1 }, - { V4L2_PIX_FMT_XBGR32, 4, 4, 1, 4, 4, 1, 1 }, - { V4L2_PIX_FMT_RGB32, 4, 4, 1, 4, 4, 1, 1 }, - { V4L2_PIX_FMT_XRGB32, 4, 4, 1, 4, 4, 1, 1 }, - { V4L2_PIX_FMT_HSV32, 4, 4, 1, 4, 4, 1, 1 }, + { V4L2_PIX_FMT_YUV420, 1, 3, 2, 1, 1, 2, 2, 3}, + { V4L2_PIX_FMT_YVU420, 1, 3, 2, 1, 1, 2, 2, 3}, + { V4L2_PIX_FMT_YUV422P, 1, 2, 1, 1, 1, 2, 1, 3}, + { V4L2_PIX_FMT_NV12, 1, 3, 2, 1, 2, 2, 2, 3}, + { V4L2_PIX_FMT_NV21, 1, 3, 2, 1, 2, 2, 2, 3}, + { V4L2_PIX_FMT_NV16, 1, 2, 1, 1, 2, 2, 1, 3}, + { V4L2_PIX_FMT_NV61, 1, 2, 1, 1, 2, 2, 1, 3}, + { V4L2_PIX_FMT_NV24, 1, 3, 1, 1, 2, 1, 1, 3}, + { V4L2_PIX_FMT_NV42, 1, 3, 1, 1, 2, 1, 1, 3}, + { V4L2_PIX_FMT_YUYV, 2, 2, 1, 2, 4, 2, 1, 3}, + { V4L2_PIX_FMT_YVYU, 2, 2, 1, 2, 4, 2, 1, 3}, + { V4L2_PIX_FMT_UYVY, 2, 2, 1, 2, 4, 2, 1, 3}, + { V4L2_PIX_FMT_VYUY, 2, 2, 1, 2, 4, 2, 1, 3}, + { V4L2_PIX_FMT_BGR24, 3, 3, 1, 3, 3, 1, 1, 3}, + { V4L2_PIX_FMT_RGB24, 3, 3, 1, 3, 3, 1, 1, 3}, + { V4L2_PIX_FMT_HSV24, 3, 3, 1, 3, 3, 1, 1, 3}, + { V4L2_PIX_FMT_BGR32, 4, 4, 1, 4, 4, 1, 1, 3}, + { V4L2_PIX_FMT_XBGR32, 4, 4, 1, 4, 4, 1, 1, 3}, + { V4L2_PIX_FMT_RGB32, 4, 4, 1, 4, 4, 1, 1, 3}, + { V4L2_PIX_FMT_XRGB32, 4, 4, 1, 4, 4, 1, 1, 3}, + { V4L2_PIX_FMT_HSV32, 4, 4, 1, 4, 4, 1, 1, 3}, + { V4L2_PIX_FMT_ARGB32, 4, 4, 1, 4, 4, 1, 1, 4}, + { V4L2_PIX_FMT_ABGR32, 4, 4, 1, 4, 4, 1, 1, 4}, + { V4L2_PIX_FMT_GREY, 1, 1, 1, 1, 0, 1, 1, 1}, }; const struct v4l2_fwht_pixfmt_info *v4l2_fwht_find_pixfmt(u32 pixelformat) @@ -68,10 +71,16 @@ int v4l2_fwht_encode(struct v4l2_fwht_state *state, u8 *p_in, u8 *p_out) rf.luma = p_in; rf.width_div = info->width_div; rf.height_div = info->height_div; - rf.luma_step = info->luma_step; + rf.luma_alpha_step = info->luma_alpha_step; rf.chroma_step = info->chroma_step; + rf.alpha = NULL; + rf.components_num = info->components_num; switch (info->id) { + case V4L2_PIX_FMT_GREY: + rf.cb = NULL; + rf.cr = NULL; + break; case V4L2_PIX_FMT_YUV420: rf.cb = rf.luma + size; rf.cr = rf.cb + size / 4; @@ -138,6 +147,18 @@ int v4l2_fwht_encode(struct v4l2_fwht_state *state, u8 *p_in, u8 *p_out) rf.cr = rf.cb + 2; rf.luma++; break; + case V4L2_PIX_FMT_ARGB32: + rf.alpha = rf.luma; + rf.cr = rf.luma + 1; + rf.cb = rf.cr + 2; + rf.luma += 2; + break; + case V4L2_PIX_FMT_ABGR32: + rf.cb = rf.luma; + rf.cr = rf.cb + 2; + rf.luma++; + rf.alpha = rf.cr + 1; + break; default: return -EINVAL; } @@ -162,12 +183,15 @@ int v4l2_fwht_encode(struct v4l2_fwht_state *state, u8 *p_in, u8 *p_out) p_hdr->version = htonl(FWHT_VERSION); p_hdr->width = htonl(cf.width); p_hdr->height = htonl(cf.height); + flags |= (info->components_num - 1) << FWHT_FL_COMPONENTS_NUM_OFFSET; if (encoding & FWHT_LUMA_UNENCODED) flags |= FWHT_FL_LUMA_IS_UNCOMPRESSED; if (encoding & FWHT_CB_UNENCODED) flags |= FWHT_FL_CB_IS_UNCOMPRESSED; if (encoding & FWHT_CR_UNENCODED) flags |= FWHT_FL_CR_IS_UNCOMPRESSED; + if (encoding & FWHT_ALPHA_UNENCODED) + flags |= FWHT_FL_ALPHA_IS_UNCOMPRESSED; if (rf.height_div == 1) flags |= FWHT_FL_CHROMA_FULL_HEIGHT; if (rf.width_div == 1) @@ -192,6 +216,8 @@ int v4l2_fwht_decode(struct v4l2_fwht_state *state, u8 *p_in, u8 *p_out) struct fwht_cframe_hdr *p_hdr; struct fwht_cframe cf; u8 *p; + unsigned int components_num = 3; + unsigned int version; if (!state->info) return -EINVAL; @@ -199,16 +225,16 @@ int v4l2_fwht_decode(struct v4l2_fwht_state *state, u8 *p_in, u8 *p_out) p_hdr = (struct fwht_cframe_hdr *)p_in; cf.width = ntohl(p_hdr->width); cf.height = ntohl(p_hdr->height); - flags = ntohl(p_hdr->flags); - state->colorspace = ntohl(p_hdr->colorspace); - state->xfer_func = ntohl(p_hdr->xfer_func); - state->ycbcr_enc = ntohl(p_hdr->ycbcr_enc); - state->quantization = ntohl(p_hdr->quantization); - cf.rlc_data = (__be16 *)(p_in + sizeof(*p_hdr)); + + version = ntohl(p_hdr->version); + if (!version || version > FWHT_VERSION) { + pr_err("version %d is not supported, current version is %d\n", + version, FWHT_VERSION); + return -EINVAL; + } if (p_hdr->magic1 != FWHT_MAGIC1 || p_hdr->magic2 != FWHT_MAGIC2 || - ntohl(p_hdr->version) != FWHT_VERSION || (cf.width & 7) || (cf.height & 7)) return -EINVAL; @@ -216,14 +242,34 @@ int v4l2_fwht_decode(struct v4l2_fwht_state *state, u8 *p_in, u8 *p_out) if (cf.width != state->width || cf.height != state->height) return -EINVAL; + flags = ntohl(p_hdr->flags); + + if (version == FWHT_VERSION) { + components_num = 1 + ((flags & FWHT_FL_COMPONENTS_NUM_MSK) >> + FWHT_FL_COMPONENTS_NUM_OFFSET); + } + + state->colorspace = ntohl(p_hdr->colorspace); + state->xfer_func = ntohl(p_hdr->xfer_func); + state->ycbcr_enc = ntohl(p_hdr->ycbcr_enc); + state->quantization = ntohl(p_hdr->quantization); + cf.rlc_data = (__be16 *)(p_in + sizeof(*p_hdr)); + if (!(flags & FWHT_FL_CHROMA_FULL_WIDTH)) chroma_size /= 2; if (!(flags & FWHT_FL_CHROMA_FULL_HEIGHT)) chroma_size /= 2; - fwht_decode_frame(&cf, &state->ref_frame, flags); + fwht_decode_frame(&cf, &state->ref_frame, flags, components_num); + /* + * TODO - handle the case where the compressed stream encodes a + * different format than the requested decoded format. + */ switch (state->info->id) { + case V4L2_PIX_FMT_GREY: + memcpy(p_out, state->ref_frame.luma, size); + break; case V4L2_PIX_FMT_YUV420: case V4L2_PIX_FMT_YUV422P: memcpy(p_out, state->ref_frame.luma, size); @@ -325,6 +371,22 @@ int v4l2_fwht_decode(struct v4l2_fwht_state *state, u8 *p_in, u8 *p_out) *p++ = 0; } break; + case V4L2_PIX_FMT_ARGB32: + for (i = 0, p = p_out; i < size; i++) { + *p++ = state->ref_frame.alpha[i]; + *p++ = state->ref_frame.cr[i]; + *p++ = state->ref_frame.luma[i]; + *p++ = state->ref_frame.cb[i]; + } + break; + case V4L2_PIX_FMT_ABGR32: + for (i = 0, p = p_out; i < size; i++) { + *p++ = state->ref_frame.cb[i]; + *p++ = state->ref_frame.luma[i]; + *p++ = state->ref_frame.cr[i]; + *p++ = state->ref_frame.alpha[i]; + } + break; default: return -EINVAL; } |