Почему я не могу хранить AVFrame * в буфере - PullRequest
0 голосов
/ 14 октября 2019

Я хочу сохранить AVframe * в буфере. Я читаю файл AVI и хочу сохранить AVframe * в буфере std :: vector.

Я могу сохранить AVFrame * av_frame в буфер, но я хочу сохранить AVFrame * gl_frame в буфери использовать его позже для обновления GL_TEXTURE_2D.

Но при попытке сохранить AVFrame * gl_frame.

ничего не сохраняется в буфере. Это структура данных приложения.

typedef struct {

    AVFormatContext *fmt_ctx;
    int stream_idx;
    AVStream *video_stream;
    AVCodecContext *codec_ctx;
    AVCodec *decoder;
    AVPacket *packet;
    AVFrame *av_frame;
    AVFrame *gl_frame;
    struct SwsContext *conv_ctx;
    unsigned int  frame_tex;

}AppData;

i Инициализировать структуру.

// Do Clip Realted Stuff
    avformat_network_init();
    initializeAppData();

    // open video
    if (avformat_open_input(&data.fmt_ctx, stdstrPathOfVideo.c_str(), NULL, NULL) < 0) {
        clearAppData();
        return;
    }

    // find stream info
    if (avformat_find_stream_info(data.fmt_ctx, NULL) < 0) {
        clearAppData();
        return;
    }

    // find the video stream
    for (unsigned int i = 0; i < data.fmt_ctx->nb_streams; ++i)
    {
        if (data.fmt_ctx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO)
        {
            data.stream_idx = i;
            break;
        }
    }


    if (data.stream_idx == -1)
    {
        clearAppData();
        return;
    }

    data.video_stream = data.fmt_ctx->streams[data.stream_idx];
    data.codec_ctx = data.video_stream->codec;

    // find the decoder
    data.decoder = avcodec_find_decoder(data.codec_ctx->codec_id);
    if (data.decoder == NULL)
    {
        clearAppData();
        return;
    }

    // open the decoder
    if (avcodec_open2(data.codec_ctx, data.decoder, NULL) < 0)
    {
        clearAppData();
        return;
    }

    // allocate the video frames
    data.av_frame = av_frame_alloc();
    data.gl_frame = av_frame_alloc();
    int size = avpicture_get_size(AV_PIX_FMT_RGBA, data.codec_ctx->width,
        data.codec_ctx->height);
    uint8_t *internal_buffer = (uint8_t *)av_malloc(size * sizeof(uint8_t));
    avpicture_fill((AVPicture *)data.gl_frame, internal_buffer, AV_PIX_FMT_RGBA,
        data.codec_ctx->width, data.codec_ctx->height);
    data.packet = (AVPacket *)av_malloc(sizeof(AVPacket));

Текущий код работает, когда я сохраняю data.av_frame, но когда я пытаюсь заменить его на data.gl_frame, тогда ничего не сохраняется.

Как можноя сохраняю данные-> gl_frame в буфер.

bool Sum_ClipPlayer::Sum_ClipPlayer::initReadFrame()
{
    do {

        glBindTexture(GL_TEXTURE_2D, data.frame_tex);
        int error = av_read_frame(data.fmt_ctx, data.packet);

        if (error)
        {           
            av_free_packet(data.packet);
            return false;
        }


        if (data.packet->stream_index == data.stream_idx)
        {
            int frame_finished = 0;

            if (avcodec_decode_video2(data.codec_ctx, data.av_frame, &frame_finished,
                data.packet) < 0) {
                av_free_packet(data.packet);
                return false;
            }

            if (frame_finished)
            {               
                if (!data.conv_ctx)
                {
                    data.conv_ctx = sws_getContext(data.codec_ctx->width,
                        data.codec_ctx->height, data.codec_ctx->pix_fmt,
                        data.codec_ctx->width, data.codec_ctx->height, AV_PIX_FMT_RGBA,
                        SWS_BICUBIC, NULL, NULL, NULL);
                }
                sws_scale(data.conv_ctx, data.av_frame->data, data.av_frame->linesize, 0,
                    data.codec_ctx->height, data.gl_frame->data, data.gl_frame->linesize);

                glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, data.codec_ctx->width,
                    data.codec_ctx->height, GL_RGBA, GL_UNSIGNED_BYTE,
                    data.gl_frame->data[0]);    


                AVFrame *cachedValue = av_frame_alloc();
                cachedValue->format = data.av_frame->format;
                cachedValue->width = data.av_frame->width;
                cachedValue->height = data.av_frame->height;
                cachedValue->channels = data.av_frame->channels;
                cachedValue->channel_layout = data.av_frame->channel_layout;
                cachedValue->nb_samples = data.av_frame->nb_samples;
                av_frame_get_buffer(cachedValue, 32);
                av_frame_copy(cachedValue, data.av_frame);
                av_frame_copy_props(cachedValue, data.av_frame);
                cache.push_back(cachedValue);
            }
        }


    } while (data.packet->stream_index != data.stream_idx);
    return true;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...