Adding support to resolution change and apdding
v2 cover Adding support to resolution change and apdding
Main changes from v1:
split the last patch to 3 patches:
1. add pixel encoding flags
2. read the compressed frame header to a different field than the frame data
3. add support for source change event
Dafna Hirschfeld (6):
media: vicodec: bugfix - replace '=' with '|='
media: vicodec: Add num_planes field to v4l2_fwht_pixfmt_info
media: vicodec: add support for CROP and COMPOSE selection
media: vicodec: Add pixel encoding flags to fwht header
media: vicodec: Separate fwht header from the frame data
media: vicodec: Add support for resolution change event.
drivers/media/platform/vicodec/codec-fwht.c | 84 ++- drivers/media/platform/vicodec/codec-fwht.h | 22 +- .../media/platform/vicodec/codec-v4l2-fwht.c | 384 +++++++---- .../media/platform/vicodec/codec-v4l2-fwht.h | 16 +- drivers/media/platform/vicodec/vicodec-core.c | 651 +++++++++++++----- 5 files changed, 836 insertions(+), 321 deletions(-)
Signature · 1 line
2.17.1
PATCH v2 1/6 media: vicodec: bugfix - replace '=' with '|='
In the fwht_encode_frame, 'encoding = encode_plane' should be replaced with 'encoding |= encode_plane' so existing flags won't be overwrriten.
--- drivers/media/platform/vicodec/codec-fwht.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/media/platform/vicodec/codec-fwht.c +4 -4
@@ -787,10 +787,10 @@ 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, - is_intra, next_is_intra); + 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 ;
Signature · 1 line
2.17.1
PATCH v2 2/6 media: vicodec: Add num_planes field to v4l2_fwht_pixfmt_info
In reply to Dafna HirschfeldAdd the field 'num_planes' to 'v4l2_fwht_pixfmt_info' struct.
--- .../media/platform/vicodec/codec-v4l2-fwht.c | 48 +++++++++---------- .../media/platform/vicodec/codec-v4l2-fwht.h | 1 + drivers/media/platform/vicodec/vicodec-core.c | 2 +- 3 files changed, 26 insertions(+), 25 deletions(-)
drivers/media/platform/vicodec/codec-v4l2-fwht.c +24 -24
@@ -11,30 +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 ,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 }, + {V4L2_PIX_FMT_YUV420 ,1 ,3 ,2 ,1 ,1 ,2 ,2 ,3 ,3 }, + {V4L2_PIX_FMT_YVU420 ,1 ,3 ,2 ,1 ,1 ,2 ,2 ,3 ,3 }, + {V4L2_PIX_FMT_YUV422P ,1 ,2 ,1 ,1 ,1 ,2 ,1 ,3 ,3 }, + {V4L2_PIX_FMT_NV12 ,1 ,3 ,2 ,1 ,2 ,2 ,2 ,3 ,2 }, + {V4L2_PIX_FMT_NV21 ,1 ,3 ,2 ,1 ,2 ,2 ,2 ,3 ,2 }, + {V4L2_PIX_FMT_NV16 ,1 ,2 ,1 ,1 ,2 ,2 ,1 ,3 ,2 }, + {V4L2_PIX_FMT_NV61 ,1 ,2 ,1 ,1 ,2 ,2 ,1 ,3 ,2 }, + {V4L2_PIX_FMT_NV24 ,1 ,3 ,1 ,1 ,2 ,1 ,1 ,3 ,2 }, + {V4L2_PIX_FMT_NV42 ,1 ,3 ,1 ,1 ,2 ,1 ,1 ,3 ,2 }, + {V4L2_PIX_FMT_YUYV ,2 ,2 ,1 ,2 ,4 ,2 ,1 ,3 ,1 }, + {V4L2_PIX_FMT_YVYU ,2 ,2 ,1 ,2 ,4 ,2 ,1 ,3 ,1 }, + {V4L2_PIX_FMT_UYVY ,2 ,2 ,1 ,2 ,4 ,2 ,1 ,3 ,1 }, + {V4L2_PIX_FMT_VYUY ,2 ,2 ,1 ,2 ,4 ,2 ,1 ,3 ,1 }, + {V4L2_PIX_FMT_BGR24 ,3 ,3 ,1 ,3 ,3 ,1 ,1 ,3 ,1 }, + {V4L2_PIX_FMT_RGB24 ,3 ,3 ,1 ,3 ,3 ,1 ,1 ,3 ,1 }, + {V4L2_PIX_FMT_HSV24 ,3 ,3 ,1 ,3 ,3 ,1 ,1 ,3 ,1 }, + {V4L2_PIX_FMT_BGR32 ,4 ,4 ,1 ,4 ,4 ,1 ,1 ,3 ,1 }, + {V4L2_PIX_FMT_XBGR32 ,4 ,4 ,1 ,4 ,4 ,1 ,1 ,3 ,1 }, + {V4L2_PIX_FMT_RGB32 ,4 ,4 ,1 ,4 ,4 ,1 ,1 ,3 ,1 }, + {V4L2_PIX_FMT_XRGB32 ,4 ,4 ,1 ,4 ,4 ,1 ,1 ,3 ,1 }, + {V4L2_PIX_FMT_HSV32 ,4 ,4 ,1 ,4 ,4 ,1 ,1 ,3 ,1 }, + {V4L2_PIX_FMT_ARGB32 ,4 ,4 ,1 ,4 ,4 ,1 ,1 ,4 ,1 }, + {V4L2_PIX_FMT_ABGR32 ,4 ,4 ,1 ,4 ,4 ,1 ,1 ,4 ,1 }, + {V4L2_PIX_FMT_GREY ,1 ,1 ,1 ,1 ,0 ,1 ,1 ,1 ,1 }, };const struct v4l2_fwht_pixfmt_info *v4l2_fwht_find_pixfmt (u32 pixelformat)
drivers/media/platform/vicodec/codec-v4l2-fwht.h +1 -0
@@ -19,6 +19,7 @@ struct v4l2_fwht_pixfmt_info {unsigned int width_div;unsigned int height_div;unsigned int components_num; +unsigned int planes_num; };struct v4l2_fwht_state {
drivers/media/platform/vicodec/vicodec-core.c +1 -1
@@ -61,7 +61,7 @@ struct pixfmt_info { };static const struct v4l2_fwht_pixfmt_info pixfmt_fwht = { -V4L2_PIX_FMT_FWHT ,0 ,3 ,1 ,1 ,1 ,1 ,1 ,0 +V4L2_PIX_FMT_FWHT ,0 ,3 ,1 ,1 ,1 ,1 ,1 ,0 ,1 };static void vicodec_dev_release (struct device *dev)
Signature · 1 line
2.17.1
PATCH v2 3/6 media: vicodec: add support for CROP and COMPOSE selection
In reply to Dafna HirschfeldAdd 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.
--- drivers/media/platform/vicodec/codec-fwht.c | 80 +++-- drivers/media/platform/vicodec/codec-fwht.h | 17 +- .../media/platform/vicodec/codec-v4l2-fwht.c | 290 ++++++++++++------ .../media/platform/vicodec/codec-v4l2-fwht.h | 7 +- drivers/media/platform/vicodec/vicodec-core.c | 150 +++++++-- 5 files changed, 382 insertions(+), 162 deletions(-)
drivers/media/platform/vicodec/codec-fwht.c +48 -32
@@ -10,6 +10,7 @@*/ #include <linux/string.h> +#include <linux/kernel.h> #include "codec-fwht.h" /*
@@ -237,8 +238,6 @@ static void fwht(const u8 *block, s16 *output_block, unsigned int stride,unsigned int i;/* stage 1 */ - stride *= input_step; -for (i =0 ; i <8 ; i++, tmp += stride, out +=8 ) {switch (input_step) {case 1 :
@@ -562,7 +561,7 @@ static void fill_encoder_block(const u8 *input, s16 *dst,for (i =0 ; i <8 ; i++) {for (j =0 ; j <8 ; j++, input += input_step) *dst++ = *input; - input += (stride -8 ) * input_step; + input += stride -8 * input_step; } }
@@ -660,7 +659,7 @@ static void add_deltas(s16 *deltas, const u8 *ref, int stride)static u32 encode_plane (u8 *input,u8 *refp,__be16 **rlco,__be16 *rlco_max,struct fwht_cframe *cf,u32 height,u32 width, -unsigned int input_step, +u32 stride,unsigned int input_step,bool is_intra,bool next_is_intra) {u8 *input_start = input;
@@ -671,7 +670,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 * stride;for (i =0 ; i < width /8 ; i++) {/* intra code, first frame is always intra coded. */ int blocktype =IBLOCK ;
@@ -679,9 +682,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, stride, input_step);if (blocktype ==IBLOCK ) { -fwht (input, cf->coeffs, width, input_step,1 ); +fwht (input, cf->coeffs, stride, input_step,1 );quantize_intra (cf->coeffs, cf->de_coeffs, cf->i_frame_qp); }else {
@@ -722,12 +725,12 @@ static u32 encode_plane(u8 *input, u8 *refp, __be16 **rlco, __be16 *rlco_max, } last_size = size; } - input += width *7 * input_step; } exit_loop:if (encoding &FWHT_FRAME_UNENCODED ) {u8 *out = (u8 *)rlco_start; +u8 *p; input = input_start;/*
@@ -736,8 +739,11 @@ static u32 encode_plane(u8 *input, u8 *refp, __be16 **rlco, __be16 *rlco_max,* by 0xfe. Since YUV is limited range such values * shouldn't appear anyway. */ -for (i =0 ; i < height * width; i++, input += input_step) - *out++ = (*input ==0xff ) ?0xfe : *input; +for (j =0 ; j < height; j++) { +for (i =0 , p = input; i < width; i++, p += input_step) + *out++ = (*p ==0xff ) ?0xfe : *p; + input += stride; + } *rlco = (__be16 *)out; encoding &= ~FWHT_FRAME_PCODED ; }
@@ -747,30 +753,32 @@ 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 stride,unsigned int chroma_stride) { -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, stride, 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;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, + chroma_stride, frm->chroma_step, is_intra, next_is_intra);if (encoding &FWHT_FRAME_UNENCODED ) encoding |=FWHT_CB_UNENCODED ;
@@ -778,7 +786,7 @@ u32 fwht_encode_frame(struct fwht_raw_frame *frm, 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, + chroma_stride, frm->chroma_step, is_intra, next_is_intra);if (encoding &FWHT_FRAME_UNENCODED ) encoding |=FWHT_CR_UNENCODED ;
@@ -788,8 +796,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, + stride, frm->luma_alpha_step, is_intra, next_is_intra);if (encoding &FWHT_FRAME_UNENCODED ) encoding |=FWHT_ALPHA_UNENCODED ;
@@ -801,13 +809,16 @@ 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 ];s16 stat;unsigned int i, j; + width =round_up (width,8 ); + height =round_up (height,8 ); +if (uncompressed) {memcpy (ref, *rlco, width * height); *rlco += width * height /2 ;
@@ -822,13 +833,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 +858,40 @@ 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 +13 -4
@@ -81,6 +81,13 @@#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 +* a 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 +102,6 @@ struct fwht_cframe_hdr { };struct fwht_cframe { -unsigned int width, height;u16 i_frame_qp;u16 p_frame_qp;__be16 *rlc_data;
@@ -106,7 +112,6 @@ struct fwht_cframe { };struct fwht_raw_frame { -unsigned int width, height;unsigned int width_div;unsigned int height_div;unsigned int luma_alpha_step;
@@ -125,8 +130,12 @@ 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, +unsigned int stride,unsigned int chroma_stride);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 +197 -93
425 lines not on this page · raw message
drivers/media/platform/vicodec/codec-v4l2-fwht.h +5 -2
@@ -24,8 +24,11 @@ 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 stride;unsigned int gop_size;unsigned int gop_cnt;u16 i_frame_qp;
drivers/media/platform/vicodec/vicodec-core.c +119 -31
254 lines not on this page · raw message
Signature · 1 line
2.17.1
PATCH v2 4/6 media: vicodec: Add pixel encoding flags to fwht header
In reply to Dafna HirschfeldAdd flags indicating the pixel encoding - yuv/rgb/hsv to fwht header and to the pixel info. Use it to enumerate the supported pixel formats.
--- drivers/media/platform/vicodec/codec-fwht.h | 5 ++ .../media/platform/vicodec/codec-v4l2-fwht.c | 76 +++++++++++++------ .../media/platform/vicodec/codec-v4l2-fwht.h | 7 ++ drivers/media/platform/vicodec/vicodec-core.c | 20 +++-- 4 files changed, 78 insertions(+), 30 deletions(-)
drivers/media/platform/vicodec/codec-fwht.h +5 -0
@@ -79,6 +79,11 @@/* A 4-values flag - the number of components - 1 */ #define FWHT_FL_COMPONENTS_NUM_MSK GENMASK(17, 16) +#define FWHT_FL_PIXENC_MSK GENMASK(19, 18) +#define FWHT_FL_PIXENC_YUV 0UL +#define FWHT_FL_PIXENC_RGB BIT(18) +#define FWHT_FL_PIXENC_HSV (BIT(18) | BIT(19)) +#define FWHT_FL_COMPONENTS_NUM_OFFSET 16/*
drivers/media/platform/vicodec/codec-v4l2-fwht.c +52 -24
98 lines not on this page · raw message
drivers/media/platform/vicodec/codec-v4l2-fwht.h +7 -0
@@ -20,6 +20,7 @@ struct v4l2_fwht_pixfmt_info {unsigned int height_div;unsigned int components_num;unsigned int planes_num; +unsigned int pixenc; };struct v4l2_fwht_state {
@@ -45,6 +46,12 @@ struct v4l2_fwht_state {const struct v4l2_fwht_pixfmt_info *v4l2_fwht_find_pixfmt (u32 pixelformat);const struct v4l2_fwht_pixfmt_info *v4l2_fwht_get_pixfmt (u32 idx); +const struct v4l2_fwht_pixfmt_info *v4l2_fwht_default_fmt (u32 width_div, +u32 height_div, +u32 version, +u32 components_num, +u32 pixenc, +unsigned int start_idx);int v4l2_fwht_encode (struct v4l2_fwht_state *state,u8 *p_in,u8 *p_out);int v4l2_fwht_decode (struct v4l2_fwht_state *state,u8 *p_in,u8 *p_out);
drivers/media/platform/vicodec/vicodec-core.c +14 -6
@@ -395,9 +395,9 @@ static int vidioc_querycap(struct file *file, void *priv,return 0 ; } -static int enum_fmt (struct v4l2_fmtdesc *f,bool is_enc,bool is_out) +static int enum_fmt (struct v4l2_fmtdesc *f,struct vicodec_ctx *ctx,bool is_out) { -bool is_uncomp = (is_enc && is_out) || (!is_enc && !is_out); +bool is_uncomp = (ctx->is_enc && is_out) || (!ctx->is_enc && !is_out);if (V4L2_TYPE_IS_MULTIPLANAR (f->type) && !multiplanar)return -EINVAL ;
@@ -405,9 +405,17 @@ static int enum_fmt(struct v4l2_fmtdesc *f, bool is_enc, bool is_out)return -EINVAL ;if (is_uncomp) { -const struct v4l2_fwht_pixfmt_info *info = -v4l2_fwht_get_pixfmt (f->index); +const struct v4l2_fwht_pixfmt_info *info =get_q_data (ctx, f->type)->info; +if (ctx->is_enc) + info =v4l2_fwht_get_pixfmt (f->index); +else + info =v4l2_fwht_default_fmt (info->width_div, + info->height_div, +FWHT_VERSION , + info->components_num, + info->pixenc, + f->index);if (!info)return -EINVAL ; f->pixelformat = info->id;
@@ -424,7 +432,7 @@ static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv, {struct vicodec_ctx *ctx =file2ctx (file); -return enum_fmt (f, ctx->is_enc, false); +return enum_fmt (f, ctx, false); } static int vidioc_enum_fmt_vid_out(struct file *file, void *priv,
@@ -432,7 +440,7 @@ static int vidioc_enum_fmt_vid_out(struct file *file, void *priv, {struct vicodec_ctx *ctx =file2ctx (file); -return enum_fmt (f, ctx->is_enc, true); +return enum_fmt (f, ctx, true); }static int vidioc_g_fmt (struct vicodec_ctx *ctx,struct v4l2_format *f)
Signature · 1 line
2.17.1
Re: [PATCH v2 4/6] media: vicodec: Add pixel encoding flags to fwht header
Quoted 17 lines · Dafna Hirschfeld
Add flags indicating the pixel encoding - yuv/rgb/hsv to fwht header and to the pixel info. Use it to enumerate the supported pixel formats.
Signed-off-by Dafna Hirschfeld <[email protected]>--- drivers/media/platform/vicodec/codec-fwht.h | 5 ++ .../media/platform/vicodec/codec-v4l2-fwht.c | 76 +++++++++++++------ .../media/platform/vicodec/codec-v4l2-fwht.h | 7 ++ drivers/media/platform/vicodec/vicodec-core.c | 20 +++-- 4 files changed, 78 insertions(+), 30 deletions(-)drivers/media/platform/vicodec/codec-fwht.h +0
-0
drivers/media/platform/vicodec/codec-fwht.h line 82
Quoted 4 lines
drivers/media/platform/vicodec/codec-fwht.h +1
-0@@ -79,6 +79,11 @@/* A 4-values flag - the number of components - 1 */ #define FWHT_FL_COMPONENTS_NUM_MSK GENMASK(17, 16) +#define FWHT_FL_PIXENC_MSK GENMASK(19, 18)
I think we should reserve 3 bits for this, so use GENMASK(20, 18).
drivers/media/platform/vicodec/codec-fwht.h line 85
Quoted 3 lines
drivers/media/platform/vicodec/codec-fwht.h +3
-0+#define FWHT_FL_PIXENC_YUV 0UL +#define FWHT_FL_PIXENC_RGB BIT(18) +#define FWHT_FL_PIXENC_HSV (BIT(18) | BIT(19))
I'd change this to:
YUV: (1 << 18)
RGB: (2 << 18)
HSV: (3 << 18)
Quoted 64 lines
drivers/media/platform/vicodec/codec-fwht.h +1
-0+#define FWHT_FL_COMPONENTS_NUM_OFFSET 16/* drivers/media/platform/vicodec/codec-v4l2-fwht.c +26
-24@@ -11,32 +11,53 @@#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 ,3 ,3 }, - {V4L2_PIX_FMT_YVU420 ,1 ,3 ,2 ,1 ,1 ,2 ,2 ,3 ,3 }, - {V4L2_PIX_FMT_YUV422P ,1 ,2 ,1 ,1 ,1 ,2 ,1 ,3 ,3 }, - {V4L2_PIX_FMT_NV12 ,1 ,3 ,2 ,1 ,2 ,2 ,2 ,3 ,2 }, - {V4L2_PIX_FMT_NV21 ,1 ,3 ,2 ,1 ,2 ,2 ,2 ,3 ,2 }, - {V4L2_PIX_FMT_NV16 ,1 ,2 ,1 ,1 ,2 ,2 ,1 ,3 ,2 }, - {V4L2_PIX_FMT_NV61 ,1 ,2 ,1 ,1 ,2 ,2 ,1 ,3 ,2 }, - {V4L2_PIX_FMT_NV24 ,1 ,3 ,1 ,1 ,2 ,1 ,1 ,3 ,2 }, - {V4L2_PIX_FMT_NV42 ,1 ,3 ,1 ,1 ,2 ,1 ,1 ,3 ,2 }, - {V4L2_PIX_FMT_YUYV ,2 ,2 ,1 ,2 ,4 ,2 ,1 ,3 ,1 }, - {V4L2_PIX_FMT_YVYU ,2 ,2 ,1 ,2 ,4 ,2 ,1 ,3 ,1 }, - {V4L2_PIX_FMT_UYVY ,2 ,2 ,1 ,2 ,4 ,2 ,1 ,3 ,1 }, - {V4L2_PIX_FMT_VYUY ,2 ,2 ,1 ,2 ,4 ,2 ,1 ,3 ,1 }, - {V4L2_PIX_FMT_BGR24 ,3 ,3 ,1 ,3 ,3 ,1 ,1 ,3 ,1 }, - {V4L2_PIX_FMT_RGB24 ,3 ,3 ,1 ,3 ,3 ,1 ,1 ,3 ,1 }, - {V4L2_PIX_FMT_HSV24 ,3 ,3 ,1 ,3 ,3 ,1 ,1 ,3 ,1 }, - {V4L2_PIX_FMT_BGR32 ,4 ,4 ,1 ,4 ,4 ,1 ,1 ,3 ,1 }, - {V4L2_PIX_FMT_XBGR32 ,4 ,4 ,1 ,4 ,4 ,1 ,1 ,3 ,1 }, - {V4L2_PIX_FMT_RGB32 ,4 ,4 ,1 ,4 ,4 ,1 ,1 ,3 ,1 }, - {V4L2_PIX_FMT_XRGB32 ,4 ,4 ,1 ,4 ,4 ,1 ,1 ,3 ,1 }, - {V4L2_PIX_FMT_HSV32 ,4 ,4 ,1 ,4 ,4 ,1 ,1 ,3 ,1 }, - {V4L2_PIX_FMT_ARGB32 ,4 ,4 ,1 ,4 ,4 ,1 ,1 ,4 ,1 }, - {V4L2_PIX_FMT_ABGR32 ,4 ,4 ,1 ,4 ,4 ,1 ,1 ,4 ,1 }, - {V4L2_PIX_FMT_GREY ,1 ,1 ,1 ,1 ,0 ,1 ,1 ,1 ,1 }, + {V4L2_PIX_FMT_YUV420 ,1 ,3 ,2 ,1 ,1 ,2 ,2 ,3 ,3 ,FWHT_FL_PIXENC_YUV }, + {V4L2_PIX_FMT_YVU420 ,1 ,3 ,2 ,1 ,1 ,2 ,2 ,3 ,3 ,FWHT_FL_PIXENC_YUV }, + {V4L2_PIX_FMT_YUV422P ,1 ,2 ,1 ,1 ,1 ,2 ,1 ,3 ,3 ,FWHT_FL_PIXENC_YUV }, + {V4L2_PIX_FMT_NV12 ,1 ,3 ,2 ,1 ,2 ,2 ,2 ,3 ,2 ,FWHT_FL_PIXENC_YUV }, + {V4L2_PIX_FMT_NV21 ,1 ,3 ,2 ,1 ,2 ,2 ,2 ,3 ,2 ,FWHT_FL_PIXENC_YUV }, + {V4L2_PIX_FMT_NV16 ,1 ,2 ,1 ,1 ,2 ,2 ,1 ,3 ,2 ,FWHT_FL_PIXENC_YUV }, + {V4L2_PIX_FMT_NV61 ,1 ,2 ,1 ,1 ,2 ,2 ,1 ,3 ,2 ,FWHT_FL_PIXENC_YUV }, + {V4L2_PIX_FMT_NV24 ,1 ,3 ,1 ,1 ,2 ,1 ,1 ,3 ,2 ,FWHT_FL_PIXENC_YUV }, + {V4L2_PIX_FMT_NV42 ,1 ,3 ,1 ,1 ,2 ,1 ,1 ,3 ,2 ,FWHT_FL_PIXENC_YUV }, + {V4L2_PIX_FMT_YUYV ,2 ,2 ,1 ,2 ,4 ,2 ,1 ,3 ,1 ,FWHT_FL_PIXENC_YUV }, + {V4L2_PIX_FMT_YVYU ,2 ,2 ,1 ,2 ,4 ,2 ,1 ,3 ,1 ,FWHT_FL_PIXENC_YUV }, + {V4L2_PIX_FMT_UYVY ,2 ,2 ,1 ,2 ,4 ,2 ,1 ,3 ,1 ,FWHT_FL_PIXENC_YUV }, + {V4L2_PIX_FMT_VYUY ,2 ,2 ,1 ,2 ,4 ,2 ,1 ,3 ,1 ,FWHT_FL_PIXENC_YUV }, + {V4L2_PIX_FMT_BGR24 ,3 ,3 ,1 ,3 ,3 ,1 ,1 ,3 ,1 ,FWHT_FL_PIXENC_RGB }, + {V4L2_PIX_FMT_RGB24 ,3 ,3 ,1 ,3 ,3 ,1 ,1 ,3 ,1 ,FWHT_FL_PIXENC_RGB }, + {V4L2_PIX_FMT_HSV24 ,3 ,3 ,1 ,3 ,3 ,1 ,1 ,3 ,1 ,FWHT_FL_PIXENC_HSV }, + {V4L2_PIX_FMT_BGR32 ,4 ,4 ,1 ,4 ,4 ,1 ,1 ,3 ,1 ,FWHT_FL_PIXENC_RGB }, + {V4L2_PIX_FMT_XBGR32 ,4 ,4 ,1 ,4 ,4 ,1 ,1 ,3 ,1 ,FWHT_FL_PIXENC_RGB }, + {V4L2_PIX_FMT_RGB32 ,4 ,4 ,1 ,4 ,4 ,1 ,1 ,3 ,1 ,FWHT_FL_PIXENC_RGB }, + {V4L2_PIX_FMT_XRGB32 ,4 ,4 ,1 ,4 ,4 ,1 ,1 ,3 ,1 ,FWHT_FL_PIXENC_RGB }, + {V4L2_PIX_FMT_HSV32 ,4 ,4 ,1 ,4 ,4 ,1 ,1 ,3 ,1 ,FWHT_FL_PIXENC_HSV }, + {V4L2_PIX_FMT_ARGB32 ,4 ,4 ,1 ,4 ,4 ,1 ,1 ,4 ,1 ,FWHT_FL_PIXENC_RGB }, + {V4L2_PIX_FMT_ABGR32 ,4 ,4 ,1 ,4 ,4 ,1 ,1 ,4 ,1 ,FWHT_FL_PIXENC_RGB }, + {V4L2_PIX_FMT_GREY ,1 ,1 ,1 ,1 ,0 ,1 ,1 ,1 ,1 ,FWHT_FL_PIXENC_RGB }, }; +const struct v4l2_fwht_pixfmt_info *v4l2_fwht_default_fmt(u32 width_div, u32 height_div, + u32 version,
drivers/media/platform/vicodec/codec-v4l2-fwht.c line 51
Quoted 10 lines
drivers/media/platform/vicodec/codec-v4l2-fwht.c +10
-0+u32 components_num, + u32 pixenc, + unsigned int start_idx) +{ + unsigned int i; + +for (i =0 ; i <ARRAY_SIZE (v4l2_fwht_pixfmts); i++) { + if (v4l2_fwht_pixfmts[i].width_div == width_div && + v4l2_fwht_pixfmts[i].height_div == height_div && + (version == 1 || v4l2_fwht_pixfmts[i].pixenc == pixenc) &&
A pixenc value of 0 means that we are dealing with an old header. So we can replace the version check with:
(!pixenc || v4l2_fwht_pixfmts[i].pixenc == pixenc) &&
drivers/media/platform/vicodec/codec-v4l2-fwht.c line 52
Quoted 1 line
drivers/media/platform/vicodec/codec-v4l2-fwht.c +1
-0+ (version == 1 || v4l2_fwht_pixfmts[i].components_num == components_num)) {
I don't think this is right. If this is an old header version, then we should only match formats with 3 components. So I'd drop the version check here and just ensure that components_num is always 3 if we have an old header.
Note that with these changes the version argument can be dropped as well.
Quoted 20 lines
drivers/media/platform/vicodec/codec-v4l2-fwht.c +9
-0+if (start_idx ==0 ) +return v4l2_fwht_pixfmts + i; + start_idx--; + } + } +return NULL ; +} +const struct v4l2_fwht_pixfmt_info *v4l2_fwht_find_pixfmt (u32 pixelformat) {unsigned int i;@@ -187,6 +208,7 @@ int v4l2_fwht_encode(struct v4l2_fwht_state *state, u8 *p_in, u8 *p_out) p_hdr->width =htonl (state->visible_width); p_hdr->height =htonl (state->visible_height); flags |= (info->components_num -1 ) <<FWHT_FL_COMPONENTS_NUM_OFFSET ; + flags |= info->pixenc;if (encoding &FWHT_LUMA_UNENCODED ) flags |=FWHT_FL_LUMA_IS_UNCOMPRESSED ;if (encoding &FWHT_CB_UNENCODED )
drivers/media/platform/vicodec/codec-v4l2-fwht.c int v4l2_fwht_decode(struct v4l2_fwht_state *state, u8 *p_in, u8 *p_out) · line 275
Quoted 9 lines
drivers/media/platform/vicodec/codec-v4l2-fwht.c +4
-0@@ -245,8 +267,14 @@ int v4l2_fwht_decode(struct v4l2_fwht_state *state, u8 *p_in, u8 *p_out) flags =ntohl (p_hdr->flags);if (version ==FWHT_VERSION ) { +u32 pixenc = flags &FWHT_FL_PIXENC_MSK ; + components_num =1 + ((flags &FWHT_FL_COMPONENTS_NUM_MSK ) >>FWHT_FL_COMPONENTS_NUM_OFFSET ); + + if (components_num != info->components_num ||
The components check should be done after this 'if'. Since it also is valid for older headers.
Quoted 77 lines
drivers/media/platform/vicodec/codec-v4l2-fwht.c +2
-0+ pixenc != info->pixenc) +return -EINVAL ; } state->colorspace =ntohl (p_hdr->colorspace);drivers/media/platform/vicodec/codec-v4l2-fwht.h +7
-0@@ -20,6 +20,7 @@ struct v4l2_fwht_pixfmt_info {unsigned int height_div;unsigned int components_num;unsigned int planes_num; +unsigned int pixenc; };struct v4l2_fwht_state {@@ -45,6 +46,12 @@ struct v4l2_fwht_state {const struct v4l2_fwht_pixfmt_info *v4l2_fwht_find_pixfmt (u32 pixelformat);const struct v4l2_fwht_pixfmt_info *v4l2_fwht_get_pixfmt (u32 idx); +const struct v4l2_fwht_pixfmt_info *v4l2_fwht_default_fmt (u32 width_div, +u32 height_div, +u32 version, +u32 components_num, +u32 pixenc, +unsigned int start_idx);int v4l2_fwht_encode (struct v4l2_fwht_state *state,u8 *p_in,u8 *p_out);int v4l2_fwht_decode (struct v4l2_fwht_state *state,u8 *p_in,u8 *p_out);drivers/media/platform/vicodec/vicodec-core.c +13
-5@@ -395,9 +395,9 @@ static int vidioc_querycap(struct file *file, void *priv,return 0 ; } -static int enum_fmt (struct v4l2_fmtdesc *f,bool is_enc,bool is_out) +static int enum_fmt (struct v4l2_fmtdesc *f,struct vicodec_ctx *ctx,bool is_out) { -bool is_uncomp = (is_enc && is_out) || (!is_enc && !is_out); +bool is_uncomp = (ctx->is_enc && is_out) || (!ctx->is_enc && !is_out);if (V4L2_TYPE_IS_MULTIPLANAR (f->type) && !multiplanar)return -EINVAL ;@@ -405,9 +405,17 @@ static int enum_fmt(struct v4l2_fmtdesc *f, bool is_enc, bool is_out)return -EINVAL ;if (is_uncomp) { -const struct v4l2_fwht_pixfmt_info *info = -v4l2_fwht_get_pixfmt (f->index); +const struct v4l2_fwht_pixfmt_info *info =get_q_data (ctx, f->type)->info; +if (ctx->is_enc) + info =v4l2_fwht_get_pixfmt (f->index); +else + info =v4l2_fwht_default_fmt (info->width_div, + info->height_div, +FWHT_VERSION , + info->components_num, + info->pixenc, + f->index);if (!info)return -EINVAL ; f->pixelformat = info->id;@@ -424,7 +432,7 @@ static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv, {struct vicodec_ctx *ctx =file2ctx (file); -return enum_fmt (f, ctx->is_enc, false); +return enum_fmt (f, ctx, false); } static int vidioc_enum_fmt_vid_out(struct file *file, void *priv,
drivers/media/platform/vicodec/vicodec-core.c static int vidioc_enum_fmt_vid_out(struct file *file, void *priv, · line 446
Quoted 8 lines
drivers/media/platform/vicodec/vicodec-core.c +1
-1@@ -432,7 +440,7 @@ static int vidioc_enum_fmt_vid_out(struct file *file, void *priv, {struct vicodec_ctx *ctx =file2ctx (file); -return enum_fmt (f, ctx->is_enc, true); +return enum_fmt (f, ctx, true); }static int vidioc_g_fmt (struct vicodec_ctx *ctx,struct v4l2_format *f)
Regards,
Hans
PATCH v2 5/6 media: vicodec: Separate fwht header from the frame data
In reply to Dafna HirschfeldKeep the fwht header in separated field from the data. Refactor job_ready to use a new function 'get_next_header'
--- .../media/platform/vicodec/codec-v4l2-fwht.c | 24 ++-- .../media/platform/vicodec/codec-v4l2-fwht.h | 1 + drivers/media/platform/vicodec/vicodec-core.c | 118 ++++++++++-------- 3 files changed, 81 insertions(+), 62 deletions(-)
drivers/media/platform/vicodec/codec-v4l2-fwht.c +11 -13
@@ -234,7 +234,6 @@ int v4l2_fwht_decode(struct v4l2_fwht_state *state, u8 *p_in, u8 *p_out) {unsigned int i, j, k;u32 flags; -struct fwht_cframe_hdr *p_hdr;struct fwht_cframe cf;u8 *p, *ref_p;unsigned int components_num =3 ;
@@ -246,25 +245,24 @@ int v4l2_fwht_decode(struct v4l2_fwht_state *state, u8 *p_in, u8 *p_out)return -EINVAL ; info = state->info; - p_hdr = (struct fwht_cframe_hdr *)p_in; - version =ntohl (p_hdr->version); + version =ntohl (state->header.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 ) +if (state->header.magic1 !=FWHT_MAGIC1 || + state->header.magic2 !=FWHT_MAGIC2 )return -EINVAL ;/* TODO: support resolution changes */ -if (ntohl (p_hdr->width) != state->visible_width || -ntohl (p_hdr->height) != state->visible_height) +if (ntohl (state->header.width) != state->visible_width || +ntohl (state->header.height) != state->visible_height)return -EINVAL ; - flags =ntohl (p_hdr->flags); + flags =ntohl (state->header.flags);if (version ==FWHT_VERSION ) {u32 pixenc = flags &FWHT_FL_PIXENC_MSK ;
@@ -277,11 +275,11 @@ int v4l2_fwht_decode(struct v4l2_fwht_state *state, u8 *p_in, u8 *p_out)return -EINVAL ; } - 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)); + state->colorspace =ntohl (state->header.colorspace); + state->xfer_func =ntohl (state->header.xfer_func); + state->ycbcr_enc =ntohl (state->header.ycbcr_enc); + state->quantization =ntohl (state->header.quantization); + cf.rlc_data = (__be16 *)p_in; hdr_width_div = (flags &FWHT_FL_CHROMA_FULL_WIDTH ) ?1 :2 ; hdr_height_div = (flags &FWHT_FL_CHROMA_FULL_HEIGHT ) ?1 :2 ;
drivers/media/platform/vicodec/codec-v4l2-fwht.h +1 -0
@@ -41,6 +41,7 @@ struct v4l2_fwht_state {enum v4l2_quantization quantization;struct fwht_raw_frame ref_frame; +struct fwht_cframe_hdr header;u8 *compressed_frame; };
drivers/media/platform/vicodec/vicodec-core.c +69 -49
157 lines not on this page · raw message
Signature · 1 line
2.17.1
Re: [PATCH v2 5/6] media: vicodec: Separate fwht header from the frame data
Quoted 96 lines · Dafna Hirschfeld
Keep the fwht header in separated field from the data. Refactor
job_readyto use a new function 'get_next_header'Signed-off-by Dafna Hirschfeld <[email protected]>--- .../media/platform/vicodec/codec-v4l2-fwht.c | 24 ++-- .../media/platform/vicodec/codec-v4l2-fwht.h | 1 + drivers/media/platform/vicodec/vicodec-core.c | 118 ++++++++++-------- 3 files changed, 81 insertions(+), 62 deletions(-)drivers/media/platform/vicodec/codec-v4l2-fwht.c +11
-13@@ -234,7 +234,6 @@ int v4l2_fwht_decode(struct v4l2_fwht_state *state, u8 *p_in, u8 *p_out) {unsigned int i, j, k;u32 flags; -struct fwht_cframe_hdr *p_hdr;struct fwht_cframe cf;u8 *p, *ref_p;unsigned int components_num =3 ;@@ -246,25 +245,24 @@ int v4l2_fwht_decode(struct v4l2_fwht_state *state, u8 *p_in, u8 *p_out)return -EINVAL ; info = state->info; - p_hdr = (struct fwht_cframe_hdr *)p_in; - version =ntohl (p_hdr->version); + version =ntohl (state->header.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 ) +if (state->header.magic1 !=FWHT_MAGIC1 || + state->header.magic2 !=FWHT_MAGIC2 )return -EINVAL ;/* TODO: support resolution changes */ -if (ntohl (p_hdr->width) != state->visible_width || -ntohl (p_hdr->height) != state->visible_height) +if (ntohl (state->header.width) != state->visible_width || +ntohl (state->header.height) != state->visible_height)return -EINVAL ; - flags =ntohl (p_hdr->flags); + flags =ntohl (state->header.flags);if (version ==FWHT_VERSION ) {u32 pixenc = flags &FWHT_FL_PIXENC_MSK ;@@ -277,11 +275,11 @@ int v4l2_fwht_decode(struct v4l2_fwht_state *state, u8 *p_in, u8 *p_out)return -EINVAL ; } - 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)); + state->colorspace =ntohl (state->header.colorspace); + state->xfer_func =ntohl (state->header.xfer_func); + state->ycbcr_enc =ntohl (state->header.ycbcr_enc); + state->quantization =ntohl (state->header.quantization); + cf.rlc_data = (__be16 *)p_in; hdr_width_div = (flags &FWHT_FL_CHROMA_FULL_WIDTH ) ?1 :2 ; hdr_height_div = (flags &FWHT_FL_CHROMA_FULL_HEIGHT ) ?1 :2 ;drivers/media/platform/vicodec/codec-v4l2-fwht.h +1
-0@@ -41,6 +41,7 @@ struct v4l2_fwht_state {enum v4l2_quantization quantization;struct fwht_raw_frame ref_frame; +struct fwht_cframe_hdr header;u8 *compressed_frame; };drivers/media/platform/vicodec/vicodec-core.c +1
-0@@ -124,6 +124,7 @@ struct vicodec_ctx {u32 cur_buf_offset;u32 comp_max_size;u32 comp_size; +u32 header_size;u32 comp_magic_cnt;u32 comp_frame_size;bool comp_has_frame;
drivers/media/platform/vicodec/vicodec-core.c static int device_process(struct vicodec_ctx *ctx, · line 206
Quoted 5 lines
drivers/media/platform/vicodec/vicodec-core.c +2
-0@@ -201,6 +202,61 @@ static int device_process(struct vicodec_ctx *ctx,/* * mem2mem callbacks */ +enum vb2_buffer_state get_next_header (struct vicodec_ctx *ctx,u8 *p_src, +u32 sz,u8 *header,u8 **pp)
This can be simplified: there is no need to pass the header since it can be obtained via ctx. And rather than passing p_src, sz and pp you can pass pp and the remaining sz in the buffer.
Quoted 43 lines
drivers/media/platform/vicodec/vicodec-core.c +43
-0+{ +static const u8 magic[] = { +0x4f ,0x4f ,0x4f ,0x4f ,0xff ,0xff ,0xff ,0xff + }; +u8 *p = *pp; +u32 state; + + state =VB2_BUF_STATE_DONE ; + +if (!ctx->header_size) { + state =VB2_BUF_STATE_ERROR ; +for (; p < p_src + sz; p++) { +u32 copy; + + p =memchr (p, magic[ctx->comp_magic_cnt], + p_src + sz - p); +if (!p) { + ctx->comp_magic_cnt =0 ; +break ; + } + copy =sizeof (magic) - ctx->comp_magic_cnt; +if (p_src + sz - p < copy) + copy = p_src + sz - p; + +memcpy (header + ctx->comp_magic_cnt, p, copy); + ctx->comp_magic_cnt += copy; +if (!memcmp (header, magic, ctx->comp_magic_cnt)) { + p += copy; + state =VB2_BUF_STATE_DONE ; +break ; + } + ctx->comp_magic_cnt =0 ; + } +if (ctx->comp_magic_cnt <sizeof (magic)) { + *pp = p; +return state; + } + ctx->header_size =sizeof (magic); + } + +if (ctx->header_size <sizeof (struct fwht_cframe_hdr )) { +u32 copy =sizeof (struct fwht_cframe_hdr ) - ctx->header_size; +
drivers/media/platform/vicodec/vicodec-core.c static int device_process(struct vicodec_ctx *ctx, · line 259
Quoted 10 lines
drivers/media/platform/vicodec/vicodec-core.c +10
-0+if (copy > p_src + sz - p) + copy = p_src + sz - p; + +memcpy (header + ctx->header_size, p, copy); + p += copy; + ctx->header_size += copy; + } + *pp = p; +return state; +}
Hmm, I think the original code is a bit buggy. I don't think it will find the correct header in some circumstances: e.g. a sequence of 5 0x4f bytes followed by 4 0xff bytes will likely fail.
Try to prepend a 0x4f byte to a fwht bitstream and see if that works. I think it will fail to find the header.
Anyway, that can be fixed in a separate patch.
I think a proper solution just counts the number of consecutive 0x4f bytes and the number of consecutive 0xff bytes that follow.
The magic header sequence is found if the 0x4f count >= 4 and the 0xff count == 4.
There is no need to copy the magic header sequence to state.header in this case since it is really just a state machine. I suspect it will actually make the code simpler.
Quoted 13 lines
drivers/media/platform/vicodec/vicodec-core.c +1
-0/* device_run() - prepares and starts the device */ static void device_run (void *priv)@@ -241,6 +297,7 @@ static void device_run(void *priv) }v4l2_m2m_buf_done (dst_buf, state); ctx->comp_size =0 ; + ctx->header_size =0 ; ctx->comp_magic_cnt =0 ; ctx->comp_has_frame = false;spin_unlock (ctx->lock);@@ -291,57 +348,19 @@ static int job_ready(void *priv)
drivers/media/platform/vicodec/vicodec-core.c static int job_ready(void *priv) · line 354
Quoted 10 lines
drivers/media/platform/vicodec/vicodec-core.c +4
-4state =VB2_BUF_STATE_DONE ; -if (!ctx->comp_size) { - state =VB2_BUF_STATE_ERROR ; -for (; p < p_src + sz; p++) { -u32 copy; +if (ctx->header_size <sizeof (struct fwht_cframe_hdr )) + state =get_next_header (ctx, p_src, sz, + (u8 *)&ctx->state.header, &p); +if (ctx->header_size <sizeof (struct fwht_cframe_hdr )) {
This 'if' should be inside the previous 'if'.
Quoted 4 lines
drivers/media/platform/vicodec/vicodec-core.c +3
-0+job_remove_src_buf (ctx, state); + goto restart; + }
drivers/media/platform/vicodec/vicodec-core.c static int job_ready(void *priv) · line 359
Quoted 10 lines
drivers/media/platform/vicodec/vicodec-core.c +1
-9- p =memchr (p, magic[ctx->comp_magic_cnt], - p_src + sz - p); -if (!p) { - ctx->comp_magic_cnt =0 ; -break ; - } - copy =sizeof (magic) - ctx->comp_magic_cnt; -if (p_src + sz - p < copy) - copy = p_src + sz - p; + ctx->comp_frame_size =ntohl (ctx->state.header.size);
This line as well...
Quoted 14 lines
drivers/media/platform/vicodec/vicodec-core.c +0
-13-memcpy (ctx->state.compressed_frame + ctx->comp_magic_cnt, - p, copy); - ctx->comp_magic_cnt += copy; -if (!memcmp (ctx->state.compressed_frame, magic, - ctx->comp_magic_cnt)) { - p += copy; - state =VB2_BUF_STATE_DONE ; -break ; - } - ctx->comp_magic_cnt =0 ; - } -if (ctx->comp_magic_cnt <sizeof (magic)) { -job_remove_src_buf (ctx, state);
drivers/media/platform/vicodec/vicodec-core.c static int job_ready(void *priv) · line 362
Quoted 10 lines
drivers/media/platform/vicodec/vicodec-core.c +2
-8- goto restart; - } - ctx->comp_size =sizeof (magic); - } -if (ctx->comp_size <sizeof (struct fwht_cframe_hdr )) { -struct fwht_cframe_hdr *p_hdr = - (struct fwht_cframe_hdr *)ctx->state.compressed_frame; -u32 copy =sizeof (struct fwht_cframe_hdr ) - ctx->comp_size; +if (ctx->comp_frame_size > ctx->comp_max_size) + ctx->comp_frame_size = ctx->comp_max_size;
...and also these two. After all, this only needs to be done when a new header was found.
Quoted 29 lines
drivers/media/platform/vicodec/vicodec-core.c +1
-15-if (copy > p_src + sz - p) - copy = p_src + sz - p; -memcpy (ctx->state.compressed_frame + ctx->comp_size, - p, copy); - p += copy; - ctx->comp_size += copy; -if (ctx->comp_size <sizeof (struct fwht_cframe_hdr )) { -job_remove_src_buf (ctx, state); - goto restart; - } - ctx->comp_frame_size =ntohl (p_hdr->size) +sizeof (*p_hdr); -if (ctx->comp_frame_size > ctx->comp_max_size) - ctx->comp_frame_size = ctx->comp_max_size; - }if (ctx->comp_size < ctx->comp_frame_size) {u32 copy = ctx->comp_frame_size - ctx->comp_size;@@ -1104,7 +1123,7 @@ static int vicodec_start_streaming(struct vb2_queue *q, state->stride = q_data->coded_width * info->bytesperline_mult; } state->ref_frame.luma =kvmalloc (total_planes_size,GFP_KERNEL ); - ctx->comp_max_size = total_planes_size +sizeof (struct fwht_cframe_hdr ); + ctx->comp_max_size = total_planes_size; state->compressed_frame =kvmalloc (ctx->comp_max_size,GFP_KERNEL );if (!state->ref_frame.luma || !state->compressed_frame) {kvfree (state->ref_frame.luma);
drivers/media/platform/vicodec/vicodec-core.c static int vicodec_start_streaming(struct vb2_queue *q, · line 1156
Quoted 7 lines
drivers/media/platform/vicodec/vicodec-core.c +1
-0@@ -1131,6 +1150,7 @@ static int vicodec_start_streaming(struct vb2_queue *q, state->gop_cnt =0 ; ctx->cur_buf_offset =0 ; ctx->comp_size =0 ; + ctx->header_size =0 ; ctx->comp_magic_cnt =0 ; ctx->comp_has_frame = false;
Regards,
Hans
PATCH v2 6/6 media: vicodec: Add support for resolution change event.
In reply to Dafna HirschfeldIf the the queues are not streaming then the first resolution change is handled in the buf_queue callback.
The following resolution change events are handled in job_ready.
--- drivers/media/platform/vicodec/vicodec-core.c | 381 ++++++++++++++---- 1 file changed, 304 insertions(+), 77 deletions(-)
drivers/media/platform/vicodec/vicodec-core.c +304 -77
@@ -129,6 +129,8 @@ struct vicodec_ctx {u32 comp_frame_size;bool comp_has_frame;bool comp_has_next_frame; +bool first_source_change_sent; +bool source_changed; };static inline struct vicodec_ctx *file2ctx (struct file *file)
@@ -322,6 +324,107 @@ static void job_remove_src_buf(struct vicodec_ctx *ctx, u32 state)spin_unlock (ctx->lock); } +static const struct v4l2_fwht_pixfmt_info *info_from_header (struct fwht_cframe_hdr p_hdr) +{ +unsigned int flags =ntohl (p_hdr.flags); +unsigned int width_div = (flags &FWHT_FL_CHROMA_FULL_WIDTH ) ?1 :2 ; +unsigned int height_div = (flags &FWHT_FL_CHROMA_FULL_HEIGHT ) ?1 :2 ; +unsigned int components_num =3 ; +unsigned int pixenc =0 ; +unsigned int version =ntohl (p_hdr.version); + +if (version ==FWHT_VERSION ) { + components_num =1 + ((flags &FWHT_FL_COMPONENTS_NUM_MSK ) >> +FWHT_FL_COMPONENTS_NUM_OFFSET ); + pixenc = (flags &FWHT_FL_PIXENC_MSK ); + } +return v4l2_fwht_default_fmt (width_div, height_div, version, + components_num, pixenc,0 ); +} + +static bool is_header_valid (struct fwht_cframe_hdr p_hdr) +{ +const struct v4l2_fwht_pixfmt_info *info; +unsigned int w =ntohl (p_hdr.width); +unsigned int h =ntohl (p_hdr.height); +unsigned int version =ntohl (p_hdr.version); +unsigned int flags =ntohl (p_hdr.flags); + +if (p_hdr.magic1 !=FWHT_MAGIC1 || p_hdr.magic2 !=FWHT_MAGIC2 ) +return false; + +if (!version || version >FWHT_VERSION ) +return false; + +if (w <MIN_WIDTH || w >MAX_WIDTH || h <MIN_HEIGHT || h >MAX_HEIGHT ) +return false; + +if (version ==FWHT_VERSION ) { +unsigned int components_num =1 + + ((flags &FWHT_FL_COMPONENTS_NUM_MSK ) >> +FWHT_FL_COMPONENTS_NUM_OFFSET ); +unsigned int pixenc = flags &FWHT_FL_PIXENC_MSK ; + +if (components_num ==0 || components_num >4 || pixenc ==BIT (19 )) +return false; + } + + info =info_from_header (p_hdr); +if (!info) +return false; +return true; +} + +static void update_capture_data_from_header (struct vicodec_ctx *ctx) +{ +struct vicodec_q_data *q_dst =get_q_data (ctx, +V4L2_BUF_TYPE_VIDEO_CAPTURE ); +struct fwht_cframe_hdr p_hdr = ctx->state.header; +const struct v4l2_fwht_pixfmt_info *info =info_from_header (p_hdr); +unsigned int flags =ntohl (p_hdr.flags); +unsigned int hdr_width_div = (flags &FWHT_FL_CHROMA_FULL_WIDTH ) ?1 :2 ; +unsigned int hdr_height_div = (flags &FWHT_FL_CHROMA_FULL_HEIGHT ) ?1 :2 ; + + q_dst->info = info; + q_dst->visible_width =ntohl (p_hdr.width); + q_dst->visible_height =ntohl (p_hdr.height); + q_dst->coded_width =vic_round_dim (q_dst->visible_width, hdr_width_div); + q_dst->coded_height =vic_round_dim (q_dst->visible_height, + hdr_height_div); + + q_dst->sizeimage = q_dst->coded_width * q_dst->coded_height * + q_dst->info->sizeimage_mult / q_dst->info->sizeimage_div; + ctx->state.colorspace =ntohl (p_hdr.colorspace); + + ctx->state.xfer_func =ntohl (p_hdr.xfer_func); + ctx->state.ycbcr_enc =ntohl (p_hdr.ycbcr_enc); + ctx->state.quantization =ntohl (p_hdr.quantization); +} + +static void set_last_buffer (struct vb2_v4l2_buffer *dst_buf, +struct vb2_v4l2_buffer *src_buf, +struct vicodec_ctx *ctx) +{ +struct vicodec_q_data *q_dst =get_q_data (ctx, +V4L2_BUF_TYPE_VIDEO_CAPTURE ); + +vb2_set_plane_payload (&dst_buf->vb2_buf,0 ,0 ); + dst_buf->sequence = q_dst->sequence++; + dst_buf->vb2_buf.timestamp = src_buf->vb2_buf.timestamp; + +if (src_buf->flags &V4L2_BUF_FLAG_TIMECODE ) + dst_buf->timecode = src_buf->timecode; + dst_buf->field = src_buf->field; + dst_buf->flags |= src_buf->flags & + (V4L2_BUF_FLAG_TIMECODE | +V4L2_BUF_FLAG_KEYFRAME | +V4L2_BUF_FLAG_PFRAME | +V4L2_BUF_FLAG_BFRAME | +V4L2_BUF_FLAG_TSTAMP_SRC_MASK ); + dst_buf->flags |=V4L2_BUF_FLAG_LAST ; +v4l2_m2m_buf_done (dst_buf,VB2_BUF_STATE_DONE ); +} +static int job_ready (void *priv) {static const u8 magic[] = {
@@ -333,7 +436,15 @@ static int job_ready(void *priv)u8 *p;u32 sz;u32 state; - +struct vicodec_q_data *q_dst =get_q_data (ctx, +V4L2_BUF_TYPE_VIDEO_CAPTURE ); +unsigned int flags; +unsigned int hdr_width_div; +unsigned int hdr_height_div; +unsigned int max_to_copy; + +if (ctx->source_changed) +return 0 ;if (ctx->is_enc || ctx->comp_has_frame)return 1 ;
@@ -358,11 +469,17 @@ static int job_ready(void *priv) ctx->comp_frame_size =ntohl (ctx->state.header.size); -if (ctx->comp_frame_size > ctx->comp_max_size) - ctx->comp_frame_size = ctx->comp_max_size; +/* +* The current scanned frame might be the first frame of a new +* resolution so its size might be larger than ctx->comp_max_size. +* In that case it is copied up to the current buffer capacity and +* the copy will continue after allocating new large enough buffer +* when restreaming +*/ + max_to_copy =min (ctx->comp_frame_size, ctx->comp_max_size); -if (ctx->comp_size < ctx->comp_frame_size) { -u32 copy = ctx->comp_frame_size - ctx->comp_size; +if (ctx->comp_size < max_to_copy) { +u32 copy = max_to_copy - ctx->comp_size;if (copy > p_src + sz - p) copy = p_src + sz - p;
@@ -371,15 +488,16 @@ static int job_ready(void *priv) p, copy); p += copy; ctx->comp_size += copy; -if (ctx->comp_size < ctx->comp_frame_size) { +if (ctx->comp_size < max_to_copy) {job_remove_src_buf (ctx, state); goto restart; } } ctx->cur_buf_offset = p - p_src; - ctx->comp_has_frame = true; +if (ctx->comp_size == ctx->comp_frame_size) + ctx->comp_has_frame = true; ctx->comp_has_next_frame = false; -if (sz - ctx->cur_buf_offset >=sizeof (struct fwht_cframe_hdr )) { +if (ctx->comp_has_frame && sz - ctx->cur_buf_offset >=sizeof (struct fwht_cframe_hdr )) {struct fwht_cframe_hdr *p_hdr = (struct fwht_cframe_hdr *)p;u32 frame_size =ntohl (p_hdr->size);u32 remaining = sz - ctx->cur_buf_offset -sizeof (*p_hdr);
@@ -387,6 +505,36 @@ static int job_ready(void *priv)if (!memcmp (p, magic,sizeof (magic))) ctx->comp_has_next_frame = remaining >= frame_size; } +/* +* if the header is invalid the device_run will just drop the frame +* with an error +*/ +if (!is_header_valid (ctx->state.header) && ctx->comp_has_frame) +return 1 ; + flags =ntohl (ctx->state.header.flags); + hdr_width_div = (flags &FWHT_FL_CHROMA_FULL_WIDTH ) ?1 :2 ; + hdr_height_div = (flags &FWHT_FL_CHROMA_FULL_HEIGHT ) ?1 :2 ; + +if (ntohl (ctx->state.header.width) != q_dst->visible_width || +ntohl (ctx->state.header.height) != q_dst->visible_height || + !q_dst->info || + hdr_width_div != q_dst->info->width_div || + hdr_height_div != q_dst->info->height_div) { +static const struct v4l2_event rs_event = { + .type =V4L2_EVENT_SOURCE_CHANGE , + .u.src_change.changes =V4L2_EVENT_SRC_CH_RESOLUTION , + }; + +struct vb2_v4l2_buffer *dst_buf = +v4l2_m2m_dst_buf_remove (ctx->fh.m2m_ctx); + +update_capture_data_from_header (ctx); + ctx->first_source_change_sent = true; +v4l2_event_queue_fh (&ctx->fh, &rs_event); +set_last_buffer (dst_buf, src_buf, ctx); + ctx->source_changed = true; +return 0 ; + }return 1 ; }
@@ -426,7 +574,7 @@ static int enum_fmt(struct v4l2_fmtdesc *f, struct vicodec_ctx *ctx, bool is_outif (is_uncomp) {const struct v4l2_fwht_pixfmt_info *info =get_q_data (ctx, f->type)->info; -if (ctx->is_enc) +if (!info || ctx->is_enc) info =v4l2_fwht_get_pixfmt (f->index);else info = v4l2_fwht_default_fmt(info->width_div,
@@ -477,6 +625,9 @@ static int vidioc_g_fmt(struct vicodec_ctx *ctx, struct v4l2_format *f) q_data =get_q_data (ctx, f->type); info = q_data->info; +if (!info) + info =v4l2_fwht_get_pixfmt (0 ); +switch (f->type) {case V4L2_BUF_TYPE_VIDEO_CAPTURE :case V4L2_BUF_TYPE_VIDEO_OUTPUT :
@@ -950,6 +1101,7 @@ static int vicodec_subscribe_event(struct v4l2_fh *fh, {switch (sub->type) {case V4L2_EVENT_EOS : +case V4L2_EVENT_SOURCE_CHANGE :return v4l2_event_subscribe (fh, sub,0 ,NULL );default :return v4l2_ctrl_subscribe_event (fh, sub);
@@ -1058,7 +1210,64 @@ static void vicodec_buf_queue(struct vb2_buffer *vb) {struct vb2_v4l2_buffer *vbuf =to_vb2_v4l2_buffer (vb);struct vicodec_ctx *ctx =vb2_get_drv_priv (vb->vb2_queue); +unsigned int sz =vb2_get_plane_payload (&vbuf->vb2_buf,0 ); +u8 *p_src =vb2_plane_vaddr (&vbuf->vb2_buf,0 ); +u8 *p = p_src; +struct vb2_queue *vq_out =v4l2_m2m_get_vq (ctx->fh.m2m_ctx, +V4L2_BUF_TYPE_VIDEO_OUTPUT ); +struct vb2_queue *vq_cap =v4l2_m2m_get_vq (ctx->fh.m2m_ctx, +V4L2_BUF_TYPE_VIDEO_CAPTURE ); + +/* buf_queue handles only the first source change event */ +if (ctx->first_source_change_sent) { +v4l2_m2m_buf_queue (ctx->fh.m2m_ctx, vbuf); +return ; + } +/* +* if both queues are streaming, the source change event is +* handled in job_ready +*/ +if (vb2_is_streaming (vq_cap) &&vb2_is_streaming (vq_out)) { +v4l2_m2m_buf_queue (ctx->fh.m2m_ctx, vbuf); +return ; + } + +if (!ctx->is_enc &&V4L2_TYPE_IS_OUTPUT (vb->vb2_queue->type)) { +bool header_valid = false; +static const struct v4l2_event rs_event = { + .type =V4L2_EVENT_SOURCE_CHANGE , + .u.src_change.changes =V4L2_EVENT_SRC_CH_RESOLUTION , + }; + +do { +enum vb2_buffer_state state =get_next_header (ctx, p_src, sz, + (u8 *)&ctx->state.header, + &p); + +if (ctx->header_size <sizeof (struct fwht_cframe_hdr )) { +v4l2_m2m_buf_done (vbuf, state); +return ; + } + header_valid =is_header_valid (ctx->state.header); +/* +* p points right after the end of the header in the +* buffer. If the header is invalid we set p to point +* to the next byte after the start of the header +*/ +if (!header_valid) { + p = p -sizeof (struct fwht_cframe_hdr ) +1 ; + ctx->header_size =0 ; + ctx->comp_magic_cnt =0 ; + } + + }while (!header_valid); +if (p < p_src + sz) + ctx->cur_buf_offset = p - p_src; +update_capture_data_from_header (ctx); + ctx->first_source_change_sent = true; +v4l2_event_queue_fh (&ctx->fh, &rs_event); + }v4l2_m2m_buf_queue (ctx->fh.m2m_ctx, vbuf); }
@@ -1087,73 +1296,80 @@ static int vicodec_start_streaming(struct vb2_queue *q,struct vicodec_q_data *q_data =get_q_data (ctx, q->type);struct v4l2_fwht_state *state = &ctx->state;const struct v4l2_fwht_pixfmt_info *info = q_data->info; -unsigned int size = q_data->coded_width * q_data->coded_height; -unsigned int chroma_div = info->width_div * info->height_div; -unsigned int total_planes_size; -/* -* we don't know ahead how many components are in the encoding type -* V4L2_PIX_FMT_FWHT, so we will allocate space for 4 planes. -*/ -if (info->id ==V4L2_PIX_FMT_FWHT || info->components_num ==4 ) - total_planes_size =2 * size +2 * (size / chroma_div); -else if (info->components_num ==3 ) - total_planes_size = size +2 * (size / chroma_div); -else - total_planes_size = size; +if (!info) +return -EINVAL ; q_data->sequence =0 ; -if (!V4L2_TYPE_IS_OUTPUT (q->type)) { -if (!ctx->is_enc) { - state->visible_width = q_data->visible_width; - state->visible_height = q_data->visible_height; - state->coded_width = q_data->coded_width; - state->coded_height = q_data->coded_height; - state->stride = q_data->coded_width * info->bytesperline_mult; + ctx->last_src_buf =NULL ; + ctx->last_dst_buf =NULL ; + state->gop_cnt =0 ; + +if ((!V4L2_TYPE_IS_OUTPUT (q->type) && !ctx->is_enc) || + (V4L2_TYPE_IS_OUTPUT (q->type) && ctx->is_enc)) { +unsigned int size = q_data->coded_width * q_data->coded_height; +unsigned int chroma_div = info->width_div * info->height_div; +unsigned int total_planes_size; +u8 *new_comp_frame; + +if (!info || info->id ==V4L2_PIX_FMT_FWHT ) { +vicodec_return_bufs (q,VB2_BUF_STATE_QUEUED ); +return -EINVAL ; } -return 0 ; - } +if (info->components_num ==4 ) + total_planes_size =2 * size +2 * (size / chroma_div); +else if (info->components_num ==3 ) + total_planes_size = size +2 * (size / chroma_div); +else + total_planes_size = size; -if (ctx->is_enc) { state->visible_width = q_data->visible_width; state->visible_height = q_data->visible_height; state->coded_width = q_data->coded_width; state->coded_height = q_data->coded_height; state->stride = q_data->coded_width * info->bytesperline_mult; - } - state->ref_frame.luma =kvmalloc (total_planes_size,GFP_KERNEL ); - ctx->comp_max_size = total_planes_size; - state->compressed_frame =kvmalloc (ctx->comp_max_size,GFP_KERNEL ); -if (!state->ref_frame.luma || !state->compressed_frame) { -kvfree (state->ref_frame.luma); -kvfree (state->compressed_frame); -vicodec_return_bufs (q,VB2_BUF_STATE_QUEUED ); -return -ENOMEM ; - } -if (info->id ==V4L2_PIX_FMT_FWHT || info->components_num >=3 ) { - state->ref_frame.cb = state->ref_frame.luma + size; - state->ref_frame.cr = state->ref_frame.cb + size / chroma_div; - }else { - state->ref_frame.cb =NULL ; - state->ref_frame.cr =NULL ; - } -if (info->id ==V4L2_PIX_FMT_FWHT || info->components_num ==4 ) - state->ref_frame.alpha = - state->ref_frame.cr + size / chroma_div; -else - state->ref_frame.alpha =NULL ; + state->ref_frame.luma =kvmalloc (total_planes_size,GFP_KERNEL ); + ctx->comp_max_size = total_planes_size; + new_comp_frame =kvmalloc (ctx->comp_max_size,GFP_KERNEL ); - ctx->last_src_buf =NULL ; - ctx->last_dst_buf =NULL ; - state->gop_cnt =0 ; - ctx->cur_buf_offset =0 ; - ctx->comp_size =0 ; - ctx->header_size =0 ; - ctx->comp_magic_cnt =0 ; - ctx->comp_has_frame = false; +if (!state->ref_frame.luma || !new_comp_frame) { +kvfree (state->ref_frame.luma); +kvfree (new_comp_frame); +vicodec_return_bufs (q,VB2_BUF_STATE_QUEUED ); +return -ENOMEM ; + } +/* +* if state->compressed_frame was already allocated then +* it contain data of the first frame of the new resolution +*/ +if (state->compressed_frame) { +if (ctx->comp_size > ctx->comp_max_size) { + ctx->comp_size = ctx->comp_max_size; + ctx->comp_frame_size = ctx->comp_max_size; + } +memcpy (new_comp_frame, + state->compressed_frame, ctx->comp_size); + } + +kvfree (state->compressed_frame); + state->compressed_frame = new_comp_frame; + +if (info->components_num >=3 ) { + state->ref_frame.cb = state->ref_frame.luma + size; + state->ref_frame.cr = state->ref_frame.cb + size / chroma_div; + }else { + state->ref_frame.cb =NULL ; + state->ref_frame.cr =NULL ; + } +if (info->components_num ==4 ) + state->ref_frame.alpha = + state->ref_frame.cr + size / chroma_div; +else + state->ref_frame.alpha =NULL ; + }return 0 ; }
@@ -1163,11 +1379,21 @@ static void vicodec_stop_streaming(struct vb2_queue *q)vicodec_return_bufs (q,VB2_BUF_STATE_ERROR ); -if (!V4L2_TYPE_IS_OUTPUT (q->type)) -return ; - -kvfree (ctx->state.ref_frame.luma); -kvfree (ctx->state.compressed_frame); +if ((!V4L2_TYPE_IS_OUTPUT (q->type) && !ctx->is_enc) || + (V4L2_TYPE_IS_OUTPUT (q->type) && ctx->is_enc)) { +kvfree (ctx->state.ref_frame.luma); + ctx->source_changed = false; + } +if (V4L2_TYPE_IS_OUTPUT (q->type) && !ctx->is_enc) { + ctx->cur_buf_offset =0 ; + ctx->comp_max_size =0 ; + ctx->comp_size =0 ; + ctx->header_size =0 ; + ctx->comp_magic_cnt =0 ; + ctx->comp_frame_size =0 ; + ctx->comp_has_frame =0 ; + ctx->comp_has_next_frame =0 ; + } }static const struct vb2_ops vicodec_qops = {
@@ -1319,16 +1545,17 @@ static int vicodec_open(struct file *file)else ctx->q_data[V4L2_M2M_SRC ].sizeimage = size +sizeof (struct fwht_cframe_hdr ); - ctx->q_data[V4L2_M2M_DST ] = ctx->q_data[V4L2_M2M_SRC ]; - ctx->q_data[V4L2_M2M_DST ].info = - ctx->is_enc ? &pixfmt_fwht :v4l2_fwht_get_pixfmt (0 ); - size =1280 *720 * ctx->q_data[V4L2_M2M_DST ].info->sizeimage_mult / - ctx->q_data[V4L2_M2M_DST ].info->sizeimage_div; -if (ctx->is_enc) - ctx->q_data[V4L2_M2M_DST ].sizeimage = - size +sizeof (struct fwht_cframe_hdr ); -else - ctx->q_data[V4L2_M2M_DST ].sizeimage = size; +if (ctx->is_enc) { + ctx->q_data[V4L2_M2M_DST ] = ctx->q_data[V4L2_M2M_SRC ]; + ctx->q_data[V4L2_M2M_DST ].info = &pixfmt_fwht; + ctx->q_data[V4L2_M2M_DST ].sizeimage =1280 *720 * + ctx->q_data[V4L2_M2M_DST ].info->sizeimage_mult / + ctx->q_data[V4L2_M2M_DST ].info->sizeimage_div + +sizeof (struct fwht_cframe_hdr ); + }else { + ctx->q_data[V4L2_M2M_DST ].info =NULL ; + } + ctx->state.colorspace =V4L2_COLORSPACE_REC709 ;if (ctx->is_enc) {
Signature · 1 line
2.17.1
Re: [PATCH v2 6/6] media: vicodec: Add support for resolution change event.
Quoted 44 lines · Dafna Hirschfeld
If the the queues are not streaming then the first resolution change is handled in the
buf_queuecallback.
The following resolution change events are handled injob_ready.Signed-off-by Dafna Hirschfeld <[email protected]>--- drivers/media/platform/vicodec/vicodec-core.c | 381 ++++++++++++++---- 1 file changed, 304 insertions(+), 77 deletions(-)drivers/media/platform/vicodec/vicodec-core.c +20
-0@@ -129,6 +129,8 @@ struct vicodec_ctx {u32 comp_frame_size;bool comp_has_frame;bool comp_has_next_frame; +bool first_source_change_sent; +bool source_changed; };static inline struct vicodec_ctx *file2ctx (struct file *file)@@ -322,6 +324,107 @@ static void job_remove_src_buf(struct vicodec_ctx *ctx, u32 state)spin_unlock (ctx->lock); } +static const struct v4l2_fwht_pixfmt_info *info_from_header (struct fwht_cframe_hdr p_hdr) +{ +unsigned int flags =ntohl (p_hdr.flags); +unsigned int width_div = (flags &FWHT_FL_CHROMA_FULL_WIDTH ) ?1 :2 ; +unsigned int height_div = (flags &FWHT_FL_CHROMA_FULL_HEIGHT ) ?1 :2 ; +unsigned int components_num =3 ; +unsigned int pixenc =0 ; +unsigned int version =ntohl (p_hdr.version); + +if (version ==FWHT_VERSION ) { + components_num =1 + ((flags &FWHT_FL_COMPONENTS_NUM_MSK ) >> +FWHT_FL_COMPONENTS_NUM_OFFSET ); + pixenc = (flags &FWHT_FL_PIXENC_MSK ); + } +return v4l2_fwht_default_fmt (width_div, height_div, version, + components_num, pixenc,0 ); +} +
drivers/media/platform/vicodec/vicodec-core.c static void job_remove_src_buf(struct vicodec_ctx *ctx, u32 state) · line 354
Quoted 10 lines
drivers/media/platform/vicodec/vicodec-core.c +10
-0+static bool is_header_valid (struct fwht_cframe_hdr p_hdr) +{ +const struct v4l2_fwht_pixfmt_info *info; +unsigned int w =ntohl (p_hdr.width); +unsigned int h =ntohl (p_hdr.height); +unsigned int version =ntohl (p_hdr.version); +unsigned int flags =ntohl (p_hdr.flags); + +if (p_hdr.magic1 !=FWHT_MAGIC1 || p_hdr.magic2 !=FWHT_MAGIC2 ) +return false;
I don't think this check is needed since you can never get here unless the magic sequence was found.
Quoted 41 lines
drivers/media/platform/vicodec/vicodec-core.c +41
-0+ +if (!version || version >FWHT_VERSION ) +return false; + +if (w <MIN_WIDTH || w >MAX_WIDTH || h <MIN_HEIGHT || h >MAX_HEIGHT ) +return false; + +if (version ==FWHT_VERSION ) { +unsigned int components_num =1 + + ((flags &FWHT_FL_COMPONENTS_NUM_MSK ) >> +FWHT_FL_COMPONENTS_NUM_OFFSET ); +unsigned int pixenc = flags &FWHT_FL_PIXENC_MSK ; + +if (components_num ==0 || components_num >4 || pixenc ==BIT (19 )) +return false; + } + + info =info_from_header (p_hdr); +if (!info) +return false; +return true; +} + +static void update_capture_data_from_header (struct vicodec_ctx *ctx) +{ +struct vicodec_q_data *q_dst =get_q_data (ctx, +V4L2_BUF_TYPE_VIDEO_CAPTURE ); +struct fwht_cframe_hdr p_hdr = ctx->state.header; +const struct v4l2_fwht_pixfmt_info *info =info_from_header (p_hdr); +unsigned int flags =ntohl (p_hdr.flags); +unsigned int hdr_width_div = (flags &FWHT_FL_CHROMA_FULL_WIDTH ) ?1 :2 ; +unsigned int hdr_height_div = (flags &FWHT_FL_CHROMA_FULL_HEIGHT ) ?1 :2 ; + + q_dst->info = info; + q_dst->visible_width =ntohl (p_hdr.width); + q_dst->visible_height =ntohl (p_hdr.height); + q_dst->coded_width =vic_round_dim (q_dst->visible_width, hdr_width_div); + q_dst->coded_height =vic_round_dim (q_dst->visible_height, + hdr_height_div); + + q_dst->sizeimage = q_dst->coded_width * q_dst->coded_height *
drivers/media/platform/vicodec/vicodec-core.c static void job_remove_src_buf(struct vicodec_ctx *ctx, u32 state) · line 405
Quoted 10 lines
drivers/media/platform/vicodec/vicodec-core.c +10
-0+ q_dst->info->sizeimage_mult / q_dst->info->sizeimage_div; + ctx->state.colorspace =ntohl (p_hdr.colorspace); + + ctx->state.xfer_func =ntohl (p_hdr.xfer_func); + ctx->state.ycbcr_enc =ntohl (p_hdr.ycbcr_enc); + ctx->state.quantization =ntohl (p_hdr.quantization); +} + +static void set_last_buffer(struct vb2_v4l2_buffer *dst_buf, + struct vb2_v4l2_buffer *src_buf,
src_buf should be made const.
Quoted 8 lines
drivers/media/platform/vicodec/vicodec-core.c +8
-0+ struct vicodec_ctx *ctx) +{ +struct vicodec_q_data *q_dst =get_q_data (ctx, +V4L2_BUF_TYPE_VIDEO_CAPTURE ); + +vb2_set_plane_payload (&dst_buf->vb2_buf,0 ,0 ); + dst_buf->sequence = q_dst->sequence++; + dst_buf->vb2_buf.timestamp = src_buf->vb2_buf.timestamp;
drivers/media/platform/vicodec/vicodec-core.c static void job_remove_src_buf(struct vicodec_ctx *ctx, u32 state) · line 423
Quoted 10 lines
drivers/media/platform/vicodec/vicodec-core.c +10
-0+ +if (src_buf->flags &V4L2_BUF_FLAG_TIMECODE ) + dst_buf->timecode = src_buf->timecode; + dst_buf->field = src_buf->field; + dst_buf->flags |= src_buf->flags & + (V4L2_BUF_FLAG_TIMECODE | +V4L2_BUF_FLAG_KEYFRAME | +V4L2_BUF_FLAG_PFRAME | +V4L2_BUF_FLAG_BFRAME | +V4L2_BUF_FLAG_TSTAMP_SRC_MASK );
Use v4l2_m2m_buf_copy_data(src_buf, dst_buf, true)
Quoted 147 lines
drivers/media/platform/vicodec/vicodec-core.c +75
-9+ dst_buf->flags |=V4L2_BUF_FLAG_LAST ; +v4l2_m2m_buf_done (dst_buf,VB2_BUF_STATE_DONE ); +} +static int job_ready (void *priv) {static const u8 magic[] = {@@ -333,7 +436,15 @@ static int job_ready(void *priv)u8 *p;u32 sz;u32 state; - +struct vicodec_q_data *q_dst =get_q_data (ctx, +V4L2_BUF_TYPE_VIDEO_CAPTURE ); +unsigned int flags; +unsigned int hdr_width_div; +unsigned int hdr_height_div; +unsigned int max_to_copy; + +if (ctx->source_changed) +return 0 ;if (ctx->is_enc || ctx->comp_has_frame)return 1 ;@@ -358,11 +469,17 @@ static int job_ready(void *priv) ctx->comp_frame_size =ntohl (ctx->state.header.size); -if (ctx->comp_frame_size > ctx->comp_max_size) - ctx->comp_frame_size = ctx->comp_max_size; +/* +* The current scanned frame might be the first frame of a new +* resolution so its size might be larger than ctx->comp_max_size. +* In that case it is copied up to the current buffer capacity and +* the copy will continue after allocating new large enough buffer +* when restreaming +*/ + max_to_copy =min (ctx->comp_frame_size, ctx->comp_max_size); -if (ctx->comp_size < ctx->comp_frame_size) { -u32 copy = ctx->comp_frame_size - ctx->comp_size; +if (ctx->comp_size < max_to_copy) { +u32 copy = max_to_copy - ctx->comp_size;if (copy > p_src + sz - p) copy = p_src + sz - p;@@ -371,15 +488,16 @@ static int job_ready(void *priv) p, copy); p += copy; ctx->comp_size += copy; -if (ctx->comp_size < ctx->comp_frame_size) { +if (ctx->comp_size < max_to_copy) {job_remove_src_buf (ctx, state); goto restart; } } ctx->cur_buf_offset = p - p_src; - ctx->comp_has_frame = true; +if (ctx->comp_size == ctx->comp_frame_size) + ctx->comp_has_frame = true; ctx->comp_has_next_frame = false; -if (sz - ctx->cur_buf_offset >=sizeof (struct fwht_cframe_hdr )) { +if (ctx->comp_has_frame && sz - ctx->cur_buf_offset >=sizeof (struct fwht_cframe_hdr )) {struct fwht_cframe_hdr *p_hdr = (struct fwht_cframe_hdr *)p;u32 frame_size =ntohl (p_hdr->size);u32 remaining = sz - ctx->cur_buf_offset -sizeof (*p_hdr);@@ -387,6 +505,36 @@ static int job_ready(void *priv)if (!memcmp (p, magic,sizeof (magic))) ctx->comp_has_next_frame = remaining >= frame_size; } +/* +* if the header is invalid the device_run will just drop the frame +* with an error +*/ +if (!is_header_valid (ctx->state.header) && ctx->comp_has_frame) +return 1 ; + flags =ntohl (ctx->state.header.flags); + hdr_width_div = (flags &FWHT_FL_CHROMA_FULL_WIDTH ) ?1 :2 ; + hdr_height_div = (flags &FWHT_FL_CHROMA_FULL_HEIGHT ) ?1 :2 ; + +if (ntohl (ctx->state.header.width) != q_dst->visible_width || +ntohl (ctx->state.header.height) != q_dst->visible_height || + !q_dst->info || + hdr_width_div != q_dst->info->width_div || + hdr_height_div != q_dst->info->height_div) { +static const struct v4l2_event rs_event = { + .type =V4L2_EVENT_SOURCE_CHANGE , + .u.src_change.changes =V4L2_EVENT_SRC_CH_RESOLUTION , + }; + +struct vb2_v4l2_buffer *dst_buf = +v4l2_m2m_dst_buf_remove (ctx->fh.m2m_ctx); + +update_capture_data_from_header (ctx); + ctx->first_source_change_sent = true; +v4l2_event_queue_fh (&ctx->fh, &rs_event); +set_last_buffer (dst_buf, src_buf, ctx); + ctx->source_changed = true; +return 0 ; + }return 1 ; }@@ -426,7 +574,7 @@ static int enum_fmt(struct v4l2_fmtdesc *f, struct vicodec_ctx *ctx, bool is_outif (is_uncomp) {const struct v4l2_fwht_pixfmt_info *info =get_q_data (ctx, f->type)->info; -if (ctx->is_enc) +if (!info || ctx->is_enc) info =v4l2_fwht_get_pixfmt (f->index);else info = v4l2_fwht_default_fmt(info->width_div,@@ -477,6 +625,9 @@ static int vidioc_g_fmt(struct vicodec_ctx *ctx, struct v4l2_format *f) q_data =get_q_data (ctx, f->type); info = q_data->info; +if (!info) + info =v4l2_fwht_get_pixfmt (0 ); +switch (f->type) {case V4L2_BUF_TYPE_VIDEO_CAPTURE :case V4L2_BUF_TYPE_VIDEO_OUTPUT :@@ -950,6 +1101,7 @@ static int vicodec_subscribe_event(struct v4l2_fh *fh, {switch (sub->type) {case V4L2_EVENT_EOS : +case V4L2_EVENT_SOURCE_CHANGE :return v4l2_event_subscribe (fh, sub,0 ,NULL );default :return v4l2_ctrl_subscribe_event (fh, sub);@@ -1058,7 +1210,64 @@ static void vicodec_buf_queue(struct vb2_buffer *vb) {struct vb2_v4l2_buffer *vbuf =to_vb2_v4l2_buffer (vb);struct vicodec_ctx *ctx =vb2_get_drv_priv (vb->vb2_queue); +unsigned int sz =vb2_get_plane_payload (&vbuf->vb2_buf,0 ); +u8 *p_src =vb2_plane_vaddr (&vbuf->vb2_buf,0 ); +u8 *p = p_src; +struct vb2_queue *vq_out =v4l2_m2m_get_vq (ctx->fh.m2m_ctx, +V4L2_BUF_TYPE_VIDEO_OUTPUT ); +struct vb2_queue *vq_cap =v4l2_m2m_get_vq (ctx->fh.m2m_ctx, +V4L2_BUF_TYPE_VIDEO_CAPTURE ); + +/* buf_queue handles only the first source change event */ +if (ctx->first_source_change_sent) { +v4l2_m2m_buf_queue (ctx->fh.m2m_ctx, vbuf); +return ; + }
drivers/media/platform/vicodec/vicodec-core.c static void vicodec_buf_queue(struct vb2_buffer *vb) · line 1235
Quoted 10 lines
drivers/media/platform/vicodec/vicodec-core.c +10
-0+/* +* if both queues are streaming, the source change event is +* handled in job_ready +*/ +if (vb2_is_streaming (vq_cap) &&vb2_is_streaming (vq_out)) { +v4l2_m2m_buf_queue (ctx->fh.m2m_ctx, vbuf); +return ; + } + +if (!ctx->is_enc &&V4L2_TYPE_IS_OUTPUT (vb->vb2_queue->type)) {
Do this instead:
if (ctx->is_enc || !V4L2_TYPE_IS_OUTPUT(vb->vb2_queue->type)) {
v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf);
return;
}Now you can shift the remainder of the code one tab to the left.
Quoted 218 lines
drivers/media/platform/vicodec/vicodec-core.c +113
-68+bool header_valid = false; +static const struct v4l2_event rs_event = { + .type =V4L2_EVENT_SOURCE_CHANGE , + .u.src_change.changes =V4L2_EVENT_SRC_CH_RESOLUTION , + }; + +do { +enum vb2_buffer_state state =get_next_header (ctx, p_src, sz, + (u8 *)&ctx->state.header, + &p); + +if (ctx->header_size <sizeof (struct fwht_cframe_hdr )) { +v4l2_m2m_buf_done (vbuf, state); +return ; + } + header_valid =is_header_valid (ctx->state.header); +/* +* p points right after the end of the header in the +* buffer. If the header is invalid we set p to point +* to the next byte after the start of the header +*/ +if (!header_valid) { + p = p -sizeof (struct fwht_cframe_hdr ) +1 ; + ctx->header_size =0 ; + ctx->comp_magic_cnt =0 ; + } + + }while (!header_valid); +if (p < p_src + sz) + ctx->cur_buf_offset = p - p_src; +update_capture_data_from_header (ctx); + ctx->first_source_change_sent = true; +v4l2_event_queue_fh (&ctx->fh, &rs_event); + }v4l2_m2m_buf_queue (ctx->fh.m2m_ctx, vbuf); }@@ -1087,73 +1296,80 @@ static int vicodec_start_streaming(struct vb2_queue *q,struct vicodec_q_data *q_data =get_q_data (ctx, q->type);struct v4l2_fwht_state *state = &ctx->state;const struct v4l2_fwht_pixfmt_info *info = q_data->info; -unsigned int size = q_data->coded_width * q_data->coded_height; -unsigned int chroma_div = info->width_div * info->height_div; -unsigned int total_planes_size; -/* -* we don't know ahead how many components are in the encoding type -* V4L2_PIX_FMT_FWHT, so we will allocate space for 4 planes. -*/ -if (info->id ==V4L2_PIX_FMT_FWHT || info->components_num ==4 ) - total_planes_size =2 * size +2 * (size / chroma_div); -else if (info->components_num ==3 ) - total_planes_size = size +2 * (size / chroma_div); -else - total_planes_size = size; +if (!info) +return -EINVAL ; q_data->sequence =0 ; -if (!V4L2_TYPE_IS_OUTPUT (q->type)) { -if (!ctx->is_enc) { - state->visible_width = q_data->visible_width; - state->visible_height = q_data->visible_height; - state->coded_width = q_data->coded_width; - state->coded_height = q_data->coded_height; - state->stride = q_data->coded_width * info->bytesperline_mult; + ctx->last_src_buf =NULL ; + ctx->last_dst_buf =NULL ; + state->gop_cnt =0 ; + +if ((!V4L2_TYPE_IS_OUTPUT (q->type) && !ctx->is_enc) || + (V4L2_TYPE_IS_OUTPUT (q->type) && ctx->is_enc)) { +unsigned int size = q_data->coded_width * q_data->coded_height; +unsigned int chroma_div = info->width_div * info->height_div; +unsigned int total_planes_size; +u8 *new_comp_frame; + +if (!info || info->id ==V4L2_PIX_FMT_FWHT ) { +vicodec_return_bufs (q,VB2_BUF_STATE_QUEUED ); +return -EINVAL ; } -return 0 ; - } +if (info->components_num ==4 ) + total_planes_size =2 * size +2 * (size / chroma_div); +else if (info->components_num ==3 ) + total_planes_size = size +2 * (size / chroma_div); +else + total_planes_size = size; -if (ctx->is_enc) { state->visible_width = q_data->visible_width; state->visible_height = q_data->visible_height; state->coded_width = q_data->coded_width; state->coded_height = q_data->coded_height; state->stride = q_data->coded_width * info->bytesperline_mult; - } - state->ref_frame.luma =kvmalloc (total_planes_size,GFP_KERNEL ); - ctx->comp_max_size = total_planes_size; - state->compressed_frame =kvmalloc (ctx->comp_max_size,GFP_KERNEL ); -if (!state->ref_frame.luma || !state->compressed_frame) { -kvfree (state->ref_frame.luma); -kvfree (state->compressed_frame); -vicodec_return_bufs (q,VB2_BUF_STATE_QUEUED ); -return -ENOMEM ; - } -if (info->id ==V4L2_PIX_FMT_FWHT || info->components_num >=3 ) { - state->ref_frame.cb = state->ref_frame.luma + size; - state->ref_frame.cr = state->ref_frame.cb + size / chroma_div; - }else { - state->ref_frame.cb =NULL ; - state->ref_frame.cr =NULL ; - } -if (info->id ==V4L2_PIX_FMT_FWHT || info->components_num ==4 ) - state->ref_frame.alpha = - state->ref_frame.cr + size / chroma_div; -else - state->ref_frame.alpha =NULL ; + state->ref_frame.luma =kvmalloc (total_planes_size,GFP_KERNEL ); + ctx->comp_max_size = total_planes_size; + new_comp_frame =kvmalloc (ctx->comp_max_size,GFP_KERNEL ); - ctx->last_src_buf =NULL ; - ctx->last_dst_buf =NULL ; - state->gop_cnt =0 ; - ctx->cur_buf_offset =0 ; - ctx->comp_size =0 ; - ctx->header_size =0 ; - ctx->comp_magic_cnt =0 ; - ctx->comp_has_frame = false; +if (!state->ref_frame.luma || !new_comp_frame) { +kvfree (state->ref_frame.luma); +kvfree (new_comp_frame); +vicodec_return_bufs (q,VB2_BUF_STATE_QUEUED ); +return -ENOMEM ; + } +/* +* if state->compressed_frame was already allocated then +* it contain data of the first frame of the new resolution +*/ +if (state->compressed_frame) { +if (ctx->comp_size > ctx->comp_max_size) { + ctx->comp_size = ctx->comp_max_size; + ctx->comp_frame_size = ctx->comp_max_size; + } +memcpy (new_comp_frame, + state->compressed_frame, ctx->comp_size); + } + +kvfree (state->compressed_frame); + state->compressed_frame = new_comp_frame; + +if (info->components_num >=3 ) { + state->ref_frame.cb = state->ref_frame.luma + size; + state->ref_frame.cr = state->ref_frame.cb + size / chroma_div; + }else { + state->ref_frame.cb =NULL ; + state->ref_frame.cr =NULL ; + } +if (info->components_num ==4 ) + state->ref_frame.alpha = + state->ref_frame.cr + size / chroma_div; +else + state->ref_frame.alpha =NULL ; + }return 0 ; }@@ -1163,11 +1379,21 @@ static void vicodec_stop_streaming(struct vb2_queue *q)vicodec_return_bufs (q,VB2_BUF_STATE_ERROR ); -if (!V4L2_TYPE_IS_OUTPUT (q->type)) -return ; - -kvfree (ctx->state.ref_frame.luma); -kvfree (ctx->state.compressed_frame); +if ((!V4L2_TYPE_IS_OUTPUT (q->type) && !ctx->is_enc) || + (V4L2_TYPE_IS_OUTPUT (q->type) && ctx->is_enc)) { +kvfree (ctx->state.ref_frame.luma); + ctx->source_changed = false; + } +if (V4L2_TYPE_IS_OUTPUT (q->type) && !ctx->is_enc) { + ctx->cur_buf_offset =0 ; + ctx->comp_max_size =0 ; + ctx->comp_size =0 ; + ctx->header_size =0 ; + ctx->comp_magic_cnt =0 ; + ctx->comp_frame_size =0 ; + ctx->comp_has_frame =0 ; + ctx->comp_has_next_frame =0 ; + } }static const struct vb2_ops vicodec_qops = {@@ -1319,16 +1545,17 @@ static int vicodec_open(struct file *file)else ctx->q_data[V4L2_M2M_SRC ].sizeimage = size +sizeof (struct fwht_cframe_hdr ); - ctx->q_data[V4L2_M2M_DST ] = ctx->q_data[V4L2_M2M_SRC ]; - ctx->q_data[V4L2_M2M_DST ].info = - ctx->is_enc ? &pixfmt_fwht :v4l2_fwht_get_pixfmt (0 ); - size =1280 *720 * ctx->q_data[V4L2_M2M_DST ].info->sizeimage_mult / - ctx->q_data[V4L2_M2M_DST ].info->sizeimage_div; -if (ctx->is_enc) - ctx->q_data[V4L2_M2M_DST ].sizeimage = - size +sizeof (struct fwht_cframe_hdr ); -else - ctx->q_data[V4L2_M2M_DST ].sizeimage = size; +if (ctx->is_enc) { + ctx->q_data[V4L2_M2M_DST ] = ctx->q_data[V4L2_M2M_SRC ]; + ctx->q_data[V4L2_M2M_DST ].info = &pixfmt_fwht; + ctx->q_data[V4L2_M2M_DST].sizeimage = 1280 * 720 *
drivers/media/platform/vicodec/vicodec-core.c static int vicodec_open(struct file *file) · line 1561
Quoted 10 lines
drivers/media/platform/vicodec/vicodec-core.c +7
-0+ ctx->q_data[V4L2_M2M_DST ].info->sizeimage_mult / + ctx->q_data[V4L2_M2M_DST ].info->sizeimage_div + +sizeof (struct fwht_cframe_hdr ); + }else { + ctx->q_data[V4L2_M2M_DST ].info =NULL ; + } + ctx->state.colorspace =V4L2_COLORSPACE_REC709 ;if (ctx->is_enc) {
To be honest, this patch is hard to follow. Not your fault, it simply is difficult code. I think that I will merge a v3 (with all the comments fixed) and then see if I can refactor things to make the code easier to understand.
And while I do that, you can start work on the stateless codec, which is after all the goal of your project :-)
Regards,
Hans
Re: [PATCH v2 6/6] media: vicodec: Add support for resolution change event.
In reply to Dafna HirschfeldQuoted 9 lines · Dafna Hirschfeld
If the the queues are not streaming then the first resolution change is handled in the
buf_queuecallback.
The following resolution change events are handled injob_ready.Signed-off-by Dafna Hirschfeld <[email protected]>--- drivers/media/platform/vicodec/vicodec-core.c | 381 ++++++++++++++---- 1 file changed, 304 insertions(+), 77 deletions(-)
<snip>
Quoted 26 lines
drivers/media/platform/vicodec/vicodec-core.c +2
-16@@ -1087,73 +1296,80 @@ static int vicodec_start_streaming(struct vb2_queue *q,struct vicodec_q_data *q_data =get_q_data (ctx, q->type);struct v4l2_fwht_state *state = &ctx->state;const struct v4l2_fwht_pixfmt_info *info = q_data->info; -unsigned int size = q_data->coded_width * q_data->coded_height; -unsigned int chroma_div = info->width_div * info->height_div; -unsigned int total_planes_size; -/* -* we don't know ahead how many components are in the encoding type -* V4L2_PIX_FMT_FWHT, so we will allocate space for 4 planes. -*/ -if (info->id ==V4L2_PIX_FMT_FWHT || info->components_num ==4 ) - total_planes_size =2 * size +2 * (size / chroma_div); -else if (info->components_num ==3 ) - total_planes_size = size +2 * (size / chroma_div); -else - total_planes_size = size; +if (!info) +return -EINVAL ; q_data->sequence =0 ; -if (!V4L2_TYPE_IS_OUTPUT (q->type)) { -if (!ctx->is_enc) { - state->visible_width = q_data->visible_width;
drivers/media/platform/vicodec/vicodec-core.c static int vicodec_start_streaming(struct vb2_queue *q, · line 1310
Quoted 10 lines
drivers/media/platform/vicodec/vicodec-core.c +6
-4- state->visible_height = q_data->visible_height; - state->coded_width = q_data->coded_width; - state->coded_height = q_data->coded_height; - state->stride = q_data->coded_width * info->bytesperline_mult; + ctx->last_src_buf =NULL ; + ctx->last_dst_buf =NULL ; + state->gop_cnt =0 ; + +if ((!V4L2_TYPE_IS_OUTPUT (q->type) && !ctx->is_enc) || + (V4L2_TYPE_IS_OUTPUT (q->type) && ctx->is_enc)) {
You can simplify this by doing:
if ((V4L2_TYPE_IS_OUTPUT(q->type) && !ctx->is_enc) || (!V4L2_TYPE_IS_OUTPUT(q->type) && ctx->is_enc)) return 0;
And the remainder can be shifted one tab to the left.
Regards,
Hans
Quoted 154 lines
drivers/media/platform/vicodec/vicodec-core.c +78
-48+unsigned int size = q_data->coded_width * q_data->coded_height; +unsigned int chroma_div = info->width_div * info->height_div; +unsigned int total_planes_size; +u8 *new_comp_frame; + +if (!info || info->id ==V4L2_PIX_FMT_FWHT ) { +vicodec_return_bufs (q,VB2_BUF_STATE_QUEUED ); +return -EINVAL ; } -return 0 ; - } +if (info->components_num ==4 ) + total_planes_size =2 * size +2 * (size / chroma_div); +else if (info->components_num ==3 ) + total_planes_size = size +2 * (size / chroma_div); +else + total_planes_size = size; -if (ctx->is_enc) { state->visible_width = q_data->visible_width; state->visible_height = q_data->visible_height; state->coded_width = q_data->coded_width; state->coded_height = q_data->coded_height; state->stride = q_data->coded_width * info->bytesperline_mult; - } - state->ref_frame.luma =kvmalloc (total_planes_size,GFP_KERNEL ); - ctx->comp_max_size = total_planes_size; - state->compressed_frame =kvmalloc (ctx->comp_max_size,GFP_KERNEL ); -if (!state->ref_frame.luma || !state->compressed_frame) { -kvfree (state->ref_frame.luma); -kvfree (state->compressed_frame); -vicodec_return_bufs (q,VB2_BUF_STATE_QUEUED ); -return -ENOMEM ; - } -if (info->id ==V4L2_PIX_FMT_FWHT || info->components_num >=3 ) { - state->ref_frame.cb = state->ref_frame.luma + size; - state->ref_frame.cr = state->ref_frame.cb + size / chroma_div; - }else { - state->ref_frame.cb =NULL ; - state->ref_frame.cr =NULL ; - } -if (info->id ==V4L2_PIX_FMT_FWHT || info->components_num ==4 ) - state->ref_frame.alpha = - state->ref_frame.cr + size / chroma_div; -else - state->ref_frame.alpha =NULL ; + state->ref_frame.luma =kvmalloc (total_planes_size,GFP_KERNEL ); + ctx->comp_max_size = total_planes_size; + new_comp_frame =kvmalloc (ctx->comp_max_size,GFP_KERNEL ); - ctx->last_src_buf =NULL ; - ctx->last_dst_buf =NULL ; - state->gop_cnt =0 ; - ctx->cur_buf_offset =0 ; - ctx->comp_size =0 ; - ctx->header_size =0 ; - ctx->comp_magic_cnt =0 ; - ctx->comp_has_frame = false; +if (!state->ref_frame.luma || !new_comp_frame) { +kvfree (state->ref_frame.luma); +kvfree (new_comp_frame); +vicodec_return_bufs (q,VB2_BUF_STATE_QUEUED ); +return -ENOMEM ; + } +/* +* if state->compressed_frame was already allocated then +* it contain data of the first frame of the new resolution +*/ +if (state->compressed_frame) { +if (ctx->comp_size > ctx->comp_max_size) { + ctx->comp_size = ctx->comp_max_size; + ctx->comp_frame_size = ctx->comp_max_size; + } +memcpy (new_comp_frame, + state->compressed_frame, ctx->comp_size); + } + +kvfree (state->compressed_frame); + state->compressed_frame = new_comp_frame; + +if (info->components_num >=3 ) { + state->ref_frame.cb = state->ref_frame.luma + size; + state->ref_frame.cr = state->ref_frame.cb + size / chroma_div; + }else { + state->ref_frame.cb =NULL ; + state->ref_frame.cr =NULL ; + } +if (info->components_num ==4 ) + state->ref_frame.alpha = + state->ref_frame.cr + size / chroma_div; +else + state->ref_frame.alpha =NULL ; + }return 0 ; }@@ -1163,11 +1379,21 @@ static void vicodec_stop_streaming(struct vb2_queue *q)vicodec_return_bufs (q,VB2_BUF_STATE_ERROR ); -if (!V4L2_TYPE_IS_OUTPUT (q->type)) -return ; - -kvfree (ctx->state.ref_frame.luma); -kvfree (ctx->state.compressed_frame); +if ((!V4L2_TYPE_IS_OUTPUT (q->type) && !ctx->is_enc) || + (V4L2_TYPE_IS_OUTPUT (q->type) && ctx->is_enc)) { +kvfree (ctx->state.ref_frame.luma); + ctx->source_changed = false; + } +if (V4L2_TYPE_IS_OUTPUT (q->type) && !ctx->is_enc) { + ctx->cur_buf_offset =0 ; + ctx->comp_max_size =0 ; + ctx->comp_size =0 ; + ctx->header_size =0 ; + ctx->comp_magic_cnt =0 ; + ctx->comp_frame_size =0 ; + ctx->comp_has_frame =0 ; + ctx->comp_has_next_frame =0 ; + } }static const struct vb2_ops vicodec_qops = {@@ -1319,16 +1545,17 @@ static int vicodec_open(struct file *file)else ctx->q_data[V4L2_M2M_SRC ].sizeimage = size +sizeof (struct fwht_cframe_hdr ); - ctx->q_data[V4L2_M2M_DST ] = ctx->q_data[V4L2_M2M_SRC ]; - ctx->q_data[V4L2_M2M_DST ].info = - ctx->is_enc ? &pixfmt_fwht :v4l2_fwht_get_pixfmt (0 ); - size =1280 *720 * ctx->q_data[V4L2_M2M_DST ].info->sizeimage_mult / - ctx->q_data[V4L2_M2M_DST ].info->sizeimage_div; -if (ctx->is_enc) - ctx->q_data[V4L2_M2M_DST ].sizeimage = - size +sizeof (struct fwht_cframe_hdr ); -else - ctx->q_data[V4L2_M2M_DST ].sizeimage = size; +if (ctx->is_enc) { + ctx->q_data[V4L2_M2M_DST ] = ctx->q_data[V4L2_M2M_SRC ]; + ctx->q_data[V4L2_M2M_DST ].info = &pixfmt_fwht; + ctx->q_data[V4L2_M2M_DST ].sizeimage =1280 *720 * + ctx->q_data[V4L2_M2M_DST ].info->sizeimage_mult / + ctx->q_data[V4L2_M2M_DST ].info->sizeimage_div + +sizeof (struct fwht_cframe_hdr ); + }else { + ctx->q_data[V4L2_M2M_DST ].info =NULL ; + } + ctx->state.colorspace =V4L2_COLORSPACE_REC709 ;if (ctx->is_enc) {