From 89080a0a5ef6913f47265eabddfb99520f5a5e7f Mon Sep 17 00:00:00 2001 From: Marton Balint Date: Sun, 22 Apr 2012 02:53:29 +0200 Subject: [PATCH 1/4] ffplay: fix video_thread when no frame is returned in get_video_frame Affects only ffplay build with avfilter disabled. Signed-off-by: Marton Balint --- ffplay.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ffplay.c b/ffplay.c index 3c5ef681c5..a9d710e4c5 100644 --- a/ffplay.c +++ b/ffplay.c @@ -1872,6 +1872,8 @@ static int video_thread(void *arg) ret = get_video_frame(is, frame, &pts_int, &pkt); pos = pkt.pos; av_free_packet(&pkt); + if (ret == 0) + continue; #endif if (ret < 0) From 84087b243e825327a17bb0514c249f29b829a5b2 Mon Sep 17 00:00:00 2001 From: Marton Balint Date: Sat, 21 Apr 2012 13:06:55 +0200 Subject: [PATCH 2/4] ffplay: use stream sample_aspect_ratio if available in source frames When we are using filter chains we have to set the aspect ratio of the source to the best known value, we use the av_guess_sample_aspect_ratio function to determine that. Fixes ticket 1228. Signed-off-by: Marton Balint --- ffplay.c | 1 + 1 file changed, 1 insertion(+) diff --git a/ffplay.c b/ffplay.c index a9d710e4c5..ef196c2a2a 100644 --- a/ffplay.c +++ b/ffplay.c @@ -1688,6 +1688,7 @@ static int input_request_frame(AVFilterLink *link) av_free_packet(&pkt); avfilter_copy_frame_props(picref, priv->frame); + picref->video->sample_aspect_ratio = av_guess_sample_aspect_ratio(priv->is->ic, priv->is->video_st, priv->frame); picref->pts = pts; avfilter_start_frame(link, picref); From 843509e2648cf117b4cded70ecc8bfd110a143c1 Mon Sep 17 00:00:00 2001 From: Marton Balint Date: Sun, 22 Apr 2012 00:17:54 +0200 Subject: [PATCH 3/4] ffplay: use AVFrame::width and height instead of using codec or filter settings Codec values may not reflect the actual frame size, and it also enables us to simplify code in the avfilter enabled and the avfilter disabled case. Signed-off-by: Marton Balint --- ffplay.c | 56 +++++++++++++++++++++++++++----------------------------- 1 file changed, 27 insertions(+), 29 deletions(-) diff --git a/ffplay.c b/ffplay.c index ef196c2a2a..962c7b2cc2 100644 --- a/ffplay.c +++ b/ffplay.c @@ -233,6 +233,11 @@ typedef struct VideoState { int refresh; } VideoState; +typedef struct AllocEventProps { + VideoState *is; + AVFrame *frame; +} AllocEventProps; + static int opt_help(const char *opt, const char *arg); /* options specified by the user */ @@ -934,6 +939,7 @@ static int video_open(VideoState *is, int force_set_video_mode) { int flags = SDL_HWSURFACE | SDL_ASYNCBLIT | SDL_HWACCEL; int w,h; + VideoPicture *vp = &is->pictq[is->pictq_rindex]; if (is_full_screen) flags |= SDL_FULLSCREEN; else flags |= SDL_RESIZABLE; @@ -944,15 +950,9 @@ static int video_open(VideoState *is, int force_set_video_mode) } else if (!is_full_screen && screen_width) { w = screen_width; h = screen_height; -#if CONFIG_AVFILTER - } else if (is->out_video_filter && is->out_video_filter->inputs[0]) { - w = is->out_video_filter->inputs[0]->w; - h = is->out_video_filter->inputs[0]->h; -#else - } else if (is->video_st && is->video_st->codec->width) { - w = is->video_st->codec->width; - h = is->video_st->codec->height; -#endif + } else if (vp->width) { + w = vp->width; + h = vp->height; } else { w = 640; h = 480; @@ -1293,9 +1293,10 @@ display: /* allocate a picture (needs to do that in main thread to avoid potential locking problems */ -static void alloc_picture(void *opaque) +static void alloc_picture(AllocEventProps *event_props) { - VideoState *is = opaque; + VideoState *is = event_props->is; + AVFrame *frame = event_props->frame; VideoPicture *vp; vp = &is->pictq[is->pictq_windex]; @@ -1307,16 +1308,14 @@ static void alloc_picture(void *opaque) if (vp->picref) avfilter_unref_buffer(vp->picref); vp->picref = NULL; - - vp->width = is->out_video_filter->inputs[0]->w; - vp->height = is->out_video_filter->inputs[0]->h; - vp->pix_fmt = is->out_video_filter->inputs[0]->format; -#else - vp->width = is->video_st->codec->width; - vp->height = is->video_st->codec->height; - vp->pix_fmt = is->video_st->codec->pix_fmt; #endif + vp->width = frame->width; + vp->height = frame->height; + vp->pix_fmt = frame->format; + + video_open(event_props->is, 0); + vp->bmp = SDL_CreateYUVOverlay(vp->width, vp->height, SDL_YV12_OVERLAY, screen); @@ -1378,22 +1377,22 @@ static int queue_picture(VideoState *is, AVFrame *src_frame, double pts1, int64_ /* alloc or resize hardware picture buffer */ if (!vp->bmp || vp->reallocate || -#if CONFIG_AVFILTER - vp->width != is->out_video_filter->inputs[0]->w || - vp->height != is->out_video_filter->inputs[0]->h) { -#else - vp->width != is->video_st->codec->width || - vp->height != is->video_st->codec->height) { -#endif + vp->width != src_frame->width || + vp->height != src_frame->height) { SDL_Event event; + AllocEventProps event_props; + + event_props.frame = src_frame; + event_props.is = is; vp->allocated = 0; vp->reallocate = 0; /* the allocation must be done in the main thread to avoid - locking problems */ + locking problems. We wait in this block for the event to complete, + so we can pass a pointer to event_props to it. */ event.type = FF_ALLOC_EVENT; - event.user.data1 = is; + event.user.data1 = &event_props; SDL_PushEvent(&event); /* wait until the picture is allocated */ @@ -2972,7 +2971,6 @@ static void event_loop(VideoState *cur_stream) do_exit(cur_stream); break; case FF_ALLOC_EVENT: - video_open(event.user.data1, 0); alloc_picture(event.user.data1); break; case FF_REFRESH_EVENT: From 825ec16da955fd9c726d8e6c846cf9257a781a87 Mon Sep 17 00:00:00 2001 From: Marton Balint Date: Sat, 28 Apr 2012 23:39:43 +0200 Subject: [PATCH 4/4] ffplay: put aspect ratio info to the VideoPicture struct Also use av_guess_sample_aspect_ratio for determining aspect ratio of the video frame if not using avfilter. Signed-off-by: Marton Balint --- ffplay.c | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/ffplay.c b/ffplay.c index 962c7b2cc2..04386e1f44 100644 --- a/ffplay.c +++ b/ffplay.c @@ -104,6 +104,7 @@ typedef struct VideoPicture { int skip; SDL_Overlay *bmp; int width, height; /* source height & width */ + AVRational sample_aspect_ratio; int allocated; int reallocate; enum PixelFormat pix_fmt; @@ -671,21 +672,11 @@ static void video_image_display(VideoState *is) vp = &is->pictq[is->pictq_rindex]; if (vp->bmp) { -#if CONFIG_AVFILTER - if (vp->picref->video->sample_aspect_ratio.num == 0) - aspect_ratio = 0; - else - aspect_ratio = av_q2d(vp->picref->video->sample_aspect_ratio); -#else - - /* XXX: use variable in the frame */ - if (is->video_st->sample_aspect_ratio.num) - aspect_ratio = av_q2d(is->video_st->sample_aspect_ratio); - else if (is->video_st->codec->sample_aspect_ratio.num) - aspect_ratio = av_q2d(is->video_st->codec->sample_aspect_ratio); - else + if (vp->sample_aspect_ratio.num == 0) aspect_ratio = 0; -#endif + else + aspect_ratio = av_q2d(vp->sample_aspect_ratio); + if (aspect_ratio <= 0.0) aspect_ratio = 1.0; aspect_ratio *= (float)vp->width / (float)vp->height; @@ -1436,6 +1427,7 @@ static int queue_picture(VideoState *is, AVFrame *src_frame, double pts1, int64_ // FIXME use direct rendering av_picture_copy(&pict, (AVPicture *)src_frame, vp->pix_fmt, vp->width, vp->height); + vp->sample_aspect_ratio = vp->picref->video->sample_aspect_ratio; #else sws_flags = av_get_int(sws_opts, "sws_flags", NULL); is->img_convert_ctx = sws_getCachedContext(is->img_convert_ctx, @@ -1447,6 +1439,7 @@ static int queue_picture(VideoState *is, AVFrame *src_frame, double pts1, int64_ } sws_scale(is->img_convert_ctx, src_frame->data, src_frame->linesize, 0, vp->height, pict.data, pict.linesize); + vp->sample_aspect_ratio = av_guess_sample_aspect_ratio(is->ic, is->video_st, src_frame); #endif /* update the bitmap content */ SDL_UnlockYUVOverlay(vp->bmp);