Go to the documentation of this file.
27 #include "config_components.h"
47 #if CONFIG_VP7_DECODER && CONFIG_VP8_DECODER
48 #define VPX(vp7, f) (vp7 ? vp7_ ## f : vp8_ ## f)
49 #elif CONFIG_VP7_DECODER
50 #define VPX(vp7, f) vp7_ ## f
51 #else // CONFIG_VP8_DECODER
52 #define VPX(vp7, f) vp8_ ## f
72 s->macroblocks =
NULL;
83 if (
s->avctx->hwaccel) {
87 if (!
f->hwaccel_priv_buf)
89 f->hwaccel_picture_private =
f->hwaccel_priv_buf->data;
104 f->hwaccel_picture_private =
NULL;
108 #if CONFIG_VP8_DECODER
122 if (
src->hwaccel_picture_private) {
140 memset(
s->framep, 0,
sizeof(
s->framep));
157 for (
i = 0;
i < 5;
i++)
169 if (
frame->tf.f->buf[0])
178 #if CONFIG_VP8_VAAPI_HWACCEL
181 #if CONFIG_VP8_NVDEC_HWACCEL
195 int i,
ret, dim_reset = 0;
197 if (
width !=
s->avctx->width || ((
width+15)/16 !=
s->mb_width || (
height+15)/16 !=
s->mb_height) &&
s->macroblocks_base ||
205 dim_reset = (
s->macroblocks_base !=
NULL);
209 !
s->actually_webp && !is_vp7) {
216 s->mb_width = (
s->avctx->coded_width + 15) / 16;
217 s->mb_height = (
s->avctx->coded_height + 15) / 16;
222 s->macroblocks_base =
av_mallocz((
s->mb_width +
s->mb_height * 2 + 1) *
223 sizeof(*
s->macroblocks));
224 s->intra4x4_pred_mode_top =
av_mallocz(
s->mb_width * 4);
226 s->macroblocks_base =
av_mallocz((
s->mb_width + 2) * (
s->mb_height + 2) *
227 sizeof(*
s->macroblocks));
229 s->top_border =
av_mallocz((
s->mb_width + 1) *
sizeof(*
s->top_border));
232 if (!
s->macroblocks_base || !
s->top_nnz || !
s->top_border ||
233 !
s->thread_data || (!
s->intra4x4_pred_mode_top && !
s->mb_layout)) {
239 s->thread_data[
i].filter_strength =
240 av_mallocz(
s->mb_width *
sizeof(*
s->thread_data[0].filter_strength));
241 if (!
s->thread_data[
i].filter_strength) {
251 s->macroblocks =
s->macroblocks_base + 1;
275 if (
s->segmentation.update_feature_data) {
278 for (
i = 0;
i < 4;
i++)
281 for (
i = 0;
i < 4;
i++)
284 if (
s->segmentation.update_map)
285 for (
i = 0;
i < 3;
i++)
294 for (
i = 0;
i < 4;
i++) {
299 s->lf_delta.ref[
i] = -
s->lf_delta.ref[
i];
308 s->lf_delta.mode[
i] = -
s->lf_delta.mode[
i];
315 const uint8_t *
sizes = buf;
321 buf += 3 * (
s->num_coeff_partitions - 1);
322 buf_size -= 3 * (
s->num_coeff_partitions - 1);
326 for (
i = 0;
i <
s->num_coeff_partitions - 1;
i++) {
328 if (buf_size -
size < 0)
330 s->coeff_partition_size[
i] =
size;
339 s->coeff_partition_size[
i] = buf_size;
376 for (
i = 0;
i < 4;
i++) {
377 if (
s->segmentation.enabled) {
378 base_qi =
s->segmentation.base_quant[
i];
379 if (!
s->segmentation.absolute_vals)
380 base_qi +=
s->quant.yac_qi;
382 base_qi =
s->quant.yac_qi;
392 s->qmat[
i].luma_dc_qmul[1] =
FFMAX(
s->qmat[
i].luma_dc_qmul[1], 8);
393 s->qmat[
i].chroma_qmul[0] =
FFMIN(
s->qmat[
i].chroma_qmul[0], 132);
429 for (
i = 0;
i < 4;
i++)
430 for (j = 0; j < 16; j++)
432 sizeof(
s->prob->token[
i][j]));
440 for (
i = 0;
i < 4;
i++)
441 for (j = 0; j < 8; j++)
442 for (k = 0; k < 3; k++)
451 #define VP7_MVC_SIZE 17
452 #define VP8_MVC_SIZE 19
461 for (
i = 0;
i < 4;
i++)
464 for (
i = 0;
i < 3;
i++)
468 for (
i = 0;
i < 2;
i++)
469 for (j = 0; j < mvc_size; j++)
489 for (j = 1; j < 3; j++) {
496 static void fade(uint8_t *dst, ptrdiff_t dst_linesize,
497 const uint8_t *
src, ptrdiff_t src_linesize,
502 for (j = 0; j <
height; j++) {
503 const uint8_t *
src2 =
src + j * src_linesize;
504 uint8_t *dst2 = dst + j * dst_linesize;
516 if (!
s->keyframe && (
alpha || beta)) {
517 int width =
s->mb_width * 16;
518 int height =
s->mb_height * 16;
542 src->data[0],
src->linesize[0],
552 int part1_size, hscale, vscale,
i, j,
ret;
553 int width =
s->avctx->width;
562 s->profile = (buf[0] >> 1) & 7;
563 if (
s->profile > 1) {
568 s->keyframe = !(buf[0] & 1);
570 part1_size =
AV_RL24(buf) >> 4;
572 if (buf_size < 4 - s->
profile + part1_size) {
573 av_log(
s->avctx,
AV_LOG_ERROR,
"Buffer size %d is too small, needed : %d\n", buf_size, 4 -
s->profile + part1_size);
577 buf += 4 -
s->profile;
578 buf_size -= 4 -
s->profile;
580 memcpy(
s->put_pixels_tab,
s->vp8dsp.put_vp8_epel_pixels_tab,
sizeof(
s->put_pixels_tab));
586 buf_size -= part1_size;
594 if (hscale || vscale)
600 sizeof(
s->prob->pred16x16));
602 sizeof(
s->prob->pred8x8c));
603 for (
i = 0;
i < 2;
i++)
606 memset(&
s->segmentation, 0,
sizeof(
s->segmentation));
607 memset(&
s->lf_delta, 0,
sizeof(
s->lf_delta));
611 if (
s->keyframe ||
s->profile > 0)
612 memset(
s->inter_dc_pred, 0 ,
sizeof(
s->inter_dc_pred));
615 for (
i = 0;
i < 4;
i++) {
617 if (
s->feature_enabled[
i]) {
620 for (j = 0; j < 3; j++)
621 s->feature_index_prob[
i][j] =
625 for (j = 0; j < 4; j++)
626 s->feature_value[
i][j] =
631 s->segmentation.enabled = 0;
632 s->segmentation.update_map = 0;
633 s->lf_delta.enabled = 0;
635 s->num_coeff_partitions = 1;
640 if (!
s->macroblocks_base ||
642 (
width + 15) / 16 !=
s->mb_width || (
height + 15) / 16 !=
s->mb_height) {
657 s->update_probabilities = 1;
660 if (
s->profile > 0) {
662 if (!
s->update_probabilities)
663 s->prob[1] =
s->prob[0];
683 for (
i = 1;
i < 16;
i++)
695 s->mbskip_enabled = 0;
716 int header_size, hscale, vscale,
ret;
717 int width =
s->avctx->width;
725 s->keyframe = !(buf[0] & 1);
726 s->profile = (buf[0]>>1) & 7;
727 s->invisible = !(buf[0] & 0x10);
728 header_size =
AV_RL24(buf) >> 5;
732 s->header_partition_size = header_size;
738 memcpy(
s->put_pixels_tab,
s->vp8dsp.put_vp8_epel_pixels_tab,
739 sizeof(
s->put_pixels_tab));
741 memcpy(
s->put_pixels_tab,
s->vp8dsp.put_vp8_bilinear_pixels_tab,
742 sizeof(
s->put_pixels_tab));
744 if (header_size > buf_size - 7 *
s->keyframe) {
750 if (
AV_RL24(buf) != 0x2a019d) {
752 "Invalid start code 0x%x\n",
AV_RL24(buf));
757 hscale = buf[4] >> 6;
758 vscale = buf[6] >> 6;
762 if (hscale || vscale)
768 sizeof(
s->prob->pred16x16));
770 sizeof(
s->prob->pred8x8c));
772 sizeof(
s->prob->mvc));
773 memset(&
s->segmentation, 0,
sizeof(
s->segmentation));
774 memset(&
s->lf_delta, 0,
sizeof(
s->lf_delta));
781 buf_size -= header_size;
793 s->segmentation.update_map = 0;
801 if (
s->lf_delta.update)
810 if (!
s->macroblocks_base ||
812 (
width+15)/16 !=
s->mb_width || (
height+15)/16 !=
s->mb_height)
827 s->prob[1] =
s->prob[0];
845 s->coder_state_at_header_end.input =
s->c.buffer - (-
s->c.bits / 8);
846 s->coder_state_at_header_end.range =
s->c.high;
847 s->coder_state_at_header_end.value =
s->c.code_word >> 16;
848 s->coder_state_at_header_end.bit_count = -
s->c.bits % 8;
857 av_clip(
s->mv_max.x, INT16_MIN, INT16_MAX));
859 av_clip(
s->mv_max.y, INT16_MIN, INT16_MAX));
872 for (
i = 0;
i < 3;
i++)
874 for (
i = (vp7 ? 7 : 9);
i > 3;
i--)
880 const uint8_t *ps = p + 2;
929 const uint8_t *mbsplits_top, *mbsplits_cur, *firstidx;
937 top_mb = &
mb[-
s->mb_width - 1];
939 top_mv = top_mb->
bmv;
953 mb->partitioning = part_idx;
955 for (n = 0; n < num; n++) {
957 uint32_t
left, above;
958 const uint8_t *submv_prob;
965 above =
AV_RN32A(&top_mv[mbsplits_top[k + 12]]);
967 above =
AV_RN32A(&cur_mv[mbsplits_cur[k - 4]]);
974 mb->bmv[n].y =
mb->mv.y +
976 mb->bmv[n].x =
mb->mv.x +
1004 int xoffset,
int yoffset,
int boundary,
1005 int *edge_x,
int *edge_y)
1007 int vwidth = mb_width + 1;
1008 int new = (mb_y + yoffset) * vwidth + mb_x + xoffset;
1009 if (
new < boundary ||
new % vwidth == vwidth - 1)
1011 *edge_y =
new / vwidth;
1012 *edge_x =
new % vwidth;
1023 int mb_x,
int mb_y,
int layout)
1026 enum { CNT_ZERO, CNT_NEAREST, CNT_NEAR };
1027 enum { VP8_EDGE_TOP, VP8_EDGE_LEFT, VP8_EDGE_TOPLEFT };
1030 uint8_t cnt[3] = { 0 };
1043 pred->yoffset, !
s->profile, &edge_x, &edge_y)) {
1045 ?
s->macroblocks_base + 1 + edge_x +
1046 (
s->mb_width + 1) * (edge_y + 1)
1047 :
s->macroblocks + edge_x +
1048 (
s->mb_height - edge_y - 1) * 2;
1051 if (
AV_RN32A(&near_mv[CNT_NEAREST])) {
1054 }
else if (
AV_RN32A(&near_mv[CNT_NEAR])) {
1084 if (cnt[CNT_NEAREST] > cnt[CNT_NEAR])
1085 AV_WN32A(&
mb->mv, cnt[CNT_ZERO] > cnt[CNT_NEAREST] ? 0 :
AV_RN32A(&near_mv[CNT_NEAREST]));
1095 mb->bmv[0] =
mb->mv;
1098 mb->mv = near_mv[CNT_NEAR];
1099 mb->bmv[0] =
mb->mv;
1102 mb->mv = near_mv[CNT_NEAREST];
1103 mb->bmv[0] =
mb->mv;
1108 mb->bmv[0] =
mb->mv;
1114 int mb_x,
int mb_y,
int layout)
1119 enum { CNT_ZERO, CNT_NEAREST, CNT_NEAR, CNT_SPLITMV };
1120 enum { VP8_EDGE_TOP, VP8_EDGE_LEFT, VP8_EDGE_TOPLEFT };
1122 int cur_sign_bias =
s->sign_bias[
mb->ref_frame];
1123 int8_t *sign_bias =
s->sign_bias;
1125 uint8_t cnt[4] = { 0 };
1129 mb_edge[0] =
mb + 2;
1130 mb_edge[2] =
mb + 1;
1132 mb_edge[0] =
mb -
s->mb_width - 1;
1133 mb_edge[2] =
mb -
s->mb_width - 2;
1141 #define MV_EDGE_CHECK(n) \
1143 VP8Macroblock *edge = mb_edge[n]; \
1144 int edge_ref = edge->ref_frame; \
1145 if (edge_ref != VP56_FRAME_CURRENT) { \
1146 uint32_t mv = AV_RN32A(&edge->mv); \
1148 if (cur_sign_bias != sign_bias[edge_ref]) { \
1151 mv = ((mv & 0x7fff7fff) + \
1152 0x00010001) ^ (mv & 0x80008000); \
1154 if (!n || mv != AV_RN32A(&near_mv[idx])) \
1155 AV_WN32A(&near_mv[++idx], mv); \
1156 cnt[idx] += 1 + (n != 2); \
1158 cnt[CNT_ZERO] += 1 + (n != 2); \
1171 if (cnt[CNT_SPLITMV] &&
1172 AV_RN32A(&near_mv[1 + VP8_EDGE_TOP]) ==
AV_RN32A(&near_mv[1 + VP8_EDGE_TOPLEFT]))
1173 cnt[CNT_NEAREST] += 1;
1176 if (cnt[CNT_NEAR] > cnt[CNT_NEAREST]) {
1177 FFSWAP(uint8_t, cnt[CNT_NEAREST], cnt[CNT_NEAR]);
1178 FFSWAP(
VP56mv, near_mv[CNT_NEAREST], near_mv[CNT_NEAR]);
1184 clamp_mv(mv_bounds, &
mb->mv, &near_mv[CNT_ZERO + (cnt[CNT_NEAREST] >= cnt[CNT_ZERO])]);
1195 mb->bmv[0] =
mb->mv;
1198 clamp_mv(mv_bounds, &
mb->mv, &near_mv[CNT_NEAR]);
1199 mb->bmv[0] =
mb->mv;
1202 clamp_mv(mv_bounds, &
mb->mv, &near_mv[CNT_NEAREST]);
1203 mb->bmv[0] =
mb->mv;
1208 mb->bmv[0] =
mb->mv;
1214 int mb_x,
int keyframe,
int layout)
1216 uint8_t *intra4x4 =
mb->intra4x4_pred_mode_mb;
1225 uint8_t *
const left =
s->intra4x4_pred_mode_left;
1227 top =
mb->intra4x4_pred_mode_top;
1229 top =
s->intra4x4_pred_mode_top + 4 * mb_x;
1230 for (y = 0; y < 4; y++) {
1231 for (x = 0; x < 4; x++) {
1235 left[y] = top[x] = *intra4x4;
1241 for (
i = 0;
i < 16;
i++)
1253 static const char *
const vp7_feature_name[] = {
"q-index",
1255 "partial-golden-update",
1260 for (
i = 0;
i < 4;
i++) {
1261 if (
s->feature_enabled[
i]) {
1264 s->feature_index_prob[
i]);
1266 "Feature %s present in macroblock (value 0x%x)\n",
1267 vp7_feature_name[
i],
s->feature_value[
i][
index]);
1271 }
else if (
s->segmentation.update_map) {
1274 }
else if (
s->segmentation.enabled)
1307 s->ref_count[
mb->ref_frame - 1]++;
1342 int i, uint8_t *token_prob, int16_t qmul[2],
1343 const uint8_t scan[16],
int vp7)
1357 token_prob = probs[
i][0];
1365 token_prob = probs[
i + 1][1];
1385 int cat = (
a << 1) +
b;
1390 token_prob = probs[
i + 1][2];
1425 int i, uint8_t *token_prob,
1427 const uint8_t scan[16])
1430 token_prob, qmul, scan,
IS_VP7);
1433 #ifndef vp8_decode_block_coeffs_internal
1437 int i, uint8_t *token_prob,
1461 int i,
int zero_nhood, int16_t qmul[2],
1462 const uint8_t scan[16],
int vp7)
1464 uint8_t *token_prob = probs[
i][zero_nhood];
1468 token_prob, qmul, scan)
1478 int i, x, y, luma_start = 0, luma_ctx = 3;
1479 int nnz_pred, nnz, nnz_total = 0;
1484 nnz_pred = t_nnz[8] + l_nnz[8];
1488 nnz_pred,
s->qmat[
segment].luma_dc_qmul,
1490 l_nnz[8] = t_nnz[8] = !!nnz;
1494 s->inter_dc_pred[
mb->ref_frame - 1]);
1501 s->vp8dsp.vp8_luma_dc_wht_dc(
td->block,
td->block_dc);
1503 s->vp8dsp.vp8_luma_dc_wht(
td->block,
td->block_dc);
1510 for (y = 0; y < 4; y++)
1511 for (x = 0; x < 4; x++) {
1512 nnz_pred = l_nnz[y] + t_nnz[x];
1514 s->prob->token[luma_ctx],
1515 luma_start, nnz_pred,
1517 s->prob[0].scan, is_vp7);
1520 td->non_zero_count_cache[y][x] = nnz + block_dc;
1521 t_nnz[x] = l_nnz[y] = !!nnz;
1528 for (
i = 4;
i < 6;
i++)
1529 for (y = 0; y < 2; y++)
1530 for (x = 0; x < 2; x++) {
1531 nnz_pred = l_nnz[
i + 2 * y] + t_nnz[
i + 2 * x];
1533 s->prob->token[2], 0, nnz_pred,
1535 s->prob[0].scan, is_vp7);
1536 td->non_zero_count_cache[
i][(y << 1) + x] = nnz;
1537 t_nnz[
i + 2 * x] = l_nnz[
i + 2 * y] = !!nnz;
1550 uint8_t *src_cb, uint8_t *src_cr,
1551 ptrdiff_t linesize, ptrdiff_t uvlinesize,
int simple)
1553 AV_COPY128(top_border, src_y + 15 * linesize);
1555 AV_COPY64(top_border + 16, src_cb + 7 * uvlinesize);
1556 AV_COPY64(top_border + 24, src_cr + 7 * uvlinesize);
1562 uint8_t *src_cr, ptrdiff_t linesize, ptrdiff_t uvlinesize,
int mb_x,
1563 int mb_y,
int mb_width,
int simple,
int xchg)
1565 uint8_t *top_border_m1 = top_border - 32;
1567 src_cb -= uvlinesize;
1568 src_cr -= uvlinesize;
1570 #define XCHG(a, b, xchg) \
1578 XCHG(top_border_m1 + 8, src_y - 8, xchg);
1579 XCHG(top_border, src_y, xchg);
1580 XCHG(top_border + 8, src_y + 8, 1);
1581 if (mb_x < mb_width - 1)
1582 XCHG(top_border + 32, src_y + 16, 1);
1586 if (!simple || !mb_y) {
1587 XCHG(top_border_m1 + 16, src_cb - 8, xchg);
1588 XCHG(top_border_m1 + 24, src_cr - 8, xchg);
1589 XCHG(top_border + 16, src_cb, 1);
1590 XCHG(top_border + 24, src_cr, 1);
1640 int *copy_buf,
int vp7)
1644 if (!mb_x && mb_y) {
1678 int x, y,
mode, nnz;
1683 if (mb_y && (
s->deblock_filter || !mb_y) &&
td->thread_nr == 0)
1685 s->linesize,
s->uvlinesize, mb_x, mb_y,
s->mb_width,
1686 s->filter.simple, 1);
1690 s->hpc.pred16x16[
mode](dst[0],
s->linesize);
1692 uint8_t *ptr = dst[0];
1693 uint8_t *intra4x4 =
mb->intra4x4_pred_mode_mb;
1694 const uint8_t lo = is_vp7 ? 128 : 127;
1695 const uint8_t hi = is_vp7 ? 128 : 129;
1696 uint8_t tr_top[4] = { lo, lo, lo, lo };
1700 uint8_t *tr_right = ptr -
s->linesize + 16;
1704 if (mb_y && mb_x ==
s->mb_width - 1) {
1705 tr = tr_right[-1] * 0x01010101
u;
1706 tr_right = (uint8_t *) &tr;
1712 for (y = 0; y < 4; y++) {
1713 uint8_t *topright = ptr + 4 -
s->linesize;
1714 for (x = 0; x < 4; x++) {
1716 ptrdiff_t linesize =
s->linesize;
1717 uint8_t *dst = ptr + 4 * x;
1720 if ((y == 0 || x == 3) && mb_y == 0) {
1723 topright = tr_right;
1726 mb_y + y, &
copy, is_vp7);
1728 dst = copy_dst + 12;
1732 AV_WN32A(copy_dst + 4, lo * 0x01010101U);
1734 AV_COPY32(copy_dst + 4, ptr + 4 * x -
s->linesize);
1738 copy_dst[3] = ptr[4 * x -
s->linesize - 1];
1747 copy_dst[11] = ptr[4 * x - 1];
1748 copy_dst[19] = ptr[4 * x +
s->linesize - 1];
1749 copy_dst[27] = ptr[4 * x +
s->linesize * 2 - 1];
1750 copy_dst[35] = ptr[4 * x +
s->linesize * 3 - 1];
1753 s->hpc.pred4x4[
mode](dst, topright, linesize);
1756 AV_COPY32(ptr + 4 * x +
s->linesize, copy_dst + 20);
1757 AV_COPY32(ptr + 4 * x +
s->linesize * 2, copy_dst + 28);
1758 AV_COPY32(ptr + 4 * x +
s->linesize * 3, copy_dst + 36);
1761 nnz =
td->non_zero_count_cache[y][x];
1764 s->vp8dsp.vp8_idct_dc_add(ptr + 4 * x,
1765 td->block[y][x],
s->linesize);
1767 s->vp8dsp.vp8_idct_add(ptr + 4 * x,
1768 td->block[y][x],
s->linesize);
1773 ptr += 4 *
s->linesize;
1779 mb_x, mb_y, is_vp7);
1780 s->hpc.pred8x8[
mode](dst[1],
s->uvlinesize);
1781 s->hpc.pred8x8[
mode](dst[2],
s->uvlinesize);
1783 if (mb_y && (
s->deblock_filter || !mb_y) &&
td->thread_nr == 0)
1785 s->linesize,
s->uvlinesize, mb_x, mb_y,
s->mb_width,
1786 s->filter.simple, 0);
1790 { 0, 1, 2, 1, 2, 1, 2, 1 },
1792 { 0, 3, 5, 3, 5, 3, 5, 3 },
1793 { 0, 2, 3, 2, 3, 2, 3, 2 },
1815 int x_off,
int y_off,
int block_w,
int block_h,
1819 uint8_t *
src =
ref->f->data[0];
1822 ptrdiff_t src_linesize = linesize;
1827 x_off +=
mv->x >> 2;
1828 y_off +=
mv->y >> 2;
1832 src += y_off * linesize + x_off;
1835 s->vdsp.emulated_edge_mc(
td->edge_emu_buffer,
1836 src - my_idx * linesize - mx_idx,
1840 x_off - mx_idx, y_off - my_idx,
1845 mc_func[my_idx][mx_idx](dst, linesize,
src, src_linesize, block_h, mx, my);
1848 mc_func[0][0](dst, linesize,
src + y_off * linesize + x_off,
1849 linesize, block_h, 0, 0);
1873 int x_off,
int y_off,
int block_w,
int block_h,
1883 x_off +=
mv->x >> 3;
1884 y_off +=
mv->y >> 3;
1887 src1 += y_off * linesize + x_off;
1888 src2 += y_off * linesize + x_off;
1892 s->vdsp.emulated_edge_mc(
td->edge_emu_buffer,
1893 src1 - my_idx * linesize - mx_idx,
1901 s->vdsp.emulated_edge_mc(
td->edge_emu_buffer,
1902 src2 - my_idx * linesize - mx_idx,
1910 mc_func[my_idx][mx_idx](dst1, linesize,
src1, linesize, block_h, mx, my);
1911 mc_func[my_idx][mx_idx](dst2, linesize,
src2, linesize, block_h, mx, my);
1915 mc_func[0][0](dst1, linesize,
src1 + y_off * linesize + x_off, linesize, block_h, 0, 0);
1916 mc_func[0][0](dst2, linesize,
src2 + y_off * linesize + x_off, linesize, block_h, 0, 0);
1923 int bx_off,
int by_off,
int block_w,
int block_h,
1930 ref_frame,
mv, x_off + bx_off, y_off + by_off,
1932 s->put_pixels_tab[block_w == 8]);
1935 if (
s->profile == 3) {
1950 dst[2] + by_off *
s->uvlinesize + bx_off, ref_frame,
1951 &uvmv, x_off + bx_off, y_off + by_off,
1953 s->put_pixels_tab[1 + (block_w == 4)]);
1963 if (
s->ref_count[
ref - 1] > (mb_xy >> 5)) {
1964 int x_off = mb_x << 4, y_off = mb_y << 4;
1965 int mx = (
mb->mv.x >> 2) + x_off + 8;
1966 int my = (
mb->mv.y >> 2) + y_off;
1967 uint8_t **
src =
s->framep[
ref]->tf.f->data;
1968 int off = mx + (my + (mb_x & 3) * 4) *
s->linesize + 64;
1972 s->vdsp.prefetch(
src[0] + off,
s->linesize, 4);
1973 off = (mx >> 1) + ((my >> 1) + (mb_x & 7)) *
s->uvlinesize + 64;
1974 s->vdsp.prefetch(
src[1] + off,
src[2] -
src[1], 2);
1985 int x_off = mb_x << 4, y_off = mb_y << 4;
1990 switch (
mb->partitioning) {
2000 for (y = 0; y < 4; y++) {
2001 for (x = 0; x < 4; x++) {
2003 ref, &bmv[4 * y + x],
2004 4 * x + x_off, 4 * y + y_off, 4, 4,
2006 s->put_pixels_tab[2]);
2015 for (y = 0; y < 2; y++) {
2016 for (x = 0; x < 2; x++) {
2017 uvmv.
x =
mb->bmv[2 * y * 4 + 2 * x ].x +
2018 mb->bmv[2 * y * 4 + 2 * x + 1].x +
2019 mb->bmv[(2 * y + 1) * 4 + 2 * x ].x +
2020 mb->bmv[(2 * y + 1) * 4 + 2 * x + 1].x;
2021 uvmv.
y =
mb->bmv[2 * y * 4 + 2 * x ].y +
2022 mb->bmv[2 * y * 4 + 2 * x + 1].y +
2023 mb->bmv[(2 * y + 1) * 4 + 2 * x ].y +
2024 mb->bmv[(2 * y + 1) * 4 + 2 * x + 1].y;
2027 if (
s->profile == 3) {
2032 dst[2] + 4 * y *
s->uvlinesize + x * 4,
ref,
2033 &uvmv, 4 * x + x_off, 4 * y + y_off, 4, 4,
2035 s->put_pixels_tab[2]);
2071 uint8_t *y_dst = dst[0];
2072 for (y = 0; y < 4; y++) {
2073 uint32_t nnz4 =
AV_RL32(
td->non_zero_count_cache[y]);
2075 if (nnz4 & ~0x01010101) {
2076 for (x = 0; x < 4; x++) {
2077 if ((uint8_t) nnz4 == 1)
2078 s->vp8dsp.vp8_idct_dc_add(y_dst + 4 * x,
2081 else if ((uint8_t) nnz4 > 1)
2082 s->vp8dsp.vp8_idct_add(y_dst + 4 * x,
2090 s->vp8dsp.vp8_idct_dc_add4y(y_dst,
td->block[y],
s->linesize);
2093 y_dst += 4 *
s->linesize;
2097 for (ch = 0; ch < 2; ch++) {
2098 uint32_t nnz4 =
AV_RL32(
td->non_zero_count_cache[4 + ch]);
2100 uint8_t *ch_dst = dst[1 + ch];
2101 if (nnz4 & ~0x01010101) {
2102 for (y = 0; y < 2; y++) {
2103 for (x = 0; x < 2; x++) {
2104 if ((uint8_t) nnz4 == 1)
2105 s->vp8dsp.vp8_idct_dc_add(ch_dst + 4 * x,
2106 td->block[4 + ch][(y << 1) + x],
2108 else if ((uint8_t) nnz4 > 1)
2109 s->vp8dsp.vp8_idct_add(ch_dst + 4 * x,
2110 td->block[4 + ch][(y << 1) + x],
2114 goto chroma_idct_end;
2116 ch_dst += 4 *
s->uvlinesize;
2119 s->vp8dsp.vp8_idct_dc_add4uv(ch_dst,
td->block[4 + ch],
s->uvlinesize);
2131 int interior_limit, filter_level;
2133 if (
s->segmentation.enabled) {
2134 filter_level =
s->segmentation.filter_level[
mb->segment];
2135 if (!
s->segmentation.absolute_vals)
2136 filter_level +=
s->filter.level;
2138 filter_level =
s->filter.level;
2140 if (
s->lf_delta.enabled) {
2141 filter_level +=
s->lf_delta.ref[
mb->ref_frame];
2142 filter_level +=
s->lf_delta.mode[
mb->mode];
2147 interior_limit = filter_level;
2148 if (
s->filter.sharpness) {
2149 interior_limit >>= (
s->filter.sharpness + 3) >> 2;
2150 interior_limit =
FFMIN(interior_limit, 9 -
s->filter.sharpness);
2152 interior_limit =
FFMAX(interior_limit, 1);
2154 f->filter_level = filter_level;
2155 f->inner_limit = interior_limit;
2156 f->inner_filter = is_vp7 || !
mb->skip ||
mb->mode ==
MODE_I4x4 ||
2162 int mb_x,
int mb_y,
int is_vp7)
2164 int mbedge_lim, bedge_lim_y, bedge_lim_uv, hev_thresh;
2165 int filter_level =
f->filter_level;
2166 int inner_limit =
f->inner_limit;
2167 int inner_filter =
f->inner_filter;
2168 ptrdiff_t linesize =
s->linesize;
2169 ptrdiff_t uvlinesize =
s->uvlinesize;
2170 static const uint8_t hev_thresh_lut[2][64] = {
2171 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1,
2172 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2173 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
2175 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1,
2176 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2177 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2185 bedge_lim_y = filter_level;
2186 bedge_lim_uv = filter_level * 2;
2187 mbedge_lim = filter_level + 2;
2190 bedge_lim_uv = filter_level * 2 + inner_limit;
2191 mbedge_lim = bedge_lim_y + 4;
2194 hev_thresh = hev_thresh_lut[
s->keyframe][filter_level];
2197 s->vp8dsp.vp8_h_loop_filter16y(dst[0], linesize,
2198 mbedge_lim, inner_limit, hev_thresh);
2199 s->vp8dsp.vp8_h_loop_filter8uv(dst[1], dst[2], uvlinesize,
2200 mbedge_lim, inner_limit, hev_thresh);
2203 #define H_LOOP_FILTER_16Y_INNER(cond) \
2204 if (cond && inner_filter) { \
2205 s->vp8dsp.vp8_h_loop_filter16y_inner(dst[0] + 4, linesize, \
2206 bedge_lim_y, inner_limit, \
2208 s->vp8dsp.vp8_h_loop_filter16y_inner(dst[0] + 8, linesize, \
2209 bedge_lim_y, inner_limit, \
2211 s->vp8dsp.vp8_h_loop_filter16y_inner(dst[0] + 12, linesize, \
2212 bedge_lim_y, inner_limit, \
2214 s->vp8dsp.vp8_h_loop_filter8uv_inner(dst[1] + 4, dst[2] + 4, \
2215 uvlinesize, bedge_lim_uv, \
2216 inner_limit, hev_thresh); \
2222 s->vp8dsp.vp8_v_loop_filter16y(dst[0], linesize,
2223 mbedge_lim, inner_limit, hev_thresh);
2224 s->vp8dsp.vp8_v_loop_filter8uv(dst[1], dst[2], uvlinesize,
2225 mbedge_lim, inner_limit, hev_thresh);
2229 s->vp8dsp.vp8_v_loop_filter16y_inner(dst[0] + 4 * linesize,
2230 linesize, bedge_lim_y,
2231 inner_limit, hev_thresh);
2232 s->vp8dsp.vp8_v_loop_filter16y_inner(dst[0] + 8 * linesize,
2233 linesize, bedge_lim_y,
2234 inner_limit, hev_thresh);
2235 s->vp8dsp.vp8_v_loop_filter16y_inner(dst[0] + 12 * linesize,
2236 linesize, bedge_lim_y,
2237 inner_limit, hev_thresh);
2238 s->vp8dsp.vp8_v_loop_filter8uv_inner(dst[1] + 4 * uvlinesize,
2239 dst[2] + 4 * uvlinesize,
2240 uvlinesize, bedge_lim_uv,
2241 inner_limit, hev_thresh);
2251 int mbedge_lim, bedge_lim;
2252 int filter_level =
f->filter_level;
2253 int inner_limit =
f->inner_limit;
2254 int inner_filter =
f->inner_filter;
2255 ptrdiff_t linesize =
s->linesize;
2260 bedge_lim = 2 * filter_level + inner_limit;
2261 mbedge_lim = bedge_lim + 4;
2264 s->vp8dsp.vp8_h_loop_filter_simple(dst, linesize, mbedge_lim);
2266 s->vp8dsp.vp8_h_loop_filter_simple(dst + 4, linesize, bedge_lim);
2267 s->vp8dsp.vp8_h_loop_filter_simple(dst + 8, linesize, bedge_lim);
2268 s->vp8dsp.vp8_h_loop_filter_simple(dst + 12, linesize, bedge_lim);
2272 s->vp8dsp.vp8_v_loop_filter_simple(dst, linesize, mbedge_lim);
2274 s->vp8dsp.vp8_v_loop_filter_simple(dst + 4 * linesize, linesize, bedge_lim);
2275 s->vp8dsp.vp8_v_loop_filter_simple(dst + 8 * linesize, linesize, bedge_lim);
2276 s->vp8dsp.vp8_v_loop_filter_simple(dst + 12 * linesize, linesize, bedge_lim);
2280 #define MARGIN (16 << 2)
2288 s->mv_bounds.mv_min.y = -
MARGIN;
2289 s->mv_bounds.mv_max.y = ((
s->mb_height - 1) << 6) +
MARGIN;
2290 for (mb_y = 0; mb_y <
s->mb_height; mb_y++) {
2292 ((
s->mb_width + 1) * (mb_y + 1) + 1);
2293 int mb_xy = mb_y *
s->mb_width;
2297 s->mv_bounds.mv_min.x = -
MARGIN;
2298 s->mv_bounds.mv_max.x = ((
s->mb_width - 1) << 6) +
MARGIN;
2300 for (mb_x = 0; mb_x <
s->mb_width; mb_x++, mb_xy++,
mb++) {
2305 AV_WN32A((
mb -
s->mb_width - 1)->intra4x4_pred_mode_top,
2308 prev_frame && prev_frame->
seg_map ?
2310 s->mv_bounds.mv_min.x -= 64;
2311 s->mv_bounds.mv_max.x -= 64;
2313 s->mv_bounds.mv_min.y -= 64;
2314 s->mv_bounds.mv_max.y -= 64;
2332 #define check_thread_pos(td, otd, mb_x_check, mb_y_check) \
2334 int tmp = (mb_y_check << 16) | (mb_x_check & 0xFFFF); \
2335 if (atomic_load(&otd->thread_mb_pos) < tmp) { \
2336 pthread_mutex_lock(&otd->lock); \
2337 atomic_store(&td->wait_mb_pos, tmp); \
2339 if (atomic_load(&otd->thread_mb_pos) >= tmp) \
2341 pthread_cond_wait(&otd->cond, &otd->lock); \
2343 atomic_store(&td->wait_mb_pos, INT_MAX); \
2344 pthread_mutex_unlock(&otd->lock); \
2348 #define update_pos(td, mb_y, mb_x) \
2350 int pos = (mb_y << 16) | (mb_x & 0xFFFF); \
2351 int sliced_threading = (avctx->active_thread_type == FF_THREAD_SLICE) && \
2353 int is_null = !next_td || !prev_td; \
2354 int pos_check = (is_null) ? 1 : \
2355 (next_td != td && pos >= atomic_load(&next_td->wait_mb_pos)) || \
2356 (prev_td != td && pos >= atomic_load(&prev_td->wait_mb_pos)); \
2357 atomic_store(&td->thread_mb_pos, pos); \
2358 if (sliced_threading && pos_check) { \
2359 pthread_mutex_lock(&td->lock); \
2360 pthread_cond_broadcast(&td->cond); \
2361 pthread_mutex_unlock(&td->lock); \
2365 #define check_thread_pos(td, otd, mb_x_check, mb_y_check) while(0)
2366 #define update_pos(td, mb_y, mb_x) while(0)
2370 int jobnr,
int threadnr,
int is_vp7)
2375 int mb_x, mb_xy = mb_y *
s->mb_width;
2376 int num_jobs =
s->num_jobs;
2377 VP8Frame *curframe =
s->curframe, *prev_frame =
s->prev_frame;
2381 curframe->
tf.
f->
data[0] + 16 * mb_y *
s->linesize,
2382 curframe->
tf.
f->
data[1] + 8 * mb_y *
s->uvlinesize,
2383 curframe->
tf.
f->
data[2] + 8 * mb_y *
s->uvlinesize
2392 prev_td = &
s->thread_data[(jobnr + num_jobs - 1) % num_jobs];
2393 if (mb_y ==
s->mb_height - 1)
2396 next_td = &
s->thread_data[(jobnr + 1) % num_jobs];
2397 if (
s->mb_layout == 1)
2398 mb =
s->macroblocks_base + ((
s->mb_width + 1) * (mb_y + 1) + 1);
2402 if (prev_frame &&
s->segmentation.enabled &&
2403 !
s->segmentation.update_map)
2405 mb =
s->macroblocks + (
s->mb_height - mb_y - 1) * 2;
2406 memset(
mb - 1, 0,
sizeof(*
mb));
2410 if (!is_vp7 || mb_y == 0)
2411 memset(
td->left_nnz, 0,
sizeof(
td->left_nnz));
2414 td->mv_bounds.mv_max.x = ((
s->mb_width - 1) << 6) +
MARGIN;
2416 for (mb_x = 0; mb_x <
s->mb_width; mb_x++, mb_xy++,
mb++) {
2420 if (prev_td !=
td) {
2421 if (threadnr != 0) {
2423 mb_x + (is_vp7 ? 2 : 1),
2424 mb_y - (is_vp7 ? 2 : 1));
2427 mb_x + (is_vp7 ? 2 : 1) +
s->mb_width + 3,
2428 mb_y - (is_vp7 ? 2 : 1));
2432 s->vdsp.prefetch(dst[0] + (mb_x & 3) * 4 *
s->linesize + 64,
2434 s->vdsp.prefetch(dst[1] + (mb_x & 7) *
s->uvlinesize + 64,
2435 dst[2] - dst[1], 2);
2439 prev_frame && prev_frame->seg_map ?
2440 prev_frame->seg_map->data + mb_xy :
NULL, 0, is_vp7);
2463 td->left_nnz[8] = 0;
2464 s->top_nnz[mb_x][8] = 0;
2468 if (
s->deblock_filter)
2471 if (
s->deblock_filter && num_jobs != 1 && threadnr == num_jobs - 1) {
2472 if (
s->filter.simple)
2477 dst[1], dst[2],
s->linesize,
s->uvlinesize, 0);
2485 td->mv_bounds.mv_min.x -= 64;
2486 td->mv_bounds.mv_max.x -= 64;
2488 if (mb_x ==
s->mb_width + 1) {
2498 int jobnr,
int threadnr)
2504 int jobnr,
int threadnr)
2510 int jobnr,
int threadnr,
int is_vp7)
2514 int mb_x, mb_y =
atomic_load(&
td->thread_mb_pos) >> 16, num_jobs =
s->num_jobs;
2515 AVFrame *curframe =
s->curframe->tf.f;
2519 curframe->
data[0] + 16 * mb_y *
s->linesize,
2520 curframe->
data[1] + 8 * mb_y *
s->uvlinesize,
2521 curframe->
data[2] + 8 * mb_y *
s->uvlinesize
2524 if (
s->mb_layout == 1)
2525 mb =
s->macroblocks_base + ((
s->mb_width + 1) * (mb_y + 1) + 1);
2527 mb =
s->macroblocks + (
s->mb_height - mb_y - 1) * 2;
2532 prev_td = &
s->thread_data[(jobnr + num_jobs - 1) % num_jobs];
2533 if (mb_y ==
s->mb_height - 1)
2536 next_td = &
s->thread_data[(jobnr + 1) % num_jobs];
2538 for (mb_x = 0; mb_x <
s->mb_width; mb_x++,
mb++) {
2542 (mb_x + 1) + (
s->mb_width + 3), mb_y - 1);
2544 if (next_td != &
s->thread_data[0])
2547 if (num_jobs == 1) {
2548 if (
s->filter.simple)
2553 dst[1], dst[2],
s->linesize,
s->uvlinesize, 0);
2556 if (
s->filter.simple)
2569 int jobnr,
int threadnr)
2575 int jobnr,
int threadnr)
2582 int threadnr,
int is_vp7)
2588 int mb_y, num_jobs =
s->num_jobs;
2591 td->thread_nr = threadnr;
2592 td->mv_bounds.mv_min.y = -
MARGIN - 64 * threadnr;
2593 td->mv_bounds.mv_max.y = ((
s->mb_height - 1) << 6) +
MARGIN - 64 * threadnr;
2594 for (mb_y = jobnr; mb_y <
s->mb_height; mb_y += num_jobs) {
2596 ret =
s->decode_mb_row_no_filter(avctx, tdata, jobnr, threadnr);
2601 if (
s->deblock_filter)
2602 s->filter_mb_row(avctx, tdata, jobnr, threadnr);
2605 td->mv_bounds.mv_min.y -= 64 * num_jobs;
2606 td->mv_bounds.mv_max.y -= 64 * num_jobs;
2616 int jobnr,
int threadnr)
2622 int jobnr,
int threadnr)
2632 int ret,
i, referenced, num_jobs;
2644 if (
s->actually_webp) {
2648 if (
s->pix_fmt < 0) {
2666 memcpy(&
s->next_framep[0], &
s->framep[0],
sizeof(
s->framep[0]) * 4);
2672 for (
i = 0;
i < 5;
i++)
2673 if (
s->frames[
i].tf.f->buf[0] &&
2674 &
s->frames[
i] != prev_frame &&
2697 "Discarding interframe without a prior keyframe!\n");
2702 curframe->tf.f->key_frame =
s->keyframe;
2743 s->linesize = curframe->tf.f->linesize[0];
2744 s->uvlinesize = curframe->tf.f->linesize[1];
2746 memset(
s->top_nnz, 0,
s->mb_width *
sizeof(*
s->top_nnz));
2750 memset(
s->macroblocks +
s->mb_height * 2 - 1, 0,
2751 (
s->mb_width + 1) *
sizeof(*
s->macroblocks));
2752 if (!
s->mb_layout &&
s->keyframe)
2753 memset(
s->intra4x4_pred_mode_top,
DC_PRED,
s->mb_width * 4);
2755 memset(
s->ref_count, 0,
sizeof(
s->ref_count));
2757 if (
s->mb_layout == 1) {
2760 if (prev_frame &&
s->segmentation.enabled &&
2761 !
s->segmentation.update_map)
2775 s->num_jobs = num_jobs;
2776 s->curframe = curframe;
2777 s->prev_frame = prev_frame;
2778 s->mv_bounds.mv_min.y = -
MARGIN;
2779 s->mv_bounds.mv_max.y = ((
s->mb_height - 1) << 6) +
MARGIN;
2794 memcpy(&
s->framep[0], &
s->next_framep[0],
sizeof(
s->framep[0]) * 4);
2799 if (!
s->update_probabilities)
2800 s->prob[0] =
s->prob[1];
2802 if (!
s->invisible) {
2810 memcpy(&
s->next_framep[0], &
s->framep[0],
sizeof(
s->framep[0]) * 4);
2820 #if CONFIG_VP7_DECODER
2845 if (!
s->frames[
i].tf.f)
2865 if (CONFIG_VP7_DECODER && is_vp7) {
2870 }
else if (CONFIG_VP8_DECODER && !is_vp7) {
2888 #if CONFIG_VP7_DECODER
2900 #if CONFIG_VP8_DECODER
2902 #define REBASE(pic) ((pic) ? (pic) - &s_src->frames[0] + &s->frames[0] : NULL)
2910 if (
s->macroblocks_base &&
2911 (s_src->mb_width !=
s->mb_width || s_src->mb_height !=
s->mb_height)) {
2913 s->mb_width = s_src->mb_width;
2914 s->mb_height = s_src->mb_height;
2917 s->pix_fmt = s_src->pix_fmt;
2918 s->prob[0] = s_src->prob[!s_src->update_probabilities];
2919 s->segmentation = s_src->segmentation;
2920 s->lf_delta = s_src->lf_delta;
2921 memcpy(
s->sign_bias, s_src->sign_bias,
sizeof(
s->sign_bias));
2924 if (s_src->frames[
i].tf.f->buf[0]) {
2925 int ret = vp8_ref_frame(
s, &
s->frames[
i], &s_src->frames[
i]);
2931 s->framep[0] = REBASE(s_src->next_framep[0]);
2932 s->framep[1] = REBASE(s_src->next_framep[1]);
2933 s->framep[2] = REBASE(s_src->next_framep[2]);
2934 s->framep[3] = REBASE(s_src->next_framep[3]);
2941 #if CONFIG_VP7_DECODER
2948 .
init = vp7_decode_init,
2957 #if CONFIG_VP8_DECODER
2974 #if CONFIG_VP8_VAAPI_HWACCEL
2977 #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.
#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 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 av_always_inline int vp8_rac_get_coeff(VP56RangeCoder *c, const uint8_t *prob)
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 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
static int vp7_read_mv_component(VP56RangeCoder *c, const uint8_t *p)
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.
static av_always_inline int vpX_rac_is_end(VP56RangeCoder *c)
vp5689 returns 1 if the end of the stream has been reached, 0 otherwise.
static av_always_inline int read_mv_component(VP56RangeCoder *c, const uint8_t *p, int vp7)
Motion vector coding, 17.1.
#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[]
static av_always_inline void clamp_mv(VP8mvbounds *s, VP56mv *dst, const VP56mv *src)
#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 int inter_predict_dc(int16_t block[16], int16_t pred[2])
static const VP56mv * get_bmv_ptr(const VP8Macroblock *mb, int subblock)
static void vp8_get_quants(VP8Context *s)
static VP56Frame ref_to_update(VP8Context *s, int update, VP56Frame ref)
Determine which buffers golden and altref should be updated with after this frame.
static int vp8_decode_block_coeffs_internal(VP56RangeCoder *r, int16_t block[16], uint8_t probs[16][3][NUM_DCT_TOKENS - 1], int i, uint8_t *token_prob, int16_t qmul[2])
static av_always_inline void backup_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 simple)
AVBufferRef * av_buffer_ref(const AVBufferRef *buf)
Create a new reference to an AVBuffer.
@ VP8_SPLITMVMODE_4x4
4x4 blocks of 4x4px each
#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 av_unused int vp8_rac_get_nn(VP56RangeCoder *c)
static int vp8_decode_mb_row_no_filter(AVCodecContext *avctx, void *tdata, int jobnr, int threadnr)
static const int8_t vp8_pred8x8c_tree[3][2]
#define bit(string, value)
#define update_pos(td, mb_y, mb_x)
static av_always_inline int update_dimensions(VP8Context *s, int width, int height, int is_vp7)
static av_always_inline int vp56_rac_get_prob_branchy(VP56RangeCoder *c, int prob)
@ 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.
static av_always_inline int vp8_rac_get(VP56RangeCoder *c)
const struct AVCodec * codec
static av_always_inline void filter_level_for_mb(VP8Context *s, VP8Macroblock *mb, VP8FilterStrength *f, int is_vp7)
static const uint8_t vp8_mv_update_prob[2][19]
enum AVDiscard skip_frame
Skip decoding for selected frames.
static av_always_inline void intra_predict(VP8Context *s, VP8ThreadData *td, uint8_t *dst[3], VP8Macroblock *mb, int mb_x, int mb_y, int is_vp7)
int thread_count
thread count is used to decide how many independent tasks should be passed to execute()
const FFCodec ff_vp8_decoder
static av_unused int vp8_rac_get_sint(VP56RangeCoder *c, int bits)
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 int check_intra_pred8x8_mode_emuedge(int mode, int mb_x, int mb_y, int vp7)
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.
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 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.
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 av_always_inline int decode_block_coeffs(VP56RangeCoder *c, int16_t block[16], uint8_t probs[16][3][NUM_DCT_TOKENS - 1], int i, int zero_nhood, int16_t qmul[2], const uint8_t scan[16], int vp7)
static const int vp7_mode_contexts[31][4]
static av_always_inline int vp78_decode_mv_mb_modes(AVCodecContext *avctx, VP8Frame *curframe, 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)
static int vp8_decode_mv_mb_modes(AVCodecContext *avctx, VP8Frame *cur_frame, VP8Frame *prev_frame)
@ VP8_SPLITMVMODE_8x16
2 8x16 blocks (horizontal)
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 av_always_inline void decode_mb_coeffs(VP8Context *s, VP8ThreadData *td, VP56RangeCoder *c, VP8Macroblock *mb, uint8_t t_nnz[9], uint8_t l_nnz[9], int is_vp7)
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)
static int vp8_rac_get_uint(VP56RangeCoder *c, int bits)
static av_always_inline int vp8_rac_get_tree(VP56RangeCoder *c, const int8_t(*tree)[2], const uint8_t *probs)
int(* end_frame)(AVCodecContext *avctx)
Called at the end of each frame or field picture.
@ AV_PICTURE_TYPE_I
Intra.
AVBufferRef * hwaccel_priv_buf
#define check_thread_pos(td, otd, mb_x_check, mb_y_check)
static const uint16_t vp7_yac_qlookup[]
static const uint8_t vp8_token_default_probs[4][8][3][NUM_DCT_TOKENS - 1]
static av_always_inline void vp8_mc_part(VP8Context *s, VP8ThreadData *td, uint8_t *dst[3], 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, VP56mv *mv)
static const uint8_t vp8_token_update_probs[4][8][3][NUM_DCT_TOKENS - 1]
#define ONLY_IF_THREADS_ENABLED(x)
Define a function with only the non-default version specified.
static const uint8_t vp8_mbsplit_count[4]
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
void(* vp8_mc_func)(uint8_t *dst, ptrdiff_t dstStride, uint8_t *src, ptrdiff_t srcStride, int h, int x, int y)
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]
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
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 av_always_inline void vp8_mc_chroma(VP8Context *s, VP8ThreadData *td, uint8_t *dst1, uint8_t *dst2, ThreadFrame *ref, const VP56mv *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 int vp7_update_dimensions(VP8Context *s, int width, int height)
#define EDGE_EMU_LINESIZE
static av_always_inline void filter_mb(VP8Context *s, uint8_t *dst[3], VP8FilterStrength *f, int mb_x, int mb_y, int is_vp7)
static void vp8_release_frame(VP8Context *s, VP8Frame *f)
#define FF_CODEC_CAP_ALLOCATE_PROGRESS
static av_always_inline void decode_mb_mode(VP8Context *s, VP8mvbounds *mv_bounds, VP8Macroblock *mb, int mb_x, int mb_y, uint8_t *segment, uint8_t *ref, int layout, int is_vp7)
static void free_buffers(VP8Context *s)
static int vp7_decode_mv_mb_modes(AVCodecContext *avctx, VP8Frame *cur_frame, VP8Frame *prev_frame)
static const av_always_inline FFCodec * ffcodec(const AVCodec *codec)
#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_read_mv_component(VP56RangeCoder *c, const uint8_t *p)
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_RL24
static av_always_inline void vp8_decode_mvs(VP8Context *s, VP8mvbounds *mv_bounds, VP8Macroblock *mb, int mb_x, int mb_y, int layout)
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]
int ff_vp56_init_range_decoder(VP56RangeCoder *c, const uint8_t *buf, int buf_size)
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)
@ 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 av_always_inline void idct_mb(VP8Context *s, VP8ThreadData *td, uint8_t *dst[3], VP8Macroblock *mb)
static av_always_inline int decode_block_coeffs_internal(VP56RangeCoder *r, int16_t block[16], uint8_t probs[16][3][NUM_DCT_TOKENS - 1], int i, uint8_t *token_prob, int16_t qmul[2], const uint8_t scan[16], int vp7)
#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 av_always_inline void decode_intra4x4_modes(VP8Context *s, VP56RangeCoder *c, VP8Macroblock *mb, int mb_x, int keyframe, int layout)
static int vp7_fade_frame(VP8Context *s, int alpha, int beta)
static av_always_inline void prefetch_motion(VP8Context *s, VP8Macroblock *mb, int mb_x, int mb_y, int mb_xy, int ref)
#define FF_CODEC_CAP_INIT_THREADSAFE
The codec does not modify any global variables in the init function, allowing to call the init functi...
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)
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 int vp7_decode_block_coeffs_internal(VP56RangeCoder *r, int16_t block[16], uint8_t probs[16][3][NUM_DCT_TOKENS - 1], int i, uint8_t *token_prob, int16_t qmul[2], const uint8_t scan[16])
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,...)
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
static av_always_inline void inter_predict(VP8Context *s, VP8ThreadData *td, uint8_t *dst[3], VP8Macroblock *mb, int mb_x, int mb_y)
Apply motion vectors to prediction buffer, chapter 18.
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 decode_splitmvs(VP8Context *s, VP56RangeCoder *c, VP8Macroblock *mb, int layout, int is_vp7)
Split motion vector prediction, 16.4.
main external API structure.
int active_thread_type
Which multithreading methods are in use by the codec.
uint8_t intra4x4_pred_mode_top[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 av_always_inline void filter_mb_simple(VP8Context *s, uint8_t *dst, VP8FilterStrength *f, int mb_x, int mb_y)
static int ref[MAX_W *MAX_W]
int(* start_frame)(AVCodecContext *avctx, const uint8_t *buf, uint32_t buf_size)
Called at the beginning of each frame or field picture.
static av_always_inline void vp8_mc_luma(VP8Context *s, VP8ThreadData *td, uint8_t *dst, ThreadFrame *ref, const VP56mv *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
static void vp78_update_probability_tables(VP8Context *s)
@ AV_PICTURE_TYPE_P
Predicted.
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 vp56_rac_get_prob
static void vp78_update_pred16x16_pred8x8_mvc_probabilities(VP8Context *s, int mvc_size)
#define avpriv_request_sample(...)
static void update_refs(VP8Context *s)
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 void copy_chroma(AVFrame *dst, AVFrame *src, int width, int height)
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 av_always_inline unsigned int vp56_rac_renorm(VP56RangeCoder *c)
static const uint8_t vp8_dc_qlookup[VP8_MAX_QUANT+1]
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