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