Compartilhamento de tecnologia

Comparação de funções antigas e novas do ffmpeg

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

O blog de “kn-zheng”, o chefe do parque de blogs de portabilidade
A partir do FFmpeg 3.0, muitas interfaces novas são usadas, como segue:

1. avcodec_decode_video2() A função de decodificação original é desmontada em duas funções avcodec_send_packet() e avcodec_receive_frame(). O uso específico é o seguinte:

old:
avcodec_decode_video2(pCodecCtx, pFrame, &got_picture, pPacket);
new:
avcodec_send_packet(pCodecCtx, pPacket);
avcodec_receive_frame(pCodecCtx, pFrame);
  • 1
  • 2
  • 3
  • 4
  • 5

2. A função de codificação correspondente a avcodec_encode_video2() também é dividida em duas funções avcodec_send_frame() e avcodec_receive_packet(). O uso específico é o seguinte:

old:
avcodec_encode_video2(pCodecCtx, pPacket, pFrame, &got_picture);
new:
avcodec_send_frame(pCodecCtx, pFrame); avcodec_receive_packet(pCodecCtx, pPacket);
  • 1
  • 2
  • 3
  • 4

3. avpicture_get_size() agora usa av_image_get_size(). O uso específico é o seguinte:

old:
avpicture_get_size(AV_PIX_FMT_YUV420P, pCodecCtx->width, pCodecCtx->height);
new: //最后一个参数align这里是置1的,具体看情况是否需要置1
av_image_get_buffer_size(AV_PIX_FMT_YUV420P, pCodecCtx->width, pCodecCtx->height, 1);
  • 1
  • 2
  • 3
  • 4

4. avpicture_fill() agora usa av_image_fill_arrays. O uso específico é o seguinte:

old:
avpicture_fill((AVPicture *)pFrame, buffer, AV_PIX_FMT_YUV420P, pCodecCtx->width, pCodecCtx->height);
new: //最后一个参数align这里是置1的,具体看情况是否需要置1
av_image_fill_arrays(pFrame->data, pFrame->linesize, buffer, AV_PIX_FMT_YUV420P, pCodecCtx->width, pCodecCtx->height,1);
  • 1
  • 2
  • 3
  • 4

5. Em relação aos problemas de codec, alguns podem ser alterados diretamente para codecpar, mas às vezes isso está errado, então ainda estou explorando aqui uma mudança no método de atribuição de pCodecCtx e pCodec.

old:
pCodecCtx = pFormatCtx->streams[video_index]->codec; 
pCodec = avcodec_find_decoder(pFormatCtx->streams[video_index]->codec->codec_id);
new:
pCodecCtx = avcodec_alloc_context3(NULL)avcodec_parameters_to_context(pCodecCtx,pFormatCtx->streams[video_index]->codecpar);
pCodec = avcodec_find_decoder(pCodecCtx->codec_id);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

6、PIX_FMT_YUV420P -> AV_PIX_FMT_YUV420P

7. 'AVStream::codec': Declarado como obsoleto:

old:
pCodecCtx = pFormatCtx->streams[videoindex]->codec;
new:
pCodecCtx = avcodec_alloc_context3(NULL)avcodec_parameters_to_context(pCodecCtx, pFormatCtx->streams[videoindex]->codecpar);
  • 1
  • 2
  • 3
  • 4
  • 5

8. 'avpicture_fill': Declarado como obsoleto:

old:
avpicture_fill((AVPicture *)pFrameYUV, out_buffer, AV_PIX_FMT_YUV420P, pCodecCtx->width, pCodecCtx->height);
new:
av_image_fill_arrays(pFrameYUV->data, pFrameYUV->linesize, out_buffer, AV_PIX_FMT_YUV420P, pCodecCtx->width, pCodecCtx->height, 1);
  • 1
  • 2
  • 3
  • 4

9. 'avcodec_decode_video2': Declarado como obsoleto:

old:
ret = avcodec_decode_video2(pCodecCtx, pFrame, &got_picture, packet); //got_picture_ptr Zero if no frame could be decompressed
new:
ret = avcodec_send_packet(pCodecCtx, packet);
got_picture = avcodec_receive_frame(pCodecCtx, pFrame); //got_picture = 0 success, a frame was returned //注意:got_picture含义相反
或者:
int ret = avcodec_send_packet(aCodecCtx, &pkt);
if (ret != 0)
{
prinitf("%s/n","error");
return;
} 
while( avcodec_receive_frame(aCodecCtx, &frame) == 0)
{
//读取到一帧音频或者视频 //处理解码后音视频 frame
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

10. 'av_free_packet': Declarado como obsoleto:

old:
av_free_packet(packet);
new:
av_packet_unref(packet);
  • 1
  • 2
  • 3
  • 4

11. avcodec_decode_audio4: Declarado como obsoleto:

old:
result = avcodec_decode_audio4(dec_ctx, out_frame, &got_output, &enc_pkt);
new:
int ret = avcodec_send_packet(dec_ctx, &enc_pkt);
if (ret != 0)
{
prinitf("%s/n","error");
} 
while( avcodec_receive_frame(dec_ctx, &out_frame) == 0)
{
//读取到一帧音频或者视频
//处理解码后音视频 frame
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
旧接口av_register_all()------------新版不需要注册
PKT_FLAG_KEY ---------------->AV_PKT_FLAG_KEY
AV_CODEC_CAP_DELAY----->AV_CODEC_CAP_DELAY
guess_format ------------>av_guess_format 
av_alloc_format_context ---------->avformat_alloc_output_context 
CODEC_TYPE_VIDEO ----------------->AVMEDIA_TYPE_VIDEO
CODEC_TYPE_AUDIO ---------------->AVMEDIA_TYPE_AUDIO
audio_resample_init ----------------->av_audio_resample_init 
PIX_FMT_YUV420P -> AV_PIX_FMT_YUV420P
AVStream::codec     被声明为已否决
‘avpicture_get_size’: 被声明为已否决
新的API中将AVStream结构体中codec作了遗弃处理,当需要解码器上下文的时候,需要用AVCodecParameters去转化,解决方案是如下
av_free_packet(packet)--------------------> av_packet_unref(packet);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13