Go to the documentation of this file.
42 #if CONFIG_VP7_DECODER && CONFIG_VP8_DECODER
43 #define VPX(vp7, f) (vp7 ? vp7_ ## f : vp8_ ## f)
44 #elif CONFIG_VP7_DECODER
45 #define VPX(vp7, f) vp7_ ## f
46 #else // CONFIG_VP8_DECODER
47 #define VPX(vp7, f) vp8_ ## f
67 s->macroblocks =
NULL;
78 if (
s->avctx->hwaccel) {
82 if (!
f->hwaccel_priv_buf)
84 f->hwaccel_picture_private =
f->hwaccel_priv_buf->data;
99 f->hwaccel_picture_private =
NULL;
103 #if CONFIG_VP8_DECODER
117 if (
src->hwaccel_picture_private) {
135 memset(
s->framep, 0,
sizeof(
s->framep));
152 for (
i = 0;
i < 5;
i++)
164 if (
frame->tf.f->buf[0])
173 #if CONFIG_VP8_VAAPI_HWACCEL
176 #if CONFIG_VP8_NVDEC_HWACCEL
192 if (
width !=
s->avctx->width || ((
width+15)/16 !=
s->mb_width || (
height+15)/16 !=
s->mb_height) &&
s->macroblocks_base ||
201 if (!
s->actually_webp && !is_vp7) {
208 s->mb_width = (
s->avctx->coded_width + 15) / 16;
209 s->mb_height = (
s->avctx->coded_height + 15) / 16;
214 s->macroblocks_base =
av_mallocz((
s->mb_width +
s->mb_height * 2 + 1) *
215 sizeof(*
s->macroblocks));
216 s->intra4x4_pred_mode_top =
av_mallocz(
s->mb_width * 4);
218 s->macroblocks_base =
av_mallocz((
s->mb_width + 2) * (
s->mb_height + 2) *
219 sizeof(*
s->macroblocks));
221 s->top_border =
av_mallocz((
s->mb_width + 1) *
sizeof(*
s->top_border));
224 if (!
s->macroblocks_base || !
s->top_nnz || !
s->top_border ||
225 !
s->thread_data || (!
s->intra4x4_pred_mode_top && !
s->mb_layout)) {
231 s->thread_data[
i].filter_strength =
232 av_mallocz(
s->mb_width *
sizeof(*
s->thread_data[0].filter_strength));
233 if (!
s->thread_data[
i].filter_strength) {
243 s->macroblocks =
s->macroblocks_base + 1;
267 if (
s->segmentation.update_feature_data) {
270 for (
i = 0;
i < 4;
i++)
273 for (
i = 0;
i < 4;
i++)
276 if (
s->segmentation.update_map)
277 for (
i = 0;
i < 3;
i++)
286 for (
i = 0;
i < 4;
i++) {
291 s->lf_delta.ref[
i] = -
s->lf_delta.ref[
i];
300 s->lf_delta.mode[
i] = -
s->lf_delta.mode[
i];
313 buf += 3 * (
s->num_coeff_partitions - 1);
314 buf_size -= 3 * (
s->num_coeff_partitions - 1);
318 for (
i = 0;
i <
s->num_coeff_partitions - 1;
i++) {
320 if (buf_size -
size < 0)
322 s->coeff_partition_size[
i] =
size;
331 s->coeff_partition_size[
i] = buf_size;
368 for (
i = 0;
i < 4;
i++) {
369 if (
s->segmentation.enabled) {
370 base_qi =
s->segmentation.base_quant[
i];
371 if (!
s->segmentation.absolute_vals)
372 base_qi +=
s->quant.yac_qi;
374 base_qi =
s->quant.yac_qi;
376 s->qmat[
i].luma_qmul[0] =
vp8_dc_qlookup[av_clip_uintp2(base_qi +
s->quant.ydc_delta, 7)];
378 s->qmat[
i].luma_dc_qmul[0] =
vp8_dc_qlookup[av_clip_uintp2(base_qi +
s->quant.y2dc_delta, 7)] * 2;
380 s->qmat[
i].luma_dc_qmul[1] =
vp8_ac_qlookup[av_clip_uintp2(base_qi +
s->quant.y2ac_delta, 7)] * 101581 >> 16;
381 s->qmat[
i].chroma_qmul[0] =
vp8_dc_qlookup[av_clip_uintp2(base_qi +
s->quant.uvdc_delta, 7)];
382 s->qmat[
i].chroma_qmul[1] =
vp8_ac_qlookup[av_clip_uintp2(base_qi +
s->quant.uvac_delta, 7)];
384 s->qmat[
i].luma_dc_qmul[1] =
FFMAX(
s->qmat[
i].luma_dc_qmul[1], 8);
385 s->qmat[
i].chroma_qmul[0] =
FFMIN(
s->qmat[
i].chroma_qmul[0], 132);
421 for (
i = 0;
i < 4;
i++)
422 for (j = 0; j < 16; j++)
424 sizeof(
s->prob->token[
i][j]));
432 for (
i = 0;
i < 4;
i++)
433 for (j = 0; j < 8; j++)
434 for (k = 0; k < 3; k++)
443 #define VP7_MVC_SIZE 17
444 #define VP8_MVC_SIZE 19
453 for (
i = 0;
i < 4;
i++)
456 for (
i = 0;
i < 3;
i++)
460 for (
i = 0;
i < 2;
i++)
461 for (j = 0; j < mvc_size; j++)
481 for (j = 1; j < 3; j++) {
494 for (j = 0; j <
height; j++) {
496 uint8_t *dst2 = dst + j * dst_linesize;
499 dst2[
i] = av_clip_uint8(y + ((y * beta) >> 8) +
alpha);
510 if (
c->end <=
c->buffer &&
c->bits >= 0)
513 if (!
s->keyframe && (
alpha || beta)) {
514 int width =
s->mb_width * 16;
515 int height =
s->mb_height * 16;
539 src->data[0],
src->linesize[0],
549 int part1_size, hscale, vscale,
i, j,
ret;
550 int width =
s->avctx->width;
557 s->profile = (
buf[0] >> 1) & 7;
558 if (
s->profile > 1) {
563 s->keyframe = !(
buf[0] & 1);
567 if (buf_size < 4 - s->
profile + part1_size) {
568 av_log(
s->avctx,
AV_LOG_ERROR,
"Buffer size %d is too small, needed : %d\n", buf_size, 4 -
s->profile + part1_size);
572 buf += 4 -
s->profile;
573 buf_size -= 4 -
s->profile;
575 memcpy(
s->put_pixels_tab,
s->vp8dsp.put_vp8_epel_pixels_tab,
sizeof(
s->put_pixels_tab));
581 buf_size -= part1_size;
589 if (hscale || vscale)
595 sizeof(
s->prob->pred16x16));
597 sizeof(
s->prob->pred8x8c));
598 for (
i = 0;
i < 2;
i++)
601 memset(&
s->segmentation, 0,
sizeof(
s->segmentation));
602 memset(&
s->lf_delta, 0,
sizeof(
s->lf_delta));
606 if (
s->keyframe ||
s->profile > 0)
607 memset(
s->inter_dc_pred, 0 ,
sizeof(
s->inter_dc_pred));
610 for (
i = 0;
i < 4;
i++) {
612 if (
s->feature_enabled[
i]) {
615 for (j = 0; j < 3; j++)
616 s->feature_index_prob[
i][j] =
620 for (j = 0; j < 4; j++)
621 s->feature_value[
i][j] =
626 s->segmentation.enabled = 0;
627 s->segmentation.update_map = 0;
628 s->lf_delta.enabled = 0;
630 s->num_coeff_partitions = 1;
635 if (!
s->macroblocks_base ||
637 (
width + 15) / 16 !=
s->mb_width || (
height + 15) / 16 !=
s->mb_height) {
652 s->update_probabilities = 1;
655 if (
s->profile > 0) {
657 if (!
s->update_probabilities)
658 s->prob[1] =
s->prob[0];
678 for (
i = 1;
i < 16;
i++)
690 s->mbskip_enabled = 0;
705 int header_size, hscale, vscale,
ret;
706 int width =
s->avctx->width;
714 s->keyframe = !(
buf[0] & 1);
715 s->profile = (
buf[0]>>1) & 7;
716 s->invisible = !(
buf[0] & 0x10);
721 s->header_partition_size = header_size;
727 memcpy(
s->put_pixels_tab,
s->vp8dsp.put_vp8_epel_pixels_tab,
728 sizeof(
s->put_pixels_tab));
730 memcpy(
s->put_pixels_tab,
s->vp8dsp.put_vp8_bilinear_pixels_tab,
731 sizeof(
s->put_pixels_tab));
733 if (header_size > buf_size - 7 *
s->keyframe) {
746 hscale =
buf[4] >> 6;
747 vscale =
buf[6] >> 6;
751 if (hscale || vscale)
757 sizeof(
s->prob->pred16x16));
759 sizeof(
s->prob->pred8x8c));
761 sizeof(
s->prob->mvc));
762 memset(&
s->segmentation, 0,
sizeof(
s->segmentation));
763 memset(&
s->lf_delta, 0,
sizeof(
s->lf_delta));
770 buf_size -= header_size;
782 s->segmentation.update_map = 0;
790 if (
s->lf_delta.update)
799 if (!
s->macroblocks_base ||
801 (
width+15)/16 !=
s->mb_width || (
height+15)/16 !=
s->mb_height)
816 s->prob[1] =
s->prob[0];
834 s->coder_state_at_header_end.input =
s->c.buffer - (-
s->c.bits / 8);
835 s->coder_state_at_header_end.range =
s->c.high;
836 s->coder_state_at_header_end.value =
s->c.code_word >> 16;
837 s->coder_state_at_header_end.bit_count = -
s->c.bits % 8;
845 dst->
x = av_clip(
src->x, av_clip(
s->mv_min.x, INT16_MIN, INT16_MAX),
846 av_clip(
s->mv_max.x, INT16_MIN, INT16_MAX));
847 dst->
y = av_clip(
src->y, av_clip(
s->mv_min.y, INT16_MIN, INT16_MAX),
848 av_clip(
s->mv_max.y, INT16_MIN, INT16_MAX));
861 for (
i = 0;
i < 3;
i++)
863 for (
i = (vp7 ? 7 : 9);
i > 3;
i--)
918 const uint8_t *mbsplits_top, *mbsplits_cur, *firstidx;
926 top_mb = &
mb[-
s->mb_width - 1];
928 top_mv = top_mb->
bmv;
942 mb->partitioning = part_idx;
944 for (
n = 0;
n < num;
n++) {
946 uint32_t
left, above;
954 above =
AV_RN32A(&top_mv[mbsplits_top[k + 12]]);
956 above =
AV_RN32A(&cur_mv[mbsplits_cur[k - 4]]);
963 mb->bmv[
n].y =
mb->mv.y +
965 mb->bmv[
n].x =
mb->mv.x +
993 int xoffset,
int yoffset,
int boundary,
994 int *edge_x,
int *edge_y)
996 int vwidth = mb_width + 1;
997 int new = (mb_y + yoffset) * vwidth + mb_x + xoffset;
998 if (
new < boundary ||
new % vwidth == vwidth - 1)
1000 *edge_y =
new / vwidth;
1001 *edge_x =
new % vwidth;
1012 int mb_x,
int mb_y,
int layout)
1015 enum { CNT_ZERO, CNT_NEAREST, CNT_NEAR };
1016 enum { VP8_EDGE_TOP, VP8_EDGE_LEFT, VP8_EDGE_TOPLEFT };
1032 pred->yoffset, !
s->profile, &edge_x, &edge_y)) {
1034 ?
s->macroblocks_base + 1 + edge_x +
1035 (
s->mb_width + 1) * (edge_y + 1)
1036 :
s->macroblocks + edge_x +
1037 (
s->mb_height - edge_y - 1) * 2;
1040 if (
AV_RN32A(&near_mv[CNT_NEAREST])) {
1043 }
else if (
AV_RN32A(&near_mv[CNT_NEAR])) {
1073 if (cnt[CNT_NEAREST] > cnt[CNT_NEAR])
1074 AV_WN32A(&
mb->mv, cnt[CNT_ZERO] > cnt[CNT_NEAREST] ? 0 :
AV_RN32A(&near_mv[CNT_NEAREST]));
1084 mb->bmv[0] =
mb->mv;
1087 mb->mv = near_mv[CNT_NEAR];
1088 mb->bmv[0] =
mb->mv;
1091 mb->mv = near_mv[CNT_NEAREST];
1092 mb->bmv[0] =
mb->mv;
1097 mb->bmv[0] =
mb->mv;
1103 int mb_x,
int mb_y,
int layout)
1108 enum { CNT_ZERO, CNT_NEAREST, CNT_NEAR, CNT_SPLITMV };
1109 enum { VP8_EDGE_TOP, VP8_EDGE_LEFT, VP8_EDGE_TOPLEFT };
1111 int cur_sign_bias =
s->sign_bias[
mb->ref_frame];
1112 int8_t *sign_bias =
s->sign_bias;
1118 mb_edge[0] =
mb + 2;
1119 mb_edge[2] =
mb + 1;
1121 mb_edge[0] =
mb -
s->mb_width - 1;
1122 mb_edge[2] =
mb -
s->mb_width - 2;
1130 #define MV_EDGE_CHECK(n) \
1132 VP8Macroblock *edge = mb_edge[n]; \
1133 int edge_ref = edge->ref_frame; \
1134 if (edge_ref != VP56_FRAME_CURRENT) { \
1135 uint32_t mv = AV_RN32A(&edge->mv); \
1137 if (cur_sign_bias != sign_bias[edge_ref]) { \
1140 mv = ((mv & 0x7fff7fff) + \
1141 0x00010001) ^ (mv & 0x80008000); \
1143 if (!n || mv != AV_RN32A(&near_mv[idx])) \
1144 AV_WN32A(&near_mv[++idx], mv); \
1145 cnt[idx] += 1 + (n != 2); \
1147 cnt[CNT_ZERO] += 1 + (n != 2); \
1160 if (cnt[CNT_SPLITMV] &&
1161 AV_RN32A(&near_mv[1 + VP8_EDGE_TOP]) ==
AV_RN32A(&near_mv[1 + VP8_EDGE_TOPLEFT]))
1162 cnt[CNT_NEAREST] += 1;
1165 if (cnt[CNT_NEAR] > cnt[CNT_NEAREST]) {
1167 FFSWAP(
VP56mv, near_mv[CNT_NEAREST], near_mv[CNT_NEAR]);
1173 clamp_mv(mv_bounds, &
mb->mv, &near_mv[CNT_ZERO + (cnt[CNT_NEAREST] >= cnt[CNT_ZERO])]);
1184 mb->bmv[0] =
mb->mv;
1187 clamp_mv(mv_bounds, &
mb->mv, &near_mv[CNT_NEAR]);
1188 mb->bmv[0] =
mb->mv;
1191 clamp_mv(mv_bounds, &
mb->mv, &near_mv[CNT_NEAREST]);
1192 mb->bmv[0] =
mb->mv;
1197 mb->bmv[0] =
mb->mv;
1203 int mb_x,
int keyframe,
int layout)
1205 uint8_t *intra4x4 =
mb->intra4x4_pred_mode_mb;
1216 top =
mb->intra4x4_pred_mode_top;
1218 top =
s->intra4x4_pred_mode_top + 4 * mb_x;
1219 for (y = 0; y < 4; y++) {
1220 for (x = 0; x < 4; x++) {
1224 left[y] = top[x] = *intra4x4;
1230 for (
i = 0;
i < 16;
i++)
1242 static const char *
const vp7_feature_name[] = {
"q-index",
1244 "partial-golden-update",
1249 for (
i = 0;
i < 4;
i++) {
1250 if (
s->feature_enabled[
i]) {
1253 s->feature_index_prob[
i]);
1255 "Feature %s present in macroblock (value 0x%x)\n",
1256 vp7_feature_name[
i],
s->feature_value[
i][
index]);
1260 }
else if (
s->segmentation.update_map) {
1263 }
else if (
s->segmentation.enabled)
1296 s->ref_count[
mb->ref_frame - 1]++;
1331 int i,
uint8_t *token_prob, int16_t qmul[2],
1332 const uint8_t scan[16],
int vp7)
1346 token_prob = probs[
i][0];
1354 token_prob = probs[
i + 1][1];
1374 int cat = (
a << 1) +
b;
1379 token_prob = probs[
i + 1][2];
1419 token_prob, qmul, scan,
IS_VP7);
1422 #ifndef vp8_decode_block_coeffs_internal
1450 int i,
int zero_nhood, int16_t qmul[2],
1451 const uint8_t scan[16],
int vp7)
1453 uint8_t *token_prob = probs[
i][zero_nhood];
1457 token_prob, qmul, scan)
1467 int i, x, y, luma_start = 0, luma_ctx = 3;
1468 int nnz_pred, nnz, nnz_total = 0;
1473 nnz_pred = t_nnz[8] + l_nnz[8];
1477 nnz_pred,
s->qmat[
segment].luma_dc_qmul,
1479 l_nnz[8] = t_nnz[8] = !!nnz;
1483 s->inter_dc_pred[
mb->ref_frame - 1]);
1490 s->vp8dsp.vp8_luma_dc_wht_dc(
td->block,
td->block_dc);
1492 s->vp8dsp.vp8_luma_dc_wht(
td->block,
td->block_dc);
1499 for (y = 0; y < 4; y++)
1500 for (x = 0; x < 4; x++) {
1501 nnz_pred = l_nnz[y] + t_nnz[x];
1503 s->prob->token[luma_ctx],
1504 luma_start, nnz_pred,
1506 s->prob[0].scan, is_vp7);
1509 td->non_zero_count_cache[y][x] = nnz + block_dc;
1510 t_nnz[x] = l_nnz[y] = !!nnz;
1517 for (
i = 4;
i < 6;
i++)
1518 for (y = 0; y < 2; y++)
1519 for (x = 0; x < 2; x++) {
1520 nnz_pred = l_nnz[
i + 2 * y] + t_nnz[
i + 2 * x];
1522 s->prob->token[2], 0, nnz_pred,
1524 s->prob[0].scan, is_vp7);
1525 td->non_zero_count_cache[
i][(y << 1) + x] = nnz;
1526 t_nnz[
i + 2 * x] = l_nnz[
i + 2 * y] = !!nnz;
1540 ptrdiff_t linesize, ptrdiff_t uvlinesize,
int simple)
1542 AV_COPY128(top_border, src_y + 15 * linesize);
1544 AV_COPY64(top_border + 16, src_cb + 7 * uvlinesize);
1545 AV_COPY64(top_border + 24, src_cr + 7 * uvlinesize);
1551 uint8_t *src_cr, ptrdiff_t linesize, ptrdiff_t uvlinesize,
int mb_x,
1552 int mb_y,
int mb_width,
int simple,
int xchg)
1554 uint8_t *top_border_m1 = top_border - 32;
1556 src_cb -= uvlinesize;
1557 src_cr -= uvlinesize;
1559 #define XCHG(a, b, xchg) \
1567 XCHG(top_border_m1 + 8, src_y - 8, xchg);
1568 XCHG(top_border, src_y, xchg);
1569 XCHG(top_border + 8, src_y + 8, 1);
1570 if (mb_x < mb_width - 1)
1571 XCHG(top_border + 32, src_y + 16, 1);
1575 if (!simple || !mb_y) {
1576 XCHG(top_border_m1 + 16, src_cb - 8, xchg);
1577 XCHG(top_border_m1 + 24, src_cr - 8, xchg);
1578 XCHG(top_border + 16, src_cb, 1);
1579 XCHG(top_border + 24, src_cr, 1);
1629 int *copy_buf,
int vp7)
1633 if (!mb_x && mb_y) {
1667 int x, y,
mode, nnz;
1672 if (mb_y && (
s->deblock_filter || !mb_y) &&
td->thread_nr == 0)
1674 s->linesize,
s->uvlinesize, mb_x, mb_y,
s->mb_width,
1675 s->filter.simple, 1);
1679 s->hpc.pred16x16[
mode](dst[0],
s->linesize);
1682 uint8_t *intra4x4 =
mb->intra4x4_pred_mode_mb;
1683 const uint8_t lo = is_vp7 ? 128 : 127;
1684 const uint8_t hi = is_vp7 ? 128 : 129;
1685 uint8_t tr_top[4] = { lo, lo, lo, lo };
1689 uint8_t *tr_right = ptr -
s->linesize + 16;
1693 if (mb_y && mb_x ==
s->mb_width - 1) {
1694 tr = tr_right[-1] * 0x01010101
u;
1701 for (y = 0; y < 4; y++) {
1702 uint8_t *topright = ptr + 4 -
s->linesize;
1703 for (x = 0; x < 4; x++) {
1705 ptrdiff_t linesize =
s->linesize;
1709 if ((y == 0 || x == 3) && mb_y == 0) {
1712 topright = tr_right;
1715 mb_y + y, &
copy, is_vp7);
1717 dst = copy_dst + 12;
1721 AV_WN32A(copy_dst + 4, lo * 0x01010101U);
1723 AV_COPY32(copy_dst + 4, ptr + 4 * x -
s->linesize);
1727 copy_dst[3] = ptr[4 * x -
s->linesize - 1];
1736 copy_dst[11] = ptr[4 * x - 1];
1737 copy_dst[19] = ptr[4 * x +
s->linesize - 1];
1738 copy_dst[27] = ptr[4 * x +
s->linesize * 2 - 1];
1739 copy_dst[35] = ptr[4 * x +
s->linesize * 3 - 1];
1742 s->hpc.pred4x4[
mode](dst, topright, linesize);
1745 AV_COPY32(ptr + 4 * x +
s->linesize, copy_dst + 20);
1746 AV_COPY32(ptr + 4 * x +
s->linesize * 2, copy_dst + 28);
1747 AV_COPY32(ptr + 4 * x +
s->linesize * 3, copy_dst + 36);
1750 nnz =
td->non_zero_count_cache[y][x];
1753 s->vp8dsp.vp8_idct_dc_add(ptr + 4 * x,
1754 td->block[y][x],
s->linesize);
1756 s->vp8dsp.vp8_idct_add(ptr + 4 * x,
1757 td->block[y][x],
s->linesize);
1762 ptr += 4 *
s->linesize;
1768 mb_x, mb_y, is_vp7);
1769 s->hpc.pred8x8[
mode](dst[1],
s->uvlinesize);
1770 s->hpc.pred8x8[
mode](dst[2],
s->uvlinesize);
1772 if (mb_y && (
s->deblock_filter || !mb_y) &&
td->thread_nr == 0)
1774 s->linesize,
s->uvlinesize, mb_x, mb_y,
s->mb_width,
1775 s->filter.simple, 0);
1779 { 0, 1, 2, 1, 2, 1, 2, 1 },
1781 { 0, 3, 5, 3, 5, 3, 5, 3 },
1782 { 0, 2, 3, 2, 3, 2, 3, 2 },
1804 int x_off,
int y_off,
int block_w,
int block_h,
1811 ptrdiff_t src_linesize = linesize;
1816 x_off +=
mv->x >> 2;
1817 y_off +=
mv->y >> 2;
1821 src += y_off * linesize + x_off;
1824 s->vdsp.emulated_edge_mc(
td->edge_emu_buffer,
1825 src - my_idx * linesize - mx_idx,
1829 x_off - mx_idx, y_off - my_idx,
1834 mc_func[my_idx][mx_idx](dst, linesize,
src, src_linesize, block_h, mx, my);
1837 mc_func[0][0](dst, linesize,
src + y_off * linesize + x_off,
1838 linesize, block_h, 0, 0);
1862 int x_off,
int y_off,
int block_w,
int block_h,
1872 x_off +=
mv->x >> 3;
1873 y_off +=
mv->y >> 3;
1876 src1 += y_off * linesize + x_off;
1877 src2 += y_off * linesize + x_off;
1881 s->vdsp.emulated_edge_mc(
td->edge_emu_buffer,
1882 src1 - my_idx * linesize - mx_idx,
1890 s->vdsp.emulated_edge_mc(
td->edge_emu_buffer,
1891 src2 - my_idx * linesize - mx_idx,
1897 mc_func[my_idx][mx_idx](dst2, linesize, src2,
EDGE_EMU_LINESIZE, block_h, mx, my);
1899 mc_func[my_idx][mx_idx](dst1, linesize,
src1, linesize, block_h, mx, my);
1900 mc_func[my_idx][mx_idx](dst2, linesize, src2, linesize, block_h, mx, my);
1904 mc_func[0][0](dst1, linesize,
src1 + y_off * linesize + x_off, linesize, block_h, 0, 0);
1905 mc_func[0][0](dst2, linesize, src2 + y_off * linesize + x_off, linesize, block_h, 0, 0);
1912 int bx_off,
int by_off,
int block_w,
int block_h,
1919 ref_frame,
mv, x_off + bx_off, y_off + by_off,
1921 s->put_pixels_tab[block_w == 8]);
1924 if (
s->profile == 3) {
1939 dst[2] + by_off *
s->uvlinesize + bx_off, ref_frame,
1940 &uvmv, x_off + bx_off, y_off + by_off,
1942 s->put_pixels_tab[1 + (block_w == 4)]);
1952 if (
s->ref_count[
ref - 1] > (mb_xy >> 5)) {
1953 int x_off = mb_x << 4, y_off = mb_y << 4;
1954 int mx = (
mb->mv.x >> 2) + x_off + 8;
1955 int my = (
mb->mv.y >> 2) + y_off;
1957 int off = mx + (my + (mb_x & 3) * 4) *
s->linesize + 64;
1961 s->vdsp.prefetch(
src[0] + off,
s->linesize, 4);
1962 off = (mx >> 1) + ((my >> 1) + (mb_x & 7)) *
s->uvlinesize + 64;
1963 s->vdsp.prefetch(
src[1] + off,
src[2] -
src[1], 2);
1974 int x_off = mb_x << 4, y_off = mb_y << 4;
1979 switch (
mb->partitioning) {
1989 for (y = 0; y < 4; y++) {
1990 for (x = 0; x < 4; x++) {
1992 ref, &bmv[4 * y + x],
1993 4 * x + x_off, 4 * y + y_off, 4, 4,
1995 s->put_pixels_tab[2]);
2004 for (y = 0; y < 2; y++) {
2005 for (x = 0; x < 2; x++) {
2006 uvmv.
x =
mb->bmv[2 * y * 4 + 2 * x ].x +
2007 mb->bmv[2 * y * 4 + 2 * x + 1].x +
2008 mb->bmv[(2 * y + 1) * 4 + 2 * x ].x +
2009 mb->bmv[(2 * y + 1) * 4 + 2 * x + 1].x;
2010 uvmv.
y =
mb->bmv[2 * y * 4 + 2 * x ].y +
2011 mb->bmv[2 * y * 4 + 2 * x + 1].y +
2012 mb->bmv[(2 * y + 1) * 4 + 2 * x ].y +
2013 mb->bmv[(2 * y + 1) * 4 + 2 * x + 1].y;
2016 if (
s->profile == 3) {
2021 dst[2] + 4 * y *
s->uvlinesize + x * 4,
ref,
2022 &uvmv, 4 * x + x_off, 4 * y + y_off, 4, 4,
2024 s->put_pixels_tab[2]);
2061 for (y = 0; y < 4; y++) {
2062 uint32_t nnz4 =
AV_RL32(
td->non_zero_count_cache[y]);
2064 if (nnz4 & ~0x01010101) {
2065 for (x = 0; x < 4; x++) {
2067 s->vp8dsp.vp8_idct_dc_add(y_dst + 4 * x,
2071 s->vp8dsp.vp8_idct_add(y_dst + 4 * x,
2079 s->vp8dsp.vp8_idct_dc_add4y(y_dst,
td->block[y],
s->linesize);
2082 y_dst += 4 *
s->linesize;
2086 for (
ch = 0;
ch < 2;
ch++) {
2087 uint32_t nnz4 =
AV_RL32(
td->non_zero_count_cache[4 +
ch]);
2090 if (nnz4 & ~0x01010101) {
2091 for (y = 0; y < 2; y++) {
2092 for (x = 0; x < 2; x++) {
2094 s->vp8dsp.vp8_idct_dc_add(ch_dst + 4 * x,
2095 td->block[4 +
ch][(y << 1) + x],
2098 s->vp8dsp.vp8_idct_add(ch_dst + 4 * x,
2099 td->block[4 +
ch][(y << 1) + x],
2103 goto chroma_idct_end;
2105 ch_dst += 4 *
s->uvlinesize;
2108 s->vp8dsp.vp8_idct_dc_add4uv(ch_dst,
td->block[4 +
ch],
s->uvlinesize);
2120 int interior_limit, filter_level;
2122 if (
s->segmentation.enabled) {
2123 filter_level =
s->segmentation.filter_level[
mb->segment];
2124 if (!
s->segmentation.absolute_vals)
2125 filter_level +=
s->filter.level;
2127 filter_level =
s->filter.level;
2129 if (
s->lf_delta.enabled) {
2130 filter_level +=
s->lf_delta.ref[
mb->ref_frame];
2131 filter_level +=
s->lf_delta.mode[
mb->mode];
2134 filter_level = av_clip_uintp2(filter_level, 6);
2136 interior_limit = filter_level;
2137 if (
s->filter.sharpness) {
2138 interior_limit >>= (
s->filter.sharpness + 3) >> 2;
2139 interior_limit =
FFMIN(interior_limit, 9 -
s->filter.sharpness);
2141 interior_limit =
FFMAX(interior_limit, 1);
2143 f->filter_level = filter_level;
2144 f->inner_limit = interior_limit;
2145 f->inner_filter = is_vp7 || !
mb->skip ||
mb->mode ==
MODE_I4x4 ||
2151 int mb_x,
int mb_y,
int is_vp7)
2153 int mbedge_lim, bedge_lim_y, bedge_lim_uv, hev_thresh;
2154 int filter_level =
f->filter_level;
2155 int inner_limit =
f->inner_limit;
2156 int inner_filter =
f->inner_filter;
2157 ptrdiff_t linesize =
s->linesize;
2158 ptrdiff_t uvlinesize =
s->uvlinesize;
2159 static const uint8_t hev_thresh_lut[2][64] = {
2160 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1,
2161 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2162 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
2164 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1,
2165 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2166 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2174 bedge_lim_y = filter_level;
2175 bedge_lim_uv = filter_level * 2;
2176 mbedge_lim = filter_level + 2;
2179 bedge_lim_uv = filter_level * 2 + inner_limit;
2180 mbedge_lim = bedge_lim_y + 4;
2183 hev_thresh = hev_thresh_lut[
s->keyframe][filter_level];
2186 s->vp8dsp.vp8_h_loop_filter16y(dst[0], linesize,
2187 mbedge_lim, inner_limit, hev_thresh);
2188 s->vp8dsp.vp8_h_loop_filter8uv(dst[1], dst[2], uvlinesize,
2189 mbedge_lim, inner_limit, hev_thresh);
2192 #define H_LOOP_FILTER_16Y_INNER(cond) \
2193 if (cond && inner_filter) { \
2194 s->vp8dsp.vp8_h_loop_filter16y_inner(dst[0] + 4, linesize, \
2195 bedge_lim_y, inner_limit, \
2197 s->vp8dsp.vp8_h_loop_filter16y_inner(dst[0] + 8, linesize, \
2198 bedge_lim_y, inner_limit, \
2200 s->vp8dsp.vp8_h_loop_filter16y_inner(dst[0] + 12, linesize, \
2201 bedge_lim_y, inner_limit, \
2203 s->vp8dsp.vp8_h_loop_filter8uv_inner(dst[1] + 4, dst[2] + 4, \
2204 uvlinesize, bedge_lim_uv, \
2205 inner_limit, hev_thresh); \
2211 s->vp8dsp.vp8_v_loop_filter16y(dst[0], linesize,
2212 mbedge_lim, inner_limit, hev_thresh);
2213 s->vp8dsp.vp8_v_loop_filter8uv(dst[1], dst[2], uvlinesize,
2214 mbedge_lim, inner_limit, hev_thresh);
2218 s->vp8dsp.vp8_v_loop_filter16y_inner(dst[0] + 4 * linesize,
2219 linesize, bedge_lim_y,
2220 inner_limit, hev_thresh);
2221 s->vp8dsp.vp8_v_loop_filter16y_inner(dst[0] + 8 * linesize,
2222 linesize, bedge_lim_y,
2223 inner_limit, hev_thresh);
2224 s->vp8dsp.vp8_v_loop_filter16y_inner(dst[0] + 12 * linesize,
2225 linesize, bedge_lim_y,
2226 inner_limit, hev_thresh);
2227 s->vp8dsp.vp8_v_loop_filter8uv_inner(dst[1] + 4 * uvlinesize,
2228 dst[2] + 4 * uvlinesize,
2229 uvlinesize, bedge_lim_uv,
2230 inner_limit, hev_thresh);
2240 int mbedge_lim, bedge_lim;
2241 int filter_level =
f->filter_level;
2242 int inner_limit =
f->inner_limit;
2243 int inner_filter =
f->inner_filter;
2244 ptrdiff_t linesize =
s->linesize;
2249 bedge_lim = 2 * filter_level + inner_limit;
2250 mbedge_lim = bedge_lim + 4;
2253 s->vp8dsp.vp8_h_loop_filter_simple(dst, linesize, mbedge_lim);
2255 s->vp8dsp.vp8_h_loop_filter_simple(dst + 4, linesize, bedge_lim);
2256 s->vp8dsp.vp8_h_loop_filter_simple(dst + 8, linesize, bedge_lim);
2257 s->vp8dsp.vp8_h_loop_filter_simple(dst + 12, linesize, bedge_lim);
2261 s->vp8dsp.vp8_v_loop_filter_simple(dst, linesize, mbedge_lim);
2263 s->vp8dsp.vp8_v_loop_filter_simple(dst + 4 * linesize, linesize, bedge_lim);
2264 s->vp8dsp.vp8_v_loop_filter_simple(dst + 8 * linesize, linesize, bedge_lim);
2265 s->vp8dsp.vp8_v_loop_filter_simple(dst + 12 * linesize, linesize, bedge_lim);
2269 #define MARGIN (16 << 2)
2277 s->mv_bounds.mv_min.y = -
MARGIN;
2278 s->mv_bounds.mv_max.y = ((
s->mb_height - 1) << 6) +
MARGIN;
2279 for (mb_y = 0; mb_y <
s->mb_height; mb_y++) {
2281 ((
s->mb_width + 1) * (mb_y + 1) + 1);
2282 int mb_xy = mb_y *
s->mb_width;
2286 s->mv_bounds.mv_min.x = -
MARGIN;
2287 s->mv_bounds.mv_max.x = ((
s->mb_width - 1) << 6) +
MARGIN;
2289 for (mb_x = 0; mb_x <
s->mb_width; mb_x++, mb_xy++,
mb++) {
2294 AV_WN32A((
mb -
s->mb_width - 1)->intra4x4_pred_mode_top,
2297 prev_frame && prev_frame->
seg_map ?
2299 s->mv_bounds.mv_min.x -= 64;
2300 s->mv_bounds.mv_max.x -= 64;
2302 s->mv_bounds.mv_min.y -= 64;
2303 s->mv_bounds.mv_max.y -= 64;
2321 #define check_thread_pos(td, otd, mb_x_check, mb_y_check) \
2323 int tmp = (mb_y_check << 16) | (mb_x_check & 0xFFFF); \
2324 if (atomic_load(&otd->thread_mb_pos) < tmp) { \
2325 pthread_mutex_lock(&otd->lock); \
2326 atomic_store(&td->wait_mb_pos, tmp); \
2328 if (atomic_load(&otd->thread_mb_pos) >= tmp) \
2330 pthread_cond_wait(&otd->cond, &otd->lock); \
2332 atomic_store(&td->wait_mb_pos, INT_MAX); \
2333 pthread_mutex_unlock(&otd->lock); \
2337 #define update_pos(td, mb_y, mb_x) \
2339 int pos = (mb_y << 16) | (mb_x & 0xFFFF); \
2340 int sliced_threading = (avctx->active_thread_type == FF_THREAD_SLICE) && \
2342 int is_null = !next_td || !prev_td; \
2343 int pos_check = (is_null) ? 1 : \
2344 (next_td != td && pos >= atomic_load(&next_td->wait_mb_pos)) || \
2345 (prev_td != td && pos >= atomic_load(&prev_td->wait_mb_pos)); \
2346 atomic_store(&td->thread_mb_pos, pos); \
2347 if (sliced_threading && pos_check) { \
2348 pthread_mutex_lock(&td->lock); \
2349 pthread_cond_broadcast(&td->cond); \
2350 pthread_mutex_unlock(&td->lock); \
2354 #define check_thread_pos(td, otd, mb_x_check, mb_y_check) while(0)
2355 #define update_pos(td, mb_y, mb_x) while(0)
2359 int jobnr,
int threadnr,
int is_vp7)
2364 int mb_x, mb_xy = mb_y *
s->mb_width;
2365 int num_jobs =
s->num_jobs;
2366 VP8Frame *curframe =
s->curframe, *prev_frame =
s->prev_frame;
2370 curframe->
tf.
f->
data[0] + 16 * mb_y *
s->linesize,
2371 curframe->
tf.
f->
data[1] + 8 * mb_y *
s->uvlinesize,
2372 curframe->
tf.
f->
data[2] + 8 * mb_y *
s->uvlinesize
2381 prev_td = &
s->thread_data[(jobnr + num_jobs - 1) % num_jobs];
2382 if (mb_y ==
s->mb_height - 1)
2385 next_td = &
s->thread_data[(jobnr + 1) % num_jobs];
2386 if (
s->mb_layout == 1)
2387 mb =
s->macroblocks_base + ((
s->mb_width + 1) * (mb_y + 1) + 1);
2391 if (prev_frame &&
s->segmentation.enabled &&
2392 !
s->segmentation.update_map)
2394 mb =
s->macroblocks + (
s->mb_height - mb_y - 1) * 2;
2395 memset(
mb - 1, 0,
sizeof(*
mb));
2399 if (!is_vp7 || mb_y == 0)
2400 memset(
td->left_nnz, 0,
sizeof(
td->left_nnz));
2403 td->mv_bounds.mv_max.x = ((
s->mb_width - 1) << 6) +
MARGIN;
2405 for (mb_x = 0; mb_x <
s->mb_width; mb_x++, mb_xy++,
mb++) {
2409 if (prev_td !=
td) {
2410 if (threadnr != 0) {
2412 mb_x + (is_vp7 ? 2 : 1),
2413 mb_y - (is_vp7 ? 2 : 1));
2416 mb_x + (is_vp7 ? 2 : 1) +
s->mb_width + 3,
2417 mb_y - (is_vp7 ? 2 : 1));
2421 s->vdsp.prefetch(dst[0] + (mb_x & 3) * 4 *
s->linesize + 64,
2423 s->vdsp.prefetch(dst[1] + (mb_x & 7) *
s->uvlinesize + 64,
2424 dst[2] - dst[1], 2);
2428 prev_frame && prev_frame->seg_map ?
2429 prev_frame->seg_map->data + mb_xy :
NULL, 0, is_vp7);
2452 td->left_nnz[8] = 0;
2453 s->top_nnz[mb_x][8] = 0;
2457 if (
s->deblock_filter)
2460 if (
s->deblock_filter && num_jobs != 1 && threadnr == num_jobs - 1) {
2461 if (
s->filter.simple)
2466 dst[1], dst[2],
s->linesize,
s->uvlinesize, 0);
2474 td->mv_bounds.mv_min.x -= 64;
2475 td->mv_bounds.mv_max.x -= 64;
2477 if (mb_x ==
s->mb_width + 1) {
2487 int jobnr,
int threadnr)
2493 int jobnr,
int threadnr)
2499 int jobnr,
int threadnr,
int is_vp7)
2503 int mb_x, mb_y =
atomic_load(&
td->thread_mb_pos) >> 16, num_jobs =
s->num_jobs;
2504 AVFrame *curframe =
s->curframe->tf.f;
2508 curframe->
data[0] + 16 * mb_y *
s->linesize,
2509 curframe->
data[1] + 8 * mb_y *
s->uvlinesize,
2510 curframe->
data[2] + 8 * mb_y *
s->uvlinesize
2513 if (
s->mb_layout == 1)
2514 mb =
s->macroblocks_base + ((
s->mb_width + 1) * (mb_y + 1) + 1);
2516 mb =
s->macroblocks + (
s->mb_height - mb_y - 1) * 2;
2521 prev_td = &
s->thread_data[(jobnr + num_jobs - 1) % num_jobs];
2522 if (mb_y ==
s->mb_height - 1)
2525 next_td = &
s->thread_data[(jobnr + 1) % num_jobs];
2527 for (mb_x = 0; mb_x <
s->mb_width; mb_x++,
mb++) {
2531 (mb_x + 1) + (
s->mb_width + 3), mb_y - 1);
2533 if (next_td != &
s->thread_data[0])
2536 if (num_jobs == 1) {
2537 if (
s->filter.simple)
2542 dst[1], dst[2],
s->linesize,
s->uvlinesize, 0);
2545 if (
s->filter.simple)
2558 int jobnr,
int threadnr)
2564 int jobnr,
int threadnr)
2571 int threadnr,
int is_vp7)
2577 int mb_y, num_jobs =
s->num_jobs;
2580 td->thread_nr = threadnr;
2581 td->mv_bounds.mv_min.y = -
MARGIN - 64 * threadnr;
2582 td->mv_bounds.mv_max.y = ((
s->mb_height - 1) << 6) +
MARGIN - 64 * threadnr;
2583 for (mb_y = jobnr; mb_y <
s->mb_height; mb_y += num_jobs) {
2585 ret =
s->decode_mb_row_no_filter(avctx, tdata, jobnr, threadnr);
2590 if (
s->deblock_filter)
2591 s->filter_mb_row(avctx, tdata, jobnr, threadnr);
2594 td->mv_bounds.mv_min.y -= 64 * num_jobs;
2595 td->mv_bounds.mv_max.y -= 64 * num_jobs;
2605 int jobnr,
int threadnr)
2611 int jobnr,
int threadnr)
2621 int ret,
i, referenced, num_jobs;
2633 if (
s->actually_webp) {
2637 if (
s->pix_fmt < 0) {
2655 memcpy(&
s->next_framep[0], &
s->framep[0],
sizeof(
s->framep[0]) * 4);
2661 for (
i = 0;
i < 5;
i++)
2662 if (
s->frames[
i].tf.f->buf[0] &&
2663 &
s->frames[
i] != prev_frame &&
2686 "Discarding interframe without a prior keyframe!\n");
2691 curframe->tf.f->key_frame =
s->keyframe;
2731 s->linesize = curframe->tf.f->linesize[0];
2732 s->uvlinesize = curframe->tf.f->linesize[1];
2734 memset(
s->top_nnz, 0,
s->mb_width *
sizeof(*
s->top_nnz));
2738 memset(
s->macroblocks +
s->mb_height * 2 - 1, 0,
2739 (
s->mb_width + 1) *
sizeof(*
s->macroblocks));
2740 if (!
s->mb_layout &&
s->keyframe)
2741 memset(
s->intra4x4_pred_mode_top,
DC_PRED,
s->mb_width * 4);
2743 memset(
s->ref_count, 0,
sizeof(
s->ref_count));
2745 if (
s->mb_layout == 1) {
2748 if (prev_frame &&
s->segmentation.enabled &&
2749 !
s->segmentation.update_map)
2763 s->num_jobs = num_jobs;
2764 s->curframe = curframe;
2765 s->prev_frame = prev_frame;
2766 s->mv_bounds.mv_min.y = -
MARGIN;
2767 s->mv_bounds.mv_max.y = ((
s->mb_height - 1) << 6) +
MARGIN;
2782 memcpy(&
s->framep[0], &
s->next_framep[0],
sizeof(
s->framep[0]) * 4);
2787 if (!
s->update_probabilities)
2788 s->prob[0] =
s->prob[1];
2790 if (!
s->invisible) {
2798 memcpy(&
s->next_framep[0], &
s->framep[0],
sizeof(
s->framep[0]) * 4);
2808 #if CONFIG_VP7_DECODER
2836 if (!
s->frames[
i].tf.f)
2857 if (CONFIG_VP7_DECODER && is_vp7) {
2862 }
else if (CONFIG_VP8_DECODER && !is_vp7) {
2880 #if CONFIG_VP7_DECODER
2892 #if CONFIG_VP8_DECODER
2909 #define REBASE(pic) ((pic) ? (pic) - &s_src->frames[0] + &s->frames[0] : NULL)
2917 if (
s->macroblocks_base &&
2918 (s_src->mb_width !=
s->mb_width || s_src->mb_height !=
s->mb_height)) {
2920 s->mb_width = s_src->mb_width;
2921 s->mb_height = s_src->mb_height;
2924 s->pix_fmt = s_src->pix_fmt;
2925 s->prob[0] = s_src->prob[!s_src->update_probabilities];
2926 s->segmentation = s_src->segmentation;
2927 s->lf_delta = s_src->lf_delta;
2928 memcpy(
s->sign_bias, s_src->sign_bias,
sizeof(
s->sign_bias));
2931 if (s_src->frames[
i].tf.f->buf[0]) {
2932 int ret = vp8_ref_frame(
s, &
s->frames[
i], &s_src->frames[
i]);
2938 s->framep[0] = REBASE(s_src->next_framep[0]);
2939 s->framep[1] = REBASE(s_src->next_framep[1]);
2940 s->framep[2] = REBASE(s_src->next_framep[2]);
2941 s->framep[3] = REBASE(s_src->next_framep[3]);
2948 #if CONFIG_VP7_DECODER
2955 .
init = vp7_decode_init,
2957 .
decode = vp7_decode_frame,
2963 #if CONFIG_VP8_DECODER
2979 #if CONFIG_VP8_VAAPI_HWACCEL
2982 #if CONFIG_VP8_NVDEC_HWACCEL
static const int vp8_mode_contexts[6][4]
#define HWACCEL_NVDEC(codec)
static const uint8_t vp8_dct_cat1_prob[]
#define VP7_MV_PRED_COUNT
const struct AVHWAccel * hwaccel
Hardware accelerator in use.
av_cold int ff_vp8_decode_free(AVCodecContext *avctx)
static const uint8_t vp7_pred4x4_mode[]
static const VP7MVPred vp7_mv_pred[VP7_MV_PRED_COUNT]
#define AV_LOG_WARNING
Something somehow does not look correct.
@ AV_PIX_FMT_CUDA
HW acceleration through CUDA.
AVPixelFormat
Pixel format.
static av_always_inline int vp8_rac_get_coeff(VP56RangeCoder *c, const uint8_t *prob)
static int vp7_calculate_mb_offset(int mb_x, int mb_y, int mb_width, int xoffset, int yoffset, int boundary, int *edge_x, int *edge_y)
The vp7 reference decoder uses a padding macroblock column (added to right edge of the frame) to guar...
#define atomic_store(object, desired)
static av_cold int init(AVCodecContext *avctx)
static void vp7_filter_mb_row(AVCodecContext *avctx, void *tdata, int jobnr, int threadnr)
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
static int vp7_read_mv_component(VP56RangeCoder *c, const uint8_t *p)
enum AVColorSpace colorspace
YUV colorspace type.
static av_always_inline int vp78_decode_init(AVCodecContext *avctx, int is_vp7)
int ff_get_format(AVCodecContext *avctx, const enum AVPixelFormat *fmt)
Select the (possibly hardware accelerated) pixel format.
static av_always_inline int vpX_rac_is_end(VP56RangeCoder *c)
vp5689 returns 1 if the end of the stream has been reached, 0 otherwise.
#define FFSWAP(type, a, b)
static av_always_inline int read_mv_component(VP56RangeCoder *c, const uint8_t *p, int vp7)
Motion vector coding, 17.1.
#define u(width, name, range_min, range_max)
static av_always_inline int check_tm_pred8x8_mode(int mode, int mb_x, int mb_y, int vp7)
static const uint8_t vp8_submv_prob[5][3]
uint8_t * data
The data buffer.
static av_always_inline int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr)
static const uint16_t vp7_ydc_qlookup[]
static av_always_inline void clamp_mv(VP8mvbounds *s, VP56mv *dst, const VP56mv *src)
uint8_t pi<< 24) CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_U8,(uint64_t)((*(const uint8_t *) pi - 0x80U))<< 56) CONV_FUNC(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_U8,(*(const uint8_t *) pi - 0x80) *(1.0f/(1<< 7))) CONV_FUNC(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_U8,(*(const uint8_t *) pi - 0x80) *(1.0/(1<< 7))) CONV_FUNC(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S16,(*(const int16_t *) pi >>8)+0x80) CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_S16,(uint64_t)(*(const int16_t *) pi)<< 48) CONV_FUNC(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S16, *(const int16_t *) pi *(1.0f/(1<< 15))) CONV_FUNC(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S16, *(const int16_t *) pi *(1.0/(1<< 15))) CONV_FUNC(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S32,(*(const int32_t *) pi >>24)+0x80) CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_S32,(uint64_t)(*(const int32_t *) pi)<< 32) CONV_FUNC(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S32, *(const int32_t *) pi *(1.0f/(1U<< 31))) CONV_FUNC(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S32, *(const int32_t *) pi *(1.0/(1U<< 31))) CONV_FUNC(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S64,(*(const int64_t *) pi >>56)+0x80) CONV_FUNC(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S64, *(const int64_t *) pi *(1.0f/(INT64_C(1)<< 63))) CONV_FUNC(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S64, *(const int64_t *) pi *(1.0/(INT64_C(1)<< 63))) CONV_FUNC(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_FLT, av_clip_uint8(lrintf(*(const float *) pi *(1<< 7))+0x80)) CONV_FUNC(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_FLT, av_clip_int16(lrintf(*(const float *) pi *(1<< 15)))) CONV_FUNC(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_FLT, av_clipl_int32(llrintf(*(const float *) pi *(1U<< 31)))) CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_FLT, llrintf(*(const float *) pi *(INT64_C(1)<< 63))) CONV_FUNC(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_DBL, av_clip_uint8(lrint(*(const double *) pi *(1<< 7))+0x80)) CONV_FUNC(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_DBL, av_clip_int16(lrint(*(const double *) pi *(1<< 15)))) CONV_FUNC(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_DBL, av_clipl_int32(llrint(*(const double *) pi *(1U<< 31)))) CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_DBL, llrint(*(const double *) pi *(INT64_C(1)<< 63))) #define FMT_PAIR_FUNC(out, in) static conv_func_type *const fmt_pair_to_conv_functions[AV_SAMPLE_FMT_NB *AV_SAMPLE_FMT_NB]={ FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_S64), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S64), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_S64), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S64), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_S64), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_S64), };static void cpy1(uint8_t **dst, const uint8_t **src, int len){ memcpy(*dst, *src, len);} static void cpy2(uint8_t **dst, const uint8_t **src, int len){ memcpy(*dst, *src, 2 *len);} static void cpy4(uint8_t **dst, const uint8_t **src, int len){ memcpy(*dst, *src, 4 *len);} static void cpy8(uint8_t **dst, const uint8_t **src, int len){ memcpy(*dst, *src, 8 *len);} AudioConvert *swri_audio_convert_alloc(enum AVSampleFormat out_fmt, enum AVSampleFormat in_fmt, int channels, const int *ch_map, int flags) { AudioConvert *ctx;conv_func_type *f=fmt_pair_to_conv_functions[av_get_packed_sample_fmt(out_fmt)+AV_SAMPLE_FMT_NB *av_get_packed_sample_fmt(in_fmt)];if(!f) return NULL;ctx=av_mallocz(sizeof(*ctx));if(!ctx) return NULL;if(channels==1){ in_fmt=av_get_planar_sample_fmt(in_fmt);out_fmt=av_get_planar_sample_fmt(out_fmt);} ctx->channels=channels;ctx->conv_f=f;ctx->ch_map=ch_map;if(in_fmt==AV_SAMPLE_FMT_U8||in_fmt==AV_SAMPLE_FMT_U8P) memset(ctx->silence, 0x80, sizeof(ctx->silence));if(out_fmt==in_fmt &&!ch_map) { switch(av_get_bytes_per_sample(in_fmt)){ case 1:ctx->simd_f=cpy1;break;case 2:ctx->simd_f=cpy2;break;case 4:ctx->simd_f=cpy4;break;case 8:ctx->simd_f=cpy8;break;} } if(HAVE_X86ASM &&1) swri_audio_convert_init_x86(ctx, out_fmt, in_fmt, channels);if(ARCH_ARM) swri_audio_convert_init_arm(ctx, out_fmt, in_fmt, channels);if(ARCH_AARCH64) swri_audio_convert_init_aarch64(ctx, out_fmt, in_fmt, channels);return ctx;} void swri_audio_convert_free(AudioConvert **ctx) { av_freep(ctx);} int swri_audio_convert(AudioConvert *ctx, AudioData *out, AudioData *in, int len) { int ch;int off=0;const int os=(out->planar ? 1 :out->ch_count) *out->bps;unsigned misaligned=0;av_assert0(ctx->channels==out->ch_count);if(ctx->in_simd_align_mask) { int planes=in->planar ? in->ch_count :1;unsigned m=0;for(ch=0;ch< planes;ch++) m|=(intptr_t) in->ch[ch];misaligned|=m &ctx->in_simd_align_mask;} if(ctx->out_simd_align_mask) { int planes=out->planar ? out->ch_count :1;unsigned m=0;for(ch=0;ch< planes;ch++) m|=(intptr_t) out->ch[ch];misaligned|=m &ctx->out_simd_align_mask;} if(ctx->simd_f &&!ctx->ch_map &&!misaligned){ off=len &~15;av_assert1(off >=0);av_assert1(off<=len);av_assert2(ctx->channels==SWR_CH_MAX||!in->ch[ctx->channels]);if(off >0){ if(out->planar==in->planar){ int planes=out->planar ? out->ch_count :1;for(ch=0;ch< planes;ch++){ ctx->simd_f(out-> ch ch
#define HOR_VP8_PRED
unaveraged version of HOR_PRED, see
static const int8_t mv[256][2]
static av_always_inline void vp7_decode_mvs(VP8Context *s, VP8Macroblock *mb, int mb_x, int mb_y, int layout)
static const uint8_t vp7_mv_default_prob[2][17]
static av_always_inline int check_intra_pred4x4_mode_emuedge(int mode, int mb_x, int mb_y, int *copy_buf, int vp7)
const uint8_t *const ff_vp8_dct_cat_prob[]
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
static av_always_inline int check_tm_pred4x4_mode(int mode, int mb_x, int mb_y, int vp7)
static const uint16_t vp7_y2dc_qlookup[]
This structure describes decoded (raw) audio or video data.
@ AVCOL_RANGE_JPEG
the normal 2^n-1 "JPEG" YUV ranges
static av_always_inline int inter_predict_dc(int16_t block[16], int16_t pred[2])
static const VP56mv * get_bmv_ptr(const VP8Macroblock *mb, int subblock)
static void vp8_get_quants(VP8Context *s)
AVBufferRef * av_buffer_allocz(int size)
Same as av_buffer_alloc(), except the returned buffer will be initialized to zero.
static VP56Frame ref_to_update(VP8Context *s, int update, VP56Frame ref)
Determine which buffers golden and altref should be updated with after this frame.
static int vp8_decode_block_coeffs_internal(VP56RangeCoder *r, int16_t block[16], uint8_t probs[16][3][NUM_DCT_TOKENS - 1], int i, uint8_t *token_prob, int16_t qmul[2])
static av_always_inline void backup_mb_border(uint8_t *top_border, uint8_t *src_y, uint8_t *src_cb, uint8_t *src_cr, ptrdiff_t linesize, ptrdiff_t uvlinesize, int simple)
@ VP8_SPLITMVMODE_4x4
4x4 blocks of 4x4px each
#define VERT_VP8_PRED
for VP8, VERT_PRED is the average of
the pkt_dts and pkt_pts fields in AVFrame will work as usual Restrictions on codec whose streams don t reset across will not work because their bitstreams cannot be decoded in parallel *The contents of buffers must not be read before ff_thread_await_progress() has been called on them. reget_buffer() and buffer age optimizations no longer work. *The contents of buffers must not be written to after ff_thread_report_progress() has been called on them. This includes draw_edges(). Porting codecs to frame threading
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
static av_unused int vp8_rac_get_nn(VP56RangeCoder *c)
static int vp8_decode_mb_row_no_filter(AVCodecContext *avctx, void *tdata, int jobnr, int threadnr)
static const int8_t vp8_pred8x8c_tree[3][2]
#define bit(string, value)
#define update_pos(td, mb_y, mb_x)
static av_always_inline int update_dimensions(VP8Context *s, int width, int height, int is_vp7)
static av_always_inline int vp56_rac_get_prob_branchy(VP56RangeCoder *c, int prob)
@ AVCOL_SPC_BT470BG
also ITU-R BT601-6 625 / ITU-R BT1358 625 / ITU-R BT1700 625 PAL & SECAM / IEC 61966-2-4 xvYCC601
@ VP8_SPLITMVMODE_8x8
2x2 blocks of 8x8px each
static av_always_inline int vp8_rac_get(VP56RangeCoder *c)
const struct AVCodec * codec
static av_always_inline void filter_level_for_mb(VP8Context *s, VP8Macroblock *mb, VP8FilterStrength *f, int is_vp7)
static const uint8_t vp8_mv_update_prob[2][19]
enum AVDiscard skip_frame
Skip decoding for selected frames.
static av_always_inline void intra_predict(VP8Context *s, VP8ThreadData *td, uint8_t *dst[3], VP8Macroblock *mb, int mb_x, int mb_y, int is_vp7)
int thread_count
thread count is used to decide how many independent tasks should be passed to execute()
static av_unused int vp8_rac_get_sint(VP56RangeCoder *c, int bits)
av_cold void ff_videodsp_init(VideoDSPContext *ctx, int bpc)
static av_always_inline void update(SilenceDetectContext *s, AVFrame *insamples, int is_silence, int current_sample, int64_t nb_samples_notify, AVRational time_base)
static av_always_inline int check_intra_pred8x8_mode_emuedge(int mode, int mb_x, int mb_y, int vp7)
static void vp8_filter_mb_row(AVCodecContext *avctx, void *tdata, int jobnr, int threadnr)
static void vp7_get_quants(VP8Context *s)
@ VP8_SPLITMVMODE_16x8
2 16x8 blocks (vertical)
static av_cold int vp8_init_frames(VP8Context *s)
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
void ff_vp7dsp_init(VP8DSPContext *c)
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
void ff_vp8dsp_init(VP8DSPContext *c)
static const uint8_t vp8_dct_cat2_prob[]
void ff_thread_report_progress(ThreadFrame *f, int n, int field)
Notify later decoding threads when part of their reference picture is ready.
static void decode(AVCodecContext *dec_ctx, AVPacket *pkt, AVFrame *frame, FILE *outfile)
static const uint8_t vp8_pred4x4_mode[]
static const uint8_t vp8_pred8x8c_prob_inter[3]
#define AV_GET_BUFFER_FLAG_REF
The decoder will keep a reference to the frame and may reuse it later.
static const int8_t vp8_pred16x16_tree_intra[4][2]
static void parse_segment_info(VP8Context *s)
static const uint8_t vp8_pred4x4_prob_inter[9]
static enum AVPixelFormat pix_fmts[]
static const uint8_t vp8_mbsplits[5][16]
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_RL16
static av_always_inline int decode_block_coeffs(VP56RangeCoder *c, int16_t block[16], uint8_t probs[16][3][NUM_DCT_TOKENS - 1], int i, int zero_nhood, int16_t qmul[2], const uint8_t scan[16], int vp7)
static const int vp7_mode_contexts[31][4]
static av_always_inline int vp78_decode_mv_mb_modes(AVCodecContext *avctx, VP8Frame *curframe, VP8Frame *prev_frame, int is_vp7)
@ AV_PIX_FMT_YUV420P
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
#define atomic_load(object)
static int vp8_decode_mv_mb_modes(AVCodecContext *avctx, VP8Frame *cur_frame, VP8Frame *prev_frame)
@ VP8_SPLITMVMODE_8x16
2 8x16 blocks (horizontal)
static const uint8_t vp8_mv_default_prob[2][19]
static const int8_t vp8_coeff_band_indexes[8][10]
static const uint8_t vp8_pred16x16_prob_inter[4]
static void vp8_decode_flush_impl(AVCodecContext *avctx, int free_mem)
#define AV_CODEC_CAP_FRAME_THREADS
Codec supports frame-level multithreading.
@ AVDISCARD_ALL
discard all
static av_always_inline void decode_mb_coeffs(VP8Context *s, VP8ThreadData *td, VP56RangeCoder *c, VP8Macroblock *mb, uint8_t t_nnz[9], uint8_t l_nnz[9], int is_vp7)
static void flush(AVCodecContext *avctx)
static const int sizes[][2]
enum AVColorRange color_range
MPEG vs JPEG YUV range.
void av_buffer_unref(AVBufferRef **buf)
Free a given reference and automatically free the buffer if there are no more references to it.
static int vp7_decode_mb_row_sliced(AVCodecContext *avctx, void *tdata, int jobnr, int threadnr)
static int vp8_update_dimensions(VP8Context *s, int width, int height)
static int vp8_rac_get_uint(VP56RangeCoder *c, int bits)
struct AVCodecInternal * internal
Private context used for internal data.
static av_always_inline int vp8_rac_get_tree(VP56RangeCoder *c, const int8_t(*tree)[2], const uint8_t *probs)
int(* end_frame)(AVCodecContext *avctx)
Called at the end of each frame or field picture.
@ AV_PICTURE_TYPE_I
Intra.
AVBufferRef * hwaccel_priv_buf
#define check_thread_pos(td, otd, mb_x_check, mb_y_check)
static const uint16_t vp7_yac_qlookup[]
static const uint8_t vp8_token_default_probs[4][8][3][NUM_DCT_TOKENS - 1]
static av_always_inline void vp8_mc_part(VP8Context *s, VP8ThreadData *td, uint8_t *dst[3], ThreadFrame *ref_frame, int x_off, int y_off, int bx_off, int by_off, int block_w, int block_h, int width, int height, VP56mv *mv)
static av_always_inline int vp78_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt, int is_vp7)
static const uint8_t vp8_token_update_probs[4][8][3][NUM_DCT_TOKENS - 1]
#define ONLY_IF_THREADS_ENABLED(x)
Define a function with only the non-default version specified.
int ff_thread_get_buffer(AVCodecContext *avctx, ThreadFrame *f, int flags)
Wrapper around get_buffer() for frame-multithreaded codecs.
static const uint8_t vp8_mbsplit_count[4]
int ff_vp8_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt)
static av_always_inline int decode_mb_row_no_filter(AVCodecContext *avctx, void *tdata, int jobnr, int threadnr, int is_vp7)
static const uint8_t vp7_feature_value_size[2][4]
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
void(* vp8_mc_func)(uint8_t *dst, ptrdiff_t dstStride, uint8_t *src, ptrdiff_t srcStride, int h, int x, int y)
av_cold int ff_vp8_decode_init(AVCodecContext *avctx)
static const uint8_t vp8_mbfirstidx[4][16]
@ AVDISCARD_NONKEY
discard all frames except keyframes
static av_always_inline void xchg_mb_border(uint8_t *top_border, uint8_t *src_y, uint8_t *src_cb, uint8_t *src_cr, ptrdiff_t linesize, ptrdiff_t uvlinesize, int mb_x, int mb_y, int mb_width, int simple, int xchg)
const uint8_t ff_zigzag_scan[16+1]
#define AV_CODEC_CAP_DR1
Codec uses get_buffer() for allocating buffers and supports custom allocators.
static const int8_t vp8_pred4x4_tree[9][2]
Tag MUST be and< 10hcoeff half pel interpolation filter coefficients, hcoeff[0] are the 2 middle coefficients[1] are the next outer ones and so on, resulting in a filter like:...eff[2], hcoeff[1], hcoeff[0], hcoeff[0], hcoeff[1], hcoeff[2] ... the sign of the coefficients is not explicitly stored but alternates after each coeff and coeff[0] is positive, so ...,+,-,+,-,+,+,-,+,-,+,... hcoeff[0] is not explicitly stored but found by subtracting the sum of all stored coefficients with signs from 32 hcoeff[0]=32 - hcoeff[1] - hcoeff[2] - ... a good choice for hcoeff and htaps is htaps=6 hcoeff={40,-10, 2} an alternative which requires more computations at both encoder and decoder side and may or may not be better is htaps=8 hcoeff={42,-14, 6,-2}ref_frames minimum of the number of available reference frames and max_ref_frames for example the first frame after a key frame always has ref_frames=1spatial_decomposition_type wavelet type 0 is a 9/7 symmetric compact integer wavelet 1 is a 5/3 symmetric compact integer wavelet others are reserved stored as delta from last, last is reset to 0 if always_reset||keyframeqlog quality(logarithmic quantizer scale) stored as delta from last, last is reset to 0 if always_reset||keyframemv_scale stored as delta from last, last is reset to 0 if always_reset||keyframe FIXME check that everything works fine if this changes between framesqbias dequantization bias stored as delta from last, last is reset to 0 if always_reset||keyframeblock_max_depth maximum depth of the block tree stored as delta from last, last is reset to 0 if always_reset||keyframequant_table quantization tableHighlevel bitstream structure:==============================--------------------------------------------|Header|--------------------------------------------|------------------------------------|||Block0||||split?||||yes no||||......... intra?||||:Block01 :yes no||||:Block02 :....... ..........||||:Block03 ::y DC ::ref index:||||:Block04 ::cb DC ::motion x :||||......... :cr DC ::motion y :||||....... ..........|||------------------------------------||------------------------------------|||Block1|||...|--------------------------------------------|------------ ------------ ------------|||Y subbands||Cb subbands||Cr subbands||||--- ---||--- ---||--- ---|||||LL0||HL0||||LL0||HL0||||LL0||HL0|||||--- ---||--- ---||--- ---||||--- ---||--- ---||--- ---|||||LH0||HH0||||LH0||HH0||||LH0||HH0|||||--- ---||--- ---||--- ---||||--- ---||--- ---||--- ---|||||HL1||LH1||||HL1||LH1||||HL1||LH1|||||--- ---||--- ---||--- ---||||--- ---||--- ---||--- ---|||||HH1||HL2||||HH1||HL2||||HH1||HL2|||||...||...||...|||------------ ------------ ------------|--------------------------------------------Decoding process:=================------------|||Subbands|------------||||------------|Intra DC||||LL0 subband prediction ------------|\ Dequantization ------------------- \||Reference frames|\ IDWT|------- -------|Motion \|||Frame 0||Frame 1||Compensation . OBMC v -------|------- -------|--------------. \------> Frame n output Frame Frame<----------------------------------/|...|------------------- Range Coder:============Binary Range Coder:------------------- The implemented range coder is an adapted version based upon "Range encoding: an algorithm for removing redundancy from a digitised message." by G. N. N. Martin. The symbols encoded by the Snow range coder are bits(0|1). The associated probabilities are not fix but change depending on the symbol mix seen so far. bit seen|new state ---------+----------------------------------------------- 0|256 - state_transition_table[256 - old_state];1|state_transition_table[old_state];state_transition_table={ 0, 0, 0, 0, 0, 0, 0, 0, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 190, 191, 192, 194, 194, 195, 196, 197, 198, 199, 200, 201, 202, 202, 204, 205, 206, 207, 208, 209, 209, 210, 211, 212, 213, 215, 215, 216, 217, 218, 219, 220, 220, 222, 223, 224, 225, 226, 227, 227, 229, 229, 230, 231, 232, 234, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 248, 0, 0, 0, 0, 0, 0, 0};FIXME Range Coding of integers:------------------------- FIXME Neighboring Blocks:===================left and top are set to the respective blocks unless they are outside of the image in which case they are set to the Null block top-left is set to the top left block unless it is outside of the image in which case it is set to the left block if this block has no larger parent block or it is at the left side of its parent block and the top right block is not outside of the image then the top right block is used for top-right else the top-left block is used Null block y, cb, cr are 128 level, ref, mx and my are 0 Motion Vector Prediction:=========================1. the motion vectors of all the neighboring blocks are scaled to compensate for the difference of reference frames scaled_mv=(mv *(256 *(current_reference+1)/(mv.reference+1))+128)> the median of the scaled top and top right vectors is used as motion vector prediction the used motion vector is the sum of the predictor and(mvx_diff, mvy_diff) *mv_scale Intra DC Prediction block[y][x] dc[1]
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
static void copy(const float *p1, float *p2, const int length)
int av_frame_ref(AVFrame *dst, const AVFrame *src)
Set up a new reference to the data described by the source frame.
static const uint8_t vp8_coeff_band[16]
static const uint8_t subpel_idx[3][8]
static av_always_inline void vp8_mc_chroma(VP8Context *s, VP8ThreadData *td, uint8_t *dst1, uint8_t *dst2, ThreadFrame *ref, const VP56mv *mv, int x_off, int y_off, int block_w, int block_h, int width, int height, ptrdiff_t linesize, vp8_mc_func mc_func[3][3])
chroma MC function
int allocate_progress
Whether to allocate progress for frame threading.
static int vp7_update_dimensions(VP8Context *s, int width, int height)
#define EDGE_EMU_LINESIZE
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 have add an init_thread_copy() which re-allocates them for other threads. Add AV_CODEC_CAP_FRAME_THREADS to the codec capabilities. There will be very little speed gain at this point but it should work. If there are inter-frame dependencies
static av_always_inline void filter_mb(VP8Context *s, uint8_t *dst[3], VP8FilterStrength *f, int mb_x, int mb_y, int is_vp7)
static void vp8_release_frame(VP8Context *s, VP8Frame *f)
static av_always_inline void decode_mb_mode(VP8Context *s, VP8mvbounds *mv_bounds, VP8Macroblock *mb, int mb_x, int mb_y, uint8_t *segment, uint8_t *ref, int layout, int is_vp7)
static void free_buffers(VP8Context *s)
static int vp7_decode_mv_mb_modes(AVCodecContext *avctx, VP8Frame *cur_frame, VP8Frame *prev_frame)
#define FF_THREAD_SLICE
Decode more than one part of a single frame at once.
static const uint8_t vp8_pred8x8c_prob_intra[3]
static int vp8_read_mv_component(VP56RangeCoder *c, const uint8_t *p)
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_RL24
static av_always_inline void vp8_decode_mvs(VP8Context *s, VP8mvbounds *mv_bounds, VP8Macroblock *mb, int mb_x, int mb_y, int layout)
static const uint8_t vp8_pred4x4_prob_intra[10][10][9]
The reader does not expect b to be semantically here and if the code is changed by maybe adding a a division or other the signedness will almost certainly be mistaken To avoid this confusion a new type was SUINT is the C unsigned type but it holds a signed int to use the same example SUINT a
#define AV_CODEC_CAP_SLICE_THREADS
Codec supports slice-based (or partition-based) multithreading.
static int vp8_decode_frame_header(VP8Context *s, const uint8_t *buf, int buf_size)
static const uint8_t vp8_mbsplit_prob[3]
static int setup_partitions(VP8Context *s, const uint8_t *buf, int buf_size)
static const int8_t vp8_pred16x16_tree_inter[4][2]
int ff_vp56_init_range_decoder(VP56RangeCoder *c, const uint8_t *buf, int buf_size)
static const int8_t vp7_feature_index_tree[4][2]
enum AVDiscard skip_loop_filter
Skip loop filtering for selected frames.
static av_always_inline int pthread_cond_destroy(pthread_cond_t *cond)
#define FF_THREAD_FRAME
Decode more than one frame at once.
#define H_LOOP_FILTER_16Y_INNER(cond)
static av_always_inline int vp78_decode_mb_row_sliced(AVCodecContext *avctx, void *tdata, int jobnr, int threadnr, int is_vp7)
static av_always_inline int pthread_mutex_destroy(pthread_mutex_t *mutex)
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel layout
static av_always_inline void idct_mb(VP8Context *s, VP8ThreadData *td, uint8_t *dst[3], VP8Macroblock *mb)
static av_always_inline int decode_block_coeffs_internal(VP56RangeCoder *r, int16_t block[16], uint8_t probs[16][3][NUM_DCT_TOKENS - 1], int i, uint8_t *token_prob, int16_t qmul[2], const uint8_t scan[16], int vp7)
#define i(width, name, range_min, range_max)
int(* decode_slice)(AVCodecContext *avctx, const uint8_t *buf, uint32_t buf_size)
Callback for each slice.
static const SiprModeParam modes[MODE_COUNT]
static av_always_inline void decode_intra4x4_modes(VP8Context *s, VP56RangeCoder *c, VP8Macroblock *mb, int mb_x, int keyframe, int layout)
static av_always_inline void prefetch_motion(VP8Context *s, VP8Macroblock *mb, int mb_x, int mb_y, int mb_xy, int ref)
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
const char * name
Name of the codec implementation.
static void vp78_reset_probability_tables(VP8Context *s)
static int vp7_decode_frame_header(VP8Context *s, const uint8_t *buf, int buf_size)
static void fade(uint8_t *dst, ptrdiff_t dst_linesize, const uint8_t *src, ptrdiff_t src_linesize, int width, int height, int alpha, int beta)
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
@ AVCOL_RANGE_MPEG
the normal 219*2^(n-8) "MPEG" YUV ranges
static int vp8_decode_mb_row_sliced(AVCodecContext *avctx, void *tdata, int jobnr, int threadnr)
@ VP8_SPLITMVMODE_NONE
(only used in prediction) no split MVs
static int vp7_decode_block_coeffs_internal(VP56RangeCoder *r, int16_t block[16], uint8_t probs[16][3][NUM_DCT_TOKENS - 1], int i, uint8_t *token_prob, int16_t qmul[2], const uint8_t scan[16])
#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)
these buffered frames must be flushed immediately if a new input produces new the filter must not call request_frame to get more It must just process the frame or queue it The task of requesting more frames is left to the filter s request_frame method or the application If a filter has several the filter must be ready for frames arriving randomly on any input any filter with several inputs will most likely require some kind of queuing mechanism It is perfectly acceptable to have a limited queue and to drop frames when the inputs are too unbalanced request_frame For filters that do not use the this method is called when a frame is wanted on an output For a it should directly call filter_frame on the corresponding output For a if there are queued frames already one of these frames should be pushed If the filter should request a frame on one of its repeatedly until at least one frame has been pushed Return or at least make progress towards producing a frame
static const uint8_t vp8_pred16x16_prob_intra[4]
static const uint16_t vp8_ac_qlookup[VP8_MAX_QUANT+1]
#define prob(name, subs,...)
the pkt_dts and pkt_pts fields in AVFrame will work as usual Restrictions on codec whose streams don t reset across will not work because their bitstreams cannot be decoded in parallel *The contents of buffers must not be read before as well as code calling up to before the decode process starts Call ff_thread_finish_setup() afterwards. If some code can 't be moved
static av_always_inline void inter_predict(VP8Context *s, VP8ThreadData *td, uint8_t *dst[3], VP8Macroblock *mb, int mb_x, int mb_y)
Apply motion vectors to prediction buffer, chapter 18.
Tag MUST be and< 10hcoeff half pel interpolation filter coefficients, hcoeff[0] are the 2 middle coefficients[1] are the next outer ones and so on, resulting in a filter like:...eff[2], hcoeff[1], hcoeff[0], hcoeff[0], hcoeff[1], hcoeff[2] ... the sign of the coefficients is not explicitly stored but alternates after each coeff and coeff[0] is positive, so ...,+,-,+,-,+,+,-,+,-,+,... hcoeff[0] is not explicitly stored but found by subtracting the sum of all stored coefficients with signs from 32 hcoeff[0]=32 - hcoeff[1] - hcoeff[2] - ... a good choice for hcoeff and htaps is htaps=6 hcoeff={40,-10, 2} an alternative which requires more computations at both encoder and decoder side and may or may not be better is htaps=8 hcoeff={42,-14, 6,-2}ref_frames minimum of the number of available reference frames and max_ref_frames for example the first frame after a key frame always has ref_frames=1spatial_decomposition_type wavelet type 0 is a 9/7 symmetric compact integer wavelet 1 is a 5/3 symmetric compact integer wavelet others are reserved stored as delta from last, last is reset to 0 if always_reset||keyframeqlog quality(logarithmic quantizer scale) stored as delta from last, last is reset to 0 if always_reset||keyframemv_scale stored as delta from last, last is reset to 0 if always_reset||keyframe FIXME check that everything works fine if this changes between framesqbias dequantization bias stored as delta from last, last is reset to 0 if always_reset||keyframeblock_max_depth maximum depth of the block tree stored as delta from last, last is reset to 0 if always_reset||keyframequant_table quantization tableHighlevel bitstream structure:==============================--------------------------------------------|Header|--------------------------------------------|------------------------------------|||Block0||||split?||||yes no||||......... intra?||||:Block01 :yes no||||:Block02 :....... ..........||||:Block03 ::y DC ::ref index:||||:Block04 ::cb DC ::motion x :||||......... :cr DC ::motion y :||||....... ..........|||------------------------------------||------------------------------------|||Block1|||...|--------------------------------------------|------------ ------------ ------------|||Y subbands||Cb subbands||Cr subbands||||--- ---||--- ---||--- ---|||||LL0||HL0||||LL0||HL0||||LL0||HL0|||||--- ---||--- ---||--- ---||||--- ---||--- ---||--- ---|||||LH0||HH0||||LH0||HH0||||LH0||HH0|||||--- ---||--- ---||--- ---||||--- ---||--- ---||--- ---|||||HL1||LH1||||HL1||LH1||||HL1||LH1|||||--- ---||--- ---||--- ---||||--- ---||--- ---||--- ---|||||HH1||HL2||||HH1||HL2||||HH1||HL2|||||...||...||...|||------------ ------------ ------------|--------------------------------------------Decoding process:=================------------|||Subbands|------------||||------------|Intra DC||||LL0 subband prediction ------------|\ Dequantization ------------------- \||Reference frames|\ IDWT|------- -------|Motion \|||Frame 0||Frame 1||Compensation . OBMC v -------|------- -------|--------------. \------> Frame n output Frame Frame<----------------------------------/|...|------------------- Range Coder:============Binary Range Coder:------------------- The implemented range coder is an adapted version based upon "Range encoding: an algorithm for removing redundancy from a digitised message." by G. N. N. Martin. The symbols encoded by the Snow range coder are bits(0|1). The associated probabilities are not fix but change depending on the symbol mix seen so far. bit seen|new state ---------+----------------------------------------------- 0|256 - state_transition_table[256 - old_state];1|state_transition_table[old_state];state_transition_table={ 0, 0, 0, 0, 0, 0, 0, 0, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 190, 191, 192, 194, 194, 195, 196, 197, 198, 199, 200, 201, 202, 202, 204, 205, 206, 207, 208, 209, 209, 210, 211, 212, 213, 215, 215, 216, 217, 218, 219, 220, 220, 222, 223, 224, 225, 226, 227, 227, 229, 229, 230, 231, 232, 234, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 248, 0, 0, 0, 0, 0, 0, 0};FIXME Range Coding of integers:------------------------- FIXME Neighboring Blocks:===================left and top are set to the respective blocks unless they are outside of the image in which case they are set to the Null block top-left is set to the top left block unless it is outside of the image in which case it is set to the left block if this block has no larger parent block or it is at the left side of its parent block and the top right block is not outside of the image then the top right block is used for top-right else the top-left block is used Null block y, cb, cr are 128 level, ref, mx and my are 0 Motion Vector Prediction:=========================1. the motion vectors of all the neighboring blocks are scaled to compensate for the difference of reference frames scaled_mv=(mv *(256 *(current_reference+1)/(mv.reference+1))+128)> the median of the scaled left
#define FF_ARRAY_ELEMS(a)
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_RL32
static av_always_inline int decode_splitmvs(VP8Context *s, VP56RangeCoder *c, VP8Macroblock *mb, int layout, int is_vp7)
Split motion vector prediction, 16.4.
main external API structure.
int active_thread_type
Which multithreading methods are in use by the codec.
uint8_t intra4x4_pred_mode_top[4]
#define HWACCEL_VAAPI(codec)
av_cold void ff_h264_pred_init(H264PredContext *h, int codec_id, const int bit_depth, int chroma_format_idc)
Set the intra prediction function pointers.
int frame_priv_data_size
Size of per-frame hardware accelerator private data.
static av_always_inline void filter_mb_simple(VP8Context *s, uint8_t *dst, VP8FilterStrength *f, int mb_x, int mb_y)
static int ref[MAX_W *MAX_W]
AVBufferRef * av_buffer_ref(AVBufferRef *buf)
Create a new reference to an AVBuffer.
int ff_thread_ref_frame(ThreadFrame *dst, ThreadFrame *src)
int(* start_frame)(AVCodecContext *avctx, const uint8_t *buf, uint32_t buf_size)
Called at the beginning of each frame or field picture.
static av_always_inline void vp8_mc_luma(VP8Context *s, VP8ThreadData *td, uint8_t *dst, ThreadFrame *ref, const VP56mv *mv, int x_off, int y_off, int block_w, int block_h, int width, int height, ptrdiff_t linesize, vp8_mc_func mc_func[3][3])
luma MC function
static void vp78_update_probability_tables(VP8Context *s)
@ AV_PICTURE_TYPE_P
Predicted.
int ff_set_dimensions(AVCodecContext *s, int width, int height)
Check that the provided frame dimensions are valid and set them on the codec context.
#define LOCAL_ALIGNED(a, t, v,...)
#define vp56_rac_get_prob
static void vp78_update_pred16x16_pred8x8_mvc_probabilities(VP8Context *s, int mvc_size)
#define avpriv_request_sample(...)
static void update_refs(VP8Context *s)
static void update_lf_deltas(VP8Context *s)
static av_always_inline void filter_mb_row(AVCodecContext *avctx, void *tdata, int jobnr, int threadnr, int is_vp7)
static const int16_t alpha[]
This structure stores compressed data.
static enum AVPixelFormat get_pixel_format(VP8Context *s)
static int vp7_fade_frame(VP8Context *s, VP56RangeCoder *c)
static VP8Frame * vp8_find_free_buffer(VP8Context *s)
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
static const double coeff[2][5]
The exact code depends on how similar the blocks are and how related they are to the block
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
static void copy_chroma(AVFrame *dst, AVFrame *src, int width, int height)
static av_always_inline int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr)
static const uint16_t vp7_y2ac_qlookup[]
#define atomic_init(obj, value)
static const uint8_t vp7_submv_prob[3]
@ AVDISCARD_NONREF
discard all non reference
static av_always_inline unsigned int vp56_rac_renorm(VP56RangeCoder *c)
static const uint8_t vp8_dc_qlookup[VP8_MAX_QUANT+1]
static void vp8_decode_flush(AVCodecContext *avctx)
int(* execute2)(struct AVCodecContext *c, int(*func)(struct AVCodecContext *c2, void *arg, int jobnr, int threadnr), void *arg2, int *ret, int count)
The codec may call this to execute several independent things.
static int vp8_alloc_frame(VP8Context *s, VP8Frame *f, int ref)
static const av_always_inline uint8_t * get_submv_prob(uint32_t left, uint32_t top, int is_vp7)
av_cold void ff_vp78dsp_init(VP8DSPContext *dsp)
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 have add an so the codec calls ff_thread_report set AVCodecInternal allocate_progress The frames must then be freed with ff_thread_release_buffer(). Otherwise leave it at zero and decode directly into the user-supplied frames. Call ff_thread_report_progress() after some part of the current picture has decoded. A good place to put this is where draw_horiz_band() is called - add this if it isn 't called anywhere
void * hwaccel_picture_private