media: fixed the issure of mpeg12 playback.

PD#156734:

Change-Id: I87d814707d864a8fc81bcb35712ef0c25fea65db
Signed-off-by: Nanxin Qin <nanxin.qin@amlogic.com>
This commit is contained in:
Nanxin Qin
2018-02-04 16:55:25 +08:00
committed by Yixun Lan
parent 3faa59e06e
commit f6cd1db849
3 changed files with 263 additions and 3 deletions

View File

@@ -966,6 +966,151 @@ static int pts_lookup_offset_inline_locked(u8 type, u32 offset, u32 *val,
return -1;
}
static int pts_pick_by_offset_inline_locked(u8 type, u32 offset, u32 *val,
u32 pts_margin, u64 *uS64)
{
struct pts_table_s *pTable;
int lookup_threshold;
int look_cnt = 0;
if (type >= PTS_TYPE_MAX)
return -EINVAL;
pTable = &pts_table[type];
if (pts_margin == 0)
lookup_threshold = pTable->lookup_threshold;
else
lookup_threshold = pts_margin;
if (!pTable->first_lookup_ok)
lookup_threshold <<= 1;
if (likely(pTable->status == PTS_RUNNING)) {
struct pts_rec_s *p = NULL;
struct pts_rec_s *p2 = NULL;
if ((pTable->lookup_cache_valid) &&
(offset == pTable->lookup_cache_offset)) {
*val = pTable->lookup_cache_pts;
return 0;
}
if ((type == PTS_TYPE_VIDEO)
&& !list_empty(&pTable->valid_list)) {
struct pts_rec_s *rec = NULL;
struct pts_rec_s *next = NULL;
int look_cnt1 = 0;
list_for_each_entry_safe(rec,
next, &pTable->valid_list, list) {
if (OFFSET_DIFF(offset, rec->offset) >
PTS_VALID_OFFSET_TO_CHECK) {
if (pTable->pts_search == &rec->list)
pTable->pts_search =
rec->list.next;
if (tsync_get_debug_vpts()) {
pr_info("remove node offset: 0x%x cnt:%d\n",
rec->offset, look_cnt1);
}
list_move_tail(&rec->list,
&pTable->free_list);
look_cnt1++;
} else {
break;
}
}
}
if (list_empty(&pTable->valid_list))
return -1;
if (pTable->pts_search == &pTable->valid_list) {
p = list_entry(pTable->valid_list.next,
struct pts_rec_s, list);
} else {
p = list_entry(pTable->pts_search, struct pts_rec_s,
list);
}
if (OFFSET_LATER(offset, p->offset)) {
p2 = p; /* lookup candidate */
list_for_each_entry_continue(p, &pTable->valid_list,
list) {
#if 0
if (type == PTS_TYPE_VIDEO)
pr_info(" >> rec: 0x%x\n", p->offset);
#endif
look_cnt++;
if (OFFSET_LATER(p->offset, offset))
break;
p2 = p;
}
} else if (OFFSET_LATER(p->offset, offset)) {
list_for_each_entry_continue_reverse(p,
&pTable->
valid_list, list) {
#if 0
if (type == PTS_TYPE_VIDEO)
pr_info(" >> rec: 0x%x\n", p->offset);
#endif
#ifdef DEBUG
look_cnt++;
#endif
if (OFFSET_EQLATER(offset, p->offset)) {
p2 = p;
break;
}
}
} else
p2 = p;
if ((p2) &&
(OFFSET_DIFF(offset, p2->offset) < lookup_threshold)) {
if (tsync_get_debug_pts_checkout()) {
if (tsync_get_debug_vpts()
&& (type == PTS_TYPE_VIDEO)) {
pr_info
("vpts look up offset<0x%x> -->",
offset);
pr_info
("<0x%x:0x%x>, look_cnt = %d\n",
p2->offset, p2->val, look_cnt);
}
if (tsync_get_debug_apts()
&& (type == PTS_TYPE_AUDIO)) {
pr_info
("apts look up offset<0x%x> -->",
offset);
pr_info
("<0x%x:0x%x>, look_cnt = %d\n",
p2->offset, p2->val, look_cnt);
}
}
*val = p2->val;
*uS64 = p2->pts_uS64;
return 0;
}
}
return -1;
}
static int pts_lookup_offset_inline(u8 type, u32 offset, u32 *val,
u32 pts_margin, u64 *uS64)
{
@@ -996,6 +1141,22 @@ static int pts_lookup_offset_inline(u8 type, u32 offset, u32 *val,
return res;
}
static int pts_pick_by_offset_inline(u8 type, u32 offset, u32 *val,
u32 pts_margin, u64 *uS64)
{
unsigned long flags;
int res;
spin_lock_irqsave(&lock, flags);
res = pts_pick_by_offset_inline_locked(
type, offset, val, pts_margin, uS64);
spin_unlock_irqrestore(&lock, flags);
return res;
}
int pts_lookup_offset(u8 type, u32 offset, u32 *val, u32 pts_margin)
{
u64 pts_us;
@@ -1011,6 +1172,14 @@ int pts_lookup_offset_us64(u8 type, u32 offset, u32 *val, u32 pts_margin,
}
EXPORT_SYMBOL(pts_lookup_offset_us64);
int pts_pickout_offset_us64(u8 type, u32 offset, u32 *val, u32 pts_margin,
u64 *uS64)
{
return pts_pick_by_offset_inline(type, offset, val, pts_margin, uS64);
}
EXPORT_SYMBOL(pts_pickout_offset_us64);
int pts_set_resolution(u8 type, u32 level)
{
if (type >= PTS_TYPE_MAX)

View File

@@ -50,6 +50,10 @@ extern int pts_lookup_offset(u8 type, u32 offset, u32 *val, u32 pts_margin);
extern int pts_lookup_offset_us64(u8 type, u32 offset, u32 *val,
u32 pts_margin, u64 *uS64);
extern int pts_pickout_offset_us64(u8 type, u32 offset,
u32 *val, u32 pts_margin,
u64 *uS64);
extern int pts_set_resolution(u8 type, u32 level);
extern int pts_set_rec_size(u8 type, u32 val);

View File

@@ -120,10 +120,20 @@
#define AMSTREAM_IOC_UD_LENGTH _IOR((_A_M), 0x54, int)
#define AMSTREAM_IOC_UD_POC _IOR((_A_M), 0x55, int)
#define AMSTREAM_IOC_UD_FLUSH_USERDATA _IOR((_A_M), 0x56, int)
#define AMSTREAM_IOC_UD_BUF_READ _IOR((_A_M), 0x57, struct userdata_param_t)
#define AMSTREAM_IOC_GET_SCREEN_MODE _IOR((_A_M), 0x58, int)
#define AMSTREAM_IOC_SET_SCREEN_MODE _IOW((_A_M), 0x59, int)
#define AMSTREAM_IOC_GET_VIDEO_DISCONTINUE_REPORT _IOR((_A_M), 0x5a, int)
#define AMSTREAM_IOC_SET_VIDEO_DISCONTINUE_REPORT _IOW((_A_M), 0x5b, int)
/*
* #define AMSTREAM_IOC_UD_BUF_STATUS _IOR((_A_M),
* 0x5c, struct userdata_buf_state_t)
*/
#define AMSTREAM_IOC_VF_STATUS _IOR((_A_M), 0x60, int)
#define AMSTREAM_IOC_CLEAR_VBUF _IO((_A_M), 0x80)
@@ -138,6 +148,8 @@
#define AMSTREAM_IOC_SET_VSYNC_UPINT _IOW((_A_M), 0x89, int)
#define AMSTREAM_IOC_GET_VSYNC_SLOW_FACTOR _IOW((_A_M), 0x8a, int)
#define AMSTREAM_IOC_SET_VSYNC_SLOW_FACTOR _IOW((_A_M), 0x8b, int)
#define AMSTREAM_IOC_GET_FIRST_FRAME_LATENCY _IOR((_A_M), 0x8c, int)
#define AMSTREAM_IOC_CLEAR_FIRST_FRAME_LATENCY _IOR((_A_M), 0x8d, int)
#define AMSTREAM_IOC_SET_DEMUX _IOW((_A_M), 0x90, int)
#define AMSTREAM_IOC_SET_DRMMODE _IOW((_A_M), 0x91, int)
#define AMSTREAM_IOC_TSTAMP_uS64 _IOW((_A_M), 0x95, int)
@@ -380,12 +392,87 @@ struct codec_profile_t {
struct userdata_poc_info_t {
unsigned int poc_info;
unsigned int poc_number;
/*
* bit 0:
* 1, group start
* 0, not group start
* bit 1-2:
* 0, extension_and_user_data( 0 )
* 1, extension_and_user_data( 1 )
* 2, extension_and_user_data( 2 )
*/
unsigned int flags;
unsigned int vpts;
unsigned int vpts_valid;
unsigned int duration;
};
/*
******************************************************************
struct userdata_meta_info_t {
uint32_t poc_number;
/************ flags bit defination ***********/
/*
* bit 0: //used for mpeg2
* 1, group start
* 0, not group start
* bit 1-2: //used for mpeg2
* 0, extension_and_user_data( 0 )
* 1, extension_and_user_data( 1 )
* 2, extension_and_user_data( 2 )
* bit 3-6: //video format
* 0, VFORMAT_MPEG12
* 1, VFORMAT_MPEG4
* 2, VFORMAT_H264
* 3, VFORMAT_MJPEG
* 4, VFORMAT_REAL
* 5, VFORMAT_JPEG
* 6, VFORMAT_VC1
* 7, VFORMAT_AVS
* 8, VFORMAT_SW
* 9, VFORMAT_H264MVC
* 10, VFORMAT_H264_4K2K
* 11, VFORMAT_HEVC
* 12, VFORMAT_H264_ENC
* 13, VFORMAT_JPEG_ENC
* 14, VFORMAT_VP9
* bit 7-9: //frame type
* 0, Unknown Frame Type
* 1, I Frame
* 2, B Frame
* 3, P Frame
* 4, D_Type_MPEG2
* bit 10: //top_field_first_flag valid
* 0: top_field_first_flag is not valid
* 1: top_field_first_flag is valid
* bit 11: //top_field_first bit val
*/
uint32_t flags;
uint32_t vpts; /*video frame pts*/
/*
* 0: pts is invalid, please use duration to calcuate
* 1: pts is valid
*/
uint32_t vpts_valid;
/*duration for frame*/
uint32_t duration;
/* how many records left in queue waiting to be read*/
uint32_t records_in_que;
unsigned long long priv_data;
uint32_t padding_data[4];
};
struct userdata_param_t {
uint32_t version;
uint32_t instance_id; /*input, 0~9*/
uint32_t buf_len; /*input*/
uint32_t data_size; /*output*/
unsigned long long pbuf_addr; /*input*/
struct userdata_meta_info_t meta_info; /*output*/
};
/*******************************************************************
* 0x100~~0x1FF : set cmd
* 0x200~~0x2FF : set ex cmd
* 0x300~~0x3FF : set ptr cmd