}
/* packet queue handling */
-static void packet_queue_init(PacketQueue *q)
+static int packet_queue_init(PacketQueue *q)
{
memset(q, 0, sizeof(PacketQueue));
q->mutex = SDL_CreateMutex();
+ if (!q->mutex) {
+ av_log(NULL, AV_LOG_FATAL, "SDL_CreateMutex(): %s\n", SDL_GetError());
+ return AVERROR(ENOMEM);
+ }
q->cond = SDL_CreateCond();
+ if (!q->cond) {
+ av_log(NULL, AV_LOG_FATAL, "SDL_CreateCond(): %s\n", SDL_GetError());
+ return AVERROR(ENOMEM);
+ }
q->abort_request = 1;
+ return 0;
}
static void packet_queue_flush(PacketQueue *q)
{
int i;
memset(f, 0, sizeof(FrameQueue));
- if (!(f->mutex = SDL_CreateMutex()))
+ if (!(f->mutex = SDL_CreateMutex())) {
+ av_log(NULL, AV_LOG_FATAL, "SDL_CreateMutex(): %s\n", SDL_GetError());
return AVERROR(ENOMEM);
- if (!(f->cond = SDL_CreateCond()))
+ }
+ if (!(f->cond = SDL_CreateCond())) {
+ av_log(NULL, AV_LOG_FATAL, "SDL_CreateCond(): %s\n", SDL_GetError());
return AVERROR(ENOMEM);
+ }
f->pktq = pktq;
f->max_size = FFMIN(max_size, FRAME_QUEUE_SIZE);
f->keep_last = !!keep_last;
}
}
+static void stream_component_close(VideoState *is, int stream_index)
+{
+ AVFormatContext *ic = is->ic;
+ AVCodecContext *avctx;
+
+ if (stream_index < 0 || stream_index >= ic->nb_streams)
+ return;
+ avctx = ic->streams[stream_index]->codec;
+
+ switch (avctx->codec_type) {
+ case AVMEDIA_TYPE_AUDIO:
+ decoder_abort(&is->auddec, &is->sampq);
+ SDL_CloseAudio();
+ decoder_destroy(&is->auddec);
+ swr_free(&is->swr_ctx);
+ av_freep(&is->audio_buf1);
+ is->audio_buf1_size = 0;
+ is->audio_buf = NULL;
+
+ if (is->rdft) {
+ av_rdft_end(is->rdft);
+ av_freep(&is->rdft_data);
+ is->rdft = NULL;
+ is->rdft_bits = 0;
+ }
+ break;
+ case AVMEDIA_TYPE_VIDEO:
+ decoder_abort(&is->viddec, &is->pictq);
+ decoder_destroy(&is->viddec);
+ break;
+ case AVMEDIA_TYPE_SUBTITLE:
+ decoder_abort(&is->subdec, &is->subpq);
+ decoder_destroy(&is->subdec);
+ break;
+ default:
+ break;
+ }
+
+ ic->streams[stream_index]->discard = AVDISCARD_ALL;
+ avcodec_close(avctx);
+ switch (avctx->codec_type) {
+ case AVMEDIA_TYPE_AUDIO:
+ is->audio_st = NULL;
+ is->audio_stream = -1;
+ break;
+ case AVMEDIA_TYPE_VIDEO:
+ is->video_st = NULL;
+ is->video_stream = -1;
+ break;
+ case AVMEDIA_TYPE_SUBTITLE:
+ is->subtitle_st = NULL;
+ is->subtitle_stream = -1;
+ break;
+ default:
+ break;
+ }
+}
+
static void stream_close(VideoState *is)
{
/* XXX: use a special url_shutdown call to abort parse cleanly */
is->abort_request = 1;
SDL_WaitThread(is->read_tid, NULL);
+
+ /* 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);
+
+ avformat_close_input(&is->ic);
+
packet_queue_destroy(&is->videoq);
packet_queue_destroy(&is->audioq);
packet_queue_destroy(&is->subtitleq);
return ret;
}
-static void decoder_start(Decoder *d, int (*fn)(void *), void *arg)
+static int decoder_start(Decoder *d, int (*fn)(void *), void *arg)
{
packet_queue_start(d->queue);
d->decoder_tid = SDL_CreateThread(fn, arg);
+ if (!d->decoder_tid) {
+ av_log(NULL, AV_LOG_ERROR, "SDL_CreateThread(): %s\n", SDL_GetError());
+ return AVERROR(ENOMEM);
+ }
+ return 0;
}
static int video_thread(void *arg)
is->auddec.start_pts = is->audio_st->start_time;
is->auddec.start_pts_tb = is->audio_st->time_base;
}
- decoder_start(&is->auddec, audio_thread, is);
+ if ((ret = decoder_start(&is->auddec, audio_thread, is)) < 0)
+ goto fail;
SDL_PauseAudio(0);
break;
case AVMEDIA_TYPE_VIDEO:
is->viddec_height = avctx->height;
decoder_init(&is->viddec, avctx, &is->videoq, is->continue_read_thread);
- decoder_start(&is->viddec, video_thread, is);
+ if ((ret = decoder_start(&is->viddec, video_thread, is)) < 0)
+ goto fail;
is->queue_attachments_req = 1;
break;
case AVMEDIA_TYPE_SUBTITLE:
is->subtitle_st = ic->streams[stream_index];
decoder_init(&is->subdec, avctx, &is->subtitleq, is->continue_read_thread);
- decoder_start(&is->subdec, subtitle_thread, is);
+ if ((ret = decoder_start(&is->subdec, subtitle_thread, is)) < 0)
+ goto fail;
break;
default:
break;
return ret;
}
-static void stream_component_close(VideoState *is, int stream_index)
-{
- AVFormatContext *ic = is->ic;
- AVCodecContext *avctx;
-
- if (stream_index < 0 || stream_index >= ic->nb_streams)
- return;
- avctx = ic->streams[stream_index]->codec;
-
- switch (avctx->codec_type) {
- case AVMEDIA_TYPE_AUDIO:
- decoder_abort(&is->auddec, &is->sampq);
- SDL_CloseAudio();
- decoder_destroy(&is->auddec);
- swr_free(&is->swr_ctx);
- av_freep(&is->audio_buf1);
- is->audio_buf1_size = 0;
- is->audio_buf = NULL;
-
- if (is->rdft) {
- av_rdft_end(is->rdft);
- av_freep(&is->rdft_data);
- is->rdft = NULL;
- is->rdft_bits = 0;
- }
- break;
- case AVMEDIA_TYPE_VIDEO:
- decoder_abort(&is->viddec, &is->pictq);
- decoder_destroy(&is->viddec);
- break;
- case AVMEDIA_TYPE_SUBTITLE:
- decoder_abort(&is->subdec, &is->subpq);
- decoder_destroy(&is->subdec);
- break;
- default:
- break;
- }
-
- ic->streams[stream_index]->discard = AVDISCARD_ALL;
- avcodec_close(avctx);
- switch (avctx->codec_type) {
- case AVMEDIA_TYPE_AUDIO:
- is->audio_st = NULL;
- is->audio_stream = -1;
- break;
- case AVMEDIA_TYPE_VIDEO:
- is->video_st = NULL;
- is->video_stream = -1;
- break;
- case AVMEDIA_TYPE_SUBTITLE:
- is->subtitle_st = NULL;
- is->subtitle_stream = -1;
- break;
- default:
- break;
- }
-}
-
static int decode_interrupt_cb(void *ctx)
{
VideoState *is = ctx;
int scan_all_pmts_set = 0;
int64_t pkt_ts;
+ if (!wait_mutex) {
+ av_log(NULL, AV_LOG_FATAL, "SDL_CreateMutex(): %s\n", SDL_GetError());
+ ret = AVERROR(ENOMEM);
+ goto fail;
+ }
+
memset(st_index, -1, sizeof(st_index));
is->last_video_stream = is->video_stream = -1;
is->last_audio_stream = is->audio_stream = -1;
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 (ic) {
+ if (ic && !is->ic)
avformat_close_input(&ic);
- is->ic = NULL;
- }
if (ret != 0) {
SDL_Event event;
if (frame_queue_init(&is->sampq, &is->audioq, SAMPLE_QUEUE_SIZE, 1) < 0)
goto fail;
- packet_queue_init(&is->videoq);
- packet_queue_init(&is->audioq);
- packet_queue_init(&is->subtitleq);
+ if (packet_queue_init(&is->videoq) < 0 ||
+ packet_queue_init(&is->audioq) < 0 ||
+ packet_queue_init(&is->subtitleq) < 0)
+ goto fail;
- is->continue_read_thread = SDL_CreateCond();
+ if (!(is->continue_read_thread = SDL_CreateCond())) {
+ av_log(NULL, AV_LOG_FATAL, "SDL_CreateCond(): %s\n", SDL_GetError());
+ goto fail;
+ }
init_clock(&is->vidclk, &is->videoq.serial);
init_clock(&is->audclk, &is->audioq.serial);
is->av_sync_type = av_sync_type;
is->read_tid = SDL_CreateThread(read_thread, is);
if (!is->read_tid) {
+ av_log(NULL, AV_LOG_FATAL, "SDL_CreateThread(): %s\n", SDL_GetError());
fail:
stream_close(is);
return NULL;
switch(op) {
case AV_LOCK_CREATE:
*mtx = SDL_CreateMutex();
- if(!*mtx)
+ if(!*mtx) {
+ av_log(NULL, AV_LOG_FATAL, "SDL_CreateMutex(): %s\n", SDL_GetError());
return 1;
+ }
return 0;
case AV_LOCK_OBTAIN:
return !!SDL_LockMutex(*mtx);