Ticket #3604: 0001-ffplay-convert-ffplay-to-use-SDL2.patch

File 0001-ffplay-convert-ffplay-to-use-SDL2.patch, 40.4 KB (added by ethe, 11 years ago)
  • configure

    From 84019449aea94dc2519d6dd6801f41738aee415a Mon Sep 17 00:00:00 2001
    From: Marton Balint <cus@passwd.hu>
    Date: Tue, 23 Feb 2016 20:43:41 +0000
    Subject: [PATCH 1/2] ffplay: convert ffplay to use SDL2
    
    ---
     configure |  27 ++-
     ffplay.c  | 591 ++++++++++++++++++++++++++------------------------------------
     2 files changed, 268 insertions(+), 350 deletions(-)
    
    diff --git a/configure b/configure
    index 3d1ee49..bd65ce4 100755
    a b HAVE_LIST="  
    19641964    perl
    19651965    pod2man
    19661966    sdl
     1967    sdl2
    19671968    section_data_rel_ro
    19681969    texi2html
    19691970    threads
    … … ffmpeg_deps="avcodec avfilter avformat swresample"  
    29602961ffmpeg_select="aformat_filter anull_filter atrim_filter format_filter
    29612962               null_filter
    29622963               setpts_filter trim_filter"
    2963 ffplay_deps="avcodec avformat swscale swresample sdl"
    2964 ffplay_libs='$sdl_libs'
     2964ffplay_deps="avcodec avformat swscale swresample sdl2"
     2965ffplay_libs='$sdl2_libs'
    29652966ffplay_select="rdft crop_filter transpose_filter hflip_filter vflip_filter rotate_filter"
    29662967ffprobe_deps="avcodec avformat"
    29672968ffserver_deps="avformat fork sarestart"
    … … if enabled gcrypt; then  
    56305631    fi
    56315632fi
    56325633
    5633 if ! disabled sdl; then
     5634
     5635SDL2_CONFIG="${cross_prefix}sdl2-config"
     5636if check_pkg_config sdl2 SDL_events.h SDL_PollEvent; then
     5637    check_cpp_condition SDL.h "(SDL_MAJOR_VERSION<<16 | SDL_MINOR_VERSION<<8 | SDL_PATCHLEVEL) >= 0x020001" $sdl2_cflags &&
     5638    check_cpp_condition SDL.h "(SDL_MAJOR_VERSION<<16 | SDL_MINOR_VERSION<<8 | SDL_PATCHLEVEL) < 0x020100" $sdl2_cflags &&
     5639    enable sdl2
     5640else
     5641  if "${SDL2_CONFIG}" --version > /dev/null 2>&1; then
     5642    sdl2_cflags=$("${SDL2_CONFIG}" --cflags)
     5643    sdl2_libs=$("${SDL2_CONFIG}" --libs)
     5644    check_cpp_condition SDL.h "(SDL_MAJOR_VERSION<<16 | SDL_MINOR_VERSION<<8 | SDL_PATCHLEVEL) >= 0x020001" $sdl2_cflags &&
     5645    check_cpp_condition SDL.h "(SDL_MAJOR_VERSION<<16 | SDL_MINOR_VERSION<<8 | SDL_PATCHLEVEL) < 0x020100" $sdl2_cflags &&
     5646    enable sdl2
     5647  fi
     5648fi
     5649enabled sdl2 && add_cflags $sdl2_cflags && add_extralibs $sdl2_libs
     5650
     5651if ! disabled sdl and ! enabled sdl2; then
    56345652    SDL_CONFIG="${cross_prefix}sdl-config"
    56355653    if check_pkg_config sdl SDL_events.h SDL_PollEvent; then
    56365654        check_cpp_condition SDL.h "(SDL_MAJOR_VERSION<<16 | SDL_MINOR_VERSION<<8 | SDL_PATCHLEVEL) >= 0x010201" $sdl_cflags &&
    … … echo "network support ${network-no}"  
    62236241echo "threading support         ${thread_type-no}"
    62246242echo "safe bitstream reader     ${safe_bitstream_reader-no}"
    62256243echo "SDL support               ${sdl-no}"
     6244echo "SDL2 support              ${sdl2-no}"
    62266245echo "opencl enabled            ${opencl-no}"
    62276246echo "texi2html enabled         ${texi2html-no}"
    62286247echo "perl enabled              ${perl-no}"
    … … HOSTLD_O=$HOSTLD_O  
    63766395TARGET_EXEC=$target_exec $target_exec_args
    63776396TARGET_PATH=$target_path
    63786397TARGET_SAMPLES=${target_samples:-\$(SAMPLES)}
    6379 CFLAGS-ffplay=$sdl_cflags
     6398CFLAGS-ffplay=$sdl2_cflags
    63806399ZLIB=$($ldflags_filter -lz)
    63816400LIB_INSTALL_EXTRA_CMD=$LIB_INSTALL_EXTRA_CMD
    63826401EXTRALIBS=$extralibs
  • ffplay.c

    diff --git a/ffplay.c b/ffplay.c
    index 2cfdf26..d4193ad 100644
    a b const int program_birth_year = 2003;  
    105105
    106106#define CURSOR_HIDE_DELAY 1000000
    107107
     108#define USE_ONEPASS_SUBTITLE_RENDER 1
     109
    108110static unsigned sws_flags = SWS_BICUBIC;
    109111
    110112typedef struct MyAVPacketList {
    … … typedef struct Clock {  
    151153typedef struct Frame {
    152154    AVFrame *frame;
    153155    AVSubtitle sub;
    154     AVSubtitleRect **subrects;  /* rescaled subtitle rectangles in yuva */
    155156    int serial;
    156157    double pts;           /* presentation timestamp for the frame */
    157158    double duration;      /* estimated duration of the frame */
    158159    int64_t pos;          /* byte position of the frame in the input file */
    159     SDL_Overlay *bmp;
     160    SDL_Texture *bmp;
    160161    int allocated;
    161     int reallocate;
    162162    int width;
    163163    int height;
     164    int format;
    164165    AVRational sar;
     166    int uploaded;
    165167} Frame;
    166168
    167169typedef struct FrameQueue {
    … … typedef struct VideoState {  
    272274    FFTSample *rdft_data;
    273275    int xpos;
    274276    double last_vis_time;
     277    SDL_Texture *vis_texture;
     278    SDL_Texture *sub_texture;
    275279
    276280    int subtitle_stream;
    277281    AVStream *subtitle_st;
    … … typedef struct VideoState {  
    284288    AVStream *video_st;
    285289    PacketQueue videoq;
    286290    double max_frame_duration;      // maximum duration of a frame - above this, we consider the jump a timestamp discontinuity
    287 #if !CONFIG_AVFILTER
    288291    struct SwsContext *img_convert_ctx;
    289 #endif
    290292    struct SwsContext *sub_convert_ctx;
    291     SDL_Rect last_display_rect;
    292293    int eof;
    293294
    294295    char *filename;
    … … typedef struct VideoState {  
    313314static AVInputFormat *file_iformat;
    314315static const char *input_filename;
    315316static const char *window_title;
    316 static int fs_screen_width;
    317 static int fs_screen_height;
    318317static int default_width  = 640;
    319318static int default_height = 480;
    320319static int screen_width  = 0;
    … … static AVPacket flush_pkt;  
    362361#define FF_ALLOC_EVENT   (SDL_USEREVENT)
    363362#define FF_QUIT_EVENT    (SDL_USEREVENT + 2)
    364363
    365 static SDL_Surface *screen;
     364static SDL_Window *window;
     365static SDL_Renderer *renderer;
    366366
    367367#if CONFIG_AVFILTER
    368368static int opt_add_vfilter(void *optctx, const char *opt, const char *arg)
    … … static void decoder_destroy(Decoder *d) {  
    646646
    647647static void frame_queue_unref_item(Frame *vp)
    648648{
    649     int i;
    650     for (i = 0; i < vp->sub.num_rects; i++) {
    651         av_freep(&vp->subrects[i]->data[0]);
    652         av_freep(&vp->subrects[i]);
    653     }
    654     av_freep(&vp->subrects);
    655649    av_frame_unref(vp->frame);
    656650    avsubtitle_free(&vp->sub);
    657651}
    … … static void decoder_abort(Decoder *d, FrameQueue *fq)  
    802796    packet_queue_flush(d->queue);
    803797}
    804798
    805 static inline void fill_rectangle(SDL_Surface *screen,
    806                                   int x, int y, int w, int h, int color, int update)
     799static inline void fill_rectangle(int x, int y, int w, int h)
    807800{
    808801    SDL_Rect rect;
    809802    rect.x = x;
    810803    rect.y = y;
    811804    rect.w = w;
    812805    rect.h = h;
    813     SDL_FillRect(screen, &rect, color);
    814     if (update && w > 0 && h > 0)
    815         SDL_UpdateRect(screen, x, y, w, h);
    816 }
    817 
    818 /* draw only the border of a rectangle */
    819 static void fill_border(int xleft, int ytop, int width, int height, int x, int y, int w, int h, int color, int update)
    820 {
    821     int w1, w2, h1, h2;
    822 
    823     /* fill the background */
    824     w1 = x;
    825     if (w1 < 0)
    826         w1 = 0;
    827     w2 = width - (x + w);
    828     if (w2 < 0)
    829         w2 = 0;
    830     h1 = y;
    831     if (h1 < 0)
    832         h1 = 0;
    833     h2 = height - (y + h);
    834     if (h2 < 0)
    835         h2 = 0;
    836     fill_rectangle(screen,
    837                    xleft, ytop,
    838                    w1, height,
    839                    color, update);
    840     fill_rectangle(screen,
    841                    xleft + width - w2, ytop,
    842                    w2, height,
    843                    color, update);
    844     fill_rectangle(screen,
    845                    xleft + w1, ytop,
    846                    width - w1 - w2, h1,
    847                    color, update);
    848     fill_rectangle(screen,
    849                    xleft + w1, ytop + height - h2,
    850                    width - w1 - w2, h2,
    851                    color, update);
    852 }
    853 
    854 #define ALPHA_BLEND(a, oldp, newp, s)\
    855 ((((oldp << s) * (255 - (a))) + (newp * (a))) / (255 << s))
    856 
    857 
    858 
    859 #define BPP 1
    860 
    861 static void blend_subrect(uint8_t **data, int *linesize, const AVSubtitleRect *rect, int imgw, int imgh)
    862 {
    863     int x, y, Y, U, V, A;
    864     uint8_t *lum, *cb, *cr;
    865     int dstx, dsty, dstw, dsth;
    866     const AVSubtitleRect *src = rect;
    867 
    868     dstw = av_clip(rect->w, 0, imgw);
    869     dsth = av_clip(rect->h, 0, imgh);
    870     dstx = av_clip(rect->x, 0, imgw - dstw);
    871     dsty = av_clip(rect->y, 0, imgh - dsth);
    872     lum = data[0] + dstx + dsty * linesize[0];
    873     cb  = data[1] + dstx/2 + (dsty >> 1) * linesize[1];
    874     cr  = data[2] + dstx/2 + (dsty >> 1) * linesize[2];
    875 
    876     for (y = 0; y<dsth; y++) {
    877         for (x = 0; x<dstw; x++) {
    878             Y = src->data[0][x + y*src->linesize[0]];
    879             A = src->data[3][x + y*src->linesize[3]];
    880             lum[0] = ALPHA_BLEND(A, lum[0], Y, 0);
    881             lum++;
    882         }
    883         lum += linesize[0] - dstw;
    884     }
    885 
    886     for (y = 0; y<dsth/2; y++) {
    887         for (x = 0; x<dstw/2; x++) {
    888             U = src->data[1][x + y*src->linesize[1]];
    889             V = src->data[2][x + y*src->linesize[2]];
    890             A = src->data[3][2*x     +  2*y   *src->linesize[3]]
    891               + src->data[3][2*x + 1 +  2*y   *src->linesize[3]]
    892               + src->data[3][2*x + 1 + (2*y+1)*src->linesize[3]]
    893               + src->data[3][2*x     + (2*y+1)*src->linesize[3]];
    894             cb[0] = ALPHA_BLEND(A>>2, cb[0], U, 0);
    895             cr[0] = ALPHA_BLEND(A>>2, cr[0], V, 0);
    896             cb++;
    897             cr++;
    898         }
    899         cb += linesize[1] - dstw/2;
    900         cr += linesize[2] - dstw/2;
    901     }
     806    if (w && h)
     807        SDL_RenderFillRect(renderer, &rect);
    902808}
    903809
    904810static void free_picture(Frame *vp)
    905811{
    906812     if (vp->bmp) {
    907          SDL_FreeYUVOverlay(vp->bmp);
     813         SDL_DestroyTexture(vp->bmp);
    908814         vp->bmp = NULL;
    909815     }
    910816}
    911817
     818static int realloc_texture(SDL_Texture **texture, Uint32 new_format, int new_width, int new_height, SDL_BlendMode blendmode, int init_texture)
     819{
     820    Uint32 format;
     821    int access, w, h;
     822    if (SDL_QueryTexture(*texture, &format, &access, &w, &h) < 0 || new_width != w || new_height != h || new_format != format) {
     823        void *pixels;
     824        int pitch;
     825        SDL_DestroyTexture(*texture);
     826        if (!(*texture = SDL_CreateTexture(renderer, new_format, SDL_TEXTUREACCESS_STREAMING, new_width, new_height)))
     827            return -1;
     828        if (SDL_SetTextureBlendMode(*texture, blendmode) < 0)
     829            return -1;
     830        if (init_texture) {
     831            if (SDL_LockTexture(*texture, NULL, &pixels, &pitch) < 0)
     832                return -1;
     833            memset(pixels, 0, pitch * new_height);
     834            SDL_UnlockTexture(*texture);
     835        }
     836    }
     837    return 0;
     838}
     839
    912840static void calculate_display_rect(SDL_Rect *rect,
    913841                                   int scr_xleft, int scr_ytop, int scr_width, int scr_height,
    914842                                   int pic_width, int pic_height, AVRational pic_sar)
    … … static void calculate_display_rect(SDL_Rect *rect,  
    940868    rect->h = FFMAX(height, 1);
    941869}
    942870
     871static int upload_texture(SDL_Texture *tex, AVFrame *frame, struct SwsContext **img_convert_ctx) {
     872    int ret = 0;
     873    switch (frame->format) {
     874        case AV_PIX_FMT_YUV420P:
     875            ret = SDL_UpdateYUVTexture(tex, NULL, frame->data[0], frame->linesize[0],
     876                                                  frame->data[1], frame->linesize[1],
     877                                                  frame->data[2], frame->linesize[2]);
     878            break;
     879        case AV_PIX_FMT_BGRA:
     880            ret = SDL_UpdateTexture(tex, NULL, frame->data[0], frame->linesize[0]);
     881            break;
     882        default:
     883            /* This should only happen if we are not using avfilter... */
     884            *img_convert_ctx = sws_getCachedContext(*img_convert_ctx,
     885                frame->width, frame->height, frame->format, frame->width, frame->height,
     886                AV_PIX_FMT_BGRA, sws_flags, NULL, NULL, NULL);
     887            if (*img_convert_ctx != NULL) {
     888                uint8_t *pixels;
     889                int pitch;
     890                if (!SDL_LockTexture(tex, NULL, (void **)&pixels, &pitch)) {
     891                    sws_scale(*img_convert_ctx, (const uint8_t * const *)frame->data, frame->linesize,
     892                              0, frame->height, &pixels, &pitch);
     893                    SDL_UnlockTexture(tex);
     894                }
     895            } else {
     896                av_log(NULL, AV_LOG_FATAL, "Cannot initialize the conversion context\n");
     897                ret = -1;
     898            }
     899            break;
     900    }
     901    return ret;
     902}
     903
    943904static void video_image_display(VideoState *is)
    944905{
    945906    Frame *vp;
    946     Frame *sp;
     907    Frame *sp = NULL;
    947908    SDL_Rect rect;
    948     int i;
    949909
    950910    vp = frame_queue_peek(&is->pictq);
    951911    if (vp->bmp) {
    … … static void video_image_display(VideoState *is)  
    954914                sp = frame_queue_peek(&is->subpq);
    955915
    956916                if (vp->pts >= sp->pts + ((float) sp->sub.start_display_time / 1000)) {
    957                     uint8_t *data[4];
    958                     int linesize[4];
    959 
    960                     SDL_LockYUVOverlay (vp->bmp);
    961 
    962                     data[0] = vp->bmp->pixels[0];
    963                     data[1] = vp->bmp->pixels[2];
    964                     data[2] = vp->bmp->pixels[1];
    965 
    966                     linesize[0] = vp->bmp->pitches[0];
    967                     linesize[1] = vp->bmp->pitches[2];
    968                     linesize[2] = vp->bmp->pitches[1];
    969 
    970                     for (i = 0; i < sp->sub.num_rects; i++)
    971                         blend_subrect(data, linesize, sp->subrects[i],
    972                                       vp->bmp->w, vp->bmp->h);
    973 
    974                     SDL_UnlockYUVOverlay (vp->bmp);
    975                 }
     917                    if (!sp->uploaded) {
     918                        uint8_t *pixels;
     919                        int pitch;
     920                        int i;
     921                        if (!sp->width || !sp->height) {
     922                            sp->width = vp->width;
     923                            sp->height = vp->height;
     924                        }
     925                        if (realloc_texture(&is->sub_texture, SDL_PIXELFORMAT_ARGB8888, sp->width, sp->height, SDL_BLENDMODE_BLEND, 1) < 0)
     926                            return;
     927
     928                        for (i = 0; i < sp->sub.num_rects; i++) {
     929                            AVSubtitleRect *sub_rect = sp->sub.rects[i];
     930
     931                            sub_rect->x = av_clip(sub_rect->x, 0, sp->width );
     932                            sub_rect->y = av_clip(sub_rect->y, 0, sp->height);
     933                            sub_rect->w = av_clip(sub_rect->w, 0, sp->width  - sub_rect->x);
     934                            sub_rect->h = av_clip(sub_rect->h, 0, sp->height - sub_rect->y);
     935
     936                            is->sub_convert_ctx = sws_getCachedContext(is->sub_convert_ctx,
     937                                sub_rect->w, sub_rect->h, AV_PIX_FMT_PAL8,
     938                                sub_rect->w, sub_rect->h, AV_PIX_FMT_BGRA,
     939                                0, NULL, NULL, NULL);
     940                            if (!is->sub_convert_ctx) {
     941                                av_log(NULL, AV_LOG_FATAL, "Cannot initialize the conversion context\n");
     942                                return;
     943                            }
     944                            if (!SDL_LockTexture(is->sub_texture, (SDL_Rect *)sub_rect, (void **)&pixels, &pitch)) {
     945                                sws_scale(is->sub_convert_ctx, (const uint8_t * const *)sub_rect->data, sub_rect->linesize,
     946                                          0, sub_rect->h, &pixels, &pitch);
     947                                SDL_UnlockTexture(is->sub_texture);
     948                            }
     949                        }
     950                        sp->uploaded = 1;
     951                    }
     952                } else
     953                    sp = NULL;
    976954            }
    977955        }
    978956
    979957        calculate_display_rect(&rect, is->xleft, is->ytop, is->width, is->height, vp->width, vp->height, vp->sar);
    980958
    981         SDL_DisplayYUVOverlay(vp->bmp, &rect);
     959        if (!vp->uploaded) {
     960            if (upload_texture(vp->bmp, vp->frame, &is->img_convert_ctx) < 0)
     961                return;
     962            vp->uploaded = 1;
     963        }
    982964
    983         if (rect.x != is->last_display_rect.x || rect.y != is->last_display_rect.y || rect.w != is->last_display_rect.w || rect.h != is->last_display_rect.h || is->force_refresh) {
    984             int bgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00);
    985             fill_border(is->xleft, is->ytop, is->width, is->height, rect.x, rect.y, rect.w, rect.h, bgcolor, 1);
    986             is->last_display_rect = rect;
     965        SDL_RenderCopy(renderer, vp->bmp, NULL, &rect);
     966        if (sp) {
     967#if USE_ONEPASS_SUBTITLE_RENDER
     968            SDL_RenderCopy(renderer, is->sub_texture, NULL, &rect);
     969#else
     970            int i;
     971            double xratio = (double)rect.w / (double)sp->width;
     972            double yratio = (double)rect.h / (double)sp->height;
     973            for (i = 0; i < sp->sub.num_rects; i++) {
     974                SDL_Rect *sub_rect = (SDL_Rect*)sp->sub.rects[i];
     975                SDL_Rect target = {.x = rect.x + sub_rect->x * xratio,
     976                                   .y = rect.y + sub_rect->y * yratio,
     977                                   .w = sub_rect->w * xratio,
     978                                   .h = sub_rect->h * yratio};
     979                SDL_RenderCopy(renderer, is->sub_texture, sub_rect, &target);
     980            }
     981#endif
    987982        }
    988983    }
    989984}
    … … static inline int compute_mod(int a, int b)  
    996991static void video_audio_display(VideoState *s)
    997992{
    998993    int i, i_start, x, y1, y, ys, delay, n, nb_display_channels;
    999     int ch, channels, h, h2, bgcolor, fgcolor;
     994    int ch, channels, h, h2;
    1000995    int64_t time_diff;
    1001996    int rdft_bits, nb_freq;
    1002997
    … … static void video_audio_display(VideoState *s)  
    10461041        i_start = s->last_i_start;
    10471042    }
    10481043
    1049     bgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00);
    10501044    if (s->show_mode == SHOW_MODE_WAVES) {
    1051         fill_rectangle(screen,
    1052                        s->xleft, s->ytop, s->width, s->height,
    1053                        bgcolor, 0);
    1054 
    1055         fgcolor = SDL_MapRGB(screen->format, 0xff, 0xff, 0xff);
     1045        SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
    10561046
    10571047        /* total height for one channel */
    10581048        h = s->height / nb_display_channels;
    … … static void video_audio_display(VideoState *s)  
    10691059                } else {
    10701060                    ys = y1;
    10711061                }
    1072                 fill_rectangle(screen,
    1073                                s->xleft + x, ys, 1, y,
    1074                                fgcolor, 0);
     1062                fill_rectangle(s->xleft + x, ys, 1, y);
    10751063                i += channels;
    10761064                if (i >= SAMPLE_ARRAY_SIZE)
    10771065                    i -= SAMPLE_ARRAY_SIZE;
    10781066            }
    10791067        }
    10801068
    1081         fgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0xff);
     1069        SDL_SetRenderDrawColor(renderer, 0, 0, 255, 255);
    10821070
    10831071        for (ch = 1; ch < nb_display_channels; ch++) {
    10841072            y = s->ytop + ch * h;
    1085             fill_rectangle(screen,
    1086                            s->xleft, y, s->width, 1,
    1087                            fgcolor, 0);
     1073            fill_rectangle(s->xleft, y, s->width, 1);
    10881074        }
    1089         SDL_UpdateRect(screen, s->xleft, s->ytop, s->width, s->height);
    10901075    } else {
     1076        if (realloc_texture(&s->vis_texture, SDL_PIXELFORMAT_ARGB8888, s->width, s->height, SDL_BLENDMODE_NONE, 1) < 0)
     1077            return;
     1078
    10911079        nb_display_channels= FFMIN(nb_display_channels, 2);
    10921080        if (rdft_bits != s->rdft_bits) {
    10931081            av_rdft_end(s->rdft);
    … … static void video_audio_display(VideoState *s)  
    11011089            s->show_mode = SHOW_MODE_WAVES;
    11021090        } else {
    11031091            FFTSample *data[2];
     1092            SDL_Rect rect = {.x = s->xpos, .y = 0, .w = 1, .h = s->height};
     1093            uint32_t *pixels;
     1094            int pitch;
    11041095            for (ch = 0; ch < nb_display_channels; ch++) {
    11051096                data[ch] = s->rdft_data + 2 * nb_freq * ch;
    11061097                i = i_start + ch;
    … … static void video_audio_display(VideoState *s)  
    11151106            }
    11161107            /* Least efficient way to do this, we should of course
    11171108             * directly access it but it is more than fast enough. */
    1118             for (y = 0; y < s->height; y++) {
    1119                 double w = 1 / sqrt(nb_freq);
    1120                 int a = sqrt(w * hypot(data[0][2 * y + 0], data[0][2 * y + 1]));
    1121                 int b = (nb_display_channels == 2 ) ? sqrt(w * hypot(data[1][2 * y + 0], data[1][2 * y + 1]))
    1122                                                     : a;
    1123                 a = FFMIN(a, 255);
    1124                 b = FFMIN(b, 255);
    1125                 fgcolor = SDL_MapRGB(screen->format, a, b, (a + b) / 2);
    1126 
    1127                 fill_rectangle(screen,
    1128                             s->xpos, s->height-y, 1, 1,
    1129                             fgcolor, 0);
     1109            if (!SDL_LockTexture(s->vis_texture, &rect, (void **)&pixels, &pitch)) {
     1110                pitch >>= 2;
     1111                pixels += pitch * s->height;
     1112                for (y = 0; y < s->height; y++) {
     1113                    double w = 1 / sqrt(nb_freq);
     1114                    int a = sqrt(w * sqrt(data[0][2 * y + 0] * data[0][2 * y + 0] + data[0][2 * y + 1] * data[0][2 * y + 1]));
     1115                    int b = (nb_display_channels == 2 ) ? sqrt(w * hypot(data[1][2 * y + 0], data[1][2 * y + 1]))
     1116                                                        : a;
     1117                    a = FFMIN(a, 255);
     1118                    b = FFMIN(b, 255);
     1119                    pixels -= pitch;
     1120                    *pixels = (a << 16) + (b << 8) + ((a+b) >> 1);
     1121                }
     1122                SDL_UnlockTexture(s->vis_texture);
    11301123            }
     1124            SDL_RenderCopy(renderer, s->vis_texture, NULL, NULL);
    11311125        }
    1132         SDL_UpdateRect(screen, s->xpos, s->ytop, 1, s->height);
    11331126        if (!s->paused)
    11341127            s->xpos++;
    11351128        if (s->xpos >= s->width)
    … … static void stream_close(VideoState *is)  
    12201213    frame_queue_destory(&is->sampq);
    12211214    frame_queue_destory(&is->subpq);
    12221215    SDL_DestroyCond(is->continue_read_thread);
    1223 #if !CONFIG_AVFILTER
    12241216    sws_freeContext(is->img_convert_ctx);
    1225 #endif
    12261217    sws_freeContext(is->sub_convert_ctx);
    12271218    av_free(is->filename);
     1219    if (is->vis_texture)
     1220        SDL_DestroyTexture(is->vis_texture);
     1221    if (is->sub_texture)
     1222        SDL_DestroyTexture(is->sub_texture);
    12281223    av_free(is);
    12291224}
    12301225
    … … static void do_exit(VideoState *is)  
    12331228    if (is) {
    12341229        stream_close(is);
    12351230    }
     1231    if (renderer)
     1232        SDL_DestroyRenderer(renderer);
     1233    if (window)
     1234        SDL_DestroyWindow(window);
    12361235    av_lockmgr_register(NULL);
    12371236    uninit_opts();
    12381237#if CONFIG_AVFILTER
    … … static void set_default_window_size(int width, int height, AVRational sar)  
    12591258    default_height = rect.h;
    12601259}
    12611260
    1262 static int video_open(VideoState *is, int force_set_video_mode, Frame *vp)
     1261static int video_open(VideoState *is, Frame *vp)
    12631262{
    1264     int flags = SDL_HWSURFACE | SDL_ASYNCBLIT | SDL_HWACCEL;
    12651263    int w,h;
    12661264
    1267     if (is_full_screen) flags |= SDL_FULLSCREEN;
    1268     else                flags |= SDL_RESIZABLE;
    1269 
    12701265    if (vp && vp->width)
    12711266        set_default_window_size(vp->width, vp->height, vp->sar);
    12721267
    1273     if (is_full_screen && fs_screen_width) {
    1274         w = fs_screen_width;
    1275         h = fs_screen_height;
    1276     } else if (!is_full_screen && screen_width) {
     1268    if (screen_width) {
    12771269        w = screen_width;
    12781270        h = screen_height;
    12791271    } else {
    12801272        w = default_width;
    12811273        h = default_height;
    12821274    }
    1283     w = FFMIN(16383, w);
    1284     if (screen && is->width == screen->w && screen->w == w
    1285        && is->height== screen->h && screen->h == h && !force_set_video_mode)
    1286         return 0;
    1287     screen = SDL_SetVideoMode(w, h, 0, flags);
    1288     if (!screen) {
     1275
     1276    if (!window) {
     1277        int flags = SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE;
     1278        if (!window_title)
     1279            window_title = input_filename;
     1280        if (is_full_screen)
     1281            flags |= SDL_WINDOW_FULLSCREEN_DESKTOP;
     1282        window = SDL_CreateWindow(window_title, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, w, h, flags);
     1283        SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "linear");
     1284        if (window) {
     1285            SDL_RendererInfo info;
     1286            renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
     1287            if (renderer) {
     1288                if (!SDL_GetRendererInfo(renderer, &info))
     1289                    av_log(NULL, AV_LOG_VERBOSE, "Initialized %s renderer.\n", info.name);
     1290            }
     1291        }
     1292    } else {
     1293        SDL_SetWindowSize(window, w, h);
     1294    }
     1295
     1296    if (!window || !renderer) {
    12891297        av_log(NULL, AV_LOG_FATAL, "SDL: could not set video mode - exiting\n");
    12901298        do_exit(is);
    12911299    }
    1292     if (!window_title)
    1293         window_title = input_filename;
    1294     SDL_WM_SetCaption(window_title, window_title);
    12951300
    1296     is->width  = screen->w;
    1297     is->height = screen->h;
     1301    is->width  = w;
     1302    is->height = h;
    12981303
    12991304    return 0;
    13001305}
    … … static int video_open(VideoState *is, int force_set_video_mode, Frame *vp)  
    13021307/* display the current picture, if any */
    13031308static void video_display(VideoState *is)
    13041309{
    1305     if (!screen)
    1306         video_open(is, 0, NULL);
     1310    if (!window)
     1311        video_open(is, NULL);
     1312
     1313    SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
     1314    SDL_RenderClear(renderer);
    13071315    if (is->audio_st && is->show_mode != SHOW_MODE_VIDEO)
    13081316        video_audio_display(is);
    13091317    else if (is->video_st)
    13101318        video_image_display(is);
     1319    SDL_RenderPresent(renderer);
    13111320}
    13121321
    13131322static double get_clock(Clock *c)
    … … retry:  
    16011610                                || (is->vidclk.pts > (sp->pts + ((float) sp->sub.end_display_time / 1000)))
    16021611                                || (sp2 && is->vidclk.pts > (sp2->pts + ((float) sp2->sub.start_display_time / 1000))))
    16031612                        {
     1613                            if (sp->uploaded) {
     1614                                int i;
     1615                                for (i = 0; i < sp->sub.num_rects; i++) {
     1616                                    AVSubtitleRect *sub_rect = sp->sub.rects[i];
     1617                                    uint8_t *pixels;
     1618                                    int pitch, j;
     1619
     1620                                    if (!SDL_LockTexture(is->sub_texture, (SDL_Rect *)sub_rect, (void **)&pixels, &pitch)) {
     1621                                        for (j = 0; j < sub_rect->h; j++, pixels += pitch)
     1622                                            memset(pixels, 0, sub_rect->w << 2);
     1623                                        SDL_UnlockTexture(is->sub_texture);
     1624                                    }
     1625                                }
     1626                            }
    16041627                            frame_queue_next(&is->subpq);
    16051628                        } else {
    16061629                            break;
    … … display:  
    16661689static void alloc_picture(VideoState *is)
    16671690{
    16681691    Frame *vp;
    1669     int64_t bufferdiff;
     1692    int sdl_format;
    16701693
    16711694    vp = &is->pictq.queue[is->pictq.windex];
    16721695
    1673     free_picture(vp);
     1696    video_open(is, vp);
    16741697
    1675     video_open(is, 0, vp);
     1698    if (vp->format == AV_PIX_FMT_YUV420P)
     1699        sdl_format = SDL_PIXELFORMAT_YV12;
     1700    else
     1701        sdl_format = SDL_PIXELFORMAT_ARGB8888;
    16761702
    1677     vp->bmp = SDL_CreateYUVOverlay(vp->width, vp->height,
    1678                                    SDL_YV12_OVERLAY,
    1679                                    screen);
    1680     bufferdiff = vp->bmp ? FFMAX(vp->bmp->pixels[0], vp->bmp->pixels[1]) - FFMIN(vp->bmp->pixels[0], vp->bmp->pixels[1]) : 0;
    1681     if (!vp->bmp || vp->bmp->pitches[0] < vp->width || bufferdiff < (int64_t)vp->height * vp->bmp->pitches[0]) {
     1703    if (realloc_texture(&vp->bmp, sdl_format, vp->width, vp->height, SDL_BLENDMODE_NONE, 0) < 0) {
    16821704        /* SDL allocates a buffer smaller than requested if the video
    16831705         * overlay hardware is unable to support the requested size. */
    16841706        av_log(NULL, AV_LOG_FATAL,
    … … static void alloc_picture(VideoState *is)  
    16941716    SDL_UnlockMutex(is->pictq.mutex);
    16951717}
    16961718
    1697 static void duplicate_right_border_pixels(SDL_Overlay *bmp) {
    1698     int i, width, height;
    1699     Uint8 *p, *maxp;
    1700     for (i = 0; i < 3; i++) {
    1701         width  = bmp->w;
    1702         height = bmp->h;
    1703         if (i > 0) {
    1704             width  >>= 1;
    1705             height >>= 1;
    1706         }
    1707         if (bmp->pitches[i] > width) {
    1708             maxp = bmp->pixels[i] + bmp->pitches[i] * height - 1;
    1709             for (p = bmp->pixels[i] + width - 1; p < maxp; p += bmp->pitches[i])
    1710                 *(p+1) = *p;
    1711         }
    1712     }
    1713 }
    1714 
    17151719static int queue_picture(VideoState *is, AVFrame *src_frame, double pts, double duration, int64_t pos, int serial)
    17161720{
    17171721    Frame *vp;
    … … static int queue_picture(VideoState *is, AVFrame *src_frame, double pts, double  
    17251729        return -1;
    17261730
    17271731    vp->sar = src_frame->sample_aspect_ratio;
     1732    vp->uploaded = 0;
    17281733
    17291734    /* alloc or resize hardware picture buffer */
    1730     if (!vp->bmp || vp->reallocate || !vp->allocated ||
     1735    if (!vp->bmp || !vp->allocated ||
    17311736        vp->width  != src_frame->width ||
    1732         vp->height != src_frame->height) {
     1737        vp->height != src_frame->height ||
     1738        vp->format != src_frame->format) {
    17331739        SDL_Event event;
    17341740
    1735         vp->allocated  = 0;
    1736         vp->reallocate = 0;
     1741        vp->allocated = 0;
    17371742        vp->width = src_frame->width;
    17381743        vp->height = src_frame->height;
     1744        vp->format = src_frame->format;
    17391745
    17401746        /* the allocation must be done in the main thread to avoid
    17411747           locking problems. */
    … … static int queue_picture(VideoState *is, AVFrame *src_frame, double pts, double  
    17491755            SDL_CondWait(is->pictq.cond, is->pictq.mutex);
    17501756        }
    17511757        /* if the queue is aborted, we have to pop the pending ALLOC event or wait for the allocation to complete */
    1752         if (is->videoq.abort_request && SDL_PeepEvents(&event, 1, SDL_GETEVENT, SDL_EVENTMASK(FF_ALLOC_EVENT)) != 1) {
     1758        if (is->videoq.abort_request && SDL_PeepEvents(&event, 1, SDL_GETEVENT, FF_ALLOC_EVENT, FF_ALLOC_EVENT) != 1) {
    17531759            while (!vp->allocated && !is->abort_request) {
    17541760                SDL_CondWait(is->pictq.cond, is->pictq.mutex);
    17551761            }
    … … static int queue_picture(VideoState *is, AVFrame *src_frame, double pts, double  
    17621768
    17631769    /* if the frame is not skipped, then display it */
    17641770    if (vp->bmp) {
    1765         uint8_t *data[4];
    1766         int linesize[4];
    1767 
    1768         /* get a pointer on the bitmap */
    1769         SDL_LockYUVOverlay (vp->bmp);
    1770 
    1771         data[0] = vp->bmp->pixels[0];
    1772         data[1] = vp->bmp->pixels[2];
    1773         data[2] = vp->bmp->pixels[1];
    1774 
    1775         linesize[0] = vp->bmp->pitches[0];
    1776         linesize[1] = vp->bmp->pitches[2];
    1777         linesize[2] = vp->bmp->pitches[1];
    1778 
    1779 #if CONFIG_AVFILTER
    1780         // FIXME use direct rendering
    1781         av_image_copy(data, linesize, (const uint8_t **)src_frame->data, src_frame->linesize,
    1782                         src_frame->format, vp->width, vp->height);
    1783 #else
    1784         {
    1785             AVDictionaryEntry *e = av_dict_get(sws_dict, "sws_flags", NULL, 0);
    1786             if (e) {
    1787                 const AVClass *class = sws_get_class();
    1788                 const AVOption    *o = av_opt_find(&class, "sws_flags", NULL, 0,
    1789                                                    AV_OPT_SEARCH_FAKE_OBJ);
    1790                 int ret = av_opt_eval_flags(&class, o, e->value, &sws_flags);
    1791                 if (ret < 0)
    1792                     exit(1);
    1793             }
    1794         }
    1795 
    1796         is->img_convert_ctx = sws_getCachedContext(is->img_convert_ctx,
    1797             vp->width, vp->height, src_frame->format, vp->width, vp->height,
    1798             AV_PIX_FMT_YUV420P, sws_flags, NULL, NULL, NULL);
    1799         if (!is->img_convert_ctx) {
    1800             av_log(NULL, AV_LOG_FATAL, "Cannot initialize the conversion context\n");
    1801             exit(1);
    1802         }
    1803         sws_scale(is->img_convert_ctx, src_frame->data, src_frame->linesize,
    1804                   0, vp->height, data, linesize);
    1805 #endif
    1806         /* workaround SDL PITCH_WORKAROUND */
    1807         duplicate_right_border_pixels(vp->bmp);
    1808         /* update the bitmap content */
    1809         SDL_UnlockYUVOverlay(vp->bmp);
    1810 
    18111771        vp->pts = pts;
    18121772        vp->duration = duration;
    18131773        vp->pos = pos;
    18141774        vp->serial = serial;
    18151775
    1816         /* now we can update the picture count */
     1776        av_frame_move_ref(vp->frame, src_frame);
    18171777        frame_queue_push(&is->pictq);
    18181778    }
    18191779    return 0;
    … … fail:  
    19011861
    19021862static int configure_video_filters(AVFilterGraph *graph, VideoState *is, const char *vfilters, AVFrame *frame)
    19031863{
    1904     static const enum AVPixelFormat pix_fmts[] = { AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE };
     1864    static const enum AVPixelFormat pix_fmts[] = { AV_PIX_FMT_YUV420P, AV_PIX_FMT_BGRA, AV_PIX_FMT_NONE };
    19051865    char sws_flags_str[512] = "";
    19061866    char buffersrc_args[256];
    19071867    int ret;
    … … static int configure_video_filters(AVFilterGraph *graph, VideoState *is, const c  
    19641924    last_filter = filt_ctx;                                                  \
    19651925} while (0)
    19661926
    1967     /* SDL YUV code is not handling odd width/height for some driver
    1968      * combinations, therefore we crop the picture to an even width/height. */
    1969     INSERT_FILT("crop", "floor(in_w/2)*2:floor(in_h/2)*2");
    1970 
    19711927    if (autorotate) {
    19721928        double theta  = get_rotation(is->video_st);
    19731929
    … … static int audio_thread(void *arg)  
    21622118static int decoder_start(Decoder *d, int (*fn)(void *), void *arg)
    21632119{
    21642120    packet_queue_start(d->queue);
    2165     d->decoder_tid = SDL_CreateThread(fn, arg);
     2121    d->decoder_tid = SDL_CreateThread(fn, "decoder", arg);
    21662122    if (!d->decoder_tid) {
    21672123        av_log(NULL, AV_LOG_ERROR, "SDL_CreateThread(): %s\n", SDL_GetError());
    21682124        return AVERROR(ENOMEM);
    … … static int video_thread(void *arg)  
    22822238static int subtitle_thread(void *arg)
    22832239{
    22842240    VideoState *is = arg;
     2241    AVCodecContext *dec = is->subtitle_st->codec;
    22852242    Frame *sp;
    22862243    int got_subtitle;
    22872244    double pts;
    2288     int i;
    22892245
    22902246    for (;;) {
    22912247        if (!(sp = frame_queue_peek_writable(&is->subpq)))
    … … static int subtitle_thread(void *arg)  
    23012257                pts = sp->sub.pts / (double)AV_TIME_BASE;
    23022258            sp->pts = pts;
    23032259            sp->serial = is->subdec.pkt_serial;
    2304             if (!(sp->subrects = av_mallocz_array(sp->sub.num_rects, sizeof(AVSubtitleRect*)))) {
    2305                 av_log(NULL, AV_LOG_FATAL, "Cannot allocate subrects\n");
    2306                 exit(1);
    2307             }
    2308 
    2309             for (i = 0; i < sp->sub.num_rects; i++)
    2310             {
    2311                 int in_w = sp->sub.rects[i]->w;
    2312                 int in_h = sp->sub.rects[i]->h;
    2313                 int subw = is->subdec.avctx->width  ? is->subdec.avctx->width  : is->viddec_width;
    2314                 int subh = is->subdec.avctx->height ? is->subdec.avctx->height : is->viddec_height;
    2315                 int out_w = is->viddec_width  ? in_w * is->viddec_width  / subw : in_w;
    2316                 int out_h = is->viddec_height ? in_h * is->viddec_height / subh : in_h;
    2317 
    2318                 if (!(sp->subrects[i] = av_mallocz(sizeof(AVSubtitleRect))) ||
    2319                     av_image_alloc(sp->subrects[i]->data, sp->subrects[i]->linesize, out_w, out_h, AV_PIX_FMT_YUVA420P, 16) < 0) {
    2320                     av_log(NULL, AV_LOG_FATAL, "Cannot allocate subtitle data\n");
    2321                     exit(1);
    2322                 }
    2323 
    2324                 is->sub_convert_ctx = sws_getCachedContext(is->sub_convert_ctx,
    2325                     in_w, in_h, AV_PIX_FMT_PAL8, out_w, out_h,
    2326                     AV_PIX_FMT_YUVA420P, sws_flags, NULL, NULL, NULL);
    2327                 if (!is->sub_convert_ctx) {
    2328                     av_log(NULL, AV_LOG_FATAL, "Cannot initialize the sub conversion context\n");
    2329                     exit(1);
    2330                 }
    2331                 sws_scale(is->sub_convert_ctx,
    2332                           (void*)sp->sub.rects[i]->data, sp->sub.rects[i]->linesize,
    2333                           0, in_h, sp->subrects[i]->data, sp->subrects[i]->linesize);
    2334 
    2335                 sp->subrects[i]->w = out_w;
    2336                 sp->subrects[i]->h = out_h;
    2337                 sp->subrects[i]->x = sp->sub.rects[i]->x * out_w / in_w;
    2338                 sp->subrects[i]->y = sp->sub.rects[i]->y * out_h / in_h;
    2339             }
     2260            sp->width = dec->width;
     2261            sp->height = dec->height;
     2262            sp->uploaded = 0;
    23402263
    23412264            /* now we can update the picture count */
    23422265            frame_queue_push(&is->subpq);
    … … static VideoState *stream_open(const char *filename, AVInputFormat *iformat)  
    31813104    is->audio_volume = SDL_MIX_MAXVOLUME;
    31823105    is->muted = 0;
    31833106    is->av_sync_type = av_sync_type;
    3184     is->read_tid     = SDL_CreateThread(read_thread, is);
     3107    is->read_tid     = SDL_CreateThread(read_thread, "read_thread", is);
    31853108    if (!is->read_tid) {
    31863109        av_log(NULL, AV_LOG_FATAL, "SDL_CreateThread(): %s\n", SDL_GetError());
    31873110fail:
    … … static void stream_cycle_channel(VideoState *is, int codec_type)  
    32723195
    32733196static void toggle_full_screen(VideoState *is)
    32743197{
    3275 #if defined(__APPLE__) && SDL_VERSION_ATLEAST(1, 2, 14)
    3276     /* OS X needs to reallocate the SDL overlays */
    3277     int i;
    3278     for (i = 0; i < VIDEO_PICTURE_QUEUE_SIZE; i++)
    3279         is->pictq.queue[i].reallocate = 1;
    3280 #endif
    32813198    is_full_screen = !is_full_screen;
    3282     video_open(is, 1, NULL);
     3199    SDL_SetWindowFullscreen(window, is_full_screen ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0);
    32833200}
    32843201
    32853202static void toggle_audio_display(VideoState *is)
    32863203{
    3287     int bgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00);
    32883204    int next = is->show_mode;
    32893205    do {
    32903206        next = (next + 1) % SHOW_MODE_NB;
    32913207    } while (next != is->show_mode && (next == SHOW_MODE_VIDEO && !is->video_st || next != SHOW_MODE_VIDEO && !is->audio_st));
    32923208    if (is->show_mode != next) {
    3293         fill_rectangle(screen,
    3294                     is->xleft, is->ytop, is->width, is->height,
    3295                     bgcolor, 1);
    32963209        is->force_refresh = 1;
    32973210        is->show_mode = next;
    32983211    }
    … … static void toggle_audio_display(VideoState *is)  
    33013214static void refresh_loop_wait_event(VideoState *is, SDL_Event *event) {
    33023215    double remaining_time = 0.0;
    33033216    SDL_PumpEvents();
    3304     while (!SDL_PeepEvents(event, 1, SDL_GETEVENT, SDL_ALLEVENTS)) {
     3217    while (!SDL_PeepEvents(event, 1, SDL_GETEVENT, SDL_FIRSTEVENT, SDL_LASTEVENT)) {
    33053218        if (!cursor_hidden && av_gettime_relative() - cursor_last_shown > CURSOR_HIDE_DELAY) {
    33063219            SDL_ShowCursor(0);
    33073220            cursor_hidden = 1;
    … … static void event_loop(VideoState *cur_stream)  
    34653378                break;
    34663379            }
    34673380            break;
    3468         case SDL_VIDEOEXPOSE:
    3469             cur_stream->force_refresh = 1;
    3470             break;
    34713381        case SDL_MOUSEBUTTONDOWN:
    34723382            if (exit_on_mousedown) {
    34733383                do_exit(cur_stream);
    … … static void event_loop(VideoState *cur_stream)  
    35233433                    stream_seek(cur_stream, ts, 0, 0);
    35243434                }
    35253435            break;
    3526         case SDL_VIDEORESIZE:
    3527                 screen = SDL_SetVideoMode(FFMIN(16383, event.resize.w), event.resize.h, 0,
    3528                                           SDL_HWSURFACE|(is_full_screen?SDL_FULLSCREEN:SDL_RESIZABLE)|SDL_ASYNCBLIT|SDL_HWACCEL);
    3529                 if (!screen) {
    3530                     av_log(NULL, AV_LOG_FATAL, "Failed to set video mode\n");
    3531                     do_exit(cur_stream);
    3532                 }
    3533                 screen_width  = cur_stream->width  = screen->w;
    3534                 screen_height = cur_stream->height = screen->h;
    3535                 cur_stream->force_refresh = 1;
     3436        case SDL_WINDOWEVENT:
     3437            switch (event.window.event) {
     3438                case SDL_WINDOWEVENT_RESIZED:
     3439                    screen_width  = cur_stream->width  = event.window.data1;
     3440                    screen_height = cur_stream->height = event.window.data2;
     3441                    if (cur_stream->vis_texture) {
     3442                        SDL_DestroyTexture(cur_stream->vis_texture);
     3443                        cur_stream->vis_texture = NULL;
     3444                    }
     3445                case SDL_WINDOWEVENT_EXPOSED:
     3446                    cur_stream->force_refresh = 1;
     3447            }
    35363448            break;
    35373449        case SDL_QUIT:
    35383450        case FF_QUIT_EVENT:
    … … int main(int argc, char **argv)  
    37693681{
    37703682    int flags;
    37713683    VideoState *is;
    3772     char dummy_videodriver[] = "SDL_VIDEODRIVER=dummy";
    37733684
    37743685    av_log_set_flags(AV_LOG_SKIP_REPEATED);
    37753686    parse_loglevel(argc, argv, options);
    … … int main(int argc, char **argv)  
    38083719    if (audio_disable)
    38093720        flags &= ~SDL_INIT_AUDIO;
    38103721    if (display_disable)
    3811         SDL_putenv(dummy_videodriver); /* For the event queue, we always need a video driver. */
    3812 #if !defined(_WIN32) && !defined(__APPLE__)
    3813     flags |= SDL_INIT_EVENTTHREAD; /* Not supported on Windows or Mac OS X */
    3814 #endif
     3722        flags &= ~SDL_INIT_VIDEO;
    38153723    if (SDL_Init (flags)) {
    38163724        av_log(NULL, AV_LOG_FATAL, "Could not initialize SDL - %s\n", SDL_GetError());
    38173725        av_log(NULL, AV_LOG_FATAL, "(Did you set the DISPLAY variable?)\n");
    38183726        exit(1);
    38193727    }
    38203728
    3821     if (!display_disable) {
    3822         const SDL_VideoInfo *vi = SDL_GetVideoInfo();
    3823         fs_screen_width = vi->current_w;
    3824         fs_screen_height = vi->current_h;
    3825     }
    3826 
    3827     SDL_EventState(SDL_ACTIVEEVENT, SDL_IGNORE);
    38283729    SDL_EventState(SDL_SYSWMEVENT, SDL_IGNORE);
    38293730    SDL_EventState(SDL_USEREVENT, SDL_IGNORE);
    38303731
    3831     SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
    3832 
    38333732    if (av_lockmgr_register(lockmgr)) {
    38343733        av_log(NULL, AV_LOG_FATAL, "Could not initialize lock manager!\n");
    38353734        do_exit(NULL);