|
11 | 11 | #include <linux/reset.h>
|
12 | 12 | #include <linux/slab.h>
|
13 | 13 |
|
| 14 | +#include <media/v4l2-h264.h> |
| 15 | + |
14 | 16 | #include "trace.h"
|
15 | 17 | #include "uapi.h"
|
16 | 18 | #include "vde.h"
|
17 | 19 |
|
| 20 | +struct h264_reflists { |
| 21 | + u8 p[V4L2_H264_NUM_DPB_ENTRIES]; |
| 22 | + u8 b0[V4L2_H264_NUM_DPB_ENTRIES]; |
| 23 | + u8 b1[V4L2_H264_NUM_DPB_ENTRIES]; |
| 24 | +}; |
| 25 | + |
18 | 26 | static int tegra_vde_wait_mbe(struct tegra_vde *vde)
|
19 | 27 | {
|
20 | 28 | u32 tmp;
|
@@ -125,8 +133,8 @@ static void tegra_vde_setup_frameid(struct tegra_vde *vde,
|
125 | 133 | u32 y_addr = frame ? frame->y_addr : 0x6CDEAD00;
|
126 | 134 | u32 cb_addr = frame ? frame->cb_addr : 0x6CDEAD00;
|
127 | 135 | u32 cr_addr = frame ? frame->cr_addr : 0x6CDEAD00;
|
128 |
| - u32 value1 = frame ? ((mbs_width << 16) | mbs_height) : 0; |
129 |
| - u32 value2 = frame ? ((((mbs_width + 1) >> 1) << 6) | 1) : 0; |
| 136 | + u32 value1 = frame ? ((frame->luma_atoms_pitch << 16) | mbs_height) : 0; |
| 137 | + u32 value2 = frame ? ((frame->chroma_atoms_pitch << 6) | 1) : 0; |
130 | 138 |
|
131 | 139 | tegra_vde_writel(vde, y_addr >> 8, vde->frameid, 0x000 + frameid * 4);
|
132 | 140 | tegra_vde_writel(vde, cb_addr >> 8, vde->frameid, 0x100 + frameid * 4);
|
@@ -645,3 +653,275 @@ int tegra_vde_decode_h264(struct tegra_vde *vde,
|
645 | 653 |
|
646 | 654 | return tegra_vde_decode_end(vde);
|
647 | 655 | }
|
| 656 | + |
| 657 | +static struct vb2_buffer *get_ref_buf(struct tegra_ctx *ctx, |
| 658 | + struct vb2_v4l2_buffer *dst, |
| 659 | + unsigned int dpb_idx) |
| 660 | +{ |
| 661 | + const struct v4l2_h264_dpb_entry *dpb = ctx->h264.decode_params->dpb; |
| 662 | + struct vb2_queue *cap_q = &ctx->fh.m2m_ctx->cap_q_ctx.q; |
| 663 | + int buf_idx = -1; |
| 664 | + |
| 665 | + if (dpb[dpb_idx].flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE) |
| 666 | + buf_idx = vb2_find_timestamp(cap_q, |
| 667 | + dpb[dpb_idx].reference_ts, 0); |
| 668 | + |
| 669 | + /* |
| 670 | + * If a DPB entry is unused or invalid, address of current destination |
| 671 | + * buffer is returned. |
| 672 | + */ |
| 673 | + if (buf_idx < 0) |
| 674 | + return &dst->vb2_buf; |
| 675 | + |
| 676 | + return vb2_get_buffer(cap_q, buf_idx); |
| 677 | +} |
| 678 | + |
| 679 | +static int tegra_vde_validate_vb_size(struct tegra_ctx *ctx, |
| 680 | + struct vb2_buffer *vb, |
| 681 | + unsigned int plane_id, |
| 682 | + size_t min_size) |
| 683 | +{ |
| 684 | + u64 offset = vb->planes[plane_id].data_offset; |
| 685 | + struct device *dev = ctx->vde->dev; |
| 686 | + |
| 687 | + if (offset + min_size > vb2_plane_size(vb, plane_id)) { |
| 688 | + dev_err(dev, "Too small plane[%u] size %lu @0x%llX, should be at least %zu\n", |
| 689 | + plane_id, vb2_plane_size(vb, plane_id), offset, min_size); |
| 690 | + return -EINVAL; |
| 691 | + } |
| 692 | + |
| 693 | + return 0; |
| 694 | +} |
| 695 | + |
| 696 | +static int tegra_vde_h264_setup_frame(struct tegra_ctx *ctx, |
| 697 | + struct tegra_vde_h264_decoder_ctx *h264, |
| 698 | + struct v4l2_h264_reflist_builder *b, |
| 699 | + struct vb2_buffer *vb, |
| 700 | + unsigned int ref_id, |
| 701 | + unsigned int id) |
| 702 | +{ |
| 703 | + struct v4l2_pix_format_mplane *pixfmt = &ctx->decoded_fmt.fmt.pix_mp; |
| 704 | + struct tegra_m2m_buffer *tb = vb_to_tegra_buf(vb); |
| 705 | + struct tegra_ctx_h264 *h = &ctx->h264; |
| 706 | + struct tegra_vde *vde = ctx->vde; |
| 707 | + struct device *dev = vde->dev; |
| 708 | + unsigned int cstride, lstride; |
| 709 | + unsigned int flags = 0; |
| 710 | + size_t lsize, csize; |
| 711 | + int err, frame_num; |
| 712 | + |
| 713 | + lsize = h264->pic_width_in_mbs * 16 * h264->pic_height_in_mbs * 16; |
| 714 | + csize = h264->pic_width_in_mbs * 8 * h264->pic_height_in_mbs * 8; |
| 715 | + lstride = pixfmt->plane_fmt[0].bytesperline; |
| 716 | + cstride = pixfmt->plane_fmt[1].bytesperline; |
| 717 | + |
| 718 | + err = tegra_vde_validate_vb_size(ctx, vb, 0, lsize); |
| 719 | + if (err) |
| 720 | + return err; |
| 721 | + |
| 722 | + err = tegra_vde_validate_vb_size(ctx, vb, 1, csize); |
| 723 | + if (err) |
| 724 | + return err; |
| 725 | + |
| 726 | + err = tegra_vde_validate_vb_size(ctx, vb, 2, csize); |
| 727 | + if (err) |
| 728 | + return err; |
| 729 | + |
| 730 | + if (!tb->aux || tb->aux->size < csize) { |
| 731 | + dev_err(dev, "Too small aux size %zd, should be at least %zu\n", |
| 732 | + tb->aux ? tb->aux->size : -1, csize); |
| 733 | + return -EINVAL; |
| 734 | + } |
| 735 | + |
| 736 | + if (id == 0) { |
| 737 | + frame_num = h->decode_params->frame_num; |
| 738 | + |
| 739 | + if (h->decode_params->nal_ref_idc) |
| 740 | + flags |= FLAG_REFERENCE; |
| 741 | + } else { |
| 742 | + frame_num = b->refs[ref_id].frame_num & 0x7fffff; |
| 743 | + } |
| 744 | + |
| 745 | + if (to_vb2_v4l2_buffer(vb)->flags & V4L2_BUF_FLAG_BFRAME) |
| 746 | + flags |= FLAG_B_FRAME; |
| 747 | + |
| 748 | + vde->frames[id].flags = flags; |
| 749 | + vde->frames[id].y_addr = tb->dma_addr[0]; |
| 750 | + vde->frames[id].cb_addr = tb->dma_addr[1]; |
| 751 | + vde->frames[id].cr_addr = tb->dma_addr[2]; |
| 752 | + vde->frames[id].aux_addr = tb->aux->dma_addr; |
| 753 | + vde->frames[id].frame_num = frame_num; |
| 754 | + vde->frames[id].luma_atoms_pitch = lstride / VDE_ATOM; |
| 755 | + vde->frames[id].chroma_atoms_pitch = cstride / VDE_ATOM; |
| 756 | + |
| 757 | + return 0; |
| 758 | +} |
| 759 | + |
| 760 | +static int tegra_vde_h264_setup_frames(struct tegra_ctx *ctx, |
| 761 | + struct tegra_vde_h264_decoder_ctx *h264) |
| 762 | +{ |
| 763 | + struct vb2_v4l2_buffer *src = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx); |
| 764 | + struct vb2_v4l2_buffer *dst = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx); |
| 765 | + const struct v4l2_h264_dpb_entry *dpb = ctx->h264.decode_params->dpb; |
| 766 | + struct tegra_ctx_h264 *h = &ctx->h264; |
| 767 | + struct v4l2_h264_reflist_builder b; |
| 768 | + struct h264_reflists reflists; |
| 769 | + struct vb2_buffer *ref; |
| 770 | + unsigned int i; |
| 771 | + u8 *dpb_id; |
| 772 | + int err; |
| 773 | + |
| 774 | + v4l2_m2m_buf_copy_metadata(src, dst, true); |
| 775 | + |
| 776 | + err = tegra_vde_h264_setup_frame(ctx, h264, NULL, &dst->vb2_buf, 0, |
| 777 | + h264->dpb_frames_nb++); |
| 778 | + if (err) |
| 779 | + return err; |
| 780 | + |
| 781 | + if (dst->flags & V4L2_BUF_FLAG_KEYFRAME) |
| 782 | + return 0; |
| 783 | + |
| 784 | + v4l2_h264_init_reflist_builder(&b, h->decode_params, h->sps, dpb); |
| 785 | + |
| 786 | + if (dst->flags & V4L2_BUF_FLAG_BFRAME) { |
| 787 | + v4l2_h264_build_b_ref_lists(&b, reflists.b0, reflists.b1); |
| 788 | + dpb_id = reflists.b0; |
| 789 | + } else { |
| 790 | + v4l2_h264_build_p_ref_list(&b, reflists.p); |
| 791 | + dpb_id = reflists.p; |
| 792 | + } |
| 793 | + |
| 794 | + for (i = 0; i < b.num_valid; i++) { |
| 795 | + ref = get_ref_buf(ctx, dst, dpb_id[i]); |
| 796 | + |
| 797 | + err = tegra_vde_h264_setup_frame(ctx, h264, &b, ref, dpb_id[i], |
| 798 | + h264->dpb_frames_nb++); |
| 799 | + if (err) |
| 800 | + return err; |
| 801 | + |
| 802 | + if (b.refs[dpb_id[i]].pic_order_count < b.cur_pic_order_count) |
| 803 | + h264->dpb_ref_frames_with_earlier_poc_nb++; |
| 804 | + } |
| 805 | + |
| 806 | + return 0; |
| 807 | +} |
| 808 | + |
| 809 | +static unsigned int to_tegra_vde_h264_level_idc(unsigned int level_idc) |
| 810 | +{ |
| 811 | + switch (level_idc) { |
| 812 | + case 11: |
| 813 | + return 2; |
| 814 | + case 12: |
| 815 | + return 3; |
| 816 | + case 13: |
| 817 | + return 4; |
| 818 | + case 20: |
| 819 | + return 5; |
| 820 | + case 21: |
| 821 | + return 6; |
| 822 | + case 22: |
| 823 | + return 7; |
| 824 | + case 30: |
| 825 | + return 8; |
| 826 | + case 31: |
| 827 | + return 9; |
| 828 | + case 32: |
| 829 | + return 10; |
| 830 | + case 40: |
| 831 | + return 11; |
| 832 | + case 41: |
| 833 | + return 12; |
| 834 | + case 42: |
| 835 | + return 13; |
| 836 | + case 50: |
| 837 | + return 14; |
| 838 | + default: |
| 839 | + break; |
| 840 | + } |
| 841 | + |
| 842 | + return 15; |
| 843 | +} |
| 844 | + |
| 845 | +static int tegra_vde_h264_setup_context(struct tegra_ctx *ctx, |
| 846 | + struct tegra_vde_h264_decoder_ctx *h264) |
| 847 | +{ |
| 848 | + struct tegra_ctx_h264 *h = &ctx->h264; |
| 849 | + struct tegra_vde *vde = ctx->vde; |
| 850 | + struct device *dev = vde->dev; |
| 851 | + int err; |
| 852 | + |
| 853 | + memset(h264, 0, sizeof(*h264)); |
| 854 | + memset(vde->frames, 0, sizeof(vde->frames)); |
| 855 | + |
| 856 | + tegra_vde_prepare_control_data(ctx, V4L2_CID_STATELESS_H264_DECODE_PARAMS); |
| 857 | + tegra_vde_prepare_control_data(ctx, V4L2_CID_STATELESS_H264_SPS); |
| 858 | + tegra_vde_prepare_control_data(ctx, V4L2_CID_STATELESS_H264_PPS); |
| 859 | + |
| 860 | + /* CABAC unsupported by hardware, requires software preprocessing */ |
| 861 | + if (h->pps->flags & V4L2_H264_PPS_FLAG_ENTROPY_CODING_MODE) |
| 862 | + return -EOPNOTSUPP; |
| 863 | + |
| 864 | + if (h->sps->profile_idc == 66) |
| 865 | + h264->baseline_profile = 1; |
| 866 | + |
| 867 | + if (h->sps->flags & V4L2_H264_SPS_FLAG_DIRECT_8X8_INFERENCE) |
| 868 | + h264->direct_8x8_inference_flag = 1; |
| 869 | + |
| 870 | + if (h->pps->flags & V4L2_H264_PPS_FLAG_CONSTRAINED_INTRA_PRED) |
| 871 | + h264->constrained_intra_pred_flag = 1; |
| 872 | + |
| 873 | + if (h->pps->flags & V4L2_H264_PPS_FLAG_DEBLOCKING_FILTER_CONTROL_PRESENT) |
| 874 | + h264->deblocking_filter_control_present_flag = 1; |
| 875 | + |
| 876 | + if (h->pps->flags & V4L2_H264_PPS_FLAG_BOTTOM_FIELD_PIC_ORDER_IN_FRAME_PRESENT) |
| 877 | + h264->pic_order_present_flag = 1; |
| 878 | + |
| 879 | + h264->level_idc = to_tegra_vde_h264_level_idc(h->sps->level_idc); |
| 880 | + h264->log2_max_pic_order_cnt_lsb = h->sps->log2_max_pic_order_cnt_lsb_minus4 + 4; |
| 881 | + h264->log2_max_frame_num = h->sps->log2_max_frame_num_minus4 + 4; |
| 882 | + h264->pic_order_cnt_type = h->sps->pic_order_cnt_type; |
| 883 | + h264->pic_width_in_mbs = h->sps->pic_width_in_mbs_minus1 + 1; |
| 884 | + h264->pic_height_in_mbs = h->sps->pic_height_in_map_units_minus1 + 1; |
| 885 | + |
| 886 | + h264->num_ref_idx_l0_active_minus1 = h->pps->num_ref_idx_l0_default_active_minus1; |
| 887 | + h264->num_ref_idx_l1_active_minus1 = h->pps->num_ref_idx_l1_default_active_minus1; |
| 888 | + h264->chroma_qp_index_offset = h->pps->chroma_qp_index_offset & 0x1f; |
| 889 | + h264->pic_init_qp = h->pps->pic_init_qp_minus26 + 26; |
| 890 | + |
| 891 | + err = tegra_vde_h264_setup_frames(ctx, h264); |
| 892 | + if (err) |
| 893 | + return err; |
| 894 | + |
| 895 | + err = tegra_vde_validate_h264_ctx(dev, h264); |
| 896 | + if (err) |
| 897 | + return err; |
| 898 | + |
| 899 | + return 0; |
| 900 | +} |
| 901 | + |
| 902 | +int tegra_vde_h264_decode_run(struct tegra_ctx *ctx) |
| 903 | +{ |
| 904 | + struct vb2_v4l2_buffer *src = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx); |
| 905 | + struct tegra_m2m_buffer *bitstream = vb_to_tegra_buf(&src->vb2_buf); |
| 906 | + size_t bitstream_size = vb2_get_plane_payload(&src->vb2_buf, 0); |
| 907 | + struct tegra_vde_h264_decoder_ctx h264; |
| 908 | + struct tegra_vde *vde = ctx->vde; |
| 909 | + int err; |
| 910 | + |
| 911 | + err = tegra_vde_h264_setup_context(ctx, &h264); |
| 912 | + if (err) |
| 913 | + return err; |
| 914 | + |
| 915 | + err = tegra_vde_decode_begin(vde, &h264, vde->frames, |
| 916 | + bitstream->dma_addr[0], |
| 917 | + bitstream_size); |
| 918 | + if (err) |
| 919 | + return err; |
| 920 | + |
| 921 | + return 0; |
| 922 | +} |
| 923 | + |
| 924 | +int tegra_vde_h264_decode_wait(struct tegra_ctx *ctx) |
| 925 | +{ |
| 926 | + return tegra_vde_decode_end(ctx->vde); |
| 927 | +} |
0 commit comments