Go to the documentation of this file.
27 #include "config_components.h"
101 s->macroblocks =
NULL;
141 memset(
s->framep, 0,
sizeof(
s->framep));
161 for (
i = 0;
i < 5;
i++)
182 #if CONFIG_VP8_VAAPI_HWACCEL
185 #if CONFIG_VP8_NVDEC_HWACCEL
199 int i,
ret, dim_reset = 0;
201 if (
width !=
s->avctx->width || ((
width+15)/16 !=
s->mb_width || (
height+15)/16 !=
s->mb_height) &&
s->macroblocks_base ||
209 dim_reset = (
s->macroblocks_base !=
NULL);
213 !
s->actually_webp && !is_vp7) {
220 s->mb_width = (
s->avctx->coded_width + 15) / 16;
221 s->mb_height = (
s->avctx->coded_height + 15) / 16;
226 s->macroblocks_base =
av_mallocz((
s->mb_width +
s->mb_height * 2 + 1) *
227 sizeof(*
s->macroblocks));
228 s->intra4x4_pred_mode_top =
av_mallocz(
s->mb_width * 4);
230 s->macroblocks_base =
av_mallocz((
s->mb_width + 2) * (
s->mb_height + 2) *
231 sizeof(*
s->macroblocks));
233 s->top_border =
av_mallocz((
s->mb_width + 1) *
sizeof(*
s->top_border));
236 if (!
s->macroblocks_base || !
s->top_nnz || !
s->top_border ||
237 !
s->thread_data || (!
s->intra4x4_pred_mode_top && !
s->mb_layout)) {
243 s->thread_data[
i].filter_strength =
244 av_mallocz(
s->mb_width *
sizeof(*
s->thread_data[0].filter_strength));
245 if (!
s->thread_data[
i].filter_strength) {
255 s->macroblocks =
s->macroblocks_base + 1;
279 if (
s->segmentation.update_feature_data) {
282 for (
i = 0;
i < 4;
i++)
285 for (
i = 0;
i < 4;
i++)
288 if (
s->segmentation.update_map)
289 for (
i = 0;
i < 3;
i++)
298 for (
i = 0;
i < 4;
i++) {
303 s->lf_delta.ref[
i] = -
s->lf_delta.ref[
i];
312 s->lf_delta.mode[
i] = -
s->lf_delta.mode[
i];
319 const uint8_t *
sizes = buf;
325 buf += 3 * (
s->num_coeff_partitions - 1);
326 buf_size -= 3 * (
s->num_coeff_partitions - 1);
330 for (
i = 0;
i <
s->num_coeff_partitions - 1;
i++) {
332 if (buf_size -
size < 0)
334 s->coeff_partition_size[
i] =
size;
343 s->coeff_partition_size[
i] = buf_size;
380 for (
i = 0;
i < 4;
i++) {
381 if (
s->segmentation.enabled) {
382 base_qi =
s->segmentation.base_quant[
i];
383 if (!
s->segmentation.absolute_vals)
384 base_qi +=
s->quant.yac_qi;
386 base_qi =
s->quant.yac_qi;
396 s->qmat[
i].luma_dc_qmul[1] =
FFMAX(
s->qmat[
i].luma_dc_qmul[1], 8);
397 s->qmat[
i].chroma_qmul[0] =
FFMIN(
s->qmat[
i].chroma_qmul[0], 132);
433 for (
i = 0;
i < 4;
i++)
434 for (j = 0; j < 16; j++)
436 sizeof(
s->prob->token[
i][j]));
444 for (
i = 0;
i < 4;
i++)
445 for (j = 0; j < 8; j++)
446 for (k = 0; k < 3; k++)
455 #define VP7_MVC_SIZE 17
456 #define VP8_MVC_SIZE 19
465 for (
i = 0;
i < 4;
i++)
468 for (
i = 0;
i < 3;
i++)
472 for (
i = 0;
i < 2;
i++)
473 for (j = 0; j < mvc_size; j++)
493 for (j = 1; j < 3; j++) {
500 static void fade(uint8_t *dst, ptrdiff_t dst_linesize,
501 const uint8_t *
src, ptrdiff_t src_linesize,
506 for (j = 0; j <
height; j++) {
507 const uint8_t *
src2 =
src + j * src_linesize;
508 uint8_t *dst2 = dst + j * dst_linesize;
520 if (!
s->keyframe && (
alpha || beta)) {
521 int width =
s->mb_width * 16;
522 int height =
s->mb_height * 16;
547 src->data[0],
src->linesize[0],
557 int part1_size, hscale, vscale,
i, j,
ret;
558 int width =
s->avctx->width;
562 int fade_present = 1;
568 s->profile = (buf[0] >> 1) & 7;
569 if (
s->profile > 1) {
574 s->keyframe = !(buf[0] & 1);
576 part1_size =
AV_RL24(buf) >> 4;
578 if (buf_size < 4 - s->
profile + part1_size) {
579 av_log(
s->avctx,
AV_LOG_ERROR,
"Buffer size %d is too small, needed : %d\n", buf_size, 4 -
s->profile + part1_size);
583 buf += 4 -
s->profile;
584 buf_size -= 4 -
s->profile;
586 memcpy(
s->put_pixels_tab,
s->vp8dsp.put_vp8_epel_pixels_tab,
sizeof(
s->put_pixels_tab));
592 buf_size -= part1_size;
600 if (hscale || vscale)
606 sizeof(
s->prob->pred16x16));
608 sizeof(
s->prob->pred8x8c));
609 for (
i = 0;
i < 2;
i++)
612 memset(&
s->segmentation, 0,
sizeof(
s->segmentation));
613 memset(&
s->lf_delta, 0,
sizeof(
s->lf_delta));
617 if (
s->keyframe ||
s->profile > 0)
618 memset(
s->inter_dc_pred, 0 ,
sizeof(
s->inter_dc_pred));
621 for (
i = 0;
i < 4;
i++) {
623 if (
s->feature_enabled[
i]) {
626 for (j = 0; j < 3; j++)
627 s->feature_index_prob[
i][j] =
631 for (j = 0; j < 4; j++)
632 s->feature_value[
i][j] =
637 s->segmentation.enabled = 0;
638 s->segmentation.update_map = 0;
639 s->lf_delta.enabled = 0;
641 s->num_coeff_partitions = 1;
646 if (!
s->macroblocks_base ||
648 (
width + 15) / 16 !=
s->mb_width || (
height + 15) / 16 !=
s->mb_height) {
663 s->update_probabilities = 1;
665 if (
s->profile > 0) {
667 if (!
s->update_probabilities)
668 s->prob[1] =
s->prob[0];
688 for (
i = 1;
i < 16;
i++)
700 s->mbskip_enabled = 0;
721 int header_size, hscale, vscale,
ret;
722 int width =
s->avctx->width;
730 s->keyframe = !(buf[0] & 1);
731 s->profile = (buf[0]>>1) & 7;
732 s->invisible = !(buf[0] & 0x10);
733 header_size =
AV_RL24(buf) >> 5;
737 s->header_partition_size = header_size;
743 memcpy(
s->put_pixels_tab,
s->vp8dsp.put_vp8_epel_pixels_tab,
744 sizeof(
s->put_pixels_tab));
746 memcpy(
s->put_pixels_tab,
s->vp8dsp.put_vp8_bilinear_pixels_tab,
747 sizeof(
s->put_pixels_tab));
749 if (header_size > buf_size - 7 *
s->keyframe) {
755 if (
AV_RL24(buf) != 0x2a019d) {
757 "Invalid start code 0x%x\n",
AV_RL24(buf));
762 hscale = buf[4] >> 6;
763 vscale = buf[6] >> 6;
767 if (hscale || vscale)
773 sizeof(
s->prob->pred16x16));
775 sizeof(
s->prob->pred8x8c));
777 sizeof(
s->prob->mvc));
778 memset(&
s->segmentation, 0,
sizeof(
s->segmentation));
779 memset(&
s->lf_delta, 0,
sizeof(
s->lf_delta));
786 buf_size -= header_size;
798 s->segmentation.update_map = 0;
806 if (
s->lf_delta.update)
815 if (!
s->macroblocks_base ||
817 (
width+15)/16 !=
s->mb_width || (
height+15)/16 !=
s->mb_height)
832 s->prob[1] =
s->prob[0];
850 s->coder_state_at_header_end.input =
s->c.buffer - (-
s->c.bits / 8);
851 s->coder_state_at_header_end.range =
s->c.high;
852 s->coder_state_at_header_end.value =
s->c.code_word >> 16;
853 s->coder_state_at_header_end.bit_count = -
s->c.bits % 8;
862 av_clip(
s->mv_max.x, INT16_MIN, INT16_MAX));
864 av_clip(
s->mv_max.y, INT16_MIN, INT16_MAX));
877 for (
i = 0;
i < 3;
i++)
879 for (
i = (vp7 ? 7 : 9);
i > 3;
i--)
885 const uint8_t *ps = p + 2;
934 const uint8_t *mbsplits_top, *mbsplits_cur, *firstidx;
936 const VP8mv *left_mv = left_mb->
bmv;
942 top_mb = &
mb[-
s->mb_width - 1];
944 top_mv = top_mb->
bmv;
958 mb->partitioning = part_idx;
960 for (n = 0; n < num; n++) {
962 uint32_t
left, above;
963 const uint8_t *submv_prob;
970 above =
AV_RN32A(&top_mv[mbsplits_top[k + 12]]);
972 above =
AV_RN32A(&cur_mv[mbsplits_cur[k - 4]]);
979 mb->bmv[n].y =
mb->mv.y +
981 mb->bmv[n].x =
mb->mv.x +
1009 int xoffset,
int yoffset,
int boundary,
1010 int *edge_x,
int *edge_y)
1012 int vwidth = mb_width + 1;
1013 int new = (mb_y + yoffset) * vwidth + mb_x + xoffset;
1014 if (
new < boundary ||
new % vwidth == vwidth - 1)
1016 *edge_y =
new / vwidth;
1017 *edge_x =
new % vwidth;
1028 int mb_x,
int mb_y,
int layout)
1030 enum { CNT_ZERO, CNT_NEAREST, CNT_NEAR };
1031 enum { VP8_EDGE_TOP, VP8_EDGE_LEFT, VP8_EDGE_TOPLEFT };
1034 uint8_t cnt[3] = { 0 };
1047 pred->yoffset, !
s->profile, &edge_x, &edge_y)) {
1049 ?
s->macroblocks_base + 1 + edge_x +
1050 (
s->mb_width + 1) * (edge_y + 1)
1051 :
s->macroblocks + edge_x +
1052 (
s->mb_height - edge_y - 1) * 2;
1055 if (
AV_RN32A(&near_mv[CNT_NEAREST])) {
1058 }
else if (
AV_RN32A(&near_mv[CNT_NEAR])) {
1088 if (cnt[CNT_NEAREST] > cnt[CNT_NEAR])
1089 AV_WN32A(&
mb->mv, cnt[CNT_ZERO] > cnt[CNT_NEAREST] ? 0 :
AV_RN32A(&near_mv[CNT_NEAREST]));
1099 mb->bmv[0] =
mb->mv;
1102 mb->mv = near_mv[CNT_NEAR];
1103 mb->bmv[0] =
mb->mv;
1106 mb->mv = near_mv[CNT_NEAREST];
1107 mb->bmv[0] =
mb->mv;
1112 mb->bmv[0] =
mb->mv;
1118 int mb_x,
int mb_y,
int layout)
1123 enum { CNT_ZERO, CNT_NEAREST, CNT_NEAR, CNT_SPLITMV };
1124 enum { VP8_EDGE_TOP, VP8_EDGE_LEFT, VP8_EDGE_TOPLEFT };
1126 int cur_sign_bias =
s->sign_bias[
mb->ref_frame];
1127 const int8_t *sign_bias =
s->sign_bias;
1129 uint8_t cnt[4] = { 0 };
1133 mb_edge[0] =
mb + 2;
1134 mb_edge[2] =
mb + 1;
1136 mb_edge[0] =
mb -
s->mb_width - 1;
1137 mb_edge[2] =
mb -
s->mb_width - 2;
1145 #define MV_EDGE_CHECK(n) \
1147 const VP8Macroblock *edge = mb_edge[n]; \
1148 int edge_ref = edge->ref_frame; \
1149 if (edge_ref != VP8_FRAME_CURRENT) { \
1150 uint32_t mv = AV_RN32A(&edge->mv); \
1152 if (cur_sign_bias != sign_bias[edge_ref]) { \
1155 mv = ((mv & 0x7fff7fff) + \
1156 0x00010001) ^ (mv & 0x80008000); \
1158 if (!n || mv != AV_RN32A(&near_mv[idx])) \
1159 AV_WN32A(&near_mv[++idx], mv); \
1160 cnt[idx] += 1 + (n != 2); \
1162 cnt[CNT_ZERO] += 1 + (n != 2); \
1175 if (cnt[CNT_SPLITMV] &&
1176 AV_RN32A(&near_mv[1 + VP8_EDGE_TOP]) ==
AV_RN32A(&near_mv[1 + VP8_EDGE_TOPLEFT]))
1177 cnt[CNT_NEAREST] += 1;
1180 if (cnt[CNT_NEAR] > cnt[CNT_NEAREST]) {
1181 FFSWAP(uint8_t, cnt[CNT_NEAREST], cnt[CNT_NEAR]);
1182 FFSWAP(
VP8mv, near_mv[CNT_NEAREST], near_mv[CNT_NEAR]);
1188 clamp_mv(mv_bounds, &
mb->mv, &near_mv[CNT_ZERO + (cnt[CNT_NEAREST] >= cnt[CNT_ZERO])]);
1199 mb->bmv[0] =
mb->mv;
1202 clamp_mv(mv_bounds, &
mb->mv, &near_mv[CNT_NEAR]);
1203 mb->bmv[0] =
mb->mv;
1206 clamp_mv(mv_bounds, &
mb->mv, &near_mv[CNT_NEAREST]);
1207 mb->bmv[0] =
mb->mv;
1212 mb->bmv[0] =
mb->mv;
1218 int mb_x,
int keyframe,
int layout)
1220 uint8_t *intra4x4 =
mb->intra4x4_pred_mode_mb;
1229 uint8_t *
const left =
s->intra4x4_pred_mode_left;
1231 top =
mb->intra4x4_pred_mode_top;
1233 top =
s->intra4x4_pred_mode_top + 4 * mb_x;
1234 for (y = 0; y < 4; y++) {
1235 for (x = 0; x < 4; x++) {
1239 left[y] = top[x] = *intra4x4;
1245 for (
i = 0;
i < 16;
i++)
1257 static const char *
const vp7_feature_name[] = {
"q-index",
1259 "partial-golden-update",
1264 for (
i = 0;
i < 4;
i++) {
1265 if (
s->feature_enabled[
i]) {
1268 s->feature_index_prob[
i]);
1270 "Feature %s present in macroblock (value 0x%x)\n",
1271 vp7_feature_name[
i],
s->feature_value[
i][
index]);
1275 }
else if (
s->segmentation.update_map) {
1278 }
else if (
s->segmentation.enabled)
1311 s->ref_count[
mb->ref_frame - 1]++;
1321 s->prob->pred16x16);
1347 int i,
const uint8_t *token_prob,
const int16_t qmul[2],
1348 const uint8_t scan[16],
int vp7)
1362 token_prob = probs[
i][0];
1370 token_prob = probs[
i + 1][1];
1390 int cat = (
a << 1) +
b;
1395 token_prob = probs[
i + 1][2];
1430 int i,
const uint8_t *token_prob,
1431 const int16_t qmul[2],
1432 const uint8_t scan[16])
1435 token_prob, qmul, scan,
IS_VP7);
1438 #ifndef vp8_decode_block_coeffs_internal
1442 int i,
const uint8_t *token_prob,
1443 const int16_t qmul[2])
1466 int i,
int zero_nhood,
const int16_t qmul[2],
1467 const uint8_t scan[16],
int vp7)
1469 const uint8_t *token_prob = probs[
i][zero_nhood];
1473 token_prob, qmul, scan)
1483 int i, x, y, luma_start = 0, luma_ctx = 3;
1484 int nnz_pred, nnz, nnz_total = 0;
1489 nnz_pred = t_nnz[8] + l_nnz[8];
1493 nnz_pred,
s->qmat[
segment].luma_dc_qmul,
1495 l_nnz[8] = t_nnz[8] = !!nnz;
1499 s->inter_dc_pred[
mb->ref_frame - 1]);
1506 s->vp8dsp.vp8_luma_dc_wht_dc(
td->block,
td->block_dc);
1508 s->vp8dsp.vp8_luma_dc_wht(
td->block,
td->block_dc);
1515 for (y = 0; y < 4; y++)
1516 for (x = 0; x < 4; x++) {
1517 nnz_pred = l_nnz[y] + t_nnz[x];
1519 s->prob->token[luma_ctx],
1520 luma_start, nnz_pred,
1522 s->prob[0].scan, is_vp7);
1525 td->non_zero_count_cache[y][x] = nnz + block_dc;
1526 t_nnz[x] = l_nnz[y] = !!nnz;
1533 for (
i = 4;
i < 6;
i++)
1534 for (y = 0; y < 2; y++)
1535 for (x = 0; x < 2; x++) {
1536 nnz_pred = l_nnz[
i + 2 * y] + t_nnz[
i + 2 * x];
1538 s->prob->token[2], 0, nnz_pred,
1540 s->prob[0].scan, is_vp7);
1541 td->non_zero_count_cache[
i][(y << 1) + x] = nnz;
1542 t_nnz[
i + 2 * x] = l_nnz[
i + 2 * y] = !!nnz;
1555 const uint8_t *src_cb,
const uint8_t *src_cr,
1556 ptrdiff_t linesize, ptrdiff_t uvlinesize,
int simple)
1558 AV_COPY128(top_border, src_y + 15 * linesize);
1560 AV_COPY64(top_border + 16, src_cb + 7 * uvlinesize);
1561 AV_COPY64(top_border + 24, src_cr + 7 * uvlinesize);
1567 uint8_t *src_cr, ptrdiff_t linesize, ptrdiff_t uvlinesize,
int mb_x,
1568 int mb_y,
int mb_width,
int simple,
int xchg)
1570 uint8_t *top_border_m1 = top_border - 32;
1572 src_cb -= uvlinesize;
1573 src_cr -= uvlinesize;
1575 #define XCHG(a, b, xchg) \
1583 XCHG(top_border_m1 + 8, src_y - 8, xchg);
1584 XCHG(top_border, src_y, xchg);
1585 XCHG(top_border + 8, src_y + 8, 1);
1586 if (mb_x < mb_width - 1)
1587 XCHG(top_border + 32, src_y + 16, 1);
1591 if (!simple || !mb_y) {
1592 XCHG(top_border_m1 + 16, src_cb - 8, xchg);
1593 XCHG(top_border_m1 + 24, src_cr - 8, xchg);
1594 XCHG(top_border + 16, src_cb, 1);
1595 XCHG(top_border + 24, src_cr, 1);
1645 int *copy_buf,
int vp7)
1649 if (!mb_x && mb_y) {
1683 int x, y,
mode, nnz;
1688 if (mb_y && (
s->deblock_filter || !mb_y) &&
td->thread_nr == 0)
1690 s->linesize,
s->uvlinesize, mb_x, mb_y,
s->mb_width,
1691 s->filter.simple, 1);
1695 s->hpc.pred16x16[
mode](dst[0],
s->linesize);
1697 uint8_t *ptr = dst[0];
1698 const uint8_t *intra4x4 =
mb->intra4x4_pred_mode_mb;
1699 const uint8_t lo = is_vp7 ? 128 : 127;
1700 const uint8_t hi = is_vp7 ? 128 : 129;
1701 const uint8_t tr_top[4] = { lo, lo, lo, lo };
1705 const uint8_t *tr_right = ptr -
s->linesize + 16;
1709 if (mb_y && mb_x ==
s->mb_width - 1) {
1710 tr = tr_right[-1] * 0x01010101
u;
1711 tr_right = (uint8_t *) &tr;
1717 for (y = 0; y < 4; y++) {
1718 const uint8_t *topright = ptr + 4 -
s->linesize;
1719 for (x = 0; x < 4; x++) {
1721 ptrdiff_t linesize =
s->linesize;
1722 uint8_t *dst = ptr + 4 * x;
1725 if ((y == 0 || x == 3) && mb_y == 0) {
1728 topright = tr_right;
1731 mb_y + y, &
copy, is_vp7);
1733 dst = copy_dst + 12;
1737 AV_WN32A(copy_dst + 4, lo * 0x01010101U);
1739 AV_COPY32(copy_dst + 4, ptr + 4 * x -
s->linesize);
1743 copy_dst[3] = ptr[4 * x -
s->linesize - 1];
1752 copy_dst[11] = ptr[4 * x - 1];
1753 copy_dst[19] = ptr[4 * x +
s->linesize - 1];
1754 copy_dst[27] = ptr[4 * x +
s->linesize * 2 - 1];
1755 copy_dst[35] = ptr[4 * x +
s->linesize * 3 - 1];
1758 s->hpc.pred4x4[
mode](dst, topright, linesize);
1761 AV_COPY32(ptr + 4 * x +
s->linesize, copy_dst + 20);
1762 AV_COPY32(ptr + 4 * x +
s->linesize * 2, copy_dst + 28);
1763 AV_COPY32(ptr + 4 * x +
s->linesize * 3, copy_dst + 36);
1766 nnz =
td->non_zero_count_cache[y][x];
1769 s->vp8dsp.vp8_idct_dc_add(ptr + 4 * x,
1770 td->block[y][x],
s->linesize);
1772 s->vp8dsp.vp8_idct_add(ptr + 4 * x,
1773 td->block[y][x],
s->linesize);
1778 ptr += 4 *
s->linesize;
1784 mb_x, mb_y, is_vp7);
1785 s->hpc.pred8x8[
mode](dst[1],
s->uvlinesize);
1786 s->hpc.pred8x8[
mode](dst[2],
s->uvlinesize);
1788 if (mb_y && (
s->deblock_filter || !mb_y) &&
td->thread_nr == 0)
1790 s->linesize,
s->uvlinesize, mb_x, mb_y,
s->mb_width,
1791 s->filter.simple, 0);
1795 { 0, 1, 2, 1, 2, 1, 2, 1 },
1797 { 0, 3, 5, 3, 5, 3, 5, 3 },
1798 { 0, 2, 3, 2, 3, 2, 3, 2 },
1820 int x_off,
int y_off,
int block_w,
int block_h,
1824 const uint8_t *
src =
ref->f->data[0];
1827 ptrdiff_t src_linesize = linesize;
1832 x_off +=
mv->x >> 2;
1833 y_off +=
mv->y >> 2;
1837 src += y_off * linesize + x_off;
1840 s->vdsp.emulated_edge_mc(
td->edge_emu_buffer,
1841 src - my_idx * linesize - mx_idx,
1845 x_off - mx_idx, y_off - my_idx,
1850 mc_func[my_idx][mx_idx](dst, linesize,
src, src_linesize, block_h, mx, my);
1853 mc_func[0][0](dst, linesize,
src + y_off * linesize + x_off,
1854 linesize, block_h, 0, 0);
1878 int x_off,
int y_off,
int block_w,
int block_h,
1888 x_off +=
mv->x >> 3;
1889 y_off +=
mv->y >> 3;
1892 src1 += y_off * linesize + x_off;
1893 src2 += y_off * linesize + x_off;
1897 s->vdsp.emulated_edge_mc(
td->edge_emu_buffer,
1898 src1 - my_idx * linesize - mx_idx,
1906 s->vdsp.emulated_edge_mc(
td->edge_emu_buffer,
1907 src2 - my_idx * linesize - mx_idx,
1915 mc_func[my_idx][mx_idx](dst1, linesize,
src1, linesize, block_h, mx, my);
1916 mc_func[my_idx][mx_idx](dst2, linesize,
src2, linesize, block_h, mx, my);
1920 mc_func[0][0](dst1, linesize,
src1 + y_off * linesize + x_off, linesize, block_h, 0, 0);
1921 mc_func[0][0](dst2, linesize,
src2 + y_off * linesize + x_off, linesize, block_h, 0, 0);
1928 int bx_off,
int by_off,
int block_w,
int block_h,
1937 s->put_pixels_tab[block_w == 8]);
1940 if (
s->profile == 3) {
1955 dst[2] + by_off *
s->uvlinesize + bx_off,
ref_frame,
1956 &uvmv, x_off + bx_off, y_off + by_off,
1958 s->put_pixels_tab[1 + (block_w == 4)]);
1965 int mb_x,
int mb_y,
int mb_xy,
int ref)
1968 if (
s->ref_count[
ref - 1] > (mb_xy >> 5)) {
1969 int x_off = mb_x << 4, y_off = mb_y << 4;
1970 int mx = (
mb->mv.x >> 2) + x_off + 8;
1971 int my = (
mb->mv.y >> 2) + y_off;
1972 uint8_t **
src =
s->framep[
ref]->tf.f->data;
1973 int off = mx + (my + (mb_x & 3) * 4) *
s->linesize + 64;
1977 s->vdsp.prefetch(
src[0] + off,
s->linesize, 4);
1978 off = (mx >> 1) + ((my >> 1) + (mb_x & 7)) *
s->uvlinesize + 64;
1979 s->vdsp.prefetch(
src[1] + off,
src[2] -
src[1], 2);
1990 int x_off = mb_x << 4, y_off = mb_y << 4;
1995 switch (
mb->partitioning) {
2005 for (y = 0; y < 4; y++) {
2006 for (x = 0; x < 4; x++) {
2008 ref, &bmv[4 * y + x],
2009 4 * x + x_off, 4 * y + y_off, 4, 4,
2011 s->put_pixels_tab[2]);
2020 for (y = 0; y < 2; y++) {
2021 for (x = 0; x < 2; x++) {
2022 uvmv.
x =
mb->bmv[2 * y * 4 + 2 * x ].x +
2023 mb->bmv[2 * y * 4 + 2 * x + 1].x +
2024 mb->bmv[(2 * y + 1) * 4 + 2 * x ].x +
2025 mb->bmv[(2 * y + 1) * 4 + 2 * x + 1].x;
2026 uvmv.
y =
mb->bmv[2 * y * 4 + 2 * x ].y +
2027 mb->bmv[2 * y * 4 + 2 * x + 1].y +
2028 mb->bmv[(2 * y + 1) * 4 + 2 * x ].y +
2029 mb->bmv[(2 * y + 1) * 4 + 2 * x + 1].y;
2032 if (
s->profile == 3) {
2037 dst[2] + 4 * y *
s->uvlinesize + x * 4,
ref,
2038 &uvmv, 4 * x + x_off, 4 * y + y_off, 4, 4,
2040 s->put_pixels_tab[2]);
2077 uint8_t *y_dst = dst[0];
2078 for (y = 0; y < 4; y++) {
2079 uint32_t nnz4 =
AV_RL32(
td->non_zero_count_cache[y]);
2081 if (nnz4 & ~0x01010101) {
2082 for (x = 0; x < 4; x++) {
2083 if ((uint8_t) nnz4 == 1)
2084 s->vp8dsp.vp8_idct_dc_add(y_dst + 4 * x,
2087 else if ((uint8_t) nnz4 > 1)
2088 s->vp8dsp.vp8_idct_add(y_dst + 4 * x,
2096 s->vp8dsp.vp8_idct_dc_add4y(y_dst,
td->block[y],
s->linesize);
2099 y_dst += 4 *
s->linesize;
2103 for (ch = 0; ch < 2; ch++) {
2104 uint32_t nnz4 =
AV_RL32(
td->non_zero_count_cache[4 + ch]);
2106 uint8_t *ch_dst = dst[1 + ch];
2107 if (nnz4 & ~0x01010101) {
2108 for (y = 0; y < 2; y++) {
2109 for (x = 0; x < 2; x++) {
2110 if ((uint8_t) nnz4 == 1)
2111 s->vp8dsp.vp8_idct_dc_add(ch_dst + 4 * x,
2112 td->block[4 + ch][(y << 1) + x],
2114 else if ((uint8_t) nnz4 > 1)
2115 s->vp8dsp.vp8_idct_add(ch_dst + 4 * x,
2116 td->block[4 + ch][(y << 1) + x],
2120 goto chroma_idct_end;
2122 ch_dst += 4 *
s->uvlinesize;
2125 s->vp8dsp.vp8_idct_dc_add4uv(ch_dst,
td->block[4 + ch],
s->uvlinesize);
2137 int interior_limit, filter_level;
2139 if (
s->segmentation.enabled) {
2140 filter_level =
s->segmentation.filter_level[
mb->segment];
2141 if (!
s->segmentation.absolute_vals)
2142 filter_level +=
s->filter.level;
2144 filter_level =
s->filter.level;
2146 if (
s->lf_delta.enabled) {
2147 filter_level +=
s->lf_delta.ref[
mb->ref_frame];
2148 filter_level +=
s->lf_delta.mode[
mb->mode];
2153 interior_limit = filter_level;
2154 if (
s->filter.sharpness) {
2155 interior_limit >>= (
s->filter.sharpness + 3) >> 2;
2156 interior_limit =
FFMIN(interior_limit, 9 -
s->filter.sharpness);
2158 interior_limit =
FFMAX(interior_limit, 1);
2160 f->filter_level = filter_level;
2161 f->inner_limit = interior_limit;
2162 f->inner_filter = is_vp7 || !
mb->skip ||
mb->mode ==
MODE_I4x4 ||
2168 int mb_x,
int mb_y,
int is_vp7)
2170 int mbedge_lim, bedge_lim_y, bedge_lim_uv, hev_thresh;
2171 int filter_level =
f->filter_level;
2172 int inner_limit =
f->inner_limit;
2173 int inner_filter =
f->inner_filter;
2174 ptrdiff_t linesize =
s->linesize;
2175 ptrdiff_t uvlinesize =
s->uvlinesize;
2176 static const uint8_t hev_thresh_lut[2][64] = {
2177 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1,
2178 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2179 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
2181 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1,
2182 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2183 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2191 bedge_lim_y = filter_level;
2192 bedge_lim_uv = filter_level * 2;
2193 mbedge_lim = filter_level + 2;
2196 bedge_lim_uv = filter_level * 2 + inner_limit;
2197 mbedge_lim = bedge_lim_y + 4;
2200 hev_thresh = hev_thresh_lut[
s->keyframe][filter_level];
2203 s->vp8dsp.vp8_h_loop_filter16y(dst[0], linesize,
2204 mbedge_lim, inner_limit, hev_thresh);
2205 s->vp8dsp.vp8_h_loop_filter8uv(dst[1], dst[2], uvlinesize,
2206 mbedge_lim, inner_limit, hev_thresh);
2209 #define H_LOOP_FILTER_16Y_INNER(cond) \
2210 if (cond && inner_filter) { \
2211 s->vp8dsp.vp8_h_loop_filter16y_inner(dst[0] + 4, linesize, \
2212 bedge_lim_y, inner_limit, \
2214 s->vp8dsp.vp8_h_loop_filter16y_inner(dst[0] + 8, linesize, \
2215 bedge_lim_y, inner_limit, \
2217 s->vp8dsp.vp8_h_loop_filter16y_inner(dst[0] + 12, linesize, \
2218 bedge_lim_y, inner_limit, \
2220 s->vp8dsp.vp8_h_loop_filter8uv_inner(dst[1] + 4, dst[2] + 4, \
2221 uvlinesize, bedge_lim_uv, \
2222 inner_limit, hev_thresh); \
2228 s->vp8dsp.vp8_v_loop_filter16y(dst[0], linesize,
2229 mbedge_lim, inner_limit, hev_thresh);
2230 s->vp8dsp.vp8_v_loop_filter8uv(dst[1], dst[2], uvlinesize,
2231 mbedge_lim, inner_limit, hev_thresh);
2235 s->vp8dsp.vp8_v_loop_filter16y_inner(dst[0] + 4 * linesize,
2236 linesize, bedge_lim_y,
2237 inner_limit, hev_thresh);
2238 s->vp8dsp.vp8_v_loop_filter16y_inner(dst[0] + 8 * linesize,
2239 linesize, bedge_lim_y,
2240 inner_limit, hev_thresh);
2241 s->vp8dsp.vp8_v_loop_filter16y_inner(dst[0] + 12 * linesize,
2242 linesize, bedge_lim_y,
2243 inner_limit, hev_thresh);
2244 s->vp8dsp.vp8_v_loop_filter8uv_inner(dst[1] + 4 * uvlinesize,
2245 dst[2] + 4 * uvlinesize,
2246 uvlinesize, bedge_lim_uv,
2247 inner_limit, hev_thresh);
2257 int mbedge_lim, bedge_lim;
2258 int filter_level =
f->filter_level;
2259 int inner_limit =
f->inner_limit;
2260 int inner_filter =
f->inner_filter;
2261 ptrdiff_t linesize =
s->linesize;
2266 bedge_lim = 2 * filter_level + inner_limit;
2267 mbedge_lim = bedge_lim + 4;
2270 s->vp8dsp.vp8_h_loop_filter_simple(dst, linesize, mbedge_lim);
2272 s->vp8dsp.vp8_h_loop_filter_simple(dst + 4, linesize, bedge_lim);
2273 s->vp8dsp.vp8_h_loop_filter_simple(dst + 8, linesize, bedge_lim);
2274 s->vp8dsp.vp8_h_loop_filter_simple(dst + 12, linesize, bedge_lim);
2278 s->vp8dsp.vp8_v_loop_filter_simple(dst, linesize, mbedge_lim);
2280 s->vp8dsp.vp8_v_loop_filter_simple(dst + 4 * linesize, linesize, bedge_lim);
2281 s->vp8dsp.vp8_v_loop_filter_simple(dst + 8 * linesize, linesize, bedge_lim);
2282 s->vp8dsp.vp8_v_loop_filter_simple(dst + 12 * linesize, linesize, bedge_lim);
2286 #define MARGIN (16 << 2)
2289 const VP8Frame *prev_frame,
int is_vp7)
2294 s->mv_bounds.mv_min.y = -
MARGIN;
2295 s->mv_bounds.mv_max.y = ((
s->mb_height - 1) << 6) +
MARGIN;
2296 for (mb_y = 0; mb_y <
s->mb_height; mb_y++) {
2298 ((
s->mb_width + 1) * (mb_y + 1) + 1);
2299 int mb_xy = mb_y *
s->mb_width;
2303 s->mv_bounds.mv_min.x = -
MARGIN;
2304 s->mv_bounds.mv_max.x = ((
s->mb_width - 1) << 6) +
MARGIN;
2306 for (mb_x = 0; mb_x <
s->mb_width; mb_x++, mb_xy++,
mb++) {
2311 AV_WN32A((
mb -
s->mb_width - 1)->intra4x4_pred_mode_top,
2314 prev_frame && prev_frame->
seg_map ?
2316 s->mv_bounds.mv_min.x -= 64;
2317 s->mv_bounds.mv_max.x -= 64;
2319 s->mv_bounds.mv_min.y -= 64;
2320 s->mv_bounds.mv_max.y -= 64;
2338 #define check_thread_pos(td, otd, mb_x_check, mb_y_check) \
2340 int tmp = (mb_y_check << 16) | (mb_x_check & 0xFFFF); \
2341 if (atomic_load(&otd->thread_mb_pos) < tmp) { \
2342 pthread_mutex_lock(&otd->lock); \
2343 atomic_store(&td->wait_mb_pos, tmp); \
2345 if (atomic_load(&otd->thread_mb_pos) >= tmp) \
2347 pthread_cond_wait(&otd->cond, &otd->lock); \
2349 atomic_store(&td->wait_mb_pos, INT_MAX); \
2350 pthread_mutex_unlock(&otd->lock); \
2354 #define update_pos(td, mb_y, mb_x) \
2356 int pos = (mb_y << 16) | (mb_x & 0xFFFF); \
2357 int sliced_threading = (avctx->active_thread_type == FF_THREAD_SLICE) && \
2359 int is_null = !next_td || !prev_td; \
2360 int pos_check = (is_null) ? 1 : \
2361 (next_td != td && pos >= atomic_load(&next_td->wait_mb_pos)) || \
2362 (prev_td != td && pos >= atomic_load(&prev_td->wait_mb_pos)); \
2363 atomic_store(&td->thread_mb_pos, pos); \
2364 if (sliced_threading && pos_check) { \
2365 pthread_mutex_lock(&td->lock); \
2366 pthread_cond_broadcast(&td->cond); \
2367 pthread_mutex_unlock(&td->lock); \
2371 #define check_thread_pos(td, otd, mb_x_check, mb_y_check) while(0)
2372 #define update_pos(td, mb_y, mb_x) while(0)
2376 int jobnr,
int threadnr,
int is_vp7)
2381 int mb_x, mb_xy = mb_y *
s->mb_width;
2382 int num_jobs =
s->num_jobs;
2383 const VP8Frame *prev_frame =
s->prev_frame;
2385 VPXRangeCoder *coeff_c = &
s->coeff_partition[mb_y & (
s->num_coeff_partitions - 1)];
2389 curframe->
tf.
f->
data[0] + 16 * mb_y *
s->linesize,
2390 curframe->
tf.
f->
data[1] + 8 * mb_y *
s->uvlinesize,
2391 curframe->
tf.
f->
data[2] + 8 * mb_y *
s->uvlinesize
2400 prev_td = &
s->thread_data[(jobnr + num_jobs - 1) % num_jobs];
2401 if (mb_y ==
s->mb_height - 1)
2404 next_td = &
s->thread_data[(jobnr + 1) % num_jobs];
2405 if (
s->mb_layout == 1)
2406 mb =
s->macroblocks_base + ((
s->mb_width + 1) * (mb_y + 1) + 1);
2410 if (prev_frame &&
s->segmentation.enabled &&
2411 !
s->segmentation.update_map)
2413 mb =
s->macroblocks + (
s->mb_height - mb_y - 1) * 2;
2414 memset(
mb - 1, 0,
sizeof(*
mb));
2418 if (!is_vp7 || mb_y == 0)
2419 memset(
td->left_nnz, 0,
sizeof(
td->left_nnz));
2422 td->mv_bounds.mv_max.x = ((
s->mb_width - 1) << 6) +
MARGIN;
2424 for (mb_x = 0; mb_x <
s->mb_width; mb_x++, mb_xy++,
mb++) {
2428 if (prev_td !=
td) {
2429 if (threadnr != 0) {
2431 mb_x + (is_vp7 ? 2 : 1),
2432 mb_y - (is_vp7 ? 2 : 1));
2435 mb_x + (is_vp7 ? 2 : 1) +
s->mb_width + 3,
2436 mb_y - (is_vp7 ? 2 : 1));
2440 s->vdsp.prefetch(dst[0] + (mb_x & 3) * 4 *
s->linesize + 64,
2442 s->vdsp.prefetch(dst[1] + (mb_x & 7) *
s->uvlinesize + 64,
2443 dst[2] - dst[1], 2);
2447 prev_frame && prev_frame->
seg_map ?
2474 td->left_nnz[8] = 0;
2475 s->top_nnz[mb_x][8] = 0;
2479 if (
s->deblock_filter)
2482 if (
s->deblock_filter && num_jobs != 1 && threadnr == num_jobs - 1) {
2483 if (
s->filter.simple)
2488 dst[1], dst[2],
s->linesize,
s->uvlinesize, 0);
2496 td->mv_bounds.mv_min.x -= 64;
2497 td->mv_bounds.mv_max.x -= 64;
2499 if (mb_x ==
s->mb_width + 1) {
2509 int jobnr,
int threadnr)
2515 int jobnr,
int threadnr)
2521 int jobnr,
int threadnr,
int is_vp7)
2525 int mb_x, mb_y =
atomic_load(&
td->thread_mb_pos) >> 16, num_jobs =
s->num_jobs;
2526 AVFrame *curframe =
s->curframe->tf.f;
2530 curframe->
data[0] + 16 * mb_y *
s->linesize,
2531 curframe->
data[1] + 8 * mb_y *
s->uvlinesize,
2532 curframe->
data[2] + 8 * mb_y *
s->uvlinesize
2535 if (
s->mb_layout == 1)
2536 mb =
s->macroblocks_base + ((
s->mb_width + 1) * (mb_y + 1) + 1);
2538 mb =
s->macroblocks + (
s->mb_height - mb_y - 1) * 2;
2543 prev_td = &
s->thread_data[(jobnr + num_jobs - 1) % num_jobs];
2544 if (mb_y ==
s->mb_height - 1)
2547 next_td = &
s->thread_data[(jobnr + 1) % num_jobs];
2549 for (mb_x = 0; mb_x <
s->mb_width; mb_x++,
mb++) {
2553 (mb_x + 1) + (
s->mb_width + 3), mb_y - 1);
2555 if (next_td != &
s->thread_data[0])
2558 if (num_jobs == 1) {
2559 if (
s->filter.simple)
2564 dst[1], dst[2],
s->linesize,
s->uvlinesize, 0);
2567 if (
s->filter.simple)
2580 int jobnr,
int threadnr)
2586 int jobnr,
int threadnr)
2593 int threadnr,
int is_vp7)
2599 int mb_y, num_jobs =
s->num_jobs;
2602 td->thread_nr = threadnr;
2603 td->mv_bounds.mv_min.y = -
MARGIN - 64 * threadnr;
2604 td->mv_bounds.mv_max.y = ((
s->mb_height - 1) << 6) +
MARGIN - 64 * threadnr;
2605 for (mb_y = jobnr; mb_y <
s->mb_height; mb_y += num_jobs) {
2607 ret =
s->decode_mb_row_no_filter(avctx, tdata, jobnr, threadnr);
2612 if (
s->deblock_filter)
2613 s->filter_mb_row(avctx, tdata, jobnr, threadnr);
2616 td->mv_bounds.mv_min.y -= 64 * num_jobs;
2617 td->mv_bounds.mv_max.y -= 64 * num_jobs;
2627 int jobnr,
int threadnr)
2633 int jobnr,
int threadnr)
2643 int ret,
i, referenced, num_jobs;
2655 if (!is_vp7 &&
s->actually_webp) {
2663 if (
s->pix_fmt < 0) {
2681 memcpy(&
s->next_framep[0], &
s->framep[0],
sizeof(
s->framep[0]) * 4);
2687 for (
i = 0;
i < 5;
i++)
2688 if (
s->frames[
i].tf.f &&
2689 &
s->frames[
i] != prev_frame &&
2712 "Discarding interframe without a prior keyframe!\n");
2744 if (!is_vp7 && !
s->actually_webp)
2762 s->linesize = curframe->tf.f->linesize[0];
2763 s->uvlinesize = curframe->tf.f->linesize[1];
2765 memset(
s->top_nnz, 0,
s->mb_width *
sizeof(*
s->top_nnz));
2769 memset(
s->macroblocks +
s->mb_height * 2 - 1, 0,
2770 (
s->mb_width + 1) *
sizeof(*
s->macroblocks));
2771 if (!
s->mb_layout &&
s->keyframe)
2772 memset(
s->intra4x4_pred_mode_top,
DC_PRED,
s->mb_width * 4);
2774 memset(
s->ref_count, 0,
sizeof(
s->ref_count));
2776 if (
s->mb_layout == 1) {
2779 if (prev_frame &&
s->segmentation.enabled &&
2780 !
s->segmentation.update_map)
2794 s->num_jobs = num_jobs;
2795 s->curframe = curframe;
2796 s->prev_frame = prev_frame;
2797 s->mv_bounds.mv_min.y = -
MARGIN;
2798 s->mv_bounds.mv_max.y = ((
s->mb_height - 1) << 6) +
MARGIN;
2813 memcpy(&
s->framep[0], &
s->next_framep[0],
sizeof(
s->framep[0]) * 4);
2818 if (!
s->update_probabilities)
2819 s->prob[0] =
s->prob[1];
2821 if (!
s->invisible) {
2829 memcpy(&
s->next_framep[0], &
s->framep[0],
sizeof(
s->framep[0]) * 4);
2839 #if CONFIG_VP7_DECODER
2866 if (CONFIG_VP7_DECODER && is_vp7) {
2871 }
else if (CONFIG_VP8_DECODER && !is_vp7) {
2884 #if CONFIG_VP7_DECODER
2896 #if CONFIG_VP8_DECODER
2903 src->hwaccel_picture_private);
2906 #define REBASE(pic) ((pic) ? (pic) - &s_src->frames[0] + &s->frames[0] : NULL)
2913 if (
s->macroblocks_base &&
2914 (s_src->mb_width !=
s->mb_width || s_src->mb_height !=
s->mb_height)) {
2916 s->mb_width = s_src->mb_width;
2917 s->mb_height = s_src->mb_height;
2920 s->pix_fmt = s_src->pix_fmt;
2921 s->prob[0] = s_src->prob[!s_src->update_probabilities];
2922 s->segmentation = s_src->segmentation;
2923 s->lf_delta = s_src->lf_delta;
2924 memcpy(
s->sign_bias, s_src->sign_bias,
sizeof(
s->sign_bias));
2927 vp8_replace_frame(&
s->frames[
i], &s_src->frames[
i]);
2929 s->framep[0] = REBASE(s_src->next_framep[0]);
2930 s->framep[1] = REBASE(s_src->next_framep[1]);
2931 s->framep[2] = REBASE(s_src->next_framep[2]);
2932 s->framep[3] = REBASE(s_src->next_framep[3]);
2939 #if CONFIG_VP7_DECODER
2946 .
init = vp7_decode_init,
2955 #if CONFIG_VP8_DECODER
2971 #if CONFIG_VP8_VAAPI_HWACCEL
2974 #if CONFIG_VP8_NVDEC_HWACCEL
static const int vp8_mode_contexts[6][4]
static const uint8_t vp8_dct_cat1_prob[]
void ff_progress_frame_report(ProgressFrame *f, int n)
Notify later decoding threads when part of their reference frame is ready.
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 void vp8_release_frame(VP8Frame *f)
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.
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]
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 ff_vp8_token_update_probs[4][8][3][11]
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[]
static av_always_inline void vp8_mc_chroma(VP8Context *s, VP8ThreadData *td, uint8_t *dst1, uint8_t *dst2, const ProgressFrame *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
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])
int ff_progress_frame_get_buffer(AVCodecContext *avctx, ProgressFrame *f, int flags)
This function sets up the ProgressFrame, i.e.
static void vp8_get_quants(VP8Context *s)
#define FF_HW_SIMPLE_CALL(avctx, function)
static av_cold void vp8_decode_flush(AVCodecContext *avctx)
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
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
static av_cold void vp8_decode_flush_impl(AVCodecContext *avctx, int free_mem)
AVCodec p
The public AVCodec.
static int ref_frame(VVCFrame *dst, const VVCFrame *src)
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)
#define FF_CODEC_CAP_USES_PROGRESSFRAMES
The decoder might make use of the ProgressFrame API.
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[]
#define AV_FRAME_FLAG_KEY
A flag to mark frames that are keyframes.
#define LOCAL_ALIGNED(a, t, v,...)
static const uint8_t vp8_pred4x4_mode[]
#define FF_CODEC_DECODE_CB(func)
int ff_hwaccel_frame_priv_alloc(AVCodecContext *avctx, void **hwaccel_picture_private)
Allocate a hwaccel frame private data if the provided avctx uses a hwaccel method that needs it.
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.
static av_always_inline void vp8_mc_luma(VP8Context *s, VP8ThreadData *td, uint8_t *dst, const ProgressFrame *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
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]
void ff_progress_frame_unref(ProgressFrame *f)
Give up a reference to the underlying frame contained in a ProgressFrame and reset the ProgressFrame,...
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_progress_frame_await() 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_progress_frame_report() has been called on them. This includes draw_edges(). Porting codecs to frame threading
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)
uint8_t * seg_map
RefStruct reference.
static av_always_inline void vp8_mc_part(VP8Context *s, VP8ThreadData *td, uint8_t *const dst[3], const ProgressFrame *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 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]
#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.
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)
@ AV_PICTURE_TYPE_I
Intra.
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(* flush)(AVBSFContext *ctx)
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 void * ff_refstruct_allocz(size_t size)
Equivalent to ff_refstruct_alloc_ext(size, 0, NULL, NULL)
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)
#define FF_HW_HAS_CB(avctx, function)
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
int(* init)(AVBSFContext *ctx)
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 free_buffers(VP8Context *s)
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.
const uint8_t *const ff_vp8_dct_cat_prob[]
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)
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.
@ 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)
#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,...)
static const char * hwaccel
int ff_vpx_init_range_decoder(VPXRangeCoder *c, const uint8_t *buf, int buf_size)
void ff_refstruct_replace(void *dstp, const void *src)
Ensure *dstp refers to the same object as src.
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
void ff_progress_frame_replace(ProgressFrame *dst, const ProgressFrame *src)
Do nothing if dst and src already refer to the same AVFrame; otherwise unreference dst and if src is ...
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.
static const FFHWAccel * ffhwaccel(const AVHWAccel *codec)
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)
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)
The ProgressFrame structure.
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)
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.
void ff_refstruct_unref(void *objp)
Decrement the reference count of the underlying object and automatically free the object if there are...
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
RefStruct reference.