diff options
-rw-r--r-- | contrib/freebsd/include/linux/videodev2.h | 1 | ||||
-rw-r--r-- | include/linux/videodev2.h | 1 | ||||
-rw-r--r-- | utils/common/codec-fwht.c | 84 | ||||
-rw-r--r-- | utils/common/codec-fwht.h | 19 | ||||
-rw-r--r-- | utils/common/codec-fwht.patch | 12 | ||||
-rw-r--r-- | utils/common/codec-v4l2-fwht.c | 123 | ||||
-rw-r--r-- | utils/common/codec-v4l2-fwht.h | 3 | ||||
-rw-r--r-- | utils/common/v4l2-tpg-core.c | 2 |
8 files changed, 175 insertions, 70 deletions
diff --git a/contrib/freebsd/include/linux/videodev2.h b/contrib/freebsd/include/linux/videodev2.h index 9928c00e..33153b53 100644 --- a/contrib/freebsd/include/linux/videodev2.h +++ b/contrib/freebsd/include/linux/videodev2.h @@ -907,6 +907,7 @@ struct v4l2_requestbuffers { #define V4L2_BUF_CAP_SUPPORTS_USERPTR (1 << 1) #define V4L2_BUF_CAP_SUPPORTS_DMABUF (1 << 2) #define V4L2_BUF_CAP_SUPPORTS_REQUESTS (1 << 3) +#define V4L2_BUF_CAP_SUPPORTS_ORPHANED_BUFS (1 << 4) /** * struct v4l2_plane - plane info for multi-planar buffers diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h index 79418cd3..a39300ca 100644 --- a/include/linux/videodev2.h +++ b/include/linux/videodev2.h @@ -873,6 +873,7 @@ struct v4l2_requestbuffers { #define V4L2_BUF_CAP_SUPPORTS_USERPTR (1 << 1) #define V4L2_BUF_CAP_SUPPORTS_DMABUF (1 << 2) #define V4L2_BUF_CAP_SUPPORTS_REQUESTS (1 << 3) +#define V4L2_BUF_CAP_SUPPORTS_ORPHANED_BUFS (1 << 4) /** * struct v4l2_plane - plane info for multi-planar buffers diff --git a/utils/common/codec-fwht.c b/utils/common/codec-fwht.c index 36656031..5630f1dc 100644 --- a/utils/common/codec-fwht.c +++ b/utils/common/codec-fwht.c @@ -753,31 +753,49 @@ u32 fwht_encode_frame(struct fwht_raw_frame *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, - frm->luma_step, is_intra, next_is_intra); + frm->luma_alpha_step, is_intra, next_is_intra); if (encoding & FWHT_FRAME_UNENCODED) encoding |= FWHT_LUMA_UNENCODED; encoding &= ~FWHT_FRAME_UNENCODED; - rlco_max = rlco + chroma_size / 2 - 256; - encoding |= encode_plane(frm->cb, ref_frm->cb, &rlco, rlco_max, cf, - chroma_h, chroma_w, - frm->chroma_step, is_intra, next_is_intra); - if (encoding & FWHT_FRAME_UNENCODED) - encoding |= FWHT_CB_UNENCODED; - encoding &= ~FWHT_FRAME_UNENCODED; - rlco_max = rlco + chroma_size / 2 - 256; - encoding |= encode_plane(frm->cr, ref_frm->cr, &rlco, rlco_max, cf, - chroma_h, chroma_w, - frm->chroma_step, is_intra, next_is_intra); - if (encoding & FWHT_FRAME_UNENCODED) - encoding |= FWHT_CR_UNENCODED; - encoding &= ~FWHT_FRAME_UNENCODED; + + if (frm->components_num >= 3) { + 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 + chroma_size / 2 - 256; + encoding |= encode_plane(frm->cb, ref_frm->cb, &rlco, rlco_max, + cf, chroma_h, chroma_w, + frm->chroma_step, + is_intra, next_is_intra); + if (encoding & FWHT_FRAME_UNENCODED) + encoding |= FWHT_CB_UNENCODED; + encoding &= ~FWHT_FRAME_UNENCODED; + rlco_max = rlco + chroma_size / 2 - 256; + encoding |= encode_plane(frm->cr, ref_frm->cr, &rlco, rlco_max, + cf, chroma_h, chroma_w, + frm->chroma_step, + is_intra, next_is_intra); + if (encoding & FWHT_FRAME_UNENCODED) + encoding |= FWHT_CR_UNENCODED; + encoding &= ~FWHT_FRAME_UNENCODED; + } + + if (frm->components_num == 4) { + rlco_max = rlco + size / 2 - 256; + encoding = encode_plane(frm->alpha, ref_frm->alpha, &rlco, + rlco_max, cf, frm->height, frm->width, + frm->luma_alpha_step, + is_intra, next_is_intra); + if (encoding & FWHT_FRAME_UNENCODED) + encoding |= FWHT_ALPHA_UNENCODED; + encoding &= ~FWHT_FRAME_UNENCODED; + } + cf->size = (rlco - cf->rlc_data) * sizeof(*rlco); return encoding; } @@ -836,20 +854,28 @@ static void decode_plane(struct fwht_cframe *cf, const __be16 **rlco, u8 *ref, } void fwht_decode_frame(struct fwht_cframe *cf, struct fwht_raw_frame *ref, - u32 hdr_flags) + u32 hdr_flags, unsigned int components_num) { const __be16 *rlco = cf->rlc_data; - u32 h = cf->height / 2; - u32 w = cf->width / 2; - if (hdr_flags & FWHT_FL_CHROMA_FULL_HEIGHT) - h *= 2; - if (hdr_flags & FWHT_FL_CHROMA_FULL_WIDTH) - w *= 2; decode_plane(cf, &rlco, ref->luma, cf->height, cf->width, hdr_flags & FWHT_FL_LUMA_IS_UNCOMPRESSED); - decode_plane(cf, &rlco, ref->cb, h, w, - hdr_flags & FWHT_FL_CB_IS_UNCOMPRESSED); - decode_plane(cf, &rlco, ref->cr, h, w, - hdr_flags & FWHT_FL_CR_IS_UNCOMPRESSED); + + if (components_num >= 3) { + u32 h = cf->height; + u32 w = cf->width; + + if (!(hdr_flags & FWHT_FL_CHROMA_FULL_HEIGHT)) + h /= 2; + if (!(hdr_flags & FWHT_FL_CHROMA_FULL_WIDTH)) + w /= 2; + decode_plane(cf, &rlco, ref->cb, h, w, + hdr_flags & FWHT_FL_CB_IS_UNCOMPRESSED); + decode_plane(cf, &rlco, ref->cr, h, w, + hdr_flags & FWHT_FL_CR_IS_UNCOMPRESSED); + } + + if (components_num == 4) + decode_plane(cf, &rlco, ref->alpha, cf->height, cf->width, + hdr_flags & FWHT_FL_ALPHA_IS_UNCOMPRESSED); } diff --git a/utils/common/codec-fwht.h b/utils/common/codec-fwht.h index f7da2b84..7de5f203 100644 --- a/utils/common/codec-fwht.h +++ b/utils/common/codec-fwht.h @@ -16,6 +16,10 @@ #define BIT(x) (1 << (x)) #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) +#define GENMASK(h, l) \ + (((~0UL) - (1UL << (l)) + 1) & (~0UL >> ((8 * sizeof(long)) - 1 - (h)))) +#define pr_err(arg...) + typedef __u32 u32; typedef __u16 u16; @@ -68,7 +72,7 @@ typedef __u8 u8; #define FWHT_MAGIC1 0x4f4f4f4f #define FWHT_MAGIC2 0xffffffff -#define FWHT_VERSION 1 +#define FWHT_VERSION 2 /* Set if this is an interlaced format */ #define FWHT_FL_IS_INTERLACED BIT(0) @@ -87,6 +91,11 @@ typedef __u8 u8; #define FWHT_FL_CR_IS_UNCOMPRESSED BIT(6) #define FWHT_FL_CHROMA_FULL_HEIGHT BIT(7) #define FWHT_FL_CHROMA_FULL_WIDTH BIT(8) +#define FWHT_FL_ALPHA_IS_UNCOMPRESSED BIT(9) + +/* A 4-values flag - the number of components - 1 */ +#define FWHT_FL_COMPONENTS_NUM_MSK GENMASK(17, 16) +#define FWHT_FL_COMPONENTS_NUM_OFFSET 16 struct fwht_cframe_hdr { u32 magic1; @@ -116,9 +125,10 @@ struct fwht_raw_frame { unsigned int width, height; unsigned int width_div; unsigned int height_div; - unsigned int luma_step; + unsigned int luma_alpha_step; unsigned int chroma_step; - u8 *luma, *cb, *cr; + unsigned int components_num; + u8 *luma, *cb, *cr, *alpha; }; #define FWHT_FRAME_PCODED BIT(0) @@ -126,12 +136,13 @@ struct fwht_raw_frame { #define FWHT_LUMA_UNENCODED BIT(2) #define FWHT_CB_UNENCODED BIT(3) #define FWHT_CR_UNENCODED BIT(4) +#define FWHT_ALPHA_UNENCODED BIT(5) u32 fwht_encode_frame(struct fwht_raw_frame *frm, struct fwht_raw_frame *ref_frm, struct fwht_cframe *cf, bool is_intra, bool next_is_intra); void fwht_decode_frame(struct fwht_cframe *cf, struct fwht_raw_frame *ref, - u32 hdr_flags); + u32 hdr_flags, unsigned int components_num); #endif diff --git a/utils/common/codec-fwht.patch b/utils/common/codec-fwht.patch index 95606bfd..4d41225b 100644 --- a/utils/common/codec-fwht.patch +++ b/utils/common/codec-fwht.patch @@ -1,8 +1,6 @@ -diff --git a/utils/common/codec-fwht.h b/utils/common/codec-fwht.h -index cdfad133..51fd147c 100644 ---- a/utils/common/codec-fwht.h -+++ b/utils/common/codec-fwht.h -@@ -8,8 +8,20 @@ +--- a/utils/common/codec-fwht.h.old 2018-11-23 13:43:52.713731559 +0100 ++++ b/utils/common/codec-fwht.h 2018-11-23 13:47:55.484198283 +0100 +@@ -8,8 +8,24 @@ #define CODEC_FWHT_H #include <linux/types.h> @@ -16,6 +14,10 @@ index cdfad133..51fd147c 100644 + +#define BIT(x) (1 << (x)) +#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) ++#define GENMASK(h, l) \ ++ (((~0UL) - (1UL << (l)) + 1) & (~0UL >> ((8 * sizeof(long)) - 1 - (h)))) ++#define pr_err(arg...) ++ + +typedef __u32 u32; +typedef __u16 u16; diff --git a/utils/common/codec-v4l2-fwht.c b/utils/common/codec-v4l2-fwht.c index e5b68fb3..ac5bb683 100644 --- a/utils/common/codec-v4l2-fwht.c +++ b/utils/common/codec-v4l2-fwht.c @@ -11,27 +11,31 @@ #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_GREY, 1, 1, 1, 1, 0, 1, 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}, + }; const struct v4l2_fwht_pixfmt_info *v4l2_fwht_find_pixfmt(u32 pixelformat) @@ -68,10 +72,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 +148,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 +184,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 +217,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 +226,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 +243,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 +372,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; } diff --git a/utils/common/codec-v4l2-fwht.h b/utils/common/codec-v4l2-fwht.h index 162465b7..ed53e28d 100644 --- a/utils/common/codec-v4l2-fwht.h +++ b/utils/common/codec-v4l2-fwht.h @@ -13,11 +13,12 @@ struct v4l2_fwht_pixfmt_info { unsigned int bytesperline_mult; unsigned int sizeimage_mult; unsigned int sizeimage_div; - unsigned int luma_step; + unsigned int luma_alpha_step; unsigned int chroma_step; /* Chroma plane subsampling */ unsigned int width_div; unsigned int height_div; + unsigned int components_num; }; struct v4l2_fwht_state { diff --git a/utils/common/v4l2-tpg-core.c b/utils/common/v4l2-tpg-core.c index 51e13809..f7311c97 100644 --- a/utils/common/v4l2-tpg-core.c +++ b/utils/common/v4l2-tpg-core.c @@ -1758,7 +1758,7 @@ typedef struct { u16 __; u8 _; } __packed x24; unsigned s; \ \ for (s = 0; s < len; s++) { \ - u8 chr = font8x16[text[s] * 16 + line]; \ + u8 chr = font8x16[(u8)text[s] * 16 + line]; \ \ if (hdiv == 2 && tpg->hflip) { \ pos[3] = (chr & (0x01 << 6) ? fg : bg); \ |