Skip to content

Commit 8d02ef3

Browse files
committed
media: staging: tegra-vde: Support V4L stateless video decoder API
Expose Tegra video decoder as a generic V4L M2M stateless video decoder. Signed-off-by: Dmitry Osipenko <[email protected]>
1 parent 028644d commit 8d02ef3

File tree

7 files changed

+1784
-8
lines changed

7 files changed

+1784
-8
lines changed

drivers/staging/media/tegra-vde/Kconfig

+7
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,16 @@
22
config TEGRA_VDE
33
tristate "NVIDIA Tegra Video Decoder Engine driver"
44
depends on ARCH_TEGRA || COMPILE_TEST
5+
depends on VIDEO_DEV && VIDEO_V4L2
56
select DMA_SHARED_BUFFER
67
select IOMMU_IOVA
8+
select MEDIA_CONTROLLER
9+
select MEDIA_CONTROLLER_REQUEST_API
710
select SRAM
11+
select VIDEOBUF2_DMA_CONTIG
12+
select VIDEOBUF2_DMA_SG
13+
select V4L2_H264
14+
select V4L2_MEM2MEM_DEV
815
help
916
Say Y here to enable support for the NVIDIA Tegra video decoder
1017
driver.
+1-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
# SPDX-License-Identifier: GPL-2.0
2-
tegra-vde-y := vde.o iommu.o dmabuf-cache.o h264.o
2+
tegra-vde-y := vde.o iommu.o dmabuf-cache.o h264.o h264_reader.o v4l2.o
33
obj-$(CONFIG_TEGRA_VDE) += tegra-vde.o

drivers/staging/media/tegra-vde/h264.c

+343-2
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,18 @@
1111
#include <linux/reset.h>
1212
#include <linux/slab.h>
1313

14+
#include <media/v4l2-h264.h>
15+
1416
#include "trace.h"
1517
#include "uapi.h"
1618
#include "vde.h"
1719

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+
1826
static int tegra_vde_wait_mbe(struct tegra_vde *vde)
1927
{
2028
u32 tmp;
@@ -125,8 +133,8 @@ static void tegra_vde_setup_frameid(struct tegra_vde *vde,
125133
u32 y_addr = frame ? frame->y_addr : 0x6CDEAD00;
126134
u32 cb_addr = frame ? frame->cb_addr : 0x6CDEAD00;
127135
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;
130138

131139
tegra_vde_writel(vde, y_addr >> 8, vde->frameid, 0x000 + frameid * 4);
132140
tegra_vde_writel(vde, cb_addr >> 8, vde->frameid, 0x100 + frameid * 4);
@@ -645,3 +653,336 @@ int tegra_vde_decode_h264(struct tegra_vde *vde,
645653

646654
return tegra_vde_decode_end(vde);
647655
}
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 void tegra_vde_h264_setup_frame_metadata(struct vb2_v4l2_buffer *src,
761+
struct vb2_v4l2_buffer *dst)
762+
{
763+
struct vb2_buffer *vb = &src->vb2_buf;
764+
unsigned int bitstream_offset;
765+
unsigned long bitstream_size;
766+
const void *bitstream;
767+
int slice_type;
768+
769+
v4l2_m2m_buf_copy_metadata(src, dst, true);
770+
771+
/*
772+
* Tegra hardware require information about frame's type, assuming
773+
* that frame consists of the same type slices. Userspace must tag
774+
* frame's type appropriately.
775+
*
776+
* Decoding of a non-uniform frames isn't supported by hardware and
777+
* require software preprocessing that we don't implement. Decoding
778+
* is expected to fail in this case. Such video streams are rare in
779+
* practice, so not a big deal.
780+
*/
781+
if (dst->flags & (V4L2_BUF_FLAG_KEYFRAME |
782+
V4L2_BUF_FLAG_PFRAME |
783+
V4L2_BUF_FLAG_BFRAME))
784+
return;
785+
786+
/*
787+
* If userspace doesn't tell us frame's type, then we will try to
788+
* extract it from the bitstream. Otherwise we'll hope for the best
789+
* and try to decode as-is.
790+
*/
791+
bitstream = vb2_plane_vaddr(vb, 0);
792+
if (!bitstream)
793+
return;
794+
795+
bitstream_offset = vb->planes[0].data_offset;
796+
bitstream_size = vb2_get_plane_payload(vb, 0);
797+
798+
slice_type = tegra_h264_parse_slice_type(bitstream + bitstream_offset,
799+
bitstream_size);
800+
if (slice_type < 0)
801+
return;
802+
803+
switch (slice_type % 5) {
804+
case V4L2_H264_SLICE_TYPE_I:
805+
dst->flags |= V4L2_BUF_FLAG_KEYFRAME;
806+
break;
807+
808+
case V4L2_H264_SLICE_TYPE_P:
809+
dst->flags |= V4L2_BUF_FLAG_PFRAME;
810+
break;
811+
812+
case V4L2_H264_SLICE_TYPE_B:
813+
dst->flags |= V4L2_BUF_FLAG_BFRAME;
814+
break;
815+
816+
default:
817+
break;
818+
}
819+
}
820+
821+
static int tegra_vde_h264_setup_frames(struct tegra_ctx *ctx,
822+
struct tegra_vde_h264_decoder_ctx *h264)
823+
{
824+
struct vb2_v4l2_buffer *src = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
825+
struct vb2_v4l2_buffer *dst = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
826+
const struct v4l2_h264_dpb_entry *dpb = ctx->h264.decode_params->dpb;
827+
struct tegra_ctx_h264 *h = &ctx->h264;
828+
struct v4l2_h264_reflist_builder b;
829+
struct h264_reflists reflists;
830+
struct vb2_buffer *ref;
831+
unsigned int i;
832+
u8 *dpb_id;
833+
int err;
834+
835+
tegra_vde_h264_setup_frame_metadata(src, dst);
836+
837+
err = tegra_vde_h264_setup_frame(ctx, h264, NULL, &dst->vb2_buf, 0,
838+
h264->dpb_frames_nb++);
839+
if (err)
840+
return err;
841+
842+
if (dst->flags & V4L2_BUF_FLAG_KEYFRAME)
843+
return 0;
844+
845+
v4l2_h264_init_reflist_builder(&b, h->decode_params, h->sps, dpb);
846+
847+
if (dst->flags & V4L2_BUF_FLAG_BFRAME) {
848+
v4l2_h264_build_b_ref_lists(&b, reflists.b0, reflists.b1);
849+
dpb_id = reflists.b0;
850+
} else {
851+
v4l2_h264_build_p_ref_list(&b, reflists.p);
852+
dpb_id = reflists.p;
853+
}
854+
855+
for (i = 0; i < b.num_valid; i++) {
856+
ref = get_ref_buf(ctx, dst, dpb_id[i]);
857+
858+
err = tegra_vde_h264_setup_frame(ctx, h264, &b, ref, dpb_id[i],
859+
h264->dpb_frames_nb++);
860+
if (err)
861+
return err;
862+
863+
if (b.refs[dpb_id[i]].pic_order_count < b.cur_pic_order_count)
864+
h264->dpb_ref_frames_with_earlier_poc_nb++;
865+
}
866+
867+
return 0;
868+
}
869+
870+
static unsigned int to_tegra_vde_h264_level_idc(unsigned int level_idc)
871+
{
872+
switch (level_idc) {
873+
case 11:
874+
return 2;
875+
case 12:
876+
return 3;
877+
case 13:
878+
return 4;
879+
case 20:
880+
return 5;
881+
case 21:
882+
return 6;
883+
case 22:
884+
return 7;
885+
case 30:
886+
return 8;
887+
case 31:
888+
return 9;
889+
case 32:
890+
return 10;
891+
case 40:
892+
return 11;
893+
case 41:
894+
return 12;
895+
case 42:
896+
return 13;
897+
case 50:
898+
return 14;
899+
default:
900+
break;
901+
}
902+
903+
return 15;
904+
}
905+
906+
static int tegra_vde_h264_setup_context(struct tegra_ctx *ctx,
907+
struct tegra_vde_h264_decoder_ctx *h264)
908+
{
909+
struct tegra_ctx_h264 *h = &ctx->h264;
910+
struct tegra_vde *vde = ctx->vde;
911+
struct device *dev = vde->dev;
912+
int err;
913+
914+
memset(h264, 0, sizeof(*h264));
915+
memset(vde->frames, 0, sizeof(vde->frames));
916+
917+
tegra_vde_prepare_control_data(ctx, V4L2_CID_STATELESS_H264_DECODE_PARAMS);
918+
tegra_vde_prepare_control_data(ctx, V4L2_CID_STATELESS_H264_SPS);
919+
tegra_vde_prepare_control_data(ctx, V4L2_CID_STATELESS_H264_PPS);
920+
921+
/* CABAC unsupported by hardware, requires software preprocessing */
922+
if (h->pps->flags & V4L2_H264_PPS_FLAG_ENTROPY_CODING_MODE)
923+
return -EOPNOTSUPP;
924+
925+
if (h->sps->profile_idc == 66)
926+
h264->baseline_profile = 1;
927+
928+
if (h->sps->flags & V4L2_H264_SPS_FLAG_DIRECT_8X8_INFERENCE)
929+
h264->direct_8x8_inference_flag = 1;
930+
931+
if (h->pps->flags & V4L2_H264_PPS_FLAG_CONSTRAINED_INTRA_PRED)
932+
h264->constrained_intra_pred_flag = 1;
933+
934+
if (h->pps->flags & V4L2_H264_PPS_FLAG_DEBLOCKING_FILTER_CONTROL_PRESENT)
935+
h264->deblocking_filter_control_present_flag = 1;
936+
937+
if (h->pps->flags & V4L2_H264_PPS_FLAG_BOTTOM_FIELD_PIC_ORDER_IN_FRAME_PRESENT)
938+
h264->pic_order_present_flag = 1;
939+
940+
h264->level_idc = to_tegra_vde_h264_level_idc(h->sps->level_idc);
941+
h264->log2_max_pic_order_cnt_lsb = h->sps->log2_max_pic_order_cnt_lsb_minus4 + 4;
942+
h264->log2_max_frame_num = h->sps->log2_max_frame_num_minus4 + 4;
943+
h264->pic_order_cnt_type = h->sps->pic_order_cnt_type;
944+
h264->pic_width_in_mbs = h->sps->pic_width_in_mbs_minus1 + 1;
945+
h264->pic_height_in_mbs = h->sps->pic_height_in_map_units_minus1 + 1;
946+
947+
h264->num_ref_idx_l0_active_minus1 = h->pps->num_ref_idx_l0_default_active_minus1;
948+
h264->num_ref_idx_l1_active_minus1 = h->pps->num_ref_idx_l1_default_active_minus1;
949+
h264->chroma_qp_index_offset = h->pps->chroma_qp_index_offset & 0x1f;
950+
h264->pic_init_qp = h->pps->pic_init_qp_minus26 + 26;
951+
952+
err = tegra_vde_h264_setup_frames(ctx, h264);
953+
if (err)
954+
return err;
955+
956+
err = tegra_vde_validate_h264_ctx(dev, h264);
957+
if (err)
958+
return err;
959+
960+
return 0;
961+
}
962+
963+
int tegra_vde_h264_decode_run(struct tegra_ctx *ctx)
964+
{
965+
struct vb2_v4l2_buffer *src = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
966+
struct tegra_m2m_buffer *bitstream = vb_to_tegra_buf(&src->vb2_buf);
967+
size_t bitstream_size = vb2_get_plane_payload(&src->vb2_buf, 0);
968+
struct tegra_vde_h264_decoder_ctx h264;
969+
struct tegra_vde *vde = ctx->vde;
970+
int err;
971+
972+
err = tegra_vde_h264_setup_context(ctx, &h264);
973+
if (err)
974+
return err;
975+
976+
err = tegra_vde_decode_begin(vde, &h264, vde->frames,
977+
bitstream->dma_addr[0],
978+
bitstream_size);
979+
if (err)
980+
return err;
981+
982+
return 0;
983+
}
984+
985+
int tegra_vde_h264_decode_wait(struct tegra_ctx *ctx)
986+
{
987+
return tegra_vde_decode_end(ctx->vde);
988+
}

0 commit comments

Comments
 (0)