2017-01-11 100 views
2

我想解碼opus使用libavcodec。我能夠單獨使用libopus庫。但我想用libavcodec實現同樣的效果。我想弄明白爲什麼它不適合我的情況。我有一個rtp流,並試圖解碼它。解碼數據包的結果與輸入相同。經過解碼的幀通常包含pcm值,而不是實際發送的Im接收opus幀。請幫幫我。FFmpeg使用libavcodec解碼opur

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

具體什麼錯在何處?初始化步驟是否失敗?或解碼步驟?或者所有的通話都成功,但音頻數據聽起來不正確?你是如何測試的?在將數據作爲輸入提供給解碼器之前,您是否通過RTP負載解析器運行RTP數據?在運行代碼時,你是否在stderr上收到任何消息? –

+0

我解析了RTP。在緩衝區它只有OPUS數據包。我有一個與liboupus的opus_decode並行工作,它的工作正常。但不使用libavcodec。它不會產生任何錯誤的主要問題。初始化或沒有失敗。 avcodec_decode_audio4返回給我一個幀,它具有我的opus數據包的數據包大小,該數據包被髮送用於解碼。我沒有收到任何錯誤消息。這是主要問題。 – Abu

+0

avcodec_decode_audio4()中的「client_sockt_num_1」是否是一個錯字? –

回答

1

我有同樣的問題。我的流編碼爲8kHz,ffmpeg始終以48kHz(硬編碼)初始化libopus。

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