⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 file_mp4_recorder.cpp

📁 完整的RTP RTSP代码库
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/* * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/MPL/ *  * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. *  * The Original Code is MPEG4IP. *  * The Initial Developer of the Original Code is Cisco Systems Inc. * Portions created by Cisco Systems Inc. are * Copyright (C) Cisco Systems Inc. 2000, 2001.  All Rights Reserved. *  * Contributor(s):  *		Dave Mackie		dmackie@cisco.com *		Bill May 		wmay@cisco.com */#include "mp4live.h"#include "file_mp4_recorder.h"#include "video_encoder.h"#include "audio_encoder.h"#include "text_encoder.h"#include "mpeg4ip_byteswap.h"#include "mp4av_h264.h"#include "video_v4l_source.h"//#define DEBUG_H264 1int CMp4Recorder::ThreadMain(void) {  CMsg *pMsg;  bool stop = false;  while (stop == false && SDL_SemWait(m_myMsgQueueSemaphore) == 0) {    pMsg = m_myMsgQueue.get_message();		    if (pMsg != NULL) {      switch (pMsg->get_value()) {      case MSG_NODE_STOP_THREAD:        DoStopRecord();	stop = true;	break;      case MSG_NODE_START:        DoStartRecord();        break;      case MSG_NODE_STOP:        DoStopRecord();        break;      case MSG_SINK_FRAME:        uint32_t dontcare;        DoWriteFrame((CMediaFrame*)pMsg->get_message(dontcare));        break;      }      delete pMsg;    }  }  while ((pMsg = m_myMsgQueue.get_message()) != NULL) {    error_message("recorder - had msg after stop");    if (pMsg->get_value() == MSG_SINK_FRAME) {      uint32_t dontcare;      CMediaFrame *mf = (CMediaFrame*)pMsg->get_message(dontcare);      if (mf->RemoveReference()) {	delete mf;      }    }    delete pMsg;  }  CHECK_AND_FREE(m_videoTempBuffer);  m_videoTempBufferSize = 0;  return 0;}void CMp4Recorder::DoStartRecord(){  // already recording  if (m_sink) {    return;  }  const char *filename;  m_makeIod = true;  m_makeIsmaCompliant = true;  m_audioFrameType = UNDEFINEDFRAME;  m_videoFrameType = UNDEFINEDFRAME;  m_textFrameType = UNDEFINEDFRAME;  if (m_stream != NULL) {    // recording normal file    m_video_profile = m_stream->GetVideoProfile();    m_audio_profile = m_stream->GetAudioProfile();    m_text_profile = m_stream->GetTextProfile();    m_recordVideo = m_stream->GetBoolValue(STREAM_VIDEO_ENABLED);    m_recordAudio = m_stream->GetBoolValue(STREAM_AUDIO_ENABLED);    m_recordText = m_stream->GetBoolValue(STREAM_TEXT_ENABLED);    if (m_recordAudio) {      m_audioTimeScale = 	m_audio_profile->GetIntegerValue(CFG_AUDIO_SAMPLE_RATE);    }    filename = m_stream->GetStringValue(STREAM_RECORD_MP4_FILE_NAME);  } else {    // recording raw file    m_recordVideo = m_pConfig->GetBoolValue(CONFIG_VIDEO_ENABLE) &&      m_pConfig->GetBoolValue(CONFIG_RECORD_RAW_IN_MP4_VIDEO);    m_recordAudio = m_pConfig->GetBoolValue(CONFIG_AUDIO_ENABLE) &&      m_pConfig->GetBoolValue(CONFIG_RECORD_RAW_IN_MP4_AUDIO);    m_recordText = false;    m_audioTimeScale = m_pConfig->GetIntegerValue(CONFIG_AUDIO_SAMPLE_RATE);    filename = m_pConfig->GetStringValue(CONFIG_RECORD_RAW_MP4_FILE_NAME);  }  if (m_recordAudio &&      m_pConfig->GetBoolValue(CONFIG_RECORD_MP4_VIDEO_TIMESCALE_USES_AUDIO))    m_videoTimeScale = m_audioTimeScale;  m_prevVideoFrame = NULL;  m_prevAudioFrame = NULL;  m_prevTextFrame = NULL;  m_videoTrackId = MP4_INVALID_TRACK_ID;  m_audioTrackId = MP4_INVALID_TRACK_ID;  m_textTrackId = MP4_INVALID_TRACK_ID;  // are we recording any video?  if (m_recordVideo || m_recordText) {    m_movieTimeScale = m_videoTimeScale;  } else { // just audio    m_movieTimeScale = m_audioTimeScale;  }  // get the mp4 file setup   // enable huge file mode in mp4   // if duration is very long or if estimated size goes over 1 GB  u_int64_t duration = m_pConfig->GetIntegerValue(CONFIG_APP_DURATION)     * m_pConfig->GetIntegerValue(CONFIG_APP_DURATION_UNITS)    * m_movieTimeScale;  bool hugeFile =     (duration > 0xFFFFFFFF)     || (m_pConfig->m_recordEstFileSize > (TO_U64(1000000000)));  uint32_t createFlags = 0;  if (hugeFile) {    createFlags |= MP4_CREATE_64BIT_DATA;  }  debug_message("Creating huge file - %s", hugeFile ? "yes" : "no");  u_int32_t verbosity =    MP4_DETAILS_ERROR  /*DEBUG  | MP4_DETAILS_WRITE_ALL */;  bool create = false;  switch (m_pConfig->GetIntegerValue(CONFIG_RECORD_MP4_FILE_STATUS)) {  case FILE_MP4_APPEND:    m_mp4File = MP4Modify(filename,                          verbosity);    break;  case FILE_MP4_CREATE_NEW: {    struct stat stats;    const char *fname = filename;    if (stat(fname, &stats) == 0) {      // file already exists - create new one      size_t len = strlen(fname);      if (strncasecmp(fname + len - 4, ".mp4", 4) == 0) {	len -= 4;      }      struct tm timeval;      int ret;      char *buffer = (char *)malloc(len + 22);      do {	time_t val = time(NULL);	localtime_r(&val, &timeval);	memcpy(buffer, fname, len);	sprintf(buffer + len, "_%04u%02u%02u_%02u%02u%02u.mp4",		1900 + timeval.tm_year, timeval.tm_mon + 1, timeval.tm_mday,		timeval.tm_hour, timeval.tm_min, timeval.tm_sec);	error_message("trying file %s", buffer);	ret = stat(buffer, &stats);	if (ret == 0) {	  SDL_Delay(100);	}      } while (ret == 0);      m_mp4FileName = strdup(buffer);      create = true;      break;    }  }    // else fall through      case FILE_MP4_OVERWRITE:    m_mp4FileName = strdup(filename);    create = true;    break;  }  if (create) {    if (m_stream &&	(m_recordAudio == false ||	 strcasecmp(m_audio_profile->GetStringValue(CFG_AUDIO_ENCODING), 		    AUDIO_ENCODING_AMR) == 0) &&	(m_recordVideo == false ||	 strcasecmp(m_video_profile->GetStringValue(CFG_VIDEO_ENCODING), 		    VIDEO_ENCODING_H263) == 0)) {      static char* p3gppSupportedBrands[2] = {"3gp5", "3gp4"};      m_mp4File = MP4CreateEx(m_mp4FileName,			      verbosity,			      createFlags,			      1,			      0,			      p3gppSupportedBrands[0],			      0x0001,			      p3gppSupportedBrands,			      NUM_ELEMENTS_IN_ARRAY(p3gppSupportedBrands));    } else {      m_mp4File = MP4Create(m_mp4FileName,			    verbosity, createFlags);    }  }      if (!m_mp4File) {    return;  }  MP4SetTimeScale(m_mp4File, m_movieTimeScale);  char buffer[80];  sprintf(buffer, "mp4live version %s %s", MPEG4IP_VERSION, 	  get_linux_video_type());  MP4SetMetadataTool(m_mp4File, buffer);  if (m_recordVideo) {    m_videoFrameNumber = 1;    if (m_stream == NULL) {      m_videoTrackId = MP4AddVideoTrack(m_mp4File,					m_videoTimeScale,					MP4_INVALID_DURATION,					m_pConfig->m_videoWidth, 					m_pConfig->m_videoHeight,					MP4_YUV12_VIDEO_TYPE);      if (m_videoTrackId == MP4_INVALID_TRACK_ID) {        error_message("can't create raw video track");        goto start_failure;      }      m_videoFrameType = YUVVIDEOFRAME;      MP4SetVideoProfileLevel(m_mp4File, 0xFF);    } else {      bool vIod, vIsma;      uint8_t videoProfile;      uint8_t *videoConfig;      uint32_t videoConfigLen;      uint8_t videoType;      m_videoFrameType =         get_video_mp4_fileinfo(m_video_profile,                               &vIod,                               &vIsma,                               &videoProfile,                               &videoConfig,                               &videoConfigLen,                               &videoType);      if (m_videoFrameType == H263VIDEOFRAME) {	m_videoTrackId = MP4AddH263VideoTrack(m_mp4File,					      m_videoTimeScale,					      0,					      m_video_profile->m_videoWidth,					      m_video_profile->m_videoHeight,					      10,					      0,					      0, 					      0);	uint32_t bitrate = 	  m_video_profile->GetIntegerValue(CFG_VIDEO_BIT_RATE) * 1000;	// may need to do this at the end	MP4SetH263Bitrates(m_mp4File,			   m_videoTrackId,			   bitrate,			   bitrate);      } else if (m_videoFrameType == H264VIDEOFRAME) {	uint8_t avcprofile, profile_compat, avclevel;	avcprofile = (m_video_profile->m_videoMpeg4ProfileId >> 16) & 0xff;	profile_compat = (m_video_profile->m_videoMpeg4ProfileId >> 8) & 0xff;	avclevel = (m_video_profile->m_videoMpeg4ProfileId) & 0xff;	debug_message("h264 track %x %x %x", 		      avcprofile, profile_compat, avclevel);	m_videoTrackId = MP4AddH264VideoTrack(m_mp4File, 					      m_videoTimeScale,					      MP4_INVALID_DURATION,					      m_video_profile->m_videoWidth,					      m_video_profile->m_videoHeight,					      avcprofile, 					      profile_compat, 					      avclevel, 					      3);	MP4SetVideoProfileLevel(m_mp4File, 0x7f);	m_makeIod = false;	m_makeIsmaCompliant = false;      } else if (m_videoFrameType == H261VIDEOFRAME) {	error_message("H.261 recording is not supported");      } else {	m_videoTrackId = MP4AddVideoTrack(m_mp4File,					  m_videoTimeScale,					  MP4_INVALID_DURATION,					  m_video_profile->m_videoWidth, 					  m_video_profile->m_videoHeight,					  videoType);		if (vIod == false) m_makeIod = false;	if (vIsma == false) m_makeIsmaCompliant = false;		if (m_videoTrackId == MP4_INVALID_TRACK_ID) {	  error_message("can't create encoded video track");	  goto start_failure;	}		MP4SetVideoProfileLevel(m_mp4File, 				videoProfile);	if (videoConfigLen > 0) {	  MP4SetTrackESConfiguration(				     m_mp4File, 				     m_videoTrackId,				     videoConfig,				     videoConfigLen);	}      }    }  }  m_audioFrameNumber = 1;  m_canRecordVideo = true;  if (m_recordAudio) {    if (m_stream == NULL) {      // raw audio      m_canRecordVideo = false;      m_audioTrackId = MP4AddAudioTrack(m_mp4File, 					m_audioTimeScale, 					0,					MP4_PCM16_BIG_ENDIAN_AUDIO_TYPE);      if (m_audioTrackId == MP4_INVALID_TRACK_ID) {        error_message("can't create raw audio track");        goto start_failure;      }      MP4SetAudioProfileLevel(m_mp4File, 0xFF);      m_audioFrameType = PCMAUDIOFRAME;    } else {      u_int8_t audioType;      bool createIod = false;      bool isma_compliant = false;      uint8_t audioProfile;      uint8_t *pAudioConfig;      uint32_t audioConfigLen;      m_canRecordVideo = false;      m_audioFrameType =         get_audio_mp4_fileinfo(m_audio_profile,                                &createIod,                               &isma_compliant,                               &audioProfile,                               &pAudioConfig,                               &audioConfigLen,                               &audioType);					             if (m_audioFrameType == AMRNBAUDIOFRAME ||	  m_audioFrameType == AMRWBAUDIOFRAME) {	m_audioTrackId = 	  MP4AddAmrAudioTrack(m_mp4File,			      m_audioFrameType == AMRNBAUDIOFRAME ? 			      8000 : 16000,			      0, 			      0, 			      1, 			      m_audioFrameType == AMRWBAUDIOFRAME);      } else {	if (createIod == false) m_makeIod = false;	if (isma_compliant == false) 	  m_makeIsmaCompliant = false;	MP4SetAudioProfileLevel(m_mp4File, audioProfile);	m_audioTrackId = MP4AddAudioTrack(						 m_mp4File, 						 m_audioTimeScale, 						 MP4_INVALID_DURATION,						 audioType);      }      if (m_audioTrackId == MP4_INVALID_TRACK_ID) {        error_message("can't create encoded audio track");        goto start_failure;      }      if (pAudioConfig) {        MP4SetTrackESConfiguration(                                   m_mp4File,                                    m_audioTrackId,                                   pAudioConfig,                                    audioConfigLen);	free(pAudioConfig);      }    }  }    debug_message("recording text %u", m_recordText);  if (m_recordText) {    m_textFrameNumber = 1;  if (m_stream == NULL) {      m_recordText = false;    } else {      const char *url;      m_textFrameType = get_text_mp4_fileinfo(m_text_profile, &url);      debug_message("text type %u", m_textFrameType);      if (m_textFrameType == HREFTEXTFRAME) {	m_textTrackId = MP4AddHrefTrack(m_mp4File, m_textTimeScale, MP4_INVALID_DURATION, url);	debug_message("Added text track %u", m_textTrackId);      } else {	m_recordText = false;      }    }  }        m_sink = true;  return; start_failure:  MP4Close(m_mp4File);  m_mp4File = NULL;  return;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -