diff options
Diffstat (limited to 'src/input/input_pvr.c')
-rw-r--r-- | src/input/input_pvr.c | 185 |
1 files changed, 91 insertions, 94 deletions
diff --git a/src/input/input_pvr.c b/src/input/input_pvr.c index bcf93af2b..740d51665 100644 --- a/src/input/input_pvr.c +++ b/src/input/input_pvr.c @@ -17,7 +17,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * pvr input plugin for WinTV-PVR 250/350 pci cards using driver from: * http://ivtv.sf.net @@ -37,8 +37,6 @@ * * usage: * xine pvr:/<prefix_to_tmp_files>\!<prefix_to_saved_files>\!<max_page_age> - * - * $Id: input_pvr.c,v 1.65 2007/01/19 01:05:25 dgp85 Exp $ */ /************************************************************************** @@ -100,7 +98,7 @@ #include <time.h> #include <pthread.h> #include <sys/ioctl.h> -#include "videodev2.h" +#include <linux/videodev2.h> #define XINE_ENABLE_EXPERIMENTAL_FEATURES @@ -110,10 +108,10 @@ #define LOG */ -#include "xine_internal.h" -#include "xineutils.h" -#include "compat.h" -#include "input_plugin.h" +#include <xine/xine_internal.h> +#include <xine/xineutils.h> +#include <xine/compat.h> +#include <xine/input_plugin.h> #define PVR_DEVICE "/dev/video0" @@ -423,8 +421,9 @@ static uint32_t pvr_plugin_get_capabilities (input_plugin_t *this_gen) { } -static off_t pvr_plugin_read (input_plugin_t *this_gen, char *buf, off_t len) { +static off_t pvr_plugin_read (input_plugin_t *this_gen, void *buf_gen, off_t len) { /*pvr_input_plugin_t *this = (pvr_input_plugin_t *) this_gen;*/ + char *buf = (char *)buf_gen; /* FIXME: Tricking the demux_mpeg_block plugin */ buf[0] = 0; @@ -512,10 +511,7 @@ static char *make_temp_name(pvr_input_plugin_t *this, int page) { char *filename; - int size = strlen(this->tmp_prefix)+PVR_FILENAME_SIZE; - filename = malloc(size); - - snprintf(filename, size, PVR_FILENAME, this->tmp_prefix, this->session, page); + asprintf(&filename, PVR_FILENAME, this->tmp_prefix, this->session, page); return filename; } @@ -528,12 +524,9 @@ static char *make_base_save_name(int channel, time_t tm) { struct tm rec_time; char *filename; - int size = SAVE_BASE_FILENAME_SIZE; - filename = malloc(size); - localtime_r(&tm, &rec_time); - snprintf(filename, size, SAVE_BASE_FILENAME, + asprintf(&filename, SAVE_BASE_FILENAME, channel, rec_time.tm_mon+1, rec_time.tm_mday, rec_time.tm_year+1900, rec_time.tm_hour, rec_time.tm_min, rec_time.tm_sec); @@ -547,10 +540,7 @@ static char *make_save_name(pvr_input_plugin_t *this, char *base, int page) { char *filename; - int size = strlen(this->save_prefix)+strlen(base)+SAVE_FILENAME_SIZE; - filename = malloc(size); - - snprintf(filename, size, SAVE_FILENAME, this->save_prefix, base, page); + asprintf(&filename, SAVE_FILENAME, this->save_prefix, base, page); return filename; } @@ -989,69 +979,92 @@ static void pvr_event_handler (pvr_input_plugin_t *this) { /* make sure we are not paused */ _x_set_speed(this->stream, XINE_SPEED_NORMAL); - if( v4l2_data->session_id != this->session ) { - /* if session changes -> closes the old one */ - pthread_mutex_lock(&this->lock); - pvr_finish_recording(this); - time(&this->start_time); - this->show_time = this->start_time; - this->session = v4l2_data->session_id; - this->new_session = 1; - this->pvr_play_paused = 0; - this->scr_tunning = 0; - pvrscr_speed_tunning(this->scr, 1.0 ); - pvr_break_rec_page(this); - pthread_mutex_unlock(&this->lock); - _x_demux_flush_engine (this->stream); - } else { - /* no session change, break the page and store a new show_time */ - pthread_mutex_lock(&this->lock); - pvr_break_rec_page(this); - this->show_page = this->rec_page; - pthread_mutex_unlock(&this->lock); - time(&this->show_time); + if ( v4l2_data->session_id != -1) { + if( v4l2_data->session_id != this->session ) { + /* if session changes -> closes the old one */ + pthread_mutex_lock(&this->lock); + pvr_finish_recording(this); + time(&this->start_time); + this->show_time = this->start_time; + this->session = v4l2_data->session_id; + this->new_session = 1; + this->pvr_play_paused = 0; + this->scr_tunning = 0; + pvrscr_speed_tunning(this->scr, 1.0 ); + pvr_break_rec_page(this); + pthread_mutex_unlock(&this->lock); + _x_demux_flush_engine (this->stream); + } else { + /* no session change, break the page and store a new show_time */ + pthread_mutex_lock(&this->lock); + pvr_break_rec_page(this); + this->show_page = this->rec_page; + pthread_mutex_unlock(&this->lock); + time(&this->show_time); + } } - - if( (v4l2_data->input != -1 && v4l2_data->input != this->input) || - (v4l2_data->channel != -1 && v4l2_data->channel != this->channel) || - (v4l2_data->frequency != -1 && v4l2_data->frequency != this->frequency) ) { - struct v4l2_frequency vf; + pthread_mutex_lock(&this->dev_lock); + + /* change input */ + if (v4l2_data->input != -1 && v4l2_data->input != this->input) { this->input = v4l2_data->input; + + /* as of ivtv 0.10.6: must close and reopen to set input */ + close(this->dev_fd); + this->dev_fd = open (this->class->devname, O_RDWR); + if (this->dev_fd < 0) { + xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, + "input_pvr: error opening device %s\n", this->class->devname ); + } else { + if( ioctl(this->dev_fd, VIDIOC_S_INPUT, &this->input) == 0 ) { + lprintf("Tuner Input set to:%d\n", v4l2_data->input); + } else { + xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, + "input_pvr: error setting v4l2 input\n"); + } + } + } + + /* change channel */ + if (v4l2_data->channel != -1 && v4l2_data->channel != this->channel) { + lprintf("change channel to:%d\n", v4l2_data->channel); this->channel = v4l2_data->channel; + } + + /* change frequency */ + if (v4l2_data->frequency != -1 && v4l2_data->frequency != this->frequency) { + double freq = (double)v4l2_data->frequency / 1000.0; + struct v4l2_frequency vf; + struct v4l2_tuner vt; + double fac = 16; + + memset(&vf, 0, sizeof(vf)); + memset(&vt, 0, sizeof(vt)); + this->frequency = v4l2_data->frequency; - lprintf("switching to input:%d chan:%d freq:%.2f\n", - v4l2_data->input, - v4l2_data->channel, - (float)v4l2_data->frequency * 62.5); - - pthread_mutex_lock(&this->dev_lock); - if( ioctl(this->dev_fd, VIDIOC_S_INPUT, &this->input) ) - xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, - "input_pvr: error setting v4l2 input\n"); - - vf.frequency = this->frequency; + if (ioctl(this->dev_fd, VIDIOC_G_TUNER, &vt) == 0) { + fac = (vt.capability & V4L2_TUNER_CAP_LOW) ? 16000 : 16; + } + vf.tuner = 0; - if( ioctl(this->dev_fd, VIDIOC_S_FREQUENCY, &vf) ) - xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, - "input_pvr: error setting v4l2 frequency\n"); + vf.type = vt.type; + vf.frequency = (__u32)(freq * fac); - /* workaround an ivtv bug where stream gets bad mpeg2 artifacts - * after changing inputs. reopening the device fixes it. - */ - close(this->dev_fd); - this->dev_fd = open (this->class->devname, O_RDWR); - if (this->dev_fd == -1) { - xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, - "input_pvr: error opening device %s\n", this->class->devname ); - return; + if (ioctl(this->dev_fd, VIDIOC_S_FREQUENCY, &vf) == 0) { + lprintf("Tuner Frequency set to %d (%f.3 MHz)\n", vf.frequency, vf.frequency / fac); + } else { + xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, + "input_pvr: error setting v4l2 frequency\n"); } - pthread_mutex_unlock(&this->dev_lock); - - /* FIXME: also flush the device */ - /* _x_demux_flush_engine(this->stream); */ } + + pthread_mutex_unlock(&this->dev_lock); + + /* FIXME: also flush the device */ + /* _x_demux_flush_engine(this->stream); */ + break; @@ -1523,22 +1536,6 @@ static input_plugin_t *pvr_class_get_instance (input_class_t *cls_gen, xine_stre /* * plugin class functions */ - -static const char *pvr_class_get_description (input_class_t *this_gen) { - return _("WinTV-PVR 250/350 input plugin"); -} - -static const char *pvr_class_get_identifier (input_class_t *this_gen) { - return "pvr"; -} - - -static void pvr_class_dispose (input_class_t *this_gen) { - pvr_input_class_t *this = (pvr_input_class_t *) this_gen; - - free (this); -} - static void *init_plugin (xine_t *xine, void *data) { pvr_input_class_t *this; @@ -1557,11 +1554,11 @@ static void *init_plugin (xine_t *xine, void *data) { NULL); this->input_class.get_instance = pvr_class_get_instance; - this->input_class.get_identifier = pvr_class_get_identifier; - this->input_class.get_description = pvr_class_get_description; + this->input_class.identifier = "pvr"; + this->input_class.description = N_("WinTV-PVR 250/350 input plugin"); this->input_class.get_dir = NULL; this->input_class.get_autoplay_list = NULL; - this->input_class.dispose = pvr_class_dispose; + this->input_class.dispose = default_input_class_dispose; this->input_class.eject_media = NULL; return this; @@ -1573,7 +1570,7 @@ static void *init_plugin (xine_t *xine, void *data) { const plugin_info_t xine_plugin_info[] EXPORTED = { /* type, API, "name", version, special_info, init_function */ - { PLUGIN_INPUT | PLUGIN_MUST_PRELOAD, 17, "pvr", XINE_VERSION_CODE, NULL, init_plugin }, + { PLUGIN_INPUT | PLUGIN_MUST_PRELOAD, 18, "pvr", XINE_VERSION_CODE, NULL, init_plugin }, { PLUGIN_NONE, 0, "", 0, NULL, NULL } }; |