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 |