|
|
@@ -104,6 +104,7 @@ typedef struct VideoPicture { |
|
|
int skip; |
|
|
int skip; |
|
|
SDL_Overlay *bmp; |
|
|
SDL_Overlay *bmp; |
|
|
int width, height; /* source height & width */ |
|
|
int width, height; /* source height & width */ |
|
|
|
|
|
AVRational sample_aspect_ratio; |
|
|
int allocated; |
|
|
int allocated; |
|
|
int reallocate; |
|
|
int reallocate; |
|
|
enum PixelFormat pix_fmt; |
|
|
enum PixelFormat pix_fmt; |
|
|
@@ -233,6 +234,11 @@ typedef struct VideoState { |
|
|
int refresh; |
|
|
int refresh; |
|
|
} VideoState; |
|
|
} VideoState; |
|
|
|
|
|
|
|
|
|
|
|
typedef struct AllocEventProps { |
|
|
|
|
|
VideoState *is; |
|
|
|
|
|
AVFrame *frame; |
|
|
|
|
|
} AllocEventProps; |
|
|
|
|
|
|
|
|
static int opt_help(const char *opt, const char *arg); |
|
|
static int opt_help(const char *opt, const char *arg); |
|
|
|
|
|
|
|
|
/* options specified by the user */ |
|
|
/* options specified by the user */ |
|
|
@@ -666,21 +672,11 @@ static void video_image_display(VideoState *is) |
|
|
|
|
|
|
|
|
vp = &is->pictq[is->pictq_rindex]; |
|
|
vp = &is->pictq[is->pictq_rindex]; |
|
|
if (vp->bmp) { |
|
|
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; |
|
|
aspect_ratio = 0; |
|
|
#endif |
|
|
|
|
|
|
|
|
else |
|
|
|
|
|
aspect_ratio = av_q2d(vp->sample_aspect_ratio); |
|
|
|
|
|
|
|
|
if (aspect_ratio <= 0.0) |
|
|
if (aspect_ratio <= 0.0) |
|
|
aspect_ratio = 1.0; |
|
|
aspect_ratio = 1.0; |
|
|
aspect_ratio *= (float)vp->width / (float)vp->height; |
|
|
aspect_ratio *= (float)vp->width / (float)vp->height; |
|
|
@@ -934,6 +930,7 @@ static int video_open(VideoState *is, int force_set_video_mode) |
|
|
{ |
|
|
{ |
|
|
int flags = SDL_HWSURFACE | SDL_ASYNCBLIT | SDL_HWACCEL; |
|
|
int flags = SDL_HWSURFACE | SDL_ASYNCBLIT | SDL_HWACCEL; |
|
|
int w,h; |
|
|
int w,h; |
|
|
|
|
|
VideoPicture *vp = &is->pictq[is->pictq_rindex]; |
|
|
|
|
|
|
|
|
if (is_full_screen) flags |= SDL_FULLSCREEN; |
|
|
if (is_full_screen) flags |= SDL_FULLSCREEN; |
|
|
else flags |= SDL_RESIZABLE; |
|
|
else flags |= SDL_RESIZABLE; |
|
|
@@ -944,15 +941,9 @@ static int video_open(VideoState *is, int force_set_video_mode) |
|
|
} else if (!is_full_screen && screen_width) { |
|
|
} else if (!is_full_screen && screen_width) { |
|
|
w = screen_width; |
|
|
w = screen_width; |
|
|
h = screen_height; |
|
|
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 { |
|
|
} else { |
|
|
w = 640; |
|
|
w = 640; |
|
|
h = 480; |
|
|
h = 480; |
|
|
@@ -1293,9 +1284,10 @@ display: |
|
|
|
|
|
|
|
|
/* allocate a picture (needs to do that in main thread to avoid |
|
|
/* allocate a picture (needs to do that in main thread to avoid |
|
|
potential locking problems */ |
|
|
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; |
|
|
VideoPicture *vp; |
|
|
|
|
|
|
|
|
vp = &is->pictq[is->pictq_windex]; |
|
|
vp = &is->pictq[is->pictq_windex]; |
|
|
@@ -1307,16 +1299,14 @@ static void alloc_picture(void *opaque) |
|
|
if (vp->picref) |
|
|
if (vp->picref) |
|
|
avfilter_unref_buffer(vp->picref); |
|
|
avfilter_unref_buffer(vp->picref); |
|
|
vp->picref = NULL; |
|
|
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 |
|
|
#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, |
|
|
vp->bmp = SDL_CreateYUVOverlay(vp->width, vp->height, |
|
|
SDL_YV12_OVERLAY, |
|
|
SDL_YV12_OVERLAY, |
|
|
screen); |
|
|
screen); |
|
|
@@ -1378,22 +1368,22 @@ static int queue_picture(VideoState *is, AVFrame *src_frame, double pts1, int64_ |
|
|
|
|
|
|
|
|
/* alloc or resize hardware picture buffer */ |
|
|
/* alloc or resize hardware picture buffer */ |
|
|
if (!vp->bmp || vp->reallocate || |
|
|
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; |
|
|
SDL_Event event; |
|
|
|
|
|
AllocEventProps event_props; |
|
|
|
|
|
|
|
|
|
|
|
event_props.frame = src_frame; |
|
|
|
|
|
event_props.is = is; |
|
|
|
|
|
|
|
|
vp->allocated = 0; |
|
|
vp->allocated = 0; |
|
|
vp->reallocate = 0; |
|
|
vp->reallocate = 0; |
|
|
|
|
|
|
|
|
/* the allocation must be done in the main thread to avoid |
|
|
/* 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.type = FF_ALLOC_EVENT; |
|
|
event.user.data1 = is; |
|
|
|
|
|
|
|
|
event.user.data1 = &event_props; |
|
|
SDL_PushEvent(&event); |
|
|
SDL_PushEvent(&event); |
|
|
|
|
|
|
|
|
/* wait until the picture is allocated */ |
|
|
/* wait until the picture is allocated */ |
|
|
@@ -1437,6 +1427,7 @@ static int queue_picture(VideoState *is, AVFrame *src_frame, double pts1, int64_ |
|
|
// FIXME use direct rendering |
|
|
// FIXME use direct rendering |
|
|
av_picture_copy(&pict, (AVPicture *)src_frame, |
|
|
av_picture_copy(&pict, (AVPicture *)src_frame, |
|
|
vp->pix_fmt, vp->width, vp->height); |
|
|
vp->pix_fmt, vp->width, vp->height); |
|
|
|
|
|
vp->sample_aspect_ratio = vp->picref->video->sample_aspect_ratio; |
|
|
#else |
|
|
#else |
|
|
sws_flags = av_get_int(sws_opts, "sws_flags", NULL); |
|
|
sws_flags = av_get_int(sws_opts, "sws_flags", NULL); |
|
|
is->img_convert_ctx = sws_getCachedContext(is->img_convert_ctx, |
|
|
is->img_convert_ctx = sws_getCachedContext(is->img_convert_ctx, |
|
|
@@ -1448,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, |
|
|
sws_scale(is->img_convert_ctx, src_frame->data, src_frame->linesize, |
|
|
0, vp->height, pict.data, pict.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 |
|
|
#endif |
|
|
/* update the bitmap content */ |
|
|
/* update the bitmap content */ |
|
|
SDL_UnlockYUVOverlay(vp->bmp); |
|
|
SDL_UnlockYUVOverlay(vp->bmp); |
|
|
@@ -1688,6 +1680,7 @@ static int input_request_frame(AVFilterLink *link) |
|
|
av_free_packet(&pkt); |
|
|
av_free_packet(&pkt); |
|
|
|
|
|
|
|
|
avfilter_copy_frame_props(picref, priv->frame); |
|
|
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; |
|
|
picref->pts = pts; |
|
|
|
|
|
|
|
|
avfilter_start_frame(link, picref); |
|
|
avfilter_start_frame(link, picref); |
|
|
@@ -1872,6 +1865,8 @@ static int video_thread(void *arg) |
|
|
ret = get_video_frame(is, frame, &pts_int, &pkt); |
|
|
ret = get_video_frame(is, frame, &pts_int, &pkt); |
|
|
pos = pkt.pos; |
|
|
pos = pkt.pos; |
|
|
av_free_packet(&pkt); |
|
|
av_free_packet(&pkt); |
|
|
|
|
|
if (ret == 0) |
|
|
|
|
|
continue; |
|
|
#endif |
|
|
#endif |
|
|
|
|
|
|
|
|
if (ret < 0) |
|
|
if (ret < 0) |
|
|
@@ -2969,7 +2964,6 @@ static void event_loop(VideoState *cur_stream) |
|
|
do_exit(cur_stream); |
|
|
do_exit(cur_stream); |
|
|
break; |
|
|
break; |
|
|
case FF_ALLOC_EVENT: |
|
|
case FF_ALLOC_EVENT: |
|
|
video_open(event.user.data1, 0); |
|
|
|
|
|
alloc_picture(event.user.data1); |
|
|
alloc_picture(event.user.data1); |
|
|
break; |
|
|
break; |
|
|
case FF_REFRESH_EVENT: |
|
|
case FF_REFRESH_EVENT: |
|
|
|