2013-03-11 55 views
0

所以,我寫了一個ffmpeg的基本解碼器,它簡單地讀取輸入幀像素數據(使用RGB 8格式存儲),並將其直接放入輸出緩衝區。 (也是RGB 8)問題是,當我在ffmpeg中使用這個解碼器時,它說有1個未釋放的緩衝區(使用ffmpeg -i Test.utah Test.png進行測試)。不幸的是,我不確定它在說什麼緩衝區,因爲我沒有創建自己的緩衝區。我嘗試在我的解碼器關閉方法中釋放AVContext的coded_frame緩衝區,但這會導致分段錯誤。ffmpeg buffer not released

任何幫助將不勝感激。

static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt) 
{ 
    int ret;   /*Hold return from get_buffer */ 
    int skipSize;  /*Number of dummy bytes to skip per line*/ 
    int fseek=8;  /*Location of the first pixel*/ 
    int i=0; int j=0; /*Output buffer seek index/Input Buffer seek index*/ 
    const uint8_t *buf = avpkt->data; /*Hold a pointer to the input buffer*/ 
    AVFrame *pict=data; /*Hold a pointer to the output buffer*/ 

    /*Set the output pixel format to RGB8*/ 
    avctx->pix_fmt = AV_PIX_FMT_RGB8; 

    /*Get the width and height*/ 
    bytestream_get_le32(&buf); 
    avctx->width=bytestream_get_le16(&buf); 
    avctx->height=bytestream_get_le16(&buf); 

    /*Release the old buffer*/ 
    if (pict->data[0]) avctx->release_buffer(avctx, pict); 

    /*Aquire a large enough data buffer to hold the decompressed picture*/ 
    if (ret=ff_get_buffer(avctx, pict) < 0) return ret; 
    skipSize=pict->linesize[0] - avctx->width; 

    /*Transfer input buffer to output buffer*/ 
    for(int y=0;y<avctx->height;y++){ 
     for(int x=0;x<avctx->width;x++){ 
      pict->data[0][i]=avpkt->data[fseek+j]; 
      j++; 
      i++; 
     } 
     i+=skipSize; 
    } 

    /*Inform ffmpeg the output is a key frame and that it is ready for external usage*/ 
    pict->pict_type  = AV_PICTURE_TYPE_I; 
    pict->key_frame  = 1; 
    *got_frame=1; 
    return 0; 
} 
+0

這是一個代碼的負載 - 你認爲你可以修剪它只有相關的部分?如果你有那麼多的代碼,用戶很難幫助你。可能將關鍵部分分開,並將整個代碼塊保留在問題底部。 – Jesse 2013-03-11 00:33:33

+0

我希望更多地減少這段代碼,但它是相當裸露的骨頭。不過,我已經編輯了它,以儘可能使其可讀。 – ByteByter 2013-03-11 02:04:13

回答

1

您沒有發佈該解碼器對象的.close方法。你是否有一個?在大多數FFmpeg解碼器中,這採用codecname_decode_end()的形式。這種方法/功能在解碼完成後被調用,並給解碼器提供清理後的機會。

在那裏我有這個打算:

decode_frame call #0: no frame held; frame allocated 
decode_frame call #1: free frame allocated during call #0; frame allocated 
decode_frame call #2: free frame allocated during call #1; frame allocated 
[...] 
decode_frame call #n: free frame allocated during call #(n-1); frame allocated 

但是當這一切都完成後,解碼器仍持有decode_frame呼叫#N期間分配的框架。 codecname_decode_end()允許解碼器釋放最後一幀。

+0

最後一幀存儲在哪裏?在AVContext coded_frame中? (avctx-> coded_frame-> data [0])avctx-> release_buffer(avctx,avctx-> coded_frame);我試過在關閉方法釋放這個,如果(avctx-> coded_frame-> data [0])avctx-> release_buffer(avctx,avctx-> coded_frame); 但它只是導致分段錯誤發生。 – ByteByter 2013-03-11 21:34:52

+0

我建議運行gdb或Valgrind快速診斷段錯誤(並確保您正在運行ffmpeg的調試版本,它是'ffmpeg_g',因此您可以獲得符號)。你熟悉這些工具嗎? – 2013-03-11 21:38:30

+0

我對gdb略微熟悉(足夠做一個堆棧跟蹤) 你需要爲ffmpeg_g做一個特殊的構建嗎? – ByteByter 2013-03-11 21:43:15