📄 mpeg2t_file.cpp
字号:
&m_buffer[m_buffer_on], m_buffer_size - m_buffer_on, &buflen_used); m_buffer_on += buflen_used; if (pidptr != NULL && pidptr->pak_type == MPEG2T_ES_PAK) { es_pid = (mpeg2t_es_t *)pidptr; if (es_pid->have_ps_ts) { es_pid->have_ps_ts = 0; max_psts = MAX(es_pid->ps_ts, max_psts); } else if (es_pid->have_dts) { es_pid->have_dts = 0; max_psts = MAX(es_pid->dts, max_psts); } } } if (m_buffer_size > m_buffer_on) { memmove(m_buffer, m_buffer + m_buffer_on, m_buffer_size - m_buffer_on); } m_buffer_on = m_buffer_size - m_buffer_on; m_buffer_size = fread(m_buffer + m_buffer_on, 1, m_buffer_size_max - m_buffer_on, m_ifile); m_buffer_size += m_buffer_on; m_buffer_on = 0; if (m_buffer_size < 188) m_buffer_size = 0; } while (m_buffer_size > 188) ; m_last_psts = max_psts; // Calculate the rough max time; hopefully it will be greater than the // initial... m_max_time = max_psts; m_max_time -= m_start_psts; m_max_time /= 90000.0;#ifdef DEBUG_MPEG2F_SEARCH player_debug_message("last psts is "U64" "U64" %g", max_psts, (max_psts - m_start_psts) / TO_U64(90000), m_max_time);#endif mpeg2t_set_loglevel(olddebuglevel); if (is_seekable) { psptr->session_set_seekable(1); } m_ts_seeked_in_msec = UINT64_MAX; rewind(m_ifile); return 0;}int CMpeg2tFile::create_video (CPlayerSession *psptr, mpeg2t_t *decoder, video_query_t *vq, uint video_offset, int &sdesc){ uint ix; CPlayerMedia *mptr; codec_plugin_t *plugin; int created = 0; // Loop through the vq structure, and set up a new player media for (ix = 0; ix < video_offset; ix++) { mpeg2t_pid_t *pidptr; mpeg2t_es_t *es_pid; pidptr = mpeg2t_lookup_pid(decoder,vq[ix].track_id); if (pidptr->pak_type != MPEG2T_ES_PAK) { mpeg2f_message(LOG_CRIT, "mpeg2t video type is not es pak - pid %x", vq[ix].track_id); exit(1); } es_pid = (mpeg2t_es_t *)pidptr; if (vq[ix].enabled != 0 && created == 0) { created = 1; mptr = new CPlayerMedia(psptr, VIDEO_SYNC); if (mptr == NULL) { return (-1); } video_info_t *vinfo; vinfo = MALLOC_STRUCTURE(video_info_t); vinfo->height = vq[ix].h; vinfo->width = vq[ix].w; plugin = check_for_video_codec(STREAM_TYPE_MPEG2_TRANSPORT_STREAM, NULL, NULL, vq[ix].type, vq[ix].profile, vq[ix].config, vq[ix].config_len, &config); int ret = mptr->create_video_plugin(plugin, STREAM_TYPE_MPEG2_TRANSPORT_STREAM, NULL, vq[ix].type, vq[ix].profile, NULL, // sdp info vinfo, // video info vq[ix].config, vq[ix].config_len); if (ret < 0) { mpeg2f_message(LOG_ERR, "Failed to create plugin data"); psptr->set_message("Failed to start plugin"); delete mptr; return -1; } CMpeg2fVideoByteStream *vbyte; vbyte = new CMpeg2fVideoByteStream(this, es_pid); if (vbyte == NULL) { mpeg2f_message(LOG_CRIT, "failed to create byte stream"); delete mptr; return (-1); } ret = mptr->create_media("video", vbyte, false); if (ret != 0) { mpeg2f_message(LOG_CRIT, "failed to create from file"); return (-1); } if (es_pid->info_loaded) { char buffer[80]; if (mpeg2t_write_stream_info(es_pid, buffer, 80) >= 0) { psptr->set_session_desc(sdesc, buffer); sdesc++; } } mpeg2t_set_frame_status(es_pid, MPEG2T_PID_SAVE_FRAME); } else { mpeg2t_set_frame_status(es_pid, MPEG2T_PID_NOTHING); } } return created;}int CMpeg2tFile::create_audio (CPlayerSession *psptr, mpeg2t_t *decoder, audio_query_t *aq, uint audio_offset, int &sdesc){ uint ix; CPlayerMedia *mptr; codec_plugin_t *plugin; int created = 0; for (ix = 0; ix < audio_offset; ix++) { mpeg2t_pid_t *pidptr; mpeg2t_es_t *es_pid; pidptr = mpeg2t_lookup_pid(decoder,aq[ix].track_id); if (pidptr->pak_type != MPEG2T_ES_PAK) { mpeg2f_message(LOG_CRIT, "mpeg2t video type is not es pak - pid %x", aq[ix].track_id); exit(1); } es_pid = (mpeg2t_es_t *)pidptr; if (aq[ix].enabled != 0 && created == 0) { created = 1; mptr = new CPlayerMedia(psptr, AUDIO_SYNC); if (mptr == NULL) { return (-1); } audio_info_t *ainfo; ainfo = MALLOC_STRUCTURE(audio_info_t); ainfo->freq = aq[ix].sampling_freq; ainfo->chans = aq[ix].chans; ainfo->bitspersample = 0; plugin = check_for_audio_codec(STREAM_TYPE_MPEG2_TRANSPORT_STREAM, NULL, NULL, aq[ix].type, aq[ix].profile, aq[ix].config, aq[ix].config_len, &config); int ret = mptr->create_audio_plugin(plugin, STREAM_TYPE_MPEG2_TRANSPORT_STREAM, NULL, aq[ix].type, aq[ix].profile, NULL, // sdp info ainfo, // video info aq[ix].config, aq[ix].config_len); if (ret < 0) { mpeg2f_message(LOG_ERR, "Failed to create plugin data"); psptr->set_message("Failed to start plugin"); delete mptr; return -1; } CMpeg2fAudioByteStream *abyte; abyte = new CMpeg2fAudioByteStream(this, es_pid); if (abyte == NULL) { mpeg2f_message(LOG_CRIT, "failed to create byte stream"); delete mptr; return (-1); } ret = mptr->create_media("audio", abyte, false); if (ret != 0) { mpeg2f_message(LOG_CRIT, "failed to create from file"); return (-1); } if (es_pid->info_loaded) { char buffer[80]; if (mpeg2t_write_stream_info(es_pid, buffer, 80) >= 0) { psptr->set_session_desc(sdesc, buffer); sdesc++; } } mpeg2t_set_frame_status(es_pid, MPEG2T_PID_SAVE_FRAME); } else { mpeg2t_set_frame_status(es_pid, MPEG2T_PID_NOTHING); } } return created;}int CMpeg2tFile::create_media (CPlayerSession *psptr, control_callback_vft_t *cc_vft){ uint audio_count, video_count; video_query_t *vq; audio_query_t *aq; int ret; int sdesc = 1; int total_enabled; mpeg2t_check_streams(&vq, &aq, m_mpeg2t, audio_count, video_count, psptr, cc_vft); ret = create_video(psptr, m_mpeg2t, vq, video_count, sdesc); if (ret < 0) { free(aq); free(vq); return -1; } total_enabled = ret; ret = create_audio(psptr, m_mpeg2t, aq, audio_count, sdesc); free(aq); free(vq); if (ret < 0) { return -1; } total_enabled += ret; psptr->set_media_close_callback(close_mpeg2t_file, (void *)this); const char *errmsg = psptr->get_message(); return *errmsg != '\0' ? 1 : 0 ;} /* * eof - if we have data in the buffer, we don't have eof. If we don't, * check if we've hit the eof */ int CMpeg2tFile::eof (void){ int ret; if (m_buffer_on + 188 <= m_buffer_size) return 0; lock_file_mutex(); ret = feof(m_ifile); unlock_file_mutex(); return ret;}/* * get_frame_for_pid - process further into the file, until we get * a frame. This has the effect of perhaps loading the frame for the * other streams. */void CMpeg2tFile::get_frame_for_pid (mpeg2t_es_t *es_pid){ mpeg2t_pid_t *pidptr; uint32_t buflen_used; lock_file_mutex(); do { while (m_buffer_on + 188 < m_buffer_size) { pidptr = mpeg2t_process_buffer(m_mpeg2t, &m_buffer[m_buffer_on], m_buffer_size - m_buffer_on, &buflen_used); m_buffer_on += buflen_used; if (es_pid->list != NULL) { unlock_file_mutex(); return; } } if (!feof(m_ifile)) { if (m_buffer_on < m_buffer_size) { memmove(m_buffer, m_buffer + m_buffer_on, m_buffer_size - m_buffer_on); m_buffer_on = m_buffer_size - m_buffer_on; } else { m_buffer_on = 0; } m_buffer_size = fread(m_buffer + m_buffer_on, 1, m_buffer_size_max - m_buffer_on, m_ifile); m_buffer_size += m_buffer_on; m_buffer_on = 0; if (m_buffer_size < 188) m_buffer_size = 0; } } while (!feof(m_ifile)); unlock_file_mutex();}/* * seek_to - get close to where they want to go */void CMpeg2tFile::seek_to (uint64_t ts_in_msec){ lock_file_mutex(); clearerr(m_ifile); // If we've already seeked, indicate that we haven't (this will not // work for 3 streams, but I'm lazy now if (m_ts_seeked_in_msec == ts_in_msec) { m_ts_seeked_in_msec = UINT64_MAX; unlock_file_mutex(); return; } // clear the buffer on and buffer size - this will force a new // read m_buffer_on = m_buffer_size = 0; // If they are looking for < 1 second, just rewind m_ts_seeked_in_msec = ts_in_msec; if (ts_in_msec < TO_U64(1000)) { rewind(m_ifile); unlock_file_mutex(); return; } uint64_t pts_seeked; // come 1 second or so earlier - this is so we don't need to track // pts vs dts, but can just get close ts_in_msec -= TO_U64(1000); pts_seeked = ts_in_msec * TO_U64(90); pts_seeked += m_start_psts; const frame_file_pos_t *start_pos; start_pos = m_file_record.find_closest_point(pts_seeked); if (start_pos == NULL) { rewind(m_ifile); unlock_file_mutex(); return; }#ifdef DEBUG_MPEG2F_SEARCH mpeg2f_message(LOG_DEBUG, "Looking for pts "U64" found "U64, pts_seeked, start_pos->timestamp);#endif fpos_t fpos; VAR_TO_FPOS(fpos, start_pos->file_position); fsetpos(m_ifile, &fpos); // Now, if we wanted, we could start reading frames, and read until // we got an i frame close to where we wanted to be. I'm lazy now, so // I won't unlock_file_mutex();}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -