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.c412
1 files changed, 206 insertions, 206 deletions
diff --git a/src/input/input_pvr.c b/src/input/input_pvr.c
index a9c92e42e..7b08ef5ea 100644
--- a/src/input/input_pvr.c
+++ b/src/input/input_pvr.c
@@ -4,17 +4,17 @@
* This plugin was sponsored by 1Control
*
* This file is part of xine, a free video player.
- *
+ *
* xine is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
- *
+ *
* xine is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
@@ -32,26 +32,26 @@
* - audio.synchronization.av_sync_method=resample
* - ivtv driver (01 Jul 2003 cvs is known to work)
*
- * MRL:
+ * MRL:
* pvr:/<prefix_to_tmp_files>!<prefix_to_saved_files>!<max_page_age>
*
- * usage:
+ * usage:
* xine pvr:/<prefix_to_tmp_files>\!<prefix_to_saved_files>\!<max_page_age>
*/
/**************************************************************************
-
+
Programmer's note (or how to write your PVR frontend):
-
+
- in order to use live pause functionality you must capture data to disk.
this is done using XINE_EVENT_SET_V4L2 event. it is important to set the
inputs/channel/frequency you want to capture data from.
-
+
comments:
1) session_id must be set: it is used to create the temporary filenames.
-
+
2) if session_id = -1 no data will be recorded to disk (no pause/replay)
-
+
3) if session_id is the same as previous value it will just set the "sync
point". sync point (show_page) may be used by the PVR frontend to tell
that a new show has began. of course, the PVR frontend should be aware
@@ -60,18 +60,18 @@
- when user wants to start recording (that is: temporary data will be made
permanent) it should issue a XINE_EVENT_PVR_SAVE.
mode can be one of the following:
-
+
-1 = do nothing, just set the name (see below)
0 = truncate current session and save from now on
1 = save from last sync point
2 = save everything on current session
-
+
saving actually means just marking the current pages as not temporary.
when a session is finished, instead of erasing the files they will be
renamed using the save file prefix.
- the permanent name can be set in two ways:
-
+
1) passing a name with the XINE_EVENT_PVR_SAVE before closing the
current session. (id = -1)
2) when a saved session is closed without setting the name, it will be
@@ -81,7 +81,7 @@
pass back a XINE_EVENT_PVR_SAVE with id set. pvr plugin will rename
the files again.
-***************************************************************************/
+***************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
@@ -167,7 +167,7 @@ typedef struct {
config_values_t *config;
char *devname;
-
+
} pvr_input_class_t;
@@ -175,18 +175,18 @@ typedef struct {
input_plugin_t input_plugin;
pvr_input_class_t *class;
-
+
xine_stream_t *stream;
-
+
xine_event_queue_t *event_queue;
-
+
pvrscr_t *scr;
int scr_tunning;
int speed_before_pause;
-
+
uint32_t session; /* session number used to identify the pvr file */
int new_session; /* force going to realtime for new sessions */
-
+
int dev_fd; /* fd of the mpeg2 encoder device */
int rec_fd; /* fd of the current recording file (session/page) */
int play_fd; /* fd of the current playback (-1 when realtime) */
@@ -200,22 +200,22 @@ typedef struct {
uint32_t show_page; /* first page of current show */
uint32_t save_page; /* first page to save */
uint32_t page_block[MAX_PAGES]; /* first block of each page */
-
+
char *mrl;
char *tmp_prefix;
char *save_prefix;
char *save_name;
xine_list_t *saved_shows;
int saved_id;
-
+
time_t start_time; /* time when recording started */
time_t show_time; /* time when current show started */
-
+
/* buffer to pass data from pvr thread to xine */
uint8_t data[PVR_BLOCK_SIZE];
int valid_data;
int want_data;
-
+
pthread_mutex_t lock;
pthread_mutex_t dev_lock;
pthread_cond_t has_valid_data;
@@ -224,14 +224,14 @@ typedef struct {
int pvr_running;
int pvr_playing;
int pvr_play_paused;
-
+
int preview_buffers;
-
+
/* device properties */
int input;
int channel;
- uint32_t frequency;
-
+ uint32_t frequency;
+
} pvr_input_plugin_t;
typedef struct {
@@ -245,7 +245,7 @@ typedef struct {
* unix System Clock Reference + fine tunning
*
* on an ideal world we would be using scr from mpeg2
- * encoder just like dxr3 does.
+ * encoder just like dxr3 does.
* unfortunately it is not supported by ivtv driver,
* and perhaps not even possible with wintv cards.
*
@@ -279,19 +279,19 @@ static void pvrscr_set_pivot (pvrscr_t *this) {
struct timeval tv;
int64_t pts;
- double pts_calc;
+ double pts_calc;
xine_monotonic_clock(&tv, NULL);
pts_calc = (tv.tv_sec - this->cur_time.tv_sec) * this->speed_factor;
pts_calc += (tv.tv_usec - this->cur_time.tv_usec) * this->speed_factor / 1e6;
pts = this->cur_pts + pts_calc;
-/* This next part introduces a one off inaccuracy
- * to the scr due to rounding tv to pts.
+/* This next part introduces a one off inaccuracy
+ * to the scr due to rounding tv to pts.
*/
this->cur_time.tv_sec=tv.tv_sec;
this->cur_time.tv_usec=tv.tv_usec;
- this->cur_pts=pts;
+ this->cur_pts=pts;
return ;
}
@@ -303,7 +303,7 @@ static int pvrscr_set_speed (scr_plugin_t *scr, int speed) {
pvrscr_set_pivot( this );
this->xine_speed = speed;
- this->speed_factor = (double) speed * 90000.0 / XINE_FINE_SPEED_NORMAL *
+ this->speed_factor = (double) speed * 90000.0 / XINE_FINE_SPEED_NORMAL *
this->speed_tunning;
pthread_mutex_unlock (&this->lock);
@@ -316,7 +316,7 @@ static void pvrscr_speed_tunning (pvrscr_t *this, double factor) {
pvrscr_set_pivot( this );
this->speed_tunning = factor;
- this->speed_factor = (double) this->xine_speed * 90000.0 / XINE_FINE_SPEED_NORMAL *
+ this->speed_factor = (double) this->xine_speed * 90000.0 / XINE_FINE_SPEED_NORMAL *
this->speed_tunning;
pthread_mutex_unlock (&this->lock);
@@ -345,7 +345,7 @@ static void pvrscr_start (scr_plugin_t *scr, int64_t start_vpts) {
this->cur_pts = start_vpts;
pthread_mutex_unlock (&this->lock);
-
+
pvrscr_set_speed (&this->scr, XINE_FINE_SPEED_NORMAL);
}
@@ -354,16 +354,16 @@ static int64_t pvrscr_get_current (scr_plugin_t *scr) {
struct timeval tv;
int64_t pts;
- double pts_calc;
+ double pts_calc;
pthread_mutex_lock (&this->lock);
xine_monotonic_clock(&tv, NULL);
-
+
pts_calc = (tv.tv_sec - this->cur_time.tv_sec) * this->speed_factor;
pts_calc += (tv.tv_usec - this->cur_time.tv_usec) * this->speed_factor / 1e6;
pts = this->cur_pts + pts_calc;
-
+
pthread_mutex_unlock (&this->lock);
return pts;
@@ -388,9 +388,9 @@ static pvrscr_t *XINE_MALLOC pvrscr_init (void) {
this->scr.start = pvrscr_start;
this->scr.get_current = pvrscr_get_current;
this->scr.exit = pvrscr_exit;
-
+
pthread_mutex_init (&this->lock, NULL);
-
+
pvrscr_speed_tunning(this, 1.0 );
pvrscr_set_speed (&this->scr, XINE_SPEED_PAUSE);
#ifdef SCRLOG
@@ -405,10 +405,10 @@ static pvrscr_t *XINE_MALLOC pvrscr_init (void) {
static uint32_t block_to_page(pvr_input_plugin_t *this, uint32_t block) {
uint32_t page;
-
+
for( page = 0; page < this->rec_page; page++ ) {
if( block < this->page_block[page+1] )
- break;
+ break;
}
return page;
}
@@ -436,7 +436,7 @@ static off_t pvr_plugin_read (input_plugin_t *this_gen, char *buf, off_t len) {
}
-/*
+/*
* this function will adjust playback speed to control buffer utilization.
* we must avoid:
* - overflow: buffer runs full. no data is read from the mpeg2 card so it will discard
@@ -447,15 +447,15 @@ static off_t pvr_plugin_read (input_plugin_t *this_gen, char *buf, off_t len) {
* OBS: use with audio.synchronization.av_sync_method=resample
*/
static void pvr_adjust_realtime_speed(pvr_input_plugin_t *this, fifo_buffer_t *fifo, int speed ) {
-
+
int num_used, num_free;
int scr_tunning = this->scr_tunning;
-
+
num_used = fifo->size(fifo);
num_free = fifo->num_free(fifo);
-
+
if( num_used == 0 && scr_tunning != -2 ) {
-
+
/* buffer is empty. pause it for a while */
this->scr_tunning = -2; /* marked as paused */
pvrscr_speed_tunning(this->scr, 1.0);
@@ -464,44 +464,44 @@ static void pvr_adjust_realtime_speed(pvr_input_plugin_t *this, fifo_buffer_t *f
#ifdef SCRLOG
printf("input_pvr: buffer empty, pausing playback\n" );
#endif
-
+
} else if( scr_tunning == -2 ) {
-
+
/* currently paused, revert to normal if 1/3 full */
if( 2*num_used > num_free ) {
this->scr_tunning = 0;
-
+
pvrscr_speed_tunning(this->scr, 1.0 );
_x_set_speed(this->stream, this->speed_before_pause);
#ifdef SCRLOG
printf("input_pvr: resuming playback\n" );
#endif
}
-
+
} else if( speed == XINE_SPEED_NORMAL && this->play_fd == -1 ) {
-
+
/* when playing realtime, adjust the scr to make xine buffers half full */
if( num_used > 2*num_free )
- scr_tunning = +1; /* play faster */
+ scr_tunning = +1; /* play faster */
else if( num_free > 2*num_used )
scr_tunning = -1; /* play slower */
else if( (scr_tunning > 0 && num_free > num_used) ||
(scr_tunning < 0 && num_used > num_free) )
scr_tunning = 0;
-
+
if( scr_tunning != this->scr_tunning ) {
this->scr_tunning = scr_tunning;
#ifdef SCRLOG
printf("input_pvr: scr_tunning = %d (used: %d free: %d)\n", scr_tunning, num_used, num_free );
#endif
-
+
/* make it play .5% faster or slower */
pvrscr_speed_tunning(this->scr, 1.0 + (0.005 * scr_tunning) );
}
-
+
} else if( this->scr_tunning ) {
this->scr_tunning = 0;
-
+
pvrscr_speed_tunning(this->scr, 1.0 );
}
}
@@ -510,21 +510,21 @@ static void pvr_adjust_realtime_speed(pvr_input_plugin_t *this, fifo_buffer_t *f
static char *make_temp_name(pvr_input_plugin_t *this, int page) {
char *filename;
-
+
asprintf(&filename, PVR_FILENAME, this->tmp_prefix, this->session, page);
-
+
return filename;
}
-
+
#define SAVE_BASE_FILENAME "ch%03d %02d-%02d-%04d %02d:%02d:%02d"
-
+
static char *make_base_save_name(int channel, time_t tm) {
struct tm rec_time;
char *filename;
-
+
localtime_r(&tm, &rec_time);
-
- asprintf(&filename, 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);
@@ -535,9 +535,9 @@ static char *make_base_save_name(int channel, time_t tm) {
static char *make_save_name(pvr_input_plugin_t *this, char *base, int page) {
char *filename;
-
+
asprintf(&filename, SAVE_FILENAME, this->save_prefix, base, page);
-
+
return filename;
}
@@ -562,27 +562,27 @@ static void pvr_report_realtime (pvr_input_plugin_t *this, int mode) {
* close current recording page and open a new one
*/
static int pvr_break_rec_page (pvr_input_plugin_t *this) {
-
+
char *filename;
-
+
if( this->session == (unsigned)-1 ) /* not recording */
return 1;
-
+
if( this->rec_fd != -1 && this->rec_fd != this->play_fd ) {
- close(this->rec_fd);
+ close(this->rec_fd);
}
-
+
if( this->rec_fd == -1 )
this->rec_page = 0;
else
this->rec_page++;
-
+
this->page_block[this->rec_page] = this->rec_blk;
-
+
filename = make_temp_name(this, this->rec_page);
-
+
lprintf("opening pvr file for writing (%s)\n", filename);
-
+
this->rec_fd = open(filename, O_RDWR | O_CREAT | O_TRUNC, 0666 );
if( this->rec_fd == -1 ) {
xprintf(this->stream->xine, XINE_VERBOSITY_LOG,
@@ -591,39 +591,39 @@ static int pvr_break_rec_page (pvr_input_plugin_t *this) {
return 0;
}
free(filename);
-
+
/* erase first_page if old and not to be saved */
- if( this->max_page_age != (unsigned)-1 &&
+ if( this->max_page_age != (unsigned)-1 &&
this->rec_page - this->max_page_age == this->first_page &&
(this->save_page == (unsigned)-1 || this->first_page < this->save_page) ) {
-
+
filename = make_temp_name(this, this->first_page);
lprintf("erasing old pvr file (%s)\n", filename);
-
+
this->first_page++;
if(this->play_fd != -1 && this->play_page < this->first_page) {
this->play_blk = this->page_block[this->first_page];
close(this->play_fd);
this->play_fd = -1;
}
-
+
remove(filename);
free(filename);
- }
+ }
return 1;
}
/*
- * check the status of recording file, open new one as needed and write the current data.
+ * check the status of recording file, open new one as needed and write the current data.
*/
static int pvr_rec_file(pvr_input_plugin_t *this) {
-
+
off_t pos;
if( this->session == (unsigned)-1 ) /* not recording */
return 1;
-
+
/* check if it's time to change page/file */
if( this->rec_fd == -1 || (this->rec_blk - this->page_block[this->rec_page]) >= BLOCKS_PER_PAGE ) {
if( !pvr_break_rec_page(this) )
@@ -631,61 +631,61 @@ static int pvr_rec_file(pvr_input_plugin_t *this) {
}
pos = (off_t)(this->rec_blk - this->page_block[this->rec_page]) * PVR_BLOCK_SIZE;
if( lseek (this->rec_fd, pos, SEEK_SET) != pos ) {
- xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,
+ xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,
"input_pvr: error setting position for writing %" PRIdMAX "\n", (intmax_t)pos);
return 0;
}
if( this->rec_fd != -1 ) {
if( write(this->rec_fd, this->data, PVR_BLOCK_SIZE) < PVR_BLOCK_SIZE ) {
- xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,
+ xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,
"input_pvr: short write to pvr file (out of disk space?)\n");
return 0;
}
this->rec_blk++;
}
-
+
return 1;
}
-/*
+/*
* check for playback mode, switching realtime <-> non-realtime.
* gets data from file in non-realtime mode.
*/
static int pvr_play_file(pvr_input_plugin_t *this, fifo_buffer_t *fifo, uint8_t *buffer, int speed) {
-
+
off_t pos;
-
+
/* check for realtime. don't switch back unless enough buffers are
* free to not block the pvr thread */
if( this->new_session ||
(this->play_blk+1 >= this->rec_blk && speed >= XINE_SPEED_NORMAL &&
(this->play_fd == -1 || fifo->size(fifo) < fifo->num_free(fifo))) ) {
-
+
this->play_blk = (this->rec_blk) ? (this->rec_blk-1) : 0;
-
+
if( speed > XINE_SPEED_NORMAL )
_x_set_speed(this->stream, XINE_SPEED_NORMAL);
-
+
if( this->play_fd != -1 ) {
if(this->play_fd != this->rec_fd )
- close(this->play_fd);
+ close(this->play_fd);
this->play_fd = -1;
-
+
lprintf("switching back to realtime\n");
pvr_report_realtime(this,1);
-
+
} else if (this->new_session) {
lprintf("starting new session in realtime\n");
pvr_report_realtime(this,1);
}
-
+
this->want_data = 1;
this->new_session = 0;
-
+
} else {
- if( this->rec_fd == -1 )
+ if( this->rec_fd == -1 )
return 1;
if(speed != XINE_SPEED_PAUSE) {
@@ -699,30 +699,30 @@ static int pvr_play_file(pvr_input_plugin_t *this, fifo_buffer_t *fifo, uint8_t
}
}
- if( this->play_fd == -1 ||
+ if( this->play_fd == -1 ||
((this->play_blk - this->page_block[this->play_page]) >= BLOCKS_PER_PAGE) ||
(this->rec_page > this->play_page && this->play_blk >= this->page_block[this->play_page+1]) ) {
-
+
if(this->play_fd == -1) {
lprintf("switching to non-realtime\n");
pvr_report_realtime(this,0);
}
-
+
if( this->play_fd != -1 && this->play_fd != this->rec_fd ) {
- close(this->play_fd);
+ close(this->play_fd);
}
-
+
if( this->play_fd == -1 )
this->play_page = block_to_page(this, this->play_blk);
else
this->play_page++;
-
+
if( this->play_page < this->first_page ) {
this->play_page = this->first_page;
this->play_blk = this->page_block[this->play_page];
}
-
+
/* should be impossible */
if( this->play_page > this->rec_page ||
this->play_blk > this->rec_blk ) {
@@ -735,11 +735,11 @@ static int pvr_play_file(pvr_input_plugin_t *this, fifo_buffer_t *fifo, uint8_t
this->play_fd = this->rec_fd;
} else {
char *filename;
-
+
filename = make_temp_name(this, this->play_page);
lprintf("opening pvr file for reading (%s)\n", filename);
-
+
this->play_fd = open(filename, O_RDONLY );
if( this->play_fd == -1 ) {
xprintf(this->stream->xine, XINE_VERBOSITY_LOG,
@@ -752,7 +752,7 @@ static int pvr_play_file(pvr_input_plugin_t *this, fifo_buffer_t *fifo, uint8_t
this->want_data = 0;
pthread_cond_signal (&this->wake_pvr);
}
-
+
if(speed != XINE_SPEED_PAUSE) {
pos = (off_t)(this->play_blk - this->page_block[this->play_page]) * PVR_BLOCK_SIZE;
@@ -803,29 +803,29 @@ static void *pvr_loop (void *this_gen) {
int lost_sync;
while( this->pvr_running ) {
-
+
pthread_mutex_lock(&this->lock);
this->valid_data = 0;
pthread_mutex_unlock(&this->lock);
-
+
total_bytes = 0;
do {
-
+
lost_sync = 0;
-
+
pthread_mutex_lock(&this->dev_lock);
while (total_bytes < PVR_BLOCK_SIZE) {
num_bytes = read (this->dev_fd, this->data + total_bytes, PVR_BLOCK_SIZE-total_bytes);
if (num_bytes <= 0) {
- if (num_bytes < 0)
+ if (num_bytes < 0)
xprintf (this->stream->xine, XINE_VERBOSITY_LOG,
_("input_pvr: read error (%s)\n"), strerror(errno));
- this->pvr_running = 0;
+ this->pvr_running = 0;
break;
}
total_bytes += num_bytes;
}
-
+
if( this->data[0] || this->data[1] || this->data[2] != 1 || this->data[3] != 0xba ) {
xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "resyncing mpeg stream\n");
@@ -836,28 +836,28 @@ static void *pvr_loop (void *this_gen) {
this->data[0] = 0; this->data[1] = 0; this->data[2] = 1; this->data[3] = 0xba;
total_bytes = 4;
}
- }
+ }
pthread_mutex_unlock(&this->dev_lock);
-
- } while( lost_sync );
-
+
+ } while( lost_sync );
+
pthread_mutex_lock(&this->lock);
-
+
if( !pvr_rec_file(this) ) {
- this->pvr_running = 0;
+ this->pvr_running = 0;
}
-
+
this->valid_data = 1;
pthread_cond_signal (&this->has_valid_data);
- while(this->valid_data && this->play_fd == -1 &&
+ while(this->valid_data && this->play_fd == -1 &&
this->want_data && this->pvr_playing) {
pthread_cond_wait (&this->wake_pvr, &this->lock);
}
-
+
pthread_mutex_unlock(&this->lock);
}
-
+
pthread_exit(NULL);
}
@@ -868,7 +868,7 @@ static void *pvr_loop (void *this_gen) {
* name (save_name) or a default one using channel and time.
*/
static void pvr_finish_recording (pvr_input_plugin_t *this) {
-
+
char *src_filename;
char *save_base;
char *dst_filename;
@@ -877,31 +877,31 @@ static void pvr_finish_recording (pvr_input_plugin_t *this) {
lprintf("finish_recording\n");
if( this->rec_fd != -1 ) {
- close(this->rec_fd);
-
+ close(this->rec_fd);
+
if( this->play_fd != -1 && this->play_fd != this->rec_fd )
close(this->play_fd);
-
+
this->rec_fd = this->play_fd = -1;
-
+
if( this->save_page == this->show_page )
save_base = make_base_save_name(this->channel, this->show_time);
else
save_base = make_base_save_name(this->channel, this->start_time);
-
+
for( i = this->first_page; i <= this->rec_page; i++ ) {
-
+
src_filename = make_temp_name(this, i);
-
+
if( this->save_page == (unsigned)-1 || i < this->save_page ) {
lprintf("erasing old pvr file (%s)\n", src_filename);
remove(src_filename);
} else {
-
+
if( !this->save_name || !strlen(this->save_name) )
dst_filename = make_save_name(this, save_base, i-this->save_page+1);
- else
+ else
dst_filename = make_save_name(this, this->save_name, i-this->save_page+1);
lprintf("moving (%s) to (%s)\n", src_filename, dst_filename);
@@ -911,17 +911,17 @@ static void pvr_finish_recording (pvr_input_plugin_t *this) {
}
free(src_filename);
}
-
+
if( this->save_page != (unsigned)-1 && (!this->save_name || !strlen(this->save_name)) ) {
saved_show_t *show = malloc(sizeof(saved_show_t));
xine_event_t event;
xine_pvr_save_data_t data;
-
+
show->base_name = save_base;
show->id = ++this->saved_id;
show->pages = this->rec_page - this->save_page + 1;
xine_list_push_back (this->saved_shows, show);
-
+
lprintf("sending event with base name [%s]\n", show->base_name);
/* tell frontend the name of the saved show */
@@ -930,18 +930,18 @@ static void pvr_finish_recording (pvr_input_plugin_t *this) {
event.data = &data;
event.data_length = sizeof(data);
gettimeofday(&event.tv, NULL);
-
+
data.mode = 0;
data.id = show->id;
strncpy(data.name, show->base_name, sizeof(data.name));
data.name[sizeof(data.name) - 1] = '\0';
-
+
xine_event_send(this->stream, &event);
} else {
free(save_base);
}
}
-
+
this->first_page = 0;
this->show_page = 0;
this->save_page = -1;
@@ -1016,13 +1016,13 @@ static void pvr_event_handler (pvr_input_plugin_t *this) {
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,
+ xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG,
"input_pvr: error setting v4l2 input\n");
}
}
}
- /* change channel */
+ /* 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;
@@ -1057,13 +1057,13 @@ static void pvr_event_handler (pvr_input_plugin_t *this) {
}
pthread_mutex_unlock(&this->dev_lock);
-
+
/* FIXME: also flush the device */
/* _x_demux_flush_engine(this->stream); */
break;
-
-
+
+
case XINE_EVENT_PVR_SAVE:
if( this->session != -1 ) {
switch( save_data->mode ) {
@@ -1096,11 +1096,11 @@ static void pvr_event_handler (pvr_input_plugin_t *this) {
if( this->save_name )
free( this->save_name );
this->save_name = NULL;
-
+
if( save_data->id < 0 ) {
/* no id: set name for current recording */
this->save_name = strdup(save_data->name);
-
+
} else {
/* search for the ID of saved shows and rename it
* to the given name. */
@@ -1108,17 +1108,17 @@ static void pvr_event_handler (pvr_input_plugin_t *this) {
char *dst_filename;
saved_show_t *show;
xine_list_iterator_t ite;
-
+
pthread_mutex_lock(&this->lock);
-
+
ite = xine_list_front (this->saved_shows);
while (ite) {
show = xine_list_get_value(this->saved_shows, ite);
if( show->id == save_data->id ) {
int i;
-
+
for( i = 0; i < show->pages; i++ ) {
-
+
src_filename = make_save_name(this, show->base_name, i+1);
dst_filename = make_save_name(this, save_data->name, i+1);
@@ -1150,7 +1150,7 @@ static void pvr_event_handler (pvr_input_plugin_t *this) {
case XINE_EVENT_SET_MPEG_DATA: {
struct ivtv_ioctl_codec codec;
-
+
pthread_mutex_lock(&this->dev_lock);
/* how lame. we must close and reopen to change bitrate. */
@@ -1161,9 +1161,9 @@ static void pvr_event_handler (pvr_input_plugin_t *this) {
_("input_pvr: error opening device %s\n"), this->class->devname );
return;
}
-
+
if (ioctl(this->dev_fd, IVTV_IOC_G_CODEC, &codec) < 0) {
- xprintf(this->stream->xine, XINE_VERBOSITY_LOG,
+ xprintf(this->stream->xine, XINE_VERBOSITY_LOG,
_("input_pvr: IVTV_IOC_G_CODEC failed, maybe API changed?\n"));
} else {
codec.bitrate = mpeg_data->bitrate_mean;
@@ -1178,7 +1178,7 @@ static void pvr_event_handler (pvr_input_plugin_t *this) {
pthread_mutex_unlock(&this->dev_lock);
}
break;
-
+
#if 0
default:
printf ("input_pvr: got an event, type 0x%08x\n", event->type);
@@ -1204,7 +1204,7 @@ static buf_element_t *pvr_plugin_read_block (input_plugin_t *this_gen, fifo_buff
if( !this->pvr_running ) {
xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "input_pvr: thread died, aborting\n");
- return NULL;
+ return NULL;
}
buf = fifo->buffer_pool_alloc (fifo);
@@ -1220,7 +1220,7 @@ static buf_element_t *pvr_plugin_read_block (input_plugin_t *this_gen, fifo_buff
if( this->pvr_play_paused )
speed = XINE_SPEED_PAUSE;
-
+
if( this->pvr_playing && _x_stream_info_get(this->stream, XINE_STREAM_INFO_IGNORE_VIDEO) ) {
/* video decoding has being disabled. avoid tweaking the clock */
this->pvr_playing = 0;
@@ -1232,55 +1232,55 @@ static buf_element_t *pvr_plugin_read_block (input_plugin_t *this_gen, fifo_buff
this->pvr_playing = 1;
this->play_blk = this->rec_blk;
}
-
+
if( this->pvr_playing )
pvr_adjust_realtime_speed(this, fifo, speed);
pvr_event_handler(this);
-
+
buf->content = buf->mem;
-
+
pthread_mutex_lock(&this->lock);
-
+
if( this->pvr_playing )
if( !pvr_play_file(this, fifo, buf->content, speed) ) {
buf->free_buffer(buf);
pthread_mutex_unlock(&this->lock);
return NULL;
}
-
+
if( todo == PVR_BLOCK_SIZE && speed != XINE_SPEED_PAUSE &&
this->pvr_playing ) {
buf->type = BUF_DEMUX_BLOCK;
buf->size = PVR_BLOCK_SIZE;
-
+
if(this->play_fd == -1) {
-
+
/* realtime mode: wait for valid data from pvr thread */
this->want_data = 1;
while(!this->valid_data && this->pvr_running)
pthread_cond_wait (&this->has_valid_data, &this->lock);
-
+
this->play_blk = this->rec_blk;
xine_fast_memcpy(buf->content, this->data, PVR_BLOCK_SIZE);
-
+
this->valid_data = 0;
pthread_cond_signal (&this->wake_pvr);
}
pthread_mutex_unlock(&this->lock);
-
+
} else {
pthread_mutex_unlock(&this->lock);
-
+
buf->type = BUF_CONTROL_NOP;
- buf->size = 0;
-
+ buf->size = 0;
+
if(this->preview_buffers)
this->preview_buffers--;
else
xine_usec_sleep (20000);
}
-
+
return buf;
}
@@ -1289,7 +1289,7 @@ static off_t pvr_plugin_seek (input_plugin_t *this_gen, off_t offset, int origin
pvr_input_plugin_t *this = (pvr_input_plugin_t *) this_gen;
pthread_mutex_lock(&this->lock);
-
+
switch( origin ) {
case SEEK_SET:
this->play_blk = (offset / PVR_BLOCK_SIZE) + this->page_block[this->first_page];
@@ -1301,18 +1301,18 @@ static off_t pvr_plugin_seek (input_plugin_t *this_gen, off_t offset, int origin
this->play_blk = this->rec_blk + (offset / PVR_BLOCK_SIZE);
break;
}
-
+
/* invalidate the fd if needed */
if( this->play_fd != -1 && block_to_page(this,this->play_blk) != this->play_page ) {
if( this->play_fd != this->rec_fd )
- close(this->play_fd);
+ close(this->play_fd);
this->play_fd = -1;
if( this->play_blk >= this->rec_blk )
pvr_report_realtime(this,1);
}
pthread_mutex_unlock(&this->lock);
-
+
return (off_t) (this->play_blk - this->page_block[this->first_page]) * PVR_BLOCK_SIZE;
}
@@ -1339,9 +1339,9 @@ static const char* pvr_plugin_get_mrl (input_plugin_t *this_gen) {
return this->mrl;
}
-static int pvr_plugin_get_optional_data (input_plugin_t *this_gen,
+static int pvr_plugin_get_optional_data (input_plugin_t *this_gen,
void *data, int data_type) {
-
+
return INPUT_OPTIONAL_UNSUPPORTED;
}
@@ -1359,11 +1359,11 @@ static void pvr_plugin_dispose (input_plugin_t *this_gen ) {
this->want_data = 0;
pthread_cond_signal (&this->wake_pvr);
pthread_mutex_unlock(&this->lock);
- pthread_join (this->pvr_thread, &p);
+ pthread_join (this->pvr_thread, &p);
lprintf("pvr thread joined\n");
}
-
+
if (this->scr) {
this->stream->xine->clock->unregister_scr(this->stream->xine->clock, &this->scr->scr);
this->scr->scr.exit(&this->scr->scr);
@@ -1376,15 +1376,15 @@ static void pvr_plugin_dispose (input_plugin_t *this_gen ) {
close(this->dev_fd);
pvr_finish_recording(this);
-
+
free (this->mrl);
-
+
if (this->tmp_prefix)
free (this->tmp_prefix);
-
+
if (this->save_prefix)
free (this->save_prefix);
-
+
ite = xine_list_front (this->saved_shows);
while (ite) {
show = xine_list_get_value(this->saved_shows, ite);
@@ -1401,7 +1401,7 @@ static int pvr_plugin_open (input_plugin_t *this_gen ) {
int64_t time;
int err;
struct ivtv_ioctl_codec codec;
-
+
this->session = 0;
this->rec_fd = -1;
this->play_fd = -1;
@@ -1417,7 +1417,7 @@ static int pvr_plugin_open (input_plugin_t *this_gen ) {
this->dev_fd = open (this->class->devname, O_RDWR);
if (this->dev_fd == -1) {
- xprintf(this->stream->xine, XINE_VERBOSITY_LOG,
+ xprintf(this->stream->xine, XINE_VERBOSITY_LOG,
_("input_pvr: error opening device %s\n"), this->class->devname );
return 0;
}
@@ -1436,42 +1436,42 @@ static int pvr_plugin_open (input_plugin_t *this_gen ) {
_("input_pvr: IVTV_IOC_S_CODEC failed, maybe API changed?\n"));
}
}
-
- /* register our own scr provider */
+
+ /* register our own scr provider */
time = this->stream->xine->clock->get_current_time(this->stream->xine->clock);
this->scr = pvrscr_init();
this->scr->scr.start(&this->scr->scr, time);
this->stream->xine->clock->register_scr(this->stream->xine->clock, &this->scr->scr);
this->scr_tunning = 0;
-
+
this->event_queue = xine_event_new_queue (this->stream);
-
+
/* enable resample method */
this->stream->xine->config->update_num(this->stream->xine->config,"audio.synchronization.av_sync_method",1);
-
+
this->pvr_running = 1;
-
+
if ((err = pthread_create (&this->pvr_thread,
NULL, pvr_loop, this)) != 0) {
xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG,
"input_pvr: can't create new thread (%s)\n", strerror(err));
_x_abort();
}
-
+
return 1;
}
-static input_plugin_t *pvr_class_get_instance (input_class_t *cls_gen, xine_stream_t *stream,
+static input_plugin_t *pvr_class_get_instance (input_class_t *cls_gen, xine_stream_t *stream,
const char *data) {
pvr_input_class_t *cls = (pvr_input_class_t *) cls_gen;
pvr_input_plugin_t *this;
char *mrl;
char *aux;
-
- if (strncasecmp (data, "pvr:/", 5))
+
+ if (strncasecmp (data, "pvr:/", 5))
return NULL;
-
+
mrl = strdup(data);
aux = &mrl[5];
@@ -1485,14 +1485,14 @@ static input_plugin_t *pvr_class_get_instance (input_class_t *cls_gen, xine_stre
/* decode configuration options from mrl */
if( strlen(aux) ) {
this->tmp_prefix = strdup(aux);
-
+
aux = strchr(this->tmp_prefix,'!');
if( aux ) {
aux[0] = '\0';
this->save_prefix = strdup(aux+1);
aux = strchr(this->save_prefix, '!');
- if( aux ) {
+ if( aux ) {
aux[0] = '\0';
if( atoi(aux+1) )
this->max_page_age = atoi(aux+1);
@@ -1504,11 +1504,11 @@ static input_plugin_t *pvr_class_get_instance (input_class_t *cls_gen, xine_stre
this->tmp_prefix=strdup("./");
this->save_prefix=strdup("./");
}
-
+
lprintf("tmp_prefix=%s\n", this->tmp_prefix);
lprintf("save_prefix=%s\n", this->save_prefix);
lprintf("max_page_age=%d\n", this->max_page_age);
-
+
this->input_plugin.open = pvr_plugin_open;
this->input_plugin.get_capabilities = pvr_plugin_get_capabilities;
this->input_plugin.read = pvr_plugin_read;
@@ -1526,12 +1526,12 @@ static input_plugin_t *pvr_class_get_instance (input_class_t *cls_gen, xine_stre
this->event_queue = NULL;
this->save_name = NULL;
this->saved_shows = xine_list_new();
-
+
pthread_mutex_init (&this->lock, NULL);
pthread_mutex_init (&this->dev_lock, NULL);
pthread_cond_init (&this->has_valid_data,NULL);
pthread_cond_init (&this->wake_pvr,NULL);
-
+
return &this->input_plugin;
}
@@ -1588,7 +1588,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 */
+ /* type, API, "name", version, special_info, init_function */
{ PLUGIN_INPUT | PLUGIN_MUST_PRELOAD, 17, "pvr", XINE_VERSION_CODE, NULL, init_plugin },
{ PLUGIN_NONE, 0, "", 0, NULL, NULL }
};