Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
qq_25606643
ijkplayer
提交
47c7d0ea
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,发现更多精彩内容 >>
提交
47c7d0ea
编写于
6月 05, 2013
作者:
Z
Zhang Rui
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
ffplay: introduce: SDL_Thread
上级
ee5afeff
变更
6
隐藏空白更改
内联
并排
Showing
6 changed file
with
571 addition
and
71 deletion
+571
-71
ijkmediaplayer/jni/ffplay/demux_thread.c
ijkmediaplayer/jni/ffplay/demux_thread.c
+0
-26
ijkmediaplayer/jni/ffplay/ffplay.h
ijkmediaplayer/jni/ffplay/ffplay.h
+225
-0
ijkmediaplayer/jni/ffplay/internal.h
ijkmediaplayer/jni/ffplay/internal.h
+0
-36
ijkmediaplayer/jni/ffplay/minisdl/minisdl_thread.c
ijkmediaplayer/jni/ffplay/minisdl/minisdl_thread.c
+18
-0
ijkmediaplayer/jni/ffplay/minisdl/minisdl_thread.h
ijkmediaplayer/jni/ffplay/minisdl/minisdl_thread.h
+17
-9
ijkmediaplayer/jni/ffplay/thread_demux.c
ijkmediaplayer/jni/ffplay/thread_demux.c
+311
-0
未找到文件。
ijkmediaplayer/jni/ffplay/demux_thread.c
已删除
100644 → 0
浏览文件 @
ee5afeff
/*****************************************************************************
* demux_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 <string.h>
#include "internal.h"
ijkmediaplayer/jni/ffplay/ffplay.h
0 → 100644
浏览文件 @
47c7d0ea
/*****************************************************************************
* ffplay.h
*****************************************************************************
*
* 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
*/
#ifndef FFPLAY_H
#define FFPLAY_H
#include <inttypes.h>
#include "pkt_queue.h"
#ifdef CONFIG_AVFILTER
#undef CONFIG_AVFILTER
#endif
#define CONFIG_AVFILTER 0
//#define MAX_QUEUE_SIZE (15 * 1024 * 1024)
//#define MIN_FRAMES 5
/* SDL audio buffer size, in samples. Should be small to have precise
A/V sync as SDL does not have hardware buffer fullness info. */
#define SDL_AUDIO_BUFFER_SIZE 1024
/* no AV sync correction is done if below the AV sync threshold */
//#define AV_SYNC_THRESHOLD 0.01
/* no AV correction is done if too big error */
//#define AV_NOSYNC_THRESHOLD 10.0
/* maximum audio speed change to get correct sync */
//#define SAMPLE_CORRECTION_PERCENT_MAX 10
/* external clock speed adjustment constants for realtime sources based on buffer fullness */
//#define EXTERNAL_CLOCK_SPEED_MIN 0.900
//#define EXTERNAL_CLOCK_SPEED_MAX 1.010
//#define EXTERNAL_CLOCK_SPEED_STEP 0.001
/* we use about AUDIO_DIFF_AVG_NB A-V differences to make the average */
//#define AUDIO_DIFF_AVG_NB 20
/* polls for possible required screen refresh at least this often, should be less than 1/fps */
//#define REFRESH_RATE 0.01
/* NOTE: the size must be big enough to compensate the hardware audio buffersize size */
/* TODO: We assume that a decoded and resampled frame fits into this buffer */
#define SAMPLE_ARRAY_SIZE (8 * 65536)
//#define CURSOR_HIDE_DELAY 1000000
//static int64_t sws_flags = SWS_BICUBIC;
/* struct MyAVPacketList */
/* struct PacketQueue */
#define VIDEO_PICTURE_QUEUE_SIZE 4
#define SUBPICTURE_QUEUE_SIZE 4
typedef
struct
VideoPicture
{
double
pts
;
// presentation timestamp for this picture
int64_t
pos
;
// byte position in file
// SDL_Overlay *bmp;
int
width
,
height
;
/* source height & width */
AVRational
sample_aspect_ratio
;
int
allocated
;
int
reallocate
;
int
serial
;
#if CONFIG_AVFILTER
AVFilterBufferRef
*
picref
;
#endif
}
VideoPicture
;
typedef
struct
SubPicture
{
double
pts
;
/* presentation time stamp for this picture */
AVSubtitle
sub
;
}
SubPicture
;
typedef
struct
AudioParams
{
int
freq
;
int
channels
;
int64_t
channel_layout
;
enum
AVSampleFormat
fmt
;
}
AudioParams
;
enum
{
AV_SYNC_AUDIO_MASTER
,
/* default choice */
AV_SYNC_VIDEO_MASTER
,
AV_SYNC_EXTERNAL_CLOCK
,
/* synchronize to an external clock */
};
typedef
struct
VideoState
{
SDL_Thread
*
read_tid
;
SDL_Thread
*
video_tid
;
AVInputFormat
*
iformat
;
int
no_background
;
int
abort_request
;
int
force_refresh
;
int
paused
;
int
last_paused
;
int
queue_attachments_req
;
int
seek_req
;
int
seek_flags
;
int64_t
seek_pos
;
int64_t
seek_rel
;
int
read_pause_return
;
AVFormatContext
*
ic
;
int
realtime
;
int
audio_stream
;
int
av_sync_type
;
double
external_clock
;
///< external clock base
double
external_clock_drift
;
///< external clock base - time (av_gettime) at which we updated external_clock
int64_t
external_clock_time
;
///< last reference time
double
external_clock_speed
;
///< speed of the external clock
double
audio_clock
;
int
audio_clock_serial
;
double
audio_diff_cum
;
/* used for AV difference average computation */
double
audio_diff_avg_coef
;
double
audio_diff_threshold
;
int
audio_diff_avg_count
;
AVStream
*
audio_st
;
PacketQueue
audioq
;
int
audio_hw_buf_size
;
uint8_t
silence_buf
[
SDL_AUDIO_BUFFER_SIZE
];
uint8_t
*
audio_buf
;
uint8_t
*
audio_buf1
;
unsigned
int
audio_buf_size
;
/* in bytes */
unsigned
int
audio_buf1_size
;
int
audio_buf_index
;
/* in bytes */
int
audio_write_buf_size
;
AVPacket
audio_pkt_temp
;
AVPacket
audio_pkt
;
int
audio_pkt_temp_serial
;
struct
AudioParams
audio_src
;
struct
AudioParams
audio_tgt
;
struct
SwrContext
*
swr_ctx
;
double
audio_current_pts
;
double
audio_current_pts_drift
;
int
frame_drops_early
;
int
frame_drops_late
;
AVFrame
*
frame
;
enum
ShowMode
{
SHOW_MODE_NONE
=
-
1
,
SHOW_MODE_VIDEO
=
0
,
SHOW_MODE_WAVES
,
SHOW_MODE_RDFT
,
SHOW_MODE_NB
}
show_mode
;
int16_t
sample_array
[
SAMPLE_ARRAY_SIZE
];
int
sample_array_index
;
int
last_i_start
;
// RDFTContext *rdft;
int
rdft_bits
;
// FFTSample *rdft_data;
int
xpos
;
double
last_vis_time
;
SDL_Thread
*
subtitle_tid
;
int
subtitle_stream
;
int
subtitle_stream_changed
;
AVStream
*
subtitle_st
;
PacketQueue
subtitleq
;
SubPicture
subpq
[
SUBPICTURE_QUEUE_SIZE
];
int
subpq_size
,
subpq_rindex
,
subpq_windex
;
SDL_mutex
*
subpq_mutex
;
SDL_cond
*
subpq_cond
;
double
frame_timer
;
double
frame_last_pts
;
double
frame_last_duration
;
double
frame_last_dropped_pts
;
double
frame_last_returned_time
;
double
frame_last_filter_delay
;
int64_t
frame_last_dropped_pos
;
int
video_stream
;
AVStream
*
video_st
;
PacketQueue
videoq
;
double
video_current_pts
;
// current displayed pts
double
video_current_pts_drift
;
// video_current_pts - time (av_gettime) at which we updated video_current_pts - used to have running video pts
int64_t
video_current_pos
;
// current displayed file pos
double
max_frame_duration
;
// maximum duration of a frame - above this, we consider the jump a timestamp discontinuity
int
video_clock_serial
;
VideoPicture
pictq
[
VIDEO_PICTURE_QUEUE_SIZE
];
int
pictq_size
,
pictq_rindex
,
pictq_windex
;
SDL_mutex
*
pictq_mutex
;
SDL_cond
*
pictq_cond
;
#if !CONFIG_AVFILTER
struct
SwsContext
*
img_convert_ctx
;
#endif
// SDL_Rect last_display_rect;
char
filename
[
1024
];
int
width
,
height
,
xleft
,
ytop
;
int
step
;
#if CONFIG_AVFILTER
AVFilterContext
*
in_video_filter
;
// the first filter in the video chain
AVFilterContext
*
out_video_filter
;
// the last filter in the video chain
int
use_dr1
;
FrameBuffer
*
buffer_pool
;
#endif
int
last_video_stream
,
last_audio_stream
,
last_subtitle_stream
;
SDL_cond
*
continue_read_thread
;
}
VideoState
;
#endif
ijkmediaplayer/jni/ffplay/internal.h
已删除
100644 → 0
浏览文件 @
ee5afeff
/*****************************************************************************
* internal.h
*****************************************************************************
*
* 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
*/
#ifndef PLAYER_H
#define PLAYER_H
#include <inttypes.h>
enum
{
AV_SYNC_AUDIO_MASTER
,
/* default choice */
AV_SYNC_VIDEO_MASTER
,
AV_SYNC_EXTERNAL_CLOCK
,
/* synchronize to an external clock */
};
#endif
ijkmediaplayer/jni/ffplay/minisdl/minisdl_thread.c
浏览文件 @
47c7d0ea
...
...
@@ -150,3 +150,21 @@ int SDL_CondWait(SDL_cond *cond, SDL_mutex *mutex)
return
pthread_cond_wait
(
&
cond
->
id
,
&
mutex
->
id
);
}
SDL_Thread
*
SDL_CreateThreadEx
(
SDL_Thread
*
thread
,
int
(
*
fn
)(
void
*
),
void
*
data
)
{
if
(
pthread_create
(
&
thread
->
id
,
NULL
,
fn
,
data
)
!=
0
)
{
return
NULL
;
}
return
thread
;
}
void
SDL_WaitThread
(
SDL_Thread
*
thread
,
int
*
status
)
{
assert
(
thread
);
if
(
!
thread
)
return
;
pthread_join
(
thread
,
status
?
&
status
:
NULL
);
}
ijkmediaplayer/jni/ffplay/minisdl/minisdl_thread.h
浏览文件 @
47c7d0ea
...
...
@@ -36,20 +36,28 @@ typedef struct SDL_mutex {
}
SDL_mutex
;
SDL_mutex
*
SDL_CreateMutex
(
void
);
void
SDL_DestroyMutex
(
SDL_mutex
*
mutex
);
int
SDL_LockMutex
(
SDL_mutex
*
mutex
);
int
SDL_UnlockMutex
(
SDL_mutex
*
mutex
);
//int SDL_TryLockMutex(SDL_mutex *
mutex);
void
SDL_DestroyMutex
(
SDL_mutex
*
mutex
);
int
SDL_LockMutex
(
SDL_mutex
*
mutex
);
int
SDL_UnlockMutex
(
SDL_mutex
*
mutex
);
//int SDL_TryLockMutex(SDL_mutex *mutex);
typedef
struct
SDL_cond
{
pthread_cond_t
id
;
}
SDL_cond
;
SDL_cond
*
SDL_CreateCond
(
void
);
void
SDL_DestroyCond
(
SDL_cond
*
cond
);
int
SDL_CondSignal
(
SDL_cond
*
cond
);
int
SDL_CondBroadcast
(
SDL_cond
*
cond
);
int
SDL_CondWaitTimeout
(
SDL_cond
*
cond
,
SDL_mutex
*
mutex
,
uint32_t
ms
);
int
SDL_CondWait
(
SDL_cond
*
cond
,
SDL_mutex
*
mutex
);
void
SDL_DestroyCond
(
SDL_cond
*
cond
);
int
SDL_CondSignal
(
SDL_cond
*
cond
);
int
SDL_CondBroadcast
(
SDL_cond
*
cond
);
int
SDL_CondWaitTimeout
(
SDL_cond
*
cond
,
SDL_mutex
*
mutex
,
uint32_t
ms
);
int
SDL_CondWait
(
SDL_cond
*
cond
,
SDL_mutex
*
mutex
);
typedef
struct
SDL_Thread
{
pthread_t
id
;
}
SDL_Thread
;
SDL_Thread
*
SDL_CreateThreadEx
(
SDL_Thread
*
thread
,
int
(
*
fn
)(
void
*
),
void
*
data
);
void
SDL_WaitThread
(
SDL_Thread
*
thread
,
int
*
status
);
#endif
ijkmediaplayer/jni/ffplay/thread_demux.c
0 → 100644
浏览文件 @
47c7d0ea
/*****************************************************************************
* thread_demux.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 <string.h>
#include "ffplay.h"
#if 0
/* this thread gets the stream from the disk or the network */
static int read_thread(void *arg)
{
VideoState *is = arg;
AVFormatContext *ic = NULL;
int err, i, ret;
int st_index[AVMEDIA_TYPE_NB];
AVPacket pkt1, *pkt = &pkt1;
int eof = 0;
int pkt_in_play_range = 0;
AVDictionaryEntry *t;
AVDictionary **opts;
int orig_nb_streams;
SDL_mutex *wait_mutex = SDL_CreateMutex();
memset(st_index, -1, sizeof(st_index));
is->last_video_stream = is->video_stream = -1;
is->last_audio_stream = is->audio_stream = -1;
is->last_subtitle_stream = is->subtitle_stream = -1;
ic = avformat_alloc_context();
ic->interrupt_callback.callback = decode_interrupt_cb;
ic->interrupt_callback.opaque = is;
err = avformat_open_input(&ic, is->filename, is->iformat, &format_opts);
if (err < 0) {
print_error(is->filename, err);
ret = -1;
goto fail;
}
if ((t = av_dict_get(format_opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key);
ret = AVERROR_OPTION_NOT_FOUND;
goto fail;
}
is->ic = ic;
if (genpts)
ic->flags |= AVFMT_FLAG_GENPTS;
opts = setup_find_stream_info_opts(ic, codec_opts);
orig_nb_streams = ic->nb_streams;
err = avformat_find_stream_info(ic, opts);
if (err < 0) {
fprintf(stderr, "%s: could not find codec parameters\n", is->filename);
ret = -1;
goto fail;
}
for (i = 0; i < orig_nb_streams; i++)
av_dict_free(&opts[i]);
av_freep(&opts);
if (ic->pb)
ic->pb->eof_reached = 0; // FIXME hack, ffplay maybe should not use url_feof() to test for the end
if (seek_by_bytes < 0)
seek_by_bytes = !!(ic->iformat->flags & AVFMT_TS_DISCONT);
is->max_frame_duration = (ic->iformat->flags & AVFMT_TS_DISCONT) ? 10.0 : 3600.0;
/* if seeking requested, we execute it */
if (start_time != AV_NOPTS_VALUE) {
int64_t timestamp;
timestamp = start_time;
/* add the stream start time */
if (ic->start_time != AV_NOPTS_VALUE)
timestamp += ic->start_time;
ret = avformat_seek_file(ic, -1, INT64_MIN, timestamp, INT64_MAX, 0);
if (ret < 0) {
fprintf(stderr, "%s: could not seek to position %0.3f\n",
is->filename, (double) timestamp / AV_TIME_BASE);
}
}
is->realtime = is_realtime(ic);
for (i = 0; i < ic->nb_streams; i++)
ic->streams[i]->discard = AVDISCARD_ALL;
if (!video_disable)
st_index[AVMEDIA_TYPE_VIDEO] =
av_find_best_stream(ic, AVMEDIA_TYPE_VIDEO,
wanted_stream[AVMEDIA_TYPE_VIDEO], -1, NULL, 0);
if (!audio_disable)
st_index[AVMEDIA_TYPE_AUDIO] =
av_find_best_stream(ic, AVMEDIA_TYPE_AUDIO,
wanted_stream[AVMEDIA_TYPE_AUDIO],
st_index[AVMEDIA_TYPE_VIDEO],
NULL, 0);
if (!video_disable && !subtitle_disable)
st_index[AVMEDIA_TYPE_SUBTITLE] =
av_find_best_stream(ic, AVMEDIA_TYPE_SUBTITLE,
wanted_stream[AVMEDIA_TYPE_SUBTITLE],
(st_index[AVMEDIA_TYPE_AUDIO] >= 0 ?
st_index[AVMEDIA_TYPE_AUDIO] :
st_index[AVMEDIA_TYPE_VIDEO]),
NULL, 0);
if (show_status) {
av_dump_format(ic, 0, is->filename, 0);
}
is->show_mode = show_mode;
/* open the streams */
if (st_index[AVMEDIA_TYPE_AUDIO] >= 0) {
stream_component_open(is, st_index[AVMEDIA_TYPE_AUDIO]);
}
ret = -1;
if (st_index[AVMEDIA_TYPE_VIDEO] >= 0) {
ret = stream_component_open(is, st_index[AVMEDIA_TYPE_VIDEO]);
}
if (is->show_mode == SHOW_MODE_NONE)
is->show_mode = ret >= 0 ? SHOW_MODE_VIDEO : SHOW_MODE_RDFT;
if (st_index[AVMEDIA_TYPE_SUBTITLE] >= 0) {
stream_component_open(is, st_index[AVMEDIA_TYPE_SUBTITLE]);
}
if (is->video_stream < 0 && is->audio_stream < 0) {
fprintf(stderr, "%s: could not open codecs\n", is->filename);
ret = -1;
goto fail;
}
if (infinite_buffer < 0 && is->realtime)
infinite_buffer = 1;
for (;;) {
if (is->abort_request)
break;
if (is->paused != is->last_paused) {
is->last_paused = is->paused;
if (is->paused)
is->read_pause_return = av_read_pause(ic);
else
av_read_play(ic);
}
#if CONFIG_RTSP_DEMUXER || CONFIG_MMSH_PROTOCOL
if (is->paused &&
(!strcmp(ic->iformat->name, "rtsp") ||
(ic->pb && !strncmp(input_filename, "mmsh:", 5)))) {
/* wait 10 ms to avoid trying to get another packet */
/* XXX: horrible */
SDL_Delay(10);
continue;
}
#endif
if (is->seek_req) {
int64_t seek_target = is->seek_pos;
int64_t seek_min = is->seek_rel > 0 ? seek_target - is->seek_rel + 2 : INT64_MIN;
int64_t seek_max = is->seek_rel < 0 ? seek_target - is->seek_rel - 2 : INT64_MAX;
// FIXME the +-2 is due to rounding being not done in the correct direction in generation
// of the seek_pos/seek_rel variables
ret = avformat_seek_file(is->ic, -1, seek_min, seek_target, seek_max, is->seek_flags);
if (ret < 0) {
fprintf(stderr, "%s: error while seeking\n", is->ic->filename);
} else {
if (is->audio_stream >= 0) {
packet_queue_flush(&is->audioq);
packet_queue_put(&is->audioq, &flush_pkt);
}
if (is->subtitle_stream >= 0) {
packet_queue_flush(&is->subtitleq);
packet_queue_put(&is->subtitleq, &flush_pkt);
}
if (is->video_stream >= 0) {
packet_queue_flush(&is->videoq);
packet_queue_put(&is->videoq, &flush_pkt);
}
if (is->seek_flags & AVSEEK_FLAG_BYTE) {
update_external_clock_pts(is, NAN);
} else {
update_external_clock_pts(is, seek_target / (double) AV_TIME_BASE);
}
}
is->seek_req = 0;
eof = 0;
if (is->paused)
step_to_next_frame(is);
}
if (is->queue_attachments_req) {
avformat_queue_attached_pictures(ic);
is->queue_attachments_req = 0;
}
/* if the queue are full, no need to read more */
if (infinite_buffer < 1 &&
(is->audioq.size + is->videoq.size + is->subtitleq.size > MAX_QUEUE_SIZE
|| ((is->audioq.nb_packets > MIN_FRAMES || is->audio_stream < 0 || is->audioq.abort_request)
&& (is->videoq.nb_packets > MIN_FRAMES || is->video_stream < 0 || is->videoq.abort_request)
&& (is->subtitleq.nb_packets > MIN_FRAMES || is->subtitle_stream < 0 || is->subtitleq.abort_request)))) {
/* wait 10 ms */
SDL_LockMutex(wait_mutex);
SDL_CondWaitTimeout(is->continue_read_thread, wait_mutex, 10);
SDL_UnlockMutex(wait_mutex);
continue;
}
if (eof) {
if (is->video_stream >= 0) {
av_init_packet(pkt);
pkt->data = NULL;
pkt->size = 0;
pkt->stream_index = is->video_stream;
packet_queue_put(&is->videoq, pkt);
}
if (is->audio_stream >= 0 &&
is->audio_st->codec->codec->capabilities & CODEC_CAP_DELAY) {
av_init_packet(pkt);
pkt->data = NULL;
pkt->size = 0;
pkt->stream_index = is->audio_stream;
packet_queue_put(&is->audioq, pkt);
}
SDL_Delay(10);
if (is->audioq.size + is->videoq.size + is->subtitleq.size == 0) {
if (loop != 1 && (!loop || --loop)) {
stream_seek(is, start_time != AV_NOPTS_VALUE ? start_time : 0, 0, 0);
} else if (autoexit) {
ret = AVERROR_EOF;
goto fail;
}
}
eof = 0;
continue;
}
ret = av_read_frame(ic, pkt);
if (ret < 0) {
if (ret == AVERROR_EOF || url_feof(ic->pb))
eof = 1;
if (ic->pb && ic->pb->error)
break;
SDL_LockMutex(wait_mutex);
SDL_CondWaitTimeout(is->continue_read_thread, wait_mutex, 10);
SDL_UnlockMutex(wait_mutex);
continue;
}
/* check if packet is in play range specified by user, then queue, otherwise discard */
pkt_in_play_range = duration == AV_NOPTS_VALUE ||
(pkt->pts - ic->streams[pkt->stream_index]->start_time) *
av_q2d(ic->streams[pkt->stream_index]->time_base) -
(double) (start_time != AV_NOPTS_VALUE ? start_time : 0) / 1000000
<= ((double) duration / 1000000);
if (pkt->stream_index == is->audio_stream && pkt_in_play_range) {
packet_queue_put(&is->audioq, pkt);
} else if (pkt->stream_index == is->video_stream && pkt_in_play_range) {
packet_queue_put(&is->videoq, pkt);
} else if (pkt->stream_index == is->subtitle_stream && pkt_in_play_range) {
packet_queue_put(&is->subtitleq, pkt);
} else {
av_free_packet(pkt);
}
}
/* wait until the end */
while (!is->abort_request) {
SDL_Delay(100);
}
ret = 0;
fail:
/* close each stream */
if (is->audio_stream >= 0)
stream_component_close(is, is->audio_stream);
if (is->video_stream >= 0)
stream_component_close(is, is->video_stream);
if (is->subtitle_stream >= 0)
stream_component_close(is, is->subtitle_stream);
if (is->ic) {
avformat_close_input(&is->ic);
}
if (ret != 0) {
SDL_Event event;
event.type = FF_QUIT_EVENT;
event.user.data1 = is;
SDL_PushEvent(&event);
}
SDL_DestroyMutex(wait_mutex);
return 0;
}
#endif
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录