summaryrefslogtreecommitdiffstats
path: root/player
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2014-10-28 16:19:07 +0100
committerwm4 <wm4@nowhere>2014-10-28 20:30:12 +0100
commit65db3291b327797ac7d09ba2ea36db9ba5383f18 (patch)
treed43c2bb41969472e18c71e7b7275e5cbd2206814 /player
parent3cde02fe2292bbc6e213b6a619c2bafa21412276 (diff)
downloadmpv-65db3291b327797ac7d09ba2ea36db9ba5383f18.tar.bz2
mpv-65db3291b327797ac7d09ba2ea36db9ba5383f18.tar.xz
client API: better error reporting
Give somewhat more information on playback failure.
Diffstat (limited to 'player')
-rw-r--r--player/audio.c1
-rw-r--r--player/client.c5
-rw-r--r--player/core.h3
-rw-r--r--player/loadfile.c55
-rw-r--r--player/misc.c7
-rw-r--r--player/video.c5
6 files changed, 52 insertions, 24 deletions
diff --git a/player/audio.c b/player/audio.c
index 6774d415c3..8274399f67 100644
--- a/player/audio.c
+++ b/player/audio.c
@@ -255,6 +255,7 @@ void reinit_audio_chain(struct MPContext *mpctx)
struct ao *ao = mpctx->ao;
if (!ao) {
MP_ERR(mpctx, "Could not open/initialize audio device -> no sound.\n");
+ mpctx->error_playing = MPV_ERROR_AO_INIT_FAILED;
goto init_error;
}
diff --git a/player/client.c b/player/client.c
index 8376756a9a..2308555a1e 100644
--- a/player/client.c
+++ b/player/client.c
@@ -1479,6 +1479,11 @@ static const char *const err_table[] = {
[-MPV_ERROR_PROPERTY_UNAVAILABLE] = "property unavailable",
[-MPV_ERROR_PROPERTY_ERROR] = "error accessing property",
[-MPV_ERROR_COMMAND] = "error running command",
+ [-MPV_ERROR_LOADING_FAILED] = "loading failed",
+ [-MPV_ERROR_AO_INIT_FAILED] = "audio output initialization failed",
+ [-MPV_ERROR_VO_INIT_FAILED] = "audio output initialization failed",
+ [-MPV_ERROR_NOTHING_TO_PLAY] = "the file has no audio or video data",
+ [-MPV_ERROR_UNKNOWN_FORMAT] = "unrecognized file format",
};
const char *mpv_error_string(int error)
diff --git a/player/core.h b/player/core.h
index 9b9873e610..32c6b45db6 100644
--- a/player/core.h
+++ b/player/core.h
@@ -38,6 +38,7 @@ enum stop_play_reason {
PT_STOP, // stop playback, clear playlist
PT_RELOAD_DEMUXER, // restart playback, but keep stream open
PT_QUIT, // stop playback, quit player
+ PT_ERROR, // play next playlist entry (due to an error)
};
enum exit_reason {
@@ -186,7 +187,7 @@ typedef struct MPContext {
enum exit_reason quit_player_rc;
int quit_custom_rc;
bool has_quit_custom_rc;
- bool error_playing;
+ int error_playing;
char **resume_defaults;
int64_t shown_vframes, shown_aframes;
diff --git a/player/loadfile.c b/player/loadfile.c
index 58b9cf9f68..46f41644c1 100644
--- a/player/loadfile.c
+++ b/player/loadfile.c
@@ -877,6 +877,7 @@ static void play_current_file(struct MPContext *mpctx)
mp_cancel_reset(mpctx->playback_abort);
+ mpctx->error_playing = MPV_ERROR_LOADING_FAILED;
mpctx->stop_play = 0;
mpctx->filename = NULL;
mpctx->shown_aframes = 0;
@@ -973,6 +974,7 @@ goto_reopen_demuxer: ;
mpctx->demuxer = open_demux_async(mpctx, mpctx->stream);
if (!mpctx->demuxer) {
MP_ERR(mpctx, "Failed to recognize file format.\n");
+ mpctx->error_playing = MPV_ERROR_UNKNOWN_FORMAT;
goto terminate_playback;
}
mpctx->master_demuxer = mpctx->demuxer;
@@ -987,6 +989,7 @@ goto_reopen_demuxer: ;
for (struct playlist_entry *e = pl->first; e; e = e->next)
e->stream_flags |= entry_stream_flags;
transfer_playlist(mpctx, pl);
+ mpctx->error_playing = 0;
goto terminate_playback;
}
@@ -1092,6 +1095,7 @@ goto_reopen_demuxer: ;
if (demux_stream_control(d, STREAM_CTRL_DVB_STEP_CHANNEL, &dir) > 0)
mpctx->stop_play = PT_RELOAD_DEMUXER;
}
+ mpctx->error_playing = MPV_ERROR_NOTHING_TO_PLAY;
goto terminate_playback;
}
@@ -1099,6 +1103,7 @@ goto_reopen_demuxer: ;
if (mpctx->max_frames == 0) {
mpctx->stop_play = PT_NEXT_ENTRY;
+ mpctx->error_playing = 0;
goto terminate_playback;
}
@@ -1124,7 +1129,7 @@ goto_reopen_demuxer: ;
mp_notify(mpctx, MPV_EVENT_FILE_LOADED, NULL);
playback_start = mp_time_sec();
- mpctx->error_playing = false;
+ mpctx->error_playing = 0;
while (!mpctx->stop_play)
run_playloop(mpctx);
@@ -1173,18 +1178,33 @@ terminate_playback:
mpctx->playback_initialized = false;
- if (mpctx->playing && mpctx->stop_play == AT_END_OF_FILE) {
- // Played/paused for longer than 1 second -> ok
- mpctx->playing->playback_short =
- playback_start < 0 || mp_time_sec() - playback_start < 1.0;
- mpctx->playing->init_failed =
- mpctx->shown_aframes == 0 && mpctx->shown_vframes == 0;
- }
-
mp_notify(mpctx, MPV_EVENT_TRACKS_CHANGED, NULL);
struct mpv_event_end_file end_event = {0};
switch (mpctx->stop_play) {
- case AT_END_OF_FILE: end_event.reason = MPV_END_FILE_REASON_EOF; break;
+ case PT_ERROR:
+ case AT_END_OF_FILE:
+ {
+ if (mpctx->error_playing >= 0 &&
+ mpctx->shown_aframes == 0 && mpctx->shown_vframes == 0)
+ {
+ mpctx->error_playing = MPV_ERROR_NOTHING_TO_PLAY;
+ }
+ end_event.error = mpctx->error_playing;
+ if (end_event.error < 0) {
+ end_event.reason = MPV_END_FILE_REASON_ERROR;
+ } else {
+ end_event.reason = MPV_END_FILE_REASON_EOF;
+ }
+ if (mpctx->playing) {
+ // Played/paused for longer than 1 second -> ok
+ mpctx->playing->playback_short =
+ playback_start < 0 || mp_time_sec() - playback_start < 1.0;
+ mpctx->playing->init_failed =
+ end_event.error == MPV_ERROR_NOTHING_TO_PLAY;
+ }
+ break;
+ }
+ // Note that error_playing is meaningless in these cases.
case PT_NEXT_ENTRY:
case PT_CURRENT_ENTRY:
case PT_STOP: end_event.reason = MPV_END_FILE_REASON_STOP; break;
@@ -1259,9 +1279,8 @@ void mp_play_files(struct MPContext *mpctx)
if (mpctx->stop_play == PT_QUIT)
break;
- mpctx->error_playing = true;
play_current_file(mpctx);
- if (mpctx->error_playing) {
+ if (mpctx->error_playing < 0) {
if (!mpctx->quit_player_rc) {
mpctx->quit_player_rc = EXIT_NOTPLAYED;
} else if (mpctx->quit_player_rc == EXIT_PLAYED) {
@@ -1275,15 +1294,11 @@ void mp_play_files(struct MPContext *mpctx)
if (mpctx->stop_play == PT_QUIT)
break;
- if (!mpctx->stop_play || mpctx->stop_play == AT_END_OF_FILE)
- mpctx->stop_play = PT_NEXT_ENTRY;
-
- struct playlist_entry *new_entry = NULL;
-
- if (mpctx->stop_play == PT_NEXT_ENTRY) {
+ struct playlist_entry *new_entry = mpctx->playlist->current;
+ if (mpctx->stop_play == PT_NEXT_ENTRY || mpctx->stop_play == PT_ERROR ||
+ mpctx->stop_play == AT_END_OF_FILE || !mpctx->stop_play)
+ {
new_entry = mp_next_file(mpctx, +1, false);
- } else {
- new_entry = mpctx->playlist->current;
}
mpctx->playlist->current = new_entry;
diff --git a/player/misc.c b/player/misc.c
index 5355e23f41..c178ec7b39 100644
--- a/player/misc.c
+++ b/player/misc.c
@@ -191,8 +191,11 @@ void error_on_track(struct MPContext *mpctx, struct track *track)
MP_INFO(mpctx, "Video: no video\n");
if (!mpctx->current_track[0][STREAM_AUDIO] &&
!mpctx->current_track[0][STREAM_VIDEO])
- mpctx->stop_play = PT_NEXT_ENTRY;
- mpctx->error_playing = true;
+ {
+ mpctx->stop_play = PT_ERROR;
+ if (mpctx->error_playing >= 0)
+ mpctx->error_playing = MPV_ERROR_NOTHING_TO_PLAY;
+ }
mpctx->sleeptime = 0;
}
}
diff --git a/player/video.c b/player/video.c
index db33406d63..7e4de2482f 100644
--- a/player/video.c
+++ b/player/video.c
@@ -273,6 +273,7 @@ int reinit_video_chain(struct MPContext *mpctx)
if (!mpctx->video_out) {
MP_FATAL(mpctx, "Error opening/initializing "
"the selected video_out (-vo) device.\n");
+ mpctx->error_playing = MPV_ERROR_VO_INIT_FAILED;
goto err_out;
}
mpctx->mouse_cursor_visible = true;
@@ -766,8 +767,10 @@ void write_video(struct MPContext *mpctx, double endpts)
MP_VERBOSE(mpctx, "VO: Description: %s\n", info->description);
int vo_r = vo_reconfig(vo, &p, 0);
- if (vo_r < 0)
+ if (vo_r < 0) {
+ mpctx->error_playing = MPV_ERROR_VO_INIT_FAILED;
goto error;
+ }
init_vo(mpctx);
mpctx->time_frame = 0; // display immediately
}