/* * 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; }
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; }
/* * 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; }
/* * 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; }
/* * 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; }