summaryrefslogtreecommitdiff
path: root/src/input/input_pvr.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/input/input_pvr.c')
-rw-r--r--src/input/input_pvr.c185
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 }
};