]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/gif.c
avformat/mux: factorize interleaved write_packet
[ffmpeg] / libavcodec / gif.c
index 67fc5a1bda10c1f9f2c4bb656d34c762b7c1e2d8..e2242d043898401640aeb7bbbf9b78f38f54f2ef 100644 (file)
@@ -48,7 +48,6 @@ typedef struct GIFContext {
     LZWState *lzw;
     uint8_t *buf;
     int buf_size;
-    int is_first_frame;
     AVFrame *last_frame;
     int flags;
     int image;
@@ -137,7 +136,7 @@ static void gif_crop_translucent(AVCodecContext *avctx,
         while (*y_start < y_end) {
             int is_trans = 1;
             for (int i = 0; i < w; i++) {
-                if (buf[w * *y_start + i] != trans) {
+                if (buf[linesize * *y_start + i] != trans) {
                     is_trans = 0;
                     break;
                 }
@@ -149,10 +148,10 @@ static void gif_crop_translucent(AVCodecContext *avctx,
         }
 
         // crop bottom
-        while (y_end < h) {
+        while (y_end > *y_start) {
             int is_trans = 1;
             for (int i = 0; i < w; i++) {
-                if (buf[w * y_end + i] != trans) {
+                if (buf[linesize * y_end + i] != trans) {
                     is_trans = 0;
                     break;
                 }
@@ -166,7 +165,7 @@ static void gif_crop_translucent(AVCodecContext *avctx,
         while (*x_start < x_end) {
             int is_trans = 1;
             for (int i = *y_start; i < y_end; i++) {
-                if (buf[w * i + *x_start] != trans) {
+                if (buf[linesize * i + *x_start] != trans) {
                     is_trans = 0;
                     break;
                 }
@@ -177,10 +176,10 @@ static void gif_crop_translucent(AVCodecContext *avctx,
         }
 
         // crop right
-        while (x_end < w) {
+        while (x_end > *x_start) {
             int is_trans = 1;
             for (int i = *y_start; i < y_end; i++) {
-                if (buf[w * i + x_end] != trans) {
+                if (buf[linesize * i + x_end] != trans) {
                     is_trans = 0;
                     break;
                 }
@@ -268,7 +267,7 @@ static int gif_image_write_image(AVCodecContext *avctx,
     int bcid = -1, honor_transparency = (s->flags & GF_TRANSDIFF) && s->last_frame && !palette;
     const uint8_t *ptr;
 
-    if (!s->is_first_frame && is_image_translucent(avctx, buf, linesize)) {
+    if (!s->image && avctx->frame_number && is_image_translucent(avctx, buf, linesize)) {
         gif_crop_translucent(avctx, buf, linesize, &width, &height, &x_start, &y_start);
         honor_transparency = 0;
         disposal = GCE_DISPOSAL_BACKGROUND;
@@ -277,7 +276,7 @@ static int gif_image_write_image(AVCodecContext *avctx,
         disposal = GCE_DISPOSAL_INPLACE;
     }
 
-    if (s->is_first_frame) { /* GIF header */
+    if (s->image || !avctx->frame_number) { /* GIF header */
         const uint32_t *global_palette = palette ? palette : s->palette;
         const AVRational sar = avctx->sample_aspect_ratio;
         int64_t aspect = 0;
@@ -301,8 +300,6 @@ static int gif_image_write_image(AVCodecContext *avctx,
             const uint32_t v = global_palette[i] & 0xffffff;
             bytestream_put_be24(bytestream, v);
         }
-
-        s->is_first_frame = 0;
     }
 
     if (honor_transparency && trans < 0) {
@@ -395,7 +392,6 @@ static av_cold int gif_encode_init(AVCodecContext *avctx)
     }
 
     s->transparent_index = -1;
-    s->is_first_frame = 1;
 
     s->lzw = av_mallocz(ff_lzw_encode_state_size);
     s->buf_size = avctx->width*avctx->height*2 + 1000;
@@ -423,9 +419,6 @@ static int gif_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
     outbuf_ptr = pkt->data;
     end        = pkt->data + pkt->size;
 
-    if (s->image)
-        s->is_first_frame = 1;
-
     if (avctx->pix_fmt == AV_PIX_FMT_PAL8) {
         palette = (uint32_t*)pict->data[1];
 
@@ -454,7 +447,7 @@ static int gif_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
     }
 
     pkt->size   = outbuf_ptr - pkt->data;
-    if (s->is_first_frame)
+    if (s->image || !avctx->frame_number)
         pkt->flags |= AV_PKT_FLAG_KEY;
     *got_packet = 1;
 
@@ -479,7 +472,7 @@ static const AVOption gif_options[] = {
     { "gifflags", "set GIF flags", OFFSET(flags), AV_OPT_TYPE_FLAGS, {.i64 = GF_OFFSETTING|GF_TRANSDIFF}, 0, INT_MAX, FLAGS, "flags" },
         { "offsetting", "enable picture offsetting", 0, AV_OPT_TYPE_CONST, {.i64=GF_OFFSETTING}, INT_MIN, INT_MAX, FLAGS, "flags" },
         { "transdiff", "enable transparency detection between frames", 0, AV_OPT_TYPE_CONST, {.i64=GF_TRANSDIFF}, INT_MIN, INT_MAX, FLAGS, "flags" },
-    { "gifimage", "enable encoding only images per frame", OFFSET(image), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS, "flags" },
+    { "gifimage", "enable encoding only images per frame", OFFSET(image), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS },
     { NULL }
 };