FFmpeg - avcodec_receive_frame возвращает 0, но кадры недействительны - PullRequest
1 голос
/ 09 июля 2019

Я пытался извлечь изображения из видео, но не те, которые имеют кодек PNG.Мой код прекрасно работает с теми, с JPEG.avcodec_receive_frame работал успешно, но данные кадров были как мусор?Нужно ли делать что-то особенное для демультиплексирования при работе с PNG?

Исключение, выданное в 0x00007FFF7DF34B9A (msvcrt.dll) в Program.exe: 0xC0000005: Место чтения нарушения доступа 0x00000000000003F0 при вызове avcodec_send_frame в моей функции saveImage, что означает, что я получаю доступ к недействительной или неразрешенной памяти, которую я предполагаю,Как это произошло?

enter image description here

Просто предположим, что все вызовы функций возвращали 0 до тех пор, пока не сгенерируется исключение.

Расшифровка:

bool ImageExtractor::decode() {
    // some other code here
    ret = avcodec_send_packet(codec_ctx, packet); // returned 0
    ret = avcodec_receive_frame(codec_ctx, frame); // returned 0
    if (ret == 0) {
        if (count >= target_frame) {
            snprintf(buf, sizeof(buf), "%s/%d.png", destination.toLocal8Bit().data(), count);
            saveImage(frame, buf); // a function that writes images on disk 
       }
    // some other code here
}


bool ImageExtractor::saveImage(AVFrame *frame, char *destination) {
     AVFormatContext *imgFmtCtx = avformat_alloc_context();
     pFormatCtx->oformat = av_guess_format("mjpeg", NULL, NULL);

     // some other code here

    if (!frame)
        std::cout << "invalid frame \n";

    if (!imgCodecCtx) // AV_CODEC_ID_MJPEG(7)
        std::cout << "invalid codec ctx \n";

    ret = avcodec_send_frame(imgCodecCtx, frame); // everything stopped here
}

Демуксирование:

avformat_open_input(&format_ctx, source.toLocal8Bit(), nullptr, nullptr);
vsi = av_find_best_stream(format_ctx, AVMEDIA_TYPE_VIDEO, -1, -1, nullptr, 0);
codec_par = avcodec_parameters_alloc();
avcodec_parameters_copy(codec_par, format_ctx->streams[vsi]->codecpar);

AVCodec* codec = avcodec_find_decoder(codec_par->codec_id); // AV_CODEC_ID_PNG(61)
codec_ctx = avcodec_alloc_context3(codec);
avcodec_parameters_to_context(codec_ctx, codec_par);
avcodec_parameters_free(&codec_par);
avcodec_open2(codec_ctx, codec, 0);
...