Go to the documentation of this file.
27 #include "config_components.h"
98 s->macroblocks =
NULL;
109 if (
s->avctx->hwaccel) {
113 if (!
f->hwaccel_priv_buf)
115 f->hwaccel_picture_private =
f->hwaccel_priv_buf->data;
130 f->hwaccel_picture_private =
NULL;
134 #if CONFIG_VP8_DECODER
148 if (
src->hwaccel_picture_private) {
166 memset(
s->framep, 0,
sizeof(
s->framep));
183 for (
i = 0;
i < 5;
i++)
195 if (
frame->tf.f->buf[0])
204 #if CONFIG_VP8_VAAPI_HWACCEL
207 #if CONFIG_VP8_NVDEC_HWACCEL
221 int i,
ret, dim_reset = 0;
223 if (
width !=
s->avctx->width || ((
width+15)/16 !=
s->mb_width || (
height+15)/16 !=
s->mb_height) &&
s->macroblocks_base ||
231 dim_reset = (
s->macroblocks_base !=
NULL);
235 !
s->actually_webp && !is_vp7) {
242 s->mb_width = (
s->avctx->coded_width + 15) / 16;
243 s->mb_height = (
s->avctx->coded_height + 15) / 16;
248 s->macroblocks_base =
av_mallocz((
s->mb_width +
s->mb_height * 2 + 1) *
249 sizeof(*
s->macroblocks));
250 s->intra4x4_pred_mode_top =
av_mallocz(
s->mb_width * 4);
252 s->macroblocks_base =
av_mallocz((
s->mb_width + 2) * (
s->mb_height + 2) *
253 sizeof(*
s->macroblocks));
255 s->top_border =
av_mallocz((
s->mb_width + 1) *
sizeof(*
s->top_border));
258 if (!
s->macroblocks_base || !
s->top_nnz || !
s->top_border ||
259 !
s->thread_data || (!
s->intra4x4_pred_mode_top && !
s->mb_layout)) {
265 s->thread_data[
i].filter_strength =
266 av_mallocz(
s->mb_width *
sizeof(*
s->thread_data[0].filter_strength));
267 if (!
s->thread_data[
i].filter_strength) {
277 s->macroblocks =
s->macroblocks_base + 1;
301 if (
s->segmentation.update_feature_data) {
304 for (
i = 0;
i < 4;
i++)
307 for (
i = 0;
i < 4;
i++)
310 if (
s->segmentation.update_map)
311 for (
i = 0;
i < 3;
i++)
320 for (
i = 0;
i < 4;
i++) {
325 s->lf_delta.ref[
i] = -
s->lf_delta.ref[
i];
334 s->lf_delta.mode[
i] = -
s->lf_delta.mode[
i];
341 const uint8_t *
sizes = buf;
347 buf += 3 * (
s->num_coeff_partitions - 1);
348 buf_size -= 3 * (
s->num_coeff_partitions - 1);
352 for (
i = 0;
i <
s->num_coeff_partitions - 1;
i++) {
354 if (buf_size -
size < 0)
356 s->coeff_partition_size[
i] =
size;
365 s->coeff_partition_size[
i] = buf_size;
402 for (
i = 0;
i < 4;
i++) {
403 if (
s->segmentation.enabled) {
404 base_qi =
s->segmentation.base_quant[
i];
405 if (!
s->segmentation.absolute_vals)
406 base_qi +=
s->quant.yac_qi;
408 base_qi =
s->quant.yac_qi;
418 s->qmat[
i].luma_dc_qmul[1] =
FFMAX(
s->qmat[
i].luma_dc_qmul[1], 8);
419 s->qmat[
i].chroma_qmul[0] =
FFMIN(
s->qmat[
i].chroma_qmul[0], 132);
455 for (
i = 0;
i < 4;
i++)
456 for (j = 0; j < 16; j++)
458 sizeof(
s->prob->token[
i][j]));
466 for (
i = 0;
i < 4;
i++)
467 for (j = 0; j < 8; j++)
468 for (k = 0; k < 3; k++)
477 #define VP7_MVC_SIZE 17
478 #define VP8_MVC_SIZE 19
487 for (
i = 0;
i < 4;
i++)
490 for (
i = 0;
i < 3;
i++)
494 for (
i = 0;
i < 2;
i++)
495 for (j = 0; j < mvc_size; j++)
515 for (j = 1; j < 3; j++) {
522 static void fade(uint8_t *dst, ptrdiff_t dst_linesize,
523 const uint8_t *
src, ptrdiff_t src_linesize,
528 for (j = 0; j <
height; j++) {
529 const uint8_t *
src2 =
src + j * src_linesize;
530 uint8_t *dst2 = dst + j * dst_linesize;
542 if (!
s->keyframe && (
alpha || beta)) {
543 int width =
s->mb_width * 16;
544 int height =
s->mb_height * 16;
569 src->data[0],
src->linesize[0],
579 int part1_size, hscale, vscale,
i, j,
ret;
580 int width =
s->avctx->width;
584 int fade_present = 1;
590 s->profile = (buf[0] >> 1) & 7;
591 if (
s->profile > 1) {
596 s->keyframe = !(buf[0] & 1);
598 part1_size =
AV_RL24(buf) >> 4;
600 if (buf_size < 4 - s->
profile + part1_size) {
601 av_log(
s->avctx,
AV_LOG_ERROR,
"Buffer size %d is too small, needed : %d\n", buf_size, 4 -
s->profile + part1_size);
605 buf += 4 -
s->profile;
606 buf_size -= 4 -
s->profile;
608 memcpy(
s->put_pixels_tab,
s->vp8dsp.put_vp8_epel_pixels_tab,
sizeof(
s->put_pixels_tab));
614 buf_size -= part1_size;
622 if (hscale || vscale)
628 sizeof(
s->prob->pred16x16));
630 sizeof(
s->prob->pred8x8c));
631 for (
i = 0;
i < 2;
i++)
634 memset(&
s->segmentation, 0,
sizeof(
s->segmentation));
635 memset(&
s->lf_delta, 0,
sizeof(
s->lf_delta));
639 if (
s->keyframe ||
s->profile > 0)
640 memset(
s->inter_dc_pred, 0 ,
sizeof(
s->inter_dc_pred));
643 for (
i = 0;
i < 4;
i++) {
645 if (
s->feature_enabled[
i]) {
648 for (j = 0; j < 3; j++)
649 s->feature_index_prob[
i][j] =
653 for (j = 0; j < 4; j++)
654 s->feature_value[
i][j] =
659 s->segmentation.enabled = 0;
660 s->segmentation.update_map = 0;
661 s->lf_delta.enabled = 0;
663 s->num_coeff_partitions = 1;
668 if (!
s->macroblocks_base ||
670 (
width + 15) / 16 !=
s->mb_width || (
height + 15) / 16 !=
s->mb_height) {
685 s->update_probabilities = 1;
687 if (
s->profile > 0) {
689 if (!
s->update_probabilities)
690 s->prob[1] =
s->prob[0];
710 for (
i = 1;
i < 16;
i++)
722 s->mbskip_enabled = 0;
743 int header_size, hscale, vscale,
ret;
744 int width =
s->avctx->width;
752 s->keyframe = !(buf[0] & 1);
753 s->profile = (buf[0]>>1) & 7;
754 s->invisible = !(buf[0] & 0x10);
755 header_size =
AV_RL24(buf) >> 5;
759 s->header_partition_size = header_size;
765 memcpy(
s->put_pixels_tab,
s->vp8dsp.put_vp8_epel_pixels_tab,
766 sizeof(
s->put_pixels_tab));
768 memcpy(
s->put_pixels_tab,
s->vp8dsp.put_vp8_bilinear_pixels_tab,
769 sizeof(
s->put_pixels_tab));
771 if (header_size > buf_size - 7 *
s->keyframe) {
777 if (
AV_RL24(buf) != 0x2a019d) {
779 "Invalid start code 0x%x\n",
AV_RL24(buf));
784 hscale = buf[4] >> 6;
785 vscale = buf[6] >> 6;
789 if (hscale || vscale)
795 sizeof(
s->prob->pred16x16));
797 sizeof(
s->prob->pred8x8c));
799 sizeof(
s->prob->mvc));
800 memset(&
s->segmentation, 0,
sizeof(
s->segmentation));
801 memset(&
s->lf_delta, 0,
sizeof(
s->lf_delta));
808 buf_size -= header_size;
820 s->segmentation.update_map = 0;
828 if (
s->lf_delta.update)
837 if (!
s->macroblocks_base ||
839 (
width+15)/16 !=
s->mb_width || (
height+15)/16 !=
s->mb_height)
854 s->prob[1] =
s->prob[0];
872 s->coder_state_at_header_end.input =
s->c.buffer - (-
s->c.bits / 8);
873 s->coder_state_at_header_end.range =
s->c.high;
874 s->coder_state_at_header_end.value =
s->c.code_word >> 16;
875 s->coder_state_at_header_end.bit_count = -
s->c.bits % 8;
884 av_clip(
s->mv_max.x, INT16_MIN, INT16_MAX));
886 av_clip(
s->mv_max.y, INT16_MIN, INT16_MAX));
899 for (
i = 0;
i < 3;
i++)
901 for (
i = (vp7 ? 7 : 9);
i > 3;
i--)
907 const uint8_t *ps = p + 2;
956 const uint8_t *mbsplits_top, *mbsplits_cur, *firstidx;
958 const VP8mv *left_mv = left_mb->
bmv;
964 top_mb = &
mb[-
s->mb_width - 1];
966 top_mv = top_mb->
bmv;
980 mb->partitioning = part_idx;
982 for (n = 0; n < num; n++) {
984 uint32_t
left, above;
985 const uint8_t *submv_prob;
992 above =
AV_RN32A(&top_mv[mbsplits_top[k + 12]]);
994 above =
AV_RN32A(&cur_mv[mbsplits_cur[k - 4]]);
1001 mb->bmv[n].y =
mb->mv.y +
1003 mb->bmv[n].x =
mb->mv.x +
1031 int xoffset,
int yoffset,
int boundary,
1032 int *edge_x,
int *edge_y)
1034 int vwidth = mb_width + 1;
1035 int new = (mb_y + yoffset) * vwidth + mb_x + xoffset;
1036 if (
new < boundary ||
new % vwidth == vwidth - 1)
1038 *edge_y =
new / vwidth;
1039 *edge_x =
new % vwidth;
1050 int mb_x,
int mb_y,
int layout)
1052 enum { CNT_ZERO, CNT_NEAREST, CNT_NEAR };
1053 enum { VP8_EDGE_TOP, VP8_EDGE_LEFT, VP8_EDGE_TOPLEFT };
1056 uint8_t cnt[3] = { 0 };
1069 pred->yoffset, !
s->profile, &edge_x, &edge_y)) {
1071 ?
s->macroblocks_base + 1 + edge_x +
1072 (
s->mb_width + 1) * (edge_y + 1)
1073 :
s->macroblocks + edge_x +
1074 (
s->mb_height - edge_y - 1) * 2;
1077 if (
AV_RN32A(&near_mv[CNT_NEAREST])) {
1080 }
else if (
AV_RN32A(&near_mv[CNT_NEAR])) {
1110 if (cnt[CNT_NEAREST] > cnt[CNT_NEAR])
1111 AV_WN32A(&
mb->mv, cnt[CNT_ZERO] > cnt[CNT_NEAREST] ? 0 :
AV_RN32A(&near_mv[CNT_NEAREST]));
1121 mb->bmv[0] =
mb->mv;
1124 mb->mv = near_mv[CNT_NEAR];
1125 mb->bmv[0] =
mb->mv;
1128 mb->mv = near_mv[CNT_NEAREST];
1129 mb->bmv[0] =
mb->mv;
1134 mb->bmv[0] =
mb->mv;
1140 int mb_x,
int mb_y,
int layout)
1145 enum { CNT_ZERO, CNT_NEAREST, CNT_NEAR, CNT_SPLITMV };
1146 enum { VP8_EDGE_TOP, VP8_EDGE_LEFT, VP8_EDGE_TOPLEFT };
1148 int cur_sign_bias =
s->sign_bias[
mb->ref_frame];
1149 const int8_t *sign_bias =
s->sign_bias;
1151 uint8_t cnt[4] = { 0 };
1155 mb_edge[0] =
mb + 2;
1156 mb_edge[2] =
mb + 1;
1158 mb_edge[0] =
mb -
s->mb_width - 1;
1159 mb_edge[2] =
mb -
s->mb_width - 2;
1167 #define MV_EDGE_CHECK(n) \
1169 const VP8Macroblock *edge = mb_edge[n]; \
1170 int edge_ref = edge->ref_frame; \
1171 if (edge_ref != VP8_FRAME_CURRENT) { \
1172 uint32_t mv = AV_RN32A(&edge->mv); \
1174 if (cur_sign_bias != sign_bias[edge_ref]) { \
1177 mv = ((mv & 0x7fff7fff) + \
1178 0x00010001) ^ (mv & 0x80008000); \
1180 if (!n || mv != AV_RN32A(&near_mv[idx])) \
1181 AV_WN32A(&near_mv[++idx], mv); \
1182 cnt[idx] += 1 + (n != 2); \
1184 cnt[CNT_ZERO] += 1 + (n != 2); \
1197 if (cnt[CNT_SPLITMV] &&
1198 AV_RN32A(&near_mv[1 + VP8_EDGE_TOP]) ==
AV_RN32A(&near_mv[1 + VP8_EDGE_TOPLEFT]))
1199 cnt[CNT_NEAREST] += 1;
1202 if (cnt[CNT_NEAR] > cnt[CNT_NEAREST]) {
1203 FFSWAP(uint8_t, cnt[CNT_NEAREST], cnt[CNT_NEAR]);
1204 FFSWAP(
VP8mv, near_mv[CNT_NEAREST], near_mv[CNT_NEAR]);
1210 clamp_mv(mv_bounds, &
mb->mv, &near_mv[CNT_ZERO + (cnt[CNT_NEAREST] >= cnt[CNT_ZERO])]);
1221 mb->bmv[0] =
mb->mv;
1224 clamp_mv(mv_bounds, &
mb->mv, &near_mv[CNT_NEAR]);
1225 mb->bmv[0] =
mb->mv;
1228 clamp_mv(mv_bounds, &
mb->mv, &near_mv[CNT_NEAREST]);
1229 mb->bmv[0] =
mb->mv;
1234 mb->bmv[0] =
mb->mv;
1240 int mb_x,
int keyframe,
int layout)
1242 uint8_t *intra4x4 =
mb->intra4x4_pred_mode_mb;
1251 uint8_t *
const left =
s->intra4x4_pred_mode_left;
1253 top =
mb->intra4x4_pred_mode_top;
1255 top =
s->intra4x4_pred_mode_top + 4 * mb_x;
1256 for (y = 0; y < 4; y++) {
1257 for (x = 0; x < 4; x++) {
1261 left[y] = top[x] = *intra4x4;
1267 for (
i = 0;
i < 16;
i++)
1279 static const char *
const vp7_feature_name[] = {
"q-index",
1281 "partial-golden-update",
1286 for (
i = 0;
i < 4;
i++) {
1287 if (
s->feature_enabled[
i]) {
1290 s->feature_index_prob[
i]);
1292 "Feature %s present in macroblock (value 0x%x)\n",
1293 vp7_feature_name[
i],
s->feature_value[
i][
index]);
1297 }
else if (
s->segmentation.update_map) {
1300 }
else if (
s->segmentation.enabled)
1333 s->ref_count[
mb->ref_frame - 1]++;
1343 s->prob->pred16x16);
1369 int i,
const uint8_t *token_prob,
const int16_t qmul[2],
1370 const uint8_t scan[16],
int vp7)
1384 token_prob = probs[
i][0];
1392 token_prob = probs[
i + 1][1];
1412 int cat = (
a << 1) +
b;
1417 token_prob = probs[
i + 1][2];
1452 int i,
const uint8_t *token_prob,
1453 const int16_t qmul[2],
1454 const uint8_t scan[16])
1457 token_prob, qmul, scan,
IS_VP7);
1460 #ifndef vp8_decode_block_coeffs_internal
1464 int i,
const uint8_t *token_prob,
1465 const int16_t qmul[2])
1488 int i,
int zero_nhood,
const int16_t qmul[2],
1489 const uint8_t scan[16],
int vp7)
1491 const uint8_t *token_prob = probs[
i][zero_nhood];
1495 token_prob, qmul, scan)
1505 int i, x, y, luma_start = 0, luma_ctx = 3;
1506 int nnz_pred, nnz, nnz_total = 0;
1511 nnz_pred = t_nnz[8] + l_nnz[8];
1515 nnz_pred,
s->qmat[
segment].luma_dc_qmul,
1517 l_nnz[8] = t_nnz[8] = !!nnz;
1521 s->inter_dc_pred[
mb->ref_frame - 1]);
1528 s->vp8dsp.vp8_luma_dc_wht_dc(
td->block,
td->block_dc);
1530 s->vp8dsp.vp8_luma_dc_wht(
td->block,
td->block_dc);
1537 for (y = 0; y < 4; y++)
1538 for (x = 0; x < 4; x++) {
1539 nnz_pred = l_nnz[y] + t_nnz[x];
1541 s->prob->token[luma_ctx],
1542 luma_start, nnz_pred,
1544 s->prob[0].scan, is_vp7);
1547 td->non_zero_count_cache[y][x] = nnz + block_dc;
1548 t_nnz[x] = l_nnz[y] = !!nnz;
1555 for (
i = 4;
i < 6;
i++)
1556 for (y = 0; y < 2; y++)
1557 for (x = 0; x < 2; x++) {
1558 nnz_pred = l_nnz[
i + 2 * y] + t_nnz[
i + 2 * x];
1560 s->prob->token[2], 0, nnz_pred,
1562 s->prob[0].scan, is_vp7);
1563 td->non_zero_count_cache[
i][(y << 1) + x] = nnz;
1564 t_nnz[
i + 2 * x] = l_nnz[
i + 2 * y] = !!nnz;
1577 const uint8_t *src_cb,
const uint8_t *src_cr,
1578 ptrdiff_t linesize, ptrdiff_t uvlinesize,
int simple)
1580 AV_COPY128(top_border, src_y + 15 * linesize);
1582 AV_COPY64(top_border + 16, src_cb + 7 * uvlinesize);
1583 AV_COPY64(top_border + 24, src_cr + 7 * uvlinesize);
1589 uint8_t *src_cr, ptrdiff_t linesize, ptrdiff_t uvlinesize,
int mb_x,
1590 int mb_y,
int mb_width,
int simple,
int xchg)
1592 uint8_t *top_border_m1 = top_border - 32;
1594 src_cb -= uvlinesize;
1595 src_cr -= uvlinesize;
1597 #define XCHG(a, b, xchg) \
1605 XCHG(top_border_m1 + 8, src_y - 8, xchg);
1606 XCHG(top_border, src_y, xchg);
1607 XCHG(top_border + 8, src_y + 8, 1);
1608 if (mb_x < mb_width - 1)
1609 XCHG(top_border + 32, src_y + 16, 1);
1613 if (!simple || !mb_y) {
1614 XCHG(top_border_m1 + 16, src_cb - 8, xchg);
1615 XCHG(top_border_m1 + 24, src_cr - 8, xchg);
1616 XCHG(top_border + 16, src_cb, 1);
1617 XCHG(top_border + 24, src_cr, 1);
1667 int *copy_buf,
int vp7)
1671 if (!mb_x && mb_y) {
1705 int x, y,
mode, nnz;
1710 if (mb_y && (
s->deblock_filter || !mb_y) &&
td->thread_nr == 0)
1712 s->linesize,
s->uvlinesize, mb_x, mb_y,
s->mb_width,
1713 s->filter.simple, 1);
1717 s->hpc.pred16x16[
mode](dst[0],
s->linesize);
1719 uint8_t *ptr = dst[0];
1720 const uint8_t *intra4x4 =
mb->intra4x4_pred_mode_mb;
1721 const uint8_t lo = is_vp7 ? 128 : 127;
1722 const uint8_t hi = is_vp7 ? 128 : 129;
1723 const uint8_t tr_top[4] = { lo, lo, lo, lo };
1727 const uint8_t *tr_right = ptr -
s->linesize + 16;
1731 if (mb_y && mb_x ==
s->mb_width - 1) {
1732 tr = tr_right[-1] * 0x01010101
u;
1733 tr_right = (uint8_t *) &tr;
1739 for (y = 0; y < 4; y++) {
1740 const uint8_t *topright = ptr + 4 -
s->linesize;
1741 for (x = 0; x < 4; x++) {
1743 ptrdiff_t linesize =
s->linesize;
1744 uint8_t *dst = ptr + 4 * x;
1747 if ((y == 0 || x == 3) && mb_y == 0) {
1750 topright = tr_right;
1753 mb_y + y, &
copy, is_vp7);
1755 dst = copy_dst + 12;
1759 AV_WN32A(copy_dst + 4, lo * 0x01010101U);
1761 AV_COPY32(copy_dst + 4, ptr + 4 * x -
s->linesize);
1765 copy_dst[3] = ptr[4 * x -
s->linesize - 1];
1774 copy_dst[11] = ptr[4 * x - 1];
1775 copy_dst[19] = ptr[4 * x +
s->linesize - 1];
1776 copy_dst[27] = ptr[4 * x +
s->linesize * 2 - 1];
1777 copy_dst[35] = ptr[4 * x +
s->linesize * 3 - 1];
1780 s->hpc.pred4x4[
mode](dst, topright, linesize);
1783 AV_COPY32(ptr + 4 * x +
s->linesize, copy_dst + 20);
1784 AV_COPY32(ptr + 4 * x +
s->linesize * 2, copy_dst + 28);
1785 AV_COPY32(ptr + 4 * x +
s->linesize * 3, copy_dst + 36);
1788 nnz =
td->non_zero_count_cache[y][x];
1791 s->vp8dsp.vp8_idct_dc_add(ptr + 4 * x,
1792 td->block[y][x],
s->linesize);
1794 s->vp8dsp.vp8_idct_add(ptr + 4 * x,
1795 td->block[y][x],
s->linesize);
1800 ptr += 4 *
s->linesize;
1806 mb_x, mb_y, is_vp7);
1807 s->hpc.pred8x8[
mode](dst[1],
s->uvlinesize);
1808 s->hpc.pred8x8[
mode](dst[2],
s->uvlinesize);
1810 if (mb_y && (
s->deblock_filter || !mb_y) &&
td->thread_nr == 0)
1812 s->linesize,
s->uvlinesize, mb_x, mb_y,
s->mb_width,
1813 s->filter.simple, 0);
1817 { 0, 1, 2, 1, 2, 1, 2, 1 },
1819 { 0, 3, 5, 3, 5, 3, 5, 3 },
1820 { 0, 2, 3, 2, 3, 2, 3, 2 },
1842 int x_off,
int y_off,
int block_w,
int block_h,
1846 const uint8_t *
src =
ref->f->data[0];
1849 ptrdiff_t src_linesize = linesize;
1854 x_off +=
mv->x >> 2;
1855 y_off +=
mv->y >> 2;
1859 src += y_off * linesize + x_off;
1862 s->vdsp.emulated_edge_mc(
td->edge_emu_buffer,
1863 src - my_idx * linesize - mx_idx,
1867 x_off - mx_idx, y_off - my_idx,
1872 mc_func[my_idx][mx_idx](dst, linesize,
src, src_linesize, block_h, mx, my);
1875 mc_func[0][0](dst, linesize,
src + y_off * linesize + x_off,
1876 linesize, block_h, 0, 0);
1900 int x_off,
int y_off,
int block_w,
int block_h,
1910 x_off +=
mv->x >> 3;
1911 y_off +=
mv->y >> 3;
1914 src1 += y_off * linesize + x_off;
1915 src2 += y_off * linesize + x_off;
1919 s->vdsp.emulated_edge_mc(
td->edge_emu_buffer,
1920 src1 - my_idx * linesize - mx_idx,
1928 s->vdsp.emulated_edge_mc(
td->edge_emu_buffer,
1929 src2 - my_idx * linesize - mx_idx,
1937 mc_func[my_idx][mx_idx](dst1, linesize,
src1, linesize, block_h, mx, my);
1938 mc_func[my_idx][mx_idx](dst2, linesize,
src2, linesize, block_h, mx, my);
1942 mc_func[0][0](dst1, linesize,
src1 + y_off * linesize + x_off, linesize, block_h, 0, 0);
1943 mc_func[0][0](dst2, linesize,
src2 + y_off * linesize + x_off, linesize, block_h, 0, 0);
1949 const ThreadFrame *ref_frame,
int x_off,
int y_off,
1950 int bx_off,
int by_off,
int block_w,
int block_h,
1957 ref_frame,
mv, x_off + bx_off, y_off + by_off,
1959 s->put_pixels_tab[block_w == 8]);
1962 if (
s->profile == 3) {
1977 dst[2] + by_off *
s->uvlinesize + bx_off, ref_frame,
1978 &uvmv, x_off + bx_off, y_off + by_off,
1980 s->put_pixels_tab[1 + (block_w == 4)]);
1987 int mb_x,
int mb_y,
int mb_xy,
int ref)
1990 if (
s->ref_count[
ref - 1] > (mb_xy >> 5)) {
1991 int x_off = mb_x << 4, y_off = mb_y << 4;
1992 int mx = (
mb->mv.x >> 2) + x_off + 8;
1993 int my = (
mb->mv.y >> 2) + y_off;
1994 uint8_t **
src =
s->framep[
ref]->tf.f->data;
1995 int off = mx + (my + (mb_x & 3) * 4) *
s->linesize + 64;
1999 s->vdsp.prefetch(
src[0] + off,
s->linesize, 4);
2000 off = (mx >> 1) + ((my >> 1) + (mb_x & 7)) *
s->uvlinesize + 64;
2001 s->vdsp.prefetch(
src[1] + off,
src[2] -
src[1], 2);
2012 int x_off = mb_x << 4, y_off = mb_y << 4;
2017 switch (
mb->partitioning) {
2027 for (y = 0; y < 4; y++) {
2028 for (x = 0; x < 4; x++) {
2030 ref, &bmv[4 * y + x],
2031 4 * x + x_off, 4 * y + y_off, 4, 4,
2033 s->put_pixels_tab[2]);
2042 for (y = 0; y < 2; y++) {
2043 for (x = 0; x < 2; x++) {
2044 uvmv.
x =
mb->bmv[2 * y * 4 + 2 * x ].x +
2045 mb->bmv[2 * y * 4 + 2 * x + 1].x +
2046 mb->bmv[(2 * y + 1) * 4 + 2 * x ].x +
2047 mb->bmv[(2 * y + 1) * 4 + 2 * x + 1].x;
2048 uvmv.
y =
mb->bmv[2 * y * 4 + 2 * x ].y +
2049 mb->bmv[2 * y * 4 + 2 * x + 1].y +
2050 mb->bmv[(2 * y + 1) * 4 + 2 * x ].y +
2051 mb->bmv[(2 * y + 1) * 4 + 2 * x + 1].y;
2054 if (
s->profile == 3) {
2059 dst[2] + 4 * y *
s->uvlinesize + x * 4,
ref,
2060 &uvmv, 4 * x + x_off, 4 * y + y_off, 4, 4,
2062 s->put_pixels_tab[2]);
2099 uint8_t *y_dst = dst[0];
2100 for (y = 0; y < 4; y++) {
2101 uint32_t nnz4 =
AV_RL32(
td->non_zero_count_cache[y]);
2103 if (nnz4 & ~0x01010101) {
2104 for (x = 0; x < 4; x++) {
2105 if ((uint8_t) nnz4 == 1)
2106 s->vp8dsp.vp8_idct_dc_add(y_dst + 4 * x,
2109 else if ((uint8_t) nnz4 > 1)
2110 s->vp8dsp.vp8_idct_add(y_dst + 4 * x,
2118 s->vp8dsp.vp8_idct_dc_add4y(y_dst,
td->block[y],
s->linesize);
2121 y_dst += 4 *
s->linesize;
2125 for (ch = 0; ch < 2; ch++) {
2126 uint32_t nnz4 =
AV_RL32(
td->non_zero_count_cache[4 + ch]);
2128 uint8_t *ch_dst = dst[1 + ch];
2129 if (nnz4 & ~0x01010101) {
2130 for (y = 0; y < 2; y++) {
2131 for (x = 0; x < 2; x++) {
2132 if ((uint8_t) nnz4 == 1)
2133 s->vp8dsp.vp8_idct_dc_add(ch_dst + 4 * x,
2134 td->block[4 + ch][(y << 1) + x],
2136 else if ((uint8_t) nnz4 > 1)
2137 s->vp8dsp.vp8_idct_add(ch_dst + 4 * x,
2138 td->block[4 + ch][(y << 1) + x],
2142 goto chroma_idct_end;
2144 ch_dst += 4 *
s->uvlinesize;
2147 s->vp8dsp.vp8_idct_dc_add4uv(ch_dst,
td->block[4 + ch],
s->uvlinesize);
2159 int interior_limit, filter_level;
2161 if (
s->segmentation.enabled) {
2162 filter_level =
s->segmentation.filter_level[
mb->segment];
2163 if (!
s->segmentation.absolute_vals)
2164 filter_level +=
s->filter.level;
2166 filter_level =
s->filter.level;
2168 if (
s->lf_delta.enabled) {
2169 filter_level +=
s->lf_delta.ref[
mb->ref_frame];
2170 filter_level +=
s->lf_delta.mode[
mb->mode];
2175 interior_limit = filter_level;
2176 if (
s->filter.sharpness) {
2177 interior_limit >>= (
s->filter.sharpness + 3) >> 2;
2178 interior_limit =
FFMIN(interior_limit, 9 -
s->filter.sharpness);
2180 interior_limit =
FFMAX(interior_limit, 1);
2182 f->filter_level = filter_level;
2183 f->inner_limit = interior_limit;
2184 f->inner_filter = is_vp7 || !
mb->skip ||
mb->mode ==
MODE_I4x4 ||
2190 int mb_x,
int mb_y,
int is_vp7)
2192 int mbedge_lim, bedge_lim_y, bedge_lim_uv, hev_thresh;
2193 int filter_level =
f->filter_level;
2194 int inner_limit =
f->inner_limit;
2195 int inner_filter =
f->inner_filter;
2196 ptrdiff_t linesize =
s->linesize;
2197 ptrdiff_t uvlinesize =
s->uvlinesize;
2198 static const uint8_t hev_thresh_lut[2][64] = {
2199 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1,
2200 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2201 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
2203 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1,
2204 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2205 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2213 bedge_lim_y = filter_level;
2214 bedge_lim_uv = filter_level * 2;
2215 mbedge_lim = filter_level + 2;
2218 bedge_lim_uv = filter_level * 2 + inner_limit;
2219 mbedge_lim = bedge_lim_y + 4;
2222 hev_thresh = hev_thresh_lut[
s->keyframe][filter_level];
2225 s->vp8dsp.vp8_h_loop_filter16y(dst[0], linesize,
2226 mbedge_lim, inner_limit, hev_thresh);
2227 s->vp8dsp.vp8_h_loop_filter8uv(dst[1], dst[2], uvlinesize,
2228 mbedge_lim, inner_limit, hev_thresh);
2231 #define H_LOOP_FILTER_16Y_INNER(cond) \
2232 if (cond && inner_filter) { \
2233 s->vp8dsp.vp8_h_loop_filter16y_inner(dst[0] + 4, linesize, \
2234 bedge_lim_y, inner_limit, \
2236 s->vp8dsp.vp8_h_loop_filter16y_inner(dst[0] + 8, linesize, \
2237 bedge_lim_y, inner_limit, \
2239 s->vp8dsp.vp8_h_loop_filter16y_inner(dst[0] + 12, linesize, \
2240 bedge_lim_y, inner_limit, \
2242 s->vp8dsp.vp8_h_loop_filter8uv_inner(dst[1] + 4, dst[2] + 4, \
2243 uvlinesize, bedge_lim_uv, \
2244 inner_limit, hev_thresh); \
2250 s->vp8dsp.vp8_v_loop_filter16y(dst[0], linesize,
2251 mbedge_lim, inner_limit, hev_thresh);
2252 s->vp8dsp.vp8_v_loop_filter8uv(dst[1], dst[2], uvlinesize,
2253 mbedge_lim, inner_limit, hev_thresh);
2257 s->vp8dsp.vp8_v_loop_filter16y_inner(dst[0] + 4 * linesize,
2258 linesize, bedge_lim_y,
2259 inner_limit, hev_thresh);
2260 s->vp8dsp.vp8_v_loop_filter16y_inner(dst[0] + 8 * linesize,
2261 linesize, bedge_lim_y,
2262 inner_limit, hev_thresh);
2263 s->vp8dsp.vp8_v_loop_filter16y_inner(dst[0] + 12 * linesize,
2264 linesize, bedge_lim_y,
2265 inner_limit, hev_thresh);
2266 s->vp8dsp.vp8_v_loop_filter8uv_inner(dst[1] + 4 * uvlinesize,
2267 dst[2] + 4 * uvlinesize,
2268 uvlinesize, bedge_lim_uv,
2269 inner_limit, hev_thresh);
2279 int mbedge_lim, bedge_lim;
2280 int filter_level =
f->filter_level;
2281 int inner_limit =
f->inner_limit;
2282 int inner_filter =
f->inner_filter;
2283 ptrdiff_t linesize =
s->linesize;
2288 bedge_lim = 2 * filter_level + inner_limit;
2289 mbedge_lim = bedge_lim + 4;
2292 s->vp8dsp.vp8_h_loop_filter_simple(dst, linesize, mbedge_lim);
2294 s->vp8dsp.vp8_h_loop_filter_simple(dst + 4, linesize, bedge_lim);
2295 s->vp8dsp.vp8_h_loop_filter_simple(dst + 8, linesize, bedge_lim);
2296 s->vp8dsp.vp8_h_loop_filter_simple(dst + 12, linesize, bedge_lim);
2300 s->vp8dsp.vp8_v_loop_filter_simple(dst, linesize, mbedge_lim);
2302 s->vp8dsp.vp8_v_loop_filter_simple(dst + 4 * linesize, linesize, bedge_lim);
2303 s->vp8dsp.vp8_v_loop_filter_simple(dst + 8 * linesize, linesize, bedge_lim);
2304 s->vp8dsp.vp8_v_loop_filter_simple(dst + 12 * linesize, linesize, bedge_lim);
2308 #define MARGIN (16 << 2)
2311 const VP8Frame *prev_frame,
int is_vp7)
2316 s->mv_bounds.mv_min.y = -
MARGIN;
2317 s->mv_bounds.mv_max.y = ((
s->mb_height - 1) << 6) +
MARGIN;
2318 for (mb_y = 0; mb_y <
s->mb_height; mb_y++) {
2320 ((
s->mb_width + 1) * (mb_y + 1) + 1);
2321 int mb_xy = mb_y *
s->mb_width;
2325 s->mv_bounds.mv_min.x = -
MARGIN;
2326 s->mv_bounds.mv_max.x = ((
s->mb_width - 1) << 6) +
MARGIN;
2328 for (mb_x = 0; mb_x <
s->mb_width; mb_x++, mb_xy++,
mb++) {
2333 AV_WN32A((
mb -
s->mb_width - 1)->intra4x4_pred_mode_top,
2336 prev_frame && prev_frame->
seg_map ?
2338 s->mv_bounds.mv_min.x -= 64;
2339 s->mv_bounds.mv_max.x -= 64;
2341 s->mv_bounds.mv_min.y -= 64;
2342 s->mv_bounds.mv_max.y -= 64;
2360 #define check_thread_pos(td, otd, mb_x_check, mb_y_check) \
2362 int tmp = (mb_y_check << 16) | (mb_x_check & 0xFFFF); \
2363 if (atomic_load(&otd->thread_mb_pos) < tmp) { \
2364 pthread_mutex_lock(&otd->lock); \
2365 atomic_store(&td->wait_mb_pos, tmp); \
2367 if (atomic_load(&otd->thread_mb_pos) >= tmp) \
2369 pthread_cond_wait(&otd->cond, &otd->lock); \
2371 atomic_store(&td->wait_mb_pos, INT_MAX); \
2372 pthread_mutex_unlock(&otd->lock); \
2376 #define update_pos(td, mb_y, mb_x) \
2378 int pos = (mb_y << 16) | (mb_x & 0xFFFF); \
2379 int sliced_threading = (avctx->active_thread_type == FF_THREAD_SLICE) && \
2381 int is_null = !next_td || !prev_td; \
2382 int pos_check = (is_null) ? 1 : \
2383 (next_td != td && pos >= atomic_load(&next_td->wait_mb_pos)) || \
2384 (prev_td != td && pos >= atomic_load(&prev_td->wait_mb_pos)); \
2385 atomic_store(&td->thread_mb_pos, pos); \
2386 if (sliced_threading && pos_check) { \
2387 pthread_mutex_lock(&td->lock); \
2388 pthread_cond_broadcast(&td->cond); \
2389 pthread_mutex_unlock(&td->lock); \
2393 #define check_thread_pos(td, otd, mb_x_check, mb_y_check) while(0)
2394 #define update_pos(td, mb_y, mb_x) while(0)
2398 int jobnr,
int threadnr,
int is_vp7)
2403 int mb_x, mb_xy = mb_y *
s->mb_width;
2404 int num_jobs =
s->num_jobs;
2405 const VP8Frame *prev_frame =
s->prev_frame;
2407 VPXRangeCoder *coeff_c = &
s->coeff_partition[mb_y & (
s->num_coeff_partitions - 1)];
2411 curframe->
tf.
f->
data[0] + 16 * mb_y *
s->linesize,
2412 curframe->
tf.
f->
data[1] + 8 * mb_y *
s->uvlinesize,
2413 curframe->
tf.
f->
data[2] + 8 * mb_y *
s->uvlinesize
2422 prev_td = &
s->thread_data[(jobnr + num_jobs - 1) % num_jobs];
2423 if (mb_y ==
s->mb_height - 1)
2426 next_td = &
s->thread_data[(jobnr + 1) % num_jobs];
2427 if (
s->mb_layout == 1)
2428 mb =
s->macroblocks_base + ((
s->mb_width + 1) * (mb_y + 1) + 1);
2432 if (prev_frame &&
s->segmentation.enabled &&
2433 !
s->segmentation.update_map)
2435 mb =
s->macroblocks + (
s->mb_height - mb_y - 1) * 2;
2436 memset(
mb - 1, 0,
sizeof(*
mb));
2440 if (!is_vp7 || mb_y == 0)
2441 memset(
td->left_nnz, 0,
sizeof(
td->left_nnz));
2444 td->mv_bounds.mv_max.x = ((
s->mb_width - 1) << 6) +
MARGIN;
2446 for (mb_x = 0; mb_x <
s->mb_width; mb_x++, mb_xy++,
mb++) {
2450 if (prev_td !=
td) {
2451 if (threadnr != 0) {
2453 mb_x + (is_vp7 ? 2 : 1),
2454 mb_y - (is_vp7 ? 2 : 1));
2457 mb_x + (is_vp7 ? 2 : 1) +
s->mb_width + 3,
2458 mb_y - (is_vp7 ? 2 : 1));
2462 s->vdsp.prefetch(dst[0] + (mb_x & 3) * 4 *
s->linesize + 64,
2464 s->vdsp.prefetch(dst[1] + (mb_x & 7) *
s->uvlinesize + 64,
2465 dst[2] - dst[1], 2);
2469 prev_frame && prev_frame->
seg_map ?
2496 td->left_nnz[8] = 0;
2497 s->top_nnz[mb_x][8] = 0;
2501 if (
s->deblock_filter)
2504 if (
s->deblock_filter && num_jobs != 1 && threadnr == num_jobs - 1) {
2505 if (
s->filter.simple)
2510 dst[1], dst[2],
s->linesize,
s->uvlinesize, 0);
2518 td->mv_bounds.mv_min.x -= 64;
2519 td->mv_bounds.mv_max.x -= 64;
2521 if (mb_x ==
s->mb_width + 1) {
2531 int jobnr,
int threadnr)
2537 int jobnr,
int threadnr)
2543 int jobnr,
int threadnr,
int is_vp7)
2547 int mb_x, mb_y =
atomic_load(&
td->thread_mb_pos) >> 16, num_jobs =
s->num_jobs;
2548 AVFrame *curframe =
s->curframe->tf.f;
2552 curframe->
data[0] + 16 * mb_y *
s->linesize,
2553 curframe->
data[1] + 8 * mb_y *
s->uvlinesize,
2554 curframe->
data[2] + 8 * mb_y *
s->uvlinesize
2557 if (
s->mb_layout == 1)
2558 mb =
s->macroblocks_base + ((
s->mb_width + 1) * (mb_y + 1) + 1);
2560 mb =
s->macroblocks + (
s->mb_height - mb_y - 1) * 2;
2565 prev_td = &
s->thread_data[(jobnr + num_jobs - 1) % num_jobs];
2566 if (mb_y ==
s->mb_height - 1)
2569 next_td = &
s->thread_data[(jobnr + 1) % num_jobs];
2571 for (mb_x = 0; mb_x <
s->mb_width; mb_x++,
mb++) {
2575 (mb_x + 1) + (
s->mb_width + 3), mb_y - 1);
2577 if (next_td != &
s->thread_data[0])
2580 if (num_jobs == 1) {
2581 if (
s->filter.simple)
2586 dst[1], dst[2],
s->linesize,
s->uvlinesize, 0);
2589 if (
s->filter.simple)
2602 int jobnr,
int threadnr)
2608 int jobnr,
int threadnr)
2615 int threadnr,
int is_vp7)
2621 int mb_y, num_jobs =
s->num_jobs;
2624 td->thread_nr = threadnr;
2625 td->mv_bounds.mv_min.y = -
MARGIN - 64 * threadnr;
2626 td->mv_bounds.mv_max.y = ((
s->mb_height - 1) << 6) +
MARGIN - 64 * threadnr;
2627 for (mb_y = jobnr; mb_y <
s->mb_height; mb_y += num_jobs) {
2629 ret =
s->decode_mb_row_no_filter(avctx, tdata, jobnr, threadnr);
2634 if (
s->deblock_filter)
2635 s->filter_mb_row(avctx, tdata, jobnr, threadnr);
2638 td->mv_bounds.mv_min.y -= 64 * num_jobs;
2639 td->mv_bounds.mv_max.y -= 64 * num_jobs;
2649 int jobnr,
int threadnr)
2655 int jobnr,
int threadnr)
2665 int ret,
i, referenced, num_jobs;
2677 if (
s->actually_webp) {
2681 if (
s->pix_fmt < 0) {
2699 memcpy(&
s->next_framep[0], &
s->framep[0],
sizeof(
s->framep[0]) * 4);
2705 for (
i = 0;
i < 5;
i++)
2706 if (
s->frames[
i].tf.f->buf[0] &&
2707 &
s->frames[
i] != prev_frame &&
2730 "Discarding interframe without a prior keyframe!\n");
2735 curframe->tf.f->key_frame =
s->keyframe;
2776 s->linesize = curframe->tf.f->linesize[0];
2777 s->uvlinesize = curframe->tf.f->linesize[1];
2779 memset(
s->top_nnz, 0,
s->mb_width *
sizeof(*
s->top_nnz));
2783 memset(
s->macroblocks +
s->mb_height * 2 - 1, 0,
2784 (
s->mb_width + 1) *
sizeof(*
s->macroblocks));
2785 if (!
s->mb_layout &&
s->keyframe)
2786 memset(
s->intra4x4_pred_mode_top,
DC_PRED,
s->mb_width * 4);
2788 memset(
s->ref_count, 0,
sizeof(
s->ref_count));
2790 if (
s->mb_layout == 1) {
2793 if (prev_frame &&
s->segmentation.enabled &&
2794 !
s->segmentation.update_map)
2808 s->num_jobs = num_jobs;
2809 s->curframe = curframe;
2810 s->prev_frame = prev_frame;
2811 s->mv_bounds.mv_min.y = -
MARGIN;
2812 s->mv_bounds.mv_max.y = ((
s->mb_height - 1) << 6) +
MARGIN;
2827 memcpy(&
s->framep[0], &
s->next_framep[0],
sizeof(
s->framep[0]) * 4);
2832 if (!
s->update_probabilities)
2833 s->prob[0] =
s->prob[1];
2835 if (!
s->invisible) {
2843 memcpy(&
s->next_framep[0], &
s->framep[0],
sizeof(
s->framep[0]) * 4);
2853 #if CONFIG_VP7_DECODER
2878 if (!
s->frames[
i].tf.f)
2898 if (CONFIG_VP7_DECODER && is_vp7) {
2903 }
else if (CONFIG_VP8_DECODER && !is_vp7) {
2921 #if CONFIG_VP7_DECODER
2933 #if CONFIG_VP8_DECODER
2935 #define REBASE(pic) ((pic) ? (pic) - &s_src->frames[0] + &s->frames[0] : NULL)
2943 if (
s->macroblocks_base &&
2944 (s_src->mb_width !=
s->mb_width || s_src->mb_height !=
s->mb_height)) {
2946 s->mb_width = s_src->mb_width;
2947 s->mb_height = s_src->mb_height;
2950 s->pix_fmt = s_src->pix_fmt;
2951 s->prob[0] = s_src->prob[!s_src->update_probabilities];
2952 s->segmentation = s_src->segmentation;
2953 s->lf_delta = s_src->lf_delta;
2954 memcpy(
s->sign_bias, s_src->sign_bias,
sizeof(
s->sign_bias));
2957 if (s_src->frames[
i].tf.f->buf[0]) {
2958 int ret = vp8_ref_frame(
s, &
s->frames[
i], &s_src->frames[
i]);
2964 s->framep[0] = REBASE(s_src->next_framep[0]);
2965 s->framep[1] = REBASE(s_src->next_framep[1]);
2966 s->framep[2] = REBASE(s_src->next_framep[2]);
2967 s->framep[3] = REBASE(s_src->next_framep[3]);
2974 #if CONFIG_VP7_DECODER
2981 .
init = vp7_decode_init,
2989 #if CONFIG_VP8_DECODER
3005 #if CONFIG_VP8_VAAPI_HWACCEL
3008 #if CONFIG_VP8_NVDEC_HWACCEL
static const int vp8_mode_contexts[6][4]
static const uint8_t vp8_dct_cat1_prob[]
int(* update_thread_context)(struct AVCodecContext *dst, const struct AVCodecContext *src)
Copy necessary context variables from a previous thread context to the current one.
static av_always_inline void decode_mb_mode(VP8Context *s, const VP8mvbounds *mv_bounds, VP8Macroblock *mb, int mb_x, int mb_y, uint8_t *segment, const uint8_t *ref, int layout, int is_vp7)
#define VP7_MV_PRED_COUNT
const struct AVHWAccel * hwaccel
Hardware accelerator in use.
av_cold int ff_vp8_decode_free(AVCodecContext *avctx)
static const uint8_t vp7_pred4x4_mode[]
static av_always_inline int decode_block_coeffs_internal(VPXRangeCoder *r, int16_t block[16], uint8_t probs[16][3][NUM_DCT_TOKENS - 1], int i, const uint8_t *token_prob, const int16_t qmul[2], const uint8_t scan[16], int vp7)
static const VP7MVPred vp7_mv_pred[VP7_MV_PRED_COUNT]
#define AV_LOG_WARNING
Something somehow does not look correct.
@ AV_PIX_FMT_CUDA
HW acceleration through CUDA.
AVPixelFormat
Pixel format.
static int vp8_decode_block_coeffs_internal(VPXRangeCoder *r, int16_t block[16], uint8_t probs[16][3][NUM_DCT_TOKENS - 1], int i, const uint8_t *token_prob, const int16_t qmul[2])
static int vp7_read_mv_component(VPXRangeCoder *c, const uint8_t *p)
static int vp7_calculate_mb_offset(int mb_x, int mb_y, int mb_width, int xoffset, int yoffset, int boundary, int *edge_x, int *edge_y)
The vp7 reference decoder uses a padding macroblock column (added to right edge of the frame) to guar...
#define atomic_store(object, desired)
static av_always_inline void backup_mb_border(uint8_t *top_border, const uint8_t *src_y, const uint8_t *src_cb, const uint8_t *src_cr, ptrdiff_t linesize, ptrdiff_t uvlinesize, int simple)
static void vp7_filter_mb_row(AVCodecContext *avctx, void *tdata, int jobnr, int threadnr)
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
enum AVColorSpace colorspace
YUV colorspace type.
void ff_thread_release_ext_buffer(AVCodecContext *avctx, ThreadFrame *f)
Unref a ThreadFrame.
static av_always_inline int vp78_decode_init(AVCodecContext *avctx, int is_vp7)
int ff_get_format(AVCodecContext *avctx, const enum AVPixelFormat *fmt)
Select the (possibly hardware accelerated) pixel format.
#define u(width, name, range_min, range_max)
static av_always_inline int check_tm_pred8x8_mode(int mode, int mb_x, int mb_y, int vp7)
static const uint8_t vp8_submv_prob[5][3]
uint8_t * data
The data buffer.
static av_always_inline int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr)
static const uint16_t vp7_ydc_qlookup[]
#define HOR_VP8_PRED
unaveraged version of HOR_PRED, see
static const int8_t mv[256][2]
static av_always_inline void vp7_decode_mvs(VP8Context *s, VP8Macroblock *mb, int mb_x, int mb_y, int layout)
static const uint8_t vp7_mv_default_prob[2][17]
static av_always_inline int check_intra_pred4x4_mode_emuedge(int mode, int mb_x, int mb_y, int *copy_buf, int vp7)
const uint8_t *const ff_vp8_dct_cat_prob[]
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
static av_always_inline int check_tm_pred4x4_mode(int mode, int mb_x, int mb_y, int vp7)
static const uint16_t vp7_y2dc_qlookup[]
This structure describes decoded (raw) audio or video data.
@ AVCOL_RANGE_JPEG
Full range content.
static av_always_inline void vp8_mc_chroma(VP8Context *s, VP8ThreadData *td, uint8_t *dst1, uint8_t *dst2, const ThreadFrame *ref, const VP8mv *mv, int x_off, int y_off, int block_w, int block_h, int width, int height, ptrdiff_t linesize, vp8_mc_func mc_func[3][3])
chroma MC function
static av_always_inline int inter_predict_dc(int16_t block[16], int16_t pred[2])
static void vp8_get_quants(VP8Context *s)
AVBufferRef * av_buffer_ref(const AVBufferRef *buf)
Create a new reference to an AVBuffer.
static av_always_inline void inter_predict(VP8Context *s, VP8ThreadData *td, uint8_t *const dst[3], VP8Macroblock *mb, int mb_x, int mb_y)
Apply motion vectors to prediction buffer, chapter 18.
@ VP8_SPLITMVMODE_4x4
4x4 blocks of 4x4px each
int ff_set_dimensions(AVCodecContext *s, int width, int height)
Check that the provided frame dimensions are valid and set them on the codec context.
#define VERT_VP8_PRED
for VP8, VERT_PRED is the average of
the pkt_dts and pkt_pts fields in AVFrame will work as usual Restrictions on codec whose streams don t reset across will not work because their bitstreams cannot be decoded in parallel *The contents of buffers must not be read before ff_thread_await_progress() has been called on them. reget_buffer() and buffer age optimizations no longer work. *The contents of buffers must not be written to after ff_thread_report_progress() has been called on them. This includes draw_edges(). Porting codecs to frame threading
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
static int vp8_decode_mb_row_no_filter(AVCodecContext *avctx, void *tdata, int jobnr, int threadnr)
static int vp8_rac_get_sint(VPXRangeCoder *c, int bits)
static const int8_t vp8_pred8x8c_tree[3][2]
#define bit(string, value)
#define update_pos(td, mb_y, mb_x)
static const VP8mv * get_bmv_ptr(const VP8Macroblock *mb, int subblock)
static av_always_inline int update_dimensions(VP8Context *s, int width, int height, int is_vp7)
@ AVCOL_SPC_BT470BG
also ITU-R BT601-6 625 / ITU-R BT1358 625 / ITU-R BT1700 625 PAL & SECAM / IEC 61966-2-4 xvYCC601
@ VP8_SPLITMVMODE_8x8
2x2 blocks of 8x8px each
AVCodec p
The public AVCodec.
const struct AVCodec * codec
static const uint8_t vp8_mv_update_prob[2][19]
enum AVDiscard skip_frame
Skip decoding for selected frames.
int thread_count
thread count is used to decide how many independent tasks should be passed to execute()
const FFCodec ff_vp8_decoder
av_cold void ff_videodsp_init(VideoDSPContext *ctx, int bpc)
static av_always_inline void update(SilenceDetectContext *s, AVFrame *insamples, int is_silence, int current_sample, int64_t nb_samples_notify, AVRational time_base)
static av_always_inline void idct_mb(VP8Context *s, VP8ThreadData *td, uint8_t *const dst[3], const VP8Macroblock *mb)
static av_always_inline int check_intra_pred8x8_mode_emuedge(int mode, int mb_x, int mb_y, int vp7)
static av_always_inline void filter_level_for_mb(const VP8Context *s, const VP8Macroblock *mb, VP8FilterStrength *f, int is_vp7)
static av_always_inline int read_mv_component(VPXRangeCoder *c, const uint8_t *p, int vp7)
Motion vector coding, 17.1.
static void vp8_filter_mb_row(AVCodecContext *avctx, void *tdata, int jobnr, int threadnr)
static void vp7_get_quants(VP8Context *s)
@ VP8_SPLITMVMODE_16x8
2 16x8 blocks (vertical)
static av_cold int vp8_init_frames(VP8Context *s)
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
static av_always_inline void vp8_mc_part(VP8Context *s, VP8ThreadData *td, uint8_t *const dst[3], const ThreadFrame *ref_frame, int x_off, int y_off, int bx_off, int by_off, int block_w, int block_h, int width, int height, const VP8mv *mv)
static av_always_inline void vp8_mc_luma(VP8Context *s, VP8ThreadData *td, uint8_t *dst, const ThreadFrame *ref, const VP8mv *mv, int x_off, int y_off, int block_w, int block_h, int width, int height, ptrdiff_t linesize, vp8_mc_func mc_func[3][3])
luma MC function
void ff_vp7dsp_init(VP8DSPContext *c)
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
void ff_vp8dsp_init(VP8DSPContext *c)
#define FF_ARRAY_ELEMS(a)
static const uint8_t vp8_dct_cat2_prob[]
void ff_thread_report_progress(ThreadFrame *f, int n, int field)
Notify later decoding threads when part of their reference picture is ready.
#define LOCAL_ALIGNED(a, t, v,...)
static const uint8_t vp8_pred4x4_mode[]
#define FF_CODEC_DECODE_CB(func)
static av_always_inline void filter_mb_simple(const VP8Context *s, uint8_t *dst, const VP8FilterStrength *f, int mb_x, int mb_y)
static av_always_inline unsigned int vpx_rac_renorm(VPXRangeCoder *c)
static const uint8_t vp8_pred8x8c_prob_inter[3]
#define AV_GET_BUFFER_FLAG_REF
The decoder will keep a reference to the frame and may reuse it later.
int(* init)(AVBSFContext *ctx)
static const int8_t vp8_pred16x16_tree_intra[4][2]
static void parse_segment_info(VP8Context *s)
static const uint8_t vp8_pred4x4_prob_inter[9]
static enum AVPixelFormat pix_fmts[]
static const uint8_t vp8_mbsplits[5][16]
static av_always_inline int vp78_decode_frame(AVCodecContext *avctx, AVFrame *rframe, int *got_frame, const AVPacket *avpkt, int is_vp7)
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_RL16
static const int vp7_mode_contexts[31][4]
static av_always_inline int vp78_decode_mv_mb_modes(AVCodecContext *avctx, VP8Frame *curframe, const VP8Frame *prev_frame, int is_vp7)
@ AV_PIX_FMT_YUV420P
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
#define atomic_load(object)
@ VP8_SPLITMVMODE_8x16
2 8x16 blocks (horizontal)
#define CODEC_LONG_NAME(str)
int ff_thread_ref_frame(ThreadFrame *dst, const ThreadFrame *src)
static const uint8_t vp8_mv_default_prob[2][19]
static const int8_t vp8_coeff_band_indexes[8][10]
static const uint8_t vp8_pred16x16_prob_inter[4]
static void vp8_decode_flush_impl(AVCodecContext *avctx, int free_mem)
#define AV_CODEC_CAP_FRAME_THREADS
Codec supports frame-level multithreading.
@ AVDISCARD_ALL
discard all
static int vp8_rac_get_nn(VPXRangeCoder *c)
static av_always_inline void clamp_mv(const VP8mvbounds *s, VP8mv *dst, const VP8mv *src)
static const int sizes[][2]
enum AVColorRange color_range
MPEG vs JPEG YUV range.
void av_buffer_unref(AVBufferRef **buf)
Free a given reference and automatically free the buffer if there are no more references to it.
static int vp7_decode_mb_row_sliced(AVCodecContext *avctx, void *tdata, int jobnr, int threadnr)
static int vp8_update_dimensions(VP8Context *s, int width, int height)
int(* end_frame)(AVCodecContext *avctx)
Called at the end of each frame or field picture.
@ AV_PICTURE_TYPE_I
Intra.
AVBufferRef * hwaccel_priv_buf
static av_unused int vp89_rac_get_uint(VPXRangeCoder *c, int bits)
#define check_thread_pos(td, otd, mb_x_check, mb_y_check)
void(* vp8_mc_func)(uint8_t *dst, ptrdiff_t dstStride, const uint8_t *src, ptrdiff_t srcStride, int h, int x, int y)
static const uint16_t vp7_yac_qlookup[]
static const uint8_t vp8_token_default_probs[4][8][3][NUM_DCT_TOKENS - 1]
static const uint8_t vp8_token_update_probs[4][8][3][NUM_DCT_TOKENS - 1]
static const uint8_t vp8_mbsplit_count[4]
#define UPDATE_THREAD_CONTEXT(func)
static av_always_inline void vp8_decode_mvs(VP8Context *s, const VP8mvbounds *mv_bounds, VP8Macroblock *mb, int mb_x, int mb_y, int layout)
static av_always_inline int decode_mb_row_no_filter(AVCodecContext *avctx, void *tdata, int jobnr, int threadnr, int is_vp7)
static const uint8_t vp7_feature_value_size[2][4]
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
av_cold int ff_vp8_decode_init(AVCodecContext *avctx)
static const uint8_t vp8_mbfirstidx[4][16]
@ AVDISCARD_NONKEY
discard all frames except keyframes
static av_always_inline void xchg_mb_border(uint8_t *top_border, uint8_t *src_y, uint8_t *src_cb, uint8_t *src_cr, ptrdiff_t linesize, ptrdiff_t uvlinesize, int mb_x, int mb_y, int mb_width, int simple, int xchg)
const uint8_t ff_zigzag_scan[16+1]
#define AV_CODEC_CAP_DR1
Codec uses get_buffer() or get_encode_buffer() for allocating buffers and supports custom allocators.
static const int8_t vp8_pred4x4_tree[9][2]
Tag MUST be and< 10hcoeff half pel interpolation filter coefficients, hcoeff[0] are the 2 middle coefficients[1] are the next outer ones and so on, resulting in a filter like:...eff[2], hcoeff[1], hcoeff[0], hcoeff[0], hcoeff[1], hcoeff[2] ... the sign of the coefficients is not explicitly stored but alternates after each coeff and coeff[0] is positive, so ...,+,-,+,-,+,+,-,+,-,+,... hcoeff[0] is not explicitly stored but found by subtracting the sum of all stored coefficients with signs from 32 hcoeff[0]=32 - hcoeff[1] - hcoeff[2] - ... a good choice for hcoeff and htaps is htaps=6 hcoeff={40,-10, 2} an alternative which requires more computations at both encoder and decoder side and may or may not be better is htaps=8 hcoeff={42,-14, 6,-2}ref_frames minimum of the number of available reference frames and max_ref_frames for example the first frame after a key frame always has ref_frames=1spatial_decomposition_type wavelet type 0 is a 9/7 symmetric compact integer wavelet 1 is a 5/3 symmetric compact integer wavelet others are reserved stored as delta from last, last is reset to 0 if always_reset||keyframeqlog quality(logarithmic quantizer scale) stored as delta from last, last is reset to 0 if always_reset||keyframemv_scale stored as delta from last, last is reset to 0 if always_reset||keyframe FIXME check that everything works fine if this changes between framesqbias dequantization bias stored as delta from last, last is reset to 0 if always_reset||keyframeblock_max_depth maximum depth of the block tree stored as delta from last, last is reset to 0 if always_reset||keyframequant_table quantization tableHighlevel bitstream structure:==============================--------------------------------------------|Header|--------------------------------------------|------------------------------------|||Block0||||split?||||yes no||||......... intra?||||:Block01 :yes no||||:Block02 :....... ..........||||:Block03 ::y DC ::ref index:||||:Block04 ::cb DC ::motion x :||||......... :cr DC ::motion y :||||....... ..........|||------------------------------------||------------------------------------|||Block1|||...|--------------------------------------------|------------ ------------ ------------|||Y subbands||Cb subbands||Cr subbands||||--- ---||--- ---||--- ---|||||LL0||HL0||||LL0||HL0||||LL0||HL0|||||--- ---||--- ---||--- ---||||--- ---||--- ---||--- ---|||||LH0||HH0||||LH0||HH0||||LH0||HH0|||||--- ---||--- ---||--- ---||||--- ---||--- ---||--- ---|||||HL1||LH1||||HL1||LH1||||HL1||LH1|||||--- ---||--- ---||--- ---||||--- ---||--- ---||--- ---|||||HH1||HL2||||HH1||HL2||||HH1||HL2|||||...||...||...|||------------ ------------ ------------|--------------------------------------------Decoding process:=================------------|||Subbands|------------||||------------|Intra DC||||LL0 subband prediction ------------|\ Dequantization ------------------- \||Reference frames|\ IDWT|------- -------|Motion \|||Frame 0||Frame 1||Compensation . OBMC v -------|------- -------|--------------. \------> Frame n output Frame Frame<----------------------------------/|...|------------------- Range Coder:============Binary Range Coder:------------------- The implemented range coder is an adapted version based upon "Range encoding: an algorithm for removing redundancy from a digitised message." by G. N. N. Martin. The symbols encoded by the Snow range coder are bits(0|1). The associated probabilities are not fix but change depending on the symbol mix seen so far. bit seen|new state ---------+----------------------------------------------- 0|256 - state_transition_table[256 - old_state];1|state_transition_table[old_state];state_transition_table={ 0, 0, 0, 0, 0, 0, 0, 0, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 190, 191, 192, 194, 194, 195, 196, 197, 198, 199, 200, 201, 202, 202, 204, 205, 206, 207, 208, 209, 209, 210, 211, 212, 213, 215, 215, 216, 217, 218, 219, 220, 220, 222, 223, 224, 225, 226, 227, 227, 229, 229, 230, 231, 232, 234, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 248, 0, 0, 0, 0, 0, 0, 0};FIXME Range Coding of integers:------------------------- FIXME Neighboring Blocks:===================left and top are set to the respective blocks unless they are outside of the image in which case they are set to the Null block top-left is set to the top left block unless it is outside of the image in which case it is set to the left block if this block has no larger parent block or it is at the left side of its parent block and the top right block is not outside of the image then the top right block is used for top-right else the top-left block is used Null block y, cb, cr are 128 level, ref, mx and my are 0 Motion Vector Prediction:=========================1. the motion vectors of all the neighboring blocks are scaled to compensate for the difference of reference frames scaled_mv=(mv *(256 *(current_reference+1)/(mv.reference+1))+128)> the median of the scaled top and top right vectors is used as motion vector prediction the used motion vector is the sum of the predictor and(mvx_diff, mvy_diff) *mv_scale Intra DC Prediction block[y][x] dc[1]
static void copy(const float *p1, float *p2, const int length)
int av_frame_ref(AVFrame *dst, const AVFrame *src)
Set up a new reference to the data described by the source frame.
static const uint8_t vp8_coeff_band[16]
static const uint8_t subpel_idx[3][8]
static int vp7_update_dimensions(VP8Context *s, int width, int height)
#define EDGE_EMU_LINESIZE
static void vp8_release_frame(VP8Context *s, VP8Frame *f)
#define FF_CODEC_CAP_ALLOCATE_PROGRESS
static void free_buffers(VP8Context *s)
static const av_always_inline FFCodec * ffcodec(const AVCodec *codec)
static av_always_inline int decode_block_coeffs(VPXRangeCoder *c, int16_t block[16], uint8_t probs[16][3][NUM_DCT_TOKENS - 1], int i, int zero_nhood, const int16_t qmul[2], const uint8_t scan[16], int vp7)
#define FF_THREAD_SLICE
Decode more than one part of a single frame at once.
static const uint8_t vp8_pred8x8c_prob_intra[3]
static int vp8_decode_mv_mb_modes(AVCodecContext *avctx, VP8Frame *cur_frame, const VP8Frame *prev_frame)
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_RL24
static const uint8_t vp8_pred4x4_prob_intra[10][10][9]
The reader does not expect b to be semantically here and if the code is changed by maybe adding a a division or other the signedness will almost certainly be mistaken To avoid this confusion a new type was SUINT is the C unsigned type but it holds a signed int to use the same example SUINT a
#define AV_CODEC_CAP_SLICE_THREADS
Codec supports slice-based (or partition-based) multithreading.
static int vp8_decode_frame_header(VP8Context *s, const uint8_t *buf, int buf_size)
static const uint8_t vp8_mbsplit_prob[3]
static int setup_partitions(VP8Context *s, const uint8_t *buf, int buf_size)
static const int8_t vp8_pred16x16_tree_inter[4][2]
static const int8_t vp7_feature_index_tree[4][2]
enum AVDiscard skip_loop_filter
Skip loop filtering for selected frames.
#define HWACCEL_NVDEC(codec)
static av_always_inline int vpx_rac_is_end(VPXRangeCoder *c)
returns 1 if the end of the stream has been reached, 0 otherwise.
@ AV_PIX_FMT_VAAPI
Hardware acceleration through VA-API, data[3] contains a VASurfaceID.
static av_always_inline int pthread_cond_destroy(pthread_cond_t *cond)
#define FF_THREAD_FRAME
Decode more than one frame at once.
#define H_LOOP_FILTER_16Y_INNER(cond)
static av_always_inline int vp78_decode_mb_row_sliced(AVCodecContext *avctx, void *tdata, int jobnr, int threadnr, int is_vp7)
static av_always_inline int pthread_mutex_destroy(pthread_mutex_t *mutex)
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel layout
static VP8FrameType ref_to_update(VP8Context *s, int update, VP8FrameType ref)
Determine which buffers golden and altref should be updated with after this frame.
static int vp8_read_mv_component(VPXRangeCoder *c, const uint8_t *p)
#define i(width, name, range_min, range_max)
int(* decode_slice)(AVCodecContext *avctx, const uint8_t *buf, uint32_t buf_size)
Callback for each slice.
static const SiprModeParam modes[MODE_COUNT]
static int vp7_fade_frame(VP8Context *s, int alpha, int beta)
static av_always_inline int vpx_rac_get_prob_branchy(VPXRangeCoder *c, int prob)
static av_always_inline void intra_predict(VP8Context *s, VP8ThreadData *td, uint8_t *const dst[3], VP8Macroblock *mb, int mb_x, int mb_y, int is_vp7)
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
const char * name
Name of the codec implementation.
static void vp78_reset_probability_tables(VP8Context *s)
static int vp7_decode_frame_header(VP8Context *s, const uint8_t *buf, int buf_size)
static void fade(uint8_t *dst, ptrdiff_t dst_linesize, const uint8_t *src, ptrdiff_t src_linesize, int width, int height, int alpha, int beta)
static av_always_inline void decode_intra4x4_modes(VP8Context *s, VPXRangeCoder *c, VP8Macroblock *mb, int mb_x, int keyframe, int layout)
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
int ff_thread_get_ext_buffer(AVCodecContext *avctx, ThreadFrame *f, int flags)
Wrapper around ff_get_buffer() for frame-multithreaded codecs.
@ AVCOL_RANGE_MPEG
Narrow or limited range content.
static int vp8_decode_mb_row_sliced(AVCodecContext *avctx, void *tdata, int jobnr, int threadnr)
const FFCodec ff_vp7_decoder
@ VP8_SPLITMVMODE_NONE
(only used in prediction) no split MVs
static av_always_inline void prefetch_motion(const VP8Context *s, const VP8Macroblock *mb, int mb_x, int mb_y, int mb_xy, int ref)
static av_always_inline int vp89_rac_get_tree(VPXRangeCoder *c, const int8_t(*tree)[2], const uint8_t *probs)
static av_always_inline void decode_mb_coeffs(VP8Context *s, VP8ThreadData *td, VPXRangeCoder *c, VP8Macroblock *mb, uint8_t t_nnz[9], uint8_t l_nnz[9], int is_vp7)
AVBufferRef * av_buffer_allocz(size_t size)
Same as av_buffer_alloc(), except the returned buffer will be initialized to zero.
#define AV_LOG_FATAL
Something went wrong and recovery is not possible.
static av_always_inline int check_dc_pred8x8_mode(int mode, int mb_x, int mb_y)
static const float pred[4]
static int vp7_decode_mb_row_no_filter(AVCodecContext *avctx, void *tdata, int jobnr, int threadnr)
#define FFSWAP(type, a, b)
these buffered frames must be flushed immediately if a new input produces new the filter must not call request_frame to get more It must just process the frame or queue it The task of requesting more frames is left to the filter s request_frame method or the application If a filter has several the filter must be ready for frames arriving randomly on any input any filter with several inputs will most likely require some kind of queuing mechanism It is perfectly acceptable to have a limited queue and to drop frames when the inputs are too unbalanced request_frame For filters that do not use the this method is called when a frame is wanted on an output For a it should directly call filter_frame on the corresponding output For a if there are queued frames already one of these frames should be pushed If the filter should request a frame on one of its repeatedly until at least one frame has been pushed Return or at least make progress towards producing a frame
static const uint8_t vp8_pred16x16_prob_intra[4]
static const uint16_t vp8_ac_qlookup[VP8_MAX_QUANT+1]
#define prob(name, subs,...)
int ff_vpx_init_range_decoder(VPXRangeCoder *c, const uint8_t *buf, int buf_size)
the pkt_dts and pkt_pts fields in AVFrame will work as usual Restrictions on codec whose streams don t reset across will not work because their bitstreams cannot be decoded in parallel *The contents of buffers must not be read before as well as code calling up to before the decode process starts Call ff_thread_finish_setup() afterwards. If some code can 't be moved
Tag MUST be and< 10hcoeff half pel interpolation filter coefficients, hcoeff[0] are the 2 middle coefficients[1] are the next outer ones and so on, resulting in a filter like:...eff[2], hcoeff[1], hcoeff[0], hcoeff[0], hcoeff[1], hcoeff[2] ... the sign of the coefficients is not explicitly stored but alternates after each coeff and coeff[0] is positive, so ...,+,-,+,-,+,+,-,+,-,+,... hcoeff[0] is not explicitly stored but found by subtracting the sum of all stored coefficients with signs from 32 hcoeff[0]=32 - hcoeff[1] - hcoeff[2] - ... a good choice for hcoeff and htaps is htaps=6 hcoeff={40,-10, 2} an alternative which requires more computations at both encoder and decoder side and may or may not be better is htaps=8 hcoeff={42,-14, 6,-2}ref_frames minimum of the number of available reference frames and max_ref_frames for example the first frame after a key frame always has ref_frames=1spatial_decomposition_type wavelet type 0 is a 9/7 symmetric compact integer wavelet 1 is a 5/3 symmetric compact integer wavelet others are reserved stored as delta from last, last is reset to 0 if always_reset||keyframeqlog quality(logarithmic quantizer scale) stored as delta from last, last is reset to 0 if always_reset||keyframemv_scale stored as delta from last, last is reset to 0 if always_reset||keyframe FIXME check that everything works fine if this changes between framesqbias dequantization bias stored as delta from last, last is reset to 0 if always_reset||keyframeblock_max_depth maximum depth of the block tree stored as delta from last, last is reset to 0 if always_reset||keyframequant_table quantization tableHighlevel bitstream structure:==============================--------------------------------------------|Header|--------------------------------------------|------------------------------------|||Block0||||split?||||yes no||||......... intra?||||:Block01 :yes no||||:Block02 :....... ..........||||:Block03 ::y DC ::ref index:||||:Block04 ::cb DC ::motion x :||||......... :cr DC ::motion y :||||....... ..........|||------------------------------------||------------------------------------|||Block1|||...|--------------------------------------------|------------ ------------ ------------|||Y subbands||Cb subbands||Cr subbands||||--- ---||--- ---||--- ---|||||LL0||HL0||||LL0||HL0||||LL0||HL0|||||--- ---||--- ---||--- ---||||--- ---||--- ---||--- ---|||||LH0||HH0||||LH0||HH0||||LH0||HH0|||||--- ---||--- ---||--- ---||||--- ---||--- ---||--- ---|||||HL1||LH1||||HL1||LH1||||HL1||LH1|||||--- ---||--- ---||--- ---||||--- ---||--- ---||--- ---|||||HH1||HL2||||HH1||HL2||||HH1||HL2|||||...||...||...|||------------ ------------ ------------|--------------------------------------------Decoding process:=================------------|||Subbands|------------||||------------|Intra DC||||LL0 subband prediction ------------|\ Dequantization ------------------- \||Reference frames|\ IDWT|------- -------|Motion \|||Frame 0||Frame 1||Compensation . OBMC v -------|------- -------|--------------. \------> Frame n output Frame Frame<----------------------------------/|...|------------------- Range Coder:============Binary Range Coder:------------------- The implemented range coder is an adapted version based upon "Range encoding: an algorithm for removing redundancy from a digitised message." by G. N. N. Martin. The symbols encoded by the Snow range coder are bits(0|1). The associated probabilities are not fix but change depending on the symbol mix seen so far. bit seen|new state ---------+----------------------------------------------- 0|256 - state_transition_table[256 - old_state];1|state_transition_table[old_state];state_transition_table={ 0, 0, 0, 0, 0, 0, 0, 0, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 190, 191, 192, 194, 194, 195, 196, 197, 198, 199, 200, 201, 202, 202, 204, 205, 206, 207, 208, 209, 209, 210, 211, 212, 213, 215, 215, 216, 217, 218, 219, 220, 220, 222, 223, 224, 225, 226, 227, 227, 229, 229, 230, 231, 232, 234, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 248, 0, 0, 0, 0, 0, 0, 0};FIXME Range Coding of integers:------------------------- FIXME Neighboring Blocks:===================left and top are set to the respective blocks unless they are outside of the image in which case they are set to the Null block top-left is set to the top left block unless it is outside of the image in which case it is set to the left block if this block has no larger parent block or it is at the left side of its parent block and the top right block is not outside of the image then the top right block is used for top-right else the top-left block is used Null block y, cb, cr are 128 level, ref, mx and my are 0 Motion Vector Prediction:=========================1. the motion vectors of all the neighboring blocks are scaled to compensate for the difference of reference frames scaled_mv=(mv *(256 *(current_reference+1)/(mv.reference+1))+128)> the median of the scaled left
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_RL32
static av_always_inline int vp89_rac_get(VPXRangeCoder *c)
main external API structure.
int active_thread_type
Which multithreading methods are in use by the codec.
uint8_t intra4x4_pred_mode_top[4]
static av_always_inline int decode_splitmvs(const VP8Context *s, VPXRangeCoder *c, VP8Macroblock *mb, int layout, int is_vp7)
Split motion vector prediction, 16.4.
av_cold void ff_h264_pred_init(H264PredContext *h, int codec_id, const int bit_depth, int chroma_format_idc)
Set the intra prediction function pointers.
int frame_priv_data_size
Size of per-frame hardware accelerator private data.
static int ref[MAX_W *MAX_W]
static int vp7_decode_block_coeffs_internal(VPXRangeCoder *r, int16_t block[16], uint8_t probs[16][3][NUM_DCT_TOKENS - 1], int i, const uint8_t *token_prob, const int16_t qmul[2], const uint8_t scan[16])
static av_always_inline void filter_mb(const VP8Context *s, uint8_t *const dst[3], const VP8FilterStrength *f, int mb_x, int mb_y, int is_vp7)
int(* start_frame)(AVCodecContext *avctx, const uint8_t *buf, uint32_t buf_size)
Called at the beginning of each frame or field picture.
static void vp78_update_probability_tables(VP8Context *s)
@ AV_PICTURE_TYPE_P
Predicted.
static void vp78_update_pred16x16_pred8x8_mvc_probabilities(VP8Context *s, int mvc_size)
#define avpriv_request_sample(...)
static void update_refs(VP8Context *s)
static int vp7_decode_mv_mb_modes(AVCodecContext *avctx, VP8Frame *cur_frame, const VP8Frame *prev_frame)
static void update_lf_deltas(VP8Context *s)
static av_always_inline void filter_mb_row(AVCodecContext *avctx, void *tdata, int jobnr, int threadnr, int is_vp7)
static const int16_t alpha[]
This structure stores compressed data.
static enum AVPixelFormat get_pixel_format(VP8Context *s)
int ff_vp8_decode_frame(AVCodecContext *avctx, AVFrame *frame, int *got_frame, AVPacket *avpkt)
#define HWACCEL_VAAPI(codec)
static VP8Frame * vp8_find_free_buffer(VP8Context *s)
int linesize[AV_NUM_DATA_POINTERS]
For video, a positive or negative value, which is typically indicating the size in bytes of each pict...
static const double coeff[2][5]
The exact code depends on how similar the blocks are and how related they are to the block
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
static av_always_inline int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr)
static const uint16_t vp7_y2ac_qlookup[]
#define atomic_init(obj, value)
static const uint8_t vp7_submv_prob[3]
@ AVDISCARD_NONREF
discard all non reference
static int vp8_rac_get_coeff(VPXRangeCoder *c, const uint8_t *prob)
static const uint8_t vp8_dc_qlookup[VP8_MAX_QUANT+1]
static void copy_chroma(AVFrame *dst, const AVFrame *src, int width, int height)
static void vp8_decode_flush(AVCodecContext *avctx)
int(* execute2)(struct AVCodecContext *c, int(*func)(struct AVCodecContext *c2, void *arg, int jobnr, int threadnr), void *arg2, int *ret, int count)
The codec may call this to execute several independent things.
static int vp8_alloc_frame(VP8Context *s, VP8Frame *f, int ref)
static const av_always_inline uint8_t * get_submv_prob(uint32_t left, uint32_t top, int is_vp7)
av_cold void ff_vp78dsp_init(VP8DSPContext *dsp)
void * hwaccel_picture_private