1. 程式人生 > >ffmpeg解密海思音訊

ffmpeg解密海思音訊

使用海思語音編解碼庫進行 G711、G726、ADPCM 格式的編碼,編碼後的碼流遵循以下表格中描述的幀結構,即在每幀碼流資料的淨荷資料之前填充有 4 個位元組的幀頭;使用語音編解碼庫進行以上格式的解碼時,需要讀取相應的幀頭資訊。

             

      這4個位元組的幀頭內容即為如下陣列中的值:

            static char aryHeard[4] = {0,1,160,0}; //hisi audio header

1表示音訊    160表示的實際長度為160 * short  = 320

==================================================

解碼流程:

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解碼器型別。

 例項程式碼:

 

[cpp] view plain copy

  1. #define  Hisi_AUDIO_HERDER_LEN          4                   //hisi 音訊資料頭  
  2. extern "C"  
  3. {  
  4. #include "libavcodec/avcodec.h"  
  5. #include "libavformat/avformat.h"  
  6. #include "libavutil/frame.h"  
  7. #include "libswscale/swscale.h"  
  8. #include "libavutil/imgutils.h"  
  9. }  
  10. //連結 ffmpeg lib庫  
  11.   
  12. AVCodec *codec;  
  13.     AVCodecContext *c= NULL;  
  14.     AVPacket avpkt;  
  15.     AVFrame *decoded_frame = NULL;  
  16.     avcodec_register_all();  
  17.     av_init_packet(&avpkt);  
  18.     /* find the mpeg audio decoder */  
  19.     /* 
  20.     ffmpeg g726編碼器:AV_CODEC_ID_ADPCM_G726 
  21.     ffmpeg g726解碼器包括:AV_CODEC_ID_ADPCM_G726、AV_CODEC_ID_ADPCM_G726LE 
  22.     如果海思g726碼流型別為asf時,請選擇AV_CODEC_ID_ADPCM_G726解碼器型別 
  23.     如果海思g726碼流型別為RFC3551標準時,請選擇AV_CODEC_ID_ADPCM_G726LE解碼器型別 
  24.     */  
  25.     codec = avcodec_find_decoder(AV_CODEC_ID_ADPCM_G726LE);  
  26.     if (!codec)   
  27.     {  
  28.         fprintf(stderr, "codec not found\n");  
  29.         return;  
  30.     }  
  31.     c = avcodec_alloc_context3(codec);  
  32.     //取樣率= 8000 每個取樣用的bit數= 16 通道數= 1  
  33.     /* 
  34.     bits_per_coded_sample:表示編碼壓縮bit值與取樣率的bit值之比。 
  35.     如果為g726音訊時,表示g726碼流壓縮與取樣率比值。比如kbps碼流壓縮比為:k/8k = 5,kbps碼流壓縮比為k/8k = 2。 
  36.     */  
  37.     c->bits_per_coded_sample = 5;  
  38.     c->channels = 1;  
  39.     c->sample_fmt = AV_SAMPLE_FMT_S16;  
  40.     c->sample_rate = 8000;  
  41.     c->codec_type = AVMEDIA_TYPE_AUDIO;  
  42.     //c->bit_rate = 16000;  
  43.     int iRet = avcodec_open2(c, codec,NULL);  
  44.     if ( iRet < 0 )   
  45.     {  
  46.         fprintf(stderr, "could not open codec\n");  
  47.         return;  
  48.     }  
  49.   
  50.     CString filePath = "";  
  51.     CString newlFilePath = "";  
  52.     char szFilter[] = {"g726 Files (*.g726_hisi)|*.g726_hisi||"};  
  53.     CFileDialog dlg(TRUE,NULL,NULL,OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,szFilter,NULL);  
  54.     if(dlg.DoModal() == IDOK)  
  55.     {  
  56.         filePath = dlg.GetPathName();  
  57.         newlFilePath = filePath;  
  58.         newlFilePath.Replace(".g726_hisi",".hisi2ff.pcm");  
  59.         BOOL bRet = 0;  
  60.         FILE * fpSrc = fopen(filePath.GetBuffer(filePath.GetLength()),"rb");  
  61.         FILE * fpDst = fopen(newlFilePath.GetBuffer(newlFilePath.GetLength()),"wb+");  
  62.         char szData[100] = {0};  
  63.         char szOutData[320] = {0};  
  64.         int  nDataLen = 100;  
  65.         int  nOutDataLen = 320;  
  66.         int  nReadedSize = 0;  
  67.         unsigned short usHisiHeader[2] = {0};  
  68.         if(fpSrc != NULL)  
  69.         {  
  70.             while(TRUE)  
  71.             {  
  72.                 //讀取頭標記  
  73.                 nDataLen = Hisi_AUDIO_HERDER_LEN;  
  74.                 nReadedSize = fread(szData,sizeof(char),nDataLen,fpSrc);  
  75.                 if(nReadedSize < nDataLen)  
  76.                 {  
  77.                     break;  
  78.                 }  
  79.                 memcpy(usHisiHeader,szData,Hisi_AUDIO_HERDER_LEN);  
  80.                 int nAudioFrameDataLen = (usHisiHeader[1] & 0x00ff) * sizeof(unsigned short);  
  81.                 nDataLen = nAudioFrameDataLen;  
  82.                 //讀取音訊幀資料  
  83.                 nReadedSize = fread(szData,sizeof(char),nDataLen,fpSrc);  
  84.                 if(nReadedSize < nDataLen)  
  85.                 {  
  86.                     break;  
  87.                 }  
  88.                 avpkt.data = (uint8_t *)szData;  
  89.                 avpkt.size = nReadedSize;  
  90.                 int got_frame = 0;  
  91.                 if (!decoded_frame)   
  92.                 {  
  93.                     if (!(decoded_frame = avcodec_alloc_frame()))   
  94.                     {  
  95.                         return;  
  96.                     }  
  97.                 }   
  98.                 else  
  99.                 {  
  100.                     avcodec_get_frame_defaults(decoded_frame);  
  101.                 }  
  102.                 int len = avcodec_decode_audio4(c, decoded_frame, &got_frame, &avpkt);  
  103.                 if (len < 0)   
  104.                 {  
  105.                     return;  
  106.                 }  
  107.                 if (got_frame)   
  108.                 {  
  109.                     /* if a frame has been decoded, output it */  
  110.                     int data_size = av_samples_get_buffer_size(NULL, c->channels,  
  111.                         decoded_frame->nb_samples,  
  112.                         c->sample_fmt, 1);  
  113.   
  114.                     fwrite(decoded_frame->data[0], 1, data_size, fpDst);  
  115.                       
  116.                 }  
  117.             }  
  118.   
  119.             fclose(fpSrc);  
  120.             fclose(fpDst);  
  121.             avcodec_close(c);  
  122.             av_free(c);  
  123.             av_free(decoded_frame);  
  124.         }  
  125.   
  126.     }  
  127.