[Ffmpeg-devel] [PATCH] fix error croping

Limin Wang lance.lmwang
Wed Apr 4 13:11:18 CEST 2007


Hi,

> > Index: libavcodec/imgconvert.c
> > ===================================================================
> > --- libavcodec/imgconvert.c	(revision 8622)
> > +++ libavcodec/imgconvert.c	(working copy)
> > @@ -2220,19 +2220,22 @@
> >      int y_shift;
> >      int x_shift;
> >  
> > -    if (pix_fmt < 0 || pix_fmt >= PIX_FMT_NB || !is_yuv_planar(&pix_fmt_info[pix_fmt]))
> > +    if (pix_fmt < 0 || pix_fmt >= PIX_FMT_NB)
> >          return -1;
> 
> What about PAL8/MONOWHITE etc ? Does it work ?

Haven't check all, the new patch will add is_crop_ok() check.


> 
> > -    y_shift = pix_fmt_info[pix_fmt].y_chroma_shift;
> > -    x_shift = pix_fmt_info[pix_fmt].x_chroma_shift;
> > -
> >      dst->data[0] = src->data[0] + (top_band * src->linesize[0]) + left_band;
> 
> That seems wrong, like Luca said.

OK, I add a field for bytes_per_pixel to fix the issue. Please review the
updated patch again. 

Now I have tested with bgr24, rgb32, rgb555, rgb565, yuyv422, uyvy422. The
other packed format like bgr565, bgr32, bgr8, etc, haven't been tested for I
failed to create them, it's killed by KILL signal after ffmpeg start. Below is
the info:

lmwang at lmwang_pc:~/open/h264/ffmpeg$ gdb ./ffmpeg_g
GNU gdb 6.6-debian
Copyright (C) 2006 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "i486-linux-gnu"...
Using host libthread_db library "/lib/tls/libthread_db.so.1".
(gdb) r -y -s 352x288 -i /home/lmwang/test_sequences/cif/foreman_cif.yuv
-pix_fmt bgr32 /tmp/bgr32.yuv
Starting program: /home/lmwang/open/h264/ffmpeg/ffmpeg_g -y -s 352x288
-i /home/lmwang/test_sequences/cif/foreman_cif.yuv -pix_fmt bgr32
/tmp/bgr32.yuv
Failed to read a valid object file image from memory.
[Thread debugging using libthread_db enabled]
[New Thread -1210661184 (LWP 4101)]
FFmpeg version SVN-r8622, Copyright (c) 2000-2007 Fabrice Bellard, et al.
  configuration: --enable-gpl --enable-x264 --enable-libfaac --enable-libfaad
  libavutil version: 49.4.0
  libavcodec version: 51.40.2
  libavformat version: 51.11.0
  built on Apr  4 2007 15:04:20, gcc: 4.1.2 20061115 (prerelease) (Debian
  4.1.1-21)
Input #0, rawvideo, from '/home/lmwang/test_sequences/cif/foreman_cif.yuv':
  Duration: N/A, bitrate: N/A
  Stream #0.0: Video: rawvideo, yuv420p, 352x288, 25.00 fps(r)
Output #0, rawvideo, to '/tmp/bgr32.yuv':
  Stream #0.0: Video: rawvideo, bgr32, 352x288, q=2-31, 200 kb/s, 25.00 fps(c)
Stream mapping:
  Stream #0.0 -> #0.0
Press [q] to stop encoding

Program terminated with signal SIGKILL, Killed.
The program no longer exists.
(gdb)
(gdb) bt
No stack.
(gdb) quit


Thanks,
Limin
-------------- next part --------------
Index: libavcodec/imgconvert.c
===================================================================
--- libavcodec/imgconvert.c	(revision 8622)
+++ libavcodec/imgconvert.c	(working copy)
@@ -55,6 +55,7 @@
 
 typedef struct PixFmtInfo {
     const char *name;
+    uint8_t bytes_per_pixel; /**< bytes per pixel */
     uint8_t nb_channels;     /**< number of channels (including alpha) */
     uint8_t color_type;      /**< color type (see FF_COLOR_xxx constants) */
     uint8_t pixel_type;      /**< pixel storage type (see FF_PIXEL_xxx constants) */
@@ -69,6 +70,7 @@
     /* YUV formats */
     [PIX_FMT_YUV420P] = {
         .name = "yuv420p",
+        .bytes_per_pixel = 1,
         .nb_channels = 3,
         .color_type = FF_COLOR_YUV,
         .pixel_type = FF_PIXEL_PLANAR,
@@ -77,6 +79,7 @@
     },
     [PIX_FMT_YUV422P] = {
         .name = "yuv422p",
+        .bytes_per_pixel = 1,
         .nb_channels = 3,
         .color_type = FF_COLOR_YUV,
         .pixel_type = FF_PIXEL_PLANAR,
@@ -85,6 +88,7 @@
     },
     [PIX_FMT_YUV444P] = {
         .name = "yuv444p",
+        .bytes_per_pixel = 1,
         .nb_channels = 3,
         .color_type = FF_COLOR_YUV,
         .pixel_type = FF_PIXEL_PLANAR,
@@ -93,6 +97,7 @@
     },
     [PIX_FMT_YUYV422] = {
         .name = "yuyv422",
+        .bytes_per_pixel = 2,
         .nb_channels = 1,
         .color_type = FF_COLOR_YUV,
         .pixel_type = FF_PIXEL_PACKED,
@@ -101,6 +106,7 @@
     },
     [PIX_FMT_UYVY422] = {
         .name = "uyvy422",
+        .bytes_per_pixel = 2,
         .nb_channels = 1,
         .color_type = FF_COLOR_YUV,
         .pixel_type = FF_PIXEL_PACKED,
@@ -109,6 +115,7 @@
     },
     [PIX_FMT_YUV410P] = {
         .name = "yuv410p",
+        .bytes_per_pixel = 1,
         .nb_channels = 3,
         .color_type = FF_COLOR_YUV,
         .pixel_type = FF_PIXEL_PLANAR,
@@ -117,6 +124,7 @@
     },
     [PIX_FMT_YUV411P] = {
         .name = "yuv411p",
+        .bytes_per_pixel = 1,
         .nb_channels = 3,
         .color_type = FF_COLOR_YUV,
         .pixel_type = FF_PIXEL_PLANAR,
@@ -127,6 +135,7 @@
     /* JPEG YUV */
     [PIX_FMT_YUVJ420P] = {
         .name = "yuvj420p",
+        .bytes_per_pixel = 1,
         .nb_channels = 3,
         .color_type = FF_COLOR_YUV_JPEG,
         .pixel_type = FF_PIXEL_PLANAR,
@@ -135,6 +144,7 @@
     },
     [PIX_FMT_YUVJ422P] = {
         .name = "yuvj422p",
+        .bytes_per_pixel = 1,
         .nb_channels = 3,
         .color_type = FF_COLOR_YUV_JPEG,
         .pixel_type = FF_PIXEL_PLANAR,
@@ -143,6 +153,7 @@
     },
     [PIX_FMT_YUVJ444P] = {
         .name = "yuvj444p",
+        .bytes_per_pixel = 1,
         .nb_channels = 3,
         .color_type = FF_COLOR_YUV_JPEG,
         .pixel_type = FF_PIXEL_PLANAR,
@@ -153,6 +164,7 @@
     /* RGB formats */
     [PIX_FMT_RGB24] = {
         .name = "rgb24",
+        .bytes_per_pixel = 3,
         .nb_channels = 3,
         .color_type = FF_COLOR_RGB,
         .pixel_type = FF_PIXEL_PACKED,
@@ -161,6 +173,7 @@
     },
     [PIX_FMT_BGR24] = {
         .name = "bgr24",
+        .bytes_per_pixel = 3,
         .nb_channels = 3,
         .color_type = FF_COLOR_RGB,
         .pixel_type = FF_PIXEL_PACKED,
@@ -169,6 +182,7 @@
     },
     [PIX_FMT_RGB32] = {
         .name = "rgb32",
+        .bytes_per_pixel = 4,
         .nb_channels = 4, .is_alpha = 1,
         .color_type = FF_COLOR_RGB,
         .pixel_type = FF_PIXEL_PACKED,
@@ -177,6 +191,7 @@
     },
     [PIX_FMT_RGB565] = {
         .name = "rgb565",
+        .bytes_per_pixel = 2,
         .nb_channels = 3,
         .color_type = FF_COLOR_RGB,
         .pixel_type = FF_PIXEL_PACKED,
@@ -185,6 +200,7 @@
     },
     [PIX_FMT_RGB555] = {
         .name = "rgb555",
+        .bytes_per_pixel = 2,
         .nb_channels = 3,
         .color_type = FF_COLOR_RGB,
         .pixel_type = FF_PIXEL_PACKED,
@@ -195,6 +211,7 @@
     /* gray / mono formats */
     [PIX_FMT_GRAY16BE] = {
         .name = "gray16be",
+        .bytes_per_pixel = 1,
         .nb_channels = 1,
         .color_type = FF_COLOR_GRAY,
         .pixel_type = FF_PIXEL_PLANAR,
@@ -202,6 +219,7 @@
     },
     [PIX_FMT_GRAY16LE] = {
         .name = "gray16le",
+        .bytes_per_pixel = 1,
         .nb_channels = 1,
         .color_type = FF_COLOR_GRAY,
         .pixel_type = FF_PIXEL_PLANAR,
@@ -209,6 +227,7 @@
     },
     [PIX_FMT_GRAY8] = {
         .name = "gray",
+        .bytes_per_pixel = 1,
         .nb_channels = 1,
         .color_type = FF_COLOR_GRAY,
         .pixel_type = FF_PIXEL_PLANAR,
@@ -216,6 +235,7 @@
     },
     [PIX_FMT_MONOWHITE] = {
         .name = "monow",
+        .bytes_per_pixel = 1,
         .nb_channels = 1,
         .color_type = FF_COLOR_GRAY,
         .pixel_type = FF_PIXEL_PLANAR,
@@ -223,6 +243,7 @@
     },
     [PIX_FMT_MONOBLACK] = {
         .name = "monob",
+        .bytes_per_pixel = 1,
         .nb_channels = 1,
         .color_type = FF_COLOR_GRAY,
         .pixel_type = FF_PIXEL_PLANAR,
@@ -232,6 +253,7 @@
     /* paletted formats */
     [PIX_FMT_PAL8] = {
         .name = "pal8",
+        .bytes_per_pixel = 1,
         .nb_channels = 4, .is_alpha = 1,
         .color_type = FF_COLOR_RGB,
         .pixel_type = FF_PIXEL_PALETTE,
@@ -245,6 +267,7 @@
     },
     [PIX_FMT_UYYVYY411] = {
         .name = "uyyvyy411",
+        .bytes_per_pixel = 3/2,
         .nb_channels = 1,
         .color_type = FF_COLOR_YUV,
         .pixel_type = FF_PIXEL_PACKED,
@@ -253,6 +276,7 @@
     },
     [PIX_FMT_BGR32] = {
         .name = "bgr32",
+        .bytes_per_pixel = 4,
         .nb_channels = 4, .is_alpha = 1,
         .color_type = FF_COLOR_RGB,
         .pixel_type = FF_PIXEL_PACKED,
@@ -261,6 +285,7 @@
     },
     [PIX_FMT_BGR565] = {
         .name = "bgr565",
+        .bytes_per_pixel = 2,
         .nb_channels = 3,
         .color_type = FF_COLOR_RGB,
         .pixel_type = FF_PIXEL_PACKED,
@@ -269,6 +294,7 @@
     },
     [PIX_FMT_BGR555] = {
         .name = "bgr555",
+        .bytes_per_pixel = 2,
         .nb_channels = 3,
         .color_type = FF_COLOR_RGB,
         .pixel_type = FF_PIXEL_PACKED,
@@ -277,6 +303,7 @@
     },
     [PIX_FMT_RGB8] = {
         .name = "rgb8",
+        .bytes_per_pixel = 1,
         .nb_channels = 1,
         .color_type = FF_COLOR_RGB,
         .pixel_type = FF_PIXEL_PACKED,
@@ -285,6 +312,7 @@
     },
     [PIX_FMT_RGB4] = {
         .name = "rgb4",
+        .bytes_per_pixel = 1,
         .nb_channels = 1,
         .color_type = FF_COLOR_RGB,
         .pixel_type = FF_PIXEL_PACKED,
@@ -293,6 +321,7 @@
     },
     [PIX_FMT_RGB4_BYTE] = {
         .name = "rgb4_byte",
+        .bytes_per_pixel = 1,
         .nb_channels = 1,
         .color_type = FF_COLOR_RGB,
         .pixel_type = FF_PIXEL_PACKED,
@@ -301,6 +330,7 @@
     },
     [PIX_FMT_BGR8] = {
         .name = "bgr8",
+        .bytes_per_pixel = 1,
         .nb_channels = 1,
         .color_type = FF_COLOR_RGB,
         .pixel_type = FF_PIXEL_PACKED,
@@ -309,6 +339,7 @@
     },
     [PIX_FMT_BGR4] = {
         .name = "bgr4",
+        .bytes_per_pixel = 1,
         .nb_channels = 1,
         .color_type = FF_COLOR_RGB,
         .pixel_type = FF_PIXEL_PACKED,
@@ -317,6 +348,7 @@
     },
     [PIX_FMT_BGR4_BYTE] = {
         .name = "bgr4_byte",
+        .bytes_per_pixel = 1,
         .nb_channels = 1,
         .color_type = FF_COLOR_RGB,
         .pixel_type = FF_PIXEL_PACKED,
@@ -325,6 +357,7 @@
     },
     [PIX_FMT_NV12] = {
         .name = "nv12",
+        .bytes_per_pixel = 1,
         .nb_channels = 2,
         .color_type = FF_COLOR_YUV,
         .pixel_type = FF_PIXEL_PLANAR,
@@ -333,6 +366,7 @@
     },
     [PIX_FMT_NV21] = {
         .name = "nv12",
+        .bytes_per_pixel = 1,
         .nb_channels = 2,
         .color_type = FF_COLOR_YUV,
         .pixel_type = FF_PIXEL_PLANAR,
@@ -342,6 +376,7 @@
 
     [PIX_FMT_BGR32_1] = {
         .name = "bgr32_1",
+        .bytes_per_pixel = 4,
         .nb_channels = 4, .is_alpha = 1,
         .color_type = FF_COLOR_RGB,
         .pixel_type = FF_PIXEL_PACKED,
@@ -350,6 +385,7 @@
     },
     [PIX_FMT_RGB32_1] = {
         .name = "rgb32_1",
+        .bytes_per_pixel = 4,
         .nb_channels = 4, .is_alpha = 1,
         .color_type = FF_COLOR_RGB,
         .pixel_type = FF_PIXEL_PACKED,
@@ -2214,25 +2250,38 @@
         ps->pixel_type == FF_PIXEL_PLANAR;
 }
 
+/* return true if crop is ok */
+static inline int is_crop_ok(const PixFmtInfo *ps)
+{
+    return (ps->color_type == FF_COLOR_YUV ||
+            ps->color_type == FF_COLOR_RGB ||
+            ps->color_type == FF_COLOR_YUV_JPEG ) &&
+        (ps->pixel_type == FF_PIXEL_PLANAR ||
+        ps->pixel_type == FF_PIXEL_PACKED );
+}
+
 int av_picture_crop(AVPicture *dst, const AVPicture *src,
               int pix_fmt, int top_band, int left_band)
 {
     int y_shift;
     int x_shift;
 
-    if (pix_fmt < 0 || pix_fmt >= PIX_FMT_NB || !is_yuv_planar(&pix_fmt_info[pix_fmt]))
+    if (pix_fmt < 0 || pix_fmt >= PIX_FMT_NB || !is_crop_ok(&pix_fmt_info[pix_fmt]))
         return -1;
 
-    y_shift = pix_fmt_info[pix_fmt].y_chroma_shift;
-    x_shift = pix_fmt_info[pix_fmt].x_chroma_shift;
+    dst->data[0] = src->data[0] + (top_band * src->linesize[0]) + left_band * pix_fmt_info[pix_fmt].bytes_per_pixel;
+    dst->linesize[0] = src->linesize[0];
+    if( is_yuv_planar(&pix_fmt_info[pix_fmt])) {
+        y_shift = pix_fmt_info[pix_fmt].y_chroma_shift;
+        x_shift = pix_fmt_info[pix_fmt].x_chroma_shift;
 
-    dst->data[0] = src->data[0] + (top_band * src->linesize[0]) + left_band;
-    dst->data[1] = src->data[1] + ((top_band >> y_shift) * src->linesize[1]) + (left_band >> x_shift);
-    dst->data[2] = src->data[2] + ((top_band >> y_shift) * src->linesize[2]) + (left_band >> x_shift);
+        dst->data[1] = src->data[1] + ((top_band >> y_shift) * src->linesize[1]) + (left_band >> x_shift);
+        dst->data[2] = src->data[2] + ((top_band >> y_shift) * src->linesize[2]) + (left_band >> x_shift);
 
-    dst->linesize[0] = src->linesize[0];
-    dst->linesize[1] = src->linesize[1];
-    dst->linesize[2] = src->linesize[2];
+        dst->linesize[1] = src->linesize[1];
+        dst->linesize[2] = src->linesize[2];
+    }
+
     return 0;
 }
 
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 481 bytes
Desc: not available
URL: <http://lists.mplayerhq.hu/pipermail/ffmpeg-devel/attachments/20070404/2cd1262a/attachment.pgp>



More information about the ffmpeg-devel mailing list