/* * cmyth_livetv_wait() * * After starting live TV or after a channel change wait here until some * recording data is available. */ static int cmyth_livetv_wait(cmyth_recorder_t rec) { int i = 0, rc = -1; cmyth_conn_t conn; static int failures = 0; usleep(250000*failures); conn = cmyth_conn_reconnect(rec->rec_conn); while (i++ < 10) { int len; cmyth_proginfo_t prog; cmyth_file_t file; if (!cmyth_recorder_is_recording(rec)) { usleep(1000); continue; } prog = cmyth_recorder_get_cur_proginfo(rec); if (prog == NULL) { usleep(1000); continue; } file = cmyth_conn_connect_file(prog, conn, 4096, 4096); ref_release(prog); if (file == NULL) { if (failures < 4) { failures++; } usleep(1000); continue; } len = cmyth_file_request_block(file, 512); ref_release(file); if (len == 512) { rc = 0; break; } if (failures < 4) { failures++; } usleep(1000); } ref_release(conn); return rc; }
/* JLB: Manage program breaks * cmyth_livetv_done_recording(cmyth_recorder_t rec, char * msg) * * Scope: PUBLIC * * Description * * Indicates that an active recording has completed on the specified * recorder. used to manage program breaks while watching live tv. * When receive event for recorder, we switch on watch signal and * force an update of livetv chain to get current program info. * Watch signal is used when down, to mark the break period and * queuing the frontend for reading file buffer. * * Return Value: * * Success: 0 * * Failure: -1 */ int cmyth_livetv_done_recording(cmyth_recorder_t rec, char * msg) { int ret, rec_id; ret = 0; if (!rec) { cmyth_dbg(CMYTH_DBG_ERROR, "%s: rec is NULL\n", __FUNCTION__); return -1; } /* * Parse msg. Should be %d ... */ if (strlen(msg) >= 1 && sscanf(msg,"%d", &rec_id) == 1) { if (rec_id == rec->rec_id && rec->rec_livetv_chain->livetv_watch != 1 && cmyth_recorder_is_recording(rec) == 1) { /* * Last recording is now completed. Then switch ON watch status * and force live tv chain update for the new current program. */ pthread_mutex_lock(&mutex); rec->rec_livetv_chain->livetv_watch = 1; pthread_mutex_unlock(&mutex); cmyth_dbg(CMYTH_DBG_DEBUG, "%s: previous recording done. Start chain update\n", __FUNCTION__); if (rec->rec_livetv_chain->chainid) { cmyth_livetv_chain_update(rec, rec->rec_livetv_chain->chainid); } else { cmyth_dbg(CMYTH_DBG_ERROR, "%s: chainid is null for recorder %d\n", __FUNCTION__, rec_id); ret = -1; } } else { cmyth_dbg(CMYTH_DBG_DEBUG, "%s: nothing to trigger for recorder: %d", __FUNCTION__, rec_id); } } else { cmyth_dbg(CMYTH_DBG_ERROR, "%s: unknown message: %s", __FUNCTION__, msg); ret = -1; } return ret; }
cmyth_recorder_t cmyth_spawn_live_tv(cmyth_recorder_t rec, unsigned buflen, int tcp_rcvbuf, void (*prog_update_callback)(cmyth_proginfo_t), char ** err, char* channame) { cmyth_recorder_t rtrn = NULL; int i; //printf("** SSDEBUG: version is %ld\n", rec->rec_conn->conn_version); if(rec->rec_conn->conn_version >= 26) { if (cmyth_recorder_spawn_chain_livetv(rec, channame) != 0) { *err = "Spawn livetv failed."; goto err; } if ((rtrn = cmyth_livetv_chain_setup(rec, tcp_rcvbuf, prog_update_callback)) == NULL) { *err = "Failed to setup livetv."; goto err; } for(i=0; i<20; i++) { if(cmyth_recorder_is_recording(rtrn) != 1) sleep(1); else break; } } else { if ((rtrn = cmyth_ringbuf_setup(rec)) == NULL) { *err = "Failed to setup ringbuffer."; goto err; } if (cmyth_conn_connect_ring(rtrn, buflen, tcp_rcvbuf) != 0) { *err = "Cannot connect to mythtv ringbuffer."; goto err; } if (cmyth_recorder_spawn_livetv(rtrn) != 0) { *err = "Spawn livetv failed."; goto err; } } if(rtrn->rec_conn->conn_version < 34 && channame) { if (cmyth_recorder_pause(rtrn) != 0) { *err = "Failed to pause recorder to change channel"; goto err; } if (cmyth_recorder_set_channel(rtrn, channame) != 0) { *err = "Failed to change channel on recorder"; goto err; } } err: return rtrn; }
static int get_recorders(int level) { int i, j; for (i=0; i<=32; i++) { cmyth_recorder_t rec; int state; rec = cmyth_conn_get_recorder(control, i); if (rec == NULL) { continue; } state = cmyth_recorder_is_recording(rec); if (state == 0) { printf("Recorder %d is idle\n", i); } else if (state == 1) { cmyth_proginfo_t prog; cmyth_timestamp_t end; char str[32]; char *title; prog = cmyth_recorder_get_cur_proginfo(rec); end = cmyth_proginfo_rec_end(prog); cmyth_timestamp_to_string(str, end); printf("Recorder %d is recording until %s\n", i, str); if (prog && (level > 0)) { title = cmyth_proginfo_title(prog); if (title) { printf("\tTitle: %s\n", title); } ref_release(title); } ref_release(prog); ref_release(end); } else { printf("Recorder %d is in an unknown state\n", i); } if (level > 1) { cmyth_chanlist_t cl; cmyth_channel_t chan; char *name; cl = cmyth_recorder_get_chanlist(rec); for (j=0; j<cmyth_chanlist_get_count(cl); j++) { chan = cmyth_chanlist_get_item(cl, j); name = cmyth_channel_string(chan); printf("\tChannel: %s\n", name); ref_release(name); ref_release(chan); } ref_release(cl); } ref_release(rec); } return 0; }