DirectorConference::~DirectorConference()
{
	// 释放所有 sources, sinks, ...
	do {
		ost::MutexLock al(cs_graphics_);
		GRAPHICS::iterator it;
		for (it = graphics_.begin(); it != graphics_.end(); ++it) {
			delete *it;
		}
		graphics_.clear();
	} while (0);

	do {
		ost::MutexLock al(cs_sinks_);
		SINKS::iterator it;
		for (it = sinks_.begin(); it != sinks_.end(); ++it) {
			del_sink(*it);
			delete *it;
		}
		sinks_.clear();
	} while (0);

	do {
		ost::MutexLock al(cs_streams_);
		STREAMS::iterator it;
		for (it = streams_.begin(); it != streams_.end(); ++it) {
			del_stream(*it);
			delete *it;
		}
		streams_.clear();
	} while (0);

	do {
		ost::MutexLock al(cs_sources_);
		SOURCES::iterator it;
		for (it = sources_.begin(); it != sources_.end(); ++it) {
			del_source(*it);
			delete *it;
		}
		sources_.clear();
	} while (0);

	pause_audio();
	pause_video();

	ms_ticker_destroy(audio_ticker_);
	ms_ticker_destroy(video_ticker_);

	ms_filter_destroy(audio_resample_);
	ms_filter_destroy(audio_encoder_);
	ms_filter_destroy(audio_mixer_);
	ms_filter_destroy(video_mixer_);
	ms_filter_destroy(audio_publisher_);
	ms_filter_destroy(video_publisher_);
	ms_filter_destroy(video_tee_);

	if (filter_tee_) ms_filter_destroy(filter_tee_);
	if (filter_sink_) ms_filter_destroy(filter_sink_);
}
Beispiel #2
0
static void *
play_stream(void *p)
{
    struct sp_stream *str = p;
    stream_player_t *sp = str->sp;
    int six = str - sp->streams;
    int shs = sp->smap[six];
    tcvp_packet_t *pk;

    tc2_print("STREAM", TC2_PRINT_DEBUG,
              "[%i] starting player thread\n", shs);

    while(waitplay(sp, six)){
        pthread_mutex_lock(&sp->lock);
        pk = tclist_shift(str->packets);

        if(pk && pk->type == TCVP_PKT_TYPE_DATA &&
           pk->data.flags & TCVP_PKT_FLAG_PTS)
            str->tailtime = pk->data.pts;

        if((tclist_items(str->packets) < min_packets ||
            str->headtime - str->tailtime < buffertime) &&
           sp->ms->used_streams[six]){
            if(!(sp->ms->streams[six].common.flags &
                 TCVP_STREAM_FLAG_NOBUFFER))
                sp->nbuf |= 1ULL << six;
            pthread_cond_broadcast(&sp->cond);
        }
        pthread_mutex_unlock(&sp->lock);
        if(!pk){
            tc2_print("STREAM", TC2_PRINT_DEBUG,
                      "null packet on stream %i\n", shs);
            break;
        }

        if(str->pipe->input(str->pipe, pk)){
            tc2_print("STREAM", TC2_PRINT_ERROR,
                      "stream %i pipeline error\n", shs);
            break;
        }
    }

    tc2_print("STREAM", TC2_PRINT_DEBUG,
              "stream %i %s\n", shs, sp->state == STOP? "stopped": "end");

    pk = tcallocz(sizeof(*pk));
    pk->data.stream = shs;
    pk->data.data = NULL;
    if(str->end->start)
        str->end->start(str->end);
    str->pipe->flush(str->pipe, sp->state == STOP);
    str->pipe->input(str->pipe, pk);

    del_stream(sp, six);

    return NULL;
}
Beispiel #3
0
static int
do_data_packet(stream_player_t *sp, tcvp_data_packet_t *pk)
{
    tcvp_player_t *sh = sp->shared;
    struct sp_stream *str;
    int ps;

    ps = pk->stream;

    if(pk->stream >= sp->nstreams || sp->smap[ps] < 0){
        if(add_stream(sp, ps)){
            del_stream(sp, ps);
            return -1;
        }
    }

    str = sp->streams + ps;
    pk->stream = sp->smap[ps];

    if(pk->flags & TCVP_PKT_FLAG_PTS){
        if(sh->starttime == -1LL){
            pthread_mutex_lock(&sh->lock);
            if(sh->starttime == -1LL){
                sh->starttime = pk->pts;
                if(sh->playtime != -1LL)
                    sh->endtime = sh->starttime + sh->playtime;
                sh->timer->reset(sh->timer, sh->starttime);
                tc2_print("STREAM", TC2_PRINT_DEBUG, "start %llu, end %llu\n",
                          sh->starttime / 27, sh->endtime / 27);
            }
            pthread_mutex_unlock(&sh->lock);
        }

        if(pk->pts > sh->endtime){
            tc2_print("STREAM", TC2_PRINT_DEBUG,
                      "[%i] end time reached\n", pk->stream);
            tcfree(pk);
            pk = NULL;
            pthread_mutex_lock(&sp->lock);
            sp->ms->used_streams[ps] = 0;
            sp->nbuf &= ~(1ULL << ps);
            pthread_cond_broadcast(&sp->cond);
            pthread_mutex_unlock(&sp->lock);
        } else if(str->starttime == -1LL){
            tc2_print("STREAM", TC2_PRINT_DEBUG,
                      "[%i] start %llu\n",
                      pk->stream, pk->pts / 27);
            sp->ms->streams[ps].common.start_time = pk->pts;
            str->starttime = pk->pts;
        }
/*     } else if(str->starttime == -1){ */
/*      tcfree(pk); */
/*      return 0; */
    }

    switch(str->probe){
    case PROBE_AGAIN:
    case PROBE_DISCARD:
        tc2_print("STREAM", TC2_PRINT_DEBUG, "[%i] probing\n",
                  pk->stream);
        sp->ms->streams[ps].common.index = pk->stream;
        str->probe = str->pipe->probe(str->pipe, pk,
                                      sp->ms->streams + ps);
        if(str->probe == PROBE_FAIL ||
           str->nprobe++ > tcvp_player_conf_max_probe){
            tc2_print("STREAM", TC2_PRINT_DEBUG,
                      "[%i] failed probe\n", pk->stream);
            sp->fail++;
            del_stream(sp, ps);
            tcfree(pk);
            break;
        } else if(str->probe == PROBE_OK){
            stream_time(sp->ms, ps, str->pipe);
            tcvp_event_send(sh->sq, TCVP_LOAD, sp->ms);
            pthread_create(&str->th, NULL, play_stream, str);
            pthread_mutex_lock(&sp->lock);
            if(str->end->start && str->run)
                str->end->start(str->end);
            pthread_mutex_unlock(&sp->lock);
        } else if(str->probe == PROBE_DISCARD){
            flush_stream(sp, ps, 1);
            tcfree(pk);
            break;
        }
    case PROBE_OK:
        pthread_mutex_lock(&sp->lock);
        if(str->packets){
            int np;

            tclist_push(str->packets, pk);
            if(pk && pk->flags & TCVP_PKT_FLAG_PTS)
                str->headtime = pk->pts;

            np = tclist_items(str->packets);
            if(str->probe == PROBE_OK && (np > max_packets ||
               ((str->headtime - str->tailtime > buffertime) &&
                np > min_packets)))
                sp->nbuf &= ~(1ULL << ps);
        }
        pthread_cond_broadcast(&sp->cond);
        pthread_mutex_unlock(&sp->lock);
        break;
    }

    return 0;
}