Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
qq_25606643
ijkplayer
提交
cd58dd6b
I
ijkplayer
项目概览
qq_25606643
/
ijkplayer
与 Fork 源项目一致
从无法访问的项目Fork
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
I
ijkplayer
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
cd58dd6b
编写于
3月 02, 2017
作者:
R
raymondzheng
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
ijkplayer: support accurate seek
上级
f80a1d07
变更
6
隐藏空白更改
内联
并排
Showing
6 changed file
with
165 addition
and
1 deletion
+165
-1
ijkmedia/ijkplayer/android/ijkplayer_android_def.h
ijkmedia/ijkplayer/android/ijkplayer_android_def.h
+2
-0
ijkmedia/ijkplayer/android/ijkplayer_jni.c
ijkmedia/ijkplayer/android/ijkplayer_jni.c
+4
-0
ijkmedia/ijkplayer/ff_ffmsg.h
ijkmedia/ijkplayer/ff_ffmsg.h
+1
-0
ijkmedia/ijkplayer/ff_ffplay.c
ijkmedia/ijkplayer/ff_ffplay.c
+142
-0
ijkmedia/ijkplayer/ff_ffplay_def.h
ijkmedia/ijkplayer/ff_ffplay_def.h
+12
-0
ijkmedia/ijkplayer/ff_ffplay_options.h
ijkmedia/ijkplayer/ff_ffplay_options.h
+4
-1
未找到文件。
ijkmedia/ijkplayer/android/ijkplayer_android_def.h
浏览文件 @
cd58dd6b
...
...
@@ -133,6 +133,8 @@ enum media_info_type {
//100xx
MEDIA_INFO_VIDEO_ROTATION_CHANGED
=
10001
,
MEDIA_INFO_AUDIO_RENDERING_START
=
10002
,
MEDIA_INFO_MEDIA_ACCURATE_SEEK_COMPLETE
=
10100
,
};
typedef
struct
ijkmp_mediacodecinfo_context
...
...
ijkmedia/ijkplayer/android/ijkplayer_jni.c
浏览文件 @
cd58dd6b
...
...
@@ -965,6 +965,10 @@ static void message_loop_n(JNIEnv *env, IjkMediaPlayer *mp)
MPTRACE
(
"FFP_MSG_SEEK_COMPLETE:
\n
"
);
post_event
(
env
,
weak_thiz
,
MEDIA_SEEK_COMPLETE
,
0
,
0
);
break
;
case
FFP_MSG_ACCURATE_SEEK_COMPLETE
:
MPTRACE
(
"FFP_MSG_ACCURATE_SEEK_COMPLETE:
\n
"
);
post_event
(
env
,
weak_thiz
,
MEDIA_INFO
,
MEDIA_INFO_MEDIA_ACCURATE_SEEK_COMPLETE
,
msg
.
arg1
);
break
;
case
FFP_MSG_PLAYBACK_STATE_CHANGED
:
break
;
case
FFP_MSG_TIMED_TEXT
:
...
...
ijkmedia/ijkplayer/ff_ffmsg.h
浏览文件 @
cd58dd6b
...
...
@@ -42,6 +42,7 @@
#define FFP_MSG_SEEK_COMPLETE 600
/* arg1 = seek position, arg2 = error */
#define FFP_MSG_PLAYBACK_STATE_CHANGED 700
#define FFP_MSG_TIMED_TEXT 800
#define FFP_MSG_ACCURATE_SEEK_COMPLETE 900
/* arg1 = current position*/
#define FFP_MSG_VIDEO_DECODER_OPEN 10001
...
...
ijkmedia/ijkplayer/ff_ffplay.c
浏览文件 @
cd58dd6b
...
...
@@ -806,7 +806,10 @@ static void stream_close(FFPlayer *ffp)
frame_queue_destory
(
&
is
->
pictq
);
frame_queue_destory
(
&
is
->
sampq
);
frame_queue_destory
(
&
is
->
subpq
);
SDL_DestroyCond
(
is
->
audio_accurate_seek_cond
);
SDL_DestroyCond
(
is
->
video_accurate_seek_cond
);
SDL_DestroyCond
(
is
->
continue_read_thread
);
SDL_DestroyMutex
(
is
->
accurate_seek_mutex
);
SDL_DestroyMutex
(
is
->
play_mutex
);
#if !CONFIG_AVFILTER
sws_freeContext
(
is
->
img_convert_ctx
);
...
...
@@ -1268,6 +1271,59 @@ static int queue_picture(FFPlayer *ffp, AVFrame *src_frame, double pts, double d
{
VideoState
*
is
=
ffp
->
is
;
Frame
*
vp
;
int
video_accurate_seek_fail
=
0
;
int64_t
video_seek_pos
=
0
;
if
(
ffp
->
enable_accurate_seek
&&
is
->
video_accurate_seek_req
&&
!
is
->
seek_req
)
{
if
(
!
isnan
(
pts
))
{
video_seek_pos
=
is
->
seek_pos
;
if
(
pts
*
1000
*
1000
<
is
->
seek_pos
)
{
if
(
is
->
drop_vframe_count
==
0
)
{
av_log
(
NULL
,
AV_LOG_INFO
,
"video accurate_seek start, is->seek_pos=%lld, pts=%lf
\n
"
,
is
->
seek_pos
,
pts
);
}
is
->
drop_vframe_count
++
;
if
(
is
->
drop_vframe_count
<
MAX_KEY_FRAME_INTERVAL
)
{
return
1
;
// drop some old frame when do accurate seek
}
else
{
av_log
(
NULL
,
AV_LOG_WARNING
,
"video accurate_seek is error, is->drop_vframe_count=%d
\n
"
,
is
->
drop_vframe_count
);
video_accurate_seek_fail
=
1
;
// if KEY_FRAME interval too big, disable accurate seek
}
}
else
{
av_log
(
NULL
,
AV_LOG_INFO
,
"video accurate_seek is ok, is->drop_vframe_count =%d, is->seek_pos=%lld, pts=%lf
\n
"
,
is
->
drop_vframe_count
,
is
->
seek_pos
,
pts
);
if
(
video_seek_pos
==
is
->
seek_pos
)
{
is
->
drop_vframe_count
=
0
;
SDL_LockMutex
(
is
->
accurate_seek_mutex
);
is
->
video_accurate_seek_req
=
0
;
SDL_CondSignal
(
is
->
audio_accurate_seek_cond
);
if
(
video_seek_pos
==
is
->
seek_pos
&&
is
->
audio_accurate_seek_req
&&
!
is
->
abort_request
)
SDL_CondWait
(
is
->
video_accurate_seek_cond
,
is
->
accurate_seek_mutex
);
ffp_notify_msg2
(
ffp
,
FFP_MSG_ACCURATE_SEEK_COMPLETE
,
(
int
)(
pts
*
1000
));
if
(
video_seek_pos
!=
is
->
seek_pos
&&
!
is
->
abort_request
)
{
is
->
video_accurate_seek_req
=
1
;
SDL_UnlockMutex
(
is
->
accurate_seek_mutex
);
return
1
;
}
SDL_UnlockMutex
(
is
->
accurate_seek_mutex
);
}
}
}
else
{
video_accurate_seek_fail
=
1
;
}
if
(
video_accurate_seek_fail
)
{
if
(
!
isnan
(
pts
))
{
ffp_notify_msg2
(
ffp
,
FFP_MSG_ACCURATE_SEEK_COMPLETE
,
(
int
)(
pts
*
1000
));
}
ffp
->
enable_accurate_seek
=
0
;
is
->
drop_vframe_count
=
0
;
SDL_LockMutex
(
is
->
accurate_seek_mutex
);
is
->
video_accurate_seek_req
=
0
;
SDL_CondSignal
(
is
->
audio_accurate_seek_cond
);
SDL_UnlockMutex
(
is
->
accurate_seek_mutex
);
}
}
#if defined(DEBUG_SYNC)
printf
(
"frame_type=%c pts=%0.3f
\n
"
,
...
...
@@ -1642,6 +1698,8 @@ static int audio_thread(void *arg)
int
got_frame
=
0
;
AVRational
tb
;
int
ret
=
0
;
int
audio_accurate_seek_fail
=
0
;
int64_t
audio_seek_pos
=
0
;
if
(
!
frame
)
return
AVERROR
(
ENOMEM
);
...
...
@@ -1653,6 +1711,58 @@ static int audio_thread(void *arg)
if
(
got_frame
)
{
tb
=
(
AVRational
){
1
,
frame
->
sample_rate
};
if
(
ffp
->
enable_accurate_seek
&&
is
->
audio_accurate_seek_req
&&
!
is
->
seek_req
)
{
double
frame_pts
=
(
frame
->
pts
==
AV_NOPTS_VALUE
)
?
NAN
:
frame
->
pts
*
av_q2d
(
tb
);
double
audio_clock
=
0
;
if
(
!
isnan
(
frame_pts
))
{
double
samples_duration
=
(
double
)
frame
->
nb_samples
/
frame
->
sample_rate
;
audio_clock
=
frame_pts
+
samples_duration
;
audio_seek_pos
=
is
->
seek_pos
;
if
(
audio_clock
*
1000
*
1000
<
is
->
seek_pos
)
{
if
(
is
->
drop_aframe_count
==
0
)
{
av_log
(
NULL
,
AV_LOG_INFO
,
"audio accurate_seek start, is->seek_pos=%lld, audio_clock=%lf
\n
"
,
is
->
seek_pos
,
audio_clock
);
}
is
->
drop_aframe_count
++
;
if
(
is
->
drop_aframe_count
<
MAX_KEY_FRAME_INTERVAL
)
{
continue
;
// drop some old frame when do accurate seek
}
else
{
av_log
(
NULL
,
AV_LOG_INFO
,
"audio accurate_seek is error, is->drop_aframe_count=%d
\n
"
,
is
->
drop_aframe_count
);
audio_accurate_seek_fail
=
1
;
}
}
else
{
if
(
audio_seek_pos
==
is
->
seek_pos
)
{
av_log
(
NULL
,
AV_LOG_INFO
,
"audio accurate_seek is ok, is->drop_aframe_count=%d
\n
"
,
is
->
drop_aframe_count
);
is
->
drop_aframe_count
=
0
;
SDL_LockMutex
(
is
->
accurate_seek_mutex
);
is
->
audio_accurate_seek_req
=
0
;
SDL_CondSignal
(
is
->
video_accurate_seek_cond
);
if
(
audio_seek_pos
==
is
->
seek_pos
&&
is
->
video_accurate_seek_req
&&
!
is
->
abort_request
)
SDL_CondWait
(
is
->
audio_accurate_seek_cond
,
is
->
accurate_seek_mutex
);
if
(
audio_seek_pos
!=
is
->
seek_pos
&&
!
is
->
abort_request
)
{
is
->
audio_accurate_seek_req
=
1
;
SDL_UnlockMutex
(
is
->
accurate_seek_mutex
);
continue
;
}
SDL_UnlockMutex
(
is
->
accurate_seek_mutex
);
}
}
}
else
{
audio_accurate_seek_fail
=
1
;
}
if
(
audio_accurate_seek_fail
)
{
if
(
!
isnan
(
frame_pts
))
{
ffp_notify_msg2
(
ffp
,
FFP_MSG_ACCURATE_SEEK_COMPLETE
,
(
int
)(
audio_clock
*
1000
));
}
ffp
->
enable_accurate_seek
=
0
;
is
->
drop_aframe_count
=
0
;
SDL_LockMutex
(
is
->
accurate_seek_mutex
);
is
->
audio_accurate_seek_req
=
0
;
SDL_CondSignal
(
is
->
video_accurate_seek_cond
);
SDL_UnlockMutex
(
is
->
accurate_seek_mutex
);
}
}
#if CONFIG_AVFILTER
dec_channel_layout
=
get_valid_channel_layout
(
frame
->
channel_layout
,
av_frame_get_channels
(
frame
));
...
...
@@ -2837,6 +2947,18 @@ static int read_thread(void *arg)
if
(
is
->
pause_req
)
step_to_next_frame_l
(
ffp
);
SDL_UnlockMutex
(
ffp
->
is
->
play_mutex
);
if
(
ffp
->
enable_accurate_seek
)
{
is
->
drop_aframe_count
=
0
;
is
->
drop_vframe_count
=
0
;
SDL_LockMutex
(
is
->
accurate_seek_mutex
);
is
->
audio_accurate_seek_req
=
1
;
is
->
video_accurate_seek_req
=
1
;
SDL_CondSignal
(
is
->
audio_accurate_seek_cond
);
SDL_CondSignal
(
is
->
video_accurate_seek_cond
);
SDL_UnlockMutex
(
is
->
accurate_seek_mutex
);
}
ffp_notify_msg3
(
ffp
,
FFP_MSG_SEEK_COMPLETE
,
(
int
)
fftime_to_milliseconds
(
seek_target
),
ret
);
ffp_toggle_buffering
(
ffp
,
1
);
}
...
...
@@ -3054,6 +3176,16 @@ static VideoState *stream_open(FFPlayer *ffp, const char *filename, AVInputForma
goto
fail
;
}
if
(
!
(
is
->
video_accurate_seek_cond
=
SDL_CreateCond
()))
{
av_log
(
NULL
,
AV_LOG_FATAL
,
"SDL_CreateCond(): %s
\n
"
,
SDL_GetError
());
ffp
->
enable_accurate_seek
=
0
;
}
if
(
!
(
is
->
audio_accurate_seek_cond
=
SDL_CreateCond
()))
{
av_log
(
NULL
,
AV_LOG_FATAL
,
"SDL_CreateCond(): %s
\n
"
,
SDL_GetError
());
ffp
->
enable_accurate_seek
=
0
;
}
init_clock
(
&
is
->
vidclk
,
&
is
->
videoq
.
serial
);
init_clock
(
&
is
->
audclk
,
&
is
->
audioq
.
serial
);
init_clock
(
&
is
->
extclk
,
&
is
->
extclk
.
serial
);
...
...
@@ -3063,6 +3195,7 @@ static VideoState *stream_open(FFPlayer *ffp, const char *filename, AVInputForma
is
->
av_sync_type
=
ffp
->
av_sync_type
;
is
->
play_mutex
=
SDL_CreateMutex
();
is
->
accurate_seek_mutex
=
SDL_CreateMutex
();
ffp
->
is
=
is
;
is
->
pause_req
=
!
ffp
->
start_on_prepared
;
...
...
@@ -3681,6 +3814,15 @@ int ffp_stop_l(FFPlayer *ffp)
}
msg_queue_abort
(
&
ffp
->
msg_queue
);
if
(
ffp
->
enable_accurate_seek
&&
is
&&
is
->
accurate_seek_mutex
&&
is
->
audio_accurate_seek_cond
&&
is
->
video_accurate_seek_cond
)
{
SDL_LockMutex
(
is
->
accurate_seek_mutex
);
is
->
audio_accurate_seek_req
=
0
;
is
->
video_accurate_seek_req
=
0
;
SDL_CondSignal
(
is
->
audio_accurate_seek_cond
);
SDL_CondSignal
(
is
->
video_accurate_seek_cond
);
SDL_UnlockMutex
(
is
->
accurate_seek_mutex
);
}
return
0
;
}
...
...
ijkmedia/ijkplayer/ff_ffplay_def.h
浏览文件 @
cd58dd6b
...
...
@@ -128,6 +128,8 @@
#define MIN_PKT_DURATION 15
#define MAX_KEY_FRAME_INTERVAL 1000 // max key frame interval is 1000
#ifdef FFP_MERGE
#define CURSOR_HIDE_DELAY 1000000
...
...
@@ -381,6 +383,14 @@ typedef struct VideoState {
volatile
int
latest_seek_load_serial
;
volatile
int64_t
latest_seek_load_start_at
;
int
drop_aframe_count
;
int
drop_vframe_count
;
int
audio_accurate_seek_req
;
int
video_accurate_seek_req
;
SDL_mutex
*
accurate_seek_mutex
;
SDL_cond
*
video_accurate_seek_cond
;
SDL_cond
*
audio_accurate_seek_cond
;
}
VideoState
;
/* options specified by the user */
...
...
@@ -665,6 +675,7 @@ typedef struct FFPlayer {
AVApplicationContext
*
app_ctx
;
IjkIOManagerContext
*
ijkio_manager_ctx
;
int
enable_accurate_seek
;
}
FFPlayer
;
#define fftime_to_milliseconds(ts) (av_rescale(ts, 1000, AV_TIME_BASE))
...
...
@@ -741,6 +752,7 @@ inline static void ffp_reset_internal(FFPlayer *ffp)
ffp
->
start_on_prepared
=
1
;
ffp
->
first_video_frame_rendered
=
0
;
ffp
->
sync_av_start
=
1
;
ffp
->
enable_accurate_seek
=
0
;
ffp
->
playable_duration_ms
=
0
;
...
...
ijkmedia/ijkplayer/ff_ffplay_options.h
浏览文件 @
cd58dd6b
...
...
@@ -147,6 +147,9 @@ static const AVOption ffp_context_options[] = {
{
"preset-5-1-center-mix-level"
,
"preset center-mix-level for 5.1 channel"
,
OPTION_OFFSET
(
preset_5_1_center_mix_level
),
OPTION_DOUBLE
(
M_SQRT1_2
,
-
32
,
32
)
},
{
"enable-accurate-seek"
,
"enable accurate seek"
,
OPTION_OFFSET
(
enable_accurate_seek
),
OPTION_INT
(
0
,
0
,
1
)
},
// iOS only options
{
"videotoolbox"
,
"VideoToolbox: enable"
,
OPTION_OFFSET
(
videotoolbox
),
OPTION_INT
(
0
,
0
,
1
)
},
...
...
@@ -178,7 +181,7 @@ static const AVOption ffp_context_options[] = {
OPTION_OFFSET
(
mediacodec_handle_resolution_change
),
OPTION_INT
(
0
,
0
,
1
)
},
{
"opensles"
,
"OpenSL ES: enable"
,
OPTION_OFFSET
(
opensles
),
OPTION_INT
(
0
,
0
,
1
)
},
{
NULL
}
};
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录