Browse code

Add support to CorePNG P-frames.

Patch by Thilo Borgmann thilo DOT borgmann A googlemail com.

Originally committed as revision 18421 to svn://svn.ffmpeg.org/ffmpeg/trunk

Thilo Borgmann authored on 2009/04/11 02:16:19
Showing 1 changed files
... ...
@@ -37,7 +37,8 @@ typedef struct PNGDecContext {
37 37
     const uint8_t *bytestream;
38 38
     const uint8_t *bytestream_start;
39 39
     const uint8_t *bytestream_end;
40
-    AVFrame picture;
40
+    AVFrame picture1, picture2;
41
+    AVFrame *current_picture, *last_picture;
41 42
 
42 43
     int state;
43 44
     int width, height;
... ...
@@ -385,10 +386,14 @@ static int decode_frame(AVCodecContext *avctx,
385 385
     int buf_size = avpkt->size;
386 386
     PNGDecContext * const s = avctx->priv_data;
387 387
     AVFrame *picture = data;
388
-    AVFrame * const p= &s->picture;
388
+    AVFrame *p;
389 389
     uint32_t tag, length;
390 390
     int ret, crc;
391 391
 
392
+    FFSWAP(AVFrame *, s->current_picture, s->last_picture);
393
+    avctx->coded_frame= s->current_picture;
394
+    p = s->current_picture;
395
+
392 396
     s->bytestream_start=
393 397
     s->bytestream= buf;
394 398
     s->bytestream_end= buf + buf_size;
... ...
@@ -584,7 +589,24 @@ static int decode_frame(AVCodecContext *avctx,
584 584
         }
585 585
     }
586 586
  exit_loop:
587
-    *picture= s->picture;
587
+     /* handle p-frames only if a predecessor frame is available */
588
+     if(s->last_picture->data[0] != NULL) {
589
+         if(!(avpkt->flags & PKT_FLAG_KEY)) {
590
+            int i, j;
591
+            uint8_t *pd = s->current_picture->data[0];
592
+            uint8_t *pd_last = s->last_picture->data[0];
593
+
594
+            for(j=0; j < s->height; j++) {
595
+                for(i=0; i < s->width * s->bpp; i++) {
596
+                    pd[i] += pd_last[i];
597
+                }
598
+                pd += s->image_linesize;
599
+                pd_last += s->image_linesize;
600
+            }
601
+        }
602
+    }
603
+
604
+    *picture= *s->current_picture;
588 605
     *data_size = sizeof(AVFrame);
589 606
 
590 607
     ret = s->bytestream - s->bytestream_start;
... ...
@@ -602,8 +624,10 @@ static int decode_frame(AVCodecContext *avctx,
602 602
 static av_cold int png_dec_init(AVCodecContext *avctx){
603 603
     PNGDecContext *s = avctx->priv_data;
604 604
 
605
-    avcodec_get_frame_defaults(&s->picture);
606
-    avctx->coded_frame= &s->picture;
605
+    s->current_picture = &s->picture1;
606
+    s->last_picture = &s->picture2;
607
+    avcodec_get_frame_defaults(&s->picture1);
608
+    avcodec_get_frame_defaults(&s->picture2);
607 609
     dsputil_init(&s->dsp, avctx);
608 610
 
609 611
     return 0;