2016-11-07 124 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並使其工作。 –