提交 2bda338b 编写于 作者: Z Zhang Rui

jni: ijkplayer: introduce display_thread

上级 70714b7a
/*****************************************************************************
* ffplay_display_thread.c
*****************************************************************************
*
* copyright (c) 2001 Fabrice Bellard
* copyright (c) 2013 Zhang Rui <bbcallen@gmail.com>
*
* This file is part of ijkPlayer.
*
* ijkPlayer is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* ijkPlayer is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with ijkPlayer; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "ffplayer.h"
/* ffplay.c 1297 */
/* called to display each frame */
static void video_refresh(void *opaque, double *remaining_time)
{
FFPlayer *ffp = opaque;
VideoState *is = &ffp->is;
VideoPicture *vp;
double time;
SubPicture *sp, *sp2;
if (!is->paused && get_master_sync_type(is) == AV_SYNC_EXTERNAL_CLOCK && is->realtime)
check_external_clock_speed(is);
if (!ffp->display_disable && is->show_mode != SHOW_MODE_VIDEO && is->audio_st) {
time = av_gettime() / 1000000.0;
if (is->force_refresh || is->last_vis_time + ffp->rdftspeed < time) {
video_display(is);
is->last_vis_time = time;
}
*remaining_time = FFMIN(*remaining_time, is->last_vis_time + ffp->rdftspeed - time);
}
if (is->video_st) {
int redisplay = 0;
if (is->force_refresh)
redisplay = pictq_prev_picture(is);
retry:
if (is->pictq_size == 0) {
SDL_LockMutex(is->pictq_mutex);
if (is->frame_last_dropped_pts != AV_NOPTS_VALUE && is->frame_last_dropped_pts > is->frame_last_pts) {
update_video_pts(is, is->frame_last_dropped_pts, is->frame_last_dropped_pos, 0);
is->frame_last_dropped_pts = AV_NOPTS_VALUE;
}
SDL_UnlockMutex(is->pictq_mutex);
// nothing to do, no picture to display in the queue
} else {
double last_duration, duration, delay;
/* dequeue the picture */
vp = &is->pictq[is->pictq_rindex];
if (vp->serial != is->videoq.serial) {
pictq_next_picture(is);
redisplay = 0;
goto retry;
}
if (is->paused)
goto display;
/* compute nominal last_duration */
last_duration = vp->pts - is->frame_last_pts;
if (last_duration > 0 && last_duration < is->max_frame_duration) {
/* if duration of the last frame was sane, update last_duration in video state */
is->frame_last_duration = last_duration;
}
delay = compute_target_delay(is->frame_last_duration, is);
time= av_gettime()/1000000.0;
if (time < is->frame_timer + delay) {
*remaining_time = FFMIN(is->frame_timer + delay - time, *remaining_time);
return;
}
if (delay > 0)
is->frame_timer += delay * FFMAX(1, floor((time-is->frame_timer) / delay));
SDL_LockMutex(is->pictq_mutex);
update_video_pts(is, vp->pts, vp->pos, vp->serial);
SDL_UnlockMutex(is->pictq_mutex);
if (is->pictq_size > 1) {
VideoPicture *nextvp = &is->pictq[(is->pictq_rindex + 1) % VIDEO_PICTURE_QUEUE_SIZE];
duration = nextvp->pts - vp->pts;
if(!is->step && (redisplay || ffp->framedrop>0 || (ffp->framedrop && get_master_sync_type(is) != AV_SYNC_VIDEO_MASTER)) && time > is->frame_timer + duration){
if (!redisplay)
is->frame_drops_late++;
pictq_next_picture(is);
redisplay = 0;
goto retry;
}
}
if (is->subtitle_st) {
if (is->subtitle_stream_changed) {
SDL_LockMutex(is->subpq_mutex);
while (is->subpq_size) {
free_subpicture(&is->subpq[is->subpq_rindex]);
/* update queue size and signal for next picture */
if (++is->subpq_rindex == SUBPICTURE_QUEUE_SIZE)
is->subpq_rindex = 0;
is->subpq_size--;
}
is->subtitle_stream_changed = 0;
SDL_CondSignal(is->subpq_cond);
SDL_UnlockMutex(is->subpq_mutex);
} else {
if (is->subpq_size > 0) {
sp = &is->subpq[is->subpq_rindex];
if (is->subpq_size > 1)
sp2 = &is->subpq[(is->subpq_rindex + 1) % SUBPICTURE_QUEUE_SIZE];
else
sp2 = NULL;
if ((is->video_current_pts > (sp->pts + ((float) sp->sub.end_display_time / 1000)))
|| (sp2 && is->video_current_pts > (sp2->pts + ((float) sp2->sub.start_display_time / 1000))))
{
free_subpicture(sp);
/* update queue size and signal for next picture */
if (++is->subpq_rindex == SUBPICTURE_QUEUE_SIZE)
is->subpq_rindex = 0;
SDL_LockMutex(is->subpq_mutex);
is->subpq_size--;
SDL_CondSignal(is->subpq_cond);
SDL_UnlockMutex(is->subpq_mutex);
}
}
}
}
display:
/* display picture */
if (!ffp->display_disable && is->show_mode == SHOW_MODE_VIDEO)
video_display(is);
pictq_next_picture(is);
if (is->step && !is->paused)
stream_toggle_pause(is);
}
}
is->force_refresh = 0;
if (ffp->show_status) {
static int64_t last_time;
int64_t cur_time;
int aqsize, vqsize, sqsize;
double av_diff;
cur_time = av_gettime();
if (!last_time || (cur_time - last_time) >= 30000) {
aqsize = 0;
vqsize = 0;
sqsize = 0;
if (is->audio_st)
aqsize = is->audioq.size;
if (is->video_st)
vqsize = is->videoq.size;
if (is->subtitle_st)
sqsize = is->subtitleq.size;
av_diff = 0;
if (is->audio_st && is->video_st)
av_diff = get_audio_clock(is) - get_video_clock(is);
printf("%7.2f A-V:%7.3f fd=%4d aq=%5dKB vq=%5dKB sq=%5dB f=%"PRId64"/%"PRId64" \r",
get_master_clock(is),
av_diff,
is->frame_drops_early + is->frame_drops_late,
aqsize / 1024,
vqsize / 1024,
sqsize,
is->video_st ? is->video_st->codec->pts_correction_num_faulty_dts : 0,
is->video_st ? is->video_st->codec->pts_correction_num_faulty_pts : 0);
fflush(stdout);
last_time = cur_time;
}
}
}
...@@ -59,9 +59,7 @@ typedef struct FFPlayer { ...@@ -59,9 +59,7 @@ typedef struct FFPlayer {
int subtitle_disable; int subtitle_disable;
int wanted_stream[AVMEDIA_TYPE_NB]; int wanted_stream[AVMEDIA_TYPE_NB];
int seek_by_bytes; int seek_by_bytes;
#if 0
int display_disable; int display_disable;
#endif
int show_status; int show_status;
#if 0 #if 0
int av_sync_type = AV_SYNC_AUDIO_MASTER; int av_sync_type = AV_SYNC_AUDIO_MASTER;
...@@ -90,8 +88,8 @@ typedef struct FFPlayer { ...@@ -90,8 +88,8 @@ typedef struct FFPlayer {
char *audio_codec_name; char *audio_codec_name;
char *subtitle_codec_name; char *subtitle_codec_name;
char *video_codec_name; char *video_codec_name;
double rdftspeed;
#if 0 #if 0
double rdftspeed = 0.02;
int64_t cursor_last_shown; int64_t cursor_last_shown;
int cursor_hidden = 0; int cursor_hidden = 0;
#endif #endif
...@@ -131,6 +129,7 @@ inline static void ijkff_reset(FFPlayer *ffp) ...@@ -131,6 +129,7 @@ inline static void ijkff_reset(FFPlayer *ffp)
ffp->wanted_stream[AVMEDIA_TYPE_VIDEO] = -1; ffp->wanted_stream[AVMEDIA_TYPE_VIDEO] = -1;
ffp->wanted_stream[AVMEDIA_TYPE_SUBTITLE] = -1; ffp->wanted_stream[AVMEDIA_TYPE_SUBTITLE] = -1;
ffp->seek_by_bytes = -1; ffp->seek_by_bytes = -1;
ffp->display_disable = 0;
ffp->show_status = 1; ffp->show_status = 1;
ffp->start_time = AV_NOPTS_VALUE; ffp->start_time = AV_NOPTS_VALUE;
ffp->duration = AV_NOPTS_VALUE; ffp->duration = AV_NOPTS_VALUE;
...@@ -152,6 +151,7 @@ inline static void ijkff_reset(FFPlayer *ffp) ...@@ -152,6 +151,7 @@ inline static void ijkff_reset(FFPlayer *ffp)
IJKFF_SAFE_FREE(ffp->audio_codec_name); IJKFF_SAFE_FREE(ffp->audio_codec_name);
IJKFF_SAFE_FREE(ffp->subtitle_codec_name); IJKFF_SAFE_FREE(ffp->subtitle_codec_name);
IJKFF_SAFE_FREE(ffp->video_codec_name); IJKFF_SAFE_FREE(ffp->video_codec_name);
ffp->rdftspeed = 0.02;
#if CONFIG_AVFILTER #if CONFIG_AVFILTER
ffp->vfilters = NULL; ffp->vfilters = NULL;
#endif #endif
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册