From 2678250cbf0eeaff5a5c3242ed3b30e946743896 Mon Sep 17 00:00:00 2001 From: Daniel Caujolle-Bert Date: Sat, 20 Dec 2003 23:42:46 +0000 Subject: No globals allowed. Fix indentation style. Explicit (void) function parameter. CVS patchset: 5929 CVS date: 2003/12/20 23:42:46 --- src/input/input_v4l.c | 2681 ++++++++++++++++++++++++------------------------- 1 file changed, 1325 insertions(+), 1356 deletions(-) diff --git a/src/input/input_v4l.c b/src/input/input_v4l.c index 7e55c1788..4910a508d 100644 --- a/src/input/input_v4l.c +++ b/src/input/input_v4l.c @@ -54,7 +54,6 @@ #include #include - /* Used to capture the audio data */ #define ALSA_PCM_NEW_HW_PARAMS_API #define ALSA_PCM_NEW_SW_PARAMS_API @@ -84,9 +83,9 @@ static struct { { 160, 120 }, }; -#define NUM_RESOLUTIONS (sizeof(resolutions)/sizeof(resolutions[0])) -#define RADIO_DEV "/dev/v4l/radio0" -#define VIDEO_DEV "/dev/v4l/video0" +#define NUM_RESOLUTIONS (sizeof(resolutions)/sizeof(resolutions[0])) +#define RADIO_DEV "/dev/v4l/radio0" +#define VIDEO_DEV "/dev/v4l/video0" /* #define LOG */ @@ -106,73 +105,76 @@ static struct { typedef struct pvrscr_s pvrscr_t; typedef struct { - - input_class_t input_class; - - xine_t *xine; + input_class_t input_class; + xine_t *xine; } v4l_input_class_t; typedef struct { - input_plugin_t input_plugin; - - xine_stream_t *stream; - char *mrl; + input_plugin_t input_plugin; + + xine_stream_t *stream; + char *mrl; - off_t curpos; + off_t curpos; - int old_interlace; - int old_zoomx; - int old_zoomy; - int audio_only; + int old_interlace; + int old_zoomx; + int old_zoomy; + int audio_only; /* Audio */ - buf_element_t *aud_frames; - pthread_mutex_t aud_frames_lock; - pthread_cond_t aud_frame_freed; + buf_element_t *aud_frames; + pthread_mutex_t aud_frames_lock; + pthread_cond_t aud_frame_freed; #ifdef HAVE_ALSA /* Handle for the PCM device */ - snd_pcm_t *pcm_handle; + snd_pcm_t *pcm_handle; /* Record stream (via line 1) */ - snd_pcm_stream_t pcm_stream; + snd_pcm_stream_t pcm_stream; /* Information and configuration for the PCM stream */ - snd_pcm_hw_params_t *pcm_hwparams; + snd_pcm_hw_params_t *pcm_hwparams; /* Name of the PCM device, plughw:0,0?=>soundcard,device*/ - char *pcm_name; + char *pcm_name; /* Use alsa to capture the sound (for a/v sync) */ - char audio_capture; + char audio_capture; - int exact_rate; /* Actual sample rate - sndpcm_hw_params_set_rate_near */ - int dir; /* exact rate == rate --> dir = 0 - exact rate < rate --> dir = -1 - exact rate > rate --> dir = 1 */ - - unsigned char *pcm_data; - - int64_t pts_aud_start; + int exact_rate; /* Actual sample rate + sndpcm_hw_params_set_rate_near */ + int dir; /* exact rate == rate --> dir = 0 + exact rate < rate --> dir = -1 + exact rate > rate --> dir = 1 */ + + unsigned char *pcm_data; + + int64_t pts_aud_start; #endif + int rate; /* Sample rate */ + int periods; /* Number of periods */ + int periodsize; /* Periodsize in bytes */ + int bits; + /* Video */ - buf_element_t *vid_frames; - pthread_mutex_t vid_frames_lock; - pthread_cond_t vid_frame_freed; + buf_element_t *vid_frames; + pthread_mutex_t vid_frames_lock; + pthread_cond_t vid_frame_freed; - int video_fd; - int radio_fd; + int video_fd; + int radio_fd; - int input; - int tuner; - unsigned long frequency; - unsigned long calc_frequency; - char *tuner_name; + int input; + int tuner; + unsigned long frequency; + unsigned long calc_frequency; + char *tuner_name; - int radio; /* ask for a radio channel */ - int channel; /* channel number */ + int radio; /* ask for a radio channel */ + int channel; /* channel number */ struct video_channel video_channel; struct video_tuner video_tuner; @@ -188,10 +190,10 @@ typedef struct { struct video_mmap gb_buf; int64_t start_time; - xine_event_queue_t *event_queue; + xine_event_queue_t *event_queue; - pvrscr_t *scr; - int scr_tunning; + pvrscr_t *scr; + int scr_tunning; } v4l_input_plugin_t; @@ -214,120 +216,119 @@ typedef struct { #define SCR_SKIP -4 struct pvrscr_s { - scr_plugin_t scr; - - struct timeval cur_time; - int64_t cur_pts; - int xine_speed; - double speed_factor; - double speed_tunning; - - pthread_mutex_t lock; + scr_plugin_t scr; + + struct timeval cur_time; + int64_t cur_pts; + int xine_speed; + double speed_factor; + double speed_tunning; + + pthread_mutex_t lock; }; static int pvrscr_get_priority(scr_plugin_t *scr) { - return 10; /* high priority */ + return 10; /* high priority */ } /* Only call this when already mutex locked */ static void pvrscr_set_pivot(pvrscr_t *this) { - struct timeval tv; - int64_t pts; - double pts_calc; - - gettimeofday(&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->cur_time.tv_sec=tv.tv_sec; - this->cur_time.tv_usec=tv.tv_usec; - this->cur_pts=pts; - - return; + struct timeval tv; + int64_t pts; + double pts_calc; + + gettimeofday(&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->cur_time.tv_sec = tv.tv_sec; + this->cur_time.tv_usec = tv.tv_usec; + this->cur_pts = pts; + + return; } static int pvrscr_set_speed (scr_plugin_t *scr, int speed) { - pvrscr_t *this = (pvrscr_t*) scr; - - pthread_mutex_lock (&this->lock); - - pvrscr_set_pivot( this ); - this->xine_speed = speed; - this->speed_factor = (double) speed * 90000.0 / 4.0 * - this->speed_tunning; - - pthread_mutex_unlock (&this->lock); - - return speed; + pvrscr_t *this = (pvrscr_t*) scr; + + pthread_mutex_lock (&this->lock); + + pvrscr_set_pivot( this ); + this->xine_speed = speed; + this->speed_factor = (double) speed * 90000.0 / 4.0 * + this->speed_tunning; + + pthread_mutex_unlock (&this->lock); + + return speed; } static void pvrscr_speed_tunning (pvrscr_t *this, double factor) { - pthread_mutex_lock (&this->lock); - - pvrscr_set_pivot( this ); - this->speed_tunning = factor; - this->speed_factor = (double) this->xine_speed * 90000.0 / 4.0 * - this->speed_tunning; - - pthread_mutex_unlock (&this->lock); + pthread_mutex_lock (&this->lock); + + pvrscr_set_pivot( this ); + this->speed_tunning = factor; + this->speed_factor = (double) this->xine_speed * 90000.0 / 4.0 * + this->speed_tunning; + + pthread_mutex_unlock (&this->lock); } static void pvrscr_adjust (scr_plugin_t *scr, int64_t vpts) { - pvrscr_t *this = (pvrscr_t*) scr; - struct timeval tv; - - pthread_mutex_lock (&this->lock); - - gettimeofday(&tv, NULL); - this->cur_time.tv_sec=tv.tv_sec; - this->cur_time.tv_usec=tv.tv_usec; - this->cur_pts = vpts; - - pthread_mutex_unlock (&this->lock); + pvrscr_t *this = (pvrscr_t*) scr; + struct timeval tv; + + pthread_mutex_lock (&this->lock); + + gettimeofday(&tv, NULL); + this->cur_time.tv_sec = tv.tv_sec; + this->cur_time.tv_usec = tv.tv_usec; + this->cur_pts = vpts; + + pthread_mutex_unlock (&this->lock); } static void pvrscr_start (scr_plugin_t *scr, int64_t start_vpts) { - pvrscr_t *this = (pvrscr_t*) scr; - - pthread_mutex_lock (&this->lock); - - gettimeofday(&this->cur_time, NULL); - this->cur_pts = start_vpts; - - pthread_mutex_unlock (&this->lock); - - pvrscr_set_speed (&this->scr, XINE_SPEED_NORMAL); + pvrscr_t *this = (pvrscr_t*) scr; + + pthread_mutex_lock (&this->lock); + + gettimeofday(&this->cur_time, NULL); + this->cur_pts = start_vpts; + + pthread_mutex_unlock (&this->lock); + + pvrscr_set_speed (&this->scr, XINE_SPEED_NORMAL); } static int64_t pvrscr_get_current (scr_plugin_t *scr) { - pvrscr_t *this = (pvrscr_t*) scr; - - struct timeval tv; - int64_t pts; - double pts_calc; - pthread_mutex_lock (&this->lock); - - gettimeofday(&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; + pvrscr_t *this = (pvrscr_t*) scr; + struct timeval tv; + int64_t pts; + double pts_calc; + + pthread_mutex_lock (&this->lock); + + gettimeofday(&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; } static void pvrscr_exit (scr_plugin_t *scr) @@ -383,8 +384,8 @@ static void report_progress (xine_stream_t *stream, int p) prg.percent = (p>100)?100:p; - event.type = XINE_EVENT_PROGRESS; - event.data = &prg; + event.type = XINE_EVENT_PROGRESS; + event.data = &prg; event.data_length = sizeof (xine_progress_data_t); xine_event_send (stream, &event); @@ -392,17 +393,8 @@ static void report_progress (xine_stream_t *stream, int p) /**** END COPY AND PASTE from net_buf_ctrl ***************/ -int rate = 44100; /* Sample rate */ -int dir; /* exact rate == rate --> dir = 0 - exact rate < rate --> dir = -1 - exact rate > rate --> dir = 1 */ -int periods = 2; /* Number of periods */ -int periodsize = 2 * 8192; /* Periodsize in bytes */ -int bits = 16; - static int search_by_tuner(v4l_input_plugin_t *this, char *input_source); static int search_by_channel(v4l_input_plugin_t *this, char *input_source); - static void v4l_event_handler(v4l_input_plugin_t *this); /** @@ -444,7 +436,7 @@ static void store_aud_frame (buf_element_t *frame) pthread_mutex_lock (&this->aud_frames_lock) ; - frame->next = this->aud_frames; + frame->next = this->aud_frames; this->aud_frames = frame; pthread_cond_signal (&this->aud_frame_freed); @@ -456,7 +448,6 @@ static void store_aud_frame (buf_element_t *frame) */ inline static buf_element_t *alloc_vid_frame (v4l_input_plugin_t *this) { - buf_element_t *frame; DBGPRINT("alloc_vid_frame. trying to get lock...\n"); @@ -470,7 +461,7 @@ inline static buf_element_t *alloc_vid_frame (v4l_input_plugin_t *this) pthread_cond_wait (&this->vid_frame_freed, &this->vid_frames_lock); } - frame = this->vid_frames; + frame = this->vid_frames; this->vid_frames = this->vid_frames->next; pthread_mutex_unlock (&this->vid_frames_lock); @@ -492,303 +483,303 @@ static void store_vid_frame (buf_element_t *frame) pthread_mutex_lock (&this->vid_frames_lock) ; - frame->next = this->vid_frames; + frame->next = this->vid_frames; this->vid_frames = frame; pthread_cond_signal (&this->vid_frame_freed); - pthread_mutex_unlock (&this->vid_frames_lock); } static int extract_mrl(v4l_input_plugin_t *this, char *mrl) { - char *tuner_name = NULL; - int frequency = 0; - char *locator = NULL; - char *begin = NULL; - - if (mrl == NULL) { - DBGPRINT("Someone passed an empty mrl\n"); - return 0; - } - - for (locator = mrl; *locator != '\0' && *locator != '/' ; locator++); - - /* Get tuner name */ - if (*locator == '/') { - begin = ++locator; - - for (; *locator != '\0' && *locator != '/' ; locator++); - - tuner_name = (char *) strndup(begin, locator - begin); - - /* Get frequency, if available */ - sscanf(locator, "/%d", &frequency); - DBGPRINT("v4l: Tuner name: '%s' freq: %d\r\n", tuner_name, frequency); - } else { - PRINT("v4l: No tuner name given. Expected syntac: v4l:/tuner/frequency\r\n"); - PRINT("v4l: Using currently tuned settings\r\n"); - } - - this->frequency = frequency; + char *tuner_name = NULL; + int frequency = 0; + char *locator = NULL; + char *begin = NULL; + + if (mrl == NULL) { + DBGPRINT("Someone passed an empty mrl\n"); + return 0; + } + + for (locator = mrl; *locator != '\0' && *locator != '/' ; locator++); + + /* Get tuner name */ + if (*locator == '/') { + begin = ++locator; + + for (; *locator != '\0' && *locator != '/' ; locator++); + + tuner_name = (char *) strndup(begin, locator - begin); + + /* Get frequency, if available */ + sscanf(locator, "/%d", &frequency); + DBGPRINT("v4l: Tuner name: '%s' freq: %d\r\n", tuner_name, frequency); + } else { + PRINT("v4l: No tuner name given. Expected syntac: v4l:/tuner/frequency\r\n"); + PRINT("v4l: Using currently tuned settings\r\n"); + } + + this->frequency = frequency; this->tuner_name = tuner_name; - + return 1; } static int set_frequency(v4l_input_plugin_t *this, unsigned long frequency) { - int ret = 0; - int fd; - - if (this->video_fd > 0) - fd = this->video_fd; - else - fd = this->radio_fd; - - if (frequency != 0) { - if (this->video_tuner.flags & VIDEO_TUNER_LOW) { - this->calc_frequency = frequency * 16; - } else { - this->calc_frequency = (frequency * 16) / 1000; - } - - - ret = ioctl(fd, VIDIOCSFREQ, &this->calc_frequency); + int ret = 0; + int fd; + + if (this->video_fd > 0) + fd = this->video_fd; + else + fd = this->radio_fd; + + if (frequency != 0) { + if (this->video_tuner.flags & VIDEO_TUNER_LOW) { + this->calc_frequency = frequency * 16; + } else { + this->calc_frequency = (frequency * 16) / 1000; + } + + + ret = ioctl(fd, VIDIOCSFREQ, &this->calc_frequency); #ifdef LOG - DBGPRINT("IOCTL set frequency (%ld) returned: %d\r\n", frequency, ret); - } else { - DBGPRINT("v4l: No frequency given. Won't be set\r\n"); - DBGPRINT("v4l: Syntax is: v4l:/tuner_name/frequency\r\n"); + DBGPRINT("IOCTL set frequency (%ld) returned: %d\r\n", frequency, ret); + } else { + DBGPRINT("v4l: No frequency given. Won't be set\r\n"); + DBGPRINT("v4l: Syntax is: v4l:/tuner_name/frequency\r\n"); #endif - } - - this->frequency = frequency; - - if (ret < 0) - return ret; - else - return 1; + } + + this->frequency = frequency; + + if (ret < 0) + return ret; + else + return 1; } static int set_input_source(v4l_input_plugin_t *this, char *input_source) { - int ret = 0; - - if ((ret = search_by_channel(this, input_source)) != 1) { - ret = search_by_tuner(this, input_source); - } - - return ret; + int ret = 0; + + if ((ret = search_by_channel(this, input_source)) != 1) { + ret = search_by_tuner(this, input_source); + } + + return ret; } static int search_by_tuner(v4l_input_plugin_t *this, char *input_source) { - int ret = 0; - int fd = 0; - int cur_tuner = 0; - - if (this->video_fd > 0) - fd = this->video_fd; - else - fd = this->radio_fd; + int ret = 0; + int fd = 0; + int cur_tuner = 0; - this->video_tuner.tuner = cur_tuner; - ioctl(fd, VIDIOCGCAP, &this->video_cap); - - DBGPRINT("This device has %d channel(s)\r\n", this->video_cap.channels); - - for (ret = ioctl(fd, VIDIOCGTUNER, &this->video_tuner); - ret == 0 && this->video_cap.channels > cur_tuner && strstr(this->video_tuner.name, input_source) == NULL; - cur_tuner++) { - - this->video_tuner.tuner = cur_tuner; - - DBGPRINT("(%d) V4L device currently set to: \r\n", ret); - DBGPRINT("Tuner: %d\r\n", this->video_tuner.tuner); - DBGPRINT("Name: %s\r\n", this->video_tuner.name); - if (this->video_tuner.flags & VIDEO_TUNER_LOW) { - DBGPRINT("Range: %ld - %ld\r\n", this->video_tuner.rangelow / 16, this->video_tuner.rangehigh * 16); - } else { - DBGPRINT("Range: %ld - %ld\r\n", this->video_tuner.rangelow * 1000 / 16, this->video_tuner.rangehigh * 1000 / 16); - } - } - - DBGPRINT("(%d) V4L device final: \r\n", ret); - DBGPRINT("Tuner: %d\r\n", this->video_tuner.tuner); - DBGPRINT("Name: %s\r\n", this->video_tuner.name); - if (this->video_tuner.flags & VIDEO_TUNER_LOW) { + if (this->video_fd > 0) + fd = this->video_fd; + else + fd = this->radio_fd; + + this->video_tuner.tuner = cur_tuner; + ioctl(fd, VIDIOCGCAP, &this->video_cap); + + DBGPRINT("This device has %d channel(s)\r\n", this->video_cap.channels); + + for (ret = ioctl(fd, VIDIOCGTUNER, &this->video_tuner); + ret == 0 && this->video_cap.channels > cur_tuner && strstr(this->video_tuner.name, input_source) == NULL; + cur_tuner++) { + + this->video_tuner.tuner = cur_tuner; + + DBGPRINT("(%d) V4L device currently set to: \r\n", ret); + DBGPRINT("Tuner: %d\r\n", this->video_tuner.tuner); + DBGPRINT("Name: %s\r\n", this->video_tuner.name); + if (this->video_tuner.flags & VIDEO_TUNER_LOW) { DBGPRINT("Range: %ld - %ld\r\n", this->video_tuner.rangelow / 16, this->video_tuner.rangehigh * 16); - } else { + } else { DBGPRINT("Range: %ld - %ld\r\n", this->video_tuner.rangelow * 1000 / 16, this->video_tuner.rangehigh * 1000 / 16); - } - - if (strstr(this->video_tuner.name, input_source) == NULL) - return -1; - - return 1; + } + } + + DBGPRINT("(%d) V4L device final: \r\n", ret); + DBGPRINT("Tuner: %d\r\n", this->video_tuner.tuner); + DBGPRINT("Name: %s\r\n", this->video_tuner.name); + if (this->video_tuner.flags & VIDEO_TUNER_LOW) { + DBGPRINT("Range: %ld - %ld\r\n", this->video_tuner.rangelow / 16, this->video_tuner.rangehigh * 16); + } else { + DBGPRINT("Range: %ld - %ld\r\n", this->video_tuner.rangelow * 1000 / 16, this->video_tuner.rangehigh * 1000 / 16); + } + + if (strstr(this->video_tuner.name, input_source) == NULL) + return -1; + + return 1; } static int search_by_channel(v4l_input_plugin_t *this, char *input_source) { - int ret = 0; - int fd = 0; - this->input = 0; - - if (this->video_fd > 0) - fd = this->video_fd; - else - fd = this->radio_fd; - - /* Tune into channel */ - ret = ioctl(fd, VIDIOCGCHAN, &this->video_channel); - DBGPRINT("(%d) V4L device currently set to:\r\n", ret); - DBGPRINT("Channel: %d\r\n", this->video_channel.channel); - DBGPRINT("Name: %s\r\n", this->video_channel.name); - DBGPRINT("Tuners: %d\r\n", this->video_channel.tuners); - DBGPRINT("Flags: %d\r\n", this->video_channel.flags); - DBGPRINT("Type: %d\r\n", this->video_channel.type); - DBGPRINT("Norm: %d\r\n", this->video_channel.norm); - - if (strlen(input_source) > 0) { - while (strstr(this->video_channel.name, input_source) == NULL && - ioctl(fd, VIDIOCGCHAN, &this->video_channel) == 0) { - - DBGPRINT("V4L device currently set to:\r\n"); - DBGPRINT("Channel: %d\r\n", this->video_channel.channel); - DBGPRINT("Name: %s\r\n", this->video_channel.name); - DBGPRINT("Tuners: %d\r\n", this->video_channel.tuners); - DBGPRINT("Flags: %d\r\n", this->video_channel.flags); - DBGPRINT("Type: %d\r\n", this->video_channel.type); - DBGPRINT("Norm: %d\r\n", this->video_channel.norm); - this->video_channel.channel = ++this->input; - } - - if (strstr(this->video_channel.name, input_source) == NULL) { - xprintf(this->stream->xine, XINE_VERBOSITY_LOG, _("Tuner name not found\n")); - return -1; - } - - this->tuner_name = input_source; - ret = ioctl(fd, VIDIOCSCHAN, &this->input); - - DBGPRINT("(%d) Set channel to %d\r\n", ret, this->input); - - /* FIXME: Don't assume tuner 0 ? */ - - this->tuner = 0; + int ret = 0; + int fd = 0; - ret = ioctl(fd, VIDIOCSTUNER, &this->tuner); - - DBGPRINT("(%d) Response on set tuner to %d\r\n", ret, this->tuner); + this->input = 0; + + if (this->video_fd > 0) + fd = this->video_fd; + else + fd = this->radio_fd; + + /* Tune into channel */ + ret = ioctl(fd, VIDIOCGCHAN, &this->video_channel); + DBGPRINT("(%d) V4L device currently set to:\r\n", ret); + DBGPRINT("Channel: %d\r\n", this->video_channel.channel); + DBGPRINT("Name: %s\r\n", this->video_channel.name); + DBGPRINT("Tuners: %d\r\n", this->video_channel.tuners); + DBGPRINT("Flags: %d\r\n", this->video_channel.flags); + DBGPRINT("Type: %d\r\n", this->video_channel.type); + DBGPRINT("Norm: %d\r\n", this->video_channel.norm); + + if (strlen(input_source) > 0) { + while (strstr(this->video_channel.name, input_source) == NULL && + ioctl(fd, VIDIOCGCHAN, &this->video_channel) == 0) { - this->video_tuner.tuner = this->tuner; - } else { - PRINT("v4l: Not setting video source. No source given\r\n"); - } - ret = ioctl(fd, VIDIOCGTUNER, &this->video_tuner); + DBGPRINT("V4L device currently set to:\r\n"); + DBGPRINT("Channel: %d\r\n", this->video_channel.channel); + DBGPRINT("Name: %s\r\n", this->video_channel.name); + DBGPRINT("Tuners: %d\r\n", this->video_channel.tuners); + DBGPRINT("Flags: %d\r\n", this->video_channel.flags); + DBGPRINT("Type: %d\r\n", this->video_channel.type); + DBGPRINT("Norm: %d\r\n", this->video_channel.norm); + this->video_channel.channel = ++this->input; + } + + if (strstr(this->video_channel.name, input_source) == NULL) { + xprintf(this->stream->xine, XINE_VERBOSITY_LOG, _("Tuner name not found\n")); + return -1; + } + + this->tuner_name = input_source; + ret = ioctl(fd, VIDIOCSCHAN, &this->input); + + DBGPRINT("(%d) Set channel to %d\r\n", ret, this->input); + + /* FIXME: Don't assume tuner 0 ? */ + + this->tuner = 0; + + ret = ioctl(fd, VIDIOCSTUNER, &this->tuner); + + DBGPRINT("(%d) Response on set tuner to %d\r\n", ret, this->tuner); + + this->video_tuner.tuner = this->tuner; + } else { + PRINT("v4l: Not setting video source. No source given\r\n"); + } + ret = ioctl(fd, VIDIOCGTUNER, &this->video_tuner); #ifdef LOG - DBGPRINT("(%d) Flags %d\r\n", ret, this->video_tuner.flags); - - DBGPRINT("VIDEO_TUNER_PAL %s set\r\n", this->video_tuner.flags & VIDEO_TUNER_PAL ? "" : "not"); - DBGPRINT("VIDEO_TUNER_NTSC %s set\r\n", this->video_tuner.flags & VIDEO_TUNER_NTSC ? "" : "not"); - DBGPRINT("VIDEO_TUNER_SECAM %s set\r\n", this->video_tuner.flags & VIDEO_TUNER_SECAM ? "" : "not"); - DBGPRINT("VIDEO_TUNER_LOW %s set\r\n", this->video_tuner.flags & VIDEO_TUNER_LOW ? "" : "not"); - DBGPRINT("VIDEO_TUNER_NORM %s set\r\n", this->video_tuner.flags & VIDEO_TUNER_NORM ? "" : "not"); - DBGPRINT("VIDEO_TUNER_STEREO_ON %s set\r\n", this->video_tuner.flags & VIDEO_TUNER_STEREO_ON ? "" : "not"); - DBGPRINT("VIDEO_TUNER_RDS_ON %s set\r\n", this->video_tuner.flags & VIDEO_TUNER_RDS_ON ? "" : "not"); - DBGPRINT("VIDEO_TUNER_MBS_ON %s set\r\n", this->video_tuner.flags & VIDEO_TUNER_MBS_ON ? "" : "not"); - - switch (this->video_tuner.mode) { - case VIDEO_MODE_PAL: - DBGPRINT("The tuner is in PAL mode\r\n"); - break; - case VIDEO_MODE_NTSC: - DBGPRINT("The tuner is in NTSC mode\r\n"); - break; - case VIDEO_MODE_SECAM: - DBGPRINT("The tuner is in SECAM mode\r\n"); - break; - case VIDEO_MODE_AUTO: - DBGPRINT("The tuner is in AUTO mode\r\n"); - break; - } + DBGPRINT("(%d) Flags %d\r\n", ret, this->video_tuner.flags); + + DBGPRINT("VIDEO_TUNER_PAL %s set\r\n", this->video_tuner.flags & VIDEO_TUNER_PAL ? "" : "not"); + DBGPRINT("VIDEO_TUNER_NTSC %s set\r\n", this->video_tuner.flags & VIDEO_TUNER_NTSC ? "" : "not"); + DBGPRINT("VIDEO_TUNER_SECAM %s set\r\n", this->video_tuner.flags & VIDEO_TUNER_SECAM ? "" : "not"); + DBGPRINT("VIDEO_TUNER_LOW %s set\r\n", this->video_tuner.flags & VIDEO_TUNER_LOW ? "" : "not"); + DBGPRINT("VIDEO_TUNER_NORM %s set\r\n", this->video_tuner.flags & VIDEO_TUNER_NORM ? "" : "not"); + DBGPRINT("VIDEO_TUNER_STEREO_ON %s set\r\n", this->video_tuner.flags & VIDEO_TUNER_STEREO_ON ? "" : "not"); + DBGPRINT("VIDEO_TUNER_RDS_ON %s set\r\n", this->video_tuner.flags & VIDEO_TUNER_RDS_ON ? "" : "not"); + DBGPRINT("VIDEO_TUNER_MBS_ON %s set\r\n", this->video_tuner.flags & VIDEO_TUNER_MBS_ON ? "" : "not"); + + switch (this->video_tuner.mode) { + case VIDEO_MODE_PAL: + DBGPRINT("The tuner is in PAL mode\r\n"); + break; + case VIDEO_MODE_NTSC: + DBGPRINT("The tuner is in NTSC mode\r\n"); + break; + case VIDEO_MODE_SECAM: + DBGPRINT("The tuner is in SECAM mode\r\n"); + break; + case VIDEO_MODE_AUTO: + DBGPRINT("The tuner is in AUTO mode\r\n"); + break; + } #endif - return 1; + return 1; } static int open_radio_capture_device(v4l_input_plugin_t *this) { - int tuner_found = 0; - int i = 0; - cfg_entry_t* entry; - - /* - * pre-alloc a bunch of frames - */ - - pthread_mutex_init (&this->vid_frames_lock, NULL); - pthread_cond_init (&this->vid_frame_freed, NULL); - pthread_mutex_init (&this->aud_frames_lock, NULL); - pthread_cond_init (&this->aud_frame_freed, NULL); - - DBGPRINT("Opening radio device\n"); - - entry = this->stream->xine->config->lookup_entry( - this->stream->xine->config, "input.v4l_radio_device_path"); - - this->radio_fd = open(entry->str_value, O_RDWR); - - if (this->radio_fd < 0) - return 0; - - DBGPRINT("Device opened, radio %d\n", this->radio_fd); - - if (set_input_source(this, this->tuner_name) > 0) - tuner_found = 1; - - _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_CHANNELS, periods); - _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_BITS, bits); - _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_SAMPLERATE, rate); - _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_AUDIO, 1); - _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_VIDEO, 0); - - /* - * Pre allocate some frames for audio and video. This way this hasn't to be - * done during capture. - */ - for (i=0; idecoder_info[1] = periodsize; - frame->content = xine_xmalloc(periodsize); - frame->type = BUF_AUDIO_RAWPCM; - frame->source = this; - frame->free_buffer = store_aud_frame; - frame->extra_info = xine_xmalloc(sizeof(extra_info_t)); - - store_aud_frame(frame); - } - - this->audio_only = 1; - - /* Unmute audio off video capture device */ - ioctl(this->radio_fd, VIDIOCGAUDIO, &this->audio); - memcpy(&this->audio_saved, &this->audio, sizeof(this->audio)); - this->audio.flags &= ~VIDEO_AUDIO_MUTE; - this->audio.volume=0x8000; - DBGPRINT("Setting audio volume\r\n"); - ioctl(this->radio_fd, VIDIOCSAUDIO, &this->audio); - - set_frequency(this, this->frequency); - - if (tuner_found) - return 1; - else - return 2; + int tuner_found = 0; + int i = 0; + cfg_entry_t *entry; + + /* + * pre-alloc a bunch of frames + */ + + pthread_mutex_init (&this->vid_frames_lock, NULL); + pthread_cond_init (&this->vid_frame_freed, NULL); + pthread_mutex_init (&this->aud_frames_lock, NULL); + pthread_cond_init (&this->aud_frame_freed, NULL); + + DBGPRINT("Opening radio device\n"); + + entry = this->stream->xine->config->lookup_entry( + this->stream->xine->config, "input.v4l_radio_device_path"); + + this->radio_fd = open(entry->str_value, O_RDWR); + + if (this->radio_fd < 0) + return 0; + + DBGPRINT("Device opened, radio %d\n", this->radio_fd); + + if (set_input_source(this, this->tuner_name) > 0) + tuner_found = 1; + + _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_CHANNELS, this->periods); + _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_BITS, this->bits); + _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_SAMPLERATE, this->rate); + _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_AUDIO, 1); + _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_VIDEO, 0); + + /* + * Pre allocate some frames for audio and video. This way this hasn't to be + * done during capture. + */ + for (i = 0; i < NUM_FRAMES; i++) { + buf_element_t *frame; + + /* Audio frame */ + frame = xine_xmalloc (sizeof (buf_element_t)); + + frame->decoder_info[1] = this->periodsize; + frame->content = xine_xmalloc(this->periodsize); + frame->type = BUF_AUDIO_RAWPCM; + frame->source = this; + frame->free_buffer = store_aud_frame; + frame->extra_info = xine_xmalloc(sizeof(extra_info_t)); + + store_aud_frame(frame); + } + + this->audio_only = 1; + + /* Unmute audio off video capture device */ + ioctl(this->radio_fd, VIDIOCGAUDIO, &this->audio); + memcpy(&this->audio_saved, &this->audio, sizeof(this->audio)); + this->audio.flags &= ~VIDEO_AUDIO_MUTE; + this->audio.volume=0x8000; + DBGPRINT("Setting audio volume\r\n"); + ioctl(this->radio_fd, VIDIOCSAUDIO, &this->audio); + + set_frequency(this, this->frequency); + + if (tuner_found) + return 1; + else + return 2; } /** @@ -800,240 +791,239 @@ static int open_radio_capture_device(v4l_input_plugin_t *this) */ static int open_video_capture_device(v4l_input_plugin_t *this) { - int i, j, ret, found = 0; - int tuner_found = 0; - cfg_entry_t* entry; - - DBGPRINT("Trying to open '%s'\n", this->mrl); - - /* - * pre-alloc a bunch of frames - */ - - pthread_mutex_init (&this->vid_frames_lock, NULL); - pthread_cond_init (&this->vid_frame_freed, NULL); - pthread_mutex_init (&this->aud_frames_lock, NULL); - pthread_cond_init (&this->aud_frame_freed, NULL); - - entry = this->stream->xine->config->lookup_entry( - this->stream->xine->config, "input.v4l_video_device_path"); - - /* Try to open the video device */ - this->video_fd = open(entry->str_value, O_RDWR); - - if (this->video_fd < 0) { - DBGPRINT("(%d) Cannot open v4l device (%s): %s\n", this->video_fd, - entry->str_value, strerror(errno)); - return 0; - } - DBGPRINT("Device opened, tv %d\n", this->video_fd); - - /* Get capabilities */ - if (ioctl(this->video_fd,VIDIOCGCAP,&this->video_cap) < 0) { - DBGPRINT ("VIDIOCGCAP ioctl went wrong\n"); - return 0; - } - - if (!(this->video_cap.type & VID_TYPE_CAPTURE)) { - /* Capture is not supported by the device. This is a must though! */ - DBGPRINT("Grab device does not handle capture\n"); - return 0; - } - - /* figure out the resolution */ - for (j=0; jmrl); + + /* + * pre-alloc a bunch of frames + */ + + pthread_mutex_init (&this->vid_frames_lock, NULL); + pthread_cond_init (&this->vid_frame_freed, NULL); + pthread_mutex_init (&this->aud_frames_lock, NULL); + pthread_cond_init (&this->aud_frame_freed, NULL); + + entry = this->stream->xine->config->lookup_entry( + this->stream->xine->config, "input.v4l_video_device_path"); + + /* Try to open the video device */ + this->video_fd = open(entry->str_value, O_RDWR); + + if (this->video_fd < 0) { + DBGPRINT("(%d) Cannot open v4l device (%s): %s\n", this->video_fd, + entry->str_value, strerror(errno)); + return 0; + } + DBGPRINT("Device opened, tv %d\n", this->video_fd); + + /* Get capabilities */ + if (ioctl(this->video_fd,VIDIOCGCAP,&this->video_cap) < 0) { + DBGPRINT ("VIDIOCGCAP ioctl went wrong\n"); + return 0; + } + + if (!(this->video_cap.type & VID_TYPE_CAPTURE)) { + /* Capture is not supported by the device. This is a must though! */ + DBGPRINT("Grab device does not handle capture\n"); + return 0; + } + + /* figure out the resolution */ + for (j = 0; j < NUM_RESOLUTIONS; j++) + { if (resolutions[j].width <= this->video_cap.maxwidth - && resolutions[j].height <= this->video_cap.maxheight - && resolutions[j].width <= MAX_RES) - { - found = 1; - break; - } - } - - if (found == 0 || resolutions[j].width < this->video_cap.minwidth - || resolutions[j].height < this->video_cap.minheight) - { + && resolutions[j].height <= this->video_cap.maxheight + && resolutions[j].width <= MAX_RES) + { + found = 1; + break; + } + } + + if (found == 0 || resolutions[j].width < this->video_cap.minwidth + || resolutions[j].height < this->video_cap.minheight) + { /* Looks like the device does not support one of the preset resolutions */ DBGPRINT("Grab device does not support any preset resolutions"); return 0; - } + } - _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_WIDTH, resolutions[j].width); - _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_HEIGHT, resolutions[j].height); - _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_CHANNELS, periods); - _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_BITS, bits); - _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_SAMPLERATE, rate); - _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_AUDIO, 1); - _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_VIDEO, 1); - - /* - * Pre allocate some frames for audio and video. This way this hasn't to be - * done during capture. - */ - for (i=0; idecoder_info[0] = resolutions[j].width; - frame->decoder_info[1] = resolutions[j].height; - frame->content = - xine_xmalloc (frame->decoder_info[0] * frame->decoder_info[1] * 3 / 2); - frame->type = BUF_VIDEO_YUV_FRAMES; - frame->source = this; - frame->free_buffer = store_vid_frame; - frame->extra_info = xine_xmalloc(sizeof(extra_info_t)); - - store_vid_frame(frame); - - /* Audio frame */ - frame = xine_xmalloc (sizeof (buf_element_t)); - - frame->decoder_info[1] = periodsize; - frame->content = xine_xmalloc(periodsize); - frame->type = BUF_AUDIO_RAWPCM; - frame->source = this; - frame->free_buffer = store_aud_frame; - frame->extra_info = xine_xmalloc(sizeof(extra_info_t)); - - store_aud_frame(frame); - } - - /* Unmute audio off video capture device */ - ioctl(this->video_fd, VIDIOCGAUDIO, &this->audio); - memcpy(&this->audio_saved, &this->audio, sizeof(this->audio)); - this->audio.flags &= ~VIDEO_AUDIO_MUTE; - this->audio.volume=0xD000; - DBGPRINT("Setting audio volume\r\n"); - ioctl(this->video_fd, VIDIOCSAUDIO, &this->audio); - - if (strlen(this->tuner_name) > 0) { - /* Tune into source and given frequency */ - if (set_input_source(this, this->tuner_name) <= 0) - return 0; - else - tuner_found = 1; - } - - set_frequency(this, this->frequency); - - /* Test for mmap video access */ - ret = ioctl(this->video_fd,VIDIOCGMBUF, &this->gb_buffers); - - if (ret < 0) { - /* Device driver does not support mmap */ - /* try to use read based access */ - struct video_picture pict; - int val; - - ioctl(this->video_fd, VIDIOCGPICT, &pict); - - /* try to choose a suitable video format */ - pict.palette=VIDEO_PALETTE_YUV420P; - ret = ioctl(this->video_fd, VIDIOCSPICT, &pict); - if (ret < 0) { - pict.palette=VIDEO_PALETTE_YUV422; - ret = ioctl(this->video_fd, VIDIOCSPICT, &pict); - if (ret < 0) { - close (this->video_fd); - this->video_fd = -1; - DBGPRINT("Grab: no colorspace format found\n"); - return 0; - } - else - DBGPRINT("Grab: format YUV 4:2:2\n"); - } - else - DBGPRINT("input_v4l: grab: format YUV 4:2:0\n"); + _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_WIDTH, resolutions[j].width); + _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_HEIGHT, resolutions[j].height); + _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_CHANNELS, this->periods); + _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_BITS, this->bits); + _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_SAMPLERATE, this->rate); + _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_AUDIO, 1); + _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_VIDEO, 1); + + /* + * Pre allocate some frames for audio and video. This way this hasn't to be + * done during capture. + */ + for (i = 0; i < NUM_FRAMES; i++) { + buf_element_t *frame; - this->frame_format = pict.palette; - - val = 1; - ioctl(this->video_fd, VIDIOCCAPTURE, &val); - - this->use_mmap = 0; - - } else { - /* Good, device driver support mmap. Mmap the memory */ - DBGPRINT("input_v4l: using mmap, size %d\n", this->gb_buffers.size); - this->video_buf = mmap(0, this->gb_buffers.size, - PROT_READ|PROT_WRITE, MAP_SHARED, - this->video_fd,0); - if ((unsigned char*)-1 == this->video_buf) { - /* mmap failed. */; - perror("mmap"); - close (this->video_fd); - return 0; - } - this->gb_frame = 0; - - /* start to grab the first frame */ - this->gb_buf.frame = (this->gb_frame + 1) % this->gb_buffers.frames; - this->gb_buf.height = resolutions[j].height; - this->gb_buf.width = resolutions[j].width; - this->gb_buf.format = VIDEO_PALETTE_YUV420P; - - ret = ioctl(this->video_fd, VIDIOCMCAPTURE, &this->gb_buf); - if (ret < 0 && errno != EAGAIN) { - /* try YUV422 */ - this->gb_buf.format = VIDEO_PALETTE_YUV422; - - ret = ioctl(this->video_fd, VIDIOCMCAPTURE, &this->gb_buf); + /* Video frame */ + frame = xine_xmalloc (sizeof (buf_element_t)); + + frame->decoder_info[0] = resolutions[j].width; + frame->decoder_info[1] = resolutions[j].height; + frame->content = xine_xmalloc (frame->decoder_info[0] * frame->decoder_info[1] * 3 / 2); + frame->type = BUF_VIDEO_YUV_FRAMES; + frame->source = this; + frame->free_buffer = store_vid_frame; + frame->extra_info = xine_xmalloc(sizeof(extra_info_t)); + + store_vid_frame(frame); + + /* Audio frame */ + frame = xine_xmalloc (sizeof (buf_element_t)); + + frame->decoder_info[1] = this->periodsize; + frame->content = xine_xmalloc(this->periodsize); + frame->type = BUF_AUDIO_RAWPCM; + frame->source = this; + frame->free_buffer = store_aud_frame; + frame->extra_info = xine_xmalloc(sizeof(extra_info_t)); + + store_aud_frame(frame); + } + + /* Unmute audio off video capture device */ + ioctl(this->video_fd, VIDIOCGAUDIO, &this->audio); + memcpy(&this->audio_saved, &this->audio, sizeof(this->audio)); + + this->audio.flags &= ~VIDEO_AUDIO_MUTE; + this->audio.volume = 0xD000; + + DBGPRINT("Setting audio volume\r\n"); + ioctl(this->video_fd, VIDIOCSAUDIO, &this->audio); + + if (strlen(this->tuner_name) > 0) { + /* Tune into source and given frequency */ + if (set_input_source(this, this->tuner_name) <= 0) + return 0; + else + tuner_found = 1; + } + + set_frequency(this, this->frequency); + + /* Test for mmap video access */ + ret = ioctl(this->video_fd,VIDIOCGMBUF, &this->gb_buffers); + + if (ret < 0) { + /* Device driver does not support mmap */ + /* try to use read based access */ + struct video_picture pict; + int val; + + ioctl(this->video_fd, VIDIOCGPICT, &pict); + + /* try to choose a suitable video format */ + pict.palette = VIDEO_PALETTE_YUV420P; + ret = ioctl(this->video_fd, VIDIOCSPICT, &pict); + if (ret < 0) { + pict.palette = VIDEO_PALETTE_YUV422; + ret = ioctl(this->video_fd, VIDIOCSPICT, &pict); + if (ret < 0) { + close (this->video_fd); + this->video_fd = -1; + DBGPRINT("Grab: no colorspace format found\n"); + return 0; } else - DBGPRINT("(%d) input_v4l: YUV420 should work\n", ret); + DBGPRINT("Grab: format YUV 4:2:2\n"); + } + else + DBGPRINT("input_v4l: grab: format YUV 4:2:0\n"); + + this->frame_format = pict.palette; + val = 1; + ioctl(this->video_fd, VIDIOCCAPTURE, &val); + + this->use_mmap = 0; + + } else { + /* Good, device driver support mmap. Mmap the memory */ + DBGPRINT("input_v4l: using mmap, size %d\n", this->gb_buffers.size); + this->video_buf = mmap(0, this->gb_buffers.size, + PROT_READ|PROT_WRITE, MAP_SHARED, + this->video_fd,0); + if ((unsigned char*)-1 == this->video_buf) { + /* mmap failed. */; + perror("mmap"); + close (this->video_fd); + return 0; + } + this->gb_frame = 0; + + /* start to grab the first frame */ + this->gb_buf.frame = (this->gb_frame + 1) % this->gb_buffers.frames; + this->gb_buf.height = resolutions[j].height; + this->gb_buf.width = resolutions[j].width; + this->gb_buf.format = VIDEO_PALETTE_YUV420P; + + ret = ioctl(this->video_fd, VIDIOCMCAPTURE, &this->gb_buf); + if (ret < 0 && errno != EAGAIN) { + /* try YUV422 */ + this->gb_buf.format = VIDEO_PALETTE_YUV422; - if (ret < 0) { - if (errno != EAGAIN) { - DBGPRINT( - "input_v4l: grab device does not support suitable format\n"); - } else { - DBGPRINT( - "input_v4l: grab device does not receive any video signal\n"); - } - close (this->video_fd); - return 0; + ret = ioctl(this->video_fd, VIDIOCMCAPTURE, &this->gb_buf); + } + else + DBGPRINT("(%d) input_v4l: YUV420 should work\n", ret); + + if (ret < 0) { + if (errno != EAGAIN) { + DBGPRINT( + "input_v4l: grab device does not support suitable format\n"); + } else { + DBGPRINT( + "input_v4l: grab device does not receive any video signal\n"); } - this->frame_format = this->gb_buf.format; - this->use_mmap = 1; - } - - switch(this->frame_format) { - case VIDEO_PALETTE_YUV420P: - this->frame_size = - (resolutions[j].width * resolutions[j].height * 3) / 2; - break; - case VIDEO_PALETTE_YUV422: - this->frame_size = resolutions[j].width * resolutions[j].height * 2; - break; - } - - /* Save dimensions */ - _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_WIDTH, resolutions[j].width); - _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_HEIGHT, resolutions[j].height); - - /* Using deinterlaceing is highly recommended. Setting to true */ - this->old_interlace = - xine_get_param(this->stream, XINE_PARAM_VO_DEINTERLACE); - xine_set_param(this->stream, XINE_PARAM_VO_DEINTERLACE, 1); - - /* Strip the vbi / sync signal from the image by zooming in */ - this->old_zoomx = xine_get_param(this->stream, XINE_PARAM_VO_ZOOM_X); - this->old_zoomy = xine_get_param(this->stream, XINE_PARAM_VO_ZOOM_Y); - - xine_set_param(this->stream, XINE_PARAM_VO_ZOOM_X, 103); - xine_set_param(this->stream, XINE_PARAM_VO_ZOOM_Y, 103); - - /* If we made it here, everything went ok */ - this->audio_only = 0; - if (tuner_found) - return 1; - else - /* Not a real error, appart that the tuner name is unknown to us */ - return 2; + close (this->video_fd); + return 0; + } + this->frame_format = this->gb_buf.format; + this->use_mmap = 1; + } + + switch(this->frame_format) { + case VIDEO_PALETTE_YUV420P: + this->frame_size = (resolutions[j].width * resolutions[j].height * 3) / 2; + break; + case VIDEO_PALETTE_YUV422: + this->frame_size = resolutions[j].width * resolutions[j].height * 2; + break; + } + + /* Save dimensions */ + _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_WIDTH, resolutions[j].width); + _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_HEIGHT, resolutions[j].height); + + /* Using deinterlaceing is highly recommended. Setting to true */ + this->old_interlace = xine_get_param(this->stream, XINE_PARAM_VO_DEINTERLACE); + xine_set_param(this->stream, XINE_PARAM_VO_DEINTERLACE, 1); + + /* Strip the vbi / sync signal from the image by zooming in */ + this->old_zoomx = xine_get_param(this->stream, XINE_PARAM_VO_ZOOM_X); + this->old_zoomy = xine_get_param(this->stream, XINE_PARAM_VO_ZOOM_Y); + + xine_set_param(this->stream, XINE_PARAM_VO_ZOOM_X, 103); + xine_set_param(this->stream, XINE_PARAM_VO_ZOOM_Y, 103); + + /* If we made it here, everything went ok */ + this->audio_only = 0; + if (tuner_found) + return 1; + else + /* Not a real error, appart that the tuner name is unknown to us */ + return 2; } /** @@ -1045,126 +1035,119 @@ static int open_video_capture_device(v4l_input_plugin_t *this) static int open_audio_capture_device(v4l_input_plugin_t *this) { #ifdef HAVE_ALSA - DBGPRINT("Audio Opening PCM Device\n"); - /* Allocate the snd_pcm_hw_params_t structure on the stack. */ - snd_pcm_hw_params_alloca(&this->pcm_hwparams); - - /* Open the PCM device. */ - if (this->audio_only) { - /* Open the sound device in blocking mode if we are not capturing video, - * otherwise xine gets to many NULL bufs and doesn't seem to handle - * them correctly - */ - if (snd_pcm_open(&this->pcm_handle, this->pcm_name, this->pcm_stream, - 0) < 0) { - PRINT("Audio :( Error opening PCM device %s\n", this->pcm_name); - this->audio_capture = 0; - } - } else - if (snd_pcm_open(&this->pcm_handle, this->pcm_name, this->pcm_stream, - SND_PCM_NONBLOCK) < 0) { + DBGPRINT("Audio Opening PCM Device\n"); + /* Allocate the snd_pcm_hw_params_t structure on the stack. */ + snd_pcm_hw_params_alloca(&this->pcm_hwparams); + + /* Open the PCM device. */ + if (this->audio_only) { + /* Open the sound device in blocking mode if we are not capturing video, + * otherwise xine gets to many NULL bufs and doesn't seem to handle + * them correctly + */ + if (snd_pcm_open(&this->pcm_handle, this->pcm_name, this->pcm_stream, 0) < 0) { + PRINT("Audio :( Error opening PCM device %s\n", this->pcm_name); + this->audio_capture = 0; + } + } else + if (snd_pcm_open(&this->pcm_handle, this->pcm_name, + this->pcm_stream, SND_PCM_NONBLOCK) < 0) { /* Open the sound device in non blocking mode when capturing video data * too, otherwise we will loose videoframes because we keep on waiting * for an audio fragment */ DBGPRINT("Audio :( Error opening PCM device %s\n", this->pcm_name); this->audio_capture = 0; - } + } - /* Get parameters */ - if (this->audio_capture && - (snd_pcm_hw_params_any(this->pcm_handle, this->pcm_hwparams) < 0) - ) { - PRINT("Audio :( Can not configure this PCM device.\n"); - this->audio_capture = 0; - } - - /* Set access type */ - if (this->audio_capture && - (snd_pcm_hw_params_set_access(this->pcm_handle, this->pcm_hwparams, - SND_PCM_ACCESS_RW_INTERLEAVED) < 0) - ) { - PRINT("Audio :( Error setting acces.\n"); - this->audio_capture = 0; - } - - if (this->audio_capture) { - if (snd_pcm_hw_params_any(this->pcm_handle, this->pcm_hwparams) < 0) { - PRINT("Audio :( Broken configuration for this PCM: No config avail\n"); this->audio_capture = 0; - } - } - - if (this->audio_capture) { - snd_pcm_access_mask_t *mask = alloca(snd_pcm_access_mask_sizeof()); - snd_pcm_access_mask_none(mask); - snd_pcm_access_mask_set(mask, SND_PCM_ACCESS_MMAP_INTERLEAVED); - if (snd_pcm_hw_params_set_access_mask(this->pcm_handle, - this->pcm_hwparams, mask) < 0) { - PRINT("Audio :( Error setting access mask\n"); - this->audio_capture = 0; - } - } - - /* Set sample format */ - if (this->audio_capture && - (snd_pcm_hw_params_set_format(this->pcm_handle, this->pcm_hwparams, - SND_PCM_FORMAT_S16_LE) < 0) - ) { - PRINT("Audio :( Error setting format.\n"); - this->audio_capture = 0; - } - - /* Set sample rate */ - if (this->audio_capture) { - this->exact_rate = snd_pcm_hw_params_set_rate_near(this->pcm_handle, - this->pcm_hwparams, &rate, &this->dir); - if (this->dir != 0) { - PRINT("Audio :s The rate %d Hz is not supported by your hardware.\n", - rate); - PRINT("Audio :s ==> Using %d instead.\n", this->exact_rate); - } - } - - /* Set number of channels */ - if (this->audio_capture && - (snd_pcm_hw_params_set_channels(this->pcm_handle, - this->pcm_hwparams, 2) < 0)) { - PRINT("Audio :( Error setting channels.\n"); - this->audio_capture = 0; - } - - if (this->audio_capture && - (snd_pcm_hw_params_set_periods(this->pcm_handle, this->pcm_hwparams, - periods, 0) < 0)) { - PRINT("Audio :( Error setting periods.\n"); - this->audio_capture = 0; - } - - /* Set buffersize */ - if (this->audio_capture && - (snd_pcm_hw_params_set_buffer_size(this->pcm_handle, - this->pcm_hwparams, - (periodsize * periods) >> 2) < 0)) { - PRINT("Audio :( Error setting buffersize.\n"); - this->audio_capture = 0; - } - - /* Apply HW parameter settings */ - if (this->audio_capture && - (snd_pcm_hw_params(this->pcm_handle, this->pcm_hwparams) < 0)){ - PRINT("Audio :( Error Setting HW params.\n"); + /* Get parameters */ + if (this->audio_capture && + (snd_pcm_hw_params_any(this->pcm_handle, this->pcm_hwparams) < 0)) { + PRINT("Audio :( Can not configure this PCM device.\n"); + this->audio_capture = 0; + } + + /* Set access type */ + if (this->audio_capture && + (snd_pcm_hw_params_set_access(this->pcm_handle, this->pcm_hwparams, + SND_PCM_ACCESS_RW_INTERLEAVED) < 0)) { + PRINT("Audio :( Error setting acces.\n"); + this->audio_capture = 0; + } + + if (this->audio_capture) { + if (snd_pcm_hw_params_any(this->pcm_handle, this->pcm_hwparams) < 0) { + PRINT("Audio :( Broken configuration for this PCM: No config avail\n"); this->audio_capture = 0; + } + } + + if (this->audio_capture) { + snd_pcm_access_mask_t *mask = alloca(snd_pcm_access_mask_sizeof()); + + snd_pcm_access_mask_none(mask); + snd_pcm_access_mask_set(mask, SND_PCM_ACCESS_MMAP_INTERLEAVED); + if (snd_pcm_hw_params_set_access_mask(this->pcm_handle, this->pcm_hwparams, mask) < 0) { + PRINT("Audio :( Error setting access mask\n"); this->audio_capture = 0; - } - - if (this->audio_capture) { - DBGPRINT("Audio Allocating memory for PCM capture :%d\n", periodsize); - this->pcm_data = (unsigned char*) malloc(periodsize); - } else - this->pcm_data = NULL; - - DBGPRINT("Audio :) Device succesfully configured\r\n"); + } + } + + /* Set sample format */ + if (this->audio_capture && + (snd_pcm_hw_params_set_format(this->pcm_handle, + this->pcm_hwparams, SND_PCM_FORMAT_S16_LE) < 0)) { + PRINT("Audio :( Error setting format.\n"); + this->audio_capture = 0; + } + + /* Set sample rate */ + if (this->audio_capture) { + this->exact_rate = snd_pcm_hw_params_set_rate_near(this->pcm_handle, + this->pcm_hwparams, &this->rate, &this->dir); + if (this->dir != 0) { + PRINT("Audio :s The rate %d Hz is not supported by your hardware.\n", this->rate); + PRINT("Audio :s ==> Using %d instead.\n", this->exact_rate); + } + } + + /* Set number of channels */ + if (this->audio_capture && + (snd_pcm_hw_params_set_channels(this->pcm_handle, this->pcm_hwparams, 2) < 0)) { + PRINT("Audio :( Error setting channels.\n"); + this->audio_capture = 0; + } + + if (this->audio_capture && + (snd_pcm_hw_params_set_periods(this->pcm_handle, this->pcm_hwparams, this->periods, 0) < 0)) { + PRINT("Audio :( Error setting periods.\n"); + this->audio_capture = 0; + } + + /* Set buffersize */ + if (this->audio_capture && + (snd_pcm_hw_params_set_buffer_size(this->pcm_handle, + this->pcm_hwparams, + (this->periodsize * this->periods) >> 2) < 0)) { + PRINT("Audio :( Error setting buffersize.\n"); + this->audio_capture = 0; + } + + /* Apply HW parameter settings */ + if (this->audio_capture && + (snd_pcm_hw_params(this->pcm_handle, this->pcm_hwparams) < 0)) { + PRINT("Audio :( Error Setting HW params.\n"); + this->audio_capture = 0; + } + + if (this->audio_capture) { + DBGPRINT("Audio Allocating memory for PCM capture :%d\n", this->periodsize); + this->pcm_data = (unsigned char*) malloc(this->periodsize); + } else + this->pcm_data = NULL; + + DBGPRINT("Audio :) Device succesfully configured\r\n"); #endif - return 0; + return 0; } /** @@ -1175,117 +1158,112 @@ static int open_audio_capture_device(v4l_input_plugin_t *this) */ static int v4l_adjust_realtime_speed(v4l_input_plugin_t *this, fifo_buffer_t *fifo, int speed) { - int num_used, num_free; - int scr_tunning = this->scr_tunning; - - if (fifo == NULL) - return 0; + int num_used, num_free; + int scr_tunning = this->scr_tunning; - num_used = fifo->size(fifo); - num_free = NUM_FRAMES - num_used; - - if (!this->audio_only && num_used == 0 && scr_tunning != SCR_PAUSED) { - /* Buffer is empty, and we did not pause playback */ - report_progress(this->stream, SCR_PAUSED); + if (fifo == NULL) + return 0; + + num_used = fifo->size(fifo); + num_free = NUM_FRAMES - num_used; + + if (!this->audio_only && num_used == 0 && scr_tunning != SCR_PAUSED) { + /* Buffer is empty, and we did not pause playback */ + report_progress(this->stream, SCR_PAUSED); + + xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, + "Buffer is empty, pausing playback (used: %d, num_free: %d)\r\n", + num_used, num_free); + + this->stream->xine->clock->set_speed (this->stream->xine->clock, XINE_SPEED_PAUSE); + this->stream->xine->clock->set_option (this->stream->xine->clock, CLOCK_SCR_ADJUSTABLE, 0); + if (this->stream->audio_out != NULL) + this->stream->audio_out->set_property(this->stream->audio_out, AO_PROP_PAUSED, 2); + + this->scr_tunning = SCR_PAUSED; + /* pvrscr_speed_tunning(this->scr, 0.0); */ + + } else if (num_free <= 1 && scr_tunning != SCR_SKIP) { + this->scr_tunning = SCR_SKIP; + PRINT("Buffer full (used: %d, free: %d)\r\n", + num_used, num_free); + return 0; + } else if (scr_tunning == SCR_PAUSED) { + if (2 * num_used > num_free) { + /* Playback was paused, but we have normal buffer usage again */ + xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, + "Resuming playback (used: %d, free: %d)\r\n", num_used, num_free); - xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, - "Buffer is empty, pausing playback (used: %d, num_free: %d)\r\n", - num_used, num_free); + this->scr_tunning = 0; - this->stream->xine->clock->set_speed (this->stream->xine->clock, XINE_SPEED_PAUSE); - this->stream->xine->clock->set_option (this->stream->xine->clock, CLOCK_SCR_ADJUSTABLE, 0); + pvrscr_speed_tunning(this->scr, 1.0); + + this->stream->xine->clock->set_speed (this->stream->xine->clock, XINE_SPEED_NORMAL); + this->stream->xine->clock->set_option (this->stream->xine->clock, CLOCK_SCR_ADJUSTABLE, 1); if (this->stream->audio_out != NULL) - this->stream->audio_out->set_property(this->stream->audio_out, AO_PROP_PAUSED, 2); - - this->scr_tunning = SCR_PAUSED; -/* pvrscr_speed_tunning(this->scr, 0.0); */ - - } else - if (num_free <= 1 && scr_tunning != SCR_SKIP) { - this->scr_tunning = SCR_SKIP; - PRINT("Buffer full (used: %d, free: %d)\r\n", - num_used, num_free); - return 0; - } else - if (scr_tunning == SCR_PAUSED) { - if (2 * num_used > num_free) { - /* Playback was paused, but we have normal buffer usage again */ - xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, - "Resuming playback (used: %d, free: %d)\r\n", num_used, num_free); - - this->scr_tunning = 0; - - pvrscr_speed_tunning(this->scr, 1.0); - - this->stream->xine->clock->set_speed (this->stream->xine->clock, XINE_SPEED_NORMAL); - this->stream->xine->clock->set_option (this->stream->xine->clock, CLOCK_SCR_ADJUSTABLE, 1); - if (this->stream->audio_out != NULL) - this->stream->audio_out->set_property(this->stream->audio_out, AO_PROP_PAUSED, 0); - } - } else - if (scr_tunning == SCR_SKIP) { - if (num_used < 2 * num_free) { - DBGPRINT("Resuming from skipping (used: %d, free %d)\r\n", + this->stream->audio_out->set_property(this->stream->audio_out, AO_PROP_PAUSED, 0); + } + } else if (scr_tunning == SCR_SKIP) { + if (num_used < 2 * num_free) { + DBGPRINT("Resuming from skipping (used: %d, free %d)\r\n", num_used, num_free); - this->scr_tunning = 0; - } else { - return 0; - } - } else - if (speed == XINE_SPEED_NORMAL) { - if (num_used > 2 * num_free) - /* buffer used > 2/3. Increase playback speed to avoid buffer - * overrun */ - scr_tunning = +1; - else if (num_free > 2 * num_used) - /* Buffer used < 1/3. Decrease playback speed to avoid buffer - * underrun */ - scr_tunning = -1; - else if ((scr_tunning > 0 && num_free > num_used) || - (scr_tunning < 0 && num_used > num_free)) - /* Buffer usage is ok again. Set playback speed to normal */ - scr_tunning = 0; - - /* Check if speed adjustment should be changed */ - if (scr_tunning != this->scr_tunning) { - this->scr_tunning = scr_tunning; - xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, - "scr tunning = %d (used: %d, free: %d)\r\n", scr_tunning, num_used, num_free); - pvrscr_speed_tunning(this->scr, 1.0 + (0.01 * scr_tunning)); - } - } else - if (this->scr_tunning) { - /* Currently speed adjustment is on. But xine is not playing at normal - * speed, so there is no reason why we should try to adjust our playback - * speed - */ this->scr_tunning = 0; - - xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, - "scr tunning resetting (used: %d, free: %d\r\n", num_used, num_free); - - pvrscr_speed_tunning(this->scr, 1.0); - } - - return 1; + } else { + return 0; + } + } else if (speed == XINE_SPEED_NORMAL) { + if (num_used > 2 * num_free) + /* buffer used > 2/3. Increase playback speed to avoid buffer + * overrun */ + scr_tunning = +1; + else if (num_free > 2 * num_used) + /* Buffer used < 1/3. Decrease playback speed to avoid buffer + * underrun */ + scr_tunning = -1; + else if ((scr_tunning > 0 && num_free > num_used) || + (scr_tunning < 0 && num_used > num_free)) + /* Buffer usage is ok again. Set playback speed to normal */ + scr_tunning = 0; + + /* Check if speed adjustment should be changed */ + if (scr_tunning != this->scr_tunning) { + this->scr_tunning = scr_tunning; + xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, + "scr tunning = %d (used: %d, free: %d)\r\n", scr_tunning, num_used, num_free); + pvrscr_speed_tunning(this->scr, 1.0 + (0.01 * scr_tunning)); + } + } else if (this->scr_tunning) { + /* Currently speed adjustment is on. But xine is not playing at normal + * speed, so there is no reason why we should try to adjust our playback + * speed + */ + this->scr_tunning = 0; + + xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, + "scr tunning resetting (used: %d, free: %d\r\n", num_used, num_free); + + pvrscr_speed_tunning(this->scr, 1.0); + } + + return 1; } /** * Plugin read. * This function is not supported by the plugin. */ -static off_t v4l_plugin_read (input_plugin_t *this_gen, - char *buf, off_t len) { - DBGPRINT("Read not supported\r\n"); - return 0; +static off_t v4l_plugin_read (input_plugin_t *this_gen, char *buf, off_t len) { + DBGPRINT("Read not supported\r\n"); + return 0; } /** * Get time. * Gets a pts time value. */ -inline static int64_t get_time() { +inline static int64_t get_time(void) { struct timeval tv; + gettimeofday(&tv,NULL); return (int64_t) tv.tv_sec * 90000 + (int64_t) tv.tv_usec * 9 / 100; @@ -1296,137 +1274,135 @@ inline static int64_t get_time() { * Plugin read block * Reads one data block. This is either an audio frame or an video frame */ -static buf_element_t *v4l_plugin_read_block (input_plugin_t *this_gen, - fifo_buffer_t *fifo, off_t todo) +static buf_element_t *v4l_plugin_read_block (input_plugin_t *this_gen, fifo_buffer_t *fifo, off_t todo) { - v4l_input_plugin_t *this = (v4l_input_plugin_t *) this_gen; - buf_element_t *buf = NULL; - uint8_t *ptr; - static char video = 0; - int speed = this->stream->xine->clock->speed; + v4l_input_plugin_t *this = (v4l_input_plugin_t *) this_gen; + buf_element_t *buf = NULL; + uint8_t *ptr; + static char video = 0; + int speed = this->stream->xine->clock->speed; - v4l_event_handler(this); - - if (!this->audio_only) { - if (!v4l_adjust_realtime_speed(this, fifo, speed)) { - return NULL; - } - } - - if (!this->audio_only) - video = !video; - else - video = 0; - - DBGPRINT("%lld bytes...\n", todo); - - if (this->start_time == 0) - /* Create a start pts value */ - this->start_time = get_time(); /* this->stream->xine->clock->get_current_time(this->stream->xine->clock); */ - - if (video) { - /* Capture video */ - buf = alloc_vid_frame (this); - this->gb_buf.frame = this->gb_frame; - - DBGPRINT("input_v4l: VIDIOCMCAPTURE\n"); - - while (ioctl(this->video_fd, VIDIOCMCAPTURE, &this->gb_buf) < 0) { - DBGPRINT("Upper while loop\n"); - if (errno == EAGAIN) { - DBGPRINT("Cannot sync\n"); - continue; - } else { - perror("VIDIOCMCAPTURE"); - buf->free_buffer(buf); - return NULL; - } + v4l_event_handler(this); + + if (!this->audio_only) { + if (!v4l_adjust_realtime_speed(this, fifo, speed)) { + return NULL; + } + } + + if (!this->audio_only) + video = !video; + else + video = 0; + + DBGPRINT("%lld bytes...\n", todo); + + if (this->start_time == 0) + /* Create a start pts value */ + this->start_time = get_time(); /* this->stream->xine->clock->get_current_time(this->stream->xine->clock); */ + + if (video) { + /* Capture video */ + buf = alloc_vid_frame (this); + this->gb_buf.frame = this->gb_frame; + + DBGPRINT("input_v4l: VIDIOCMCAPTURE\n"); + + while (ioctl(this->video_fd, VIDIOCMCAPTURE, &this->gb_buf) < 0) { + DBGPRINT("Upper while loop\n"); + if (errno == EAGAIN) { + DBGPRINT("Cannot sync\n"); + continue; + } else { + perror("VIDIOCMCAPTURE"); + buf->free_buffer(buf); + return NULL; } - - this->gb_frame = (this->gb_frame + 1) % this->gb_buffers.frames; - - while (ioctl(this->video_fd, VIDIOCSYNC, &this->gb_frame) < 0 && - (errno == EAGAIN || errno == EINTR)) + } + + this->gb_frame = (this->gb_frame + 1) % this->gb_buffers.frames; + + while (ioctl(this->video_fd, VIDIOCSYNC, &this->gb_frame) < 0 && + (errno == EAGAIN || errno == EINTR)) { - DBGPRINT("Waiting for videosync\n"); + DBGPRINT("Waiting for videosync\n"); } - - /* printf ("grabbing frame #%d\n", frame_num); */ - - ptr = this->video_buf + this->gb_buffers.offsets[this->gb_frame]; - buf->pts = get_time(); /* this->stream->xine->clock->get_current_time(this->stream->xine->clock); */ - xine_fast_memcpy (buf->content, ptr, this->frame_size); - } + + /* printf ("grabbing frame #%d\n", frame_num); */ + + ptr = this->video_buf + this->gb_buffers.offsets[this->gb_frame]; + buf->pts = get_time(); /* this->stream->xine->clock->get_current_time(this->stream->xine->clock); */ + xine_fast_memcpy (buf->content, ptr, this->frame_size); + } #ifdef HAVE_ALSA - else if (this->audio_capture) { - - /* Record audio */ - - int pcmreturn; - if ((pcmreturn = snd_pcm_mmap_readi(this->pcm_handle, this->pcm_data, (periodsize)>> 2)) < 0) { - switch (pcmreturn) { - case -EAGAIN: - /* No data available at the moment */ - break; - case -EBADFD: /* PCM device in wrong state */ - PRINT("Audio :( PCM is not in the right state\n"); - break; - case -EPIPE: /* Buffer overrun */ - PRINT("Audio :( Buffer Overrun (lost some samples)\n"); - /* On buffer overrun we need to re prepare the capturing pcm device */ - snd_pcm_prepare(this->pcm_handle); - break; - case -ESTRPIPE: /* Suspend event */ - PRINT("Audio :( Suspend event occured\n"); - break; - default: /* Unknown */ - PRINT("Audio :o Unknown error code: %d\n", pcmreturn); - snd_pcm_prepare(this->pcm_handle); - } - } else { - /* Succesfully read audio data */ - if (rate != this->exact_rate) - PRINT("HELP: Should pass sample rate %d instead of %d\r\n", this->exact_rate, rate); - - if (this->pts_aud_start) - buf = alloc_aud_frame (this); - - /* We want the pts on the start of the sample. As the soundcard starts - * sampling a new sample as soon as the read function returned with a - * success we will save the current pts and assign the current pts to - * that sample when we read it - */ - - /* Assign start pts to sample */ - if (buf) - buf->pts = this->pts_aud_start; - - /* Save start pts */ - this->pts_aud_start = get_time(); /* this->stream->xine->clock->get_current_time(this->stream->xine->clock); */ - - if (!buf) - /* Skip first sample as we don't have a good pts for this one */ - return NULL; - - DBGPRINT("Audio: Data read: %d [%d, %d]. Pos: %d\r\n", - pcmreturn, (int) (*this->pcm_data), (int) (*(this->pcm_data + periodsize - 3)), - (int) this->curpos); - - - /* Tell decoder the number of bytes we have read */ - buf->decoder_info[0] = pcmreturn; - buf->type = BUF_AUDIO_RAWPCM; - - this->curpos++; - - xine_fast_memcpy(buf->content, this->pcm_data, periodsize); + else if (this->audio_capture) { + /* Record audio */ + int pcmreturn; + + if ((pcmreturn = snd_pcm_mmap_readi(this->pcm_handle, this->pcm_data, (this->periodsize)>> 2)) < 0) { + switch (pcmreturn) { + case -EAGAIN: + /* No data available at the moment */ + break; + case -EBADFD: /* PCM device in wrong state */ + PRINT("Audio :( PCM is not in the right state\n"); + break; + case -EPIPE: /* Buffer overrun */ + PRINT("Audio :( Buffer Overrun (lost some samples)\n"); + /* On buffer overrun we need to re prepare the capturing pcm device */ + snd_pcm_prepare(this->pcm_handle); + break; + case -ESTRPIPE: /* Suspend event */ + PRINT("Audio :( Suspend event occured\n"); + break; + default: /* Unknown */ + PRINT("Audio :o Unknown error code: %d\n", pcmreturn); + snd_pcm_prepare(this->pcm_handle); } - } + } else { + /* Succesfully read audio data */ + if (this->rate != this->exact_rate) + PRINT("HELP: Should pass sample rate %d instead of %d\r\n", this->exact_rate, this->rate); + + if (this->pts_aud_start) + buf = alloc_aud_frame (this); + + /* We want the pts on the start of the sample. As the soundcard starts + * sampling a new sample as soon as the read function returned with a + * success we will save the current pts and assign the current pts to + * that sample when we read it + */ + + /* Assign start pts to sample */ + if (buf) + buf->pts = this->pts_aud_start; + + /* Save start pts */ + this->pts_aud_start = get_time(); /* this->stream->xine->clock->get_current_time(this->stream->xine->clock); */ + + if (!buf) + /* Skip first sample as we don't have a good pts for this one */ + return NULL; + + DBGPRINT("Audio: Data read: %d [%d, %d]. Pos: %d\r\n", + pcmreturn, (int) (*this->pcm_data), (int) (*(this->pcm_data + this->periodsize - 3)), + (int) this->curpos); + + + /* Tell decoder the number of bytes we have read */ + buf->decoder_info[0] = pcmreturn; + buf->type = BUF_AUDIO_RAWPCM; + + this->curpos++; + + xine_fast_memcpy(buf->content, this->pcm_data, this->periodsize); + } + } #endif - - DBGPRINT("read block done\n"); - - return buf; + + DBGPRINT("read block done\n"); + + return buf; } /** @@ -1435,10 +1411,8 @@ static buf_element_t *v4l_plugin_read_block (input_plugin_t *this_gen, */ static off_t v4l_plugin_seek (input_plugin_t *this_gen, off_t offset, int origin) { v4l_input_plugin_t *this = (v4l_input_plugin_t *) this_gen; - - DBGPRINT("input_v4l: seek %lld bytes, origin %d\n", - offset, origin); - + + DBGPRINT("input_v4l: seek %lld bytes, origin %d\n", offset, origin); return this->curpos; } @@ -1447,12 +1421,11 @@ static off_t v4l_plugin_seek (input_plugin_t *this_gen, off_t offset, int origin * This is a live stream, and as such does not have an known end. */ static off_t v4l_plugin_get_length (input_plugin_t *this_gen) { - /* - v4l_input_plugin_t *this = (v4l_input_plugin_t *) this_gen; - off_t length; + v4l_input_plugin_t *this = (v4l_input_plugin_t *) this_gen; + off_t length; */ - + return -1; } @@ -1462,12 +1435,12 @@ static off_t v4l_plugin_get_length (input_plugin_t *this_gen) { */ static uint32_t v4l_plugin_get_capabilities (input_plugin_t *this_gen) { - v4l_input_plugin_t *this = (v4l_input_plugin_t *) this_gen; - - if (this->audio_only) - return 0x10; - else - return 0; /* 0x10: Has audio only. */ + v4l_input_plugin_t *this = (v4l_input_plugin_t *) this_gen; + + if (this->audio_only) + return 0x10; + else + return 0; /* 0x10: Has audio only. */ } /** @@ -1485,11 +1458,11 @@ static uint32_t v4l_plugin_get_blocksize (input_plugin_t *this_gen) */ static off_t v4l_plugin_get_current_pos (input_plugin_t *this_gen){ v4l_input_plugin_t *this = (v4l_input_plugin_t *) this_gen; - + /* - printf ("current pos is %lld\n", this->curpos); + printf ("current pos is %lld\n", this->curpos); */ - + return this->curpos; } @@ -1500,37 +1473,38 @@ static off_t v4l_plugin_get_current_pos (input_plugin_t *this_gen){ * without closing the v4l plugin. */ static void v4l_event_handler (v4l_input_plugin_t *this) { - xine_event_t *event; - - while ((event = xine_event_get (this->event_queue))) { - xine_set_v4l2_data_t *v4l2_data = event->data; - - switch (event->type) { - case XINE_EVENT_SET_V4L2: - if( v4l2_data->input != this->input || - v4l2_data->channel != this->channel || - v4l2_data->frequency != this->frequency ) { - this->input = v4l2_data->input; - this->channel = v4l2_data->channel; - this->frequency = v4l2_data->frequency; - - DBGPRINT("Switching to input:%d chan:%d freq:%.2f\n", - v4l2_data->input, - v4l2_data->channel, - (float)v4l2_data->frequency); - set_frequency(this, this->frequency); - - _x_demux_flush_engine(this->stream); - } - break; -/* default: - - DBGPRINT("Got an event, type 0x%08x\n", event->type); - */ + xine_event_t *event; + + while ((event = xine_event_get (this->event_queue))) { + xine_set_v4l2_data_t *v4l2_data = event->data; + + switch (event->type) { + case XINE_EVENT_SET_V4L2: + if( v4l2_data->input != this->input || + v4l2_data->channel != this->channel || + v4l2_data->frequency != this->frequency ) { + + this->input = v4l2_data->input; + this->channel = v4l2_data->channel; + this->frequency = v4l2_data->frequency; + + DBGPRINT("Switching to input:%d chan:%d freq:%.2f\n", + v4l2_data->input, + v4l2_data->channel, + (float)v4l2_data->frequency); + + set_frequency(this, this->frequency); + _x_demux_flush_engine(this->stream); } - - xine_event_free (event); - } + break; + /* default: + + DBGPRINT("Got an event, type 0x%08x\n", event->type); + */ + } + + xine_event_free (event); + } } /** @@ -1541,126 +1515,125 @@ static void v4l_event_handler (v4l_input_plugin_t *this) { */ static void v4l_plugin_dispose (input_plugin_t *this_gen) { v4l_input_plugin_t *this = (v4l_input_plugin_t *) this_gen; - + if(this->mrl) free(this->mrl); - + if (this->scr) { - this->stream->xine->clock->unregister_scr(this->stream->xine->clock, &this->scr->scr); - this->scr->scr.exit(&this->scr->scr); + this->stream->xine->clock->unregister_scr(this->stream->xine->clock, &this->scr->scr); + this->scr->scr.exit(&this->scr->scr); } - + /* Close and free video device */ if (this->tuner_name) free(this->tuner_name); - - /* Close video device only if device was openend */ - if (this->video_fd > 0) { - - /* Restore v4l audio volume */ - DBGPRINT("Video Restoring audio volume %d\r\n", - ioctl(this->video_fd, VIDIOCSAUDIO, &this->audio_saved)); - ioctl(this->video_fd, VIDIOCSAUDIO, &this->audio_saved); - - /* Unmap memory */ - if (this->video_buf != NULL && - munmap(this->video_buf, this->gb_buffers.size) != 0) { - PRINT("Video :( Could not unmap memory, reason: %s\r\n", - strerror(errno)); - } else - DBGPRINT("Video :) Succesfully unmapped memory (size %d)\r\n", + + /* Close video device only if device was openend */ + if (this->video_fd > 0) { + + /* Restore v4l audio volume */ + DBGPRINT("Video Restoring audio volume %d\r\n", + ioctl(this->video_fd, VIDIOCSAUDIO, &this->audio_saved)); + ioctl(this->video_fd, VIDIOCSAUDIO, &this->audio_saved); + + /* Unmap memory */ + if (this->video_buf != NULL && + munmap(this->video_buf, this->gb_buffers.size) != 0) { + PRINT("Video :( Could not unmap memory, reason: %s\r\n", + strerror(errno)); + } else + DBGPRINT("Video :) Succesfully unmapped memory (size %d)\r\n", this->gb_buffers.size); - - DBGPRINT("Video Closing video filehandler %d\r\n", this->video_fd); - - /* Now close the video device */ - if (close(this->video_fd) != 0) - PRINT("Video :( Error while closing video file handler, " - "reason: %s\r\n", strerror(errno)); - else - DBGPRINT("Video :) Device succesfully closed\r\n"); - - /* Restore interlace setting */ - xine_set_param(this->stream, XINE_PARAM_VO_DEINTERLACE, - this->old_interlace); - - /* Restore zoom setting */ - xine_set_param(this->stream, XINE_PARAM_VO_ZOOM_X, this->old_zoomx); - xine_set_param(this->stream, XINE_PARAM_VO_ZOOM_Y, this->old_zoomy); - } + + DBGPRINT("Video Closing video filehandler %d\r\n", this->video_fd); + + /* Now close the video device */ + if (close(this->video_fd) != 0) + PRINT("Video :( Error while closing video file handler, " + "reason: %s\r\n", strerror(errno)); + else + DBGPRINT("Video :) Device succesfully closed\r\n"); + + /* Restore interlace setting */ + xine_set_param(this->stream, XINE_PARAM_VO_DEINTERLACE, this->old_interlace); + + /* Restore zoom setting */ + xine_set_param(this->stream, XINE_PARAM_VO_ZOOM_X, this->old_zoomx); + xine_set_param(this->stream, XINE_PARAM_VO_ZOOM_Y, this->old_zoomy); + } + + if (this->radio_fd > 0) { + close(this->radio_fd); + } - if (this->radio_fd > 0) { - close(this->radio_fd); - } - #ifdef HAVE_ALSA - /* Close audio device */ - if (this->pcm_handle) { - snd_pcm_drop(this->pcm_handle); - snd_pcm_close(this->pcm_handle); - } - - if (this->pcm_data) { - free(this->pcm_data); - } - - if (this->pcm_name) { - free(this->pcm_name); - } + /* Close audio device */ + if (this->pcm_handle) { + snd_pcm_drop(this->pcm_handle); + snd_pcm_close(this->pcm_handle); + } + + if (this->pcm_data) { + free(this->pcm_data); + } + + if (this->pcm_name) { + free(this->pcm_name); + } #endif - - if (this->event_queue) - xine_event_dispose_queue (this->event_queue); - - DBGPRINT("Freeing allocated audio frames"); - if (this->aud_frames) { - buf_element_t *cur_frame = this->aud_frames; - buf_element_t *next_frame = NULL; - - while ((next_frame = cur_frame->next) != NULL) { + + if (this->event_queue) + xine_event_dispose_queue (this->event_queue); + + DBGPRINT("Freeing allocated audio frames"); + if (this->aud_frames) { + buf_element_t *cur_frame = this->aud_frames; + buf_element_t *next_frame = NULL; + + while ((next_frame = cur_frame->next) != NULL) { #ifdef LOG - printf("."); fflush(stdout); + printf("."); fflush(stdout); #endif - if (cur_frame->content) - free(cur_frame->content); - - if (cur_frame->extra_info) - free(cur_frame->extra_info); - - free(cur_frame); - cur_frame = next_frame; - } - } + if (cur_frame->content) + free(cur_frame->content); + + if (cur_frame->extra_info) + free(cur_frame->extra_info); + + free(cur_frame); + cur_frame = next_frame; + } + } #ifdef LOG - printf("\r\n"); + printf("\r\n"); #endif - - DBGPRINT("Freeing allocated video frames"); - if (this->vid_frames) { - buf_element_t *cur_frame = this->vid_frames; - buf_element_t *next_frame = NULL; - - while ((next_frame = cur_frame->next) != NULL) { + + DBGPRINT("Freeing allocated video frames"); + if (this->vid_frames) { + buf_element_t *cur_frame = this->vid_frames; + buf_element_t *next_frame = NULL; + + while ((next_frame = cur_frame->next) != NULL) { #ifdef LOG - printf("."); fflush(stdout); + printf("."); fflush(stdout); #endif - if (cur_frame->content) - free(cur_frame->content); - - if (cur_frame->extra_info) - free(cur_frame->extra_info); - - free(cur_frame); - cur_frame = next_frame; - } - } + if (cur_frame->content) + free(cur_frame->content); + + if (cur_frame->extra_info) + free(cur_frame->extra_info); + + free(cur_frame); + cur_frame = next_frame; + } + } #ifdef LOG - printf("\r\n"); + printf("\r\n"); #endif - - free (this); - - DBGPRINT("plugin Bye bye! \r\n"); + + free (this); + + DBGPRINT("plugin Bye bye! \r\n"); } /** @@ -1670,7 +1643,7 @@ static void v4l_plugin_dispose (input_plugin_t *this_gen) { */ static char* v4l_plugin_get_mrl (input_plugin_t *this_gen) { v4l_input_plugin_t *this = (v4l_input_plugin_t *) this_gen; - + return this->mrl; } @@ -1682,53 +1655,53 @@ static int v4l_plugin_get_optional_data (input_plugin_t *this_gen, } static int v4l_plugin_radio_open (input_plugin_t *this_gen) { - v4l_input_plugin_t *this = (v4l_input_plugin_t *) this_gen; - - if(open_radio_capture_device(this) != 1) - return 0; - - open_audio_capture_device(this); - + v4l_input_plugin_t *this = (v4l_input_plugin_t *) this_gen; + + if(open_radio_capture_device(this) != 1) + return 0; + + open_audio_capture_device(this); + #ifdef HAVE_ALSA - this->start_time = 0; - this->pts_aud_start = 0; - this->curpos = 0; - this->event_queue = xine_event_new_queue (this->stream); + this->start_time = 0; + this->pts_aud_start = 0; + this->curpos = 0; + this->event_queue = xine_event_new_queue (this->stream); #endif - - return 1; + + return 1; } static int v4l_plugin_video_open (input_plugin_t *this_gen) { - v4l_input_plugin_t *this = (v4l_input_plugin_t *) this_gen; - int64_t time; - - if(!open_video_capture_device(this)) - return 0; - - open_audio_capture_device(this); - + v4l_input_plugin_t *this = (v4l_input_plugin_t *) this_gen; + int64_t time; + + if(!open_video_capture_device(this)) + return 0; + + open_audio_capture_device(this); + #ifdef HAVE_ALSA - this->pts_aud_start = 0; + this->pts_aud_start = 0; #endif - this->start_time = 0; - this->curpos = 0; - - /* 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; - - /* enable resample method */ - this->stream->xine->config->update_num(this->stream->xine->config, "audio.av_sync_method", 1); - - this->event_queue = xine_event_new_queue (this->stream); - - return 1; + this->start_time = 0; + this->curpos = 0; + + /* 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; + + /* enable resample method */ + this->stream->xine->config->update_num(this->stream->xine->config, "audio.av_sync_method", 1); + + this->event_queue = xine_event_new_queue (this->stream); + + return 1; } /** @@ -1738,192 +1711,189 @@ static int v4l_plugin_video_open (input_plugin_t *this_gen) * does initialise the structure. */ static input_plugin_t *v4l_class_get_instance (input_class_t *cls_gen, - xine_stream_t *stream, const char *data) + xine_stream_t *stream, const char *data) { - char *locator = NULL; - - /* v4l_input_class_t *cls = (v4l_input_class_t *) cls_gen; */ - v4l_input_plugin_t *this; - char *mrl = strdup(data); - - /* Example mrl: v4l:/Television/62500 */ - - if (strncasecmp (mrl, "v4l:/", 5)) { - free (mrl); - return NULL; - } - - if (mrl != NULL) { - for (locator = mrl; *locator != '\0' && *locator != '/' ; locator++); - } else - PRINT("EUhmz, mrl was NULL?\r\n"); - - this = (v4l_input_plugin_t *) xine_xmalloc (sizeof (v4l_input_plugin_t)); - - extract_mrl(this, mrl); - - this->stream = stream; - this->mrl = mrl; - this->video_buf = NULL; - this->video_fd = -1; - this->radio_fd = -1; - this->event_queue = NULL; - this->scr = NULL; + /* v4l_input_class_t *cls = (v4l_input_class_t *) cls_gen; */ + v4l_input_plugin_t *this; + char *locator = NULL; + char *mrl = strdup(data); + + /* Example mrl: v4l:/Television/62500 */ + + if (strncasecmp (mrl, "v4l:/", 5)) { + free (mrl); + return NULL; + } + + if (mrl != NULL) { + for (locator = mrl; *locator != '\0' && *locator != '/' ; locator++); + } else + PRINT("EUhmz, mrl was NULL?\r\n"); + + this = (v4l_input_plugin_t *) xine_xmalloc (sizeof (v4l_input_plugin_t)); + + extract_mrl(this, mrl); + + this->stream = stream; + this->mrl = mrl; + this->video_buf = NULL; + this->video_fd = -1; + this->radio_fd = -1; + this->event_queue = NULL; + this->scr = NULL; #ifdef HAVE_ALSA - this->pcm_name = NULL; - this->pcm_data = NULL; - this->pcm_hwparams = NULL; - - /* Audio */ - this->pcm_stream = SND_PCM_STREAM_CAPTURE; - this->pcm_name = strdup("plughw:0,0"); - this->audio_capture = 1; + this->pcm_name = NULL; + this->pcm_data = NULL; + this->pcm_hwparams = NULL; + + /* Audio */ + this->pcm_stream = SND_PCM_STREAM_CAPTURE; + this->pcm_name = strdup("plughw:0,0"); + this->audio_capture = 1; #endif - - pthread_mutex_init (&this->aud_frames_lock, NULL); - pthread_cond_init (&this->aud_frame_freed, NULL); - - pthread_mutex_init (&this->vid_frames_lock, NULL); - pthread_cond_init (&this->vid_frame_freed, NULL); - - this->input_plugin.get_capabilities = v4l_plugin_get_capabilities; - this->input_plugin.read = v4l_plugin_read; - this->input_plugin.read_block = v4l_plugin_read_block; - this->input_plugin.seek = v4l_plugin_seek; - this->input_plugin.get_current_pos = v4l_plugin_get_current_pos; - this->input_plugin.get_length = v4l_plugin_get_length; - this->input_plugin.get_blocksize = v4l_plugin_get_blocksize; - this->input_plugin.get_mrl = v4l_plugin_get_mrl; - this->input_plugin.dispose = v4l_plugin_dispose; - this->input_plugin.get_optional_data = v4l_plugin_get_optional_data; - this->input_plugin.input_class = cls_gen; - - return &this->input_plugin; + this->rate = 44100; + this->periods = 2; + this->periodsize = 2 * 8192; + this->bits = 16; + + pthread_mutex_init (&this->aud_frames_lock, NULL); + pthread_cond_init (&this->aud_frame_freed, NULL); + + pthread_mutex_init (&this->vid_frames_lock, NULL); + pthread_cond_init (&this->vid_frame_freed, NULL); + + this->input_plugin.get_capabilities = v4l_plugin_get_capabilities; + this->input_plugin.read = v4l_plugin_read; + this->input_plugin.read_block = v4l_plugin_read_block; + this->input_plugin.seek = v4l_plugin_seek; + this->input_plugin.get_current_pos = v4l_plugin_get_current_pos; + this->input_plugin.get_length = v4l_plugin_get_length; + this->input_plugin.get_blocksize = v4l_plugin_get_blocksize; + this->input_plugin.get_mrl = v4l_plugin_get_mrl; + this->input_plugin.dispose = v4l_plugin_dispose; + this->input_plugin.get_optional_data = v4l_plugin_get_optional_data; + this->input_plugin.input_class = cls_gen; + + return &this->input_plugin; } static input_plugin_t *v4l_class_get_video_instance (input_class_t *cls_gen, - xine_stream_t *stream, const char *data) + xine_stream_t *stream, const char *data) { - int is_ok = 1; - cfg_entry_t* entry; - - v4l_input_plugin_t *this = NULL; + v4l_input_plugin_t *this = NULL; + int is_ok = 1; + cfg_entry_t *entry; - this = (v4l_input_plugin_t *) - v4l_class_get_instance (cls_gen, stream, data); - - if (this) - this->input_plugin.open = v4l_plugin_video_open; - else - return NULL; - - entry = this->stream->xine->config->lookup_entry( - this->stream->xine->config, "input.v4l_video_device_path"); - - /* Try to see if the MRL contains a v4l device we understand */ - if (is_ok) - extract_mrl(this, this->mrl); - - /* Try to open the video device */ - if (is_ok) - this->video_fd = open(entry->str_value, O_RDWR); - - if (is_ok && this->video_fd < 0) { - DBGPRINT("(%d) Cannot open v4l device: %s\n", this->video_fd, - strerror(errno)); - xine_log(this->stream->xine, XINE_LOG_MSG, - _("input_v4l: Sorry, could not open %s\n"), entry->str_value); - is_ok = 0; - } else - DBGPRINT("Device opened, tv %d\n", this->video_fd); - - /* Get capabilities */ - if (is_ok && ioctl(this->video_fd,VIDIOCGCAP,&this->video_cap) < 0) { - xine_log(this->stream->xine, XINE_LOG_MSG, - _("input_v4l: Sorry your v4l card doesn't support some features needed by xine\n")); - DBGPRINT ("VIDIOCGCAP ioctl went wrong\n"); - is_ok = 0;; - } - - if (is_ok && !(this->video_cap.type & VID_TYPE_CAPTURE)) { - /* Capture is not supported by the device. This is a must though! */ - xine_log(this->stream->xine, XINE_LOG_MSG, - _("input_v4l: Sorry, your v4l card doesn't support frame grabbing." - " This is needed by xine though\n")); - - DBGPRINT("Grab device does not handle capture\n"); - is_ok = 0; - } - - if (is_ok && set_input_source(this, this->tuner_name) <= 0) {\ - xine_log(this->stream->xine, XINE_LOG_MSG, - _("input_v4l: Could not locate the tuner name [%s] on your v4l card\n"), - this->tuner_name); - is_ok = 0; - } - - if (is_ok && this->video_fd > 0) { - close(this->video_fd); - this->video_fd = -1; - } - - if (!is_ok) { - v4l_plugin_dispose((input_plugin_t *) this); - return NULL; - } + this = (v4l_input_plugin_t *) v4l_class_get_instance (cls_gen, stream, data); - - return &this->input_plugin; + if (this) + this->input_plugin.open = v4l_plugin_video_open; + else + return NULL; + + entry = this->stream->xine->config->lookup_entry(this->stream->xine->config, "input.v4l_video_device_path"); + + /* Try to see if the MRL contains a v4l device we understand */ + if (is_ok) + extract_mrl(this, this->mrl); + + /* Try to open the video device */ + if (is_ok) + this->video_fd = open(entry->str_value, O_RDWR); + + if (is_ok && this->video_fd < 0) { + DBGPRINT("(%d) Cannot open v4l device: %s\n", this->video_fd, + strerror(errno)); + xine_log(this->stream->xine, XINE_LOG_MSG, + _("input_v4l: Sorry, could not open %s\n"), entry->str_value); + is_ok = 0; + } else + DBGPRINT("Device opened, tv %d\n", this->video_fd); + + /* Get capabilities */ + if (is_ok && ioctl(this->video_fd,VIDIOCGCAP,&this->video_cap) < 0) { + xine_log(this->stream->xine, XINE_LOG_MSG, + _("input_v4l: Sorry your v4l card doesn't support some features needed by xine\n")); + DBGPRINT ("VIDIOCGCAP ioctl went wrong\n"); + is_ok = 0;; + } + + if (is_ok && !(this->video_cap.type & VID_TYPE_CAPTURE)) { + /* Capture is not supported by the device. This is a must though! */ + xine_log(this->stream->xine, XINE_LOG_MSG, + _("input_v4l: Sorry, your v4l card doesn't support frame grabbing." + " This is needed by xine though\n")); + + DBGPRINT("Grab device does not handle capture\n"); + is_ok = 0; + } + + if (is_ok && set_input_source(this, this->tuner_name) <= 0) { + xine_log(this->stream->xine, XINE_LOG_MSG, + _("input_v4l: Could not locate the tuner name [%s] on your v4l card\n"), + this->tuner_name); + is_ok = 0; + } + + if (is_ok && this->video_fd > 0) { + close(this->video_fd); + this->video_fd = -1; + } + + if (!is_ok) { + v4l_plugin_dispose((input_plugin_t *) this); + return NULL; + } + + return &this->input_plugin; } static input_plugin_t *v4l_class_get_radio_instance (input_class_t *cls_gen, - xine_stream_t *stream, const char *data) + xine_stream_t *stream, const char *data) { - int is_ok = 1; - v4l_input_plugin_t *this = NULL; - cfg_entry_t* entry; - - if (strstr(data, "Radio") == NULL) - return NULL; - - this = (v4l_input_plugin_t *) - v4l_class_get_instance (cls_gen, stream, data); - - if (this) - this->input_plugin.open = v4l_plugin_radio_open; - else - return NULL; - - entry = this->stream->xine->config->lookup_entry( - this->stream->xine->config, "input.v4l_radio_device_path"); - - if (is_ok) - this->radio_fd = open(entry->str_value, O_RDWR); - - if (this->radio_fd < 0) { - xine_log(this->stream->xine, XINE_LOG_MSG, - _("input_v4l: Allthough normally we would be able to handle this MRL,\n" - "input_v4l: I am unable to open the radio device.[%s]\n"), - entry->str_value); - is_ok = 0; - } else - DBGPRINT("Device opened, radio %d\n", this->radio_fd); - - if (is_ok && set_input_source(this, this->tuner_name) <= 0) { - xine_log(this->stream->xine, XINE_LOG_MSG, - _("input_v4l: Sorry, you Radio device doesn't support this tunername\n")); - is_ok = 0; - } - - if (!is_ok) { - v4l_plugin_dispose((input_plugin_t *) this); - return NULL; - } + v4l_input_plugin_t *this = NULL; + int is_ok = 1; + cfg_entry_t *entry; - close(this->radio_fd); - - return &this->input_plugin; + if (strstr(data, "Radio") == NULL) + return NULL; + + this = (v4l_input_plugin_t *) v4l_class_get_instance (cls_gen, stream, data); + + if (this) + this->input_plugin.open = v4l_plugin_radio_open; + else + return NULL; + + entry = this->stream->xine->config->lookup_entry(this->stream->xine->config, "input.v4l_radio_device_path"); + + if (is_ok) + this->radio_fd = open(entry->str_value, O_RDWR); + + if (this->radio_fd < 0) { + xine_log(this->stream->xine, XINE_LOG_MSG, + _("input_v4l: Allthough normally we would be able to handle this MRL,\n" + "input_v4l: I am unable to open the radio device.[%s]\n"), + entry->str_value); + is_ok = 0; + } else + DBGPRINT("Device opened, radio %d\n", this->radio_fd); + + if (is_ok && set_input_source(this, this->tuner_name) <= 0) { + xine_log(this->stream->xine, XINE_LOG_MSG, + _("input_v4l: Sorry, you Radio device doesn't support this tunername\n")); + is_ok = 0; + } + + if (!is_ok) { + v4l_plugin_dispose((input_plugin_t *) this); + return NULL; + } + + close(this->radio_fd); + + return &this->input_plugin; } @@ -1939,7 +1909,6 @@ static char *v4l_class_get_radio_description (input_class_t *this_gen) { return _("v4l radio input plugin"); } - static char *v4l_class_get_identifier (input_class_t *this_gen) { return "v4l"; } @@ -1952,52 +1921,52 @@ static void v4l_class_dispose (input_class_t *this_gen) { static void *init_video_class (xine_t *xine, void *data) { - v4l_input_class_t *this; - config_values_t *config = xine->config; - - this = (v4l_input_class_t *) xine_xmalloc (sizeof (v4l_input_class_t)); - - this->xine = xine; - - this->input_class.get_instance = v4l_class_get_video_instance; - this->input_class.get_identifier = v4l_class_get_identifier; - this->input_class.get_description = v4l_class_get_video_description; - this->input_class.get_dir = NULL; - this->input_class.get_autoplay_list = NULL; - this->input_class.dispose = v4l_class_dispose; - this->input_class.eject_media = NULL; - - config->register_string (config, "input.v4l_video_device_path", - VIDEO_DEV, - _("path to the v4l video device"), - NULL, 10, NULL, NULL); - - return this; + v4l_input_class_t *this; + config_values_t *config = xine->config; + + this = (v4l_input_class_t *) xine_xmalloc (sizeof (v4l_input_class_t)); + + this->xine = xine; + + this->input_class.get_instance = v4l_class_get_video_instance; + this->input_class.get_identifier = v4l_class_get_identifier; + this->input_class.get_description = v4l_class_get_video_description; + this->input_class.get_dir = NULL; + this->input_class.get_autoplay_list = NULL; + this->input_class.dispose = v4l_class_dispose; + this->input_class.eject_media = NULL; + + config->register_string (config, "input.v4l_video_device_path", + VIDEO_DEV, + _("path to the v4l video device"), + NULL, 10, NULL, NULL); + + return this; } static void *init_radio_class (xine_t *xine, void *data) { - v4l_input_class_t *this; - config_values_t *config = xine->config; - - this = (v4l_input_class_t *) xine_xmalloc (sizeof (v4l_input_class_t)); + v4l_input_class_t *this; + config_values_t *config = xine->config; - this->xine = xine; - - this->input_class.get_instance = v4l_class_get_radio_instance; - this->input_class.get_identifier = v4l_class_get_identifier; - this->input_class.get_description = v4l_class_get_radio_description; - this->input_class.get_dir = NULL; - this->input_class.get_autoplay_list = NULL; - this->input_class.dispose = v4l_class_dispose; - this->input_class.eject_media = NULL; - - config->register_string (config, "input.v4l_radio_device_path", - RADIO_DEV, - _("path to the v4l radio device"), - NULL, 10, NULL, NULL); - - return this; + this = (v4l_input_class_t *) xine_xmalloc (sizeof (v4l_input_class_t)); + + this->xine = xine; + + this->input_class.get_instance = v4l_class_get_radio_instance; + this->input_class.get_identifier = v4l_class_get_identifier; + this->input_class.get_description = v4l_class_get_radio_description; + this->input_class.get_dir = NULL; + this->input_class.get_autoplay_list = NULL; + this->input_class.dispose = v4l_class_dispose; + this->input_class.eject_media = NULL; + + config->register_string (config, "input.v4l_radio_device_path", + RADIO_DEV, + _("path to the v4l radio device"), + NULL, 10, NULL, NULL); + + return this; } /* -- cgit v1.2.3