Пример #1
0
/*
 * cmyth_livetv_chain_seek(cmyth_recorder_t file, long long offset, int whence)
 *
 * Scope: PUBLIC
 *
 * Description
 *
 * Seek to a new position in the file based on the value of whence:
 *	SEEK_SET
 *		The offset is set to offset bytes.
 *	SEEK_CUR
 *		The offset is set to the current position plus offset bytes.
 *	SEEK_END
 *		The offset is set to the size of the file minus offset bytes.
 *
 * Return Value:
 *
 * Sucess: 0
 *
 * Failure: an int containing -errno
 */
static long long
cmyth_livetv_chain_seek(cmyth_recorder_t rec, long long offset, int whence)
{
    long long ret;
    cmyth_file_t file;

    if (rec == NULL)
        return -EINVAL;

    if (!rec->rec_connected) {
        return -1;
    }

    pthread_mutex_lock(&rec->rec_conn->conn_mutex);

    if ((file=cmyth_livetv_current_file(rec)) == NULL) {
        ret = -1;
        goto out;
    }

    /*
     * XXX: This needs to seek across the entire chain...
     */

    ret = cmyth_file_seek(file, offset, whence);

    ref_release(file);

out:
    pthread_mutex_unlock(&rec->rec_conn->conn_mutex);

    return ret;
}
Пример #2
0
static int
cmyth_livetv_chain_select(cmyth_recorder_t rec, struct timeval *timeout)
{
    cmyth_file_t file;
    int rc;

    cmyth_dbg(CMYTH_DBG_DEBUG, "%s [%s:%d]: (trace) {\n",
              __FUNCTION__, __FILE__, __LINE__);

    if (!rec || !rec->rec_connected) {
        return -EINVAL;
    }

    if ((file=cmyth_livetv_current_file(rec)) == NULL) {
        return -1;
    }

    rc = cmyth_file_select(file, timeout);

    ref_release(file);

    cmyth_dbg(CMYTH_DBG_DEBUG, "%s [%s:%d]: (trace) }\n",
              __FUNCTION__, __FILE__, __LINE__);

    return rc;
}
Пример #3
0
/*
 * cmyth_livetv_chain_get_block(cmyth_recorder_t rec, char *buf,
 *				unsigned long len)
 * Scope: PUBLIC
 * Description
 * Read incoming file data off the network into a buffer of length len.
 *
 * Return Value:
 * Sucess: number of bytes read into buf
 * Failure: -1
 */
int
cmyth_livetv_chain_get_block(cmyth_recorder_t rec, char *buf,
                             unsigned long len)
{
    cmyth_file_t file;
    int rc;

    cmyth_dbg(CMYTH_DBG_DEBUG, "%s [%s:%d]: (trace) {\n",
              __FUNCTION__, __FILE__, __LINE__);

    if (!rec || !rec->rec_connected) {
        return -EINVAL;
    }

    if ((file=cmyth_livetv_current_file(rec)) == NULL) {
        return -1;
    }

    rc = cmyth_file_get_block(file, buf, len);

    ref_release(file);

    cmyth_dbg(CMYTH_DBG_DEBUG, "%s [%s:%d]: (trace) }\n",
              __FUNCTION__, __FILE__, __LINE__);

    return rc;
}
Пример #4
0
/*
 * cmyth_livetv_chain_request_block(cmyth_recorder_t file, unsigned long len)
 *
 * Scope: PUBLIC
 *
 * Description
 *
 * Request a file data block of a certain size, and return when the
 * block has been transfered.
 *
 * Return Value:
 *
 * Sucess: number of bytes transfered
 *
 * Failure: an int containing -errno
 */
static int
cmyth_livetv_chain_request_block(cmyth_recorder_t rec, unsigned long len)
{
    int rc;
    cmyth_file_t file;

    cmyth_dbg(CMYTH_DBG_DEBUG, "%s [%s:%d]: (trace) {\n", __FUNCTION__,
              __FILE__, __LINE__);

    if (!rec) {
        cmyth_dbg(CMYTH_DBG_ERROR, "%s: no connection\n",
                  __FUNCTION__);
        return -EINVAL;
    }

    if (!rec->rec_connected) {
        return -1;
    }

    pthread_mutex_lock(&rec->rec_conn->conn_mutex);

retry:
    if ((file=cmyth_livetv_current_file(rec)) == NULL) {
        rc = -1;
        goto out;
    }

    rc = cmyth_file_request_block(file, len);

    if (rc == 0) {
        cmyth_dbg(CMYTH_DBG_DEBUG,
                  "%s(): no data, move forward in chain and retry\n",
                  __FUNCTION__);
        if (cmyth_chain_switch(rec->rec_chain, 1) == 0) {
            ref_release(file);
            goto retry;
        }
    }

    ref_release(file);

out:
    pthread_mutex_unlock(&rec->rec_conn->conn_mutex);

    cmyth_dbg(CMYTH_DBG_DEBUG, "%s [%s:%d]: (trace) }\n",
              __FUNCTION__, __FILE__, __LINE__);

    return rc;
}
Пример #5
0
/*
 * cmyth_recorder_set_channel(cmyth_recorder_t rec,
 *                            char *channame)
 * 
 * Scope: PUBLIC
 *
 * Description
 *
 * Request that the recorder 'rec' change channels to the channel
 * named 'channame'.
 *
 * Note that the recorder must not be actively recording when this
 * request is made or bad things may happen to the server (i.e. it may
 * segfault).
 *
 * Return Value:
 *
 * Success: 0
 *
 * Failure: -(ERRNO)
 */
int
cmyth_recorder_set_channel(cmyth_recorder_t rec, char *channame)
{
	int err;
	int ret = -1;
	char msg[256];
	cmyth_file_t file;

	if (!rec) {
		cmyth_dbg(CMYTH_DBG_ERROR, "%s: no recorder connection\n",
			  __FUNCTION__);
		return -ENOSYS;
	}

	if (!rec->rec_connected) {
		return -EINVAL;
	}

	pthread_mutex_lock(&rec->rec_conn->conn_mutex);

	cmyth_chain_lock(rec->rec_chain);

	snprintf(msg, sizeof(msg),
		 "QUERY_RECORDER %d[]:[]SET_CHANNEL[]:[]%s",
		 rec->rec_id, channame);

	if ((err=cmyth_send_message(rec->rec_conn, msg)) < 0) {
		cmyth_dbg(CMYTH_DBG_ERROR,
			  "%s: cmyth_send_message() failed (%d)\n",
			  __FUNCTION__, err);
		goto fail;
	}

	if ((err=cmyth_rcv_okay(rec->rec_conn)) < 0) {
		cmyth_dbg(CMYTH_DBG_ERROR,
			  "%s: cmyth_rcv_okay() failed (%d)\n",
			  __FUNCTION__, err);
		goto fail;
	}

	pthread_mutex_unlock(&rec->rec_conn->conn_mutex);

	cmyth_chain_add_wait(rec->rec_chain);

	cmyth_chain_unlock(rec->rec_chain);

	if ((file=cmyth_livetv_current_file(rec)) == NULL) {
		goto fail_nolock;
	}

	cmyth_file_seek(file, 0, SEEK_SET);

	ref_release(file);

	ret = 0;

fail:
	pthread_mutex_unlock(&rec->rec_conn->conn_mutex);

fail_nolock:
	return ret;
}