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

📄 mpeg2f_bytestream.cpp

📁 完整的RTP RTSP代码库
💻 CPP
字号:
/* * 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. 2004.  All Rights Reserved. *  * Contributor(s):  *              Bill May        wmay@cisco.com *//* * mpeg2f_bytestream.cpp - convert mpeg2 transport stream file to bytestream * using lib/mpeg2t to read file. */#include "mpeg4ip.h"#include "mpeg2f_bytestream.h"#include "player_util.h"#include "mp4av.h"//#define DEBUG_MPEG2T_FRAME 1//#define DEBUG_MPEG2T_PSTS 1static inline bool convert_psts (mpeg2t_es_t *es_pid,				 mpeg2t_frame_t *fptr,				 uint64_t start_psts){  uint64_t ps_ts;#ifdef DEBUG_MPEG2T_PSTS  uint64_t initial;#endif  // we want to 0 out the timestamps of the incoming transport  // stream so that the on-demand shows the correct timestamps  // see if we've set the initial timestamp  // here, we want to check for a gross change in the psts  if (fptr->have_ps_ts == 0 && fptr->have_dts == 0) return true;  if (fptr->have_dts) {    ps_ts = fptr->dts;    if (ps_ts < start_psts) return false;#ifdef DEBUG_MPEG2T_PSTS    initial = fptr->dts;#endif    fptr->dts -= start_psts;#ifdef DEBUG_MPEG2T_PSTS    player_debug_message(" convert dts "U64" to "U64" "U64,			 fptr->dts, start_psts, initial);#endif  } else {    ps_ts = fptr->ps_ts;    if (ps_ts < start_psts) return false;#ifdef DEBUG_MPEG2T_PSTS    initial = fptr->dts;#endif    fptr->ps_ts -= start_psts;#ifdef DEBUG_MPEG2T_PSTS    player_debug_message(" convert psts "U64" to "U64" "U64,			 fptr->ps_ts, start_psts, initial);#endif  }  return true;}/************************************************************************** *  **************************************************************************/CMpeg2fByteStream::CMpeg2fByteStream (CMpeg2tFile *f,				      mpeg2t_es_t *es_pid,				      const char *type,				      int has_video)  : COurInByteStream(type){#ifdef OUTPUT_TO_FILE  char buffer[80];  strcpy(buffer, type);  strcat(buffer, ".raw");  m_output_file = fopen(buffer, "w");#endif  m_file = f;  m_es_pid = es_pid;  m_has_video = has_video;  m_timestamp_loaded = 0;  m_frame = NULL;}CMpeg2fByteStream::~CMpeg2fByteStream(){  mpeg2t_set_frame_status(m_es_pid, MPEG2T_PID_NOTHING); // eliminate any callbacks#ifdef OUTPUT_TO_FILE  fclose(m_output_file);#endif  mpeg2t_free_frame(m_frame);}int CMpeg2fByteStream::eof(void){  return m_es_pid->list == NULL && m_file->eof();}// clear out the cruft.void CMpeg2fByteStream::reset (void) {  mpeg2t_frame_t *p;  do {    p = mpeg2t_get_es_list_head(m_es_pid);    if (p != NULL)      mpeg2t_free_frame(p);  } while (p != NULL);}// pause - just reset.  We might not want to do this if we// need to start where we stopped.void CMpeg2fByteStream::pause (void){  reset();}void CMpeg2fByteStream::play (uint64_t start_time){  m_play_start_time = start_time;  m_file->seek_to(start_time);  mpeg2t_clear_frames(m_es_pid);}bool CMpeg2fByteStream::start_next_frame (uint8_t **buffer, 					  uint32_t *buflen,					  frame_timestamp_t *ts,					  void **ud){  if (m_frame) {    mpeg2t_free_frame(m_frame);  }    // see if there is a frame ready for this pid.  If not,   // request one  m_frame = mpeg2t_get_es_list_head(m_es_pid);  if (m_frame == NULL) {    m_file->get_frame_for_pid(m_es_pid);    m_frame = mpeg2t_get_es_list_head(m_es_pid);    if (m_frame == NULL) {      player_debug_message("%s no frame %d", m_name, m_file->eof());      return false;    }  }  // Convert the psts  if (convert_psts(m_es_pid, m_frame, m_file->get_start_psts()) == false) {    return false;  }  // convert the psts into a timestamp  if (get_timestamp_for_frame(m_frame, ts) >= 0) {    *buffer = m_frame->frame;    *buflen = m_frame->frame_len;#ifdef DEBUG_MPEG2T_FRAME    player_debug_message("%s - len %d time "U64" ftype %d", 			 m_name, *buflen, ret, m_frame->frame_type);#endif    return true;  }  return false;}void CMpeg2fByteStream::used_bytes_for_frame (uint32_t bytes_used){  // nothing here yet...}bool CMpeg2fByteStream::skip_next_frame (frame_timestamp_t *pts, 					int *pSync,					uint8_t **buffer, 					uint32_t *buflen,					void **userdata){  *pSync = 0; //m_frame_on_has_sync;  return start_next_frame(buffer, buflen, pts, NULL);}double CMpeg2fByteStream::get_max_playtime (void) {  return m_file->get_max_time();};void CMpeg2fVideoByteStream::reset(void){  m_have_prev_frame_type = 0;  m_timestamp_loaded = 0;  CMpeg2fByteStream::reset();}void CMpeg2fVideoByteStream::play (uint64_t start_time){  CMpeg2fByteStream::play(start_time);  // make sure we start with the next i frame  do {    m_file->get_frame_for_pid(m_es_pid);    while (m_es_pid->list && m_es_pid->list->frame_type != 1) {      mpeg2t_free_frame(mpeg2t_get_es_list_head(m_es_pid));    }  } while (!m_file->eof() && 	   (m_es_pid->list == NULL || m_es_pid->list->frame_type != 1));}int CMpeg2fVideoByteStream::get_timestamp_for_frame (mpeg2t_frame_t *fptr,						     frame_timestamp_t *ts){#ifdef DEBUG_MPEG2T_PSTS  if (fptr->have_dts) {    player_debug_message("video frame len %d have  dts %d ts "U64,			 fptr->frame_len, fptr->have_dts, fptr->dts);  } if (fptr->have_ps_ts) {    player_debug_message("video frame len %d have psts %d ts "U64, 			 fptr->frame_len, fptr->have_ps_ts, fptr->ps_ts);  }#endif#if 0  if (m_es_pid->stream_type == MPEG2T_STREAM_H264) {    if (fptr->have_dts || fptr->have_ps_ts) {      if (fptr->have_dts)	outts = fptr->dts;      else	outts = fptr->ps_ts;      outts *= TO_U64(1000);      outts /= TO_U64(90000); // get msec from 90000 timescale      return 0;    }    return -1;  }  uint64_t ts;  //  m_es_pid->frame_rate = 24;  double value = 90000.0 / m_es_pid->frame_rate;  uint64_t frame_time = (uint64_t)value;  if (fptr->have_ps_ts == 0 && fptr->have_dts == 0) {    // We don't have a timestamp on this - just increment from    // the previous timestamp.    if (m_timestamp_loaded == 0) return -1;    if (m_es_pid->info_loaded == 0) return -1;    outts = m_prev_ts + frame_time;    m_have_prev_frame_type = 1;    m_prev_frame_type = fptr->frame_type;    m_prev_ts = outts;    outts *= TO_U64(1000);    outts /= TO_U64(90000); // get msec from 90000 timescale    return 0;  }  m_timestamp_loaded = 1;  if (fptr->have_dts != 0) {    outts = fptr->dts;  } else {    ts = fptr->ps_ts;    if (m_have_prev_frame_type) {      if (fptr->frame_type == 3) {	// B frame	outts = ts;      } else {	outts = m_prev_ts + frame_time;      }    } else {      if (fptr->frame_type == 1) {	uint16_t temp_ref = MP4AV_Mpeg3PictHdrTempRef(fptr->frame + fptr->pict_header_offset);	ts -= ((temp_ref + 1) * m_es_pid->tick_per_frame);	outts = ts;      } else {	player_error_message( "no psts and no prev frame");	outts = ts;      }    }  }  m_have_prev_frame_type = 1;  m_prev_frame_type = fptr->frame_type;  m_prev_ts = outts;  outts *= TO_U64(1000);  outts /= TO_U64(90000); // get msec from 90000 timescale    return 0;#endif  ts->timestamp_is_pts = fptr->have_dts == false;  uint64_t outts;  if (fptr->have_dts)    outts = fptr->dts;  else if (fptr->have_ps_ts)     outts = fptr->ps_ts;  else     outts = m_prev_ts + 3003; // just a guess for now  m_prev_ts = outts;  outts *= TO_U64(1000);  outts /= TO_U64(90000); // get msec from 90000 timescale  ts->msec_timestamp = outts;  return 0;}void CMpeg2fAudioByteStream::reset(void){  m_timestamp_loaded = 0;  CMpeg2fByteStream::reset();}int CMpeg2fAudioByteStream::get_timestamp_for_frame (mpeg2t_frame_t *fptr,						     frame_timestamp_t *ts){  uint64_t pts_in_msec;  // all ts for audio are stored in msec, not in timescale#ifdef DEBUG_MPEG2T_PSTS  player_debug_message("audio frame len %d have  dts %d ts "U64, 		       fptr->frame_len, fptr->have_dts, fptr->dts);  player_debug_message("audio frame len %d have psts %d ts "U64" %d %d", 		       fptr->frame_len, fptr->have_ps_ts, fptr->ps_ts,		       m_es_pid->sample_per_frame, 		       m_es_pid->sample_freq);#endif  if (fptr->have_ps_ts != 0 || fptr->have_dts != 0) {    m_timestamp_loaded = 1;    pts_in_msec = fptr->have_dts ? fptr->dts : fptr->ps_ts;    m_audio_last_freq_timestamp =       ((pts_in_msec * m_es_pid->sample_freq) / TO_U64(90000));    ts->audio_freq_timestamp = m_audio_last_freq_timestamp;    ts->audio_freq = m_es_pid->sample_freq;    pts_in_msec *= TO_U64(1000);    pts_in_msec /= TO_U64(90000);    m_last_timestamp = pts_in_msec;    ts->msec_timestamp = m_last_timestamp;    m_frames_since_last_timestamp = 0;    return 0;  }  if (m_timestamp_loaded == 0) return -1;  if (m_es_pid->info_loaded == 0) return -1;  ts->msec_timestamp = m_last_timestamp;  ts->audio_freq_timestamp = m_audio_last_freq_timestamp;  ts->audio_freq = m_es_pid->sample_freq;  return 0;}/* end file mpeg2t_bytestream.cpp */

⌨️ 快捷键说明

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