| OLD | NEW | 
|---|
| 1 /** | 1 /** | 
| 2  * VP8 compatible video decoder | 2  * VP8 compatible video decoder | 
| 3  * | 3  * | 
| 4  * Copyright (C) 2010 David Conrad | 4  * Copyright (C) 2010 David Conrad | 
| 5  * Copyright (C) 2010 Ronald S. Bultje | 5  * Copyright (C) 2010 Ronald S. Bultje | 
| 6  * Copyright (C) 2010 Jason Garrett-Glaser | 6  * Copyright (C) 2010 Jason Garrett-Glaser | 
| 7  * | 7  * | 
| 8  * This file is part of FFmpeg. | 8  * This file is part of FFmpeg. | 
| 9  * | 9  * | 
| 10  * FFmpeg is free software; you can redistribute it and/or | 10  * FFmpeg is free software; you can redistribute it and/or | 
| (...skipping 23 matching lines...) Expand all  Loading... | 
| 34 #endif | 34 #endif | 
| 35 | 35 | 
| 36 static void free_buffers(VP8Context *s) | 36 static void free_buffers(VP8Context *s) | 
| 37 { | 37 { | 
| 38     av_freep(&s->macroblocks_base); | 38     av_freep(&s->macroblocks_base); | 
| 39     av_freep(&s->filter_strength); | 39     av_freep(&s->filter_strength); | 
| 40     av_freep(&s->intra4x4_pred_mode_top); | 40     av_freep(&s->intra4x4_pred_mode_top); | 
| 41     av_freep(&s->top_nnz); | 41     av_freep(&s->top_nnz); | 
| 42     av_freep(&s->edge_emu_buffer); | 42     av_freep(&s->edge_emu_buffer); | 
| 43     av_freep(&s->top_border); | 43     av_freep(&s->top_border); | 
| 44     av_freep(&s->segmentation_map); |  | 
| 45 | 44 | 
| 46     s->macroblocks        = NULL; | 45     s->macroblocks        = NULL; | 
| 47 } | 46 } | 
| 48 | 47 | 
| 49 static void vp8_decode_flush(AVCodecContext *avctx) | 48 static int vp8_alloc_frame(VP8Context *s, AVFrame *f) | 
|  | 49 { | 
|  | 50     int ret; | 
|  | 51     if ((ret = ff_thread_get_buffer(s->avctx, f)) < 0) | 
|  | 52         return ret; | 
|  | 53     if (!s->maps_are_invalid && s->num_maps_to_be_freed) { | 
|  | 54         f->ref_index[0] = s->segmentation_maps[--s->num_maps_to_be_freed]; | 
|  | 55     } else if (!(f->ref_index[0] = av_mallocz(s->mb_width * s->mb_height))) { | 
|  | 56         ff_thread_release_buffer(s->avctx, f); | 
|  | 57         return AVERROR(ENOMEM); | 
|  | 58     } | 
|  | 59     return 0; | 
|  | 60 } | 
|  | 61 | 
|  | 62 static void vp8_release_frame(VP8Context *s, AVFrame *f, int is_close) | 
|  | 63 { | 
|  | 64     if (!is_close) { | 
|  | 65         if (f->ref_index[0]) { | 
|  | 66             assert(s->num_maps_to_be_freed < FF_ARRAY_ELEMS(s->segmentation_maps
      )); | 
|  | 67             s->segmentation_maps[s->num_maps_to_be_freed++] = f->ref_index[0]; | 
|  | 68             f->ref_index[0] = NULL; | 
|  | 69         } | 
|  | 70     } else { | 
|  | 71         av_freep(&f->ref_index[0]); | 
|  | 72     } | 
|  | 73     ff_thread_release_buffer(s->avctx, f); | 
|  | 74 } | 
|  | 75 | 
|  | 76 static void vp8_decode_flush_impl(AVCodecContext *avctx, int force, int is_close
      ) | 
| 50 { | 77 { | 
| 51     VP8Context *s = avctx->priv_data; | 78     VP8Context *s = avctx->priv_data; | 
| 52     int i; | 79     int i; | 
| 53 | 80 | 
| 54     if (!avctx->is_copy) { | 81     if (!avctx->is_copy || force) { | 
| 55         for (i = 0; i < 5; i++) | 82         for (i = 0; i < 5; i++) | 
| 56             if (s->frames[i].data[0]) | 83             if (s->frames[i].data[0]) | 
| 57                 ff_thread_release_buffer(avctx, &s->frames[i]); | 84                 vp8_release_frame(s, &s->frames[i], is_close); | 
| 58     } | 85     } | 
| 59     memset(s->framep, 0, sizeof(s->framep)); | 86     memset(s->framep, 0, sizeof(s->framep)); | 
| 60 | 87 | 
| 61     free_buffers(s); | 88     free_buffers(s); | 
|  | 89     s->maps_are_invalid = 1; | 
|  | 90 } | 
|  | 91 | 
|  | 92 static void vp8_decode_flush(AVCodecContext *avctx) | 
|  | 93 { | 
|  | 94     vp8_decode_flush_impl(avctx, 0, 0); | 
| 62 } | 95 } | 
| 63 | 96 | 
| 64 static int update_dimensions(VP8Context *s, int width, int height) | 97 static int update_dimensions(VP8Context *s, int width, int height) | 
| 65 { | 98 { | 
| 66     if (width  != s->avctx->width || | 99     if (width  != s->avctx->width || | 
| 67         height != s->avctx->height) { | 100         height != s->avctx->height) { | 
| 68         if (av_image_check_size(width, height, 0, s->avctx)) | 101         if (av_image_check_size(width, height, 0, s->avctx)) | 
| 69             return AVERROR_INVALIDDATA; | 102             return AVERROR_INVALIDDATA; | 
| 70 | 103 | 
| 71         vp8_decode_flush(s->avctx); | 104         vp8_decode_flush_impl(s->avctx, 1, 0); | 
| 72 | 105 | 
| 73         avcodec_set_dimensions(s->avctx, width, height); | 106         avcodec_set_dimensions(s->avctx, width, height); | 
| 74     } | 107     } | 
| 75 | 108 | 
| 76     s->mb_width  = (s->avctx->coded_width +15) / 16; | 109     s->mb_width  = (s->avctx->coded_width +15) / 16; | 
| 77     s->mb_height = (s->avctx->coded_height+15) / 16; | 110     s->mb_height = (s->avctx->coded_height+15) / 16; | 
| 78 | 111 | 
| 79     s->macroblocks_base        = av_mallocz((s->mb_width+s->mb_height*2+1)*sizeo
      f(*s->macroblocks)); | 112     s->macroblocks_base        = av_mallocz((s->mb_width+s->mb_height*2+1)*sizeo
      f(*s->macroblocks)); | 
| 80     s->filter_strength         = av_mallocz(s->mb_width*sizeof(*s->filter_streng
      th)); | 113     s->filter_strength         = av_mallocz(s->mb_width*sizeof(*s->filter_streng
      th)); | 
| 81     s->intra4x4_pred_mode_top  = av_mallocz(s->mb_width*4); | 114     s->intra4x4_pred_mode_top  = av_mallocz(s->mb_width*4); | 
| 82     s->top_nnz                 = av_mallocz(s->mb_width*sizeof(*s->top_nnz)); | 115     s->top_nnz                 = av_mallocz(s->mb_width*sizeof(*s->top_nnz)); | 
| 83     s->top_border              = av_mallocz((s->mb_width+1)*sizeof(*s->top_borde
      r)); | 116     s->top_border              = av_mallocz((s->mb_width+1)*sizeof(*s->top_borde
      r)); | 
| 84     s->segmentation_map        = av_mallocz(s->mb_width*s->mb_height); |  | 
| 85 | 117 | 
| 86     if (!s->macroblocks_base || !s->filter_strength || !s->intra4x4_pred_mode_to
      p || | 118     if (!s->macroblocks_base || !s->filter_strength || !s->intra4x4_pred_mode_to
      p || | 
| 87         !s->top_nnz || !s->top_border || !s->segmentation_map) | 119         !s->top_nnz || !s->top_border) | 
| 88         return AVERROR(ENOMEM); | 120         return AVERROR(ENOMEM); | 
| 89 | 121 | 
| 90     s->macroblocks        = s->macroblocks_base + 1; | 122     s->macroblocks        = s->macroblocks_base + 1; | 
| 91 | 123 | 
| 92     return 0; | 124     return 0; | 
| 93 } | 125 } | 
| 94 | 126 | 
| 95 static void parse_segment_info(VP8Context *s) | 127 static void parse_segment_info(VP8Context *s) | 
| 96 { | 128 { | 
| 97     VP56RangeCoder *c = &s->c; | 129     VP56RangeCoder *c = &s->c; | 
| (...skipping 1402 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1500     uint8_t *dst = curframe->data[0] + 16*mb_y*s->linesize; | 1532     uint8_t *dst = curframe->data[0] + 16*mb_y*s->linesize; | 
| 1501     int mb_x; | 1533     int mb_x; | 
| 1502 | 1534 | 
| 1503     for (mb_x = 0; mb_x < s->mb_width; mb_x++) { | 1535     for (mb_x = 0; mb_x < s->mb_width; mb_x++) { | 
| 1504         backup_mb_border(s->top_border[mb_x+1], dst, NULL, NULL, s->linesize, 0,
       1); | 1536         backup_mb_border(s->top_border[mb_x+1], dst, NULL, NULL, s->linesize, 0,
       1); | 
| 1505         filter_mb_simple(s, dst, f++, mb_x, mb_y); | 1537         filter_mb_simple(s, dst, f++, mb_x, mb_y); | 
| 1506         dst += 16; | 1538         dst += 16; | 
| 1507     } | 1539     } | 
| 1508 } | 1540 } | 
| 1509 | 1541 | 
|  | 1542 static void release_queued_segmaps(VP8Context *s, int is_close) | 
|  | 1543 { | 
|  | 1544     int leave_behind = is_close ? 0 : !s->maps_are_invalid; | 
|  | 1545     while (s->num_maps_to_be_freed > leave_behind) | 
|  | 1546         av_freep(&s->segmentation_maps[--s->num_maps_to_be_freed]); | 
|  | 1547     s->maps_are_invalid = 0; | 
|  | 1548 } | 
|  | 1549 | 
| 1510 static int vp8_decode_frame(AVCodecContext *avctx, void *data, int *data_size, | 1550 static int vp8_decode_frame(AVCodecContext *avctx, void *data, int *data_size, | 
| 1511                             AVPacket *avpkt) | 1551                             AVPacket *avpkt) | 
| 1512 { | 1552 { | 
| 1513     VP8Context *s = avctx->priv_data; | 1553     VP8Context *s = avctx->priv_data; | 
| 1514     int ret, mb_x, mb_y, i, y, referenced; | 1554     int ret, mb_x, mb_y, i, y, referenced; | 
| 1515     enum AVDiscard skip_thresh; | 1555     enum AVDiscard skip_thresh; | 
| 1516     AVFrame *av_uninit(curframe), *prev_frame = s->framep[VP56_FRAME_CURRENT]; | 1556     AVFrame *av_uninit(curframe), *prev_frame = s->framep[VP56_FRAME_CURRENT]; | 
| 1517 | 1557 | 
|  | 1558     release_queued_segmaps(s, 0); | 
|  | 1559 | 
| 1518     if ((ret = decode_frame_header(s, avpkt->data, avpkt->size)) < 0) | 1560     if ((ret = decode_frame_header(s, avpkt->data, avpkt->size)) < 0) | 
| 1519         return ret; | 1561         return ret; | 
| 1520 | 1562 | 
| 1521     referenced = s->update_last || s->update_golden == VP56_FRAME_CURRENT | 1563     referenced = s->update_last || s->update_golden == VP56_FRAME_CURRENT | 
| 1522                                 || s->update_altref == VP56_FRAME_CURRENT; | 1564                                 || s->update_altref == VP56_FRAME_CURRENT; | 
| 1523 | 1565 | 
| 1524     skip_thresh = !referenced ? AVDISCARD_NONREF : | 1566     skip_thresh = !referenced ? AVDISCARD_NONREF : | 
| 1525                     !s->keyframe ? AVDISCARD_NONKEY : AVDISCARD_ALL; | 1567                     !s->keyframe ? AVDISCARD_NONKEY : AVDISCARD_ALL; | 
| 1526 | 1568 | 
| 1527     if (avctx->skip_frame >= skip_thresh) { | 1569     if (avctx->skip_frame >= skip_thresh) { | 
| 1528         s->invisible = 1; | 1570         s->invisible = 1; | 
| 1529         goto skip_decode; | 1571         goto skip_decode; | 
| 1530     } | 1572     } | 
| 1531     s->deblock_filter = s->filter.level && avctx->skip_loop_filter < skip_thresh
      ; | 1573     s->deblock_filter = s->filter.level && avctx->skip_loop_filter < skip_thresh
      ; | 
| 1532 | 1574 | 
| 1533     // release no longer referenced frames | 1575     // release no longer referenced frames | 
| 1534     for (i = 0; i < 5; i++) | 1576     for (i = 0; i < 5; i++) | 
| 1535         if (s->frames[i].data[0] && | 1577         if (s->frames[i].data[0] && | 
| 1536             &s->frames[i] != prev_frame && | 1578             &s->frames[i] != prev_frame && | 
| 1537             &s->frames[i] != s->framep[VP56_FRAME_PREVIOUS] && | 1579             &s->frames[i] != s->framep[VP56_FRAME_PREVIOUS] && | 
| 1538             &s->frames[i] != s->framep[VP56_FRAME_GOLDEN] && | 1580             &s->frames[i] != s->framep[VP56_FRAME_GOLDEN] && | 
| 1539             &s->frames[i] != s->framep[VP56_FRAME_GOLDEN2]) | 1581             &s->frames[i] != s->framep[VP56_FRAME_GOLDEN2]) | 
| 1540             ff_thread_release_buffer(avctx, &s->frames[i]); | 1582             vp8_release_frame(s, &s->frames[i], 0); | 
| 1541 | 1583 | 
| 1542     // find a free buffer | 1584     // find a free buffer | 
| 1543     for (i = 0; i < 5; i++) | 1585     for (i = 0; i < 5; i++) | 
| 1544         if (&s->frames[i] != prev_frame && | 1586         if (&s->frames[i] != prev_frame && | 
| 1545             &s->frames[i] != s->framep[VP56_FRAME_PREVIOUS] && | 1587             &s->frames[i] != s->framep[VP56_FRAME_PREVIOUS] && | 
| 1546             &s->frames[i] != s->framep[VP56_FRAME_GOLDEN] && | 1588             &s->frames[i] != s->framep[VP56_FRAME_GOLDEN] && | 
| 1547             &s->frames[i] != s->framep[VP56_FRAME_GOLDEN2]) { | 1589             &s->frames[i] != s->framep[VP56_FRAME_GOLDEN2]) { | 
| 1548             curframe = s->framep[VP56_FRAME_CURRENT] = &s->frames[i]; | 1590             curframe = s->framep[VP56_FRAME_CURRENT] = &s->frames[i]; | 
| 1549             break; | 1591             break; | 
| 1550         } | 1592         } | 
| 1551     if (i == 5) { | 1593     if (i == 5) { | 
| 1552         av_log(avctx, AV_LOG_FATAL, "Ran out of free frames!\n"); | 1594         av_log(avctx, AV_LOG_FATAL, "Ran out of free frames!\n"); | 
| 1553         abort(); | 1595         abort(); | 
| 1554     } | 1596     } | 
| 1555     if (curframe->data[0]) | 1597     if (curframe->data[0]) | 
| 1556         ff_thread_release_buffer(avctx, curframe); | 1598         ff_thread_release_buffer(avctx, curframe); | 
| 1557 | 1599 | 
| 1558     curframe->key_frame = s->keyframe; | 1600     curframe->key_frame = s->keyframe; | 
| 1559     curframe->pict_type = s->keyframe ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P; | 1601     curframe->pict_type = s->keyframe ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P; | 
| 1560     curframe->reference = referenced ? 3 : 0; | 1602     curframe->reference = referenced ? 3 : 0; | 
| 1561     curframe->ref_index[0] = s->segmentation_map; | 1603     if ((ret = vp8_alloc_frame(s, curframe))) { | 
| 1562     if ((ret = ff_thread_get_buffer(avctx, curframe))) { |  | 
| 1563         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed!\n"); | 1604         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed!\n"); | 
| 1564         return ret; | 1605         return ret; | 
| 1565     } | 1606     } | 
| 1566 | 1607 | 
| 1567     // check if golden and altref are swapped | 1608     // check if golden and altref are swapped | 
| 1568     if (s->update_altref != VP56_FRAME_NONE) { | 1609     if (s->update_altref != VP56_FRAME_NONE) { | 
| 1569         s->next_framep[VP56_FRAME_GOLDEN2]  = s->framep[s->update_altref]; | 1610         s->next_framep[VP56_FRAME_GOLDEN2]  = s->framep[s->update_altref]; | 
| 1570     } else { | 1611     } else { | 
| 1571         s->next_framep[VP56_FRAME_GOLDEN2]  = s->framep[VP56_FRAME_GOLDEN2]; | 1612         s->next_framep[VP56_FRAME_GOLDEN2]  = s->framep[VP56_FRAME_GOLDEN2]; | 
| 1572     } | 1613     } | 
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1644         s->mv_min.x = -MARGIN; | 1685         s->mv_min.x = -MARGIN; | 
| 1645         s->mv_max.x = ((s->mb_width  - 1) << 6) + MARGIN; | 1686         s->mv_max.x = ((s->mb_width  - 1) << 6) + MARGIN; | 
| 1646         if (prev_frame && s->segmentation.enabled && !s->segmentation.update_map
      ) | 1687         if (prev_frame && s->segmentation.enabled && !s->segmentation.update_map
      ) | 
| 1647             ff_thread_await_progress(prev_frame, mb_y, 0); | 1688             ff_thread_await_progress(prev_frame, mb_y, 0); | 
| 1648 | 1689 | 
| 1649         for (mb_x = 0; mb_x < s->mb_width; mb_x++, mb_xy++, mb++) { | 1690         for (mb_x = 0; mb_x < s->mb_width; mb_x++, mb_xy++, mb++) { | 
| 1650             /* Prefetch the current frame, 4 MBs ahead */ | 1691             /* Prefetch the current frame, 4 MBs ahead */ | 
| 1651             s->dsp.prefetch(dst[0] + (mb_x&3)*4*s->linesize + 64, s->linesize, 4
      ); | 1692             s->dsp.prefetch(dst[0] + (mb_x&3)*4*s->linesize + 64, s->linesize, 4
      ); | 
| 1652             s->dsp.prefetch(dst[1] + (mb_x&7)*s->uvlinesize + 64, dst[2] - dst[1
      ], 2); | 1693             s->dsp.prefetch(dst[1] + (mb_x&7)*s->uvlinesize + 64, dst[2] - dst[1
      ], 2); | 
| 1653 | 1694 | 
| 1654             decode_mb_mode(s, mb, mb_x, mb_y, s->segmentation_map + mb_xy, | 1695             decode_mb_mode(s, mb, mb_x, mb_y, curframe->ref_index[0] + mb_xy, | 
| 1655                            prev_frame ? prev_frame->ref_index[0] + mb_xy : NULL)
      ; | 1696                            prev_frame && prev_frame->ref_index[0] ? prev_frame->
      ref_index[0] + mb_xy : NULL); | 
| 1656 | 1697 | 
| 1657             prefetch_motion(s, mb, mb_x, mb_y, mb_xy, VP56_FRAME_PREVIOUS); | 1698             prefetch_motion(s, mb, mb_x, mb_y, mb_xy, VP56_FRAME_PREVIOUS); | 
| 1658 | 1699 | 
| 1659             if (!mb->skip) | 1700             if (!mb->skip) | 
| 1660                 decode_mb_coeffs(s, c, mb, s->top_nnz[mb_x], s->left_nnz); | 1701                 decode_mb_coeffs(s, c, mb, s->top_nnz[mb_x], s->left_nnz); | 
| 1661 | 1702 | 
| 1662             if (mb->mode <= MODE_I4x4) | 1703             if (mb->mode <= MODE_I4x4) | 
| 1663                 intra_predict(s, dst, mb, mb_x, mb_y); | 1704                 intra_predict(s, dst, mb, mb_x, mb_y); | 
| 1664             else | 1705             else | 
| 1665                 inter_predict(s, dst, mb, mb_x, mb_y); | 1706                 inter_predict(s, dst, mb, mb_x, mb_y); | 
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1728 | 1769 | 
| 1729     dsputil_init(&s->dsp, avctx); | 1770     dsputil_init(&s->dsp, avctx); | 
| 1730     ff_h264_pred_init(&s->hpc, CODEC_ID_VP8, 8); | 1771     ff_h264_pred_init(&s->hpc, CODEC_ID_VP8, 8); | 
| 1731     ff_vp8dsp_init(&s->vp8dsp); | 1772     ff_vp8dsp_init(&s->vp8dsp); | 
| 1732 | 1773 | 
| 1733     return 0; | 1774     return 0; | 
| 1734 } | 1775 } | 
| 1735 | 1776 | 
| 1736 static av_cold int vp8_decode_free(AVCodecContext *avctx) | 1777 static av_cold int vp8_decode_free(AVCodecContext *avctx) | 
| 1737 { | 1778 { | 
| 1738     vp8_decode_flush(avctx); | 1779     vp8_decode_flush_impl(avctx, 0, 1); | 
|  | 1780     release_queued_segmaps(avctx->priv_data, 1); | 
| 1739     return 0; | 1781     return 0; | 
| 1740 } | 1782 } | 
| 1741 | 1783 | 
| 1742 static av_cold int vp8_decode_init_thread_copy(AVCodecContext *avctx) | 1784 static av_cold int vp8_decode_init_thread_copy(AVCodecContext *avctx) | 
| 1743 { | 1785 { | 
| 1744     VP8Context *s = avctx->priv_data; | 1786     VP8Context *s = avctx->priv_data; | 
| 1745 | 1787 | 
| 1746     s->avctx = avctx; | 1788     s->avctx = avctx; | 
| 1747 | 1789 | 
| 1748     return 0; | 1790     return 0; | 
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1782     vp8_decode_init, | 1824     vp8_decode_init, | 
| 1783     NULL, | 1825     NULL, | 
| 1784     vp8_decode_free, | 1826     vp8_decode_free, | 
| 1785     vp8_decode_frame, | 1827     vp8_decode_frame, | 
| 1786     CODEC_CAP_DR1 | CODEC_CAP_FRAME_THREADS, | 1828     CODEC_CAP_DR1 | CODEC_CAP_FRAME_THREADS, | 
| 1787     .flush = vp8_decode_flush, | 1829     .flush = vp8_decode_flush, | 
| 1788     .long_name = NULL_IF_CONFIG_SMALL("On2 VP8"), | 1830     .long_name = NULL_IF_CONFIG_SMALL("On2 VP8"), | 
| 1789     .init_thread_copy      = ONLY_IF_THREADS_ENABLED(vp8_decode_init_thread_copy
      ), | 1831     .init_thread_copy      = ONLY_IF_THREADS_ENABLED(vp8_decode_init_thread_copy
      ), | 
| 1790     .update_thread_context = ONLY_IF_THREADS_ENABLED(vp8_decode_update_thread_co
      ntext), | 1832     .update_thread_context = ONLY_IF_THREADS_ENABLED(vp8_decode_update_thread_co
      ntext), | 
| 1791 }; | 1833 }; | 
| OLD | NEW | 
|---|