技术专栏
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
#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);
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
<
原文连接:https://blog.csdn.net/huabiaochen/article/details/83012355
- 1
声明:本文内容由易百纳平台入驻作者撰写,文章观点仅代表作者本人,不代表易百纳立场。如有内容侵权或者其他问题,请联系本站进行删除。
红包
点赞
收藏
评论
打赏
- 分享
- 举报
评论
0个
手气红包

相关专栏
-
浏览量:4475次2020-08-10 09:16:13
-
浏览量:6006次2021-04-26 17:27:59
-
浏览量:2555次2018-12-17 17:07:51
-
浏览量:3252次2020-08-03 11:02:46
-
浏览量:1230次2023-12-22 11:12:20
-
浏览量:2813次2020-08-27 19:30:09
-
浏览量:2112次2020-07-28 20:16:56
-
浏览量:2721次2024-01-18 15:01:07
-
浏览量:3938次2021-12-10 16:59:31
-
浏览量:1227次2024-01-24 18:13:58
-
浏览量:2043次2020-08-12 09:23:23
-
浏览量:6760次2020-08-24 21:24:41
-
浏览量:3886次2020-08-24 21:28:44
-
浏览量:3237次2024-01-22 11:16:26
-
浏览量:4063次2020-09-24 11:58:24
-
浏览量:1400次2024-01-24 18:44:43
-
浏览量:14522次2019-09-21 19:14:57
-
浏览量:5554次2021-04-23 14:10:42
-
浏览量:3468次2020-07-29 11:56:51
置顶时间设置
结束时间
删除原因
-
广告/SPAM
-
恶意灌水
-
违规内容
-
文不对题
-
重复发帖
打赏作者

在学了在学了!
您的支持将鼓励我继续创作!
打赏金额:
¥1

¥5

¥10

¥50

¥100

支付方式:

举报反馈
举报类型
- 内容涉黄/赌/毒
- 内容侵权/抄袭
- 政治相关
- 涉嫌广告
- 侮辱谩骂
- 其他
详细说明
审核成功
发布时间设置
发布时间:
请选择发布时间设置
是否关联周任务-专栏模块
审核失败
失败原因
请选择失败原因
备注
请输入备注