2016-11-07 117 views
0

我正在编写一个程序以从视频流中提取图像。到目前为止,我已经想出了如何寻找正确的帧,解码视频流,并将相关数据收集到AVFrame结构中。我现在试图将数据写入JPEG图像,但我的代码无法正常工作。我得到的代码是从这里:https://gist.github.com/RLovelett/67856c5bfdf5739944ed如何将AVFrame写入JPEG图像

int save_frame_as_jpeg(AVCodecContext *pCodecCtx, AVFrame *pFrame, int FrameNo) { 
    AVCodec *jpegCodec = avcodec_find_encoder(AV_CODEC_ID_JPEG2000); 
    if (!jpegCodec) { 
     return -1; 
    } 
    AVCodecContext *jpegContext = avcodec_alloc_context3(jpegCodec); 
    if (!jpegContext) { 
     return -1; 
    } 

    jpegContext->pix_fmt = pCodecCtx->pix_fmt; 
    jpegContext->height = pFrame->height; 
    jpegContext->width = pFrame->width; 

    if (avcodec_open2(jpegContext, jpegCodec, NULL) < 0) { 
     return -1; 
    } 
    FILE *JPEGFile; 
    char JPEGFName[256]; 

    AVPacket packet = {.data = NULL, .size = 0}; 
    av_init_packet(&packet); 
    int gotFrame; 

    if (avcodec_encode_video2(jpegContext, &packet, pFrame, &gotFrame) < 0) { 
     return -1; 
    } 

    sprintf(JPEGFName, "dvr-%06d.jpg", FrameNo); 
    JPEGFile = fopen(JPEGFName, "wb"); 
    fwrite(packet.data, 1, packet.size, JPEGFile); 
    fclose(JPEGFile); 

    av_free_packet(&packet); 
    avcodec_close(jpegContext); 
    return 0; 
} 

如果我使用的代码,我得到的第一个错误是关于time_base上没有设置AVCodecContext。我把它设置为我的视频解码结构的时基。现在我得到另一个错误

[jpeg2000 @ 0x7fd6a4015200] dimensions not set 
[jpeg2000 @ 0x7fd6a307c400] dimensions not set 
[jpeg2000 @ 0x7fd6a5800000] dimensions not set 
[jpeg2000 @ 0x7fd6a307ca00] dimensions not set 
[jpeg2000 @ 0x7fd6a3092400] dimensions not set 

和图像仍然没有被写入。从Github Gist,一位评论者声称元数据没有写入JPEG图像,但我应该如何编写这个元数据?我确实设置了编码上下文的宽度和高度,所以我不确定它为什么声称没有设置尺寸。

+0

如果你打印出的宽度和高度做出来的价值是有道理的?你有没有做过什么来检查进入的帧是否正确? – Chris

回答

3

JPEG2000不是jpeg。要编码JPEG图像,请使用AV_CODEC_ID_MJPEG。 MJPEG代表“动态JPEG”,这是通常调用组成视频流的一系列JPEG图片的方式。

+0

谢谢!我最终使用MJPEG并使其工作。 –