From f22f9005943246613039d0e907b71b34afabedce Mon Sep 17 00:00:00 2001 From: Luca Barbato Date: Sat, 2 Jan 2016 12:19:27 +0100 Subject: avplay: Move the stream setup in the main thread And refactor the code in preparation of the following patches. Signed-off-by: Luca Barbato --- avplay.c | 65 +++++++++++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 44 insertions(+), 21 deletions(-) diff --git a/avplay.c b/avplay.c index 56ec731..0de5b93 100644 --- a/avplay.c +++ b/avplay.c @@ -1204,7 +1204,7 @@ retry: } } -static void stream_close(VideoState *is) +static void player_close(VideoState *is) { VideoPicture *vp; int i; @@ -1235,7 +1235,7 @@ static void stream_close(VideoState *is) static void do_exit(void) { if (cur_stream) { - stream_close(cur_stream); + player_close(cur_stream); cur_stream = NULL; } uninit_opts(); @@ -2256,16 +2256,28 @@ static int decode_interrupt_cb(void *ctx) return global_video_state && global_video_state->abort_request; } -/* this thread gets the stream from the disk or the network */ -static int decode_thread(void *arg) +static void stream_close(VideoState *is) +{ + /* disable interrupting */ + global_video_state = 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); + if (is->ic) { + avformat_close_input(&is->ic); + } +} + +static int stream_setup(VideoState *is) { - 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; @@ -2385,6 +2397,23 @@ static int decode_thread(void *arg) goto fail; } + return 0; + +fail: + stream_close(is); + + return ret; +} + +/* this thread gets the stream from the disk or the network */ +static int decode_thread(void *arg) +{ + VideoState *is = arg; + AVPacket pkt1, *pkt = &pkt1; + AVFormatContext *ic = is->ic; + int pkt_in_play_range = 0; + int ret, eof = 0; + for (;;) { if (is->abort_request) break; @@ -2499,20 +2528,9 @@ static int decode_thread(void *arg) } ret = 0; - fail: - /* disable interrupting */ - global_video_state = 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); - if (is->ic) { - avformat_close_input(&is->ic); - } +fail: + stream_close(is); if (ret != 0) { SDL_Event event; @@ -2536,6 +2554,11 @@ static VideoState *stream_open(const char *filename, AVInputFormat *iformat) is->ytop = 0; is->xleft = 0; + if (stream_setup(is) < 0) { + av_free(is); + return NULL; + } + /* start video display */ is->pictq_mutex = SDL_CreateMutex(); is->pictq_cond = SDL_CreateCond(); -- cgit v1.1 From fdd464cb7045298852072b1efa6b6ac04c23fb33 Mon Sep 17 00:00:00 2001 From: Luca Barbato Date: Sat, 2 Jan 2016 12:19:28 +0100 Subject: avplay: Allocate the refresh thread next to the decode thread It does not belong to the stream setup. Signed-off-by: Luca Barbato --- avplay.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/avplay.c b/avplay.c index 0de5b93..0a079c8 100644 --- a/avplay.c +++ b/avplay.c @@ -2381,7 +2381,6 @@ static int stream_setup(VideoState *is) if (st_index[AVMEDIA_TYPE_VIDEO] >= 0) { ret = stream_component_open(is, st_index[AVMEDIA_TYPE_VIDEO]); } - is->refresh_tid = SDL_CreateThread(refresh_thread, is); if (ret < 0) { if (!display_disable) is->show_audio = 2; @@ -2567,6 +2566,7 @@ static VideoState *stream_open(const char *filename, AVInputFormat *iformat) is->subpq_cond = SDL_CreateCond(); is->av_sync_type = av_sync_type; + is->refresh_tid = SDL_CreateThread(refresh_thread, is); is->parse_tid = SDL_CreateThread(decode_thread, is); if (!is->parse_tid) { av_free(is); -- cgit v1.1 From 21bbc345ccb644f05c7c9fd4c9b356a91652f105 Mon Sep 17 00:00:00 2001 From: Luca Barbato Date: Sat, 2 Jan 2016 12:19:29 +0100 Subject: avplay: Rename VideoState to PlayerState The structure is not video-specific. Signed-off-by: Luca Barbato --- avplay.c | 80 ++++++++++++++++++++++++++++++++-------------------------------- 1 file changed, 40 insertions(+), 40 deletions(-) diff --git a/avplay.c b/avplay.c index 0a079c8..7a7c108 100644 --- a/avplay.c +++ b/avplay.c @@ -124,7 +124,7 @@ enum { AV_SYNC_EXTERNAL_CLOCK, /* synchronize to an external clock */ }; -typedef struct VideoState { +typedef struct PlayerState { SDL_Thread *parse_tid; SDL_Thread *video_tid; SDL_Thread *refresh_tid; @@ -222,7 +222,7 @@ typedef struct VideoState { float skip_frames; float skip_frames_index; int refresh; -} VideoState; +} PlayerState; /* options specified by the user */ static AVInputFormat *file_iformat; @@ -270,7 +270,7 @@ static int autorotate = 1; /* current context */ static int is_full_screen; -static VideoState *cur_stream; +static PlayerState *cur_stream; static int64_t audio_callback_time; static AVPacket flush_pkt; @@ -638,7 +638,7 @@ static void free_subpicture(SubPicture *sp) avsubtitle_free(&sp->sub); } -static void video_image_display(VideoState *is) +static void video_image_display(PlayerState *is) { VideoPicture *vp; SubPicture *sp; @@ -708,7 +708,7 @@ static void video_image_display(VideoState *is) /* get the current audio output buffer size, in samples. With SDL, we cannot have a precise information */ -static int audio_write_get_buf_size(VideoState *is) +static int audio_write_get_buf_size(PlayerState *is) { return is->audio_buf_size - is->audio_buf_index; } @@ -722,7 +722,7 @@ static inline int compute_mod(int a, int b) return a + b; } -static void video_audio_display(VideoState *s) +static void video_audio_display(PlayerState *s) { int i, i_start, x, y1, y, ys, delay, n, nb_display_channels; int ch, channels, h, h2, bgcolor, fgcolor; @@ -862,7 +862,7 @@ static void video_audio_display(VideoState *s) } } -static int video_open(VideoState *is) +static int video_open(PlayerState *is) { int flags = SDL_HWSURFACE | SDL_ASYNCBLIT | SDL_HWACCEL; int w,h; @@ -914,7 +914,7 @@ static int video_open(VideoState *is) } /* display the current picture, if any */ -static void video_display(VideoState *is) +static void video_display(PlayerState *is) { if (!screen) video_open(cur_stream); @@ -926,7 +926,7 @@ static void video_display(VideoState *is) static int refresh_thread(void *opaque) { - VideoState *is= opaque; + PlayerState *is= opaque; while (!is->abort_request) { SDL_Event event; event.type = FF_REFRESH_EVENT; @@ -941,7 +941,7 @@ static int refresh_thread(void *opaque) } /* get the current audio clock value */ -static double get_audio_clock(VideoState *is) +static double get_audio_clock(PlayerState *is) { double pts; int hw_buf_size, bytes_per_sec; @@ -958,7 +958,7 @@ static double get_audio_clock(VideoState *is) } /* get the current video clock value */ -static double get_video_clock(VideoState *is) +static double get_video_clock(PlayerState *is) { if (is->paused) { return is->video_current_pts; @@ -968,7 +968,7 @@ static double get_video_clock(VideoState *is) } /* get the current external clock value */ -static double get_external_clock(VideoState *is) +static double get_external_clock(PlayerState *is) { int64_t ti; ti = av_gettime_relative(); @@ -976,7 +976,7 @@ static double get_external_clock(VideoState *is) } /* get the current master clock value */ -static double get_master_clock(VideoState *is) +static double get_master_clock(PlayerState *is) { double val; @@ -997,7 +997,7 @@ static double get_master_clock(VideoState *is) } /* seek in the stream */ -static void stream_seek(VideoState *is, int64_t pos, int64_t rel, int seek_by_bytes) +static void stream_seek(PlayerState *is, int64_t pos, int64_t rel, int seek_by_bytes) { if (!is->seek_req) { is->seek_pos = pos; @@ -1010,7 +1010,7 @@ static void stream_seek(VideoState *is, int64_t pos, int64_t rel, int seek_by_by } /* pause or resume the video */ -static void stream_pause(VideoState *is) +static void stream_pause(PlayerState *is) { if (is->paused) { is->frame_timer += av_gettime_relative() / 1000000.0 + is->video_current_pts_drift - is->video_current_pts; @@ -1022,7 +1022,7 @@ static void stream_pause(VideoState *is) is->paused = !is->paused; } -static double compute_target_time(double frame_current_pts, VideoState *is) +static double compute_target_time(double frame_current_pts, PlayerState *is) { double delay, sync_threshold, diff = 0; @@ -1065,7 +1065,7 @@ static double compute_target_time(double frame_current_pts, VideoState *is) /* called to display each frame */ static void video_refresh_timer(void *opaque) { - VideoState *is = opaque; + PlayerState *is = opaque; VideoPicture *vp; SubPicture *sp, *sp2; @@ -1204,7 +1204,7 @@ retry: } } -static void player_close(VideoState *is) +static void player_close(PlayerState *is) { VideoPicture *vp; int i; @@ -1251,7 +1251,7 @@ static void do_exit(void) potential locking problems */ static void alloc_picture(void *opaque) { - VideoState *is = opaque; + PlayerState *is = opaque; VideoPicture *vp; vp = &is->pictq[is->pictq_windex]; @@ -1289,7 +1289,7 @@ static void alloc_picture(void *opaque) /* The 'pts' parameter is the dts of the packet / pts of the frame and * guessed if not known. */ -static int queue_picture(VideoState *is, AVFrame *src_frame, double pts, int64_t pos) +static int queue_picture(PlayerState *is, AVFrame *src_frame, double pts, int64_t pos) { VideoPicture *vp; #if !CONFIG_AVFILTER @@ -1397,7 +1397,7 @@ static int queue_picture(VideoState *is, AVFrame *src_frame, double pts, int64_t /* Compute the exact PTS for the picture if it is omitted in the stream. * The 'pts1' parameter is the dts of the packet / pts of the frame. */ -static int output_picture2(VideoState *is, AVFrame *src_frame, double pts1, int64_t pos) +static int output_picture2(PlayerState *is, AVFrame *src_frame, double pts1, int64_t pos) { double frame_delay, pts; int ret; @@ -1422,7 +1422,7 @@ static int output_picture2(VideoState *is, AVFrame *src_frame, double pts1, int6 return ret; } -static int get_video_frame(VideoState *is, AVFrame *frame, int64_t *pts, AVPacket *pkt) +static int get_video_frame(PlayerState *is, AVFrame *frame, int64_t *pts, AVPacket *pkt) { int got_picture, i; @@ -1481,7 +1481,7 @@ static int get_video_frame(VideoState *is, AVFrame *frame, int64_t *pts, AVPacke } #if CONFIG_AVFILTER -static int configure_video_filters(AVFilterGraph *graph, VideoState *is, const char *vfilters) +static int configure_video_filters(AVFilterGraph *graph, PlayerState *is, const char *vfilters) { char sws_flags_str[128]; char buffersrc_args[256]; @@ -1581,7 +1581,7 @@ static int configure_video_filters(AVFilterGraph *graph, VideoState *is, const c static int video_thread(void *arg) { AVPacket pkt = { 0 }; - VideoState *is = arg; + PlayerState *is = arg; AVFrame *frame = av_frame_alloc(); int64_t pts_int; double pts; @@ -1691,7 +1691,7 @@ static int video_thread(void *arg) static int subtitle_thread(void *arg) { - VideoState *is = arg; + PlayerState *is = arg; SubPicture *sp; AVPacket pkt1, *pkt = &pkt1; int got_subtitle; @@ -1759,7 +1759,7 @@ static int subtitle_thread(void *arg) } /* copy samples for viewing in editor window */ -static void update_sample_display(VideoState *is, short *samples, int samples_size) +static void update_sample_display(PlayerState *is, short *samples, int samples_size) { int size, len; @@ -1779,7 +1779,7 @@ static void update_sample_display(VideoState *is, short *samples, int samples_si /* return the new audio buffer size (samples can be added or deleted to get better sync if video or external master clock) */ -static int synchronize_audio(VideoState *is, short *samples, +static int synchronize_audio(PlayerState *is, short *samples, int samples_size1, double pts) { int n, samples_size; @@ -1853,7 +1853,7 @@ static int synchronize_audio(VideoState *is, short *samples, } /* decode one audio frame and returns its uncompressed size */ -static int audio_decode_frame(VideoState *is, double *pts_ptr) +static int audio_decode_frame(PlayerState *is, double *pts_ptr) { AVPacket *pkt_temp = &is->audio_pkt_temp; AVPacket *pkt = &is->audio_pkt; @@ -2012,7 +2012,7 @@ static int audio_decode_frame(VideoState *is, double *pts_ptr) /* prepare a new audio buffer */ static void sdl_audio_callback(void *opaque, Uint8 *stream, int len) { - VideoState *is = opaque; + PlayerState *is = opaque; int audio_size, len1; double pts; @@ -2045,7 +2045,7 @@ static void sdl_audio_callback(void *opaque, Uint8 *stream, int len) } /* open a given stream. Return 0 if OK */ -static int stream_component_open(VideoState *is, int stream_index) +static int stream_component_open(PlayerState *is, int stream_index) { AVFormatContext *ic = is->ic; AVCodecContext *avctx; @@ -2165,7 +2165,7 @@ fail: return ret; } -static void stream_component_close(VideoState *is, int stream_index) +static void stream_component_close(PlayerState *is, int stream_index) { AVFormatContext *ic = is->ic; AVCodecContext *avctx; @@ -2249,14 +2249,14 @@ static void stream_component_close(VideoState *is, int stream_index) /* since we have only one decoding thread, we can use a global variable instead of a thread local variable */ -static VideoState *global_video_state; +static PlayerState *global_video_state; static int decode_interrupt_cb(void *ctx) { return global_video_state && global_video_state->abort_request; } -static void stream_close(VideoState *is) +static void stream_close(PlayerState *is) { /* disable interrupting */ global_video_state = NULL; @@ -2273,7 +2273,7 @@ static void stream_close(VideoState *is) } } -static int stream_setup(VideoState *is) +static int stream_setup(PlayerState *is) { AVFormatContext *ic = NULL; int err, i, ret; @@ -2407,7 +2407,7 @@ fail: /* this thread gets the stream from the disk or the network */ static int decode_thread(void *arg) { - VideoState *is = arg; + PlayerState *is = arg; AVPacket pkt1, *pkt = &pkt1; AVFormatContext *ic = is->ic; int pkt_in_play_range = 0; @@ -2541,11 +2541,11 @@ fail: return 0; } -static VideoState *stream_open(const char *filename, AVInputFormat *iformat) +static PlayerState *stream_open(const char *filename, AVInputFormat *iformat) { - VideoState *is; + PlayerState *is; - is = av_mallocz(sizeof(VideoState)); + is = av_mallocz(sizeof(PlayerState)); if (!is) return NULL; av_strlcpy(is->filename, filename, sizeof(is->filename)); @@ -2575,7 +2575,7 @@ static VideoState *stream_open(const char *filename, AVInputFormat *iformat) return is; } -static void stream_cycle_channel(VideoState *is, int codec_type) +static void stream_cycle_channel(PlayerState *is, int codec_type) { AVFormatContext *ic = is->ic; int start_index, stream_index; @@ -2666,7 +2666,7 @@ static void toggle_audio_display(void) } } -static void seek_chapter(VideoState *is, int incr) +static void seek_chapter(PlayerState *is, int incr) { int64_t pos = get_master_clock(is) * AV_TIME_BASE; int i; -- cgit v1.1 From 611ba89b896a5286b6d8ad9bfdbb8b4f5c11df9c Mon Sep 17 00:00:00 2001 From: Luca Barbato Date: Sat, 2 Jan 2016 12:19:30 +0100 Subject: avplay: Rename cur_stream to player The name was misleading. Signed-off-by: Luca Barbato --- avplay.c | 106 +++++++++++++++++++++++++++++++-------------------------------- 1 file changed, 53 insertions(+), 53 deletions(-) diff --git a/avplay.c b/avplay.c index 7a7c108..c4de70a 100644 --- a/avplay.c +++ b/avplay.c @@ -270,7 +270,7 @@ static int autorotate = 1; /* current context */ static int is_full_screen; -static PlayerState *cur_stream; +static PlayerState *player; static int64_t audio_callback_time; static AVPacket flush_pkt; @@ -917,7 +917,7 @@ static int video_open(PlayerState *is) static void video_display(PlayerState *is) { if (!screen) - video_open(cur_stream); + video_open(player); if (is->audio_st && is->show_audio) video_audio_display(is); else if (is->video_st) @@ -1234,9 +1234,9 @@ static void player_close(PlayerState *is) static void do_exit(void) { - if (cur_stream) { - player_close(cur_stream); - cur_stream = NULL; + if (player) { + player_close(player); + player = NULL; } uninit_opts(); avformat_network_deinit(); @@ -1676,8 +1676,8 @@ static int video_thread(void *arg) if (step) - if (cur_stream) - stream_pause(cur_stream); + if (player) + stream_pause(player); } the_end: #if CONFIG_AVFILTER @@ -2488,7 +2488,7 @@ static int decode_thread(void *arg) SDL_Delay(10); if (is->audioq.size + is->videoq.size + is->subtitleq.size == 0) { if (loop != 1 && (!loop || --loop)) { - stream_seek(cur_stream, start_time != AV_NOPTS_VALUE ? start_time : 0, 0, 0); + stream_seek(player, start_time != AV_NOPTS_VALUE ? start_time : 0, 0, 0); } else if (!noautoexit) { ret = AVERROR_EOF; goto fail; @@ -2631,38 +2631,38 @@ static void toggle_full_screen(void) /* OS X needs to empty the picture_queue */ int i; for (i = 0; i < VIDEO_PICTURE_QUEUE_SIZE; i++) - cur_stream->pictq[i].reallocate = 1; + player->pictq[i].reallocate = 1; #endif is_full_screen = !is_full_screen; - video_open(cur_stream); + video_open(player); } static void toggle_pause(void) { - if (cur_stream) - stream_pause(cur_stream); + if (player) + stream_pause(player); step = 0; } static void step_to_next_frame(void) { - if (cur_stream) { + if (player) { /* if the stream is paused unpause it, then step */ - if (cur_stream->paused) - stream_pause(cur_stream); + if (player->paused) + stream_pause(player); } step = 1; } static void toggle_audio_display(void) { - if (cur_stream) { + if (player) { int bgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00); - cur_stream->show_audio = (cur_stream->show_audio + 1) % 3; + player->show_audio = (player->show_audio + 1) % 3; fill_rectangle(screen, - cur_stream->xleft, cur_stream->ytop, cur_stream->width, cur_stream->height, + player->xleft, player->ytop, player->width, player->height, bgcolor); - SDL_UpdateRect(screen, cur_stream->xleft, cur_stream->ytop, cur_stream->width, cur_stream->height); + SDL_UpdateRect(screen, player->xleft, player->ytop, player->width, player->height); } } @@ -2724,25 +2724,25 @@ static void event_loop(void) step_to_next_frame(); break; case SDLK_a: - if (cur_stream) - stream_cycle_channel(cur_stream, AVMEDIA_TYPE_AUDIO); + if (player) + stream_cycle_channel(player, AVMEDIA_TYPE_AUDIO); break; case SDLK_v: - if (cur_stream) - stream_cycle_channel(cur_stream, AVMEDIA_TYPE_VIDEO); + if (player) + stream_cycle_channel(player, AVMEDIA_TYPE_VIDEO); break; case SDLK_t: - if (cur_stream) - stream_cycle_channel(cur_stream, AVMEDIA_TYPE_SUBTITLE); + if (player) + stream_cycle_channel(player, AVMEDIA_TYPE_SUBTITLE); break; case SDLK_w: toggle_audio_display(); break; case SDLK_PAGEUP: - seek_chapter(cur_stream, 1); + seek_chapter(player, 1); break; case SDLK_PAGEDOWN: - seek_chapter(cur_stream, -1); + seek_chapter(player, -1); break; case SDLK_LEFT: incr = -10.0; @@ -2756,24 +2756,24 @@ static void event_loop(void) case SDLK_DOWN: incr = -60.0; do_seek: - if (cur_stream) { + if (player) { if (seek_by_bytes) { - if (cur_stream->video_stream >= 0 && cur_stream->video_current_pos >= 0) { - pos = cur_stream->video_current_pos; - } else if (cur_stream->audio_stream >= 0 && cur_stream->audio_pkt.pos >= 0) { - pos = cur_stream->audio_pkt.pos; + if (player->video_stream >= 0 && player->video_current_pos >= 0) { + pos = player->video_current_pos; + } else if (player->audio_stream >= 0 && player->audio_pkt.pos >= 0) { + pos = player->audio_pkt.pos; } else - pos = avio_tell(cur_stream->ic->pb); - if (cur_stream->ic->bit_rate) - incr *= cur_stream->ic->bit_rate / 8.0; + pos = avio_tell(player->ic->pb); + if (player->ic->bit_rate) + incr *= player->ic->bit_rate / 8.0; else incr *= 180000.0; pos += incr; - stream_seek(cur_stream, pos, incr, 1); + stream_seek(player, pos, incr, 1); } else { - pos = get_master_clock(cur_stream); + pos = get_master_clock(player); pos += incr; - stream_seek(cur_stream, (int64_t)(pos * AV_TIME_BASE), (int64_t)(incr * AV_TIME_BASE), 0); + stream_seek(player, (int64_t)(pos * AV_TIME_BASE), (int64_t)(incr * AV_TIME_BASE), 0); } } break; @@ -2794,38 +2794,38 @@ static void event_loop(void) break; x = event.motion.x; } - if (cur_stream) { - if (seek_by_bytes || cur_stream->ic->duration <= 0) { - uint64_t size = avio_size(cur_stream->ic->pb); - stream_seek(cur_stream, size*x/cur_stream->width, 0, 1); + if (player) { + if (seek_by_bytes || player->ic->duration <= 0) { + uint64_t size = avio_size(player->ic->pb); + stream_seek(player, size*x/player->width, 0, 1); } else { int64_t ts; int ns, hh, mm, ss; int tns, thh, tmm, tss; - tns = cur_stream->ic->duration / 1000000LL; + tns = player->ic->duration / 1000000LL; thh = tns / 3600; tmm = (tns % 3600) / 60; tss = (tns % 60); - frac = x / cur_stream->width; + frac = x / player->width; ns = frac * tns; hh = ns / 3600; mm = (ns % 3600) / 60; ss = (ns % 60); fprintf(stderr, "Seek to %2.0f%% (%2d:%02d:%02d) of total duration (%2d:%02d:%02d) \n", frac*100, hh, mm, ss, thh, tmm, tss); - ts = frac * cur_stream->ic->duration; - if (cur_stream->ic->start_time != AV_NOPTS_VALUE) - ts += cur_stream->ic->start_time; - stream_seek(cur_stream, ts, 0, 0); + ts = frac * player->ic->duration; + if (player->ic->start_time != AV_NOPTS_VALUE) + ts += player->ic->start_time; + stream_seek(player, ts, 0, 0); } } break; case SDL_VIDEORESIZE: - if (cur_stream) { + if (player) { screen = SDL_SetVideoMode(event.resize.w, event.resize.h, 0, SDL_HWSURFACE|SDL_RESIZABLE|SDL_ASYNCBLIT|SDL_HWACCEL); - screen_width = cur_stream->width = event.resize.w; - screen_height = cur_stream->height = event.resize.h; + screen_width = player->width = event.resize.w; + screen_height = player->height = event.resize.h; } break; case SDL_QUIT: @@ -2838,7 +2838,7 @@ static void event_loop(void) break; case FF_REFRESH_EVENT: video_refresh_timer(event.user.data1); - cur_stream->refresh = 0; + player->refresh = 0; break; default: break; @@ -3057,7 +3057,7 @@ int main(int argc, char **argv) av_init_packet(&flush_pkt); flush_pkt.data = (uint8_t *)&flush_pkt; - cur_stream = stream_open(input_filename, file_iformat); + player = stream_open(input_filename, file_iformat); event_loop(); -- cgit v1.1 From 6fa464f8d29b7f295bc93704d6ebca84571cc8e5 Mon Sep 17 00:00:00 2001 From: Luca Barbato Date: Sat, 2 Jan 2016 12:19:31 +0100 Subject: avplay: Statically allocate the player state And move the resource deallocation in stream_open failure path. Signed-off-by: Luca Barbato --- avplay.c | 35 +++++++++++++++++------------------ 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/avplay.c b/avplay.c index c4de70a..c7e3b4d 100644 --- a/avplay.c +++ b/avplay.c @@ -270,7 +270,8 @@ static int autorotate = 1; /* current context */ static int is_full_screen; -static PlayerState *player; +static PlayerState player_state; +static PlayerState *player = &player_state; static int64_t audio_callback_time; static AVPacket flush_pkt; @@ -1229,7 +1230,6 @@ static void player_close(PlayerState *is) if (is->img_convert_ctx) sws_freeContext(is->img_convert_ctx); #endif - av_free(is); } static void do_exit(void) @@ -2399,8 +2399,6 @@ static int stream_setup(PlayerState *is) return 0; fail: - stream_close(is); - return ret; } @@ -2541,21 +2539,18 @@ fail: return 0; } -static PlayerState *stream_open(const char *filename, AVInputFormat *iformat) +static int stream_open(PlayerState *is, + const char *filename, AVInputFormat *iformat) { - PlayerState *is; + int ret; - is = av_mallocz(sizeof(PlayerState)); - if (!is) - return NULL; av_strlcpy(is->filename, filename, sizeof(is->filename)); is->iformat = iformat; is->ytop = 0; is->xleft = 0; - if (stream_setup(is) < 0) { - av_free(is); - return NULL; + if ((ret = stream_setup(is)) < 0) { + return ret; } /* start video display */ @@ -2567,12 +2562,12 @@ static PlayerState *stream_open(const char *filename, AVInputFormat *iformat) is->av_sync_type = av_sync_type; is->refresh_tid = SDL_CreateThread(refresh_thread, is); + if (!is->refresh_tid) + return -1; is->parse_tid = SDL_CreateThread(decode_thread, is); - if (!is->parse_tid) { - av_free(is); - return NULL; - } - return is; + if (!is->parse_tid) + return -1; + return 0; } static void stream_cycle_channel(PlayerState *is, int codec_type) @@ -3057,7 +3052,11 @@ int main(int argc, char **argv) av_init_packet(&flush_pkt); flush_pkt.data = (uint8_t *)&flush_pkt; - player = stream_open(input_filename, file_iformat); + if (stream_open(player, input_filename, file_iformat) < 0) { + fprintf(stderr, "Could not setup the player\n"); + stream_close(player); + exit(1); + } event_loop(); -- cgit v1.1 From eef9f06508354d1c7d5624c1c18997e7974288f1 Mon Sep 17 00:00:00 2001 From: Luca Barbato Date: Sat, 2 Jan 2016 12:19:32 +0100 Subject: avplay: Allow to override the codec Signed-off-by: Luca Barbato --- avplay.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 59 insertions(+), 2 deletions(-) diff --git a/avplay.c b/avplay.c index c7e3b4d..5af7f01 100644 --- a/avplay.c +++ b/avplay.c @@ -222,6 +222,9 @@ typedef struct PlayerState { float skip_frames; float skip_frames_index; int refresh; + + SpecifierOpt *codec_names; + int nb_codec_names; } PlayerState; /* options specified by the user */ @@ -2044,6 +2047,52 @@ static void sdl_audio_callback(void *opaque, Uint8 *stream, int len) } } +static AVCodec *find_codec_or_die(const char *name, enum AVMediaType type) +{ + const AVCodecDescriptor *desc; + AVCodec *codec = avcodec_find_decoder_by_name(name); + + if (!codec && (desc = avcodec_descriptor_get_by_name(name))) { + codec = avcodec_find_decoder(desc->id); + if (codec) + av_log(NULL, AV_LOG_VERBOSE, "Matched decoder '%s' for codec '%s'.\n", + codec->name, desc->name); + } + + if (!codec) { + av_log(NULL, AV_LOG_FATAL, "Unknown decoder '%s'\n", name); + exit_program(1); + } + + if (codec->type != type) { + av_log(NULL, AV_LOG_FATAL, "Invalid decoder type '%s'\n", name); + exit_program(1); + } + + return codec; +} + +static AVCodec *choose_decoder(PlayerState *is, AVFormatContext *ic, AVStream *st) +{ + char *codec_name = NULL; + int i, ret; + + for (i = 0; i < is->nb_codec_names; i++) { + char *spec = is->codec_names[i].specifier; + if ((ret = check_stream_specifier(ic, st, spec)) > 0) + codec_name = is->codec_names[i].u.str; + else if (ret < 0) + exit_program(1); + } + + if (codec_name) { + AVCodec *codec = find_codec_or_die(codec_name, st->codec->codec_type); + st->codec->codec_id = codec->id; + return codec; + } else + return avcodec_find_decoder(st->codec->codec_id); +} + /* open a given stream. Return 0 if OK */ static int stream_component_open(PlayerState *is, int stream_index) { @@ -2061,7 +2110,7 @@ static int stream_component_open(PlayerState *is, int stream_index) opts = filter_codec_opts(codec_opts, avctx->codec_id, ic, ic->streams[stream_index], NULL); - codec = avcodec_find_decoder(avctx->codec_id); + codec = choose_decoder(is, ic, ic->streams[stream_index]); avctx->workaround_bugs = workaround_bugs; avctx->idct_algo = idct; avctx->skip_frame = skip_frame; @@ -2302,6 +2351,7 @@ static int stream_setup(PlayerState *is) 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; @@ -2315,6 +2365,9 @@ static int stream_setup(PlayerState *is) opts = setup_find_stream_info_opts(ic, codec_opts); orig_nb_streams = ic->nb_streams; + for (i = 0; i < ic->nb_streams; i++) + ic->streams[i]->codec->codec = choose_decoder(is, ic, ic->streams[i]); + err = avformat_find_stream_info(ic, opts); for (i = 0; i < orig_nb_streams; i++) @@ -2904,6 +2957,7 @@ static int opt_duration(void *optctx, const char *opt, const char *arg) return 0; } +#define OFF(x) offsetof(PlayerState, x) static const OptionDef options[] = { #include "cmdutils_common_opts.h" { "x", HAS_ARG, { .func_arg = opt_width }, "force displayed width", "width" }, @@ -2946,6 +3000,9 @@ static const OptionDef options[] = { { "default", HAS_ARG | OPT_AUDIO | OPT_VIDEO | OPT_EXPERT, { opt_default }, "generic catch all option", "" }, { "i", 0, { NULL }, "avconv compatibility dummy option", ""}, { "autorotate", OPT_BOOL, { &autorotate }, "automatically rotate video", "" }, + { "c", HAS_ARG | OPT_STRING | OPT_SPEC | OPT_INPUT, { .off = OFF(codec_names) }, "codec name", "codec" }, + { "codec", HAS_ARG | OPT_STRING | OPT_SPEC | OPT_INPUT, { .off = OFF(codec_names) }, "codec name", "codec" }, + { NULL, }, }; @@ -3018,7 +3075,7 @@ int main(int argc, char **argv) show_banner(); - parse_options(NULL, argc, argv, options, opt_input_file); + parse_options(player, argc, argv, options, opt_input_file); if (!input_filename) { show_usage(); -- cgit v1.1