---
 libavcodec/vc1.h    |    2 +
 libavcodec/vc1dec.c |   76 +++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 78 insertions(+), 0 deletions(-)

diff --git a/libavcodec/vc1.h b/libavcodec/vc1.h
index ac65348..28b667f 100644
--- a/libavcodec/vc1.h
+++ b/libavcodec/vc1.h
@@ -172,6 +172,8 @@ typedef struct VC1Context{
     VC1DSPContext vc1dsp;
 
     int bits;
+    uint8_t *data_out_base, *data_out[3];
+    uint8_t *data_out_last_base, *data_out_last[3];
 
     /** Simple/Main Profile sequence header */
     //@{
diff --git a/libavcodec/vc1dec.c b/libavcodec/vc1dec.c
index 6ca7585..97123ef 100644
--- a/libavcodec/vc1dec.c
+++ b/libavcodec/vc1dec.c
@@ -5406,6 +5406,10 @@ static av_cold int vc1_decode_end(AVCodecContext *avctx)
         avctx->release_buffer(avctx, &v->sprite_output_frame);
     for (i = 0; i < 4; i++)
         av_freep(&v->sr_rows[i >> 1][i & 1]);
+    if (v->data_out_base)
+        av_freep(&v->data_out_base);
+    if (v->data_out_last_base)
+        av_freep(&v->data_out_last_base);
     av_freep(&v->hrd_rate);
     av_freep(&v->hrd_buffer);
     MPV_common_end(&v->s);
@@ -5456,6 +5460,13 @@ static int vc1_decode_frame(AVCodecContext *avctx, void 
*data,
         /* special case for last picture */
         if (s->low_delay == 0 && s->next_picture_ptr) {
             *pict = *(AVFrame*)s->next_picture_ptr;
+            if (v->range_mapy_flag) {
+                pict->data[0] = v->data_out_last[0];
+            }
+            if (v->range_mapuv_flag) {
+                pict->data[1] = v->data_out_last[1];
+                pict->data[2] = v->data_out_last[2];
+            }
             s->next_picture_ptr = NULL;
 
             *data_size = sizeof(AVFrame);
@@ -5654,6 +5665,21 @@ static int vc1_decode_frame(AVCodecContext *avctx, void 
*data,
         goto err;
     }
 
+    if (!v->data_out_base) {
+        /* Allocate temporary data buffer for range mapped pictures */
+        v->data_out_base = av_malloc(avctx->coded_height * s->linesize + 
(avctx->coded_height * s->linesize >> 1));
+        v->data_out[0] = v->data_out_base;
+        v->data_out[1] = v->data_out[0] + avctx->coded_height * s->linesize;
+        v->data_out[2] = v->data_out[1] + (avctx->coded_height * s->linesize 
>> 2);
+    }
+    if (!v->data_out_last_base) {
+        /* We need another buffer to hold reference picture */
+        v->data_out_last_base = av_malloc(avctx->coded_height * s->linesize + 
(avctx->coded_height * s->linesize >> 1));
+        v->data_out_last[0] = v->data_out_last_base;
+        v->data_out_last[1] = v->data_out_last[0] + avctx->coded_height * 
s->linesize;
+        v->data_out_last[2] = v->data_out_last[1] + (avctx->coded_height * 
s->linesize >> 2);
+    }
+
     s->me.qpel_put = s->dsp.put_qpel_pixels_tab;
     s->me.qpel_avg = s->dsp.avg_qpel_pixels_tab;
 
@@ -5731,6 +5757,34 @@ static int vc1_decode_frame(AVCodecContext *avctx, void 
*data,
             s->linesize                      >>= 1;
             s->uvlinesize                    >>= 1;
         }
+
+        /* Apply range mapping if flag present */
+        if (v->range_mapy_flag) {
+            int j, k;
+            uint8_t *srcy, *desty;
+            for (k = 0; k < avctx->coded_height; k++) {
+                for (j = 0; j < s->linesize; j++) {
+                    srcy = s->current_picture_ptr->f.data[0] + k * s->linesize 
+ j;
+                    desty = v->data_out[0] + k * s->linesize + j;
+                    *desty = av_clip((((*srcy - 128) * (v->range_mapy + 9) + 
4) >> 3) + 128, 0, 255);
+                }
+            }
+        }
+        if (v->range_mapuv_flag) {
+            int j, k;
+            uint8_t *srcu, *srcv;
+            uint8_t *destu, *destv;
+            for (k = 0; k < (avctx->coded_height >> 1); k++) {
+                for (j = 0; j < (s->linesize >> 1); j++) {
+                    srcu = s->current_picture_ptr->f.data[1] + k * 
(s->linesize >> 1) + j;
+                    srcv = s->current_picture_ptr->f.data[2] + k * 
(s->linesize >> 1) + j;
+                    destu = v->data_out[1] + k * (s->linesize >> 1) + j;
+                    destv = v->data_out[2] + k * (s->linesize >> 1) + j;
+                    *destu = av_clip((((*srcu - 128) * (v->range_mapy + 9) + 
4) >> 3) + 128, 0, 255);
+                    *destv = av_clip((((*srcv - 128) * (v->range_mapy + 9) + 
4) >> 3) + 128, 0, 255);
+                }
+            }
+        }
 //av_log(s->avctx, AV_LOG_INFO, "Consumed %i/%i bits\n", 
get_bits_count(&s->gb), s->gb.size_in_bits);
 //  if (get_bits_count(&s->gb) > buf_size * 8)
 //      return -1;
@@ -5754,8 +5808,30 @@ image:
     } else {
         if (s->pict_type == AV_PICTURE_TYPE_B || s->low_delay) {
             *pict = *(AVFrame*)s->current_picture_ptr;
+            /* Output range mapped frame instead of decoded frame if flag 
present */
+            if (v->range_mapy_flag)
+                pict->data[0] = v->data_out[0];
+            if (v->range_mapuv_flag) {
+                pict->data[1] = v->data_out[1];
+                pict->data[2] = v->data_out[2];
+            }
         } else if (s->last_picture_ptr != NULL) {
             *pict = *(AVFrame*)s->last_picture_ptr;
+            /* Same as above */
+            if (v->range_mapy_flag)
+                pict->data[0] = v->data_out_last[0];
+            if (v->range_mapuv_flag) {
+                pict->data[1] = v->data_out_last[1];
+                pict->data[2] = v->data_out_last[2];
+            }
+        }
+        if (s->pict_type != AV_PICTURE_TYPE_B && !s->low_delay) {
+            if (v->range_mapy_flag)
+                FFSWAP(uint8_t*, v->data_out_last[0], v->data_out[0]);
+            if (v->range_mapuv_flag) {
+                FFSWAP(uint8_t*, v->data_out_last[1], v->data_out[1]);
+                FFSWAP(uint8_t*, v->data_out_last[2], v->data_out[2]);
+            }
         }
         if (s->last_picture_ptr || s->low_delay) {
             *data_size = sizeof(AVFrame);
-- 
1.7.4.1

_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel

Reply via email to