Home > OS >  SDL shows h264 video not clear when creating window from HWND
SDL shows h264 video not clear when creating window from HWND

Time:01-03

In the Windows development environment:

  1. If you use SDL_CreateWindow() to create a window, run as a console program, and render h264 video, it is clear.

  2. However if you use SDL_CreateWindowFrom() to bind MFC window, rendering h264 is not clear. This confuses me.

How do I test it?

  • I save each frame of h264 frame data into .264 files, and each file has 0x00000001 start_code.

  • Then I read the h264 file through the program and convert it into AVFrame.

  • Then hand it over to SDL for rendering.

Here is the code about SDL:

class EMSDL {
public:
    EMSDL() {}
    ~EMSDL() {}

    static void delay(long ms) {
        SDL_Delay(ms);
    }

    void initSDL(int width, int height) {
        
        int ret = SDL_Init(SDL_INIT_VIDEO);
        if (ret)
        {
            LOG << "Failed";
            return;
        }

        //for MFC HWND
        //pSDLWindow = SDL_CreateWindowFrom(hWnd);

        //for console
        pSDLWindow = SDL_CreateWindow("EMEET_SDL",
            0,
            0,
            width,
            height,
            SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE);
        if (!pSDLWindow)
        {
            LOG << "Failed";
            return;
        }

        pSDLRenderer = SDL_CreateRenderer(pSDLWindow, -1, SDL_RENDERER_PRESENTVSYNC);
        if (!pSDLRenderer)
        {
            LOG << "Failed";
            return;
        }

        pSDLTexture = SDL_CreateTexture(pSDLRenderer,
            SDL_PIXELFORMAT_IYUV,//SDL_PIXELFORMAT_YV12
            SDL_TEXTUREACCESS_STREAMING,
            width,
            height);

        if (!pSDLTexture)
        {
            LOG << "Failed";
            return;
        }
    }

    void uninitSDL() {

        if (pSDLTexture) {
            SDL_DestroyTexture(pSDLTexture);
            pSDLTexture = nullptr;
        }
        if (pSDLRenderer) {
            SDL_DestroyRenderer(pSDLRenderer);
            pSDLRenderer = nullptr;
        }
        if (pSDLWindow) {
            SDL_DestroyWindow(pSDLWindow);
            pSDLWindow = nullptr;
        }
        SDL_Quit();
    }

    void render(AVFrame* frame) {

        SDL_UpdateYUVTexture(pSDLTexture,
            NULL,
            frame->data[0], frame->linesize[0],
            frame->data[1], frame->linesize[1],
            frame->data[2], frame->linesize[2]);

        SDL_RenderClear(pSDLRenderer);
        // Texture to Renderer
        SDL_Rect        sdlRect;
        sdlRect.x = 0;
        sdlRect.y = 0;
        sdlRect.w = frame->width;
        sdlRect.h = frame->height;

        SDL_RenderCopy(pSDLRenderer, pSDLTexture, &sdlRect, &sdlRect);

        // update and show
        SDL_RenderPresent(pSDLRenderer);
        //
        //SDL_PollEvent(&event);
    } 

    bool checkQuitEvent() {

        //handle events
        int myEvent = SDL_PollEvent(&event);
        //SDL_WaitEvent(&event);
        switch (event.type) {
        case SDL_KEYDOWN:
        {
            printf("key down! key code = %d, key name= %s\n", event.key.keysym.sym, SDL_GetKeyName(event.key.keysym.sym));
            if (event.key.keysym.sym == SDLK_ESCAPE || event.key.keysym.sym == SDLK_q) {
                return true;
            }
        }break;
        case SDL_QUIT: {
            return true;
        }break;
        }

        return false;
    }


protected:
    SDL_Window* pSDLWindow = nullptr;
    SDL_Renderer* pSDLRenderer = nullptr;
    SDL_Surface* pSDLSurface = nullptr;
    SDL_Texture* pSDLTexture = nullptr;
    SDL_Event event;
};

The most obvious difference is that where the hand shakes, the picture is not clear (SDL_CreateWindowFrom)。

CodePudding user response:

I found that the problem was not with SDL, but that I was calling avcodec_send_packet and avcodec_receive_frame repeatedly.

this problem is closed.

  • Related