コード例 #1
0
/**
 * hls_progress_buffer_loop()
 *
 * Primary function for push-mode.  Pulls data from progressbuffer's cache queue.
 */
static void hls_progress_buffer_loop(void *data)
{
    HLSProgressBuffer* element = HLS_PROGRESS_BUFFER(data);
    GstFlowReturn      result = GST_FLOW_OK;

    g_mutex_lock(element->lock);

    while (element->srcresult == GST_FLOW_OK && !cache_has_enough_data(element->cache[element->cache_read_index]))
    {
        if (element->is_eos)
        {
            gst_pad_push_event(element->srcpad, gst_event_new_eos());
            element->srcresult = GST_FLOW_WRONG_STATE;
            break;
        }

        if (!element->is_eos)
        {
            g_cond_wait(element->add_cond, element->lock);
        }
    }

    result = element->srcresult;

    if (result == GST_FLOW_OK)
    {
        GstBuffer *buffer = NULL;
        guint64 read_position = cache_read_buffer(element->cache[element->cache_read_index], &buffer);

        if (read_position == element->cache_size[element->cache_read_index])
        {
            element->cache_write_ready[element->cache_read_index] = TRUE;
            element->cache_read_index = (element->cache_read_index + 1) % NUM_OF_CACHED_SEGMENTS;
            send_hls_not_full_message(element);
            g_cond_signal(element->del_cond);
        }

        g_mutex_unlock(element->lock);

        gst_buffer_set_caps(buffer, GST_PAD_CAPS(element->sinkpad));

        // Send the data to the hls progressbuffer source pad
        result = gst_pad_push(element->srcpad, buffer);

        g_mutex_lock(element->lock);
        if (GST_FLOW_OK == element->srcresult || GST_FLOW_OK != result)
            element->srcresult = result;
        else
            result = element->srcresult;
        g_mutex_unlock(element->lock);
    }
    else
    {
        g_mutex_unlock(element->lock);
    }

    if (result != GST_FLOW_OK && !element->is_flushing)
        gst_pad_pause_task(element->srcpad);
}
コード例 #2
0
ファイル: progressbuffer.c プロジェクト: mjparme/openjdk-jfx
/**
 * progress_buffer_loop()
 *
 * Primary function for push-mode.  Pulls data from progressbuffer's cache queue.
 */
static void progress_buffer_loop(void *data)
{
    ProgressBuffer *element = PROGRESS_BUFFER(data);
    GstFlowReturn  result;
    gboolean       skip = FALSE;

    g_mutex_lock(&element->lock);

next_item:
    while (element->srcresult == GST_FLOW_OK &&
           element->pending_src_event == NULL &&
           (!cache_has_enough_data(element->cache) || !element->instant_seek))
    {
        if (element->instant_seek)
            send_underrun_message(element);
        g_cond_wait(&element->add_cond, &element->lock);
    }

    result = element->srcresult;

    if (result == GST_FLOW_OK)
    {
        if (element->pending_src_event)
        {
            GstEvent *event = gst_event_ref(element->pending_src_event);
            progress_buffer_set_pending_event(element, NULL);

            switch(GST_EVENT_TYPE (event))
            {
                case GST_EVENT_EOS:
                    result = GST_FLOW_EOS;
                    break;
                case GST_EVENT_SEGMENT:
                    skip = FALSE;
                    break;
                default:
                    if (skip)
                    {
                        gst_event_unref (event); // INLINE - gst_event_unref()
                        goto next_item;
                    }
                    break;
            }
            element->srcresult = result;
            g_mutex_unlock(&element->lock);
            gst_pad_push_event (element->srcpad, event);
        }
        else // create a buffer
        {
            GstBuffer *buffer = NULL;
            guint64 read_position = cache_read_buffer(element->cache, &buffer);
            read_position += element->cache_read_offset;
            GST_BUFFER_OFFSET(buffer) = read_position - gst_buffer_get_size(buffer);

            if (read_position == element->sink_segment.stop)
                progress_buffer_set_pending_event(element, gst_event_new_eos());

            if (skip)
            {
                gst_buffer_unref(buffer); // INLINE - gst_buffer_unref()
                goto next_item;
            }
            else
            {
                g_mutex_unlock(&element->lock);

                // Send the data to the progressbuffer source pad
                result = gst_pad_push(element->srcpad, buffer);

                // Switch to skip mode. No we can only pass EOS and NEWSEGMENT events.
                if (result == GST_FLOW_EOS)
                {
                    g_mutex_lock(&element->lock);
                    skip = TRUE;
                    goto next_item;
                }

                g_mutex_lock(&element->lock);
                element->srcresult = result;
                g_mutex_unlock(&element->lock);
            }
        }
    }
    else
    {
        if (skip) // Run out of items in skip mode. Expecting only EOS or NEWSEGMENT in _chain()
        {
            element->unexpected = TRUE;
            result = GST_FLOW_OK;
        }
        g_mutex_unlock(&element->lock);
    }

    if (result != GST_FLOW_OK)
        gst_pad_pause_task(element->srcpad);
}