mpp icon indicating copy to clipboard operation
mpp copied to clipboard

如何 MppFrame 转 SDL_Texture

Open nulijiabei opened this issue 5 years ago • 5 comments

希望可以使用 SDL 来显示 MPP 解码出来的帧,但是不知道如何转换 ...

nulijiabei avatar Jul 09 '20 15:07 nulijiabei

可以参考这个教程,这个是ffmpeg的AvFrame 转到SDL,MppFrame的话可以对比下结构体定义,看看如何使用

qvoid avatar Jul 10 '20 01:07 qvoid

感谢

nulijiabei avatar Jul 11 '20 09:07 nulijiabei

            char* pixels;
            int pitch;

            if (SDL_LockTexture(m_texture, nullptr, (void**)&pixels, &pitch) < 0)
                SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL_LockTexture() failed: %s", SDL_GetError());

            decode_simple(&m_decoder->data, pkt->avpkt, pixels);

            SDL_UnlockTexture(m_texture);



                    RK_U32 width    = 0;
                    RK_U32 height   = 0;
                    RK_U32 h_stride = 0;
                    RK_U32 v_stride = 0;

                    MppBuffer buffer = NULL;
                    RK_U8 *base = NULL;

                    width    = mpp_frame_get_width(frame);
                    height   = mpp_frame_get_height(frame);
                    h_stride = mpp_frame_get_hor_stride(frame);
                    v_stride = mpp_frame_get_ver_stride(frame);
                    buffer   = mpp_frame_get_buffer(frame);

                    base = (RK_U8 *)mpp_buffer_get_ptr(buffer);
                    RK_U32 buf_size = mpp_frame_get_buf_size(frame);
                    size_t base_length = mpp_buffer_get_size(buffer);
                    mpp_log("base_length = %d\n", base_length);

                    RK_U32 i;
                    RK_U8 *base_y = base;
                    RK_U8 *base_c = base + h_stride * v_stride;

                    // ---------------------------------------------- //
                    // 虽然不正确,但是起码能看到画面 ...
                    // 待大神修正 

                    int idx = 0;
                    for (i = 0; i < height; i++, base_y += h_stride) {
                        memcpy(pixels + idx, base_y, width);
                        idx += width;
                    }
                    for (i = 0; i < height / 2; i++, base_c += h_stride) {
                        memcpy(pixels + idx, base_c, width);
                        idx += width;
                    }

nulijiabei avatar Jul 11 '20 09:07 nulijiabei

            char* pixels;
            int pitch;

            if (SDL_LockTexture(m_texture, nullptr, (void**)&pixels, &pitch) < 0)
                SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL_LockTexture() failed: %s", SDL_GetError());

            decode_simple(&m_decoder->data, pkt->avpkt, pixels);

            SDL_UnlockTexture(m_texture);



                    RK_U32 width    = 0;
                    RK_U32 height   = 0;
                    RK_U32 h_stride = 0;
                    RK_U32 v_stride = 0;

                    MppBuffer buffer = NULL;
                    RK_U8 *base = NULL;

                    width    = mpp_frame_get_width(frame);
                    height   = mpp_frame_get_height(frame);
                    h_stride = mpp_frame_get_hor_stride(frame);
                    v_stride = mpp_frame_get_ver_stride(frame);
                    buffer   = mpp_frame_get_buffer(frame);

                    base = (RK_U8 *)mpp_buffer_get_ptr(buffer);
                    RK_U32 buf_size = mpp_frame_get_buf_size(frame);
                    size_t base_length = mpp_buffer_get_size(buffer);
                    mpp_log("base_length = %d\n", base_length);

                    RK_U32 i;
                    RK_U8 *base_y = base;
                    RK_U8 *base_c = base + h_stride * v_stride;

                    // ---------------------------------------------- //
                    // 虽然不正确,但是起码能看到画面 ...
                    // 待大神修正 

                    int idx = 0;
                    for (i = 0; i < height; i++, base_y += h_stride) {
                        memcpy(pixels + idx, base_y, width);
                        idx += width;
                    }
                    for (i = 0; i < height / 2; i++, base_c += h_stride) {
                        memcpy(pixels + idx, base_c, width);
                        idx += width;
                    }

nulijiabei avatar Jul 11 '20 09:07 nulijiabei

另外,如果不识别 AVPacket 可以 ...

    // is video stream
    const char start_code[4] = { 0, 0, 0, 1 };
    if(memcmp(start_code, av_packet->data, 4) != 0)
    {   // is avc1 code, have no start code of H264
        int len = 0;
        uint8_t *p = av_packet->data;
        do
        {   // add start_code for each NAL, one frame may have multi NALs.
            len = ntohl(*((long*)p));
            memcpy(p, start_code, 4);
            p += 4;
            p += len;
            if(p >= av_packet->data + av_packet->size)
            {
                break;
            }
        } while (1);
    }

nulijiabei avatar Jul 11 '20 10:07 nulijiabei