FFMPEG解碼海思音訊資料
阿新 • • 發佈:2018-12-16
解碼流程: 1、 讀取海思g726音訊資料,海思g726音訊會多4個位元組的海思頭資訊。 2、選擇ffmpeg g726編碼器進行解碼。ffmpeg g726解碼器包括:AV_CODEC_ID_ADPCM_G726、AV_CODEC_ID_ADPCM_G726LE。如果海思g726碼流型別為asf時,請選擇AV_CODEC_ID_ADPCM_G726解碼器型別;如果海思g726碼流型別為RFC3551標準時,請選擇AV_CODEC_ID_ADPCM_G726LE解碼器型別。 例項程式碼:
解碼流程:
1、 讀取海思g726音訊資料,海思g726音訊會多4個位元組的海思頭資訊。
2、選擇ffmpeg g726編碼器進行解碼。ffmpeg g726解碼器包括:AV_CODEC_ID_ADPCM_G726、AV_CODEC_ID_ADPCM_G726LE。如果海思g726碼流型別為asf時,請選擇AV_CODEC_ID_ADPCM_G726解碼器型別;如果海思g726碼流型別為RFC3551標準時,請選擇AV_CODEC_ID_ADPCM_G726LE解碼器型別。
例項程式碼:
#define Hisi_AUDIO_HERDER_LEN 4 //hisi 音訊資料頭 extern "C" { #include "libavcodec/avcodec.h" #include "libavformat/avformat.h" #include "libavutil/frame.h" #include "libswscale/swscale.h" #include "libavutil/imgutils.h" } //連結 ffmpeg lib庫 AVCodec *codec; AVCodecContext *c= NULL; AVPacket avpkt; AVFrame *decoded_frame = NULL; avcodec_register_all(); av_init_packet(&avpkt); /* find the mpeg audio decoder */ /* ffmpeg g726編碼器:AV_CODEC_ID_ADPCM_G726 ffmpeg g726解碼器包括:AV_CODEC_ID_ADPCM_G726、AV_CODEC_ID_ADPCM_G726LE 如果海思g726碼流型別為asf時,請選擇AV_CODEC_ID_ADPCM_G726解碼器型別 如果海思g726碼流型別為RFC3551標準時,請選擇AV_CODEC_ID_ADPCM_G726LE解碼器型別 */ codec = avcodec_find_decoder(AV_CODEC_ID_ADPCM_G726LE); if (!codec) { fprintf(stderr, "codec not found\n"); return; } c = avcodec_alloc_context3(codec); //取樣率= 8000 每個取樣用的bit數= 16 通道數= 1 /* bits_per_coded_sample:表示編碼壓縮bit值與取樣率的bit值之比。 如果為g726音訊時,表示g726碼流壓縮與取樣率比值。比如kbps碼流壓縮比為:k/8k = 5,kbps碼流壓縮比為k/8k = 2。 */ c->bits_per_coded_sample = 5; c->channels = 1; c->sample_fmt = AV_SAMPLE_FMT_S16; c->sample_rate = 8000; c->codec_type = AVMEDIA_TYPE_AUDIO; //c->bit_rate = 16000; int iRet = avcodec_open2(c, codec,NULL); if ( iRet < 0 ) { fprintf(stderr, "could not open codec\n"); return; } CString filePath = ""; CString newlFilePath = ""; char szFilter[] = {"g726 Files (*.g726_hisi)|*.g726_hisi||"}; CFileDialog dlg(TRUE,NULL,NULL,OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,szFilter,NULL); if(dlg.DoModal() == IDOK) { filePath = dlg.GetPathName(); newlFilePath = filePath; newlFilePath.Replace(".g726_hisi",".hisi2ff.pcm"); BOOL bRet = 0; FILE * fpSrc = fopen(filePath.GetBuffer(filePath.GetLength()),"rb"); FILE * fpDst = fopen(newlFilePath.GetBuffer(newlFilePath.GetLength()),"wb+"); char szData[100] = {0}; char szOutData[320] = {0}; int nDataLen = 100; int nOutDataLen = 320; int nReadedSize = 0; unsigned short usHisiHeader[2] = {0}; if(fpSrc != NULL) { while(TRUE) { //讀取頭標記 nDataLen = Hisi_AUDIO_HERDER_LEN; nReadedSize = fread(szData,sizeof(char),nDataLen,fpSrc); if(nReadedSize < nDataLen) { break; } memcpy(usHisiHeader,szData,Hisi_AUDIO_HERDER_LEN); int nAudioFrameDataLen = (usHisiHeader[1] & 0x00ff) * sizeof(unsigned short); nDataLen = nAudioFrameDataLen; //讀取音訊幀資料 nReadedSize = fread(szData,sizeof(char),nDataLen,fpSrc); if(nReadedSize < nDataLen) { break; } avpkt.data = (uint8_t *)szData; avpkt.size = nReadedSize; int got_frame = 0; if (!decoded_frame) { if (!(decoded_frame = avcodec_alloc_frame())) { return; } } else { avcodec_get_frame_defaults(decoded_frame); } int len = avcodec_decode_audio4(c, decoded_frame, &got_frame, &avpkt); if (len < 0) { return; } if (got_frame) { /* if a frame has been decoded, output it */ int data_size = av_samples_get_buffer_size(NULL, c->channels, decoded_frame->nb_samples, c->sample_fmt, 1); fwrite(decoded_frame->data[0], 1, data_size, fpDst); } } fclose(fpSrc); fclose(fpDst); avcodec_close(c); av_free(c); av_free(decoded_frame); } }