Decoding opus using libavcodec from FFmpeg

删除回忆录丶 提交于 2019-12-23 19:23:12

问题


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);

回答1:


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

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;
    (...)  
}

I've replaced that by:

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);


来源:https://stackoverflow.com/questions/41589934/decoding-opus-using-libavcodec-from-ffmpeg

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!