media: vicodec: add support for CROP and COMPOSE selection
PATCH v3 1/1 media: vicodec: add support for CROP and COMPOSE selection
Add support for the selection api for the crop and compose targets. The driver rounds up the coded width and height such that all planes dimensions are multiple of 8.
Signed-off-by Dafna Hirschfeld <[email protected]>
---
Main Changes from v2:
Add support for compose selection.
Rename the width/height fields of q_data to coded_width/height
they contain the rounded w/h calculated with vic_round_up macro.
Rename 'stride' field/variable to 'coded_width' since this is what is actually contain. visible_width/height are the values given from either crop or compose.
drivers/media/platform/vicodec/codec-fwht.c | 92 ++++++----- drivers/media/platform/vicodec/codec-fwht.h | 15 +- .../media/platform/vicodec/codec-v4l2-fwht.c | 36 ++--- .../media/platform/vicodec/codec-v4l2-fwht.h | 6 +- drivers/media/platform/vicodec/vicodec-core.c | 146 ++++++++++++++---- 5 files changed, 200 insertions(+), 95 deletions(-)
drivers/media/platform/vicodec/codec-fwht.c +52 -40
@@ -11,6 +11,7 @@#include <linux/string.h> #include "codec-fwht.h" +#include <linux/kernel.h> /* * Note: bit 0 of the header must always be 0. Otherwise it cannot
@@ -226,7 +227,7 @@ static void dequantize_inter(s16 *coeff) *coeff <<= *quant; } -static void fwht (const u8 *block,s16 *output_block,unsigned int stride, +static void fwht (const u8 *block,s16 *output_block,unsigned int coded_width,unsigned int input_step,bool intra) {/* we'll need more than 8 bits for the transformed coefficients */
@@ -237,9 +238,9 @@ static void fwht(const u8 *block, s16 *output_block, unsigned int stride,unsigned int i;/* stage 1 */ - stride *= input_step; + coded_width *= input_step; -for (i =0 ; i <8 ; i++, tmp += stride, out +=8 ) { +for (i =0 ; i <8 ; i++, tmp += coded_width, out +=8 ) {switch (input_step) {case 1 : workspace1[0 ] = tmp[0 ] + tmp[1 ] - add;
@@ -361,7 +362,7 @@ static void fwht(const u8 *block, s16 *output_block, unsigned int stride,* Furthermore values can be negative... This is just a version that * works with 16 signed data */ -static void fwht16 (const s16 *block,s16 *output_block,int stride,int intra) +static void fwht16 (const s16 *block,s16 *output_block,int coded_width,int intra) {/* we'll need more than 8 bits for the transformed coefficients */ s32 workspace1[8 ], workspace2[8 ];
@@ -369,7 +370,7 @@ static void fwht16(const s16 *block, s16 *output_block, int stride, int intra)s16 *out = output_block;int i; -for (i =0 ; i <8 ; i++, tmp += stride, out +=8 ) { +for (i =0 ; i <8 ; i++, tmp += coded_width, out +=8 ) {/* stage 1 */ workspace1[0 ] = tmp[0 ] + tmp[1 ]; workspace1[1 ] = tmp[0 ] - tmp[1 ];
@@ -555,14 +556,14 @@ static void ifwht(const s16 *block, s16 *output_block, int intra) }static void fill_encoder_block (const u8 *input,s16 *dst, -unsigned int stride,unsigned int input_step) +unsigned int coded_width,unsigned int input_step) {int i, j;for (i =0 ; i <8 ; i++) {for (j =0 ; j <8 ; j++, input += input_step) *dst++ = *input; - input += (stride -8 ) * input_step; + input += (coded_width -8 ) * input_step; } }
@@ -593,7 +594,7 @@ static int var_inter(const s16 *old, const s16 *new) }static int decide_blocktype (const u8 *cur,const u8 *reference, -s16 *deltablock,unsigned int stride, +s16 *deltablock,unsigned int coded_width,unsigned int input_step) {s16 tmp[64 ];
@@ -603,7 +604,7 @@ static int decide_blocktype(const u8 *cur, const u8 *reference,int vari;int vard; -fill_encoder_block (cur, tmp, stride, input_step); +fill_encoder_block (cur, tmp, coded_width, input_step);fill_encoder_block (reference, old,8 ,1 ); vari =var_intra (tmp);
@@ -620,7 +621,7 @@ static int decide_blocktype(const u8 *cur, const u8 *reference,return vari <= vard ?IBLOCK :PBLOCK ; } -static void fill_decoder_block (u8 *dst,const s16 *input,int stride) +static void fill_decoder_block (u8 *dst,const s16 *input,int coded_width) {int i, j;
@@ -633,11 +634,11 @@ static void fill_decoder_block(u8 *dst, const s16 *input, int stride)else *dst = *input; } - dst += stride -8 ; + dst += coded_width -8 ; } } -static void add_deltas (s16 *deltas,const u8 *ref,int stride) +static void add_deltas (s16 *deltas,const u8 *ref,int coded_width) {int k, l;
@@ -654,12 +655,12 @@ static void add_deltas(s16 *deltas, const u8 *ref, int stride) *deltas =255 ; deltas++; } - ref += stride -8 ; + ref += coded_width -8 ; } }static u32 encode_plane (u8 *input,u8 *refp,__be16 **rlco,__be16 *rlco_max, -struct fwht_cframe *cf,u32 height,u32 width, +struct fwht_cframe *cf,u32 height,u32 width,u32 coded_width,unsigned int input_step,bool is_intra,bool next_is_intra) {
@@ -671,7 +672,11 @@ static u32 encode_plane(u8 *input, u8 *refp, __be16 **rlco, __be16 *rlco_max,unsigned int last_size =0 ;unsigned int i, j; + width =round_up (width,8 ); + height =round_up (height,8 ); +for (j =0 ; j < height /8 ; j++) { + input = input_start + j *8 * coded_width * input_step;for (i =0 ; i < width /8 ; i++) {/* intra code, first frame is always intra coded. */ int blocktype =IBLOCK ;
@@ -679,9 +684,9 @@ static u32 encode_plane(u8 *input, u8 *refp, __be16 **rlco, __be16 *rlco_max,if (!is_intra) blocktype =decide_blocktype (input, refp, - deltablock, width, input_step); + deltablock, coded_width, input_step);if (blocktype ==IBLOCK ) { -fwht (input, cf->coeffs, width, input_step,1 ); +fwht (input, cf->coeffs, coded_width, input_step,1 );quantize_intra (cf->coeffs, cf->de_coeffs, cf->i_frame_qp); }else {
@@ -722,7 +727,6 @@ static u32 encode_plane(u8 *input, u8 *refp, __be16 **rlco, __be16 *rlco_max, } last_size = size; } - input += width *7 * input_step; } exit_loop:
@@ -747,29 +751,31 @@ static u32 encode_plane(u8 *input, u8 *refp, __be16 **rlco, __be16 *rlco_max,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) +bool is_intra,bool next_is_intra, +unsigned int width,unsigned int height) { -unsigned int size = frm->height * frm->width; +unsigned int size = height * width;__be16 *rlco = cf->rlc_data;__be16 *rlco_max;u32 encoding; rlco_max = rlco + size /2 -256 ; encoding =encode_plane (frm->luma, ref_frm->luma, &rlco, rlco_max, cf, - frm->height, frm->width, + height, width, frm->coded_width, frm->luma_alpha_step, is_intra, next_is_intra);if (encoding &FWHT_FRAME_UNENCODED ) encoding |=FWHT_LUMA_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; +u32 chroma_h = height / frm->height_div; +u32 chroma_w = width / frm->width_div; +u32 chroma_coded_width = frm->coded_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, + cf, chroma_h, chroma_w, chroma_coded_width, frm->chroma_step, is_intra, next_is_intra);if (encoding &FWHT_FRAME_UNENCODED )
@@ -777,7 +783,7 @@ u32 fwht_encode_frame(struct fwht_raw_frame *frm, 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, + cf, chroma_h, chroma_w, chroma_coded_width, frm->chroma_step, is_intra, next_is_intra);if (encoding &FWHT_FRAME_UNENCODED )
@@ -788,8 +794,8 @@ u32 fwht_encode_frame(struct fwht_raw_frame *frm,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, + rlco_max, cf, height, width, + frm->coded_width, frm->luma_alpha_step, is_intra, next_is_intra);if (encoding &FWHT_FRAME_UNENCODED ) encoding |=FWHT_ALPHA_UNENCODED ;
@@ -801,7 +807,7 @@ u32 fwht_encode_frame(struct fwht_raw_frame *frm, }static void decode_plane (struct fwht_cframe *cf,const __be16 **rlco,u8 *ref, -u32 height,u32 width,bool uncompressed) +u32 height,u32 width,u32 coded_width,bool uncompressed) {unsigned int copies =0 ;s16 copy[8 *8 ];
@@ -813,6 +819,8 @@ static void decode_plane(struct fwht_cframe *cf, const __be16 **rlco, u8 *ref, *rlco += width * height /2 ;return ; } + width =round_up (width,8 ); + height =round_up (height,8 );/* * When decoding each macroblock the rlco pointer will be increased
@@ -822,13 +830,13 @@ static void decode_plane(struct fwht_cframe *cf, const __be16 **rlco, u8 *ref,*/ for (j =0 ; j < height /8 ; j++) {for (i =0 ; i < width /8 ; i++) { -u8 *refp = ref + j *8 * width + i *8 ; +u8 *refp = ref + j *8 * coded_width + i *8 ;if (copies) {memcpy (cf->de_fwht, copy,sizeof (copy));if (stat &PFRAME_BIT ) -add_deltas (cf->de_fwht, refp, width); -fill_decoder_block (refp, cf->de_fwht, width); +add_deltas (cf->de_fwht, refp, coded_width); +fill_decoder_block (refp, cf->de_fwht, coded_width); copies--;continue ; }
@@ -847,35 +855,39 @@ static void decode_plane(struct fwht_cframe *cf, const __be16 **rlco, u8 *ref,if (copies)memcpy (copy, cf->de_fwht,sizeof (copy));if (stat &PFRAME_BIT ) -add_deltas (cf->de_fwht, refp, width); -fill_decoder_block (refp, cf->de_fwht, width); +add_deltas (cf->de_fwht, refp, coded_width); +fill_decoder_block (refp, cf->de_fwht, coded_width); } } }void fwht_decode_frame (struct fwht_cframe *cf,struct fwht_raw_frame *ref, -u32 hdr_flags,unsigned int components_num) +u32 hdr_flags,unsigned int components_num, +unsigned int width,unsigned int height,unsigned int coded_width) {const __be16 *rlco = cf->rlc_data; -decode_plane (cf, &rlco, ref->luma, cf->height, cf->width, +decode_plane (cf, &rlco, ref->luma, height, width, coded_width, hdr_flags &FWHT_FL_LUMA_IS_UNCOMPRESSED );if (components_num >=3 ) { -u32 h = cf->height; -u32 w = cf->width; +u32 h = height; +u32 w = width; +u32 c = coded_width;if (!(hdr_flags &FWHT_FL_CHROMA_FULL_HEIGHT )) h /=2 ; -if (!(hdr_flags &FWHT_FL_CHROMA_FULL_WIDTH )) +if (!(hdr_flags &FWHT_FL_CHROMA_FULL_WIDTH )) { w /=2 ; -decode_plane (cf, &rlco, ref->cb, h, w, + c /=2 ; + } +decode_plane (cf, &rlco, ref->cb, h, w, c, hdr_flags &FWHT_FL_CB_IS_UNCOMPRESSED ); -decode_plane (cf, &rlco, ref->cr, h, w, +decode_plane (cf, &rlco, ref->cr, h, w, c, hdr_flags &FWHT_FL_CR_IS_UNCOMPRESSED ); }if (components_num ==4 ) -decode_plane (cf, &rlco, ref->alpha, cf->height, cf->width, +decode_plane (cf, &rlco, ref->alpha, height, width, coded_width, hdr_flags &FWHT_FL_ALPHA_IS_UNCOMPRESSED ); }
drivers/media/platform/vicodec/codec-fwht.h +11 -4
@@ -81,6 +81,12 @@#define FWHT_FL_COMPONENTS_NUM_MSK GENMASK(17, 16)#define FWHT_FL_COMPONENTS_NUM_OFFSET 16 +/* A macro to calculate the needed padding in order to make sure +* both luma and chroma components resolutions are rounded up to +* closest multiple of 8 +*/ +#define vic_round_dim (dim, div) (round_up((dim) / (div), 8) * (div)) +struct fwht_cframe_hdr {u32 magic1;u32 magic2;
@@ -95,7 +101,6 @@ struct fwht_cframe_hdr { };struct fwht_cframe { -unsigned int width, height;u16 i_frame_qp;u16 p_frame_qp;__be16 *rlc_data;
@@ -106,12 +111,12 @@ struct fwht_cframe { };struct fwht_raw_frame { -unsigned int width, height;unsigned int width_div;unsigned int height_div;unsigned int luma_alpha_step;unsigned int chroma_step;unsigned int components_num; +unsigned int coded_width;u8 *luma, *cb, *cr, *alpha; };
@@ -125,8 +130,10 @@ struct fwht_raw_frame {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); +bool is_intra,bool next_is_intra, +unsigned int width,unsigned int height);void fwht_decode_frame (struct fwht_cframe *cf,struct fwht_raw_frame *ref, -u32 hdr_flags,unsigned int components_num); +u32 hdr_flags,unsigned int components_num, +unsigned int width,unsigned int height,unsigned int coded_width);#endif
drivers/media/platform/vicodec/codec-v4l2-fwht.c +18 -18
@@ -56,7 +56,7 @@ const struct v4l2_fwht_pixfmt_info *v4l2_fwht_get_pixfmt(u32 idx)int v4l2_fwht_encode (struct v4l2_fwht_state *state,u8 *p_in,u8 *p_out) { -unsigned int size = state->width * state->height; +unsigned int size;const struct v4l2_fwht_pixfmt_info *info = state->info;struct fwht_cframe_hdr *p_hdr;struct fwht_cframe cf;
@@ -66,8 +66,9 @@ int v4l2_fwht_encode(struct v4l2_fwht_state *state, u8 *p_in, u8 *p_out)if (!info)return -EINVAL ; - rf.width = state->width; - rf.height = state->height; + + size = state->coded_width * state->coded_height; + rf.coded_width = state->coded_width; rf.luma = p_in; rf.width_div = info->width_div; rf.height_div = info->height_div;
@@ -163,15 +164,14 @@ int v4l2_fwht_encode(struct v4l2_fwht_state *state, u8 *p_in, u8 *p_out)return -EINVAL ; } - cf.width = state->width; - cf.height = state->height; cf.i_frame_qp = state->i_frame_qp; cf.p_frame_qp = state->p_frame_qp; cf.rlc_data = (__be16 *)(p_out +sizeof (*p_hdr)); encoding =fwht_encode_frame (&rf, &state->ref_frame, &cf, !state->gop_cnt, - state->gop_cnt == state->gop_size -1 ); + state->gop_cnt == state->gop_size -1 , + state->visible_width, state->visible_height);if (!(encoding &FWHT_FRAME_PCODED )) state->gop_cnt =0 ;if (++state->gop_cnt >= state->gop_size)
@@ -181,8 +181,8 @@ int v4l2_fwht_encode(struct v4l2_fwht_state *state, u8 *p_in, u8 *p_out) p_hdr->magic1 =FWHT_MAGIC1 ; p_hdr->magic2 =FWHT_MAGIC2 ; p_hdr->version =htonl (FWHT_VERSION ); - p_hdr->width =htonl (cf.width); - p_hdr->height =htonl (cf.height); + p_hdr->width =htonl (state->visible_width); + p_hdr->height =htonl (state->visible_height); flags |= (info->components_num -1 ) <<FWHT_FL_COMPONENTS_NUM_OFFSET ;if (encoding &FWHT_LUMA_UNENCODED ) flags |=FWHT_FL_LUMA_IS_UNCOMPRESSED ;
@@ -202,15 +202,13 @@ int v4l2_fwht_encode(struct v4l2_fwht_state *state, u8 *p_in, u8 *p_out) p_hdr->ycbcr_enc =htonl (state->ycbcr_enc); p_hdr->quantization =htonl (state->quantization); p_hdr->size =htonl (cf.size); - state->ref_frame.width = cf.width; - state->ref_frame.height = cf.height;return cf.size +sizeof (*p_hdr); }int v4l2_fwht_decode (struct v4l2_fwht_state *state,u8 *p_in,u8 *p_out) { -unsigned int size = state->width * state->height; -unsigned int chroma_size = size; +unsigned int size; +unsigned int chroma_size;unsigned int i;u32 flags;struct fwht_cframe_hdr *p_hdr;
@@ -218,13 +216,15 @@ int v4l2_fwht_decode(struct v4l2_fwht_state *state, u8 *p_in, u8 *p_out)u8 *p;unsigned int components_num =3 ;unsigned int version; +const struct v4l2_fwht_pixfmt_info *info;if (!state->info)return -EINVAL ; + info = state->info; + size = state->coded_width * state->coded_height; + chroma_size = size; p_hdr = (struct fwht_cframe_hdr *)p_in; - cf.width =ntohl (p_hdr->width); - cf.height =ntohl (p_hdr->height); version =ntohl (p_hdr->version);if (!version || version >FWHT_VERSION ) {
@@ -234,12 +234,11 @@ int v4l2_fwht_decode(struct v4l2_fwht_state *state, u8 *p_in, u8 *p_out) }if (p_hdr->magic1 !=FWHT_MAGIC1 || - p_hdr->magic2 !=FWHT_MAGIC2 || - (cf.width &7 ) || (cf.height &7 )) + p_hdr->magic2 !=FWHT_MAGIC2 )return -EINVAL ;/* TODO: support resolution changes */ -if (cf.width != state->width || cf.height != state->height) +if (ntohl (p_hdr->width) != state->visible_width ||ntohl (p_hdr->height) != state->visible_height)return -EINVAL ; flags =ntohl (p_hdr->flags);
@@ -260,7 +259,8 @@ int v4l2_fwht_decode(struct v4l2_fwht_state *state, u8 *p_in, u8 *p_out)if (!(flags &FWHT_FL_CHROMA_FULL_HEIGHT )) chroma_size /=2 ; -fwht_decode_frame (&cf, &state->ref_frame, flags, components_num); +fwht_decode_frame (&cf, &state->ref_frame, flags, components_num, + state->visible_width, state->visible_height, state->coded_width);/* * TODO - handle the case where the compressed stream encodes a
drivers/media/platform/vicodec/codec-v4l2-fwht.h +4 -2
@@ -23,8 +23,10 @@ struct v4l2_fwht_pixfmt_info {struct v4l2_fwht_state {const struct v4l2_fwht_pixfmt_info *info; -unsigned int width; -unsigned int height; +unsigned int visible_width; +unsigned int visible_height; +unsigned int coded_width; +unsigned int coded_height;unsigned int gop_size;unsigned int gop_cnt;u16 i_frame_qp;
drivers/media/platform/vicodec/vicodec-core.c +115 -31
250 lines not on this page · raw message
Signature · 1 line
2.17.1