Commit 9e812549 authored by Dafna Hirschfeld's avatar Dafna Hirschfeld Committed by Mauro Carvalho Chehab

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: default avatarDafna Hirschfeld <dafna3@gmail.com>
Signed-off-by: default avatarHans Verkuil <hverkuil-cisco@xs4all.nl>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab+samsung@kernel.org>
parent 8c1d02f1
......@@ -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,17 @@ 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 +834,15 @@ 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 +861,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);
}
......@@ -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
......@@ -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;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment