[MPlayer-dev-eng] [PATCH] vf_ass: support uyvy and yuy2 directly
Reimar Döffinger
Reimar.Doeffinger at gmx.de
Sat Aug 25 13:18:28 CEST 2012
On Thu, Aug 23, 2012 at 11:28:55PM +0800, Xidorn Quan wrote:
> Hi,
>
> This patch adds uyvy and yuy2 format support for vf_ass. uyvy and yuy2
> pictures then needn't to be convert by scale anymore when using ass.
>
> Though, I think the code can probably be optimized more by using sth
> like MMX, or considering more about CPU cache. But I'm not experienced
> in doing so.
>
> Best Regards,
> Xidorn Quan
> +typedef void (*copy_from_image_t)(struct vf_instance *vf, int first_row, int last_row);
> +typedef void (*copy_to_image_t)(struct vf_instance *vf);
Names ending with _t are reserved by POSIX, so we shouldn't really use
them (even if we already do in a lot of places I admit).
> + if (!vf->priv->is_planar)
> + vf->priv->planes[0] = malloc(vf->priv->outw * vf->priv->outh);
> vf->priv->planes[1] = malloc(vf->priv->outw * vf->priv->outh);
> vf->priv->planes[2] = malloc(vf->priv->outw * vf->priv->outh);
Why are you allocating data for planes[1] and [2] for non-planar
formats?
> - dst = mpi->planes[0] + y1 * mpi->stride[0];
> - for (y = 0; y < y2 - y1; ++y) {
> - memset(dst, color[0], mpi->w);
> - dst += mpi->stride[0];
> + if (mpi->flags & MP_IMGFLAG_PLANAR) {
> + dst = mpi->planes[0] + y1 * mpi->stride[0];
> + for (y = 0; y < y2 - y1; ++y) {
> + memset(dst, color[0], mpi->w);
> + dst += mpi->stride[0];
Please don't reindent code you did not change (or use the diff options
to ignore whitespace-only differences), it makes changes much easier to
review.
> + } else {
> + if (mpi->imgfmt == IMGFMT_UYVY) {
> + packed_color.c[0] = color[1];
> + packed_color.c[1] = color[0];
> + packed_color.c[2] = color[2];
> + packed_color.c[3] = color[0];
> + } else if (mpi->imgfmt == IMGFMT_YUY2) {
> + packed_color.c[0] = color[0];
> + packed_color.c[1] = color[1];
> + packed_color.c[2] = color[0];
> + packed_color.c[3] = color[2];
> + }
> + dst = mpi->planes[0] + y1 * mpi->stride[0];
> + for (y = 0; y < y2 - y1; ++y)
> + for (x = 0; x < mpi->w; ++x)
> + *((uint32_t *)dst + x) = packed_color.i;
Raw type-casting like that is risky, also falling back to e.g.
YUY2 case in case imgfmt should be something unexpected is safer
coding than using uninitialized data.
So I think it would be simpler as something along the lines of
} else {
uint8_t c[4];
if (mpi->imgfmt == IMGFMT_UYVY) {
...
} else {
...
}
....
AV_COPY32(dst + 4*x, c);
> - if ((vf->priv->dirty_rows[i * 2] == 1)) {
> + if (vf->priv->dirty_rows[i * 2]) {
Why?
> + for (i = first_row; i < last_row; ++i) {
> + int next_off = dst_off + dst_stride;
> + if (!dirty_rows[i]) {
> + if (is_uyvy) {
> + for (j = dst_off, k = 0; j < next_off; j += 2, k += 4) {
I don't think this can work, because
a) the area between the width and stride length should be considered
reserved and not accessed
b) stride can be negative
> + for (j = src_off, k = 0; j < next_off; j += 2, k += 4) {
> + dst[k ] = AVERAGE(src[1][j], src[1][j + 1]);
If next_off is odd, [j + 1] will access data outside the allocated
memory.
Also chroma usually isn't located in-between the Y values, so taking the
average is likely _less_ correct that just taking src[1][j].
(note: OS X might not take the chroma sitting issue seriously anyway,
but if it will be wrong either way the simpler code is better)
> - switch (fmt) {
> - case IMGFMT_YV12:
> - case IMGFMT_I420:
> - case IMGFMT_IYUV:
> + if (fmt == vf->priv->outfmt)
> return vf_next_query_format(vf, vf->priv->outfmt);
This seems slightly unrelated.
> + if (vf->priv->is_planar)
> + free(vf->priv->planes[0]);
The malloc used the inverted condition I think?
Did you try running this under valgrind?
More information about the MPlayer-dev-eng
mailing list