PD #98650(97418):merge pcr master .

http://10.8.9.5/kernel/common/commit/?h=amlogic-pd-93123-01&id=eb9f5e55d99857452bdfbf805d43e46098629d89
http://10.8.9.5/kernel/common/commit/?h=amlogic-pd-97418&id=67606625f74d81ca18430a05e96fded80a5cbfe3
http://10.8.9.5/kernel/common/commit/?h=amlogic-pd-97418-1&id=dec32e9944bc547974f1e7d40f1414664052587e

Change-Id: I0788b74d16a9d78575c03703af1683d02d89190c

PD #98650(97418):the compile problem in M6

Change-Id: Ia69ba55f5c2feb1a495136a993103e9f3fe33463
This commit is contained in:
le.yang
2014-10-16 08:33:11 +00:00
committed by Mauro Ribeiro
parent 5df72f4e83
commit f4ee3bf45d
14 changed files with 543 additions and 163 deletions

View File

@@ -66,6 +66,7 @@
#include "amvideocap_priv.h"
#include "amports_priv.h"
#include "amports_config.h"
#include "tsync_pcr.h"
#include <linux/firmware.h>
@@ -665,24 +666,25 @@ static int amstream_port_init(stream_port_t *port)
}
}
if (port->type & PORT_TYPE_MPTS) {
if (HAS_HEVC_VDEC) {
r = tsdemux_init((port->flag & PORT_FLAG_VID) ? port->vid : 0xffff,
(port->flag & PORT_FLAG_AID) ? port->aid : 0xffff,
(port->flag & PORT_FLAG_SID) ? port->sid : 0xffff,
port->pcrid,
(port->vformat == VFORMAT_HEVC));
} else {
r = tsdemux_init((port->flag & PORT_FLAG_VID) ? port->vid : 0xffff,
(port->flag & PORT_FLAG_AID) ? port->aid : 0xffff,
(port->flag & PORT_FLAG_SID) ? port->sid : 0xffff,
port->pcrid, 0);
}
if (port->type & PORT_TYPE_MPTS) {
if (HAS_HEVC_VDEC) {
r = tsdemux_init((port->flag & PORT_FLAG_VID) ? port->vid : 0xffff,
(port->flag & PORT_FLAG_AID) ? port->aid : 0xffff,
(port->flag & PORT_FLAG_SID) ? port->sid : 0xffff,
(port->pcr_inited == 1) ? port->pcrid : 0xffff,
(port->vformat == VFORMAT_HEVC));
}else{
r = tsdemux_init((port->flag & PORT_FLAG_VID) ? port->vid : 0xffff,
(port->flag & PORT_FLAG_AID) ? port->aid : 0xffff,
(port->flag & PORT_FLAG_SID) ? port->sid : 0xffff,
(port->pcr_inited == 1) ? port->pcrid : 0xffff, 0);
}
if (r < 0) {
printk("tsdemux_init failed\n");
goto error4;
}
tsync_pcr_start();
}
if (port->type & PORT_TYPE_MPPS) {
r = psparser_init((port->flag & PORT_FLAG_VID) ? port->vid : 0xffff,
@@ -736,6 +738,7 @@ static int amstream_port_release(stream_port_t *port)
}
if (port->type & PORT_TYPE_MPTS) {
tsync_pcr_stop();
tsdemux_release();
}
@@ -756,6 +759,7 @@ static int amstream_port_release(stream_port_t *port)
sub_port_release(port, psbuf);
}
port->pcr_inited=0;
port->flag = 0;
return 0;
}
@@ -1142,6 +1146,7 @@ static int amstream_open(struct inode *inode, struct file *file)
file->private_data = this;
this->flag = PORT_FLAG_IN_USE;
this->pcr_inited = 0;
#ifdef DATA_DEBUG
debug_filp = filp_open(DEBUG_FILE_NAME, O_WRONLY, 0);
if (IS_ERR(debug_filp)) {
@@ -1334,6 +1339,7 @@ static long amstream_ioctl(struct file *file,
case AMSTREAM_IOC_PCRID:
this->pcrid= (u32)arg;
this->pcr_inited = 1;
printk("set pcrid = 0x%x \n", this->pcrid);
break;
@@ -1742,6 +1748,9 @@ static long amstream_ioctl(struct file *file,
printk("Get audio pts from user space fault! \n");
return -EFAULT;
}
if(tsync_get_mode()==TSYNC_MODE_PCRMASTER)
tsync_pcr_set_apts(pts);
else
tsync_set_apts(pts);
break;
}
@@ -1811,6 +1820,7 @@ static ssize_t ports_show(struct class *class, struct class_attribute *attr, cha
pbuf += sprintf(pbuf, "\tVid:%d\n", (p->flag & PORT_FLAG_VID) ? p->vid : -1);
pbuf += sprintf(pbuf, "\tAid:%d\n", (p->flag & PORT_FLAG_AID) ? p->aid : -1);
pbuf += sprintf(pbuf, "\tSid:%d\n", (p->flag & PORT_FLAG_SID) ? p->sid : -1);
pbuf += sprintf(pbuf, "\tPCRid:%d\n", (p->pcr_inited == 1) ? p->pcrid : -1);
pbuf += sprintf(pbuf, "\tachannel:%d\n", p->achanl);
pbuf += sprintf(pbuf, "\tasamprate:%d\n", p->asamprate);
pbuf += sprintf(pbuf, "\tadatawidth:%d\n\n", p->adatawidth);

View File

@@ -280,6 +280,27 @@ int calculation_vcached_delayed(void)
}
EXPORT_SYMBOL(calculation_vcached_delayed);
// return the 1/90000 unit time
int calculation_acached_delayed(void){
pts_table_t *pTable;
u32 delay=0;
pTable = &pts_table[PTS_TYPE_AUDIO];
delay = pTable->last_checkin_pts-pTable->last_checkout_pts;
if (0<delay && delay<5*90000)
return delay;
if(pTable->last_avg_bitrate>0){
int diff = pTable->last_checkin_offset-pTable->last_checkout_offset;
delay=diff*90000/(1+pTable->last_avg_bitrate/8);
return delay;
}
return -1;
}
EXPORT_SYMBOL(calculation_acached_delayed);
int calculation_stream_ext_delayed_ms(u8 type)
{
pts_table_t *pTable;
@@ -548,7 +569,7 @@ int pts_lookup(u8 type, u32 *val, u32 pts_margin)
}
EXPORT_SYMBOL(pts_lookup);
static int pts_lookup_offset_inline(
static int _pts_lookup_offset_inline(
u8 type, u32 offset, u32 *val, u32 pts_margin, u64 *uS64)
{
ulong flags;
@@ -771,6 +792,24 @@ static int pts_lookup_offset_inline(
return -1;
}
static int pts_lookup_offset_inline(
u8 type, u32 offset, u32 *val, u32 pts_margin, u64 *uS64){
int res = _pts_lookup_offset_inline(type,offset,val,pts_margin,uS64);
if(timestamp_firstvpts_get()==0&&res==0&&(*val)!=0&&type==PTS_TYPE_VIDEO){
timestamp_firstvpts_set(*val);
}
#if MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON8
else if(timestamp_firstvpts_get()==0&&res==0&&(*val)!=0&&type==PTS_TYPE_HEVC){
timestamp_firstvpts_set(*val);
}
#endif
else if(timestamp_firstapts_get()==0&&res==0&&(*val)!=0&&type==PTS_TYPE_AUDIO){
timestamp_firstapts_set(*val);
}
return res;
}
int pts_lookup_offset(u8 type, u32 offset, u32 *val, u32 pts_margin){
u64 pts_us;
return pts_lookup_offset_inline(type,offset,val,pts_margin,&pts_us);
@@ -929,6 +968,7 @@ int pts_start(u8 type)
- pTable->buf_start;
WRITE_MPEG_REG(VIDEO_PTS, 0);
timestamp_pcrscr_set(0);//video always need the pcrscr,Clear it to use later
timestamp_firstvpts_set(0);
pTable->first_checkin_pts = -1;
pTable->first_lookup_ok = 0;
pTable->first_lookup_is_fail = 0;
@@ -948,6 +988,7 @@ int pts_start(u8 type)
WRITE_MPEG_REG(VIDEO_PTS, 0);
timestamp_pcrscr_set(0);//video always need the pcrscr,Clear it to use later
timestamp_firstvpts_set(0);
pTable->first_checkin_pts = -1;
pTable->first_lookup_ok = 0;
pTable->first_lookup_is_fail = 0;
@@ -959,6 +1000,7 @@ int pts_start(u8 type)
//BUG_ON(pTable->buf_size <= 0x10000);
WRITE_MPEG_REG(AUDIO_PTS, 0);
timestamp_firstapts_set(0);
pTable->first_checkin_pts = -1;
pTable->first_lookup_ok = 0;
pTable->first_lookup_is_fail = 0;

View File

@@ -67,6 +67,7 @@ typedef struct stream_port_s {
/* ports control */
s32 type;
s32 flag;
s32 pcr_inited;
/* decoder info */
s32 vformat;

View File

@@ -1,5 +1,5 @@
#include <linux/module.h>
#include <linux/amlogic/amports/tsync.h>
#include <mach/am_regs.h>
unsigned int timestamp_enable_resample_flag = 0;
EXPORT_SYMBOL(timestamp_enable_resample_flag);
@@ -72,7 +72,7 @@ void timestamp_apts_inc(s32 inc)
#ifdef MODIFY_TIMESTAMP_INC_WITH_PLL
inc = inc*timestamp_inc_factor/PLL_FACTOR;
#endif
if(0){//timestamp_enable_resample_flag){
if(tsync_get_mode()!=TSYNC_MODE_PCRMASTER){//timestamp_enable_resample_flag){
if(timestamp_resample_type_flag==0){
//0-->no resample processing
}else if(timestamp_resample_type_flag==1){//1-->down resample processing
@@ -100,6 +100,7 @@ EXPORT_SYMBOL(timestamp_apts_inc);
void timestamp_apts_enable(u32 enable)
{
audio_pts_up = enable;
printk("timestamp_apts_enable enable:%x, \n", enable);
}
EXPORT_SYMBOL(timestamp_apts_enable);
@@ -135,6 +136,7 @@ EXPORT_SYMBOL(timestamp_pcrscr_set);
void timestamp_firstvpts_set(u32 pts)
{
first_vpts = pts;
printk("video first pts = %x\n", first_vpts);
}
EXPORT_SYMBOL(timestamp_firstvpts_set);
@@ -148,6 +150,7 @@ EXPORT_SYMBOL(timestamp_firstvpts_get);
void timestamp_firstapts_set(u32 pts)
{
first_apts = pts;
printk("audio first pts = %x\n", first_apts);
}
EXPORT_SYMBOL(timestamp_firstapts_set);
@@ -164,7 +167,7 @@ void timestamp_pcrscr_inc(s32 inc)
#ifdef MODIFY_TIMESTAMP_INC_WITH_PLL
inc = inc*timestamp_inc_factor/PLL_FACTOR;
#endif
if(0){//timestamp_enable_resample_flag){
if(tsync_get_mode()!=TSYNC_MODE_PCRMASTER){//timestamp_enable_resample_flag){
if(timestamp_resample_type_flag==0){ //0-->no resample processing
}else if(timestamp_resample_type_flag==1){//1-->down resample processing

View File

@@ -52,7 +52,8 @@ const static char tsdemux_irq_id[] = "tsdemux-irq-id";
static DECLARE_WAIT_QUEUE_HEAD(wq);
static u32 fetch_done;
static u32 discontinued_counter;
static int pcrscr_valid=0;
static u32 first_pcr = 0;
static u8 pcrscr_valid=0;
static int demux_skipbyte;
@@ -620,6 +621,7 @@ s32 tsdemux_init(u32 vid, u32 aid, u32 sid, u32 pcrid, bool is_hevc)
}
#endif
if (pcrid < 0x1FFF){
/* set paramater to fetch pcr */
pcr_num=0;
if(pcrid == vid)
@@ -644,7 +646,9 @@ s32 tsdemux_init(u32 vid, u32 aid, u32 sid, u32 pcrid, bool is_hevc)
WRITE_MPEG_REG(ASSIGN_PID_NUMBER, pcr_num);
printk("[tsdemux_init] To use device 1,pcr_num=%d \n",pcr_num);
}
first_pcr = 0;
pcrscr_valid=1;
}
return 0;
@@ -669,6 +673,7 @@ err1:
void tsdemux_release(void)
{
pcrscr_valid=0;
first_pcr=0;
WRITE_MPEG_REG(PARSER_INT_ENABLE, 0);
WRITE_MPEG_REG(PARSER_VIDEO_HOLE, 0);
@@ -911,18 +916,27 @@ void tsdemux_set_demux(int dev)
u32 tsdemux_pcrscr_get(void)
{
u32 pcr;
if(READ_MPEG_REG(TS_HIU_CTL_2) & 0x40){
return READ_MPEG_REG(PCR_DEMUX_2);
pcr = READ_MPEG_REG(PCR_DEMUX_2);
}
else if(READ_MPEG_REG(TS_HIU_CTL_3) & 0x40){
return READ_MPEG_REG(PCR_DEMUX_3);
pcr = READ_MPEG_REG(PCR_DEMUX_3);
}
else{
return READ_MPEG_REG(PCR_DEMUX);
pcr = READ_MPEG_REG(PCR_DEMUX);
}
if(first_pcr == 0)
first_pcr = pcr;
return pcr;
}
int tsdemux_pcrscr_valid(void)
u32 tsdemux_first_pcrscr_get(void)
{
return first_pcr;
}
u8 tsdemux_pcrscr_valid(void)
{
return pcrscr_valid;
}

View File

@@ -81,7 +81,8 @@ extern ssize_t tsdemux_write(struct file *file,
const char __user *buf, size_t count);
extern u32 tsdemux_pcrscr_get(void);
extern int tsdemux_pcrscr_valid(void);
extern u8 tsdemux_pcrscr_valid(void);
extern u32 tsdemux_first_pcrscr_get(void);
int tsdemux_class_register(void);
void tsdemux_class_unregister(void);

View File

@@ -976,6 +976,12 @@ void tsync_pcr_recover(void)
EXPORT_SYMBOL(tsync_pcr_recover);
int tsync_get_mode(void)
{
return tsync_mode;
}
EXPORT_SYMBOL(tsync_get_mode);
int tsync_get_debug_pts_checkin(void)
{
return debug_pts_checkin;

View File

@@ -1,16 +1,20 @@
#include <linux/module.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/timer.h>
#include <linux/amlogic/amports/tsync.h>
#include <linux/platform_device.h>
#include <linux/amlogic/amports/timestamp.h>
#include <linux/amlogic/amports/ptsserv.h>
#include "tsync_pcr.h"
#include "amvdec.h"
#include "tsdemux.h"
#include "streambuf.h"
#include "amports_priv.h"
//#define CONFIG_AM_PCRSYNC_LOG
#define CONFIG_AM_PCRSYNC_LOG
#ifdef CONFIG_AM_PCRSYNC_LOG
#define AMLOG
@@ -34,9 +38,9 @@ typedef enum {
#define CHECK_INTERVAL (HZ * 5)
#define START_AUDIO_LEVEL 256
#define START_VIDEO_LEVEL 2048
#define START_VIDEO_LEVEL 20480
#define PAUSE_AUDIO_LEVEL 16
#define PAUSE_VIDEO_LEVEL 512
#define PAUSE_VIDEO_LEVEL 256
#define UP_RESAMPLE_AUDIO_LEVEL 128
#define UP_RESAMPLE_VIDEO_LEVEL 1024
#define DOWN_RESAMPLE_CACHE_TIME 90000*2
@@ -45,17 +49,43 @@ typedef enum {
/* the diff of system time and referrence lock, which use the threshold to adjust the system time */
#define OPEN_RECOVERY_THRESHOLD 18000
#define CLOSE_RECOVERY_THRESHOLD 300
#define RECOVERY_SPAN 10
#define RECOVERY_SPAN 5
#define FORCE_RECOVERY_SPAN 20
/* the delay from ts demuxer to the amvideo */
#define DEFAULT_VSTREAM_DELAY 18000
static struct timer_list tsync_pcr_check_timer;
#define RESAMPLE_TYPE_NONE 0
#define RESAMPLE_TYPE_DOWN 1
#define RESAMPLE_TYPE_UP 2
#define RESAMPLE_DOWN_FORCE_PCR_SLOW 3
#define MS_INTERVAL (HZ/1000)
#define TEN_MS_INTERVAL (HZ/100)
// ------------------------------------------------------------------
// The const
static u32 tsync_pcr_discontinue_threshold = (TIME_UNIT90K * 1.5);
static u32 tsync_pcr_ref_latency = 30000; //TIME_UNIT90K/3
static u32 tsync_pcr_ref_cache_time = TIME_UNIT90K;
// use for pcr valid mode
static u32 tsync_pcr_max_cache_time = TIME_UNIT90K*2; //TIME_UNIT90K*2;
static u32 tsync_pcr_up_cache_time = TIME_UNIT90K*1.5; //TIME_UNIT90K*1.5;
static u32 tsync_pcr_down_cache_time = TIME_UNIT90K*1.2; //TIME_UNIT90K*1.2;
static u32 tsync_pcr_min_cache_time = TIME_UNIT90K*0.8; //TIME_UNIT90K*0.8;
// use for pcr invalid mode
static u32 tsync_pcr_max_delay_time = TIME_UNIT90K*3; //TIME_UNIT90K*3;
static u32 tsync_pcr_up_delay_time = TIME_UNIT90K*2; //TIME_UNIT90K*2;
static u32 tsync_pcr_down_delay_time = TIME_UNIT90K*1.5; //TIME_UNIT90K*1.5;
static u32 tsync_pcr_min_delay_time = TIME_UNIT90K*1; //TIME_UNIT90K*0.8;
// ------------------------------------------------------------------
// The variate
static struct timer_list tsync_pcr_check_timer;
static u32 tsync_pcr_system_startpcr=0;
static u32 tsync_pcr_tsdemux_startpcr=0;
@@ -63,19 +93,24 @@ static u32 tsync_pcr_tsdemux_startpcr=0;
static int tsync_pcr_vpause_flag = 0;
static int tsync_pcr_apause_flag = 0;
static int tsync_pcr_vstart_flag = 0;
static int tsync_pcr_astart_flag = 0;
static int tsync_pcr_inited_flag = 0;
// the really ts demuxer pcr, haven't delay
static u32 tsync_pcr_last_tsdemuxpcr = 0;
static u32 tsync_pcr_discontinue_point = 0;
static u32 tsync_pcr_discontinue_local_point = 0;
static u32 tsync_pcr_discontinue_waited = 0; // the time waited the v-discontinue to happen
static int tsync_pcr_tsdemuxpcr_discontinue = 0; // the boolean value
static u8 tsync_pcr_tsdemuxpcr_discontinue = 0; // the boolean value
static u32 tsync_pcr_discontinue_point = 0;
static int abuf_level=0;
static int abuf_size=0;
static int vbuf_level=0;
static int vbuf_size=0;
static int play_mode=PLAY_MODE_NORMAL;
static u8 tsync_pcr_started=0;
static int tsync_pcr_read_cnt=0;
static u8 tsync_pcr_usepcr=1;
//static int tsync_pcr_debug_pcrscr = 100;
extern int get_vsync_pts_inc_mode(void);
@@ -91,13 +126,13 @@ u32 tsync_pcr_vstream_delayed(void)
void tsync_pcr_avevent_locked(avevent_t event, u32 param)
{
switch (event) {
case VIDEO_START:
if (tsync_pcr_vstart_flag == 0) {
timestamp_firstvpts_set(param);
//play_mode=PLAY_MODE_NORMAL;
printk("video start! init system time param=%x cur_pcr=%x\n",param,timestamp_pcrscr_get());
}
/*
if(tsync_pcr_vstart_flag == 0 && tsync_pcr_inited_flag == 0){
u32 ref_pcr=param - VIDEO_HOLD_THRESHOLD; // to wait 3 second
u32 tsdemux_pcr = tsdemux_pcrscr_get();
@@ -110,14 +145,13 @@ void tsync_pcr_avevent_locked(avevent_t event, u32 param)
if (!tsync_pcr_vpause_flag) {
timestamp_pcrscr_enable(1);
}
}
}*/
tsync_pcr_vstart_flag=1;
break;
case VIDEO_STOP:
timestamp_pcrscr_enable(0);
timestamp_vpts_set(0);
timestamp_firstvpts_set(0);
//tsync_pcr_debug_pcrscr=100;
tsync_pcr_vpause_flag=0;
@@ -126,50 +160,55 @@ void tsync_pcr_avevent_locked(avevent_t event, u32 param)
tsync_pcr_tsdemuxpcr_discontinue=0;
tsync_pcr_discontinue_point=0;
tsync_pcr_discontinue_local_point=0;
tsync_pcr_discontinue_waited=0;
tsync_pcr_tsdemux_startpcr = 0;
tsync_pcr_system_startpcr = 0;
play_mode=PLAY_MODE_NORMAL;
printk("video stop! \n");
break;
case VIDEO_TSTAMP_DISCONTINUITY:
{
unsigned oldpts=timestamp_vpts_get();
if((abs(param-oldpts)>AV_DISCONTINUE_THREDHOLD_MIN) && (!get_vsync_pts_inc_mode())){
u32 tsdemux_pcr = tsdemux_pcrscr_get();
u32 ref_pcr = param;
printk("[tsync_pcr_avevent_locked] video discontinue happen.param=%x,discontinue=%d\n",param,tsync_pcr_tsdemuxpcr_discontinue);
//unsigned oldpts=timestamp_vpts_get();
u32 tsdemux_pcr = tsdemux_pcrscr_get();
//if((abs(param-oldpts)>AV_DISCONTINUE_THREDHOLD_MIN) && (!get_vsync_pts_inc_mode())){
if(!get_vsync_pts_inc_mode()){
u32 ref_pcr = param-tsync_pcr_ref_latency*2;
//if(ref_pcr == 0)
// ref_pcr=tsdemux_pcr-tsync_pcr_vstream_delayed();
timestamp_pcrscr_set(ref_pcr);
tsync_pcr_tsdemux_startpcr = tsdemux_pcr;
tsync_pcr_system_startpcr = ref_pcr;
printk("reset ref pcr=%x , ts demuxer pcr=%x \n",tsync_pcr_system_startpcr, tsync_pcr_tsdemux_startpcr);
//play_mode=PLAY_MODE_FORCE_SLOW;
printk("[tsync_pcr_avevent_locked] video discontinue happen and slow play.ref_pcr=%x,param=%x,discontinue=%d\n",ref_pcr,param,tsync_pcr_tsdemuxpcr_discontinue);
/* to resume the pcr check*/
tsync_pcr_tsdemuxpcr_discontinue=0;
tsync_pcr_discontinue_point=0;
tsync_pcr_discontinue_local_point=0;
tsync_pcr_discontinue_waited=0;
}
//}
timestamp_vpts_set(param);
break;
}
case AUDIO_PRE_START:
timestamp_apts_start(0);
tsync_pcr_astart_flag=0;
printk("audio prestart! \n");
break;
case AUDIO_START:
if(timestamp_apts_started()==0)
timestamp_firstapts_set(param);
case AUDIO_START:
timestamp_apts_set(param);
timestamp_apts_enable(1);
timestamp_apts_start(1);
tsync_pcr_astart_flag=1;
tsync_pcr_apause_flag=0;
printk("audio start!timestamp_apts_set =%x. \n",param);
break;
@@ -184,7 +223,7 @@ void tsync_pcr_avevent_locked(avevent_t event, u32 param)
timestamp_apts_enable(0);
timestamp_apts_set(-1);
timestamp_apts_start(0);
timestamp_firstapts_set(0);
tsync_pcr_astart_flag=0;
tsync_pcr_apause_flag=0;
printk("audio stop! \n");
break;
@@ -236,36 +275,48 @@ void tsync_pcr_avevent_locked(avevent_t event, u32 param)
// timer to check the system with the referrence time in ts stream.
static unsigned long tsync_pcr_check(void)
{
u32 tsdemux_pcr=tsdemux_pcrscr_get();
u32 tsdemux_pcr=0;
u32 tsdemux_pcr_diff=0;
int need_recovery=1;
unsigned long res=jiffies;
/* check the value valid */
if(tsync_pcr_last_tsdemuxpcr ==0 && tsdemux_pcr ==0)
return res;
// To monitor the pcr discontinue
tsdemux_pcr_diff=abs(tsdemux_pcr - tsync_pcr_last_tsdemuxpcr);
if(tsdemux_pcr_diff > tsync_pcr_discontinue_threshold && tsync_pcr_tsdemuxpcr_discontinue==0 && tsync_pcr_inited_flag==1){
tsync_pcr_tsdemuxpcr_discontinue=1;
tsync_pcr_discontinue_waited=tsync_pcr_vstream_delayed()+TIME_UNIT90K;
printk("[tsync_pcr_check] refpcr_discontinue. tsdemux_pcr_diff=%x, last refpcr=%x, repcr=%x\n",tsdemux_pcr_diff,tsync_pcr_last_tsdemuxpcr,tsdemux_pcr);
tsync_pcr_discontinue_point=timestamp_pcrscr_get();
need_recovery=0;
unsigned long res=1;
if(tsync_get_mode() != TSYNC_MODE_PCRMASTER){
return res;
}
else if(tsync_pcr_tsdemuxpcr_discontinue == 1){
// to pause the pcr check
if(abs(timestamp_pcrscr_get()-tsync_pcr_discontinue_point)>tsync_pcr_discontinue_waited){
// the v-discontinue did'n happen
tsync_pcr_tsdemuxpcr_discontinue=0;
tsync_pcr_discontinue_point=0;
tsync_pcr_discontinue_waited=0;
printk("[tsync_pcr_check] video discontinue didn't happen, waited=%lx\n",abs(tsdemux_pcr-tsync_pcr_discontinue_point));
tsdemux_pcr=tsdemux_pcrscr_get();
if(tsync_pcr_usepcr==1){
// To monitor the pcr discontinue
tsdemux_pcr_diff=abs(tsdemux_pcr - tsync_pcr_last_tsdemuxpcr);
if(tsync_pcr_last_tsdemuxpcr!=0&&tsdemux_pcr!=0&&tsdemux_pcr_diff > tsync_pcr_discontinue_threshold && tsync_pcr_inited_flag==1){
u32 video_delayed=0;
tsync_pcr_tsdemuxpcr_discontinue=1;
video_delayed = tsync_pcr_vstream_delayed();
if(TIME_UNIT90K*2<=video_delayed&&video_delayed<=TIME_UNIT90K*4)
tsync_pcr_discontinue_waited=video_delayed+TIME_UNIT90K;
else if(TIME_UNIT90K*2>video_delayed)
tsync_pcr_discontinue_waited=TIME_UNIT90K*3;
else
tsync_pcr_discontinue_waited=TIME_UNIT90K*5;
printk("[tsync_pcr_check] refpcr_discontinue. tsdemux_pcr_diff=%x, last refpcr=%x, repcr=%x,waited=%x\n",tsdemux_pcr_diff,tsync_pcr_last_tsdemuxpcr,tsdemux_pcr,tsync_pcr_discontinue_waited);
tsync_pcr_discontinue_local_point=timestamp_pcrscr_get();
tsync_pcr_discontinue_point=tsdemux_pcr-tsync_pcr_ref_latency;
need_recovery=0;
}
need_recovery=0;
else if(tsync_pcr_tsdemuxpcr_discontinue == 1){
// to pause the pcr check
if(abs(timestamp_pcrscr_get()-tsync_pcr_discontinue_local_point)>tsync_pcr_discontinue_waited){
printk("[tsync_pcr_check] video discontinue didn't happen, waited=%x\n",tsync_pcr_discontinue_waited);
// the v-discontinue did'n happen
tsync_pcr_tsdemuxpcr_discontinue=0;
tsync_pcr_discontinue_point=0;
tsync_pcr_discontinue_local_point=0;
tsync_pcr_discontinue_waited=0;
}
need_recovery=0;
}
tsync_pcr_last_tsdemuxpcr=tsdemux_pcr;
}
tsync_pcr_last_tsdemuxpcr=tsdemux_pcr;
abuf_level= stbuf_level(get_buf_by_type(BUF_TYPE_AUDIO));
abuf_size= stbuf_size(get_buf_by_type(BUF_TYPE_AUDIO));
@@ -273,68 +324,117 @@ static unsigned long tsync_pcr_check(void)
vbuf_size= stbuf_size(get_buf_by_type(BUF_TYPE_VIDEO));
if(tsync_pcr_inited_flag == 0){
// check the video and audio stream buffer, to check to start
if((timestamp_apts_started() == 1 && tsync_pcr_vstart_flag)){
u32 ref_pcr =0;
//if(timestamp_firstvpts_get() <= timestamp_firstapts_get() || timestamp_firstapts_get() == 0){
ref_pcr=timestamp_firstvpts_get();
printk("[tsync_pcr_check]Inited use video pts. ref_pcr=%x tsdemux time=%x \n",ref_pcr,tsdemux_pcr);
//}
//else{
// ref_pcr=timestamp_firstapts_get();
// printk("[tsync_pcr_check]Inited use audio pts. ref_pcr=%x tsdemux time=%x \n",ref_pcr,tsdemux_pcr);
//}
timestamp_pcrscr_set(ref_pcr);
tsync_pcr_tsdemux_startpcr = tsdemux_pcr;
tsync_pcr_system_startpcr = ref_pcr;
tsync_pcr_inited_flag = 1;
play_mode=PLAY_MODE_FORCE_SLOW;
printk("[tsync_pcr_check] init and slow play.abuf_level=%x vbuf_level=%x \n", abuf_level,vbuf_level);
if (!tsync_pcr_vpause_flag) {
timestamp_pcrscr_enable(1);
}
u32 first_pcr =tsdemux_first_pcrscr_get();
u32 first_vpts = timestamp_firstvpts_get();
u32 first_apts = timestamp_firstapts_get();
u32 ref_pcr=0;
u8 ref_pcr_valid=0;
if(tsync_pcr_usepcr==1){
if(first_pcr != 0){
// pcr is valid, use
ref_pcr = first_pcr - tsync_pcr_ref_latency;
ref_pcr_valid=1;
printk("[tsync_pcr_check]Inited use pcr mode.ref_pcr=%x first_pcr=%x first_vpts=%x first_apts=%x \n",ref_pcr,first_pcr,first_vpts,first_apts);
}else{
if(first_vpts!=0||first_apts!=0){
tsync_pcr_usepcr=0;
printk("[tsync_pcr_check]can't read valid pcr, use other mode. read_cnt=%d \n",tsync_pcr_read_cnt);
}
tsync_pcr_read_cnt++;
}
}
else{
// pcr is invalid, use vmaster or amaster mode
if(tsync_pcr_astart_flag==1&&tsync_pcr_vstart_flag==1&&first_vpts!=0&&first_apts!=0&&vbuf_level>=START_VIDEO_LEVEL){
if(first_vpts <= first_apts){
//play_mode=PLAY_MODE_FORCE_SLOW;
ref_pcr = first_vpts;
printk("[tsync_pcr_check]Inited use video pts and slow play.ref_pcr=%x first_pcr=%x first_vpts=%x first_apts=%x \n",ref_pcr,first_pcr,first_vpts,first_apts);
}
else{
//play_mode=PLAY_MODE_FORCE_SLOW;
ref_pcr=first_apts;
printk("[tsync_pcr_check]Inited use audio pts and slow play.ref_pcr=%x first_pcr=%x first_vpts=%x first_apts=%x \n",ref_pcr,first_pcr,first_vpts,first_apts);
}
ref_pcr_valid=1;
}
else if(tsync_pcr_astart_flag==0&&tsync_pcr_vstart_flag==1&&first_vpts!=0&&(vbuf_level*20)>vbuf_size&&abuf_level==0){
int vdelayed=calculation_vcached_delayed();
if(tsync_pcr_max_cache_time<vdelayed){
//play_mode=PLAY_MODE_FORCE_SLOW;
ref_pcr = first_vpts;
printk("[tsync_pcr_check]No audio.Inited video pts and slow play.ref_pcr=%x first_pcr=%x first_vpts=%x vdelayed=%x \n",ref_pcr,first_pcr,first_vpts,vdelayed);
ref_pcr_valid=1;
}
}
else if(tsync_pcr_astart_flag==1&&tsync_pcr_vstart_flag==0&&first_apts!=0&&(abuf_level*20)>abuf_size&&vbuf_level==0){
int adelayed=calculation_acached_delayed();
if(tsync_pcr_max_cache_time<adelayed){
//play_mode=PLAY_MODE_FORCE_SLOW;
ref_pcr = first_apts;
ref_pcr_valid=1;
printk("[tsync_pcr_check]No video.Inited audio pts and slow play.ref_pcr=%x first_pcr=%x adelayed=%x first_apts=%x \n",ref_pcr,first_pcr,adelayed,first_apts);
}
}
}
return res;
}
if(!tsync_pcr_vpause_flag){
if(vbuf_level < PAUSE_VIDEO_LEVEL||abuf_level<PAUSE_AUDIO_LEVEL){
tsync_pcr_avevent_locked(VIDEO_PAUSE,1); // to pause
printk("[tsync_pcr_check] to pause abuf_level=%x vbuf_level=%x play_mode=%d \n",abuf_level,vbuf_level,play_mode);
if(ref_pcr_valid==1){
timestamp_pcrscr_set(ref_pcr);
tsync_pcr_inited_flag = 1;
printk("[tsync_pcr_check] inited.ref_pcr=%x abuf_level=%x vbuf_level=%x \n", ref_pcr,abuf_level,vbuf_level);
if (!tsync_pcr_vpause_flag) {
timestamp_pcrscr_enable(1);
}
}else{
return res;
}
}else{
if(vbuf_level < START_VIDEO_LEVEL||abuf_level < START_AUDIO_LEVEL)
return res;
}
}
printk("[tsync_pcr_check] resume and show play. abuf_level=%x vbuf_level=%x play_mode=%d\n",abuf_level,vbuf_level,play_mode);
// to resume
tsync_pcr_avevent_locked(VIDEO_PAUSE,0);
play_mode=PLAY_MODE_FORCE_SLOW;
if(tsync_pcr_usepcr==0){
if(!tsync_pcr_vpause_flag){
if(vbuf_level < PAUSE_VIDEO_LEVEL/*||abuf_level<PAUSE_AUDIO_LEVEL*/){
tsync_pcr_avevent_locked(VIDEO_PAUSE,1); // to pause
printk("[tsync_pcr_check] to pause abuf_level=%x vbuf_level=%x play_mode=%d \n",abuf_level,vbuf_level,play_mode);
return res;
}
}else{
if(vbuf_level < START_VIDEO_LEVEL/*||abuf_level < START_AUDIO_LEVEL*/)
return res;
printk("[tsync_pcr_check] resume and show play. abuf_level=%x vbuf_level=%x play_mode=%d\n",abuf_level,vbuf_level,play_mode);
// to resume
tsync_pcr_avevent_locked(VIDEO_PAUSE,0);
play_mode=PLAY_MODE_FORCE_SLOW;
}
}
if((vbuf_level * 5 > vbuf_size * 4 || abuf_level * 5 > abuf_size * 4) && play_mode != PLAY_MODE_FORCE_SPEED){
printk("[tsync_pcr_check]Buffer will overflow and speed play. vlevel=%x vsize=%x alevel=%x asize=%x play_mode=%d\n",
vbuf_level,vbuf_size,abuf_level,abuf_size, play_mode);
// the video stream buffer will happen overflow
play_mode=PLAY_MODE_FORCE_SPEED;
u32 new_pcr=0;
play_mode=PLAY_MODE_FORCE_SPEED;
new_pcr=timestamp_pcrscr_get()+72000; // 90000*0.8
timestamp_pcrscr_set(new_pcr);
printk("[tsync_pcr_check]Buffer will overflow and speed play. new_pcr=%x vlevel=%x vsize=%x alevel=%x asize=%x play_mode=%d\n",
new_pcr,vbuf_level,vbuf_size,abuf_level,abuf_size, play_mode);
}
if(play_mode == PLAY_MODE_FORCE_SLOW){
if((vbuf_level * 50 > vbuf_size && abuf_level * 50 > abuf_size)||
vbuf_level * 10 > vbuf_size ||
abuf_level * 10 > abuf_size){
/*if((vbuf_level * 50 > vbuf_size && abuf_level * 50 > abuf_size)||
vbuf_level * 20 > vbuf_size ||
abuf_level * 20 > abuf_size){*/
if(vbuf_level * 20 > vbuf_size){
play_mode=PLAY_MODE_NORMAL;
printk("[tsync_pcr_check]Buffer to vlevel=%x vsize=%x alevel=%x asize=%x. slow to normal play\n",
vbuf_level,vbuf_size,abuf_level,abuf_size);
}
}
else if(play_mode == PLAY_MODE_FORCE_SPEED){
if((vbuf_level * 3 < vbuf_size && abuf_level * 3 < abuf_size) ||
vbuf_level * 10 < vbuf_size ||
abuf_level * 10 < abuf_size){
if((vbuf_level * 4 < vbuf_size && abuf_level * 4 < abuf_size) ||
(vbuf_level * 4 < vbuf_size && abuf_level == 0)||
(abuf_level * 4 < abuf_size && vbuf_level == 0)){
play_mode=PLAY_MODE_NORMAL;
tsync_pcr_tsdemux_startpcr = tsdemux_pcr;
tsync_pcr_system_startpcr = timestamp_pcrscr_get();
@@ -349,35 +449,75 @@ static unsigned long tsync_pcr_check(void)
tsync_pcr_debug_pcrscr=0;
}
*/
//if(need_recovery==1 || play_mode == PLAY_MODE_FORCE_SLOW || play_mode == PLAY_MODE_FORCE_SPEED){
/* To check the system time with ts demuxer pcr */
if(play_mode != PLAY_MODE_FORCE_SLOW && play_mode != PLAY_MODE_FORCE_SPEED){
u32 ref_pcr=tsdemux_pcr-tsync_pcr_ref_cache_time;
u32 cur_pcr=timestamp_pcrscr_get();
u32 diff=abs(ref_pcr - cur_pcr);
if(diff > OPEN_RECOVERY_THRESHOLD && cur_pcr<ref_pcr && play_mode!=PLAY_MODE_SPEED && need_recovery){
play_mode= PLAY_MODE_SPEED;
amlog_level(LOG_LEVEL_INFO, "[tsync_pcr_check] diff=%x to speed play \n",diff);
}
else if(diff > OPEN_RECOVERY_THRESHOLD && cur_pcr>ref_pcr && play_mode!=PLAY_MODE_SLOW && need_recovery){
if((play_mode != PLAY_MODE_FORCE_SLOW) && (play_mode != PLAY_MODE_FORCE_SPEED) && (tsync_pcr_usepcr==1)){
// use the pcr to adjust
//u32 ref_pcr=tsdemux_pcr-calculation_vcached_delayed();
int64_t ref_pcr=(int64_t)tsdemux_pcr- (int64_t)tsync_pcr_ref_latency;
int64_t cur_pcr=(int64_t)timestamp_pcrscr_get();
int64_t diff=abs(ref_pcr - cur_pcr);
//if(diff > OPEN_RECOVERY_THRESHOLD && cur_pcr<ref_pcr && play_mode!=PLAY_MODE_SPEED && need_recovery){
if(((ref_pcr -cur_pcr) > (tsync_pcr_max_cache_time)) && (play_mode!=PLAY_MODE_SPEED) && need_recovery){
play_mode=PLAY_MODE_SPEED;
amlog_level(LOG_LEVEL_INFO, "[tsync_pcr_check] diff=%lld to speed play \n",diff);
amlog_level(LOG_LEVEL_INFO, "[tsync_pcr_check] ref_pcr=%lld to speed play \n",ref_pcr);
amlog_level(LOG_LEVEL_INFO, "[tsync_pcr_check] cur_pcr=%lld to speed play \n",cur_pcr);
amlog_level(LOG_LEVEL_INFO, "[tsync_pcr_check] tsync_pcr_max_cache_time=%d to speed play \n",tsync_pcr_max_cache_time);
}
//else if(diff > OPEN_RECOVERY_THRESHOLD && cur_pcr>ref_pcr && play_mode!=PLAY_MODE_SLOW && need_recovery){
else if((ref_pcr - cur_pcr) < (tsync_pcr_min_cache_time) && (play_mode!=PLAY_MODE_SLOW) && need_recovery){
play_mode=PLAY_MODE_SLOW;
amlog_level(LOG_LEVEL_INFO, "[tsync_pcr_check] diff=%x to show play \n",diff);
}
else if(diff < CLOSE_RECOVERY_THRESHOLD && play_mode!=PLAY_MODE_NORMAL){
play_mode=PLAY_MODE_NORMAL;
amlog_level(LOG_LEVEL_INFO, "[tsync_pcr_check] diff=%x to nomal play \n",diff);
}
amlog_level(LOG_LEVEL_INFO, "[tsync_pcr_check] diff=%lld to slow play \n",diff);
amlog_level(LOG_LEVEL_INFO, "[tsync_pcr_check] ref_pcr=%lld to slow play \n",ref_pcr);
amlog_level(LOG_LEVEL_INFO, "[tsync_pcr_check] cur_pcr=%lld to slow play \n",cur_pcr);
amlog_level(LOG_LEVEL_INFO, "[tsync_pcr_check] tsync_pcr_max_cache_time=%d to slow play \n",tsync_pcr_max_cache_time);
}
//else if(diff < CLOSE_RECOVERY_THRESHOLD && play_mode!=PLAY_MODE_NORMAL){
else if((!need_recovery||((tsync_pcr_down_cache_time<ref_pcr-cur_pcr)&&(ref_pcr-cur_pcr<tsync_pcr_up_cache_time)))&&(play_mode!=PLAY_MODE_NORMAL)){
play_mode=PLAY_MODE_NORMAL;
amlog_level(LOG_LEVEL_INFO, "[tsync_pcr_check] ref_pcr=%lld to nomal play \n",ref_pcr);
amlog_level(LOG_LEVEL_INFO, "[tsync_pcr_check] cur_pcr=%lld to nomal play \n",cur_pcr);
amlog_level(LOG_LEVEL_INFO, "[tsync_pcr_check] tsync_pcr_max_cache_time=%d to nomal play \n",tsync_pcr_max_cache_time);
amlog_level(LOG_LEVEL_INFO, "[tsync_pcr_check] diff=%lld,need_recovery=%d to nomal play \n",diff,need_recovery);
}
}
else if((play_mode != PLAY_MODE_FORCE_SLOW) && (play_mode != PLAY_MODE_FORCE_SPEED) && (tsync_pcr_usepcr==0)){
// use the video cache time to adjust
int video_cache_time = calculation_vcached_delayed();
if(video_cache_time > tsync_pcr_max_delay_time){
if(play_mode!=PLAY_MODE_SPEED){
play_mode= PLAY_MODE_SPEED;
amlog_level(LOG_LEVEL_INFO, "[tsync_pcr_check] video_delay_time=%d to speed play \n",video_cache_time);
}
}
else if( video_cache_time < tsync_pcr_min_delay_time && video_cache_time>=0 ){
if(play_mode!=PLAY_MODE_SLOW){
play_mode=PLAY_MODE_SLOW;
amlog_level(LOG_LEVEL_INFO, "[tsync_pcr_check] video_delay_time=%d to show play \n",video_cache_time);
}
}
else{
if(tsync_pcr_down_delay_time<=video_cache_time&&video_cache_time<=tsync_pcr_up_delay_time&&play_mode!=PLAY_MODE_NORMAL){
play_mode=PLAY_MODE_NORMAL;
amlog_level(LOG_LEVEL_INFO, "[tsync_pcr_check] video_delay_time=%d to nomal play \n", video_cache_time);
}
}
}
if(need_recovery&&!tsync_pcr_vpause_flag){
if(play_mode == PLAY_MODE_SLOW)
timestamp_pcrscr_set(timestamp_pcrscr_get()-RECOVERY_SPAN);
else if( play_mode == PLAY_MODE_FORCE_SLOW)
timestamp_pcrscr_set(timestamp_pcrscr_get()-FORCE_RECOVERY_SPAN);
else if(play_mode == PLAY_MODE_SPEED)
timestamp_pcrscr_set(timestamp_pcrscr_get()+RECOVERY_SPAN);
else if( play_mode == PLAY_MODE_FORCE_SPEED)
timestamp_pcrscr_set(timestamp_pcrscr_get()+FORCE_RECOVERY_SPAN);
}
if(play_mode == PLAY_MODE_SLOW)
timestamp_pcrscr_set(timestamp_pcrscr_get()-RECOVERY_SPAN);
else if( play_mode == PLAY_MODE_FORCE_SLOW)
timestamp_pcrscr_set(timestamp_pcrscr_get()-FORCE_RECOVERY_SPAN);
else if(play_mode == PLAY_MODE_SPEED)
timestamp_pcrscr_set(timestamp_pcrscr_get()+RECOVERY_SPAN);
else if( play_mode == PLAY_MODE_FORCE_SPEED)
timestamp_pcrscr_set(timestamp_pcrscr_get()+FORCE_RECOVERY_SPAN);
//}
return res;
@@ -385,17 +525,73 @@ static unsigned long tsync_pcr_check(void)
static void tsync_pcr_check_timer_func(unsigned long arg)
{
if(tsdemux_pcrscr_valid() == 1){
tsync_pcr_check_timer.expires = tsync_pcr_check();
}
else{
tsync_pcr_last_tsdemuxpcr=0;
tsync_pcr_check_timer.expires = jiffies;
}
tsync_pcr_check();
tsync_pcr_check_timer.expires = jiffies+TEN_MS_INTERVAL;
add_timer(&tsync_pcr_check_timer);
}
static void tsync_pcr_param_reset(void){
tsync_pcr_system_startpcr=0;
tsync_pcr_tsdemux_startpcr=0;
tsync_pcr_vpause_flag = 0;
tsync_pcr_apause_flag = 0;
tsync_pcr_vstart_flag = 0;
tsync_pcr_astart_flag = 0;
tsync_pcr_inited_flag = 0;
tsync_pcr_last_tsdemuxpcr = 0;
tsync_pcr_discontinue_local_point=0;
tsync_pcr_discontinue_point = 0;
tsync_pcr_discontinue_waited = 0; // the time waited the v-discontinue to happen
tsync_pcr_tsdemuxpcr_discontinue = 0; // the boolean value
abuf_level=0;
abuf_size=0;
vbuf_level=0;
vbuf_size=0;
play_mode=PLAY_MODE_NORMAL;
tsync_pcr_started=0;
}
int tsync_pcr_set_apts(unsigned pts)
{
timestamp_apts_set(pts);
//printk("[tsync_pcr_set_apts]set apts=%x",pts);
return 0;
}
int tsync_pcr_start(void)
{
tsync_pcr_param_reset();
if(tsync_get_mode() == TSYNC_MODE_PCRMASTER){
printk("[tsync_pcr_start]PCRMASTER started success. \n");
init_timer(&tsync_pcr_check_timer);
tsync_pcr_check_timer.function = tsync_pcr_check_timer_func;
tsync_pcr_check_timer.expires = jiffies;
tsync_pcr_started=1;
tsync_pcr_usepcr=tsdemux_pcrscr_valid();
tsync_pcr_read_cnt=0;
printk("[tsync_pcr_start]usepcr=%d\n",tsync_pcr_usepcr);
add_timer(&tsync_pcr_check_timer);
}
return 0;
}
void tsync_pcr_stop(void)
{
if(tsync_pcr_started==1){
del_timer_sync(&tsync_pcr_check_timer);
printk("[tsync_pcr_start]PCRMASTER stop success. \n");
}
tsync_pcr_started=0;
}
// --------------------------------------------------------------------------------
// define of tsync pcr class node
static ssize_t show_play_mode(struct class *class,
struct class_attribute *attr,
char *buf)
@@ -403,12 +599,59 @@ static ssize_t show_play_mode(struct class *class,
return sprintf(buf, "%d\n", play_mode);
}
static ssize_t show_tsync_pcr_dispoint(struct class *class,
struct class_attribute *attr,
char *buf)
{
printk("[%s:%d] tsync_pcr_discontinue_point:%x, HZ:%x, \n", __FUNCTION__, __LINE__, tsync_pcr_discontinue_point, HZ);
return sprintf(buf, "0x%x\n", tsync_pcr_discontinue_point);
}
static ssize_t store_tsync_pcr_dispoint(struct class *class,
struct class_attribute *attr,
const char *buf,
size_t size)
{
unsigned pts;
ssize_t r;
r = sscanf(buf, "0x%x", &pts);
if (r != 1) {
return -EINVAL;
}
tsync_pcr_discontinue_point = pts;
printk("[%s:%d] tsync_pcr_discontinue_point:%x, \n", __FUNCTION__, __LINE__, tsync_pcr_discontinue_point);
return size;
}
static ssize_t store_tsync_pcr_audio_resample_type(struct class *class,
struct class_attribute *attr,
const char *buf,
size_t size)
{
unsigned type;
ssize_t r;
r = sscanf(buf, "%d", &type);
if (r != 1) {
return -EINVAL;
}
if(type==RESAMPLE_DOWN_FORCE_PCR_SLOW){
play_mode=PLAY_MODE_SLOW;
printk("[%s:%d] Audio to FORCE_PCR_SLOW\n", __FUNCTION__, __LINE__);
}
return size;
}
// --------------------------------------------------------------------------------
// define of tsync pcr module
static struct class_attribute tsync_pcr_class_attrs[] = {
__ATTR(play_mode, S_IRUGO | S_IWUSR | S_IWGRP, show_play_mode, NULL),
__ATTR(tsync_pcr_discontinue_point, S_IRUGO | S_IWUSR, show_tsync_pcr_dispoint, store_tsync_pcr_dispoint),
__ATTR(audio_resample_type, S_IRUGO | S_IWUSR, NULL, store_tsync_pcr_audio_resample_type),
__ATTR_NULL
};
static struct class tsync_pcr_class = {
@@ -432,21 +675,12 @@ static int __init tsync_pcr_init(void)
timestamp_vpts_set(0);
timestamp_pcrscr_set(0);
init_timer(&tsync_pcr_check_timer);
tsync_pcr_check_timer.function = tsync_pcr_check_timer_func;
tsync_pcr_check_timer.expires = jiffies;
add_timer(&tsync_pcr_check_timer);
printk("[tsync_pcr_init]init success. \n");
return (0);
}
static void __exit tsync_pcr_exit(void)
{
del_timer_sync(&tsync_pcr_check_timer);
class_unregister(&tsync_pcr_class);
printk("[tsync_pcr_exit]exit success. \n");
}

View File

@@ -3,6 +3,11 @@
extern void tsync_pcr_avevent_locked(avevent_t event, u32 param);
extern int tsync_pcr_start(void);
extern void tsync_pcr_stop(void);
extern int tsync_pcr_set_apts(unsigned pts);
#endif

View File

@@ -591,6 +591,10 @@ static u32 force_blackout = 0;
/* disable video */
static u32 disable_video = VIDEO_DISABLE_NONE;
/* show first frame*/
static bool show_first_frame_nosync=true;
//static bool first_frame=false;
/* test screen*/
static u32 test_screen = 0;
@@ -2214,6 +2218,8 @@ static irqreturn_t vsync_isr(int irq, void *dev_id)
vdin_v4l2_ops_t *vdin_ops = NULL;
vdin_arg_t arg;
#endif
bool show_nosync=false;
#ifdef CONFIG_AM_VIDEO_LOG
int toggle_cnt;
#endif
@@ -2423,10 +2429,14 @@ static irqreturn_t vsync_isr(int irq, void *dev_id)
tsync_avevent_locked(VIDEO_START,
(vf->pts) ? vf->pts : timestamp_vpts_get());
#ifdef SLOW_SYNC_REPEAT
frame_repeat_count = 0;
#endif
if(show_first_frame_nosync)
show_nosync=true;
} else if ((cur_dispbuf == &vf_local) && (video_property_changed)) {
if (!(blackout|force_blackout)) {
if((READ_VCBUS_REG(DI_IF1_GEN_REG)&0x1)==0)
@@ -2457,7 +2467,7 @@ static irqreturn_t vsync_isr(int irq, void *dev_id)
}
while (vf) {
if (vpts_expire(cur_dispbuf, vf)) {
if (vpts_expire(cur_dispbuf, vf)||show_nosync) {
amlog_mask(LOG_MASK_TIMESTAMP,
"VIDEO_PTS = 0x%x, cur_dur=0x%x, next_pts=0x%x, scr = 0x%x\n",
timestamp_vpts_get(),
@@ -4873,6 +4883,30 @@ static ssize_t video_angle_store(struct class *cla, struct class_attribute *attr
return strnlen(buf, count);
}
static ssize_t show_first_frame_nosync_show(struct class *cla, struct class_attribute *attr, char *buf)
{
return sprintf(buf, "%d\n", show_first_frame_nosync?1:0);
}
static ssize_t show_first_frame_nosync_store(struct class *cla, struct class_attribute *attr, const char *buf,
size_t count)
{
size_t r;
int value;
r = sscanf(buf, "%d", &value);
if (r != 1) {
return -EINVAL;
}
if(value==0)
show_first_frame_nosync=false;
else
show_first_frame_nosync=true;
return count;
}
static struct class_attribute amvideo_class_attrs[] = {
__ATTR(axis,
S_IRUGO | S_IWUSR | S_IWGRP,
@@ -4973,6 +5007,10 @@ static struct class_attribute amvideo_class_attrs[] = {
__ATTR(stereo_scaler,
S_IRUGO|S_IWUSR,NULL,
video_3d_scale_store),
__ATTR(show_first_frame_nosync,
S_IRUGO | S_IWUSR,
show_first_frame_nosync_show,
show_first_frame_nosync_store),
__ATTR_RO(device_resolution),
__ATTR_RO(frame_addr),
__ATTR_RO(frame_canvas_width),

View File

@@ -1406,6 +1406,7 @@ static int dmx_enable(struct aml_dmx *dmx)
(1<<VIDEO_PACKET) |
(1<<AUDIO_PACKET) |
(1<<SUB_PACKET) |
(1<<SCR_ONLY_PACKET) |
(1<<OTHER_PES_PACKET));
DMX_WRITE_REG(dmx->id, PES_STRONG_SYNC, 0x1234);
DMX_WRITE_REG(dmx->id, DEMUX_ENDIAN,
@@ -1483,6 +1484,9 @@ static u32 dmx_get_chan_target(struct aml_dmx *dmx, int cid)
case DMX_PES_TELETEXT:
type = SUB_PACKET;
break;
case DMX_PES_PCR:
type=SCR_ONLY_PACKET;
break;
default:
type = OTHER_PES_PACKET;
break;

View File

@@ -556,8 +556,19 @@ static ssize_t tso_store_source(struct class *class,struct class_attribute *attr
return size;
}
/*Show PCR*/
#define DEMUX_PCR_FUNC_DECL(i) \
static ssize_t demux##i##_show_pcr(struct class *class, struct class_attribute *attr,char *buf)\
{\
int f = 0;\
if(i == 0)\
f = READ_MPEG_REG(PCR_DEMUX);\
else if(i==1)\
f = READ_MPEG_REG(PCR_DEMUX_2);\
else if(i==2)\
f = READ_MPEG_REG(PCR_DEMUX_3);\
return sprintf(buf, "%08x\n", f);\
}
/*Show the STB input source*/
#define DEMUX_SOURCE_FUNC_DECL(i) \
@@ -736,6 +747,7 @@ static ssize_t dvr##i##_store_mode(struct class *class, struct class_attribute
}
#if DMX_DEV_COUNT>0
DEMUX_PCR_FUNC_DECL(0)
DEMUX_SOURCE_FUNC_DECL(0)
DEMUX_FREE_FILTERS_FUNC_DECL(0)
DEMUX_FILTER_USERS_FUNC_DECL(0)
@@ -744,6 +756,7 @@ static ssize_t dvr##i##_store_mode(struct class *class, struct class_attribute
DEMUX_CHANNEL_ACTIVITY_FUNC_DECL(0)
#endif
#if DMX_DEV_COUNT>1
DEMUX_PCR_FUNC_DECL(1)
DEMUX_SOURCE_FUNC_DECL(1)
DEMUX_FREE_FILTERS_FUNC_DECL(1)
DEMUX_FILTER_USERS_FUNC_DECL(1)
@@ -752,6 +765,7 @@ static ssize_t dvr##i##_store_mode(struct class *class, struct class_attribute
DEMUX_CHANNEL_ACTIVITY_FUNC_DECL(1)
#endif
#if DMX_DEV_COUNT>2
DEMUX_PCR_FUNC_DECL(2)
DEMUX_SOURCE_FUNC_DECL(2)
DEMUX_FREE_FILTERS_FUNC_DECL(2)
DEMUX_FILTER_USERS_FUNC_DECL(2)
@@ -1044,6 +1058,8 @@ static struct class_attribute aml_stb_class_attrs[] = {
__ATTR(source, S_IRUGO | S_IWUSR | S_IWGRP, stb_show_source, stb_store_source),
__ATTR(dsc_source, S_IRUGO | S_IWUSR, dsc_show_source, dsc_store_source),
__ATTR(tso_source, S_IRUGO | S_IWUSR, tso_show_source, tso_store_source),
#define DEMUX_SOURCE_ATTR_PCR(i)\
__ATTR(demux##i##_pcr, S_IRUGO | S_IWUSR, demux##i##_show_pcr, NULL)
#define DEMUX_SOURCE_ATTR_DECL(i)\
__ATTR(demux##i##_source, S_IRUGO | S_IWUSR | S_IWGRP, demux##i##_show_source, demux##i##_store_source)
#define DEMUX_FREE_FILTERS_ATTR_DECL(i)\
@@ -1057,6 +1073,7 @@ static struct class_attribute aml_stb_class_attrs[] = {
#define DEMUX_CHANNEL_ACTIVITY_ATTR_DECL(i)\
__ATTR(demux##i##_channel_activity, S_IRUGO | S_IWUSR, demux##i##_show_channel_activity, NULL)
#if DMX_DEV_COUNT>0
DEMUX_SOURCE_ATTR_PCR(0),
DEMUX_SOURCE_ATTR_DECL(0),
DEMUX_FREE_FILTERS_ATTR_DECL(0),
DEMUX_FILTER_USERS_ATTR_DECL(0),
@@ -1065,6 +1082,7 @@ static struct class_attribute aml_stb_class_attrs[] = {
DEMUX_CHANNEL_ACTIVITY_ATTR_DECL(0),
#endif
#if DMX_DEV_COUNT>1
DEMUX_SOURCE_ATTR_PCR(1),
DEMUX_SOURCE_ATTR_DECL(1),
DEMUX_FREE_FILTERS_ATTR_DECL(1),
DEMUX_FILTER_USERS_ATTR_DECL(1),
@@ -1073,6 +1091,7 @@ static struct class_attribute aml_stb_class_attrs[] = {
DEMUX_CHANNEL_ACTIVITY_ATTR_DECL(1),
#endif
#if DMX_DEV_COUNT>2
DEMUX_SOURCE_ATTR_PCR(2),
DEMUX_SOURCE_ATTR_DECL(2),
DEMUX_FREE_FILTERS_ATTR_DECL(2),
DEMUX_FILTER_USERS_ATTR_DECL(2),

View File

@@ -74,4 +74,5 @@ extern int calculation_stream_delayed_ms(u8 type,u32 *latestbirate,u32*avg_bitar
extern int calculation_vcached_delayed(void);
extern int calculation_acached_delayed(void);
#endif /* PTSSERV_H */

View File

@@ -65,6 +65,8 @@ extern void tsync_set_dec_reset(void);
extern void tsync_set_enable(int enable);
extern int tsync_get_mode(void);
extern int tsync_get_sync_adiscont(void);
extern int tsync_get_sync_vdiscont(void);