使用FFmpeg的libavcodec解码作品 [英] Decoding opus using libavcodec from FFmpeg

查看:380
本文介绍了使用FFmpeg的libavcodec解码作品的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用libavcodec解码作品.我可以单独使用libopus库来做到这一点.但是我正在尝试使用libavcodec达到相同的效果.我试图弄清楚为什么它在我的情况下不起作用.我有一个rtp流,并尝试对其进行解码.解码包中的结果与输入相同.解码后的帧通常包含pcm值,而不是实际发送的Im正在接收的Opus帧.请帮助我.

I am trying to decode opus using libavcodec. I am able to do it using libopus library alone. But I am trying to acheive same using libavcodec. I am trying to figure it out Why its not working in my case. I have an rtp stream and trying to decode it. The result in decoded packet is same as input. Decoded frame normally contain pcm values instead of that Im receving opus frame that actually I send. Please help me.

av_register_all();
avcodec_register_all();
AVCodec *codec;
AVCodecContext *c = NULL;
AVPacket avpkt;
AVFrame *decoded_frame = NULL;
av_init_packet(&avpkt);
codec = avcodec_find_decoder(AV_CODEC_ID_OPUS);
if (!codec) {
     printf("Codec not found\n");
     exit(1);
}
c = avcodec_alloc_context3(codec);
if (!c) {
   printf("Could not allocate audio codec context\n");
   exit(1);
}
/* put sample parameters */
c->sample_rate = 48000;
c->request_sample_fmt = AV_SAMPLE_FMT_FLT;
c->channels = 2;
/* open it */
if (avcodec_open2(c, codec, NULL) < 0) {
    printf("Could not open codec\n");
    exit(1);
}

AVPacket avpkt;
AVFrame *decoded_frame = NULL;
av_init_packet(&avpkt);
avpkt.data = Buffer;  // Buffer is packet data here
avpkt.size = len;    // length of the packet
int i, ch;

if (!decoded_frame) {
    if (!(decoded_frame = av_frame_alloc())) {
        RELAY_SERVER_PRINT("Could not allocate audio frame\n");
        exit(1);
    }
}
int ret;
int got_frame = 0;
ret = avcodec_decode_audio4(c, decoded_frame, &got_frame, &avpkt);
if (ret < 0) {
        fprintf(stderr, "Error decoding audio frame (%s)\n", av_err2str(ret));
        return ret;
    }
printf("length %i\n", decoded_frame->pkt_size);

推荐答案

我遇到了同样的问题.我的流使用8kHz编码,而ffmpeg始终使用48kHz(硬编码)初始化libopus.

I had the same problem. My stream was encoded with 8kHz and ffmpeg is always initializing libopus with 48kHz (hard-coded).

请参阅ffmpeg代码段:

See ffmpeg code snippet:

static av_cold int libopus_decode_init(AVCodecContext *avc)
{
    (...)
    avc->sample_rate    = 48000;
    avc->sample_fmt     = avc->request_sample_fmt == AV_SAMPLE_FMT_FLT ?
                          AV_SAMPLE_FMT_FLT : AV_SAMPLE_FMT_S16;
    (...)  
}

我将其替换为:

if (avc->sample_rate == 0)
    avc->sample_rate = 48000;

和解码现在可以使用了.我不知道此解码器是否支持动态比特率更改.

and decoding works now. I wonder if this decoder supports dynamic bitrate changes.

原始帧的长度必须通过以下方式计算:

The length of the raw frame has to be calculated by:

int frame_size = decoded_frame->nb_samples * av_get_bytes_per_sample(decoded_frame->sample_fmt);

这篇关于使用FFmpeg的libavcodec解码作品的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆