IMX Scaler / CSC m2m driver.
Ian Molton
imolton at ad-holdings.co.uk
Tue Mar 24 05:35:00 PDT 2015
Hi Philipp!
I've located the cause of the "giant oops" I noted a couple of days ago.
because ctx->icc is recycled, it must be a valid or NULL pointer for kfree().
When an error occurs, the pointer is not reset to NULL, and kfree() crashes.
This helps:
@@ -208,10 +208,11 @@ static void ipu_scaler_work(struct work_struct *work)
kfree(ctx->icc);
ctx->icc = ipu_image_convert_prepare(ipu_scaler->ipu, &in,
&out, ctx->ctrl,
&ctx->num_tiles);
if (IS_ERR(ctx->icc)) {
+ ctx->icc = NULL;
schedule_work(&ctx->skip_run);
return;
}
}
This fix "band-aids" it, but I don't think its complete, as IMO, this really
should result in gstreamer giving up, not displaying blank frames.
On the plus side, it does make the whole thing a lot more reliable.
It seems also like this case should be caught a lot earlier.
I've also noticed odd behaviour below width=480; (height=272)
479: works
478: works
477: gstreamer errors out
476: works (but no video output)
475: ditto
747: ditto
743: gstreamer errors out
The error is:
0:00:00.284476334 1216 0xd01e30 ERROR v4l2transform gstv4l2transform.c:239:gst_v4l2_transform_set_caps:<v4l2video0convert0> failed to set output caps: video/x-raw, pixel-aspect-ratio=(fraction)1/1, interlace-mode=(string)progressive, framerate=(fraction)24/1, format=(string)BGRx, width=(int)473, height=(int)272
ERROR: from element /GstPipeline:pipeline0/v4l2video0convert:v4l2video0convert0: Device '/dev/video0' cannot capture at 473x272
Additional debug info:
gstv4l2object.c(2967): gst_v4l2_object_set_format (): /GstPipeline:pipeline0/v4l2video0convert:v4l2video0convert0:
Tried to capture at 473x272, but device returned size 472x272
ERROR: pipeline doesn't want to preroll.
which smells like a shift or bitwise test thats not right.
I'm guessing 478 and 479 are rounding up to 480, but the others aren't.
More comments below:
On 23/03/15 10:22, Philipp Zabel wrote:
>> So would I be right in thinking that this test (and comment) are wrong:
>>
>> /* Cannot downsize more than 8:1 */
>> if ((out_size << 3) < in_size) {
>> dev_err(ipu->dev, "Unsupported downsize\n");
>> return -EINVAL;
>> }
>>
>> (drivers/gpu/ipu-v3/ipu-ic.c)
Ok, so I've changed this thus:
@@ -360,12 +360,12 @@ static int calc_resize_coeffs(struct ipu_ic *ic,
if (out_size > 1024) {
dev_err(ipu->dev, "Unsupported resize (out_size > 1024)\n");
return -EINVAL;
}
- /* Cannot downsize more than 8:1 */
- if ((out_size << 3) < in_size) {
+ /* Cannot downsize more than 4:1 */
+ if ((out_size << 2) < in_size) {
dev_err(ipu->dev, "Unsupported downsize\n");
return -EINVAL;
}
> Exactly. And the error you are hitting is here:
>
> --- a/drivers/gpu/ipu-v3/ipu-ic.c
> +++ b/drivers/gpu/ipu-v3/ipu-ic.c
> @@ -1092,7 +1092,7 @@ struct image_convert_ctx *ipu_image_convert_prepare(struct ipu_soc *ipu,
>
> /* validate input */
> if (in->rect.width < 16 || out->rect.width < 16 ||
> - (in->rect.width / 8) > out->rect.width)
> + (in->rect.width / 4) > out->rect.width)
> return ERR_PTR(-EINVAL);
>
> /* tile setup */
>
> And obviously the v4l2 mem2mem scaler driver should catch this earlier.
This test looks broken still - surely it should check height too?
Something like:
@@ -896,11 +896,12 @@ struct image_convert_ctx *ipu_image_convert_prepare(struct ipu_soc *ipu,
u32 v_downsize_coeff = 0, h_downsize_coeff = 0;
u32 v_resize_coeff, h_resize_coeff;
/* validate input */
if (in->rect.width < 16 || out->rect.width < 16 ||
- (in->rect.width / 8) > out->rect.width)
+ (in->rect.width / 4) > out->rect.width ||
+ (in->rect.height / 4) > out->rect.height)
return ERR_PTR(-EINVAL);
-Ian
More information about the gstreamer-devel
mailing list