SDL_Overlay *overlay;
char *window_title;
char *icon_title;
- int window_width, window_height;
- int overlay_width, overlay_height;
+ int window_width, window_height; /**< size of the window */
+ int overlay_width, overlay_height; /**< size of the video in the window */
+ int overlay_x, overlay_y;
int overlay_fmt;
int sdl_was_already_inited;
} SDLContext;
SDLContext *sdl = s->priv_data;
AVStream *st = s->streams[0];
AVCodecContext *encctx = st->codec;
- float sar, dar; /* sample and display aspect ratios */
+ AVRational sar, dar; /* sample and display aspect ratios */
int i, ret;
if (!sdl->window_title)
}
/* compute overlay width and height from the codec context information */
- sar = st->sample_aspect_ratio.num ? av_q2d(st->sample_aspect_ratio) : 1;
- dar = sar * (float)encctx->width / (float)encctx->height;
+ sar = st->sample_aspect_ratio.num ? st->sample_aspect_ratio : (AVRational){ 1, 1 };
+ dar = av_mul_q(sar, (AVRational){ encctx->width, encctx->height });
/* we suppose the screen has a 1/1 sample aspect ratio */
- sdl->overlay_height = encctx->height;
- sdl->overlay_width = ((int)rint(sdl->overlay_height * dar));
- if (sdl->overlay_width > encctx->width) {
- sdl->overlay_width = encctx->width;
- sdl->overlay_height = ((int)rint(sdl->overlay_width / dar));
- }
-
- if (!sdl->window_width || !sdl->window_height) {
+ if (sdl->window_width && sdl->window_height) {
+ /* fit in the window */
+ if (av_cmp_q(dar, (AVRational){ sdl->window_width, sdl->window_height }) > 0) {
+ /* fit in width */
+ sdl->overlay_width = sdl->window_width;
+ sdl->overlay_height = av_rescale(sdl->overlay_width, dar.den, dar.num);
+ } else {
+ /* fit in height */
+ sdl->overlay_height = sdl->window_height;
+ sdl->overlay_width = av_rescale(sdl->overlay_height, dar.num, dar.den);
+ }
+ } else {
+ if (sar.num > sar.den) {
+ sdl->overlay_width = encctx->width;
+ sdl->overlay_height = av_rescale(sdl->overlay_width, dar.den, dar.num);
+ } else {
+ sdl->overlay_height = encctx->height;
+ sdl->overlay_width = av_rescale(sdl->overlay_height, dar.num, dar.den);
+ }
sdl->window_width = sdl->overlay_width;
sdl->window_height = sdl->overlay_height;
}
+ sdl->overlay_x = (sdl->window_width - sdl->overlay_width ) / 2;
+ sdl->overlay_y = (sdl->window_height - sdl->overlay_height) / 2;
SDL_WM_SetCaption(sdl->window_title, sdl->icon_title);
sdl->surface = SDL_SetVideoMode(sdl->window_width, sdl->window_height,
goto fail;
}
- sdl->overlay = SDL_CreateYUVOverlay(sdl->overlay_width, sdl->overlay_height,
+ sdl->overlay = SDL_CreateYUVOverlay(encctx->width, encctx->height,
sdl->overlay_fmt, sdl->surface);
- if (!sdl->overlay || sdl->overlay->pitches[0] < sdl->overlay_width) {
+ if (!sdl->overlay || sdl->overlay->pitches[0] < encctx->width) {
av_log(s, AV_LOG_ERROR,
"SDL does not support an overlay with size of %dx%d pixels.\n",
- sdl->overlay_width, sdl->overlay_height);
+ encctx->width, encctx->height);
ret = AVERROR(EINVAL);
goto fail;
}
- av_log(s, AV_LOG_INFO, "w:%d h:%d fmt:%s sar:%f -> w:%d h:%d\n",
- encctx->width, encctx->height, av_get_pix_fmt_name(encctx->pix_fmt), sar,
- sdl->window_width, sdl->window_height);
+ av_log(s, AV_LOG_INFO, "w:%d h:%d fmt:%s sar:%d/%d -> w:%d h:%d\n",
+ encctx->width, encctx->height, av_get_pix_fmt_name(encctx->pix_fmt), sar.num, sar.den,
+ sdl->overlay_width, sdl->overlay_height);
return 0;
fail:
{
SDLContext *sdl = s->priv_data;
AVCodecContext *encctx = s->streams[0]->codec;
- SDL_Rect rect = { 0, 0, sdl->window_width, sdl->window_height };
+ SDL_Rect rect = { sdl->overlay_x, sdl->overlay_y, sdl->overlay_width, sdl->overlay_height };
AVPicture pict;
int i;
SDL_DisplayYUVOverlay(sdl->overlay, &rect);
SDL_UnlockYUVOverlay(sdl->overlay);
- SDL_UpdateRect(sdl->surface, 0, 0, sdl->overlay_width, sdl->overlay_height);
+ SDL_UpdateRect(sdl->surface, rect.x, rect.y, rect.w, rect.h);
return 0;
}
.write_header = sdl_write_header,
.write_packet = sdl_write_packet,
.write_trailer = sdl_write_trailer,
- .flags = AVFMT_NOFILE,
+ .flags = AVFMT_NOFILE | AVFMT_VARIABLE_FPS | AVFMT_NOTIMESTAMPS,
.priv_class = &sdl_class,
};