Go to the documentation of this file.
27 #include "config_components.h"
100 s->macroblocks =
NULL;
130 #if CONFIG_VP8_DECODER
141 src->hwaccel_picture_private);
154 memset(
s->framep, 0,
sizeof(
s->framep));
174 for (
i = 0;
i < 5;
i++)
195 #if CONFIG_VP8_VAAPI_HWACCEL
198 #if CONFIG_VP8_NVDEC_HWACCEL
212 int i,
ret, dim_reset = 0;
214 if (
width !=
s->avctx->width || ((
width+15)/16 !=
s->mb_width || (
height+15)/16 !=
s->mb_height) &&
s->macroblocks_base ||
222 dim_reset = (
s->macroblocks_base !=
NULL);
226 !
s->actually_webp && !is_vp7) {
233 s->mb_width = (
s->avctx->coded_width + 15) / 16;
234 s->mb_height = (
s->avctx->coded_height + 15) / 16;
239 s->macroblocks_base =
av_mallocz((
s->mb_width +
s->mb_height * 2 + 1) *
240 sizeof(*
s->macroblocks));
241 s->intra4x4_pred_mode_top =
av_mallocz(
s->mb_width * 4);
243 s->macroblocks_base =
av_mallocz((
s->mb_width + 2) * (
s->mb_height + 2) *
244 sizeof(*
s->macroblocks));
246 s->top_border =
av_mallocz((
s->mb_width + 1) *
sizeof(*
s->top_border));
249 if (!
s->macroblocks_base || !
s->top_nnz || !
s->top_border ||
250 !
s->thread_data || (!
s->intra4x4_pred_mode_top && !
s->mb_layout)) {
256 s->thread_data[
i].filter_strength =
257 av_mallocz(
s->mb_width *
sizeof(*
s->thread_data[0].filter_strength));
258 if (!
s->thread_data[
i].filter_strength) {
268 s->macroblocks =
s->macroblocks_base + 1;
292 if (
s->segmentation.update_feature_data) {
295 for (
i = 0;
i < 4;
i++)
298 for (
i = 0;
i < 4;
i++)
301 if (
s->segmentation.update_map)
302 for (
i = 0;
i < 3;
i++)
311 for (
i = 0;
i < 4;
i++) {
316 s->lf_delta.ref[
i] = -
s->lf_delta.ref[
i];
325 s->lf_delta.mode[
i] = -
s->lf_delta.mode[
i];
332 const uint8_t *
sizes = buf;
338 buf += 3 * (
s->num_coeff_partitions - 1);
339 buf_size -= 3 * (
s->num_coeff_partitions - 1);
343 for (
i = 0;
i <
s->num_coeff_partitions - 1;
i++) {
345 if (buf_size -
size < 0)
347 s->coeff_partition_size[
i] =
size;
356 s->coeff_partition_size[
i] = buf_size;
393 for (
i = 0;
i < 4;
i++) {
394 if (
s->segmentation.enabled) {
395 base_qi =
s->segmentation.base_quant[
i];
396 if (!
s->segmentation.absolute_vals)
397 base_qi +=
s->quant.yac_qi;
399 base_qi =
s->quant.yac_qi;
409 s->qmat[
i].luma_dc_qmul[1] =
FFMAX(
s->qmat[
i].luma_dc_qmul[1], 8);
410 s->qmat[
i].chroma_qmul[0] =
FFMIN(
s->qmat[
i].chroma_qmul[0], 132);
446 for (
i = 0;
i < 4;
i++)
447 for (j = 0; j < 16; j++)
449 sizeof(
s->prob->token[
i][j]));
457 for (
i = 0;
i < 4;
i++)
458 for (j = 0; j < 8; j++)
459 for (k = 0; k < 3; k++)
468 #define VP7_MVC_SIZE 17
469 #define VP8_MVC_SIZE 19
478 for (
i = 0;
i < 4;
i++)
481 for (
i = 0;
i < 3;
i++)
485 for (
i = 0;
i < 2;
i++)
486 for (j = 0; j < mvc_size; j++)
506 for (j = 1; j < 3; j++) {
513 static void fade(uint8_t *dst, ptrdiff_t dst_linesize,
514 const uint8_t *
src, ptrdiff_t src_linesize,
519 for (j = 0; j <
height; j++) {
520 const uint8_t *
src2 =
src + j * src_linesize;
521 uint8_t *dst2 = dst + j * dst_linesize;
533 if (!
s->keyframe && (
alpha || beta)) {
534 int width =
s->mb_width * 16;
535 int height =
s->mb_height * 16;
560 src->data[0],
src->linesize[0],
570 int part1_size, hscale, vscale,
i, j,
ret;
571 int width =
s->avctx->width;
575 int fade_present = 1;
581 s->profile = (buf[0] >> 1) & 7;
582 if (
s->profile > 1) {
587 s->keyframe = !(buf[0] & 1);
589 part1_size =
AV_RL24(buf) >> 4;
591 if (buf_size < 4 - s->
profile + part1_size) {
592 av_log(
s->avctx,
AV_LOG_ERROR,
"Buffer size %d is too small, needed : %d\n", buf_size, 4 -
s->profile + part1_size);
596 buf += 4 -
s->profile;
597 buf_size -= 4 -
s->profile;
599 memcpy(
s->put_pixels_tab,
s->vp8dsp.put_vp8_epel_pixels_tab,
sizeof(
s->put_pixels_tab));
605 buf_size -= part1_size;
613 if (hscale || vscale)
619 sizeof(
s->prob->pred16x16));
621 sizeof(
s->prob->pred8x8c));
622 for (
i = 0;
i < 2;
i++)
625 memset(&
s->segmentation, 0,
sizeof(
s->segmentation));
626 memset(&
s->lf_delta, 0,
sizeof(
s->lf_delta));
630 if (
s->keyframe ||
s->profile > 0)
631 memset(
s->inter_dc_pred, 0 ,
sizeof(
s->inter_dc_pred));
634 for (
i = 0;
i < 4;
i++) {
636 if (
s->feature_enabled[
i]) {
639 for (j = 0; j < 3; j++)
640 s->feature_index_prob[
i][j] =
644 for (j = 0; j < 4; j++)
645 s->feature_value[
i][j] =
650 s->segmentation.enabled = 0;
651 s->segmentation.update_map = 0;
652 s->lf_delta.enabled = 0;
654 s->num_coeff_partitions = 1;
659 if (!
s->macroblocks_base ||
661 (
width + 15) / 16 !=
s->mb_width || (
height + 15) / 16 !=
s->mb_height) {
676 s->update_probabilities = 1;
678 if (
s->profile > 0) {
680 if (!
s->update_probabilities)
681 s->prob[1] =
s->prob[0];
701 for (
i = 1;
i < 16;
i++)
713 s->mbskip_enabled = 0;
734 int header_size, hscale, vscale,
ret;
735 int width =
s->avctx->width;
743 s->keyframe = !(buf[0] & 1);
744 s->profile = (buf[0]>>1) & 7;
745 s->invisible = !(buf[0] & 0x10);
746 header_size =
AV_RL24(buf) >> 5;
750 s->header_partition_size = header_size;
756 memcpy(
s->put_pixels_tab,
s->vp8dsp.put_vp8_epel_pixels_tab,
757 sizeof(
s->put_pixels_tab));
759 memcpy(
s->put_pixels_tab,
s->vp8dsp.put_vp8_bilinear_pixels_tab,
760 sizeof(
s->put_pixels_tab));
762 if (header_size > buf_size - 7 *
s->keyframe) {
768 if (
AV_RL24(buf) != 0x2a019d) {
770 "Invalid start code 0x%x\n",
AV_RL24(buf));
775 hscale = buf[4] >> 6;
776 vscale = buf[6] >> 6;
780 if (hscale || vscale)
786 sizeof(
s->prob->pred16x16));
788 sizeof(
s->prob->pred8x8c));
790 sizeof(
s->prob->mvc));
791 memset(&
s->segmentation, 0,
sizeof(
s->segmentation));
792 memset(&
s->lf_delta, 0,
sizeof(
s->lf_delta));
799 buf_size -= header_size;
811 s->segmentation.update_map = 0;
819 if (
s->lf_delta.update)
828 if (!
s->macroblocks_base ||
830 (
width+15)/16 !=
s->mb_width || (
height+15)/16 !=
s->mb_height)
845 s->prob[1] =
s->prob[0];
863 s->coder_state_at_header_end.input =
s->c.buffer - (-
s->c.bits / 8);
864 s->coder_state_at_header_end.range =
s->c.high;
865 s->coder_state_at_header_end.value =
s->c.code_word >> 16;
866 s->coder_state_at_header_end.bit_count = -
s->c.bits % 8;
875 av_clip(
s->mv_max.x, INT16_MIN, INT16_MAX));
877 av_clip(
s->mv_max.y, INT16_MIN, INT16_MAX));
890 for (
i = 0;
i < 3;
i++)
892 for (
i = (vp7 ? 7 : 9);
i > 3;
i--)
898 const uint8_t *ps = p + 2;
947 const uint8_t *mbsplits_top, *mbsplits_cur, *firstidx;
949 const VP8mv *left_mv = left_mb->
bmv;
955 top_mb = &
mb[-
s->mb_width - 1];
957 top_mv = top_mb->
bmv;
971 mb->partitioning = part_idx;
973 for (n = 0; n < num; n++) {
975 uint32_t
left, above;
976 const uint8_t *submv_prob;
983 above =
AV_RN32A(&top_mv[mbsplits_top[k + 12]]);
985 above =
AV_RN32A(&cur_mv[mbsplits_cur[k - 4]]);
992 mb->bmv[n].y =
mb->mv.y +
994 mb->bmv[n].x =
mb->mv.x +
1022 int xoffset,
int yoffset,
int boundary,
1023 int *edge_x,
int *edge_y)
1025 int vwidth = mb_width + 1;
1026 int new = (mb_y + yoffset) * vwidth + mb_x + xoffset;
1027 if (
new < boundary ||
new % vwidth == vwidth - 1)
1029 *edge_y =
new / vwidth;
1030 *edge_x =
new % vwidth;
1041 int mb_x,
int mb_y,
int layout)
1043 enum { CNT_ZERO, CNT_NEAREST, CNT_NEAR };
1044 enum { VP8_EDGE_TOP, VP8_EDGE_LEFT, VP8_EDGE_TOPLEFT };
1047 uint8_t cnt[3] = { 0 };
1060 pred->yoffset, !
s->profile, &edge_x, &edge_y)) {
1062 ?
s->macroblocks_base + 1 + edge_x +
1063 (
s->mb_width + 1) * (edge_y + 1)
1064 :
s->macroblocks + edge_x +
1065 (
s->mb_height - edge_y - 1) * 2;
1068 if (
AV_RN32A(&near_mv[CNT_NEAREST])) {
1071 }
else if (
AV_RN32A(&near_mv[CNT_NEAR])) {
1101 if (cnt[CNT_NEAREST] > cnt[CNT_NEAR])
1102 AV_WN32A(&
mb->mv, cnt[CNT_ZERO] > cnt[CNT_NEAREST] ? 0 :
AV_RN32A(&near_mv[CNT_NEAREST]));
1112 mb->bmv[0] =
mb->mv;
1115 mb->mv = near_mv[CNT_NEAR];
1116 mb->bmv[0] =
mb->mv;
1119 mb->mv = near_mv[CNT_NEAREST];
1120 mb->bmv[0] =
mb->mv;
1125 mb->bmv[0] =
mb->mv;
1131 int mb_x,
int mb_y,
int layout)
1136 enum { CNT_ZERO, CNT_NEAREST, CNT_NEAR, CNT_SPLITMV };
1137 enum { VP8_EDGE_TOP, VP8_EDGE_LEFT, VP8_EDGE_TOPLEFT };
1139 int cur_sign_bias =
s->sign_bias[
mb->ref_frame];
1140 const int8_t *sign_bias =
s->sign_bias;
1142 uint8_t cnt[4] = { 0 };
1146 mb_edge[0] =
mb + 2;
1147 mb_edge[2] =
mb + 1;
1149 mb_edge[0] =
mb -
s->mb_width - 1;
1150 mb_edge[2] =
mb -
s->mb_width - 2;
1158 #define MV_EDGE_CHECK(n) \
1160 const VP8Macroblock *edge = mb_edge[n]; \
1161 int edge_ref = edge->ref_frame; \
1162 if (edge_ref != VP8_FRAME_CURRENT) { \
1163 uint32_t mv = AV_RN32A(&edge->mv); \
1165 if (cur_sign_bias != sign_bias[edge_ref]) { \
1168 mv = ((mv & 0x7fff7fff) + \
1169 0x00010001) ^ (mv & 0x80008000); \
1171 if (!n || mv != AV_RN32A(&near_mv[idx])) \
1172 AV_WN32A(&near_mv[++idx], mv); \
1173 cnt[idx] += 1 + (n != 2); \
1175 cnt[CNT_ZERO] += 1 + (n != 2); \
1188 if (cnt[CNT_SPLITMV] &&
1189 AV_RN32A(&near_mv[1 + VP8_EDGE_TOP]) ==
AV_RN32A(&near_mv[1 + VP8_EDGE_TOPLEFT]))
1190 cnt[CNT_NEAREST] += 1;
1193 if (cnt[CNT_NEAR] > cnt[CNT_NEAREST]) {
1194 FFSWAP(uint8_t, cnt[CNT_NEAREST], cnt[CNT_NEAR]);
1195 FFSWAP(
VP8mv, near_mv[CNT_NEAREST], near_mv[CNT_NEAR]);
1201 clamp_mv(mv_bounds, &
mb->mv, &near_mv[CNT_ZERO + (cnt[CNT_NEAREST] >= cnt[CNT_ZERO])]);
1212 mb->bmv[0] =
mb->mv;
1215 clamp_mv(mv_bounds, &
mb->mv, &near_mv[CNT_NEAR]);
1216 mb->bmv[0] =
mb->mv;
1219 clamp_mv(mv_bounds, &
mb->mv, &near_mv[CNT_NEAREST]);
1220 mb->bmv[0] =
mb->mv;
1225 mb->bmv[0] =
mb->mv;
1231 int mb_x,
int keyframe,
int layout)
1233 uint8_t *intra4x4 =
mb->intra4x4_pred_mode_mb;
1242 uint8_t *
const left =
s->intra4x4_pred_mode_left;
1244 top =
mb->intra4x4_pred_mode_top;
1246 top =
s->intra4x4_pred_mode_top + 4 * mb_x;
1247 for (y = 0; y < 4; y++) {
1248 for (x = 0; x < 4; x++) {
1252 left[y] = top[x] = *intra4x4;
1258 for (
i = 0;
i < 16;
i++)
1270 static const char *
const vp7_feature_name[] = {
"q-index",
1272 "partial-golden-update",
1277 for (
i = 0;
i < 4;
i++) {
1278 if (
s->feature_enabled[
i]) {
1281 s->feature_index_prob[
i]);
1283 "Feature %s present in macroblock (value 0x%x)\n",
1284 vp7_feature_name[
i],
s->feature_value[
i][
index]);
1288 }
else if (
s->segmentation.update_map) {
1291 }
else if (
s->segmentation.enabled)
1324 s->ref_count[
mb->ref_frame - 1]++;
1334 s->prob->pred16x16);
1360 int i,
const uint8_t *token_prob,
const int16_t qmul[2],
1361 const uint8_t scan[16],
int vp7)
1375 token_prob = probs[
i][0];
1383 token_prob = probs[
i + 1][1];
1403 int cat = (
a << 1) +
b;
1408 token_prob = probs[
i + 1][2];
1443 int i,
const uint8_t *token_prob,
1444 const int16_t qmul[2],
1445 const uint8_t scan[16])
1448 token_prob, qmul, scan,
IS_VP7);
1451 #ifndef vp8_decode_block_coeffs_internal
1455 int i,
const uint8_t *token_prob,
1456 const int16_t qmul[2])
1479 int i,
int zero_nhood,
const int16_t qmul[2],
1480 const uint8_t scan[16],
int vp7)
1482 const uint8_t *token_prob = probs[
i][zero_nhood];
1486 token_prob, qmul, scan)
1496 int i, x, y, luma_start = 0, luma_ctx = 3;
1497 int nnz_pred, nnz, nnz_total = 0;
1502 nnz_pred = t_nnz[8] + l_nnz[8];
1506 nnz_pred,
s->qmat[
segment].luma_dc_qmul,
1508 l_nnz[8] = t_nnz[8] = !!nnz;
1512 s->inter_dc_pred[
mb->ref_frame - 1]);
1519 s->vp8dsp.vp8_luma_dc_wht_dc(
td->block,
td->block_dc);
1521 s->vp8dsp.vp8_luma_dc_wht(
td->block,
td->block_dc);
1528 for (y = 0; y < 4; y++)
1529 for (x = 0; x < 4; x++) {
1530 nnz_pred = l_nnz[y] + t_nnz[x];
1532 s->prob->token[luma_ctx],
1533 luma_start, nnz_pred,
1535 s->prob[0].scan, is_vp7);
1538 td->non_zero_count_cache[y][x] = nnz + block_dc;
1539 t_nnz[x] = l_nnz[y] = !!nnz;
1546 for (
i = 4;
i < 6;
i++)
1547 for (y = 0; y < 2; y++)
1548 for (x = 0; x < 2; x++) {
1549 nnz_pred = l_nnz[
i + 2 * y] + t_nnz[
i + 2 * x];
1551 s->prob->token[2], 0, nnz_pred,
1553 s->prob[0].scan, is_vp7);
1554 td->non_zero_count_cache[
i][(y << 1) + x] = nnz;
1555 t_nnz[
i + 2 * x] = l_nnz[
i + 2 * y] = !!nnz;
1568 const uint8_t *src_cb,
const uint8_t *src_cr,
1569 ptrdiff_t linesize, ptrdiff_t uvlinesize,
int simple)
1571 AV_COPY128(top_border, src_y + 15 * linesize);
1573 AV_COPY64(top_border + 16, src_cb + 7 * uvlinesize);
1574 AV_COPY64(top_border + 24, src_cr + 7 * uvlinesize);
1580 uint8_t *src_cr, ptrdiff_t linesize, ptrdiff_t uvlinesize,
int mb_x,
1581 int mb_y,
int mb_width,
int simple,
int xchg)
1583 uint8_t *top_border_m1 = top_border - 32;
1585 src_cb -= uvlinesize;
1586 src_cr -= uvlinesize;
1588 #define XCHG(a, b, xchg) \
1596 XCHG(top_border_m1 + 8, src_y - 8, xchg);
1597 XCHG(top_border, src_y, xchg);
1598 XCHG(top_border + 8, src_y + 8, 1);
1599 if (mb_x < mb_width - 1)
1600 XCHG(top_border + 32, src_y + 16, 1);
1604 if (!simple || !mb_y) {
1605 XCHG(top_border_m1 + 16, src_cb - 8, xchg);
1606 XCHG(top_border_m1 + 24, src_cr - 8, xchg);
1607 XCHG(top_border + 16, src_cb, 1);
1608 XCHG(top_border + 24, src_cr, 1);
1658 int *copy_buf,
int vp7)
1662 if (!mb_x && mb_y) {
1696 int x, y,
mode, nnz;
1701 if (mb_y && (
s->deblock_filter || !mb_y) &&
td->thread_nr == 0)
1703 s->linesize,
s->uvlinesize, mb_x, mb_y,
s->mb_width,
1704 s->filter.simple, 1);
1708 s->hpc.pred16x16[
mode](dst[0],
s->linesize);
1710 uint8_t *ptr = dst[0];
1711 const uint8_t *intra4x4 =
mb->intra4x4_pred_mode_mb;
1712 const uint8_t lo = is_vp7 ? 128 : 127;
1713 const uint8_t hi = is_vp7 ? 128 : 129;
1714 const uint8_t tr_top[4] = { lo, lo, lo, lo };
1718 const uint8_t *tr_right = ptr -
s->linesize + 16;
1722 if (mb_y && mb_x ==
s->mb_width - 1) {
1723 tr = tr_right[-1] * 0x01010101
u;
1724 tr_right = (uint8_t *) &tr;
1730 for (y = 0; y < 4; y++) {
1731 const uint8_t *topright = ptr + 4 -
s->linesize;
1732 for (x = 0; x < 4; x++) {
1734 ptrdiff_t linesize =
s->linesize;
1735 uint8_t *dst = ptr + 4 * x;
1738 if ((y == 0 || x == 3) && mb_y == 0) {
1741 topright = tr_right;
1744 mb_y + y, &
copy, is_vp7);
1746 dst = copy_dst + 12;
1750 AV_WN32A(copy_dst + 4, lo * 0x01010101U);
1752 AV_COPY32(copy_dst + 4, ptr + 4 * x -
s->linesize);
1756 copy_dst[3] = ptr[4 * x -
s->linesize - 1];
1765 copy_dst[11] = ptr[4 * x - 1];
1766 copy_dst[19] = ptr[4 * x +
s->linesize - 1];
1767 copy_dst[27] = ptr[4 * x +
s->linesize * 2 - 1];
1768 copy_dst[35] = ptr[4 * x +
s->linesize * 3 - 1];
1771 s->hpc.pred4x4[
mode](dst, topright, linesize);
1774 AV_COPY32(ptr + 4 * x +
s->linesize, copy_dst + 20);
1775 AV_COPY32(ptr + 4 * x +
s->linesize * 2, copy_dst + 28);
1776 AV_COPY32(ptr + 4 * x +
s->linesize * 3, copy_dst + 36);
1779 nnz =
td->non_zero_count_cache[y][x];
1782 s->vp8dsp.vp8_idct_dc_add(ptr + 4 * x,
1783 td->block[y][x],
s->linesize);
1785 s->vp8dsp.vp8_idct_add(ptr + 4 * x,
1786 td->block[y][x],
s->linesize);
1791 ptr += 4 *
s->linesize;
1797 mb_x, mb_y, is_vp7);
1798 s->hpc.pred8x8[
mode](dst[1],
s->uvlinesize);
1799 s->hpc.pred8x8[
mode](dst[2],
s->uvlinesize);
1801 if (mb_y && (
s->deblock_filter || !mb_y) &&
td->thread_nr == 0)
1803 s->linesize,
s->uvlinesize, mb_x, mb_y,
s->mb_width,
1804 s->filter.simple, 0);
1808 { 0, 1, 2, 1, 2, 1, 2, 1 },
1810 { 0, 3, 5, 3, 5, 3, 5, 3 },
1811 { 0, 2, 3, 2, 3, 2, 3, 2 },
1833 int x_off,
int y_off,
int block_w,
int block_h,
1837 const uint8_t *
src =
ref->f->data[0];
1840 ptrdiff_t src_linesize = linesize;
1845 x_off +=
mv->x >> 2;
1846 y_off +=
mv->y >> 2;
1850 src += y_off * linesize + x_off;
1853 s->vdsp.emulated_edge_mc(
td->edge_emu_buffer,
1854 src - my_idx * linesize - mx_idx,
1858 x_off - mx_idx, y_off - my_idx,
1863 mc_func[my_idx][mx_idx](dst, linesize,
src, src_linesize, block_h, mx, my);
1866 mc_func[0][0](dst, linesize,
src + y_off * linesize + x_off,
1867 linesize, block_h, 0, 0);
1891 int x_off,
int y_off,
int block_w,
int block_h,
1901 x_off +=
mv->x >> 3;
1902 y_off +=
mv->y >> 3;
1905 src1 += y_off * linesize + x_off;
1906 src2 += y_off * linesize + x_off;
1910 s->vdsp.emulated_edge_mc(
td->edge_emu_buffer,
1911 src1 - my_idx * linesize - mx_idx,
1919 s->vdsp.emulated_edge_mc(
td->edge_emu_buffer,
1920 src2 - my_idx * linesize - mx_idx,
1928 mc_func[my_idx][mx_idx](dst1, linesize,
src1, linesize, block_h, mx, my);
1929 mc_func[my_idx][mx_idx](dst2, linesize,
src2, linesize, block_h, mx, my);
1933 mc_func[0][0](dst1, linesize,
src1 + y_off * linesize + x_off, linesize, block_h, 0, 0);
1934 mc_func[0][0](dst2, linesize,
src2 + y_off * linesize + x_off, linesize, block_h, 0, 0);
1941 int bx_off,
int by_off,
int block_w,
int block_h,
1950 s->put_pixels_tab[block_w == 8]);
1953 if (
s->profile == 3) {
1968 dst[2] + by_off *
s->uvlinesize + bx_off,
ref_frame,
1969 &uvmv, x_off + bx_off, y_off + by_off,
1971 s->put_pixels_tab[1 + (block_w == 4)]);
1978 int mb_x,
int mb_y,
int mb_xy,
int ref)
1981 if (
s->ref_count[
ref - 1] > (mb_xy >> 5)) {
1982 int x_off = mb_x << 4, y_off = mb_y << 4;
1983 int mx = (
mb->mv.x >> 2) + x_off + 8;
1984 int my = (
mb->mv.y >> 2) + y_off;
1985 uint8_t **
src =
s->framep[
ref]->tf.f->data;
1986 int off = mx + (my + (mb_x & 3) * 4) *
s->linesize + 64;
1990 s->vdsp.prefetch(
src[0] + off,
s->linesize, 4);
1991 off = (mx >> 1) + ((my >> 1) + (mb_x & 7)) *
s->uvlinesize + 64;
1992 s->vdsp.prefetch(
src[1] + off,
src[2] -
src[1], 2);
2003 int x_off = mb_x << 4, y_off = mb_y << 4;
2008 switch (
mb->partitioning) {
2018 for (y = 0; y < 4; y++) {
2019 for (x = 0; x < 4; x++) {
2021 ref, &bmv[4 * y + x],
2022 4 * x + x_off, 4 * y + y_off, 4, 4,
2024 s->put_pixels_tab[2]);
2033 for (y = 0; y < 2; y++) {
2034 for (x = 0; x < 2; x++) {
2035 uvmv.
x =
mb->bmv[2 * y * 4 + 2 * x ].x +
2036 mb->bmv[2 * y * 4 + 2 * x + 1].x +
2037 mb->bmv[(2 * y + 1) * 4 + 2 * x ].x +
2038 mb->bmv[(2 * y + 1) * 4 + 2 * x + 1].x;
2039 uvmv.
y =
mb->bmv[2 * y * 4 + 2 * x ].y +
2040 mb->bmv[2 * y * 4 + 2 * x + 1].y +
2041 mb->bmv[(2 * y + 1) * 4 + 2 * x ].y +
2042 mb->bmv[(2 * y + 1) * 4 + 2 * x + 1].y;
2045 if (
s->profile == 3) {
2050 dst[2] + 4 * y *
s->uvlinesize + x * 4,
ref,
2051 &uvmv, 4 * x + x_off, 4 * y + y_off, 4, 4,
2053 s->put_pixels_tab[2]);
2090 uint8_t *y_dst = dst[0];
2091 for (y = 0; y < 4; y++) {
2092 uint32_t nnz4 =
AV_RL32(
td->non_zero_count_cache[y]);
2094 if (nnz4 & ~0x01010101) {
2095 for (x = 0; x < 4; x++) {
2096 if ((uint8_t) nnz4 == 1)
2097 s->vp8dsp.vp8_idct_dc_add(y_dst + 4 * x,
2100 else if ((uint8_t) nnz4 > 1)
2101 s->vp8dsp.vp8_idct_add(y_dst + 4 * x,
2109 s->vp8dsp.vp8_idct_dc_add4y(y_dst,
td->block[y],
s->linesize);
2112 y_dst += 4 *
s->linesize;
2116 for (ch = 0; ch < 2; ch++) {
2117 uint32_t nnz4 =
AV_RL32(
td->non_zero_count_cache[4 + ch]);
2119 uint8_t *ch_dst = dst[1 + ch];
2120 if (nnz4 & ~0x01010101) {
2121 for (y = 0; y < 2; y++) {
2122 for (x = 0; x < 2; x++) {
2123 if ((uint8_t) nnz4 == 1)
2124 s->vp8dsp.vp8_idct_dc_add(ch_dst + 4 * x,
2125 td->block[4 + ch][(y << 1) + x],
2127 else if ((uint8_t) nnz4 > 1)
2128 s->vp8dsp.vp8_idct_add(ch_dst + 4 * x,
2129 td->block[4 + ch][(y << 1) + x],
2133 goto chroma_idct_end;
2135 ch_dst += 4 *
s->uvlinesize;
2138 s->vp8dsp.vp8_idct_dc_add4uv(ch_dst,
td->block[4 + ch],
s->uvlinesize);
2150 int interior_limit, filter_level;
2152 if (
s->segmentation.enabled) {
2153 filter_level =
s->segmentation.filter_level[
mb->segment];
2154 if (!
s->segmentation.absolute_vals)
2155 filter_level +=
s->filter.level;
2157 filter_level =
s->filter.level;
2159 if (
s->lf_delta.enabled) {
2160 filter_level +=
s->lf_delta.ref[
mb->ref_frame];
2161 filter_level +=
s->lf_delta.mode[
mb->mode];
2166 interior_limit = filter_level;
2167 if (
s->filter.sharpness) {
2168 interior_limit >>= (
s->filter.sharpness + 3) >> 2;
2169 interior_limit =
FFMIN(interior_limit, 9 -
s->filter.sharpness);
2171 interior_limit =
FFMAX(interior_limit, 1);
2173 f->filter_level = filter_level;
2174 f->inner_limit = interior_limit;
2175 f->inner_filter = is_vp7 || !
mb->skip ||
mb->mode ==
MODE_I4x4 ||
2181 int mb_x,
int mb_y,
int is_vp7)
2183 int mbedge_lim, bedge_lim_y, bedge_lim_uv, hev_thresh;
2184 int filter_level =
f->filter_level;
2185 int inner_limit =
f->inner_limit;
2186 int inner_filter =
f->inner_filter;
2187 ptrdiff_t linesize =
s->linesize;
2188 ptrdiff_t uvlinesize =
s->uvlinesize;
2189 static const uint8_t hev_thresh_lut[2][64] = {
2190 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1,
2191 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2192 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
2194 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1,
2195 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2196 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2204 bedge_lim_y = filter_level;
2205 bedge_lim_uv = filter_level * 2;
2206 mbedge_lim = filter_level + 2;
2209 bedge_lim_uv = filter_level * 2 + inner_limit;
2210 mbedge_lim = bedge_lim_y + 4;
2213 hev_thresh = hev_thresh_lut[
s->keyframe][filter_level];
2216 s->vp8dsp.vp8_h_loop_filter16y(dst[0], linesize,
2217 mbedge_lim, inner_limit, hev_thresh);
2218 s->vp8dsp.vp8_h_loop_filter8uv(dst[1], dst[2], uvlinesize,
2219 mbedge_lim, inner_limit, hev_thresh);
2222 #define H_LOOP_FILTER_16Y_INNER(cond) \
2223 if (cond && inner_filter) { \
2224 s->vp8dsp.vp8_h_loop_filter16y_inner(dst[0] + 4, linesize, \
2225 bedge_lim_y, inner_limit, \
2227 s->vp8dsp.vp8_h_loop_filter16y_inner(dst[0] + 8, linesize, \
2228 bedge_lim_y, inner_limit, \
2230 s->vp8dsp.vp8_h_loop_filter16y_inner(dst[0] + 12, linesize, \
2231 bedge_lim_y, inner_limit, \
2233 s->vp8dsp.vp8_h_loop_filter8uv_inner(dst[1] + 4, dst[2] + 4, \
2234 uvlinesize, bedge_lim_uv, \
2235 inner_limit, hev_thresh); \
2241 s->vp8dsp.vp8_v_loop_filter16y(dst[0], linesize,
2242 mbedge_lim, inner_limit, hev_thresh);
2243 s->vp8dsp.vp8_v_loop_filter8uv(dst[1], dst[2], uvlinesize,
2244 mbedge_lim, inner_limit, hev_thresh);
2248 s->vp8dsp.vp8_v_loop_filter16y_inner(dst[0] + 4 * linesize,
2249 linesize, bedge_lim_y,
2250 inner_limit, hev_thresh);
2251 s->vp8dsp.vp8_v_loop_filter16y_inner(dst[0] + 8 * linesize,
2252 linesize, bedge_lim_y,
2253 inner_limit, hev_thresh);
2254 s->vp8dsp.vp8_v_loop_filter16y_inner(dst[0] + 12 * linesize,
2255 linesize, bedge_lim_y,
2256 inner_limit, hev_thresh);
2257 s->vp8dsp.vp8_v_loop_filter8uv_inner(dst[1] + 4 * uvlinesize,
2258 dst[2] + 4 * uvlinesize,
2259 uvlinesize, bedge_lim_uv,
2260 inner_limit, hev_thresh);
2270 int mbedge_lim, bedge_lim;
2271 int filter_level =
f->filter_level;
2272 int inner_limit =
f->inner_limit;
2273 int inner_filter =
f->inner_filter;
2274 ptrdiff_t linesize =
s->linesize;
2279 bedge_lim = 2 * filter_level + inner_limit;
2280 mbedge_lim = bedge_lim + 4;
2283 s->vp8dsp.vp8_h_loop_filter_simple(dst, linesize, mbedge_lim);
2285 s->vp8dsp.vp8_h_loop_filter_simple(dst + 4, linesize, bedge_lim);
2286 s->vp8dsp.vp8_h_loop_filter_simple(dst + 8, linesize, bedge_lim);
2287 s->vp8dsp.vp8_h_loop_filter_simple(dst + 12, linesize, bedge_lim);
2291 s->vp8dsp.vp8_v_loop_filter_simple(dst, linesize, mbedge_lim);
2293 s->vp8dsp.vp8_v_loop_filter_simple(dst + 4 * linesize, linesize, bedge_lim);
2294 s->vp8dsp.vp8_v_loop_filter_simple(dst + 8 * linesize, linesize, bedge_lim);
2295 s->vp8dsp.vp8_v_loop_filter_simple(dst + 12 * linesize, linesize, bedge_lim);
2299 #define MARGIN (16 << 2)
2302 const VP8Frame *prev_frame,
int is_vp7)
2307 s->mv_bounds.mv_min.y = -
MARGIN;
2308 s->mv_bounds.mv_max.y = ((
s->mb_height - 1) << 6) +
MARGIN;
2309 for (mb_y = 0; mb_y <
s->mb_height; mb_y++) {
2311 ((
s->mb_width + 1) * (mb_y + 1) + 1);
2312 int mb_xy = mb_y *
s->mb_width;
2316 s->mv_bounds.mv_min.x = -
MARGIN;
2317 s->mv_bounds.mv_max.x = ((
s->mb_width - 1) << 6) +
MARGIN;
2319 for (mb_x = 0; mb_x <
s->mb_width; mb_x++, mb_xy++,
mb++) {
2324 AV_WN32A((
mb -
s->mb_width - 1)->intra4x4_pred_mode_top,
2327 prev_frame && prev_frame->
seg_map ?
2329 s->mv_bounds.mv_min.x -= 64;
2330 s->mv_bounds.mv_max.x -= 64;
2332 s->mv_bounds.mv_min.y -= 64;
2333 s->mv_bounds.mv_max.y -= 64;
2351 #define check_thread_pos(td, otd, mb_x_check, mb_y_check) \
2353 int tmp = (mb_y_check << 16) | (mb_x_check & 0xFFFF); \
2354 if (atomic_load(&otd->thread_mb_pos) < tmp) { \
2355 pthread_mutex_lock(&otd->lock); \
2356 atomic_store(&td->wait_mb_pos, tmp); \
2358 if (atomic_load(&otd->thread_mb_pos) >= tmp) \
2360 pthread_cond_wait(&otd->cond, &otd->lock); \
2362 atomic_store(&td->wait_mb_pos, INT_MAX); \
2363 pthread_mutex_unlock(&otd->lock); \
2367 #define update_pos(td, mb_y, mb_x) \
2369 int pos = (mb_y << 16) | (mb_x & 0xFFFF); \
2370 int sliced_threading = (avctx->active_thread_type == FF_THREAD_SLICE) && \
2372 int is_null = !next_td || !prev_td; \
2373 int pos_check = (is_null) ? 1 : \
2374 (next_td != td && pos >= atomic_load(&next_td->wait_mb_pos)) || \
2375 (prev_td != td && pos >= atomic_load(&prev_td->wait_mb_pos)); \
2376 atomic_store(&td->thread_mb_pos, pos); \
2377 if (sliced_threading && pos_check) { \
2378 pthread_mutex_lock(&td->lock); \
2379 pthread_cond_broadcast(&td->cond); \
2380 pthread_mutex_unlock(&td->lock); \
2384 #define check_thread_pos(td, otd, mb_x_check, mb_y_check) while(0)
2385 #define update_pos(td, mb_y, mb_x) while(0)
2389 int jobnr,
int threadnr,
int is_vp7)
2394 int mb_x, mb_xy = mb_y *
s->mb_width;
2395 int num_jobs =
s->num_jobs;
2396 const VP8Frame *prev_frame =
s->prev_frame;
2398 VPXRangeCoder *coeff_c = &
s->coeff_partition[mb_y & (
s->num_coeff_partitions - 1)];
2402 curframe->
tf.
f->
data[0] + 16 * mb_y *
s->linesize,
2403 curframe->
tf.
f->
data[1] + 8 * mb_y *
s->uvlinesize,
2404 curframe->
tf.
f->
data[2] + 8 * mb_y *
s->uvlinesize
2413 prev_td = &
s->thread_data[(jobnr + num_jobs - 1) % num_jobs];
2414 if (mb_y ==
s->mb_height - 1)
2417 next_td = &
s->thread_data[(jobnr + 1) % num_jobs];
2418 if (
s->mb_layout == 1)
2419 mb =
s->macroblocks_base + ((
s->mb_width + 1) * (mb_y + 1) + 1);
2423 if (prev_frame &&
s->segmentation.enabled &&
2424 !
s->segmentation.update_map)
2426 mb =
s->macroblocks + (
s->mb_height - mb_y - 1) * 2;
2427 memset(
mb - 1, 0,
sizeof(*
mb));
2431 if (!is_vp7 || mb_y == 0)
2432 memset(
td->left_nnz, 0,
sizeof(
td->left_nnz));
2435 td->mv_bounds.mv_max.x = ((
s->mb_width - 1) << 6) +
MARGIN;
2437 for (mb_x = 0; mb_x <
s->mb_width; mb_x++, mb_xy++,
mb++) {
2441 if (prev_td !=
td) {
2442 if (threadnr != 0) {
2444 mb_x + (is_vp7 ? 2 : 1),
2445 mb_y - (is_vp7 ? 2 : 1));
2448 mb_x + (is_vp7 ? 2 : 1) +
s->mb_width + 3,
2449 mb_y - (is_vp7 ? 2 : 1));
2453 s->vdsp.prefetch(dst[0] + (mb_x & 3) * 4 *
s->linesize + 64,
2455 s->vdsp.prefetch(dst[1] + (mb_x & 7) *
s->uvlinesize + 64,
2456 dst[2] - dst[1], 2);
2460 prev_frame && prev_frame->
seg_map ?
2487 td->left_nnz[8] = 0;
2488 s->top_nnz[mb_x][8] = 0;
2492 if (
s->deblock_filter)
2495 if (
s->deblock_filter && num_jobs != 1 && threadnr == num_jobs - 1) {
2496 if (
s->filter.simple)
2501 dst[1], dst[2],
s->linesize,
s->uvlinesize, 0);
2509 td->mv_bounds.mv_min.x -= 64;
2510 td->mv_bounds.mv_max.x -= 64;
2512 if (mb_x ==
s->mb_width + 1) {
2522 int jobnr,
int threadnr)
2528 int jobnr,
int threadnr)
2534 int jobnr,
int threadnr,
int is_vp7)
2538 int mb_x, mb_y =
atomic_load(&
td->thread_mb_pos) >> 16, num_jobs =
s->num_jobs;
2539 AVFrame *curframe =
s->curframe->tf.f;
2543 curframe->
data[0] + 16 * mb_y *
s->linesize,
2544 curframe->
data[1] + 8 * mb_y *
s->uvlinesize,
2545 curframe->
data[2] + 8 * mb_y *
s->uvlinesize
2548 if (
s->mb_layout == 1)
2549 mb =
s->macroblocks_base + ((
s->mb_width + 1) * (mb_y + 1) + 1);
2551 mb =
s->macroblocks + (
s->mb_height - mb_y - 1) * 2;
2556 prev_td = &
s->thread_data[(jobnr + num_jobs - 1) % num_jobs];
2557 if (mb_y ==
s->mb_height - 1)
2560 next_td = &
s->thread_data[(jobnr + 1) % num_jobs];
2562 for (mb_x = 0; mb_x <
s->mb_width; mb_x++,
mb++) {
2566 (mb_x + 1) + (
s->mb_width + 3), mb_y - 1);
2568 if (next_td != &
s->thread_data[0])
2571 if (num_jobs == 1) {
2572 if (
s->filter.simple)
2577 dst[1], dst[2],
s->linesize,
s->uvlinesize, 0);
2580 if (
s->filter.simple)
2593 int jobnr,
int threadnr)
2599 int jobnr,
int threadnr)
2606 int threadnr,
int is_vp7)
2612 int mb_y, num_jobs =
s->num_jobs;
2615 td->thread_nr = threadnr;
2616 td->mv_bounds.mv_min.y = -
MARGIN - 64 * threadnr;
2617 td->mv_bounds.mv_max.y = ((
s->mb_height - 1) << 6) +
MARGIN - 64 * threadnr;
2618 for (mb_y = jobnr; mb_y <
s->mb_height; mb_y += num_jobs) {
2620 ret =
s->decode_mb_row_no_filter(avctx, tdata, jobnr, threadnr);
2625 if (
s->deblock_filter)
2626 s->filter_mb_row(avctx, tdata, jobnr, threadnr);
2629 td->mv_bounds.mv_min.y -= 64 * num_jobs;
2630 td->mv_bounds.mv_max.y -= 64 * num_jobs;
2640 int jobnr,
int threadnr)
2646 int jobnr,
int threadnr)
2656 int ret,
i, referenced, num_jobs;
2668 if (
s->actually_webp) {
2672 if (
s->pix_fmt < 0) {
2690 memcpy(&
s->next_framep[0], &
s->framep[0],
sizeof(
s->framep[0]) * 4);
2696 for (
i = 0;
i < 5;
i++)
2697 if (
s->frames[
i].tf.f->buf[0] &&
2698 &
s->frames[
i] != prev_frame &&
2721 "Discarding interframe without a prior keyframe!\n");
2771 s->linesize = curframe->tf.f->linesize[0];
2772 s->uvlinesize = curframe->tf.f->linesize[1];
2774 memset(
s->top_nnz, 0,
s->mb_width *
sizeof(*
s->top_nnz));
2778 memset(
s->macroblocks +
s->mb_height * 2 - 1, 0,
2779 (
s->mb_width + 1) *
sizeof(*
s->macroblocks));
2780 if (!
s->mb_layout &&
s->keyframe)
2781 memset(
s->intra4x4_pred_mode_top,
DC_PRED,
s->mb_width * 4);
2783 memset(
s->ref_count, 0,
sizeof(
s->ref_count));
2785 if (
s->mb_layout == 1) {
2788 if (prev_frame &&
s->segmentation.enabled &&
2789 !
s->segmentation.update_map)
2803 s->num_jobs = num_jobs;
2804 s->curframe = curframe;
2805 s->prev_frame = prev_frame;
2806 s->mv_bounds.mv_min.y = -
MARGIN;
2807 s->mv_bounds.mv_max.y = ((
s->mb_height - 1) << 6) +
MARGIN;
2822 memcpy(&
s->framep[0], &
s->next_framep[0],
sizeof(
s->framep[0]) * 4);
2827 if (!
s->update_probabilities)
2828 s->prob[0] =
s->prob[1];
2830 if (!
s->invisible) {
2838 memcpy(&
s->next_framep[0], &
s->framep[0],
sizeof(
s->framep[0]) * 4);
2848 #if CONFIG_VP7_DECODER
2873 if (!
s->frames[
i].tf.f)
2893 if (CONFIG_VP7_DECODER && is_vp7) {
2898 }
else if (CONFIG_VP8_DECODER && !is_vp7) {
2916 #if CONFIG_VP7_DECODER
2928 #if CONFIG_VP8_DECODER
2930 #define REBASE(pic) ((pic) ? (pic) - &s_src->frames[0] + &s->frames[0] : NULL)
2938 if (
s->macroblocks_base &&
2939 (s_src->mb_width !=
s->mb_width || s_src->mb_height !=
s->mb_height)) {
2941 s->mb_width = s_src->mb_width;
2942 s->mb_height = s_src->mb_height;
2945 s->pix_fmt = s_src->pix_fmt;
2946 s->prob[0] = s_src->prob[!s_src->update_probabilities];
2947 s->segmentation = s_src->segmentation;
2948 s->lf_delta = s_src->lf_delta;
2949 memcpy(
s->sign_bias, s_src->sign_bias,
sizeof(
s->sign_bias));
2952 if (s_src->frames[
i].tf.f->buf[0]) {
2953 int ret = vp8_ref_frame(&
s->frames[
i], &s_src->frames[
i]);
2959 s->framep[0] = REBASE(s_src->next_framep[0]);
2960 s->framep[1] = REBASE(s_src->next_framep[1]);
2961 s->framep[2] = REBASE(s_src->next_framep[2]);
2962 s->framep[3] = REBASE(s_src->next_framep[3]);
2969 #if CONFIG_VP7_DECODER
2976 .
init = vp7_decode_init,
2984 #if CONFIG_VP8_DECODER
3000 #if CONFIG_VP8_VAAPI_HWACCEL
3003 #if CONFIG_VP8_NVDEC_HWACCEL
static const int vp8_mode_contexts[6][4]
static const uint8_t vp8_dct_cat1_prob[]
int(* update_thread_context)(struct AVCodecContext *dst, const struct AVCodecContext *src)
Copy necessary context variables from a previous thread context to the current one.
static av_always_inline void decode_mb_mode(VP8Context *s, const VP8mvbounds *mv_bounds, VP8Macroblock *mb, int mb_x, int mb_y, uint8_t *segment, const uint8_t *ref, int layout, int is_vp7)
#define VP7_MV_PRED_COUNT
const struct AVHWAccel * hwaccel
Hardware accelerator in use.
av_cold int ff_vp8_decode_free(AVCodecContext *avctx)
static const uint8_t vp7_pred4x4_mode[]
static av_always_inline int decode_block_coeffs_internal(VPXRangeCoder *r, int16_t block[16], uint8_t probs[16][3][NUM_DCT_TOKENS - 1], int i, const uint8_t *token_prob, const int16_t qmul[2], const uint8_t scan[16], int vp7)
static 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)
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
static av_always_inline int check_tm_pred4x4_mode(int mode, int mb_x, int mb_y, int vp7)
static const uint16_t vp7_y2dc_qlookup[]
This structure describes decoded (raw) audio or video data.
@ AVCOL_RANGE_JPEG
Full range content.
static av_always_inline void vp8_mc_chroma(VP8Context *s, VP8ThreadData *td, uint8_t *dst1, uint8_t *dst2, const ThreadFrame *ref, const VP8mv *mv, int x_off, int y_off, int block_w, int block_h, int width, int height, ptrdiff_t linesize, vp8_mc_func mc_func[3][3])
chroma MC function
static av_always_inline int inter_predict_dc(int16_t block[16], int16_t pred[2])
static void vp8_get_quants(VP8Context *s)
#define FF_HW_SIMPLE_CALL(avctx, function)
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
AVBufferRef * buf[AV_NUM_DATA_POINTERS]
AVBuffer references backing the data for this frame.
int ff_set_dimensions(AVCodecContext *s, int width, int height)
Check that the provided frame dimensions are valid and set them on the codec context.
#define VERT_VP8_PRED
for VP8, VERT_PRED is the average of
the pkt_dts and pkt_pts fields in AVFrame will work as usual Restrictions on codec whose streams don t reset across will not work because their bitstreams cannot be decoded in parallel *The contents of buffers must not be read before ff_thread_await_progress() has been called on them. reget_buffer() and buffer age optimizations no longer work. *The contents of buffers must not be written to after ff_thread_report_progress() has been called on them. This includes draw_edges(). Porting codecs to frame threading
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
static int vp8_decode_mb_row_no_filter(AVCodecContext *avctx, void *tdata, int jobnr, int threadnr)
static int vp8_rac_get_sint(VPXRangeCoder *c, int bits)
static const int8_t vp8_pred8x8c_tree[3][2]
#define bit(string, value)
#define update_pos(td, mb_y, mb_x)
static const VP8mv * get_bmv_ptr(const VP8Macroblock *mb, int subblock)
static av_always_inline int update_dimensions(VP8Context *s, int width, int height, int is_vp7)
@ AVCOL_SPC_BT470BG
also ITU-R BT601-6 625 / ITU-R BT1358 625 / ITU-R BT1700 625 PAL & SECAM / IEC 61966-2-4 xvYCC601
@ VP8_SPLITMVMODE_8x8
2x2 blocks of 8x8px each
AVCodec p
The public AVCodec.
const struct AVCodec * codec
static const uint8_t vp8_mv_update_prob[2][19]
enum AVDiscard skip_frame
Skip decoding for selected frames.
int thread_count
thread count is used to decide how many independent tasks should be passed to execute()
const FFCodec ff_vp8_decoder
int(* end_frame)(AVCodecContext *avctx)
Called at the end of each frame or field picture.
av_cold void ff_videodsp_init(VideoDSPContext *ctx, int bpc)
static av_always_inline void update(SilenceDetectContext *s, AVFrame *insamples, int is_silence, int current_sample, int64_t nb_samples_notify, AVRational time_base)
static av_always_inline void idct_mb(VP8Context *s, VP8ThreadData *td, uint8_t *const dst[3], const VP8Macroblock *mb)
static av_always_inline int check_intra_pred8x8_mode_emuedge(int mode, int mb_x, int mb_y, int vp7)
static av_always_inline void filter_level_for_mb(const VP8Context *s, const VP8Macroblock *mb, VP8FilterStrength *f, int is_vp7)
static av_always_inline int read_mv_component(VPXRangeCoder *c, const uint8_t *p, int vp7)
Motion vector coding, 17.1.
static void vp8_filter_mb_row(AVCodecContext *avctx, void *tdata, int jobnr, int threadnr)
static void vp7_get_quants(VP8Context *s)
@ VP8_SPLITMVMODE_16x8
2 16x8 blocks (vertical)
static av_cold int vp8_init_frames(VP8Context *s)
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
static av_always_inline void vp8_mc_part(VP8Context *s, VP8ThreadData *td, uint8_t *const dst[3], const ThreadFrame *ref_frame, int x_off, int y_off, int bx_off, int by_off, int block_w, int block_h, int width, int height, const VP8mv *mv)
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, const ThreadFrame *ref, const VP8mv *mv, int x_off, int y_off, int block_w, int block_h, int width, int height, ptrdiff_t linesize, vp8_mc_func mc_func[3][3])
luma MC function
void ff_vp7dsp_init(VP8DSPContext *c)
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
void ff_vp8dsp_init(VP8DSPContext *c)
#define FF_ARRAY_ELEMS(a)
static const uint8_t vp8_dct_cat2_prob[]
#define AV_FRAME_FLAG_KEY
A flag to mark frames that are keyframes.
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 AVFrame * ref_frame(const struct pl_frame_mix *mix)
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.
int(* init)(AVBSFContext *ctx)
static const int8_t vp8_pred16x16_tree_intra[4][2]
static void parse_segment_info(VP8Context *s)
static const uint8_t vp8_pred4x4_prob_inter[9]
static enum AVPixelFormat pix_fmts[]
static const uint8_t vp8_mbsplits[5][16]
static av_always_inline int vp78_decode_frame(AVCodecContext *avctx, AVFrame *rframe, int *got_frame, const AVPacket *avpkt, int is_vp7)
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_RL16
static const int vp7_mode_contexts[31][4]
static av_always_inline int vp78_decode_mv_mb_modes(AVCodecContext *avctx, VP8Frame *curframe, const VP8Frame *prev_frame, int is_vp7)
@ AV_PIX_FMT_YUV420P
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
#define atomic_load(object)
@ VP8_SPLITMVMODE_8x16
2 8x16 blocks (horizontal)
#define CODEC_LONG_NAME(str)
uint8_t * seg_map
RefStruct reference.
int ff_thread_ref_frame(ThreadFrame *dst, const ThreadFrame *src)
static const uint8_t vp8_mv_default_prob[2][19]
static const int8_t vp8_coeff_band_indexes[8][10]
static const uint8_t vp8_pred16x16_prob_inter[4]
static void vp8_decode_flush_impl(AVCodecContext *avctx, int free_mem)
#define AV_CODEC_CAP_FRAME_THREADS
Codec supports frame-level multithreading.
@ AVDISCARD_ALL
discard all
static int vp8_rac_get_nn(VPXRangeCoder *c)
static av_always_inline void clamp_mv(const VP8mvbounds *s, VP8mv *dst, const VP8mv *src)
static const int sizes[][2]
enum AVColorRange color_range
MPEG vs JPEG YUV range.
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 ff_thread_release_ext_buffer(ThreadFrame *f)
Unref a ThreadFrame.
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_token_update_probs[4][8][3][NUM_DCT_TOKENS - 1]
static const uint8_t vp8_mbsplit_count[4]
#define UPDATE_THREAD_CONTEXT(func)
static av_always_inline void vp8_decode_mvs(VP8Context *s, const VP8mvbounds *mv_bounds, VP8Macroblock *mb, int mb_x, int mb_y, int layout)
#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
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
#define FF_CODEC_CAP_ALLOCATE_PROGRESS
static void free_buffers(VP8Context *s)
static const av_always_inline FFCodec * ffcodec(const AVCodec *codec)
static av_always_inline int decode_block_coeffs(VPXRangeCoder *c, int16_t block[16], uint8_t probs[16][3][NUM_DCT_TOKENS - 1], int i, int zero_nhood, const int16_t qmul[2], const uint8_t scan[16], int vp7)
#define FF_THREAD_SLICE
Decode more than one part of a single frame at once.
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.
int ff_thread_get_ext_buffer(AVCodecContext *avctx, ThreadFrame *f, int flags)
Wrapper around ff_get_buffer() for frame-multithreaded codecs.
@ AVCOL_RANGE_MPEG
Narrow or limited range content.
static int vp8_decode_mb_row_sliced(AVCodecContext *avctx, void *tdata, int jobnr, int threadnr)
const FFCodec ff_vp7_decoder
@ VP8_SPLITMVMODE_NONE
(only used in prediction) no split MVs
static av_always_inline void prefetch_motion(const VP8Context *s, const VP8Macroblock *mb, int mb_x, int mb_y, int mb_xy, int ref)
static av_always_inline int vp89_rac_get_tree(VPXRangeCoder *c, const int8_t(*tree)[2], const uint8_t *probs)
static av_always_inline void decode_mb_coeffs(VP8Context *s, VP8ThreadData *td, VPXRangeCoder *c, VP8Macroblock *mb, uint8_t t_nnz[9], uint8_t l_nnz[9], int is_vp7)
#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)
static const uint8_t vp8_pred16x16_prob_intra[4]
static const uint16_t vp8_ac_qlookup[VP8_MAX_QUANT+1]
#define prob(name, subs,...)
int ff_vpx_init_range_decoder(VPXRangeCoder *c, const uint8_t *buf, int buf_size)
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
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)
int(* decode_slice)(AVCodecContext *avctx, const uint8_t *buf, uint32_t buf_size)
Callback for each slice.
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.
void(* flush)(AVBSFContext *ctx)
static void vp78_update_pred16x16_pred8x8_mvc_probabilities(VP8Context *s, int mvc_size)
#define avpriv_request_sample(...)
static void update_refs(VP8Context *s)
static int vp7_decode_mv_mb_modes(AVCodecContext *avctx, VP8Frame *cur_frame, const VP8Frame *prev_frame)
static void update_lf_deltas(VP8Context *s)
static av_always_inline void filter_mb_row(AVCodecContext *avctx, void *tdata, int jobnr, int threadnr, int is_vp7)
static const int16_t alpha[]
This structure stores compressed data.
static enum AVPixelFormat get_pixel_format(VP8Context *s)
int ff_vp8_decode_frame(AVCodecContext *avctx, AVFrame *frame, int *got_frame, AVPacket *avpkt)
#define HWACCEL_VAAPI(codec)
static VP8Frame * vp8_find_free_buffer(VP8Context *s)
int linesize[AV_NUM_DATA_POINTERS]
For video, a positive or negative value, which is typically indicating the size in bytes of each pict...
static const double coeff[2][5]
The exact code depends on how similar the blocks are and how related they are to the block
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
static av_always_inline int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr)
static const uint16_t vp7_y2ac_qlookup[]
#define atomic_init(obj, value)
static const uint8_t vp7_submv_prob[3]
@ AVDISCARD_NONREF
discard all non reference
static int vp8_rac_get_coeff(VPXRangeCoder *c, const uint8_t *prob)
static const uint8_t vp8_dc_qlookup[VP8_MAX_QUANT+1]
static void copy_chroma(AVFrame *dst, const AVFrame *src, int width, int height)
static void vp8_decode_flush(AVCodecContext *avctx)
int(* execute2)(struct AVCodecContext *c, int(*func)(struct AVCodecContext *c2, void *arg, int jobnr, int threadnr), void *arg2, int *ret, int count)
The codec may call this to execute several independent things.
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.