mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-07 19:30:30 +09:00
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:
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user