static GF_Err FFD_CloseService(GF_InputService *plug) { FFDemux *ffd = plug->priv; ffd->is_running = 0; #ifndef FF_API_CLOSE_INPUT_FILE if (ffd->ctx) av_close_input_file(ffd->ctx); #else if (ffd->ctx) avformat_close_input(&ffd->ctx); #endif ffd->ctx = NULL; ffd->audio_ch = ffd->video_ch = NULL; ffd->audio_run = ffd->video_run = 0; if (ffd->dnload) { if (ffd->is_running) { while (!ffd->is_running) gf_sleep(1); ffd->is_running = 0; } gf_service_download_del(ffd->dnload); ffd->dnload = NULL; } if (ffd->buffer) gf_free(ffd->buffer); ffd->buffer = NULL; gf_service_disconnect_ack(ffd->service, NULL, GF_OK); #ifdef FFMPEG_DUMP_REMOTE if (ffd->outdbg) fclose(ffd->outdbg); #endif return GF_OK; }
GF_Err ISOR_DisconnectChannel(GF_InputService *plug, LPNETCHANNEL channel) { ISOMChannel *ch; GF_Err e; ISOMReader *read; if (!plug || !plug->priv) return GF_SERVICE_ERROR; read = (ISOMReader *) plug->priv; if (!read->mov) return GF_SERVICE_ERROR; gf_mx_p(read->segment_mutex); e = GF_OK; ch = isor_get_channel(read, channel); assert(ch); if (!ch) { e = GF_STREAM_NOT_FOUND; goto exit; } /*signal the service is broken but still process the delete*/ isor_delete_channel(read, ch); assert(!isor_get_channel(read, channel)); exit: if (read->input->query_proxy && read->input->proxy_udta && read->input->proxy_type) { send_proxy_command(read, 1, 0, e, NULL, channel); } else { gf_service_disconnect_ack(read->service, channel, e); } gf_mx_v(read->segment_mutex); return e; }
static GF_Err VTT_CloseService(GF_InputService *plug) { VTTIn *vttin; if (!plug) return GF_BAD_PARAM; vttin = (VTTIn *)plug->priv; if (!vttin) return GF_BAD_PARAM; //if (vttin->szFile) { // gf_delete_file(vttin->szFile); // gf_free(vttin->szFile); //} //vttin->szFile = NULL; if (vttin->dnload) { gf_service_download_del(vttin->dnload); } vttin->dnload = NULL; if (vttin->service) { gf_service_disconnect_ack(vttin->service, NULL, GF_OK); } vttin->service = NULL; return GF_OK; }
GF_Err LIBPLAYER_DisconnectChannel(GF_InputService *plug, LPNETCHANNEL channel) { LibPlayerIn *read = (LibPlayerIn *) plug->priv; GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[LibPlayerIN] instance %d disconnect channel\n", read->player_id)); gf_service_disconnect_ack(read->service, channel, GF_OK); return GF_OK; }
GF_Err ISOR_CloseService(GF_InputService *plug) { GF_Err reply; ISOMReader *read; if (!plug || !plug->priv) return GF_SERVICE_ERROR; read = (ISOMReader *) plug->priv; reply = GF_OK; read->disconnected = GF_TRUE; while (gf_list_count(read->channels)) { ISOMChannel *ch = (ISOMChannel *)gf_list_get(read->channels, 0); gf_list_rem(read->channels, 0); isor_delete_channel(read, ch); } if (read->dnload) gf_service_download_del(read->dnload); read->dnload = NULL; if (read->mov) gf_isom_close(read->mov); read->mov = NULL; if (read->input->query_proxy && read->input->proxy_udta && read->input->proxy_type) { send_proxy_command(read, GF_TRUE, GF_FALSE, reply, NULL, NULL); } else { gf_service_disconnect_ack(read->service, NULL, reply); } return GF_OK; }
GF_Err LIBPLAYER_CloseService(GF_InputService *plug) { LibPlayerIn *read = (LibPlayerIn *) plug->priv; #ifndef TEST_LIBPLAYER // only disconnect if if (read->player_type == PLAYER_FILE) { player_playback_stop(read->player); fprintf(stderr, "[LibPlayerIN]player_playback_stop for instance %d\n", read->player_id); player_uninit(read->player); fprintf(stderr, "[LibPlayerIN]player_uninit for instance %d\n", read->player_id); read->player = NULL; libplayer_id--; read->state = 0; gf_service_disconnect_ack(read->service, NULL, GF_OK); GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[LibPlayerIn] Closing libplayer instance %d\n", read->player_id)); // channel zapping dvb case, don't disconnect service } else { GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[LibPlayerIn] Don't close service libplayer instance %d, use this instance for channel zapping\n", read->player_id)); } return GF_OK; #endif }
GF_Err DC_CloseService(GF_InputService *plug) { DCReader *read = (DCReader *) plug->priv; if (read->dnload) gf_service_download_del(read->dnload); read->dnload = NULL; gf_service_disconnect_ack(read->service, NULL, GF_OK); return GF_OK; }
GF_Err DC_DisconnectChannel(GF_InputService *plug, LPNETCHANNEL channel) { Bool had_ch; DCReader *read = (DCReader *) plug->priv; had_ch = DC_RemoveChannel(read, channel); gf_service_disconnect_ack(read->service, channel, had_ch ? GF_OK : GF_STREAM_NOT_FOUND); return GF_OK; }
/* Indicate that the media source object is unused anymore */ static GF_Err MSE_CloseService(GF_InputService *plug) { GF_MSE_In *msein = (GF_MSE_In*) plug->priv; assert( msein ); GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("[MSE_IN] Received Close Service request on Service %p from terminal for URL '%s'\n", msein->mediasource->service, msein->mediasource->blobURI)); if (msein->mediasource) { gf_service_disconnect_ack(msein->mediasource->service, NULL, GF_OK); gf_mse_mediasource_del(msein->mediasource, GF_FALSE); msein->mediasource = NULL; } return GF_OK; }
static GF_Err IMG_DisconnectChannel(GF_InputService *plug, LPNETCHANNEL channel) { GF_Err e = GF_STREAM_NOT_FOUND; IMGLoader *read = (IMGLoader *)plug->priv; if (read->ch == channel) { read->ch = NULL; e = GF_OK; } gf_service_disconnect_ack(read->service, channel, e); return GF_OK; }
static GF_Err AC3_CloseService(GF_InputService *plug) { AC3Reader *read = plug->priv; if (read->stream) fclose(read->stream); read->stream = NULL; if (read->dnload) gf_service_download_del(read->dnload); read->dnload = NULL; if (read->data) gf_free(read->data); read->data = NULL; gf_service_disconnect_ack(read->service, NULL, GF_OK); return GF_OK; }
static GF_Err VTT_DisconnectChannel(GF_InputService *plug, LPNETCHANNEL channel) { VTTIn *vttin = (VTTIn *)plug->priv; GF_Err e = GF_STREAM_NOT_FOUND; if (!vttin) return GF_BAD_PARAM; if (vttin->channel == channel) { vttin->channel = NULL; e = GF_OK; } gf_service_disconnect_ack(vttin->service, channel, e); return GF_OK; }
static GF_Err AC3_DisconnectChannel(GF_InputService *plug, LPNETCHANNEL channel) { AC3Reader *read = plug->priv; GF_Err e = GF_STREAM_NOT_FOUND; if (read->ch == channel) { read->ch = NULL; if (read->data) gf_free(read->data); read->data = NULL; e = GF_OK; } gf_service_disconnect_ack(read->service, channel, e); return GF_OK; }
GF_Err MPD_CloseService(GF_InputService *plug) { GF_MPD_In *mpdin = (GF_MPD_In*) plug->priv; assert( mpdin ); GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("[MPD_IN] Received Close Service (%p) request from terminal\n", mpdin->service)); mpdin->closed = 1; if (mpdin->dash) gf_dash_close(mpdin->dash); gf_service_disconnect_ack(mpdin->service, NULL, GF_OK); return GF_OK; }
static GF_Err IMG_CloseService(GF_InputService *plug) { IMGLoader *read; if (!plug) return GF_BAD_PARAM; read = (IMGLoader *)plug->priv; if (!read) return GF_BAD_PARAM; if (read->stream) gf_fclose(read->stream); read->stream = NULL; if (read->dnload) gf_service_download_del(read->dnload); read->dnload = NULL; if (read->service) gf_service_disconnect_ack(read->service, NULL, GF_OK); return GF_OK; }
static GF_Err SAF_DisconnectChannel(GF_InputService *plug, LPNETCHANNEL channel) { SAFChannel *ch; SAFIn *read = (SAFIn *)plug->priv; GF_Err e = GF_STREAM_NOT_FOUND; ch = saf_get_channel(read, 0, channel); if (ch) { gf_list_del_item(read->channels, ch); if (ch->esd) gf_odf_desc_del((GF_Descriptor*)ch->esd); gf_free(ch); e = GF_OK; } gf_service_disconnect_ack(read->service, channel, e); return GF_OK; }
static GF_Err RP_DisconnectChannel(GF_InputService *plug, LPNETCHANNEL channel) { RTPStream *ch; RTPClient *priv = (RTPClient *)plug->priv; GF_LOG(GF_LOG_DEBUG, GF_LOG_RTP, ("[RTP] Disconnecting channel @%08x\n", channel)); ch = RP_FindChannel(priv, channel, 0, NULL, 0); if (!ch) return GF_STREAM_NOT_FOUND; gf_mx_p(priv->mx); /*disconnect stream BUT DO NOT DELETE IT since we don't store SDP*/ ch->flags &= ~RTP_CONNECTED; ch->channel = NULL; gf_mx_v(priv->mx); gf_service_disconnect_ack(priv->service, channel, GF_OK); return GF_OK; }
static GF_Err RP_CloseService(GF_InputService *plug) { u32 i; const char *opt; RTSPSession *sess; RTPClient *rtp = (RTPClient *)plug->priv; GF_LOG(GF_LOG_DEBUG, GF_LOG_RTP, ("[RTP] Closing service\n")); RP_FlushCommands(rtp); if (rtp->session_migration) { opt = gf_modules_get_option((GF_BaseInterface *) plug, "Streaming", "SessionMigrationPause"); if (opt && !strcmp(opt, "yes")) { GF_NetworkCommand com; com.command_type = GF_NET_CHAN_PAUSE; com.base.on_channel = NULL; /*send pause on all sessions*/ i=0; while ((sess = (RTSPSession *)gf_list_enum(rtp->sessions, &i))) { RP_UserCommand(sess, NULL, &com); } } RP_SaveSessionState(rtp); } else { /*remove session state file*/ if (rtp->session_state_data) { gf_free(rtp->session_state_data); rtp->session_state_data = NULL; } /*send teardown on all sessions*/ i=0; while ((sess = (RTSPSession *)gf_list_enum(rtp->sessions, &i))) { RP_Teardown(sess, NULL); } } RP_FlushCommands(rtp); /*shutdown thread*/ if (rtp->th_state==1) rtp->th_state = 0; /*confirm close*/ gf_service_disconnect_ack(rtp->service, NULL, GF_OK); return GF_OK; }
static GF_Err FFD_DisconnectChannel(GF_InputService *plug, LPNETCHANNEL channel) { GF_Err e; FFDemux *ffd = plug->priv; e = GF_STREAM_NOT_FOUND; if (ffd->audio_ch == channel) { e = GF_OK; ffd->audio_ch = NULL; ffd->audio_run = 0; } else if (ffd->video_ch == channel) { e = GF_OK; ffd->video_ch = NULL; ffd->video_run = 0; } gf_service_disconnect_ack(ffd->service, channel, e); return GF_OK; }
static GF_Err SAF_CloseService(GF_InputService *plug) { SAFIn *read = (SAFIn *)plug->priv; if (read->th) { if (read->run_state == 1) { read->run_state=0; while (read->run_state!=2) gf_sleep(2); } gf_th_del(read->th); read->th = NULL; } if (read->stream) fclose(read->stream); read->stream = NULL; if (read->dnload) gf_service_download_del(read->dnload); read->dnload = NULL; gf_service_disconnect_ack(read->service, NULL, GF_OK); return GF_OK; }
/* Callback functions used by a media parser when parsing events happens */ GF_Err gf_mse_proxy(GF_InputService *parser, GF_NetworkCommand *command) { if (!parser || !command || !parser->proxy_udta) { return GF_BAD_PARAM; } else { GF_HTML_SourceBuffer *sb = (GF_HTML_SourceBuffer *)parser->proxy_udta; switch (command->command_type) { case GF_NET_SERVICE_QUERY_INIT_RANGE: break; case GF_NET_SERVICE_QUERY_NEXT: /* The parser is asking for the next media segment in the buffer, check for the media time and give the right one */ { GF_HTML_ArrayBuffer *buffer; /* The input buffer should not be modified by append operations at the same time, no need to protect access */ buffer = (GF_HTML_ArrayBuffer *)gf_list_get(sb->input_buffer, 0); if (buffer) { command->url_query.discontinuity_type = 0; command->url_query.current_download = GF_FALSE; command->url_query.start_range = 0; command->url_query.end_range = 0; command->url_query.switch_start_range = 0; command->url_query.switch_end_range = 0; command->url_query.next_url_init_or_switch_segment = NULL; if (buffer->is_init) { GF_HTML_ArrayBuffer *next = (GF_HTML_ArrayBuffer *)gf_list_get(sb->input_buffer, 1); command->url_query.discontinuity_type = 1; if (next) { GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("[MSE] Next segment to parse %s with init \n", next->url, buffer->url)); command->url_query.next_url = next->url; command->url_query.next_url_init_or_switch_segment = buffer->url; gf_list_rem(sb->input_buffer, 0); gf_list_rem(sb->input_buffer, 0); } else { GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("[MSE] Only one init segment to parse %s, need to wait\n", buffer->url)); command->url_query.next_url = NULL; } } else { GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("[MSE] Next segment to parse %s\n", buffer->url)); command->url_query.next_url = buffer->url; gf_list_rem(sb->input_buffer, 0); } sb->prev_buffer = buffer; } else { command->url_query.next_url = NULL; command->url_query.discontinuity_type = 0; } } break; case GF_NET_SERVICE_STATUS_PROXY: /* The parser is informing the proxy about its status changes: - new track found - all tracks parsed - connect/disconnect - */ if (command->status.is_add_media) { if (command->status.desc) { gf_mse_source_buffer_store_track_desc(sb, (GF_ObjectDescriptor *)command->status.desc); } else { /* this is the last add media, we can switch updating to false */ /* the first init segment was correctly processed */ gf_mse_source_buffer_set_update(sb, GF_FALSE); /* TODO: set active tracks and send addsourcebuffer event */ /* TODO: send media loadedmetadata event */ } gf_service_declare_media(sb->mediasource->service, command->status.desc, (command->status.desc ? GF_TRUE : GF_FALSE)); } /* general connection/disconnection messages from the media parser (not track related) */ else if (!command->status.channel) { /* connection message */ if (!command->status.is_disconnect) { if (command->status.e == GF_OK) { /* nothing needs to be done. Setup is done with final add media */ sb->parser_connected = GF_TRUE; sb->mediasource->durationType = DURATION_INFINITY; gf_mse_source_buffer_setup_tracks(sb); } else { /* wrong first init segment */ /* TODO: fire an error event */ } gf_service_connect_ack(sb->mediasource->service, command->status.channel, command->status.e); } else { gf_service_disconnect_ack(sb->mediasource->service, command->status.channel, command->status.e); } } /* channel (track related) specific connection/disconnection messages from the media parser */ else { if (!command->status.is_disconnect) { gf_service_connect_ack(sb->mediasource->service, command->status.channel, command->status.e); } else { gf_service_disconnect_ack(sb->mediasource->service, command->status.channel, command->status.e); } } break; default: gf_service_command(sb->mediasource->service, command, GF_OK); break; } return GF_OK; } }
GF_Err mpdin_dash_io_on_dash_event(GF_DASHFileIO *dashio, GF_DASHEventType dash_evt, s32 group_idx, GF_Err error_code) { GF_Err e; u32 i; GF_MPD_In *mpdin = (GF_MPD_In *)dashio->udta; if (dash_evt==GF_DASH_EVENT_PERIOD_SETUP_ERROR) { if (!mpdin->connection_ack_sent) { mpdin->fn_connect_ack(mpdin->service, NULL, error_code); mpdin->connection_ack_sent= GF_TRUE; } return GF_OK; } if (dash_evt==GF_DASH_EVENT_SELECT_GROUPS) { const char *opt; //configure buffer in dynamic mode without low latency: we indicate how much the player will buffer if (gf_dash_is_dynamic_mpd(mpdin->dash) && !mpdin->use_low_latency) { u32 buffer_ms = 0; const char *opt = gf_modules_get_option((GF_BaseInterface *)mpdin->plug, "Network", "BufferLength"); if (opt) buffer_ms = atoi(opt); //use min buffer from MPD if (mpdin->buffer_mode>=MPDIN_BUFFER_MIN) { u32 mpd_buffer_ms = gf_dash_get_min_buffer_time(mpdin->dash); if (mpd_buffer_ms > buffer_ms) buffer_ms = mpd_buffer_ms; } if (buffer_ms) { gf_dash_set_user_buffer(mpdin->dash, buffer_ms); } } //let the player decide which group to play: we declare everything //however select the default languague opt = gf_modules_get_option((GF_BaseInterface *)mpdin->plug, "Systems", "LanguageName"); if (opt) gf_dash_groups_set_language(mpdin->dash, opt); return GF_OK; } /*for all selected groups, create input service and connect to init/first segment*/ if (dash_evt==GF_DASH_EVENT_CREATE_PLAYBACK) { /*select input services if possible*/ for (i=0; i<gf_dash_get_group_count(mpdin->dash); i++) { const char *mime, *init_segment; //let the player decide which group to play if (!gf_dash_is_group_selectable(mpdin->dash, i)) continue; mime = gf_dash_group_get_segment_mime(mpdin->dash, i); init_segment = gf_dash_group_get_segment_init_url(mpdin->dash, i, NULL, NULL); e = MPD_LoadMediaService(mpdin, i, mime, init_segment); if (e != GF_OK) { gf_dash_group_select(mpdin->dash, i, 0); } else { u32 w, h; /*connect our media service*/ GF_MPDGroup *group = gf_dash_get_group_udta(mpdin->dash, i); gf_dash_group_get_video_info(mpdin->dash, i, &w, &h); if (w && h && w>mpdin->width && h>mpdin->height) { mpdin->width = w; mpdin->height = h; } e = group->segment_ifce->ConnectService(group->segment_ifce, mpdin->service, init_segment); if (e) { GF_LOG(GF_LOG_WARNING, GF_LOG_DASH, ("[MPD_IN] Unable to connect input service to %s\n", init_segment)); gf_dash_group_select(mpdin->dash, i, 0); } else { group->service_connected = 1; } if (mpdin->closed) return GF_OK; } } if (!mpdin->connection_ack_sent) { mpdin->fn_connect_ack(mpdin->service, NULL, GF_OK); mpdin->connection_ack_sent=1; } //we had a seek outside of the period we were setting up, during period setup ! //request the seek again from the player if (mpdin->seek_request>=0) { GF_NetworkCommand com; memset(&com, 0, sizeof(GF_NetworkCommand)); com.command_type = GF_NET_SERVICE_SEEK; com.play.start_range = mpdin->seek_request; mpdin->seek_request = 0; gf_service_command(mpdin->service, &com, GF_OK); } return GF_OK; } /*for all running services, stop service*/ if (dash_evt==GF_DASH_EVENT_DESTROY_PLAYBACK) { mpdin->service->subservice_disconnect = 1; gf_service_disconnect_ack(mpdin->service, NULL, GF_OK); mpdin->service->subservice_disconnect = 2; for (i=0; i<gf_dash_get_group_count(mpdin->dash); i++) { GF_MPDGroup *group = gf_dash_get_group_udta(mpdin->dash, i); if (!group) continue; if (group->segment_ifce) { if (group->service_connected) { group->segment_ifce->CloseService(group->segment_ifce); group->service_connected = 0; } gf_modules_close_interface((GF_BaseInterface *) group->segment_ifce); } gf_free(group); gf_dash_set_group_udta(mpdin->dash, i, NULL); } mpdin->service->subservice_disconnect = 0; return GF_OK; } if (dash_evt==GF_DASH_EVENT_BUFFERING) { u32 tot, done; gf_dash_get_buffer_info(mpdin->dash, &tot, &done); fprintf(stderr, "DASH: Buffering %g%% out of %d ms\n", (100.0*done)/tot, tot); return GF_OK; } if (dash_evt==GF_DASH_EVENT_SEGMENT_AVAILABLE) { if (group_idx>=0) { GF_MPDGroup *group = gf_dash_get_group_udta(mpdin->dash, group_idx); if (group) MPD_NotifyData(group, 0); } return GF_OK; } if (dash_evt==GF_DASH_EVENT_QUALITY_SWITCH) { if (group_idx>=0) { GF_MPDGroup *group = gf_dash_get_group_udta(mpdin->dash, group_idx); if (group) { GF_NetworkCommand com; memset(&com, 0, sizeof(GF_NetworkCommand) ); com.command_type = GF_NET_SERVICE_EVENT; com.send_event.evt.type = GF_EVENT_QUALITY_SWITCHED; gf_service_command(mpdin->service, &com, GF_OK); } } return GF_OK; } if (dash_evt==GF_DASH_EVENT_TIMESHIFT_OVERFLOW) { GF_NetworkCommand com; com.command_type = GF_NET_SERVICE_EVENT; com.send_event.evt.type = (group_idx>=0) ? GF_EVENT_TIMESHIFT_OVERFLOW : GF_EVENT_TIMESHIFT_UNDERRUN; gf_service_command(mpdin->service, &com, GF_OK); } if (dash_evt==GF_DASH_EVENT_TIMESHIFT_UPDATE) { GF_NetworkCommand com; com.command_type = GF_NET_SERVICE_EVENT; com.send_event.evt.type = GF_EVENT_TIMESHIFT_UPDATE; gf_service_command(mpdin->service, &com, GF_OK); } return GF_OK; }