2017-01-11 13 views
2

Я пытаюсь декодировать opus с помощью libavcodec. Я могу сделать это, используя библиотеку libopus. Но я пытаюсь добиться того же, используя libavcodec. Я пытаюсь понять, почему он не работает в моем случае. У меня поток rtp и я пытаюсь его декодировать. Результат в декодированном пакете такой же, как и вход. Декодированный кадр обычно содержит значения pcm вместо того, что я получаю рамку opus, которую я отправляю. Пожалуйста, помогите мне.Декодирование opus с помощью libavcodec из FFmpeg

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

Что конкретно идет не так? Не удалось ли выполнить этап init? Или шаг декодирования? Или все звонки преуспевают, но звуковые данные звучат неправильно? Как вы это протестировали? Выполняли ли вы данные RTP через анализатор полезной нагрузки RTP перед подачей данных в качестве входных данных в декодер? Получаете ли вы какие-либо сообщения на stderr во время запуска кода? –

+0

Я проанализировал RTP. В Buffer - только OPUS-пакет. У меня параллельная работа с opus_decode от liboupus, работающая нормально. Но с помощью libavcodec его нет. Основная проблема не вызывает ошибок. Init или ничего не сработает. Avcodec_decode_audio4 возвращает мне фрейм с размером пакета моего пакета opus, который был отправлен для декодирования. Я не получаю сообщение об ошибке. Это главная проблема. – Abu

+0

Является ли «client_sockt_num_1» в avcodec_decode_audio4() опечаткой? –

ответ

1

У меня была та же проблема. Мой поток был закодирован с 8 кГц, а ffmpeg всегда инициализирует libopus с 48 кГц (жестко закодированный).

См FFmpeg фрагмент кода:

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; 

и декодирование работает сейчас. Интересно, поддерживает ли этот декодер динамические изменения битрейта.

Длина исходного кадра должна быть рассчитана:

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