iOS-FFMpeg音视频开发

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/samuelandkevin/article/details/88040046

参考资料

直播类APP功能及技术难点

概念:

Adpcm:(ADPCM Adaptive Differential Pulse Code Modulation)自适应差分脉冲编码调制,最早使用于数字通信系统中,有损压缩算法。
pcm:(Pulse Code Modulation)脉冲编码调制,用于提供话音、图象传送、远程教学等其他业务
openGL ES:(OpenGL for Embedded Systems),用于嵌入式设备的openGL
openGL:(Open Graphics Library)跨平台的图形库,是用于渲染2D、3D矢量图形
openAL:(Open Audio Library)是跨平台音效API
AAC:(Advanced Audio Coding)高级音频编码. 优点:相对于mp3,AAC格式的音质更佳,文件更小。不足:AAC属于有损压缩的格式,与时下流行的APE、FLAC等无损格式相比音质存在“本质上”的差距。加之,传输速度更快的USB3.0和16G以上大容量MP3正在加速普及,也使得AAC头上“小巧”的光环不复存在了。
音频采样率:指录音设备在一秒钟内对声音信号的采样次数,采样频率越高声音的还原就越真实越自然。在当今的主流采集卡上,采样频率一般共分为22.05KHz、44.1KHz、48KHz三个等级,22.05KHz只能达到FM广播的声音品质,44.1KHz则是理论上的CD音质界限,48KHz则更加精确一些。
比特率:指每秒传送的比特(bit)数。单位为 bps(Bit Per Second),比特率越高,传送数据速度越快。声音中的比特率是指将模拟声音信号转换成数字声音信号后,单位时间内的二进制数据量,是间接衡量音频质量的一个指标。 视频中的比特率(码率)原理与声音中的相同,都是指由模拟信号转换为数字信号后,单位时间内的二进制数据量。
信道编码中,K符号大小的信源数据块通过编码映射为N符号大小的码字,则K/N成为码率,其中假设编码前后的符号表没有变化。
RTMP:(Real Time Messaging Protocol),实时消息传输协议。Adobe公司开发的一种实时传输协议,支持1000万人同时在线看,大并发 ,长时间监控录像。缺点:消耗带宽,直播。带宽费用,国内用户带宽上下行是不对等。上512 下20M。amazon,阿里云。vps。延时 3~4秒。
RTSP:(Real Time Streaming Protocol),RFC2326,实时流传输协议
WebRTC:网页实时通信(Web Real-Time Communication),支持iPhone,android,linux ,windows,Mac web browser。IE firefox chrome. safari.应用于视频会议,视频通话。监控摄像头 withings.缺点:不适合大并发,一般三四个同时在线看。一般情况下延时较流媒体转发小一些。1~2秒。
SIP:(Session Initiation Protocol),会话初始协议。

获取H.264数据

情景:
摄像头采集数据
1帧图片2M,1秒30帧,1秒采集60M图片,也就是1秒要传输60M,在中国的网络带宽是实现不了.因此要对图片进行压缩,压缩到一秒传输0.2M.

ffmpeg解码h.264

对H.264进行封装的协议有:RTSP,RTMP
无论是RTSP,RTMP传输,解开的数据是H.264流
把H.264解码成一帧一帧数据:通过FFMPEG
解码数据到OPELGS显示

(1)硬件编码成H.264:
在这里插入图片描述
(2)FFMPEG解码成一帧一帧数据:
在这里插入图片描述

OPGL ES渲染YUV图像

要了解YUV420, YUV如何转成RGB?
分析:sws_scale() :功能是YUV转RGB,不建议使用,效率非常低.
答案:通过OpenGLes转换,rgb转换

情景:
定义一个pictureWidth,比如是720p
如果视频尺寸更改,我们可以丢掉这个frame

if((pictureWidth!=0)&&(pictureWidth!=pCodeCtx->width)){
	pictureWidth=pCodeCtx->width;
	return -1;
}

在这里插入图片描述

接收音频数据

假如sensor采集的是PCM数据,要在网络中传输PCM数据,怎么办?
PCM编码后的音频格式有:G711 , Adpmc , AAC
解码后的格式:PCM
扬声器结合PCM进行音频播放.
在这里插入图片描述
工程中g711.c,adpcm.c可以解码成pcm的音频

音频解码iPhone麦克风采集

压缩率比较
PCM转G711,压缩率1/2
PCM转Adpcm,压缩率1/4
在这里插入图片描述

OpenAL播放音频

苹果官方Demo提供音频采集和播放.
互相对话可能会产生回声干扰,怎么去消除?
苹果公司会用硬件去回声消除
苹果公司提供AudioQueue

H.264 IPB帧 NAL

H.264 SPS PPS IPB帧解析

0x67: SPS
0x68: PPS
0x65: IDR
0x61: non-IDR Slice 0x01: B Slice
0x06: SEI
0x09: AU Delimiter

通过和0x1F按位与操作,遍历数据,查找IPB帧
在这里插入图片描述

QuickTime mp4容器分析

使用的mp4文件分析工具软件:mp4info,
找出61 76 63 43位置(avcC BOX_TYPE) eg:
在这里插入图片描述
H.264的SPS和PPS串,包含了初始化H.264解码器所需要的信息参数,包括编码所用的profile,level,图像的宽和高,deblock滤波器等。

决定一个视频的质量因素:
码率:256~512 kb/s
帧率:15~20fps (24fps肉眼看起来比较流畅)
分辨率:1280x720(HD) 640x368(VGA) 1920x1080(UHD)

FFMPEG不带编码功能,通过x264进行编码
比特率,码流,帧率,分辨率

aac pcm等音频格式

pcm:设备采集声音最原始的数据
边下边播
对于网络上一首歌,要知道这首歌的采样率
设备初始化参数一般有:通道数,采样率,采样精度,原始数据长度,编码时候生成AAC最大长度…

libaac pcm实时转aac

pcm如何转aac? 答案:通过第三方faac. (FFMPEG不支持pcm转aac)
pcm如何转mp3?答案:通过第三方lame.

音频文件描述符号:faacEncHandle

MP4(里面含有H.264和AAC)
在视频录制的时候,怎么样吧声音和图像数据合成MP4格式的视频?
答案:合成成mp4方式有以下三种:
(1)AVAssetWriter
(2)FFmpeg
(3)Mp4V2

在这里插入图片描述

typedef struct MP4_AAC_CONFIGURE
{
    faacEncHandle hEncoder;           //音频文件描述符
    unsigned int nSampleRate;         //音频采样数
    unsigned int nChannels;  	      //音频声道数
    unsigned int nPCMBitSize;         //音频采样精度
    unsigned int nInputSamples;       //每次调用编码时所应接收的原始数据长度
    unsigned int nMaxOutputBytes;     //每次调用编码时生成的AAC数据的最大长度
    unsigned char* pcmBuffer;         //pcm数据
    unsigned char* aacBuffer;         //aac数据
    
}AACEncodeConfig;
  pcmBufferSize = (int)(aacConfig->nInputSamples*(aacConfig->     nPCMBitSize/8));
    //转码前需要输入的大小 pcm
    aacConfig->pcmBuffer=(unsigned char*)malloc(pcmBufferSize*sizeof(unsigned char));
    memset(aacConfig->pcmBuffer, 0, pcmBufferSize);
    
   //转码后aac的大小
    aacConfig->aacBuffer=(unsigned char*)malloc(aacConfig->nMaxOutputBytes*sizeof(unsigned char));
    memset(aacConfig->aacBuffer, 0, aacConfig->nMaxOutputBytes);

假如每次传过来的是1280字节pcm数据,但是输入端一次能处理的pcm数据为1024字节,输出端为768字节的aac数据.
在这里插入图片描述
1280-1024=256
1024-256=768
1280-768=512

ffmpeg合成h.264+aac到MP4容器

ffmpeg写 mp4+aac时呢,音频有两个值得注意的地方。
1 写aac音频时,要添加两个字节的信息到AVCodecContext.

 pCodecContext->extradata_size = sizeof(indexBuffer);;
    pCodecContext->extradata = (uint8_t*)malloc(2);
    memcpy(pCodecContext->extradata, indexBuffer,2);

2 ffmpeg 写AAC音频数据不能含有ADTS头
在这里插入图片描述

-(int)getSampleIndex:(unsigned int)aSamples
{
    switch(aSamples){
        case 96000: return 0;
        case 88200: return 1;
        case 64000: return 2;
        case 48000: return 3;
        case 44100: return 4;
        case 32000: return 5;
        case 24000: return 6;
        case 22050: return 7;
        case 16000: return 8;
        case 12000: return 9;
        case 11025: return 10;
        case 8000:  return 11;
        case 7350:  return 12;
        default:    return 0;
    }
    
}

需要了解一下ADTS

ffmpeg liblame pcm转mp3

猜你喜欢

转载自blog.csdn.net/samuelandkevin/article/details/88040046