コード例 #1
0
ファイル: format.c プロジェクト: GitLaboratory/icecast-kh
int format_file_read (client_t *client, format_plugin_t *plugin, icefile_handle f)
{
    refbuf_t *refbuf = client->refbuf;
    ssize_t bytes = -1;
    int unprocessed = 0;

    do
    {
        if (refbuf == NULL)
        {
            if (file_in_use (f) == 0)
                return -2;
            refbuf = client->refbuf = refbuf_new (8192);
            client->flags |= CLIENT_HAS_INTRO_CONTENT;
            client->pos = refbuf->len;
            client->queue_pos = 0;
        }
        if (client->pos < refbuf->len)
            break;

        if (refbuf->next)
        {
            //DEBUG1 ("next intro block is %d", refbuf->next->len);
            client->refbuf = refbuf->next;
            refbuf->next = NULL;
            refbuf_release (refbuf);
            client->pos = 0;
            return 0;
        }

        if (file_in_use (f) == 0) return -2;

        bytes = pread (f, refbuf->data, 8192, client->intro_offset);
        if (bytes <= 0)
            return bytes < 0 ? -2 : -1;

        refbuf->len = bytes;
        client->pos = 0;
        if (plugin && plugin->align_buffer)
        {
            /* here the buffer may require truncating to keep the buffers aligned on
             * certain boundaries */
            unprocessed = plugin->align_buffer (client, plugin);
            if (unprocessed == bytes)
                return -1;
            if (unprocessed < 0 || unprocessed > bytes)
            {
                unprocessed = 0;
                client->connection.error = 1;
            }
        }
        client->intro_offset += (bytes - unprocessed);
    } while (1);
    return refbuf->len - client->pos;
}
コード例 #2
0
ファイル: fserve.c プロジェクト: roderickm/icecast-kh
static int prefile_send (client_t *client)
{
    int loop = 8, bytes, written = 0;
    worker_t *worker = client->worker;

    while (loop)
    {
        refbuf_t *refbuf = client->refbuf;
        fh_node *fh = client->shared_data;
        loop--;
        if (fserve_running == 0 || client->connection.error)
            return -1;
        if (refbuf == NULL || client->pos == refbuf->len)
        {
            if (fh->finfo.fallback)
                return fserve_move_listener (client);

            if (refbuf == NULL || refbuf->next == NULL)
            {
                if (file_in_use (fh->f)) // is there a file to read from
                {
                    if (fh->finfo.limit)
                        client->ops = &throttled_file_content_ops;
                    else
                        client->ops = &file_content_ops;
                    refbuf_release (client->refbuf);
                    client->refbuf = NULL;
                    client->pos = 0;
                    return client->ops->process (client);
                }
                if (client->respcode)
                    return -1;
                return client_send_404 (client, NULL);
            }
            else
            {
                refbuf_t *to_go = client->refbuf;
                refbuf = client->refbuf = to_go->next;
                to_go->next = NULL;
                refbuf_release (to_go);
            }
            client->pos = 0;
        }
        if (refbuf->flags & WRITE_BLOCK_GENERIC)
            bytes = format_generic_write_to_client (client);
        else 
            bytes = client->check_buffer (client);
        if (bytes < 0)
        {
            client->schedule_ms = worker->time_ms + (written ? 150 : 300);
            return 0;
        }
        written += bytes;
        global_add_bitrates (global.out_bitrate, bytes, worker->time_ms);
        if (written > 30000)
            break;
    }
    return 0;
}
コード例 #3
0
ファイル: format.c プロジェクト: niko/icecast-kh
int format_file_read (client_t *client, format_plugin_t *plugin, icefile_handle f)
{
    refbuf_t *refbuf = client->refbuf;
    ssize_t bytes = -1;
    int unprocessed = 0;

    do
    {
        if (refbuf == NULL)
        {
            if (file_in_use (f) == 0)
                return -2;
            refbuf = client->refbuf = refbuf_new (8192);
            client->flags |= CLIENT_HAS_INTRO_CONTENT;
            client->pos = refbuf->len;
            client->queue_pos = 0;
            refbuf->flags |= BUFFER_LOCAL_USE;
        }
        if (client->pos < refbuf->len)
            break;

        if (refbuf->next)
        {
            //DEBUG1 ("next intro block is %d", refbuf->next->len);
            client->refbuf = refbuf->next;
            refbuf->next = NULL;
            refbuf_release (refbuf);
            client->pos = 0;
            return 0;
        }
        if ((refbuf->flags & BUFFER_LOCAL_USE) == 0)
        {
            client_set_queue (client, NULL);
            refbuf = NULL;
            continue;
        }

        if (file_in_use (f) == 0) return -2;

        bytes = pread (f, refbuf->data, 8192, client->intro_offset);
        if (bytes <= 0)
            return bytes < 0 ? -2 : -1;

        if (client->connection.sent_bytes > 0 && client->intro_offset == 0 &&
                bytes >= 10 && memcmp (refbuf->data, "ID3", 3) == 0)
        {
            // special case of filtering ID3 from fallback files
            unsigned char *p = (unsigned char*)refbuf->data;
            
            if (p[3] < 0xFF && p[4] < 0xFF && (p[5] & 0xF) == 0)
            {
                int ver = p[3], rev = p[4];
                size_t size = (p[6] & 0x7f);
                size = (size << 7) + (p[7] & 0x7f);
                size = (size << 7) + (p[8] & 0x7f);
                size = (size << 7) + (p[9] & 0x7f);

                client->intro_offset = size + 10;
                DEBUG3 ("Detected ID3v2 (%d.%d) in file, tag size %" PRIu64, ver, rev, (uint64_t)size);
                continue;
            }
        }
        refbuf->len = bytes;
        client->pos = 0;
        if (plugin && plugin->align_buffer)
        {
            /* here the buffer may require truncating to keep the buffers aligned on
             * certain boundaries */
            unprocessed = plugin->align_buffer (client, plugin);
            if (unprocessed == bytes)
                return -1;
            if (unprocessed < 0 || unprocessed > bytes)
            {
                unprocessed = 0;
                client->connection.error = 1;
            }
        }
        client->intro_offset += (bytes - unprocessed);
    } while (1);
    return refbuf->len - client->pos;
}