升級 FFmpeg 版本(3.x → 4.x+)編譯既有專案時,常遇到 C4996 警告:avcodec_alloc_frame、avcodec_free_frame 等函式已標記棄用。本文說明替換規則與記憶體管理差異,助你快速遷移。
warning C4996: 'avcodec_alloc_frame': was declared deprecated
warning C4996: 'avcodec_free_frame': was declared deprecated

| 舊 API(棄用) | 新 API(建議) | 備註 |
|---|---|---|
avcodec_alloc_frame() | av_frame_alloc() | 回傳 AVFrame*,失敗回傳 NULL |
avcodec_free_frame(frame) | av_frame_free(&frame) | 參數為雙重指標,會將指標設為 NULL |
avcodec_get_frame_defaults(frame) | 不需要 | av_frame_alloc() 已初始化為預設值 |
avpicture_alloc() | av_frame_get_buffer(frame, align) | 需先 av_frame_alloc() 並設定 format/width/height |
avpicture_free() | av_frame_unref(frame) + av_frame_free() | 解參考緩衝區再釋放結構體 |
AVFrame* frame = avcodec_alloc_frame();
if (!frame) return -1;
// 設定參數後分配緩衝區
avpicture_alloc((AVPicture*)frame, AV_PIX_FMT_YUV420P, width, height);
// ... 使用 frame ...
avpicture_free((AVPicture*)frame);
avcodec_free_frame(frame);
AVFrame* frame = av_frame_alloc();
if (!frame) return -1;
frame->format = AV_PIX_FMT_YUV420P;
frame->width = width;
frame->height = height;
int ret = av_frame_get_buffer(frame, 32); // 32-byte 對齊
if (ret < 0) {
av_frame_free(&frame);
return ret;
}
// ... 使用 frame ...
av_frame_unref(frame); // 釋放緩衝區引用計數
av_frame_free(&frame); // 釋放 AVFrame 結構體
AVFrame 同時用於編碼/解碼/濾鏡,不再區分 AVPicture。refcount 機制,av_frame_ref()/unref() 管理緩衝區生命週期,支援零拷貝傳遞。av_frame_get_buffer(frame, align) 的 align 建議 32 或 64(SIMD 優化需求)。/wd4996 抑制警告(不建議長期使用)。| 舊函式 | 新函式 |
|---|---|
avcodec_encode_video2 | avcodec_send_frame / avcodec_receive_packet |
avcodec_decode_video2 | avcodec_send_packet / avcodec_receive_frame |
av_free_packet | av_packet_unref |
av_malloc / av_free | 仍可用,但推薦 av_mallocz / av_freep |