📄 media_utils.cpp
字号:
* create_media_from_sdp_file - create a streaming session based on an
* sdp file. It could be either an on-demand program (we look for the
* url in the control string), or a broadcast.
*/
static int create_from_sdp (CPlayerSession *psptr,
const char *name,
char *errmsg,
uint32_t errlen,
sdp_decode_info_t *sdp_info,
int have_audio_driver,
control_callback_vft_t *cc_vft)
{
session_desc_t *sdp;
int translated;
if (sdp_info == NULL) {
strcpy(errmsg, "SDP error");
return (-1);
}
if (sdp_decode(sdp_info, &sdp, &translated) != 0) {
snprintf(errmsg, errlen, "Invalid SDP file");
sdp_decode_info_free(sdp_info);
return (-1);
}
if (translated != 1) {
snprintf(errmsg, errlen, "More than 1 program described in SDP");
sdp_decode_info_free(sdp_info);
return (-1);
}
int err;
if (sdp->control_string != NULL) {
// An on demand file... Just use the URL...
err = create_media_for_streaming_ondemand(psptr,
sdp->control_string,
errmsg,
errlen,
cc_vft);
sdp_free_session_desc(sdp);
sdp_decode_info_free(sdp_info);
return (err);
}
sdp_decode_info_free(sdp_info);
return (create_media_for_streaming_broadcast(psptr,
name,
sdp,
errmsg,
errlen,
have_audio_driver,
cc_vft));
}
static int create_media_from_sdp_file(CPlayerSession *psptr,
const char *name,
char *errmsg,
uint32_t errlen,
int have_audio_driver,
control_callback_vft_t *cc_vft)
{
sdp_decode_info_t *sdp_info;
sdp_info = set_sdp_decode_from_filename(name);
return (create_from_sdp(psptr,
name,
errmsg,
errlen,
sdp_info,
have_audio_driver,
cc_vft));
}
static int create_media_for_http (CPlayerSession *psptr,
const char *name,
char *errmsg,
uint32_t errlen,
control_callback_vft_t *cc_vft)
{
http_client_t *http_client;
int ret;
http_resp_t *http_resp;
http_resp = NULL;
http_client = http_init_connection(name);
if (http_client == NULL) {
snprintf(errmsg, errlen, "Can't create http client");
return -1;
}
ret = http_get(http_client, NULL, &http_resp);
if (ret > 0) {
sdp_decode_info_t *sdp_info;
int have_audio_driver = do_we_have_audio();
sdp_info = set_sdp_decode_from_memory(http_resp->body);
ret = create_from_sdp(psptr,
name,
errmsg,
errlen,
sdp_info,
have_audio_driver,
cc_vft);
} else {
ret = -1;
}
http_resp_free(http_resp);
http_free_connection(http_client);
return (ret);
}
/*
* parse_name_for_session - look at the name, determine what routine to
* call to set up the session. This should be redone with plugins at
* some point.
*/
#define ADV_SPACE(a) {while (isspace(*(a)) && (*(a) != '\0'))(a)++;}
int parse_name_for_session (CPlayerSession *psptr,
const char *name,
char *errmsg,
uint32_t errlen,
control_callback_vft_t *cc_vft)
{
int err;
ADV_SPACE(name);
if (strncmp(name, "rtsp://", strlen("rtsp://")) == 0) {
err = create_media_for_streaming_ondemand(psptr,
name,
errmsg,
errlen,
cc_vft);
return (err);
}
if (strncmp(name, "http://", strlen("http://")) == 0) {
err = create_media_for_http(psptr, name, errmsg, errlen, cc_vft);
return (err);
}
#if 0
if (strncmp(name, "mpeg2t://", strlen("mpeg2t://")) == 0) {
err = create_mpeg2t_session(psptr, name, errmsg, errlen, cc_vft);
return (err);
}
#endif
#ifndef _WINDOWS
struct stat statbuf;
if (stat(name, &statbuf) != 0) {
snprintf(errmsg, errlen, "File \'%s\' not found", name);
return (-1);
}
if (!S_ISREG(statbuf.st_mode)) {
snprintf(errmsg, errlen, "File \'%s\' is not a file", name);
return (-1);
}
#else
OFSTRUCT ReOpenBuff;
if (OpenFile(name, &ReOpenBuff,OF_READ) == HFILE_ERROR) {
snprintf(errmsg, errlen, "File %s not found", name);
return (-1);
}
#endif
err = -1;
const char *suffix = strrchr(name, '.');
if (suffix == NULL) {
snprintf(errmsg, errlen, "No useable suffix on file %s", name);
return err;
}
int have_audio_driver;
have_audio_driver = do_we_have_audio();
if (strcasecmp(suffix, ".sdp") == 0) {
err = create_media_from_sdp_file(psptr,
name,
errmsg,
errlen,
have_audio_driver,
cc_vft);
} else if ((strcasecmp(suffix, ".mov") == 0) ||
((config.get_config_value(CONFIG_USE_OLD_MP4_LIB) != 0) &&
(strcasecmp(suffix, ".mp4") == 0))){
err = create_media_for_qtime_file(psptr,
name,
errmsg,
errlen,
have_audio_driver);
} else if (strcasecmp(suffix, ".mp4") == 0) {
err = create_media_for_mp4_file(psptr,
name,
errmsg,
errlen,
have_audio_driver,
cc_vft);
} else if (strcasecmp(suffix, ".avi") == 0) {
err = create_media_for_avi_file(psptr,
name,
errmsg,
errlen,
have_audio_driver,
cc_vft);
} else if (strcasecmp(suffix, ".mpeg") == 0 ||
strcasecmp(suffix, ".mpg") == 0) {
err = create_media_for_mpeg_file(psptr, name, errmsg,
errlen, have_audio_driver);
} else {
// raw files
if (have_audio_driver) {
err = audio_codec_check_for_raw_file(psptr, name);
}
if (err < 0) {
err = video_codec_check_for_raw_file(psptr, name);
}
}
if (err >= 0) {
const char *temp;
temp = psptr->get_session_desc(0);
if (temp == NULL) {
psptr->set_session_desc(0, name);
}
}
return (err);
}
CRtpByteStreamBase *create_rtp_byte_stream_for_format (format_list_t *fmt,
unsigned int rtp_pt,
int ondemand,
uint64_t tps,
rtp_packet **head,
rtp_packet **tail,
int rtp_seq_set,
uint16_t rtp_seq,
int rtp_ts_set,
uint32_t rtp_base_ts,
int rtcp_received,
uint32_t ntp_frac,
uint32_t ntp_sec,
uint32_t rtp_ts)
{
CRtpByteStreamBase *rtp_byte_stream;
int codec;
if (strcmp("video", fmt->media->media) == 0) {
if (rtp_pt == 32) {
codec = VIDEO_MPEG12;
rtp_byte_stream = new CMpeg3RtpByteStream(rtp_pt,
fmt,
ondemand,
tps,
head,
tail,
rtp_seq_set,
rtp_seq,
rtp_ts_set,
rtp_base_ts,
rtcp_received,
ntp_frac,
ntp_sec,
rtp_ts);
if (rtp_byte_stream != NULL) {
return (rtp_byte_stream);
}
} else {
codec = lookup_codec_by_name(fmt->rtpmap->encode_name,
video_codecs);
if (codec < 0) {
return (NULL);
}
}
} else {
if (rtp_pt == 14) {
codec = MPEG4IP_AUDIO_MP3;
} else {
codec = lookup_codec_by_name(fmt->rtpmap->encode_name,
audio_codecs);
if (codec < 0) {
return (NULL);
}
}
switch (codec) {
case MPEG4IP_AUDIO_AAC:
case MPEG4IP_AUDIO_MPEG4_GENERIC:
fmtp_parse_t *fmtp;
fmtp = parse_fmtp_for_mpeg4(fmt->fmt_param, message);
if (fmtp->size_length == 0) {
// No headers in RTP packet -create normal bytestream
player_debug_message("Size of AAC RTP header is 0 - normal bytestream");
break;
}
rtp_byte_stream = new CIsmaAudioRtpByteStream(fmt,
fmtp,
rtp_pt,
ondemand,
tps,
head,
tail,
rtp_seq_set,
rtp_seq,
rtp_ts_set,
rtp_base_ts,
rtcp_received,
ntp_frac,
ntp_sec,
rtp_ts);
if (rtp_byte_stream != NULL) {
return (rtp_byte_stream);
}
// Otherwise, create default...
break;
case MPEG4IP_AUDIO_MP3:
rtp_byte_stream =
new CMP3RtpByteStream(rtp_pt, fmt, ondemand, tps, head, tail,
rtp_seq_set, rtp_seq,
rtp_ts_set, rtp_base_ts,
rtcp_received, ntp_frac, ntp_sec, rtp_ts);
if (rtp_byte_stream != NULL) {
player_debug_message("Starting mp3 2250 byte stream");
return (rtp_byte_stream);
}
break;
case MPEG4IP_AUDIO_MP3_ROBUST:
rtp_byte_stream =
new CRfc3119RtpByteStream(rtp_pt, fmt, ondemand, tps, head, tail,
rtp_seq_set, rtp_seq,
rtp_ts_set, rtp_base_ts,
rtcp_received, ntp_frac, ntp_sec, rtp_ts);
if (rtp_byte_stream != NULL) {
player_debug_message("Starting mpa robust byte stream");
return (rtp_byte_stream);
}
break;
case MPEG4IP_AUDIO_GENERIC:
rtp_byte_stream =
new CAudioRtpByteStream(rtp_pt, fmt, ondemand, tps, head, tail,
rtp_seq_set, rtp_seq,
rtp_ts_set, rtp_base_ts,
rtcp_received, ntp_frac, ntp_sec, rtp_ts);
if (rtp_byte_stream != NULL) {
player_debug_message("Starting generic audio byte stream");
return (rtp_byte_stream);
}
default:
break;
}
}
rtp_byte_stream = new CRtpByteStream(fmt->media->media,
fmt,
rtp_pt,
ondemand,
tps,
head,
tail,
rtp_seq_set,
rtp_seq,
rtp_ts_set,
rtp_base_ts,
rtcp_received,
ntp_frac,
ntp_sec,
rtp_ts);
return (rtp_byte_stream);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -