[FFmpeg-devel] [PATCH 1/2] ffplay: do not preallocate video texture

Marton Balint cus at passwd.hu
Sun Jan 15 19:40:07 EET 2017


Since the uploads happen in the main display function, it does not matter much.

Signed-off-by: Marton Balint <cus at passwd.hu>
---
 ffplay.c | 120 +++++++++++----------------------------------------------------
 1 file changed, 20 insertions(+), 100 deletions(-)

diff --git a/ffplay.c b/ffplay.c
index 967679e..d76e41c 100644
--- a/ffplay.c
+++ b/ffplay.c
@@ -158,8 +158,6 @@ typedef struct Frame {
     double pts;           /* presentation timestamp for the frame */
     double duration;      /* estimated duration of the frame */
     int64_t pos;          /* byte position of the frame in the input file */
-    SDL_Texture *bmp;
-    int allocated;
     int width;
     int height;
     int format;
@@ -274,6 +272,7 @@ typedef struct VideoState {
     double last_vis_time;
     SDL_Texture *vis_texture;
     SDL_Texture *sub_texture;
+    SDL_Texture *vid_texture;
 
     int subtitle_stream;
     AVStream *subtitle_st;
@@ -357,7 +356,6 @@ static int64_t audio_callback_time;
 
 static AVPacket flush_pkt;
 
-#define FF_ALLOC_EVENT   (SDL_USEREVENT)
 #define FF_QUIT_EVENT    (SDL_USEREVENT + 2)
 
 static SDL_Window *window;
@@ -392,8 +390,6 @@ int64_t get_valid_channel_layout(int64_t channel_layout, int channels)
         return 0;
 }
 
-static void free_picture(Frame *vp);
-
 static int packet_queue_put_private(PacketQueue *q, AVPacket *pkt)
 {
     MyAVPacketList *pkt1;
@@ -677,7 +673,6 @@ static void frame_queue_destory(FrameQueue *f)
         Frame *vp = &f->queue[i];
         frame_queue_unref_item(vp);
         av_frame_free(&vp->frame);
-        free_picture(vp);
     }
     SDL_DestroyMutex(f->mutex);
     SDL_DestroyCond(f->cond);
@@ -798,14 +793,6 @@ static inline void fill_rectangle(int x, int y, int w, int h)
         SDL_RenderFillRect(renderer, &rect);
 }
 
-static void free_picture(Frame *vp)
-{
-     if (vp->bmp) {
-         SDL_DestroyTexture(vp->bmp);
-         vp->bmp = NULL;
-     }
-}
-
 static int realloc_texture(SDL_Texture **texture, Uint32 new_format, int new_width, int new_height, SDL_BlendMode blendmode, int init_texture)
 {
     Uint32 format;
@@ -907,7 +894,6 @@ static void video_image_display(VideoState *is)
     SDL_Rect rect;
 
     vp = frame_queue_peek_last(&is->pictq);
-    if (vp->bmp) {
         if (is->subtitle_st) {
             if (frame_queue_nb_remaining(&is->subpq) > 0) {
                 sp = frame_queue_peek(&is->subpq);
@@ -956,13 +942,16 @@ static void video_image_display(VideoState *is)
         calculate_display_rect(&rect, is->xleft, is->ytop, is->width, is->height, vp->width, vp->height, vp->sar);
 
         if (!vp->uploaded) {
-            if (upload_texture(vp->bmp, vp->frame, &is->img_convert_ctx) < 0)
+            int sdl_pix_fmt = vp->frame->format == AV_PIX_FMT_YUV420P ? SDL_PIXELFORMAT_YV12 : SDL_PIXELFORMAT_ARGB8888;
+            if (realloc_texture(&is->vid_texture, sdl_pix_fmt, vp->frame->width, vp->frame->height, SDL_BLENDMODE_NONE, 0) < 0)
+                return;
+            if (upload_texture(is->vid_texture, vp->frame, &is->img_convert_ctx) < 0)
                 return;
             vp->uploaded = 1;
             vp->flip_v = vp->frame->linesize[0] < 0;
         }
 
-        SDL_RenderCopyEx(renderer, vp->bmp, NULL, &rect, 0, NULL, vp->flip_v ? SDL_FLIP_VERTICAL : 0);
+        SDL_RenderCopyEx(renderer, is->vid_texture, NULL, &rect, 0, NULL, vp->flip_v ? SDL_FLIP_VERTICAL : 0);
         if (sp) {
 #if USE_ONEPASS_SUBTITLE_RENDER
             SDL_RenderCopy(renderer, is->sub_texture, NULL, &rect);
@@ -980,7 +969,6 @@ static void video_image_display(VideoState *is)
             }
 #endif
         }
-    }
 }
 
 static inline int compute_mod(int a, int b)
@@ -1217,6 +1205,8 @@ static void stream_close(VideoState *is)
     av_free(is->filename);
     if (is->vis_texture)
         SDL_DestroyTexture(is->vis_texture);
+    if (is->vid_texture)
+        SDL_DestroyTexture(is->vid_texture);
     if (is->sub_texture)
         SDL_DestroyTexture(is->sub_texture);
     av_free(is);
@@ -1257,13 +1247,10 @@ static void set_default_window_size(int width, int height, AVRational sar)
     default_height = rect.h;
 }
 
-static int video_open(VideoState *is, Frame *vp)
+static int video_open(VideoState *is)
 {
     int w,h;
 
-    if (vp && vp->width)
-        set_default_window_size(vp->width, vp->height, vp->sar);
-
     if (screen_width) {
         w = screen_width;
         h = screen_height;
@@ -1311,7 +1298,7 @@ static int video_open(VideoState *is, Frame *vp)
 static void video_display(VideoState *is)
 {
     if (!window)
-        video_open(is, NULL);
+        video_open(is);
 
     SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
     SDL_RenderClear(renderer);
@@ -1678,38 +1665,6 @@ display:
     }
 }
 
-/* allocate a picture (needs to do that in main thread to avoid
-   potential locking problems */
-static void alloc_picture(VideoState *is)
-{
-    Frame *vp;
-    int sdl_format;
-
-    vp = &is->pictq.queue[is->pictq.windex];
-
-    video_open(is, vp);
-
-    if (vp->format == AV_PIX_FMT_YUV420P)
-        sdl_format = SDL_PIXELFORMAT_YV12;
-    else
-        sdl_format = SDL_PIXELFORMAT_ARGB8888;
-
-    if (realloc_texture(&vp->bmp, sdl_format, vp->width, vp->height, SDL_BLENDMODE_NONE, 0) < 0) {
-        /* SDL allocates a buffer smaller than requested if the video
-         * overlay hardware is unable to support the requested size. */
-        av_log(NULL, AV_LOG_FATAL,
-               "Error: the video system does not support an image\n"
-                        "size of %dx%d pixels. Try using -lowres or -vf \"scale=w:h\"\n"
-                        "to reduce the image size.\n", vp->width, vp->height );
-        do_exit(is);
-    }
-
-    SDL_LockMutex(is->pictq.mutex);
-    vp->allocated = 1;
-    SDL_CondSignal(is->pictq.cond);
-    SDL_UnlockMutex(is->pictq.mutex);
-}
-
 static int queue_picture(VideoState *is, AVFrame *src_frame, double pts, double duration, int64_t pos, int serial)
 {
     Frame *vp;
@@ -1725,51 +1680,19 @@ static int queue_picture(VideoState *is, AVFrame *src_frame, double pts, double
     vp->sar = src_frame->sample_aspect_ratio;
     vp->uploaded = 0;
 
-    /* alloc or resize hardware picture buffer */
-    if (!vp->bmp || !vp->allocated ||
-        vp->width  != src_frame->width ||
-        vp->height != src_frame->height ||
-        vp->format != src_frame->format) {
-        SDL_Event event;
-
-        vp->allocated = 0;
-        vp->width = src_frame->width;
-        vp->height = src_frame->height;
-        vp->format = src_frame->format;
-
-        /* the allocation must be done in the main thread to avoid
-           locking problems. */
-        event.type = FF_ALLOC_EVENT;
-        event.user.data1 = is;
-        SDL_PushEvent(&event);
-
-        /* wait until the picture is allocated */
-        SDL_LockMutex(is->pictq.mutex);
-        while (!vp->allocated && !is->videoq.abort_request) {
-            SDL_CondWait(is->pictq.cond, is->pictq.mutex);
-        }
-        /* if the queue is aborted, we have to pop the pending ALLOC event or wait for the allocation to complete */
-        if (is->videoq.abort_request && SDL_PeepEvents(&event, 1, SDL_GETEVENT, FF_ALLOC_EVENT, FF_ALLOC_EVENT) != 1) {
-            while (!vp->allocated && !is->abort_request) {
-                SDL_CondWait(is->pictq.cond, is->pictq.mutex);
-            }
-        }
-        SDL_UnlockMutex(is->pictq.mutex);
+    vp->width = src_frame->width;
+    vp->height = src_frame->height;
+    vp->format = src_frame->format;
 
-        if (is->videoq.abort_request)
-            return -1;
-    }
+    vp->pts = pts;
+    vp->duration = duration;
+    vp->pos = pos;
+    vp->serial = serial;
 
-    /* if the frame is not skipped, then display it */
-    if (vp->bmp) {
-        vp->pts = pts;
-        vp->duration = duration;
-        vp->pos = pos;
-        vp->serial = serial;
+    set_default_window_size(vp->width, vp->height, vp->sar);
 
-        av_frame_move_ref(vp->frame, src_frame);
-        frame_queue_push(&is->pictq);
-    }
+    av_frame_move_ref(vp->frame, src_frame);
+    frame_queue_push(&is->pictq);
     return 0;
 }
 
@@ -3461,9 +3384,6 @@ static void event_loop(VideoState *cur_stream)
         case FF_QUIT_EVENT:
             do_exit(cur_stream);
             break;
-        case FF_ALLOC_EVENT:
-            alloc_picture(event.user.data1);
-            break;
         default:
             break;
         }
-- 
2.10.2



More information about the ffmpeg-devel mailing list