---
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