Skip to content

Update amlogic vpu code to changes required for Kodi v18 Leia to work #332

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions drivers/amlogic/amports/ptsserv.c
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,9 @@ int calculation_stream_delayed_ms(u8 type, u32 *latestbitrate,
outtime = timestamp_pcrscr_get();
if (outtime == 0 || outtime == 0xffffffff)
outtime = pTable->last_checkout_pts;
timestampe_delayed = (pTable->last_checkin_pts - outtime) / 90;
if (pTable->last_checkin_pts > outtime)
timestampe_delayed = (pTable->last_checkin_pts - outtime) / 90;

pTable->last_pts_delay_ms = timestampe_delayed;
if ((timestampe_delayed < 10
|| abs(pTable->last_pts_delay_ms - timestampe_delayed) > 3000)
Expand All @@ -253,6 +255,7 @@ int calculation_stream_delayed_ms(u8 type, u32 *latestbitrate,
} else
/* #endif */
diff2 = stbuf_level(get_buf_by_type(type));

/* #if MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON8 */
if (has_hevc_vdec()) {
if (pTable->hevc) {
Expand All @@ -270,7 +273,7 @@ int calculation_stream_delayed_ms(u8 type, u32 *latestbitrate,
if (diff2 > stbuf_space(get_buf_by_type(type)))
diff = diff2;
}
delay_ms = diff * 1000 / (1 + pTable->last_avg_bitrate / 8);
delay_ms = (diff * 1000) / (int)(1 + pTable->last_avg_bitrate / 8);

if (timestampe_delayed < 10
|| (abs(timestampe_delayed - delay_ms) > 3 * 1000
Expand Down Expand Up @@ -888,6 +891,7 @@ static int pts_lookup_offset_inline_locked(u8 type, u32 offset, u32 *val,
* use first checkin pts instead */
if (!pTable->first_lookup_ok) {
*val = pTable->first_checkin_pts;
*uS64 = div64_u64((u64)pTable->first_checkin_pts * 100, 9);
pTable->first_lookup_ok = 1;
pTable->first_lookup_is_fail = 1;

Expand Down
2 changes: 2 additions & 0 deletions drivers/amlogic/amports/video.c
Original file line number Diff line number Diff line change
Expand Up @@ -3340,6 +3340,8 @@ static irqreturn_t vsync_isr(int irq, void *dev_id)
}
if (omx_secret_mode == true) {
u32 system_time = timestamp_pcrscr_get();
video_notify_flag |= VIDEO_NOTIFY_TRICK_WAIT;
atomic_set(&trickmode_framedone, 1);
int diff = system_time - omx_pts;
if ((diff - omx_pts_interval_upper) > 0
|| (diff - omx_pts_interval_lower) < 0) {
Expand Down
2 changes: 2 additions & 0 deletions drivers/amlogic/deinterlace/deinterlace.c
Original file line number Diff line number Diff line change
Expand Up @@ -1689,6 +1689,7 @@ struct di_post_stru_s {
bool toggle_flag;
bool vscale_skip_flag;
uint start_pts;
u64 start_pts_us64;
int buf_type;
};
#define di_post_stru_t struct di_post_stru_s
Expand Down Expand Up @@ -4438,6 +4439,7 @@ di_buf_i->vframe->type); */
disp_vf->height = di_buf_i->vframe->height;
disp_vf->duration = di_buf_i->vframe->duration;
disp_vf->pts = di_buf_i->vframe->pts;
disp_vf->pts_us64 = di_buf_i->vframe->pts_us64;
disp_vf->flag = di_buf_i->vframe->flag;
disp_vf->canvas0Addr = di_post_idx[di_post_stru.canvas_id][0];
disp_vf->canvas1Addr = di_post_idx[di_post_stru.canvas_id][0];
Expand Down
1 change: 1 addition & 0 deletions drivers/amlogic/video_dev/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ config V4L_AMLOGIC_VIDEO
tristate "Amlogic v4l video device support"
select VIDEO_DEV
select VIDEO_V4L2
select VIDEOBUF_GEN
select VIDEOBUF_RESOURCE
default n
---help---
Expand Down
68 changes: 60 additions & 8 deletions drivers/amlogic/video_dev/amlvideo.c
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,11 @@ AMLVIDEO_MINOR_VERSION, AMLVIDEO_RELEASE)

#define AMLVIDEO_POOL_SIZE 16
static struct vfq_s q_ready;
static struct vfq_s q_omx;
/*extern bool omx_secret_mode;*/
static u8 first_frame;
static u64 last_pts_us64;
static u32 omx_freerun_index = 0;

#define DUR2PTS(x) ((x) - ((x) >> 4))
#define DUR2PTS_RM(x) ((x) & 0xf)
Expand Down Expand Up @@ -144,9 +146,11 @@ static struct vivi_fmt formats[] = {
};

struct vframe_s *amlvideo_pool_ready[AMLVIDEO_POOL_SIZE + 1];
struct vframe_s *amlvideo_pool_omx[AMLVIDEO_POOL_SIZE + 1];
/* ------------------------------------------------------------------
* provider operations
*-----------------------------------------------------------------*/

static struct vframe_s *amlvideo_vf_peek(void *op_arg)
{
return vfq_peek(&q_ready);
Expand Down Expand Up @@ -182,10 +186,11 @@ static int amlvideo_vf_states(struct vframe_states *states, void *op_arg)
{
/* unsigned long flags; */
/* spin_lock_irqsave(&lock, flags); */
int avail_count = vfq_level(&q_ready) + vfq_level(&q_omx);
states->vf_pool_size = AMLVIDEO_POOL_SIZE;
states->buf_recycle_num = 0;
states->buf_free_num = AMLVIDEO_POOL_SIZE - vfq_level(&q_ready);
states->buf_avail_num = vfq_level(&q_ready);
states->buf_free_num = AMLVIDEO_POOL_SIZE - avail_count;
states->buf_avail_num = avail_count;
/* spin_unlock_irqrestore(&lock, flags); */
return 0;
}
Expand Down Expand Up @@ -315,6 +320,8 @@ static int video_receiver_event_fun(int type, void *data, void *private_data)
NULL);
vfq_init(&q_ready, AMLVIDEO_POOL_SIZE + 1,
&amlvideo_pool_ready[0]);
vfq_init(&q_omx, AMLVIDEO_POOL_SIZE + 1,
&amlvideo_pool_omx[0]);
}
}
return 0;
Expand Down Expand Up @@ -550,8 +557,34 @@ static int vidioc_querybuf(struct file *file, void *priv, struct v4l2_buffer *p)
static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *p)
{
int ret = 0;
u32 index;
if (omx_secret_mode == true)
{
if (freerun_mode == 3)
{
struct vframe_s *vf;
while ((vf = vfq_peek(&q_omx)))
{
index = (u32)vf->pts_us64;
if (p->index > index)
{
vf_put(vfq_pop(&q_omx), RECEIVER_NAME);
printk("vidioc_qbuf skip: index:%u:%u\n", p->index, index);
continue;
}
else if (p->index == index)
{
vf = (vfq_pop(&q_omx));
if (p->flags & V4L2_BUF_FLAG_DONE)
vf_put(vf, RECEIVER_NAME);
else
vfq_push(&q_ready, vf);
}
break;
}
}
return ret;
}

if (ppmgrvf) {
vf_put(ppmgrvf, RECEIVER_NAME);
Expand Down Expand Up @@ -633,8 +666,11 @@ static int freerun_dqbuf(struct v4l2_buffer *p)
return -EAGAIN;
}
if (omx_secret_mode == true) {
vfq_push(&q_ready, ppmgrvf);
p->index = 0;

//printk("%s, %s, %d %x %llx\n", __FILE__, __FUNCTION__, __LINE__, ppmgrvf->pts, ppmgrvf->pts_us64);

if (!ppmgrvf->pts_us64)
ppmgrvf->pts_us64 = ((u64)ppmgrvf->pts * 100) / 9;

if (ppmgrvf->pts_us64) {
first_frame = 1;
Expand All @@ -644,11 +680,27 @@ static int freerun_dqbuf(struct v4l2_buffer *p)
pts_us64 = 0;
} else {
pts_us64 = last_pts_us64
+ (DUR2PTS(ppmgrvf->duration));
+ (DUR2PTS(ppmgrvf->duration)) * 100 / 9;
}
p->timestamp.tv_sec = pts_us64 >> 32;
p->timestamp.tv_usec = pts_us64 & 0xFFFFFFFF;
last_pts_us64 = pts_us64;

if (freerun_mode != 3)
{
p->index = 0;
vfq_push(&q_ready, ppmgrvf);
vf_notify_receiver(
PROVIDER_NAME,
VFRAME_EVENT_PROVIDER_VFRAME_READY,
NULL);
}
else
{
p->index = omx_freerun_index;
ppmgrvf->pts_us64 = omx_freerun_index++;
vfq_push(&q_omx, ppmgrvf);
}
return ret;
}
if (ppmgrvf->pts != 0) {
Expand All @@ -658,8 +710,8 @@ static int freerun_dqbuf(struct v4l2_buffer *p)
ppmgrvf->pts = timestamp_vpts_get();
}

if (!ppmgrvf->pts)
ppmgrvf->pts_us64 = ppmgrvf->pts * 100 / 9;
if (!ppmgrvf->pts_us64)
ppmgrvf->pts_us64 = ((u64)ppmgrvf->pts * 100) / 9;

if (unregFlag || startFlag) {
if (ppmgrvf->pts == 0)
Expand Down Expand Up @@ -776,7 +828,7 @@ static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
{
int ret = 0;

if (freerun_mode == 1) {
if (freerun_mode == 1 || freerun_mode == 3) {
/* pr_err("amlvideo dqbuf called freerun_mode=1\n"); */
ret = freerun_dqbuf(p);
} else if (freerun_mode == 2) {
Expand Down