Ошибка масштабирования FFMPEG — неверный размер

Я работаю над проектом в FFMPEG, и сейчас я застрял в проблеме.

Что я пытаюсь сделать, так это преобразовать изображение png в видеофайл mpeg. Мне уже удалось взять информацию с картинки, но почему-то не получается конвертировать картинку в формат YUV. Он возвращает «0x0-> 0x0 - недопустимые размеры масштабирования».

Вот мой код:

 AVFrame *pFrame;
AVFrame *pFrameYUV;
pFrame = av_frame_alloc();
pFrameYUV = av_frame_alloc();
int numBytes;//Groesse des Bildes
uint8_t *buffer= NULL;
numBytes=avpicture_get_size(AV_PIX_FMT_RGB24, pCodecCtx->width,pCodecCtx->height); 
buffer=(uint8_t *)av_malloc(numBytes*sizeof(uint8_t)); 

/*avpicture_fill((AVPicture *)pFrameYUV, buffer, AV_PIX_FMT_YUV420P,
                pCodecCtx->width, pCodecCtx->height);*/
av_image_fill_arrays(pFrameYUV->data,pFrameYUV->linesize,buffer,AV_PIX_FMT_YUV420P,pCodecCtx->width,pCodecCtx->height,32);


struct SwsContext *sws_ctx = NULL;

AVPacket packet;
// initialize SWS context for software scaling
sws_ctx=sws_getCachedContext(NULL,pFrame->width,pFrame->height,AV_PIX_FMT_RGB24,pFrameYUV->width,pFrameYUV->height,AV_PIX_FMT_YUV420P,0,0,0,0);
pFrameYUV->height= pFrame->height;
pFrameYUV->width= pFrame->width;

while (av_read_frame(pFormatCtx,&packet)>=0)
{
    if(packet.stream_index == videoStream)
    {
        avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, &packet); 

        if(frameFinished)
        {

        sws_scale(sws_ctx, (uint8_t const * const *)pFrame->data,
          pFrame->linesize, 0, pCodecCtx->height,
          pFrameYUV->data, pFrameYUV->linesize);
        printf("%d",pFrameYUV->height);

    }
    }
    av_free_packet(&packet);
}

РЕДАКТИРОВАТЬ:

После преобразования я попытался закодировать кадр в пакет, но размер пакета равен 0. Код

AVPacket pkt;
av_init_packet(&pkt);
pkt.stream_index= st->index;
pkt.data= buffer;
pkt.size=numBytes;
int got_pkt;
test=avcodec_encode_video2(st->codec,&pkt,pFrameYUV,&got_pkt);

printf("%d",got_pkt);

person Van Gan    schedule 16.06.2016    source источник


Ответы (1)


Эти значения pFrameYUV->height, pFrame->height, pFrameYUV->width, pFrame->width не были установлены при вызове sws_getCachedContext.

Вы имеете в виду, что размер не меняется? Если это так, установите их перед sws_getCachedContext.

pFrameYUV->height = pFrame->height = pCodecCtx->height;
pFrameYUV->width = pFrame->width = pCodecCtx->width;
sws_ctx=sws_getCachedContext(NULL,pFrame->width,pFrame->height,AV_PIX_FMT_RGB24,pFrameYUV->width,pFrameYUV->height,AV_PIX_FMT_YUV420P,0,0,0,0);
person alijandro    schedule 16.06.2016
comment
Я думал, что они установлены с помощью av_image_fill_Arrays? Должен ли я также установить пикс fmt кадра? - person Van Gan; 16.06.2016
comment
Да, вы также должны установить pix_fmt для безопасности. - person alijandro; 16.06.2016
comment
Эй, это работает. Но поле данных pFrameYUV после масштабирования остается пустым. Как мне установить это? - person Van Gan; 16.06.2016
comment
sws_scale заполнит для вас. Вы должны проверить возвращаемое значение avcodec_decode_video2 с помощью frameFinished, чтобы убедиться, что декодирование кадра прошло успешно. - person alijandro; 16.06.2016
comment
Декодирование выполнено успешно, кадр завершен, но поле данных pFrameYUV все еще пусто - person Van Gan; 16.06.2016
comment
Хорошо, раскомментируйте эту строку avpicture_fill. av_image_fill_arrays не будет выделять вам AVFrame памяти. - person alijandro; 16.06.2016
comment
Согласно документации avpicture_fill устарел, и следует использовать av_Image_fill_Arrays. - person Van Gan; 16.06.2016
comment
Еще одна странная вещь: когда я пытаюсь закодировать pFrameYUV, он все еще говорит, что вместо этого мне нужно использовать av_send_Frame. И когда я вызываю av_send_Frame, я возвращаю -22 (что является ошибкой) - person Van Gan; 16.06.2016
comment
Если он устарел, используйте av_image_alloc вместо av_image_fill_arrays, чтобы выделить AVFrame памяти. Да, новый API — это av_send_frame и av_receive_packet. Меняем на новый. - person alijandro; 16.06.2016
comment
Как проверить, копируются ли данные из pFrame в pFrameYUV? - person Van Gan; 16.06.2016
comment
sws_scale вернет высоту в случае успеха. нет лучшего способа проверить, насколько я знаю. - person alijandro; 16.06.2016
comment
Я попытался скопировать кадр в пакет, используя av_inerleaved_write_Frame. Размер пакета 0, значит в pFameYUV ничего нет - person Van Gan; 16.06.2016
comment
Не видя вашего кода, я не мог понять, что произошло в вашем коде. - person alijandro; 16.06.2016
comment
AVPacket должен быть заполнен энкодером. pkt.data = NULL; pkt.size = 0; - person alijandro; 16.06.2016
comment
Это не работает. Я думаю, проблема в sws_scale - person Van Gan; 16.06.2016
comment
Изменить эту строку avpicture_get_size(AV_PIX_FMT_YUV420P, pCodecCtx->width,pCodecCtx->height); - person alijandro; 16.06.2016
comment
В данных pFrameYUv нет абсолютно ничего, вот в чем проблема. - person Van Gan; 16.06.2016