Skip to content

Commit 1fac8cc

Browse files
committed
Updates to odd dimension support.
Reverted some of the unnecessary changes from commit: f6ef16b - Restored the format conversion structure prior to f6ef16b - No need to handle odd stride for 420 and 422 output. - Dimensions for output format 444 and 400 format can be odd Tested with few YUV444 and YUV400 odd dimension clips To generate: $ ffmpeg -f lavfi -i testsrc=s=511x511 -c:v libx265 -pix_fmt yuv444p -t 1 -tag:v hvc1 y444_511x511.hevc $ ffmpeg -f lavfi -i testsrc=s=511x511 -c:v libx265 -pix_fmt gray -t 1 -tag:v hvc1 y400_511x511.hevc To decode using hevcdec for YUV420 output format $ hevcdec -i y444_511x511.hevc -o y444_511x511.yuv --save_output 1 --num_frames -1 --chroma_format YUV_420P --enable_yuv_format 31 $ hevcdec -i y400_511x511.hevc -o y400_511x511.yuv --save_output 1 --num_frames -1 --chroma_format YUV_420P --enable_yuv_format 31 To decode using hevcdec for YUV444 output format $ hevcdec -i y444_511x511.hevc -o y444_511x511.yuv --save_output 1 --num_frames -1 --chroma_format YUV_444P --enable_yuv_format 31 To decode using hevcdec for YUV400 output format $ hevcdec -i y400_511x511.hevc -o y400_511x511.yuv --save_output 1 --num_frames -1 --chroma_format GRAY --enable_yuv_format 31 Display resulting output using ffplay by passing `-f rawvideo -pixel_format yuv420p -video_size 511x511` Change pixel_format to yuv420p/yuv444p/gray based on decoder chroma_format argument
1 parent f6ef16b commit 1fac8cc

4 files changed

Lines changed: 168 additions & 121 deletions

File tree

decoder/ihevcd_api.c

Lines changed: 39 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -2635,6 +2635,7 @@ WORD32 ihevcd_get_status(iv_obj_t *ps_codec_obj,
26352635
WORD32 i;
26362636
codec_t *ps_codec;
26372637
WORD32 wd, ht;
2638+
WORD32 aligned_wd, aligned_ht;
26382639
ivd_ctl_getstatus_op_t *ps_ctl_op = (ivd_ctl_getstatus_op_t *)pv_api_op;
26392640

26402641
UNUSED(pv_api_ip);
@@ -2713,39 +2714,38 @@ WORD32 ihevcd_get_status(iv_obj_t *ps_codec_obj,
27132714
}
27142715

27152716
/*!*/
2716-
WORD32 aligned_wd = ALIGN2(wd);
2717-
WORD32 aligned_ht = ALIGN2(ht);
2717+
aligned_wd = ALIGN2(wd);
2718+
aligned_ht = ALIGN2(ht);
27182719
if(ps_codec->e_chroma_fmt == IV_YUV_420P)
27192720
{
27202721
ps_ctl_op->u4_min_out_buf_size[0] = (aligned_wd * aligned_ht);
2721-
ps_ctl_op->u4_min_out_buf_size[1] = (aligned_wd >> 1) * (aligned_ht >> 1);
2722-
ps_ctl_op->u4_min_out_buf_size[2] = (aligned_wd >> 1) * (aligned_ht >> 1);
2722+
ps_ctl_op->u4_min_out_buf_size[1] = (aligned_wd * aligned_ht) >> 2;
2723+
ps_ctl_op->u4_min_out_buf_size[2] = (aligned_wd * aligned_ht) >> 2;
27232724
}
27242725
else if(ps_codec->e_chroma_fmt == IV_YUV_444P)
27252726
{
2726-
ps_ctl_op->u4_min_out_buf_size[0] = (aligned_wd * aligned_ht);
2727-
ps_ctl_op->u4_min_out_buf_size[1] = (aligned_wd * aligned_ht);
2728-
ps_ctl_op->u4_min_out_buf_size[2] = (aligned_wd * aligned_ht);
2727+
ps_ctl_op->u4_min_out_buf_size[0] = (wd * ht);
2728+
ps_ctl_op->u4_min_out_buf_size[1] = (wd * ht);
2729+
ps_ctl_op->u4_min_out_buf_size[2] = (wd * ht);
27292730
}
27302731
else if((ps_codec->e_chroma_fmt == IV_YUV_420SP_UV)
27312732
|| (ps_codec->e_chroma_fmt == IV_YUV_420SP_VU))
27322733
{
27332734
ps_ctl_op->u4_min_out_buf_size[0] = (aligned_wd * aligned_ht);
2734-
ps_ctl_op->u4_min_out_buf_size[1] = (aligned_wd >> 1) * (aligned_ht >> 1);
2735-
ps_ctl_op->u4_min_out_buf_size[1] <<= 1;
2735+
ps_ctl_op->u4_min_out_buf_size[1] = (aligned_wd * aligned_ht) >> 1;
27362736
ps_ctl_op->u4_min_out_buf_size[2] = 0;
27372737
}
27382738
else if(ps_codec->e_chroma_fmt == IV_GRAY)
27392739
{
2740-
ps_ctl_op->u4_min_out_buf_size[0] = (aligned_wd * aligned_ht);
2740+
ps_ctl_op->u4_min_out_buf_size[0] = (wd * ht);
27412741
ps_ctl_op->u4_min_out_buf_size[1] = 0;
27422742
ps_ctl_op->u4_min_out_buf_size[2] = 0;
27432743
}
27442744
else if(ps_codec->e_chroma_fmt == IV_YUV_422P)
27452745
{
27462746
ps_ctl_op->u4_min_out_buf_size[0] = (aligned_wd * aligned_ht);
2747-
ps_ctl_op->u4_min_out_buf_size[1] = (aligned_wd >> 1) * aligned_ht;
2748-
ps_ctl_op->u4_min_out_buf_size[2] = (aligned_wd >> 1) * aligned_ht;
2747+
ps_ctl_op->u4_min_out_buf_size[1] = (aligned_wd * aligned_ht) >> 1;
2748+
ps_ctl_op->u4_min_out_buf_size[2] = (aligned_wd * aligned_ht) >> 1;
27492749
}
27502750
ps_ctl_op->u4_pic_ht = ht;
27512751
ps_ctl_op->u4_pic_wd = wd;
@@ -2798,6 +2798,7 @@ WORD32 ihevcd_get_buf_info(iv_obj_t *ps_codec_obj,
27982798
codec_t *ps_codec;
27992799
UWORD32 i = 0;
28002800
WORD32 wd, ht;
2801+
WORD32 aligned_wd, aligned_ht;
28012802
ivd_ctl_getbufinfo_op_t *ps_ctl_op =
28022803
(ivd_ctl_getbufinfo_op_t *)pv_api_op;
28032804

@@ -2904,38 +2905,38 @@ WORD32 ihevcd_get_buf_info(iv_obj_t *ps_codec_obj,
29042905
}
29052906

29062907
/*!*/
2907-
WORD32 aligned_wd = ALIGN2(wd);
2908-
WORD32 aligned_ht = ALIGN2(ht);
2908+
aligned_wd = ALIGN2(wd);
2909+
aligned_ht = ALIGN2(ht);
29092910
if(ps_codec->e_chroma_fmt == IV_YUV_420P)
29102911
{
29112912
ps_ctl_op->u4_min_out_buf_size[0] = (aligned_wd * aligned_ht);
2912-
ps_ctl_op->u4_min_out_buf_size[1] = (aligned_wd >> 1) * (aligned_ht >> 1);
2913-
ps_ctl_op->u4_min_out_buf_size[2] = (aligned_wd >> 1) * (aligned_ht >> 1);
2913+
ps_ctl_op->u4_min_out_buf_size[1] = (aligned_wd * aligned_ht) >> 2;
2914+
ps_ctl_op->u4_min_out_buf_size[2] = (aligned_wd * aligned_ht) >> 2;
29142915
}
29152916
else if(ps_codec->e_chroma_fmt == IV_YUV_444P)
29162917
{
2917-
ps_ctl_op->u4_min_out_buf_size[0] = (aligned_wd * aligned_ht);
2918-
ps_ctl_op->u4_min_out_buf_size[1] = (aligned_wd * aligned_ht);
2919-
ps_ctl_op->u4_min_out_buf_size[2] = (aligned_wd * aligned_ht);
2918+
ps_ctl_op->u4_min_out_buf_size[0] = (wd * ht);
2919+
ps_ctl_op->u4_min_out_buf_size[1] = (wd * ht);
2920+
ps_ctl_op->u4_min_out_buf_size[2] = (wd * ht);
29202921
}
29212922
else if((ps_codec->e_chroma_fmt == IV_YUV_420SP_UV)
29222923
|| (ps_codec->e_chroma_fmt == IV_YUV_420SP_VU))
29232924
{
29242925
ps_ctl_op->u4_min_out_buf_size[0] = (aligned_wd * aligned_ht);
2925-
ps_ctl_op->u4_min_out_buf_size[1] = (aligned_wd >> 1) * (aligned_ht >> 1);
2926-
ps_ctl_op->u4_min_out_buf_size[1] <<= 1;
2926+
ps_ctl_op->u4_min_out_buf_size[1] = (aligned_wd * aligned_ht) >> 1;
29272927
ps_ctl_op->u4_min_out_buf_size[2] = 0;
29282928
}
29292929
else if(ps_codec->e_chroma_fmt == IV_GRAY)
29302930
{
2931-
ps_ctl_op->u4_min_out_buf_size[0] = (aligned_wd * aligned_ht);
2932-
ps_ctl_op->u4_min_out_buf_size[1] = ps_ctl_op->u4_min_out_buf_size[2] = 0;
2931+
ps_ctl_op->u4_min_out_buf_size[0] = (wd * ht);
2932+
ps_ctl_op->u4_min_out_buf_size[1] =
2933+
ps_ctl_op->u4_min_out_buf_size[2] = 0;
29332934
}
29342935
else if(ps_codec->e_chroma_fmt == IV_YUV_422P)
29352936
{
29362937
ps_ctl_op->u4_min_out_buf_size[0] = (aligned_wd * aligned_ht);
2937-
ps_ctl_op->u4_min_out_buf_size[1] = (aligned_wd >> 1) * aligned_ht;
2938-
ps_ctl_op->u4_min_out_buf_size[2] = (aligned_wd >> 1) * aligned_ht;
2938+
ps_ctl_op->u4_min_out_buf_size[1] = (aligned_wd * aligned_ht) >> 1;
2939+
ps_ctl_op->u4_min_out_buf_size[2] = (aligned_wd * aligned_ht) >> 1;
29392940
}
29402941
ps_codec->i4_num_disp_bufs = ps_ctl_op->u4_num_disp_bufs;
29412942

@@ -3029,6 +3030,17 @@ WORD32 ihevcd_set_params(iv_obj_t *ps_codec_obj,
30293030
}
30303031
}
30313032

3033+
// output stride needs to be even for all formats other than 400 and 444
3034+
if(ps_codec->e_chroma_fmt != IV_GRAY && ps_codec->e_chroma_fmt != IV_YUV_444P)
3035+
{
3036+
if (strd & 1)
3037+
{
3038+
s_ctl_dynparams_op->u4_error_code |= (1 << IVD_UNSUPPORTEDPARAM);
3039+
s_ctl_dynparams_op->u4_error_code |= IHEVCD_INVALID_DISP_STRD;
3040+
ret = IV_FAIL;
3041+
}
3042+
}
3043+
30323044
ps_codec->i4_disp_strd = strd;
30333045
if(1 == ps_codec->i4_share_disp_buf)
30343046
{
@@ -3306,9 +3318,9 @@ WORD32 ihevcd_get_frame_dimensions(iv_obj_t *ps_codec_obj,
33063318
>> 1);
33073319
ps_op->u4_disp_ht[1] = ps_op->u4_disp_ht[2] = ((ps_op->u4_disp_ht[0] + 1)
33083320
>> 1);
3309-
ps_op->u4_buffer_wd[1] = ps_op->u4_buffer_wd[2] = ((ps_op->u4_buffer_wd[0] + 1)
3321+
ps_op->u4_buffer_wd[1] = ps_op->u4_buffer_wd[2] = (ps_op->u4_buffer_wd[0]
33103322
>> 1);
3311-
ps_op->u4_buffer_ht[1] = ps_op->u4_buffer_ht[2] = ((ps_op->u4_buffer_ht[0] + 1)
3323+
ps_op->u4_buffer_ht[1] = ps_op->u4_buffer_ht[2] = (ps_op->u4_buffer_ht[0]
33123324
>> 1);
33133325
ps_op->u4_x_offset[1] = ps_op->u4_x_offset[2] = (ps_op->u4_x_offset[0]
33143326
>> 1);

decoder/ihevcd_decode.c

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -325,13 +325,14 @@ static void ihevcd_fill_outargs(codec_t *ps_codec,
325325
ps_dec_ip->s_out_buffer.pu1_bufs[1];
326326
ps_dec_op->s_disp_frm_buf.pv_v_buf =
327327
ps_dec_ip->s_out_buffer.pu1_bufs[2];
328-
ps_dec_op->s_disp_frm_buf.u4_y_strd = ALIGN2(ps_codec->i4_disp_strd);
328+
ps_dec_op->s_disp_frm_buf.u4_y_strd = ps_codec->i4_disp_strd;
329329
}
330330

331331
if((IV_YUV_420SP_VU == ps_codec->e_chroma_fmt)
332332
|| (IV_YUV_420SP_UV == ps_codec->e_chroma_fmt))
333333
{
334-
ps_dec_op->s_disp_frm_buf.u4_u_strd = ALIGN2(ps_dec_op->s_disp_frm_buf.u4_y_strd);
334+
ps_dec_op->s_disp_frm_buf.u4_u_strd =
335+
ps_dec_op->s_disp_frm_buf.u4_y_strd;
335336
ps_dec_op->s_disp_frm_buf.u4_v_strd = 0;
336337
ps_dec_op->s_disp_frm_buf.u4_u_wd = ALIGN2(ps_dec_op->s_disp_frm_buf.u4_y_wd);
337338
ps_dec_op->s_disp_frm_buf.u4_v_wd = 0;
@@ -340,17 +341,19 @@ static void ihevcd_fill_outargs(codec_t *ps_codec,
340341
}
341342
else if(IV_YUV_420P == ps_codec->e_chroma_fmt)
342343
{
343-
ps_dec_op->s_disp_frm_buf.u4_u_strd = ALIGN2(ps_dec_op->s_disp_frm_buf.u4_y_strd) / 2;
344-
ps_dec_op->s_disp_frm_buf.u4_v_strd = ALIGN2(ps_dec_op->s_disp_frm_buf.u4_y_strd) / 2;
344+
ps_dec_op->s_disp_frm_buf.u4_u_strd =
345+
ps_dec_op->s_disp_frm_buf.u4_y_strd / 2;
346+
ps_dec_op->s_disp_frm_buf.u4_v_strd =
347+
ps_dec_op->s_disp_frm_buf.u4_y_strd / 2;
345348
ps_dec_op->s_disp_frm_buf.u4_u_wd = ALIGN2(ps_dec_op->s_disp_frm_buf.u4_y_wd) / 2;
346349
ps_dec_op->s_disp_frm_buf.u4_v_wd = ALIGN2(ps_dec_op->s_disp_frm_buf.u4_y_wd) / 2;
347350
ps_dec_op->s_disp_frm_buf.u4_u_ht = ALIGN2(ps_dec_op->s_disp_frm_buf.u4_y_ht) / 2;
348351
ps_dec_op->s_disp_frm_buf.u4_v_ht = ALIGN2(ps_dec_op->s_disp_frm_buf.u4_y_ht) / 2;
349352
}
350353
else if(IV_YUV_444P == ps_codec->e_chroma_fmt)
351354
{
352-
ps_dec_op->s_disp_frm_buf.u4_u_strd = ALIGN2(ps_dec_op->s_disp_frm_buf.u4_y_strd);
353-
ps_dec_op->s_disp_frm_buf.u4_v_strd = ALIGN2(ps_dec_op->s_disp_frm_buf.u4_y_strd);
355+
ps_dec_op->s_disp_frm_buf.u4_u_strd = ps_dec_op->s_disp_frm_buf.u4_y_strd;
356+
ps_dec_op->s_disp_frm_buf.u4_v_strd = ps_dec_op->s_disp_frm_buf.u4_y_strd;
354357
ps_dec_op->s_disp_frm_buf.u4_u_wd = ps_dec_op->s_disp_frm_buf.u4_y_wd;
355358
ps_dec_op->s_disp_frm_buf.u4_v_wd = ps_dec_op->s_disp_frm_buf.u4_y_wd;
356359
ps_dec_op->s_disp_frm_buf.u4_u_ht = ps_dec_op->s_disp_frm_buf.u4_y_ht;
@@ -367,8 +370,10 @@ static void ihevcd_fill_outargs(codec_t *ps_codec,
367370
}
368371
else if(IV_YUV_422P == ps_codec->e_chroma_fmt)
369372
{
370-
ps_dec_op->s_disp_frm_buf.u4_u_strd = ALIGN2(ps_dec_op->s_disp_frm_buf.u4_y_strd) / 2;
371-
ps_dec_op->s_disp_frm_buf.u4_v_strd = ALIGN2(ps_dec_op->s_disp_frm_buf.u4_y_strd) / 2;
373+
ps_dec_op->s_disp_frm_buf.u4_u_strd =
374+
ps_dec_op->s_disp_frm_buf.u4_y_strd / 2;
375+
ps_dec_op->s_disp_frm_buf.u4_v_strd =
376+
ps_dec_op->s_disp_frm_buf.u4_y_strd / 2;
372377
ps_dec_op->s_disp_frm_buf.u4_u_wd = ALIGN2(ps_dec_op->s_disp_frm_buf.u4_y_wd) / 2;
373378
ps_dec_op->s_disp_frm_buf.u4_v_wd = ALIGN2(ps_dec_op->s_disp_frm_buf.u4_y_wd) / 2;
374379
ps_dec_op->s_disp_frm_buf.u4_u_ht = ALIGN2(ps_dec_op->s_disp_frm_buf.u4_y_ht);

0 commit comments

Comments
 (0)