예제 #1
0
파일: rtp.c 프로젝트: phully/feng_build
/**
 * @brief Resume (or start) an RTP session
 *
 * @param session_gen The session to resume or start
 * @param range_gen Pointer tp @ref RTSP_Range to start with
 *
 * @todo This function should probably take care of starting eventual
 *       libev events when the scheduler is replaced.
 *
 * This function is used by the PLAY method of RTSP to start or resume
 * a session; since a newly-created session starts as paused, this is
 * the only method available.
 *
 * The use of a pointer to double rather than a double itself is to
 * make it possible to pass this function straight to foreach
 * functions from glib.
 *
 * @internal This function should only be called from g_slist_foreach.
 */
static void rtp_session_resume(gpointer session_gen, gpointer range_gen) {
    RTP_session *session = (RTP_session*)session_gen;
    RTSP_Range *range = (RTSP_Range*)range_gen;

    fnc_log(FNC_LOG_VERBOSE, "Resuming session %p\n", session);

    session->range = range;
    session->start_seq = 1 + session->seq_no;
    session->start_rtptime = g_random_int();
    session->send_time = 0.0;
    session->last_packet_send_time = time(NULL);

    /* Create the new thread pool for the read requests */
    session->fill_pool = g_thread_pool_new(rtp_session_fill_cb, session,
                                           1, true, NULL);

    /* Prefetch frames */
    rtp_session_fill(session);

    ev_periodic_set(&session->transport.rtp_writer,
                    range->playback_time - 0.05,
                    0, NULL);
    ev_periodic_start(session->srv->loop, &session->transport.rtp_writer);
    ev_io_start(session->srv->loop, &session->transport.rtcp_reader);
}
예제 #2
0
void start_time_redraw_tick(struct ev_loop* main_loop) {
    if (time_redraw_tick) {
        ev_periodic_set(time_redraw_tick, 0., 1.0, 0);
        ev_periodic_again(main_loop, time_redraw_tick);
    } else {
        if (!(time_redraw_tick = calloc(sizeof(struct ev_periodic), 1))) {
           return;
        }
        ev_periodic_init(time_redraw_tick, time_redraw_cb, 0., 1., 0);
        ev_periodic_start(main_loop, time_redraw_tick);
    }
}
예제 #3
0
void flux_periodic_watcher_reset (flux_watcher_t *w,
                                  double next, double interval,
                                  flux_reschedule_f reschedule_cb)
{
    struct f_periodic *fp = w->impl;
    struct ev_loop *loop = w->r->loop;
    assert (w->signature == PERIODIC_SIG);
    fp->reschedule_cb = reschedule_cb;
    ev_periodic_set (&fp->evp, next, interval,
                     reschedule_cb ? periodic_reschedule_cb : NULL);
    ev_periodic_again (loop, &fp->evp);
}
예제 #4
0
파일: Scheduler.c 프로젝트: CZ-NIC/dionaea
/* SchedulerType.tp_new */
static PyObject *
Scheduler_tp_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
{
    Scheduler *self = (Scheduler *)PeriodicBaseType.tp_new(type, args, kwargs);
    if (!self) {
        return NULL;
    }
    self->prepare.data = (void *)self;
    ev_prepare_init(&self->prepare, stop_scheduler_Scheduler);
    ev_periodic_set(&((PeriodicBase *)self)->periodic, 0.0, 0.0,
                    scheduler_Scheduler);
    return (PyObject *)self;
}
예제 #5
0
void start_time_redraw_tick(struct ev_loop* main_loop) {
    if (time_redraw_tick) {
        ev_periodic_set(time_redraw_tick, 1.0, 60., 0);
        ev_periodic_again(main_loop, time_redraw_tick);
    } else {
        /* When there is no memory, we just don’t have a timeout. We cannot
        * exit() here, since that would effectively unlock the screen. */
        if (!(time_redraw_tick = calloc(sizeof(struct ev_periodic), 1)))
            return;
        ev_periodic_init(time_redraw_tick,time_redraw_cb, 1.0, 60., 0);
        ev_periodic_start(main_loop, time_redraw_tick);
    }
}
예제 #6
0
파일: Scheduler.c 프로젝트: pdecat/pyev
/* SchedulerType.tp_new */
static PyObject *
Scheduler_tp_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
{
    Scheduler *self = (Scheduler *)PeriodicBaseType.tp_new(type, args, kwargs);
    if (!self) {
        return NULL;
    }
    self->prepare = PyMem_Malloc(sizeof(ev_prepare));
    if (!self->prepare) {
        PyErr_NoMemory();
        Py_DECREF(self);
        return NULL;
    }
    ev_prepare_init(self->prepare, Scheduler_Stop);
    self->prepare->data = self;
    ev_periodic_set((ev_periodic *)((Watcher *)self)->watcher,
                    0.0, 0.0, Scheduler_Schedule);
    return (PyObject *)self;
}
예제 #7
0
파일: rtp.c 프로젝트: phully/feng_build
/**
 * Send pending RTP packets to a session.
 *
 * @param loop eventloop
 * @param w contains the session the RTP session for which to send the packets
 * @todo implement a saner ratecontrol
 */
static void rtp_write_cb(struct ev_loop *loop, ev_periodic *w,
                         ATTR_UNUSED int revents)
{
    RTP_session *session = w->data;
    Resource *resource = session->track->parent;
    MParserBuffer *buffer = NULL;
    ev_tstamp next_time = w->offset;

#ifdef HAVE_METADATA
    if (session->metadata)
        cpd_send(session, now);
#endif
    /* If there is no buffer, it means that either the producer
     * has been stopped (as we reached the end of stream) or that
     * there is no data for the consumer to read. If that's the
     * case we just give control back to the main loop for now.
     */
    if ( bq_consumer_stopped(session->consumer) ) {
        /* If the producer has been stopped, we send the
         * finishing packets and go away.
         */
        fnc_log(FNC_LOG_INFO, "[rtp] Stream Finished");
        rtcp_send_sr(session, BYE);
        return;
    }

    /* Check whether we have enough extra frames to send. If we have
     * no extra frames we have a problem, since we're going to send
     * one packet at least.
     */
    if (resource->eor)
        fnc_log(FNC_LOG_INFO,
                "[%s] end of resource %d packets to be fetched",
                session->track->properties.encoding_name,
                bq_consumer_unseen(session->consumer));

    /* Get the current buffer, if there is enough data */
    if ( !(buffer = bq_consumer_get(session->consumer)) ) {
        /* We wait a bit of time to get the data but before it is
         * expired.
         */
        if (resource->eor) {
            fnc_log(FNC_LOG_INFO, "[rtp] Stream Finished");
            rtcp_send_sr(session, BYE);
            return;
        }
        next_time += 0.01; // assumed to be enough
    } else {
        MParserBuffer *next;
        double delivery  = buffer->delivery;
        double timestamp = buffer->timestamp;
        double duration  = buffer->duration;
        gboolean marker  = buffer->marker;

        rtp_packet_send(session, buffer);

        if (session->pkt_count % 29 == 1)
            rtcp_send_sr(session, SDES);

        if (bq_consumer_move(session->consumer)) {
            next = bq_consumer_get(session->consumer);
            if(delivery != next->delivery) {
                if (session->track->properties.media_source == MS_live)
                    next_time += next->delivery - delivery;
                else
                    next_time = session->range->playback_time -
                                session->range->begin_time +
                                next->delivery;
            }
        } else {
            if (marker)
                next_time += duration;
        }

        fnc_log(FNC_LOG_VERBOSE,
                "[%s] Now: %5.4f, cur %5.4f[%5.4f][%5.4f], next %5.4f %s\n",
                session->track->properties.encoding_name,
                ev_now(loop) - session->range->playback_time,
                delivery,
                timestamp,
                duration,
                next_time - session->range->playback_time,
                marker? "M" : " ");
    }
    ev_periodic_set(w, next_time, 0, NULL);
    ev_periodic_again(loop, w);

    rtp_session_fill(session);
}