int CMp4File::create_media (CPlayerSession *psptr, int have_audio_driver, control_callback_vft_t *cc_vft) { uint video_count, video_offset; uint text_count, text_offset; uint audio_count, audio_offset; MP4TrackId trackId; video_query_t *vq; audio_query_t *aq; text_query_t *tq; uint ix; codec_plugin_t *plugin; int ret_value = 0; uint8_t *foo; u_int32_t bufsize; uint32_t verb = MP4GetVerbosity(m_mp4file); MP4SetVerbosity(m_mp4file, verb & ~(MP4_DETAILS_ERROR)); video_count = MP4GetNumberOfTracks(m_mp4file, MP4_VIDEO_TRACK_TYPE); audio_count = MP4GetNumberOfTracks(m_mp4file, MP4_AUDIO_TRACK_TYPE); text_count = MP4GetNumberOfTracks(m_mp4file, MP4_CNTL_TRACK_TYPE); mp4f_message(LOG_DEBUG, "cntl tracks %u", text_count); MP4SetVerbosity(m_mp4file, verb); if (video_count == 0 && audio_count == 0 && text_count == 0) { psptr->set_message("No audio, video or control tracks in file"); return -1; } if (video_count > 0) { vq = (video_query_t *)malloc(sizeof(video_query_t) * video_count); memset(vq, 0, sizeof(video_query_t) * video_count); } else { vq = NULL; } if (have_audio_driver && audio_count > 0) { aq = (audio_query_t *)malloc(sizeof(audio_query_t) * audio_count); memset(aq, 0, sizeof(audio_query_t) * audio_count); } else { aq = NULL; } if (text_count > 0) { tq = (text_query_t *)malloc(sizeof(text_query_t) * text_count); memset(tq, 0, sizeof(text_query_t) * text_count); } else { tq = NULL; } for (ix = 0, video_offset = 0; ix < video_count; ix++) { trackId = MP4FindTrackId(m_mp4file, ix, MP4_VIDEO_TRACK_TYPE); const char *media_data_name; media_data_name = MP4GetTrackMediaDataName(m_mp4file, trackId); // for now, treat mp4v and encv the same vq[video_offset].track_id = trackId; vq[video_offset].stream_type = STREAM_TYPE_MP4_FILE; vq[video_offset].compressor = media_data_name; if (strcasecmp(media_data_name, "mp4v") == 0 || strcasecmp(media_data_name, "encv") == 0) { uint8_t video_type = MP4GetTrackEsdsObjectTypeId(m_mp4file, trackId); uint8_t profileID = MP4GetVideoProfileLevel(m_mp4file, trackId); mp4f_message(LOG_DEBUG, "MP4 - got track %x profile ID %d", trackId, profileID); MP4SetVerbosity(m_mp4file, verb & ~(MP4_DETAILS_ERROR)); MP4GetTrackESConfiguration(m_mp4file, trackId, &foo, &bufsize); MP4SetVerbosity(m_mp4file, verb); vq[video_offset].type = video_type; vq[video_offset].profile = profileID; vq[video_offset].fptr = NULL; vq[video_offset].config = foo; vq[video_offset].config_len = bufsize; } else if (strcasecmp(media_data_name, "avc1") == 0) { uint8_t profile, level; uint8_t **seqheader, **pictheader; uint32_t *pictheadersize, *seqheadersize; uint32_t ix; MP4GetTrackH264ProfileLevel(m_mp4file, trackId, &profile, &level); MP4GetTrackH264SeqPictHeaders(m_mp4file, trackId, &seqheader, &seqheadersize, &pictheader, &pictheadersize); bufsize = 0; for (ix = 0; seqheadersize[ix] != 0; ix++) { bufsize += seqheadersize[ix] + 4; } for (ix = 0; pictheadersize[ix] != 0; ix++) { bufsize += pictheadersize[ix] + 4; } foo = (uint8_t *)malloc(bufsize + 4); memset(foo, 0, bufsize + 4); uint32_t copied = 0; // headers do not have the byte stream start code stored in the file for (ix = 0; seqheadersize[ix] != 0; ix++) { foo[copied] = 0; foo[copied + 1] = 0; foo[copied + 2] = 0; foo[copied + 3] = 1; copied += 4; // add header memcpy(foo + copied, seqheader[ix], seqheadersize[ix]); copied += seqheadersize[ix]; free(seqheader[ix]); } free(seqheader); free(seqheadersize); for (ix = 0; pictheadersize[ix] != 0; ix++) { foo[copied] = 0; foo[copied + 1] = 0; foo[copied + 2] = 0; foo[copied + 3] = 1; copied += 4; // add header memcpy(foo + copied, pictheader[ix], pictheadersize[ix]); copied += pictheadersize[ix]; free(pictheader[ix]); } free(pictheader); free(pictheadersize); vq[video_offset].type = level; vq[video_offset].profile = profile; vq[video_offset].fptr = NULL; vq[video_offset].config = foo; vq[video_offset].config_len = bufsize; } else { MP4GetTrackVideoMetadata(m_mp4file, trackId, &foo, &bufsize); vq[video_offset].config = foo; vq[video_offset].config_len = bufsize; } plugin = check_for_video_codec(vq[video_offset].stream_type, vq[video_offset].compressor, NULL, vq[video_offset].type, vq[video_offset].profile, vq[video_offset].config, vq[video_offset].config_len, &config); if (plugin == NULL) { psptr->set_message("Can't find plugin for video %s type %d, profile %d", vq[video_offset].compressor, vq[video_offset].type, vq[video_offset].profile); m_illegal_video_codec++; ret_value = 1; // possibly memleak for foo here } else { vq[video_offset].h = MP4GetTrackVideoHeight(m_mp4file, trackId); vq[video_offset].w = MP4GetTrackVideoWidth(m_mp4file, trackId); vq[video_offset].frame_rate = MP4GetTrackVideoFrameRate(m_mp4file, trackId); vq[video_offset].enabled = 0; vq[video_offset].reference = NULL; video_offset++; } } audio_offset = 0; if (have_audio_driver) { for (ix = 0; ix < audio_count; ix++) { trackId = MP4FindTrackId(m_mp4file, ix, MP4_AUDIO_TRACK_TYPE); const char *media_data_name; media_data_name = MP4GetTrackMediaDataName(m_mp4file, trackId); aq[audio_offset].track_id = trackId; aq[audio_offset].stream_type = STREAM_TYPE_MP4_FILE; aq[audio_offset].compressor = media_data_name; if (strcasecmp(media_data_name, "mp4a") == 0 || strcasecmp(media_data_name, "enca") == 0) { uint8_t *userdata = NULL; u_int32_t userdata_size; aq[audio_offset].type = MP4GetTrackEsdsObjectTypeId(m_mp4file, trackId); MP4SetVerbosity(m_mp4file, verb & ~(MP4_DETAILS_ERROR)); aq[audio_offset].profile = MP4GetAudioProfileLevel(m_mp4file); MP4GetTrackESConfiguration(m_mp4file, trackId, &userdata, &userdata_size); MP4SetVerbosity(m_mp4file, verb); aq[audio_offset].config = userdata; aq[audio_offset].config_len = userdata_size; } plugin = check_for_audio_codec(aq[audio_offset].stream_type, aq[audio_offset].compressor, NULL, aq[audio_offset].type, aq[audio_offset].profile, aq[audio_offset].config, aq[audio_offset].config_len, &config); if (plugin != NULL) { aq[audio_offset].fptr = NULL; aq[audio_offset].sampling_freq = MP4GetTrackTimeScale(m_mp4file, trackId); MP4SetVerbosity(m_mp4file, verb & ~(MP4_DETAILS_ERROR)); aq[audio_offset].chans = MP4GetTrackAudioChannels(m_mp4file, trackId); MP4SetVerbosity(m_mp4file, verb); aq[audio_offset].enabled = 0; aq[audio_offset].reference = NULL; audio_offset++; m_have_audio = true; } else { m_illegal_audio_codec++; ret_value = 1; } } } else { if (audio_count) ret_value = 1; } text_offset = 0; for (ix = 0; ix < text_count; ix++) { trackId = MP4FindTrackId(m_mp4file, ix, MP4_CNTL_TRACK_TYPE); const char *media_data_name; media_data_name = MP4GetTrackMediaDataName(m_mp4file, trackId); tq[text_offset].track_id = trackId; tq[text_offset].stream_type = STREAM_TYPE_MP4_FILE; tq[text_offset].compressor = media_data_name; plugin = check_for_text_codec(tq[text_offset].stream_type, tq[text_offset].compressor, NULL, NULL, 0, &config); if (plugin != NULL) { tq[text_offset].fptr = NULL; tq[text_offset].enabled = 0; tq[text_offset].reference = NULL; text_offset++; } else { m_illegal_text_codec++; ret_value = 1; } } if (video_offset == 0 && audio_offset == 0 && text_offset == 0) { psptr->set_message("No playable codecs in mp4 file"); return -1; } if (cc_vft && cc_vft->media_list_query != NULL) { (cc_vft->media_list_query)(psptr, video_offset, vq, audio_offset, aq, text_offset, tq); } else { if (video_offset > 0) { vq[0].enabled = 1; } if (audio_offset > 0) { aq[0].enabled = 1; } if (text_offset > 0) { tq[0].enabled = 1; } } int vidret, audret, textret; uint start_desc = 1; vidret = create_video(psptr, vq, video_offset, start_desc); free(vq); if (vidret < 0) { free(aq); free(tq); return -1; } audret = create_audio(psptr, aq, audio_offset, start_desc); free(aq); textret = create_text(psptr, tq, text_offset, start_desc); free(tq); if (audret < 0 || textret < 0) ret_value = -1; char *name; verb = MP4GetVerbosity(m_mp4file); MP4SetVerbosity(m_mp4file, verb & ~(MP4_DETAILS_ERROR)); if (MP4GetMetadataName(m_mp4file, &name) && name != NULL) { psptr->set_session_desc(0, name); free(name); } MP4SetVerbosity(m_mp4file, verb); return (ret_value); }
int CMp4File::create_video(CPlayerSession *psptr, video_query_t *vq, uint video_offset, uint &start_desc) { uint ix; CPlayerMedia *mptr; codec_plugin_t *plugin; const char *file_kms_uri; const char *inuse_kms_uri; for (ix = 0; ix < video_offset; ix++) { if (vq[ix].enabled != 0) { mptr = new CPlayerMedia(psptr, VIDEO_SYNC); if (mptr == NULL) { return (-1); } video_info_t *vinfo; vinfo = (video_info_t *)malloc(sizeof(video_info_t)); vinfo->height = vq[ix].h; vinfo->width = vq[ix].w; plugin = check_for_video_codec(vq[ix].stream_type, vq[ix].compressor, NULL, vq[ix].type, vq[ix].profile, vq[ix].config, vq[ix].config_len, &config); int ret = mptr->create_video_plugin(plugin, vq[ix].stream_type, vq[ix].compressor, vq[ix].type, vq[ix].profile, NULL, // sdp info vinfo, // video info vq[ix].config, vq[ix].config_len); if (ret < 0) { mp4f_message(LOG_ERR, "Failed to create plugin data"); psptr->set_message("Failed to start plugin"); delete mptr; return -1; } CMp4VideoByteStream *vbyte = NULL; uint64_t IVLength; /* check if clear-text or ismacryp. * in this context original format is encv * and compressor specifies which codec */ uint32_t verb = MP4GetVerbosity(m_mp4file); MP4SetVerbosity(m_mp4file, verb & ~(MP4_DETAILS_ERROR)); if (strcasecmp(vq[ix].original_fmt, "avc1") == 0) { vbyte = new CMp4H264VideoByteStream(this, vq[ix].track_id); } else if (strcasecmp(vq[ix].original_fmt, "encv") == 0) { MP4GetTrackIntegerProperty(m_mp4file, vq[ix].track_id, "mdia.minf.stbl.stsd.encv.sinf.schi.iSFM.IV-length", &IVLength); if (strcasecmp(vq[ix].compressor, "mp4v") == 0) { vbyte = new CMp4EncVideoByteStream(this, vq[ix].track_id,IVLength); } else if (((strcasecmp(vq[ix].compressor, "avc1") == 0) || (strcasecmp(vq[ix].compressor, "264b")) == 0)) { vbyte = new CMp4EncH264VideoByteStream(this, vq[ix].track_id,IVLength); // check if file kms uri matches in-use kms uri // advisory only MP4GetTrackStringProperty(m_mp4file, vq[ix].track_id, "mdia.minf.stbl.stsd.encv.sinf.schi.iKMS.kms_URI", &file_kms_uri); inuse_kms_uri = ((CMp4EncH264VideoByteStream *)vbyte)->get_inuse_kms_uri(); if (file_kms_uri && inuse_kms_uri) { if (strcmp(file_kms_uri, inuse_kms_uri)) { mp4f_message(LOG_DEBUG, "KMS in file (%s) does not match KMS in use (%s)\n", file_kms_uri, inuse_kms_uri); } } } } else { vbyte = new CMp4VideoByteStream(this, vq[ix].track_id); } MP4SetVerbosity(m_mp4file, verb); if (vbyte == NULL) { delete mptr; return (-1); } ret = mptr->create_media("video", vbyte); if (ret != 0) { return (-1); } MP4SetVerbosity(m_mp4file, verb & ~(MP4_DETAILS_ERROR)); char *mp4info = MP4Info(m_mp4file, vq[ix].track_id); MP4SetVerbosity(m_mp4file, verb); char *temp = mp4info; while (*temp != '\0') { if (isspace(*temp)) *temp = ' '; if (!isprint(*temp)) *temp = '*'; temp++; } psptr->set_session_desc(start_desc, mp4info); free(mp4info); start_desc++; } else { if (vq[ix].config != NULL) free((void *)vq[ix].config); } } return 0; }
int CMp4File::create_video(CPlayerSession *psptr, video_query_t *vq, uint video_offset, uint &start_desc) { uint ix; CPlayerMedia *mptr; codec_plugin_t *plugin; for (ix = 0; ix < video_offset; ix++) { if (vq[ix].enabled != 0) { mptr = new CPlayerMedia(psptr, VIDEO_SYNC); if (mptr == NULL) { return (-1); } video_info_t *vinfo; vinfo = (video_info_t *)malloc(sizeof(video_info_t)); vinfo->height = vq[ix].h; vinfo->width = vq[ix].w; plugin = check_for_video_codec(vq[ix].stream_type, vq[ix].compressor, NULL, vq[ix].type, vq[ix].profile, vq[ix].config, vq[ix].config_len, &config); int ret = mptr->create_video_plugin(plugin, vq[ix].stream_type, vq[ix].compressor, vq[ix].type, vq[ix].profile, NULL, // sdp info vinfo, // video info vq[ix].config, vq[ix].config_len); if (ret < 0) { mp4f_message(LOG_ERR, "Failed to create plugin data"); psptr->set_message("Failed to start plugin"); delete mptr; return -1; } CMp4VideoByteStream *vbyte; uint64_t IVLength; /* check if ismacryp */ uint32_t verb = MP4GetVerbosity(m_mp4file); MP4SetVerbosity(m_mp4file, verb & ~(MP4_DETAILS_ERROR)); if (strcasecmp(vq[ix].compressor, "avc1") == 0) { vbyte = new CMp4H264VideoByteStream(this, vq[ix].track_id); } else if (strcasecmp(vq[ix].compressor, "encv") == 0) { MP4GetTrackIntegerProperty(m_mp4file, vq[ix].track_id, "mdia.minf.stbl.stsd.encv.sinf.schi.iSFM.IV-length", &IVLength); vbyte = new CMp4EncVideoByteStream(this, vq[ix].track_id,IVLength); } else { vbyte = new CMp4VideoByteStream(this, vq[ix].track_id); } MP4SetVerbosity(m_mp4file, verb); if (vbyte == NULL) { delete mptr; return (-1); } ret = mptr->create_media("video", vbyte); if (ret != 0) { return (-1); } MP4SetVerbosity(m_mp4file, verb & ~(MP4_DETAILS_ERROR)); char *mp4info = MP4Info(m_mp4file, vq[ix].track_id); MP4SetVerbosity(m_mp4file, verb); char *temp = mp4info; while (*temp != '\0') { if (isspace(*temp)) *temp = ' '; if (!isprint(*temp)) *temp = '*'; temp++; } psptr->set_session_desc(start_desc, mp4info); free(mp4info); start_desc++; } else { if (vq[ix].config != NULL) free((void *)vq[ix].config); } } return 0; }
static int create_mpeg3_video (video_query_t *vq, mpeg2ps_t *vfile, CPlayerSession *psptr, int &sdesc) { CPlayerMedia *mptr; codec_plugin_t *plugin; int ret; plugin = check_for_video_codec(STREAM_TYPE_MPEG_FILE, "mp2v", NULL, vq->type, -1, NULL, 0, &config); if (plugin == NULL) { psptr->set_message("Can't find plugin for mpeg video"); return 0; } mptr = new CPlayerMedia(psptr, VIDEO_SYNC); if (mptr == NULL) { psptr->set_message("Could not create video media"); return -1; } video_info_t *vinfo; vinfo = MALLOC_STRUCTURE(video_info_t); vinfo->height = vq->h; vinfo->width = vq->w; char buffer[80]; int bitrate; char *name = mpeg2ps_get_video_stream_name(vfile, vq->track_id); ret = snprintf(buffer, 80, "%s Video, %d x %d", name, vinfo->width, vinfo->height); free(name); if (vq->frame_rate != 0.0) { ret += snprintf(buffer + ret, 80 - ret, ", %g", vq->frame_rate); } bitrate = (int)(mpeg2ps_get_video_stream_bitrate(vfile, vq->track_id) / 1000.0); if (bitrate > 0) { snprintf(buffer + ret, 80 - ret, ", %d kbps", bitrate); } psptr->set_session_desc(sdesc, buffer); sdesc++; mpeg3f_message(LOG_DEBUG, "video stream h %d w %d fr %g bitr %d", vinfo->height, vinfo->width, vq->frame_rate, bitrate); ret = mptr->create_video_plugin(plugin, STREAM_TYPE_MPEG_FILE, vq->compressor, vq->type, vq->profile, NULL, vinfo, NULL, 0); if (ret < 0) { mpeg3f_message(LOG_ERR, "Failed to create video plugin"); psptr->set_message("Failed to create video plugin"); free(vinfo); return -1; } CMpeg3VideoByteStream *vbyte; vbyte = new CMpeg3VideoByteStream(vfile, vq->track_id); if (vbyte == NULL) { psptr->set_message("Failed to create video bytestream"); return -1; } ret = mptr->create_media("video", vbyte); if (ret != 0) { psptr->set_message("Couldn't create video media"); return -1; } return 1; }
int create_media_for_mpeg_file (CPlayerSession *psptr, const char *name, int have_audio_driver, control_callback_vft_t *cc_vft) { mpeg2ps_t *file; int video_streams, audio_streams; int video_cnt, audio_cnt; int ix; codec_plugin_t *plugin; int video_offset, audio_offset; int ret; int sdesc; file = mpeg2ps_init(name); if (file == NULL) { psptr->set_message("file %s is not a valid .mpg file", name); return -1; } psptr->set_media_close_callback(close_mpeg3_file, (void *)file); video_streams = mpeg2ps_get_video_stream_count(file); audio_streams = mpeg2ps_get_audio_stream_count(file); video_cnt = 0; if (video_streams > 0) { plugin = check_for_video_codec(STREAM_TYPE_MPEG_FILE, "mp2v", NULL, mpeg2ps_get_video_stream_type(file, 0), -1, NULL, 0, &config); if (plugin != NULL) video_cnt = video_streams; } for (ix = 0, audio_cnt = 0; ix < audio_streams; ix++) { plugin = check_for_audio_codec(STREAM_TYPE_MPEG_FILE, NULL, NULL, mpeg2ps_get_audio_stream_type(file, ix), -1, NULL, 0, &config); if (plugin != NULL) audio_cnt++; } video_query_t *vq; audio_query_t *aq; if (video_cnt > 0) { vq = (video_query_t *)malloc(sizeof(video_query_t) * video_cnt); } else { vq = NULL; } if (have_audio_driver && audio_cnt > 0) { aq = (audio_query_t *)malloc(sizeof(audio_query_t) * audio_cnt); } else { aq = NULL; } video_offset = 0; for (ix = 0; ix < video_cnt; ix++) { vq[video_offset].track_id = ix; vq[video_offset].stream_type = STREAM_TYPE_MPEG_FILE; vq[video_offset].compressor = "mp2v"; vq[video_offset].type = mpeg2ps_get_video_stream_type(file, ix); vq[video_offset].profile = -1; vq[video_offset].fptr = NULL; vq[video_offset].h = mpeg2ps_get_video_stream_height(file, ix); vq[video_offset].w = mpeg2ps_get_video_stream_width(file, ix); vq[video_offset].frame_rate = mpeg2ps_get_video_stream_framerate(file, ix); vq[video_offset].config = NULL; vq[video_offset].config_len = 0; vq[video_offset].enabled = 0; vq[video_offset].reference = NULL; video_offset++; } audio_offset = 0; if (have_audio_driver) { for (ix = 0; ix < audio_streams; ix++) { plugin = check_for_audio_codec(STREAM_TYPE_MPEG_FILE, NULL, NULL, mpeg2ps_get_audio_stream_type(file, ix), -1, NULL, 0, &config); if (plugin != NULL) { aq[audio_offset].track_id = ix; aq[audio_offset].stream_type = STREAM_TYPE_MPEG_FILE; aq[audio_offset].compressor = NULL; aq[audio_offset].type = mpeg2ps_get_audio_stream_type(file, ix); aq[audio_offset].profile = -1; aq[audio_offset].fptr = NULL; aq[audio_offset].config = NULL; aq[audio_offset].config_len = 0; aq[audio_offset].sampling_freq = mpeg2ps_get_audio_stream_sample_freq(file, ix); aq[audio_offset].chans = mpeg2ps_get_audio_stream_channels(file, ix); aq[audio_offset].enabled = 0; aq[audio_offset].reference = NULL; audio_offset++; } else { mpeg3f_message(LOG_ERR, "Unsupported audio type %s in track %d", mpeg2ps_get_audio_stream_name(file, ix), ix); } } } if (audio_offset == 0 && video_offset == 0) { psptr->set_message("No playable streams in file"); CHECK_AND_FREE(aq); CHECK_AND_FREE(vq); return -1; } if (cc_vft && cc_vft->media_list_query != NULL) { (cc_vft->media_list_query)(psptr, video_offset, vq, audio_offset, aq, 0, NULL); } else { if (video_offset > 0) vq[0].enabled = 1; if (audio_offset > 0) aq[0].enabled = 1; } ret = 0; sdesc = 1; for (ix = 0; ret >= 0 && ix < video_offset; ix++) { if (vq[ix].enabled) { ret = create_mpeg3_video(&vq[ix], file, psptr, sdesc); if (ret <= 0) { } } } if (ret >= 0) { for (ix = 0; ix < audio_offset && ret >= 0; ix++) { if (aq[ix].enabled) { ret = create_mpeg3_audio(&aq[ix], file, psptr, sdesc); if (ret <= 0) { } } } } free(vq); free(aq); if (ret < 0) { mpeg2ps_close(file); return ret; } psptr->session_set_seekable(1); return 0; }
/* * Create the media for the quicktime file, and set up some session stuff. */ int create_media_for_avi_file (CPlayerSession *psptr, const char *name, char *errmsg, uint32_t errlen, int have_audio_driver, control_callback_vft_t *cc_vft) { CAviFile *Avifile1 = NULL; avi_t *avi; CPlayerMedia *mptr; avi = AVI_open_input_file(name, 1); if (avi == NULL) { snprintf(errmsg, errlen, "%s", AVI_strerror()); player_error_message("%s", AVI_strerror()); return (-1); } int video_count = 1; codec_plugin_t *plugin; video_query_t vq; const char *codec_name = AVI_video_compressor(avi); player_debug_message("Trying avi video codec %s", codec_name); plugin = check_for_video_codec(STREAM_TYPE_AVI_FILE, codec_name, NULL, -1, -1, NULL, 0, &config); if (plugin == NULL) { video_count = 0; } else { vq.track_id = 1; vq.stream_type = STREAM_TYPE_AVI_FILE; vq.compressor = codec_name; vq.type = -1; vq.profile = -1; vq.fptr = NULL; vq.h = AVI_video_height(avi); vq.w = AVI_video_width(avi); vq.frame_rate = AVI_video_frame_rate(avi); vq.config = NULL; vq.config_len = 0; vq.enabled = 0; vq.reference = NULL; } int have_audio = 0; int audio_count = 0; audio_query_t aq; if (AVI_audio_bytes(avi) != 0) { have_audio = 1; plugin = check_for_audio_codec(STREAM_TYPE_AVI_FILE, NULL, NULL, AVI_audio_format(avi), -1, NULL, 0, &config); if (plugin != NULL) { audio_count = 1; aq.track_id = 1; aq.stream_type = STREAM_TYPE_AVI_FILE; aq.compressor = NULL; aq.type = AVI_audio_format(avi); aq.profile = -1; aq.fptr = NULL; aq.sampling_freq = AVI_audio_rate(avi); aq.chans = AVI_audio_channels(avi); aq.config = NULL; aq.config_len = 0; aq.enabled = 0; aq.reference = NULL; } } if (cc_vft != NULL && cc_vft->media_list_query != NULL) { (cc_vft->media_list_query)(psptr, video_count, &vq, audio_count, &aq); } else { if (video_count != 0) vq.enabled = 1; if (audio_count != 0) aq.enabled = 1; } if ((video_count == 0 || vq.enabled == 0) && (audio_count == 0 || aq.enabled == 0)) { snprintf(errmsg, errlen, "No audio or video tracks enabled or playable"); AVI_close(avi); return -1; } Avifile1 = new CAviFile(name, avi, vq.enabled, audio_count); psptr->set_media_close_callback(close_avi_file, Avifile1); if (video_count != 0 && vq.enabled) { mptr = new CPlayerMedia(psptr); if (mptr == NULL) { return (-1); } video_info_t *vinfo = MALLOC_STRUCTURE(video_info_t); if (vinfo == NULL) return (-1); vinfo->height = vq.h; vinfo->width = vq.w; player_debug_message("avi file h %d w %d frame rate %g", vinfo->height, vinfo->width, vq.frame_rate); plugin = check_for_video_codec(STREAM_TYPE_AVI_FILE, codec_name, NULL, -1, -1, NULL, 0, &config); int ret; ret = mptr->create_video_plugin(plugin, STREAM_TYPE_AVI_FILE, codec_name, -1, -1, NULL, vinfo, NULL, 0); if (ret < 0) { snprintf(errmsg, errlen, "Failed to create video plugin %s", codec_name); player_error_message("Failed to create plugin data"); delete mptr; return -1; } CAviVideoByteStream *vbyte = new CAviVideoByteStream(Avifile1); if (vbyte == NULL) { delete mptr; return (-1); } vbyte->config(AVI_video_frames(avi), vq.frame_rate); ret = mptr->create(vbyte, TRUE, errmsg, errlen); if (ret != 0) { return (-1); } } int seekable = 1; if (have_audio_driver > 0 && audio_count > 0 && aq.enabled != 0) { plugin = check_for_audio_codec(STREAM_TYPE_AVI_FILE, NULL, NULL, aq.type, -1, NULL, 0, &config); CAviAudioByteStream *abyte; mptr = new CPlayerMedia(psptr); if (mptr == NULL) { return (-1); } audio_info_t *ainfo; ainfo = MALLOC_STRUCTURE(audio_info_t); ainfo->freq = aq.sampling_freq; ainfo->chans = aq.chans; ainfo->bitspersample = AVI_audio_bits(avi); int ret; ret = mptr->create_audio_plugin(plugin, aq.stream_type, aq.compressor, aq.type, aq.profile, NULL, ainfo, NULL, 0); if (ret < 0) { delete mptr; player_error_message("Couldn't create audio from plugin %s", plugin->c_name); return -1; } abyte = new CAviAudioByteStream(Avifile1); ret = mptr->create(abyte, FALSE, errmsg, errlen); if (ret != 0) { return (-1); } seekable = 0; } psptr->session_set_seekable(seekable); if (audio_count == 0 && have_audio != 0) { snprintf(errmsg, errlen, "Unknown Audio Codec in avi file "); return (1); } if (video_count != 1) { snprintf(errmsg, errlen, "Unknown Video Codec %s in avi file", codec_name); return (1); } 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; }
static int create_media_from_sdp (CPlayerSession *psptr, session_desc_t *sdp, char *errmsg, uint32_t errlen, int have_audio_driver, int broadcast, int only_check_first, control_callback_vft_t *cc_vft) { int err; int media_count = 0; int invalid_count = 0; int have_audio_but_no_driver = 0; char buffer[80]; codec_plugin_t *codec; format_list_t *fmt; int audio_count, video_count; int audio_offset, video_offset; int ix; if (sdp->session_name != NULL) { snprintf(buffer, sizeof(buffer), "Name: %s", sdp->session_name); psptr->set_session_desc(0, buffer); } if (sdp->session_desc != NULL) { snprintf(buffer, sizeof(buffer), "Description: %s", sdp->session_desc); psptr->set_session_desc(1, buffer); } #ifndef _WIN32 if (sdp->media != NULL && sdp->media->next == NULL && strcasecmp(sdp->media->media, "video") == 0 && sdp->media->fmt != NULL && strcmp(sdp->media->fmt->fmt, "33") == 0) { // we have a mpeg2 transport stream return (create_mpeg2t_session(psptr, NULL, sdp, errmsg, errlen, have_audio_driver, cc_vft)); } #endif media_desc_t *sdp_media; audio_count = video_count = 0; for (sdp_media = psptr->get_sdp_info()->media; sdp_media != NULL; sdp_media = sdp_media->next) { if (strcasecmp(sdp_media->media, "audio") == 0) { if (have_audio_driver == 0) { have_audio_but_no_driver = 1; } else { audio_count++; } } else if (strcasecmp(sdp_media->media, "video") == 0) { video_count++; } } video_query_t *vq; audio_query_t *aq; if (video_count > 0) { vq = (video_query_t *)malloc(sizeof(video_query_t) * video_count); } else { vq = NULL; } if (audio_count > 0) { aq = (audio_query_t *)malloc(sizeof(audio_query_t) * audio_count); } else { aq = NULL; } video_offset = audio_offset = 0; for (sdp_media = psptr->get_sdp_info()->media; sdp_media != NULL; sdp_media = sdp_media->next) { if (have_audio_driver != 0 && strcasecmp(sdp_media->media, "audio") == 0) { fmt = sdp_media->fmt; codec = NULL; while (codec == NULL && fmt != NULL) { codec = check_for_audio_codec(STREAM_TYPE_RTP, NULL, fmt, -1, -1, NULL, 0, &config); if (codec == NULL) { if (only_check_first != 0) fmt = NULL; else fmt = fmt->next; } } if (codec == NULL) { invalid_count++; continue; } else { // set up audio qualifier aq[audio_offset].track_id = audio_offset; aq[audio_offset].stream_type = STREAM_TYPE_RTP; aq[audio_offset].compressor = NULL; aq[audio_offset].type = -1; aq[audio_offset].profile = -1; aq[audio_offset].fptr = fmt; aq[audio_offset].sampling_freq = -1; aq[audio_offset].chans = -1; aq[audio_offset].enabled = 0; aq[audio_offset].reference = NULL; audio_offset++; } } else if (strcasecmp(sdp_media->media, "video") == 0) { fmt = sdp_media->fmt; codec = NULL; while (codec == NULL && fmt != NULL) { codec = check_for_video_codec(STREAM_TYPE_RTP, NULL, fmt, -1, -1, NULL, 0, &config); if (codec == NULL) { if (only_check_first != 0) fmt = NULL; else fmt = fmt->next; } } if (codec == NULL) { invalid_count++; continue; } else { vq[video_offset].track_id = video_offset; vq[video_offset].stream_type = STREAM_TYPE_RTP; vq[video_offset].compressor = NULL; vq[video_offset].type = -1; vq[video_offset].profile = -1; vq[video_offset].fptr = fmt; vq[video_offset].h = -1; vq[video_offset].w = -1; vq[video_offset].frame_rate = -1; vq[video_offset].enabled = 0; vq[video_offset].reference = NULL; video_offset++; } } else { player_error_message("Skipping media type `%s\'", sdp_media->media); continue; } } // okay - from here, write the callback call, and go ahead... if (cc_vft != NULL && cc_vft->media_list_query != NULL) { (cc_vft->media_list_query)(psptr, video_offset, vq, audio_offset, aq); } else { if (video_offset > 0) { vq[0].enabled = 1; } if (audio_offset > 0) { aq[0].enabled = 1; } } for (ix = 0; ix < video_offset; ix++) { if (vq[ix].enabled != 0) { CPlayerMedia *mptr = new CPlayerMedia(psptr); err = mptr->create_streaming(vq[ix].fptr->media, errmsg, errlen, broadcast, config.get_config_value(CONFIG_USE_RTP_OVER_RTSP), media_count); if (err < 0) { return (-1); } if (err > 0) { delete mptr; } else media_count++; } } for (ix = 0; ix < audio_offset; ix++) { if (aq[ix].enabled != 0) { CPlayerMedia *mptr = new CPlayerMedia(psptr); err = mptr->create_streaming(aq[ix].fptr->media, errmsg, errlen, broadcast, config.get_config_value(CONFIG_USE_RTP_OVER_RTSP), media_count); if (err < 0) { return (-1); } if (err > 0) { delete mptr; } else media_count++; } } if (aq != NULL) free(aq); if (vq != NULL) free(vq); if (media_count == 0) { snprintf(errmsg, errlen, "No known codecs found in SDP"); return (-1); } psptr->streaming_media_set_up(); if (have_audio_but_no_driver > 0) { snprintf(errmsg, errlen, "Not playing audio codecs - no driver"); return (1); } if (invalid_count > 0) { snprintf(errmsg, errlen, "There were unknowns codecs during decode - playing valid ones"); return (1); } return (0); }