#include "MP4Recorder.h"
MP4Recorder::MP4Recorder(void)
{
rtsp_state=false;
pts_rtsp=0;
}
MP4Recorder::~MP4Recorder()
{
}
int MP4Recorder::OpenRtspStream(const char* url,AVFormatContext **ic)
{
AVDictionary* options = NULL;
int ret=NO_VALUE;
ret=av_dict_set(&options,"rtsp_transport", "tcp", 0);
if(ret<0)
return AV_DICT_SET_ERROR;
ret=av_dict_set(&options,"stimeout","10000000",0);
if(ret<0)
return AV_DICT_SET_ERROR;
if(avformat_open_input(ic,url,NULL,&options)!=0) //avformat_close_input 关闭
{
if(!(*ic))
avformat_free_context(*ic);
return OPEN_INPUT_ERROER;
}
if(avformat_find_stream_info(*ic,NULL)<0)
{
if(!(*ic))
{
avformat_close_input(ic);
avformat_free_context(*ic);
}
return FIND_INFO_ERROER;
}
printf("-----------rtsp流输入信息--------------\n");
av_dump_format(*ic, 0, url,0);
printf("---------------------------------------\n");
printf("\n");
return 0;
}
int MP4Recorder::Find_StreamIndex(AVFormatContext* ic,enum AVMediaType type)
{
int Index=-1;
for(unsigned int i=0; i< ic->nb_streams; i++)
if(ic->streams[i]->codecpar->codec_type==type)
{
Index=i;
break;
}
if(Index==-1)
return -1;
return Index;
}
int MP4Recorder::Open_Decoder(AVFormatContext** ic,AVCodecContext** pInCodecCtx,int index,bool open)
{
AVCodec* pInCodec=NULL;
int ret=NO_VALUE;
pInCodec=avcodec_find_decoder((*ic)->streams[index]->codecpar->codec_id);
if(pInCodec==NULL)
return FIND_DECODER_ERROR;
*pInCodecCtx=avcodec_alloc_context3(pInCodec);
if(!(*pInCodecCtx))
return ALLOC_AVCODECCONTEXT_ERROR;
ret=avcodec_parameters_to_context(*pInCodecCtx,(*ic)->streams[index]->codecpar);
if(ret<0)
return COPY_CODECCONTEXT_ERROR;
if(open)
{
if(avcodec_open2(*pInCodecCtx, pInCodec,NULL)<0)
return AVCODEC_OPEN_ERROR;
}
return 0;
}
AVStream* MP4Recorder::AddVideoStream(AVFormatContext* oc,AVCodecContext** pOutCodecCtx,AVFormatContext* ic,int index,bool mark,bool open)
{
AVCodec *video_codec=NULL;
AVStream *VideoSt=NULL;
video_codec=avcodec_find_encoder(ic->streams[index]->codecpar->codec_id);
if(!video_codec)
return NULL;
VideoSt=avformat_new_stream(oc,video_codec);
if (!VideoSt)
{
return NULL;
}
*pOutCodecCtx=avcodec_alloc_context3(video_codec);
if(!(*pOutCodecCtx))
return NULL;
if(avcodec_parameters_copy(VideoSt->codecpar,ic->streams[index]->codecpar)<0)
return NULL;
if(avcodec_parameters_to_context(*pOutCodecCtx,VideoSt->codecpar)<0)
return NULL;
if(av_q2d(ic->streams[index]->avg_frame_rate)<20.0||av_q2d(ic->streams[index]->avg_frame_rate)>30.0||ic->streams[index]->avg_frame_rate.den==0)
(*pOutCodecCtx)->time_base.den=25;
else
(*pOutCodecCtx)->time_base.den = av_q2d(ic->streams[index]->avg_frame_rate);//帧率: 30
VideoSt->time_base.num=1;
VideoSt->time_base.den=ic->streams[index]->time_base.den;
if(!mark)
{
if(oc->oformat->flags&AVFMT_GLOBALHEADER)
(*pOutCodecCtx)->flags|=AV_CODEC_FLAG_GLOBAL_HEADER;
}
if(open)
{
if(avcodec_open2(*pOutCodecCtx,video_codec,NULL)<0)
return NULL;
}
return VideoSt;
}
AVStream* MP4Recorder::AddAudioStream(AVFormatContext* oc,AVCodecContext** pOutCodecCtx,AVFormatContext* ic,int index,bool mark,bool open)
{
AVStream *AudioSt=NULL;
AVCodec *audio_codec=NULL;
audio_codec=avcodec_find_encoder(AV_CODEC_ID_AAC);
if(!audio_codec)
return NULL;
AudioSt=avformat_new_stream(oc,audio_codec);
if (!AudioSt)
return NULL;
*pOutCodecCtx=avcodec_alloc_context3(audio_codec);
if(!(*pOutCodecCtx))
return NULL;
(*pOutCodecCtx)->channels=OUTPUT_CHANNELS;
(*pOutCodecCtx)->channel_layout=av_get_default_channel_layout((*pOutCodecCtx)->channels);
(*pOutCodecCtx)->sample_rate=ic->streams[index]->codecpar->sample_rate;
(*pOutCodecCtx)->sample_fmt=audio_codec->sample_fmts[0];
(*pOutCodecCtx)->bit_rate=OUTPUT_BIT_RATE;
(*pOutCodecCtx)->strict_std_compliance=FF_COMPLIANCE_EXPERIMENTAL;
(*pOutCodecCtx)->time_base.num=1;
(*pOutCodecCtx)->time_base.den=ic->streams[index]->codecpar->sample_rate;
AudioSt->time_base.num=1;
AudioSt->time_base.den=ic->streams[index]->codecpar->sample_rate;//是否变化,注意测试 时基在发生改变
if(!mark)
{
if(oc->oformat->flags&AVFMT_GLOBALHEADER)
(*pOutCodecCtx)->flags|=AV_CODEC_FLAG_GLOBAL_HEADER;
}
if(open)
{
if(avcodec_open2(*pOutCodecCtx,audio_codec,NULL)<0)
return NULL;
}
if(avcodec_parameters_from_context(AudioSt->codecpar,(*pOutCodecCtx))<0)
return NULL;
return AudioSt;
}
int MP4Recorder::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;
}
}
void MP4Recorder::GetIndexConfigure(unsigned int aSample ,unsigned int aChannels , unsigned char* indexBuff)
{
unsigned int object_type = 2;
indexBuff[0] = (object_type<<3) | (aSample>>1);
indexBuff[1] = ((aSample&1)<<7) | (aChannels<<3);
}
int MP4Recorder::Search_I_Frame(uint8_t* buf,int size)
{
int i=0,j=0;
for(i=size-1;i>=3;i--)
{
if(buf[i] == 0x01 && buf[i-1] == 0x00 && buf[i-2] == 0x00 && buf[i-3] == 0x00)
break;
}
j=i-3;
if(i<3)
return SEARCH_I_FRAME_ERROR;
else
return j;
}
int MP4Recorder::MP4WriteH264Track(AVFormatContext *ic,int index,AVStream *video_st,AVCodecContext *pOutcodecCtx,int type)
{
int ret=-1;
int sps_pps_size=0;
uint8_t sps_pps_Buffer[200];
if(type==0)
{
sps_pps_size=ic->streams[index]->codecpar->extradata_size;
memset(sps_pps_Buffer,0,sps_pps_size*sizeof(uint8_t));
for(int i=0;i<sps_pps_size;i++)
sps_pps_Buffer[i]=ic->streams[index]->codecpar->extradata[i];
ret=mp4encoder_rtsp.MP4AddH264Track(sps_pps_Buffer,sps_pps_size,ic->streams[index]->codecpar->width,ic->streams[index]->codecpar->height,pOutcodecCtx->time_base.den,ic->streams[index]->time_base.den);
}
if(ret<0)
return ADD_H264_TRACK_ERROR;
return 0;
}
int MP4Recorder::MP4WriteAACTrack(AVFormatContext *ic,int index,AVStream *audio_st,AVCodecContext *pOutcodecCtx,int type)
{
int Sample_Index=0;
int ret=-1;
uint8_t sdata[2]={0}; //{0x12,0x08}海康卫视输出音频参数
if(type==0)
{
Sample_Index=GetSampleIndex(pOutcodecCtx->sample_rate);
GetIndexConfigure(Sample_Index,pOutcodecCtx->channels,sdata);
ret=mp4encoder_rtsp.MP4AddAACTrack(sdata,2,ic->streams[index]->codecpar->sample_rate);
}
if(ret<0)
return ADD_AAC_TRACK_ERROR;
return 0;
}
int MP4Recorder::Init_Converted_Samples(uint8_t ***converted_input_samples,AVCodecContext *output_codec_context,int frame_size)
{
if (!(*converted_input_samples =(uint8_t **)calloc(output_codec_context->channels,sizeof(**converted_input_samples))))
return ALLOC_CONVERT_SAMPLES_ERROR;
if (av_samples_alloc(*converted_input_samples, NULL,output_codec_context->channels,frame_size,output_codec_context->sample_fmt, 0) < 0)
{
av_freep(&(*converted_input_samples)[0]);
free(*converted_input_samples);
return ALLOC_AV_SAMPLES_ERROR;
}
return 0;
}
int MP4Recorder::Convert_Samples(const uint8_t **input_data,uint8_t **converted_data, const int frame_size,SwrContext *resample_context)
{
if (swr_convert(resample_context,converted_data, frame_size,input_data, frame_size) < 0)
{
return SWR_CONVERT_ERROR;
}
return 0;
}
int MP4Recorder::Add_Samples_To_Fifo(AVAudioFifo *fifo,uint8_t **converted_input_samples,const int frame_size)
{
if (av_audio_fifo_realloc(fifo, av_audio_fifo_size(fifo) + frame_size) < 0)
return REALLOCATE_FIFO
MP4v2录制rtsp流存为MP4文件
需积分: 47 93 浏览量
2018-08-22
22:48:17
上传
评论
收藏 10.15MB ZIP 举报
unfound
- 粉丝: 36
- 资源: 11
最新资源
- 机器学习和数据挖掘课程设计-米其林餐厅数据挖掘管理系统源码+使用文档说明.zip
- html html html展示我与ai的对化
- 数据结构课程设计-全国交通出行咨询模拟系统C语言实现源码.zip
- cef-binary-109.0.1+gcd5e37a+chromium-109.0.5414.8-windows32
- 基于C语言的全国交通咨询系统模拟源码.zip
- 正点原子HAL库 STM32F4 DMA(学习自用附源码)
- 炫酷代码雨,超级炫酷哦!!!
- 基于物联网MQTT协议的智能停车场管理系统
- POETIZE个人博客系统源码 - 最美博客
- 基于深度学习的行人检测系统源码+项目说明(YoloV3+Tensorflow).zip
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈