diff options
author | James Stembridge <jstembridge@users.sourceforge.net> | 2004-03-10 22:46:17 +0000 |
---|---|---|
committer | James Stembridge <jstembridge@users.sourceforge.net> | 2004-03-10 22:46:17 +0000 |
commit | edab3101267300b22b84900c0e30dbf100f32ea9 (patch) | |
tree | c0e877df334e94eca9223f116b25d5b6f7e22cfa | |
parent | 47d841a93998622f35ccd7827ad3df0e634a5640 (diff) | |
download | xine-lib-edab3101267300b22b84900c0e30dbf100f32ea9.tar.gz xine-lib-edab3101267300b22b84900c0e30dbf100f32ea9.tar.bz2 |
Send headers so that the standard yuv and lpcm decoders can be used
CVS patchset: 6239
CVS date: 2004/03/10 22:46:17
-rw-r--r-- | src/demuxers/demux_yuv_frames.c | 22 | ||||
-rw-r--r-- | src/input/input_v4l.c | 121 |
2 files changed, 97 insertions, 46 deletions
diff --git a/src/demuxers/demux_yuv_frames.c b/src/demuxers/demux_yuv_frames.c index 5f4bbc565..42e3ec160 100644 --- a/src/demuxers/demux_yuv_frames.c +++ b/src/demuxers/demux_yuv_frames.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003 the xine project + * Copyright (C) 2003-2004 the xine project * Copyright (C) 2003 Jeroen Asselman <j.asselman@itsec-ps.nl> * * This file is part of xine, a free video player. @@ -20,7 +20,7 @@ */ /* - * $Id: demux_yuv_frames.c,v 1.14 2004/01/12 17:35:15 miguelfreitas Exp $ + * $Id: demux_yuv_frames.c,v 1.15 2004/03/10 22:46:18 jstembridge Exp $ * * dummy demultiplexer for raw yuv frames (delivered by v4l) */ @@ -87,11 +87,12 @@ static int switch_buf(demux_yuv_frames_t *this , buf_element_t *buf){ this->last_pts = buf->pts; switch (buf->type) { - case BUF_VIDEO_YUV_FRAMES: + case BUF_VIDEO_I420: + case BUF_VIDEO_YUY2: this->video_fifo->put(this->video_fifo, buf); result = 1; /* 1, we still should read audio */ break; - case BUF_AUDIO_RAWPCM: + case BUF_AUDIO_LPCM_LE: if (!_x_stream_info_get(this->stream, XINE_STREAM_INFO_HAS_VIDEO)) _x_demux_control_newpts(this->stream, buf->pts, 0); this->audio_fifo->put(this->audio_fifo, buf); @@ -120,10 +121,23 @@ static int demux_yuv_frames_send_chunk (demux_plugin_t *this_gen){ static void demux_yuv_frames_send_headers (demux_plugin_t *this_gen){ demux_yuv_frames_t *this = (demux_yuv_frames_t *) this_gen; + buf_element_t *buf; this->video_fifo = this->stream->video_fifo; this->audio_fifo = this->stream->audio_fifo; + if(_x_stream_info_get(this->stream, XINE_STREAM_INFO_HAS_AUDIO)) { + buf = this->input->read_block(this->input, this->audio_fifo, 0); + + this->audio_fifo->put(this->audio_fifo, buf); + } + + if(_x_stream_info_get(this->stream, XINE_STREAM_INFO_HAS_VIDEO)) { + buf = this->input->read_block(this->input, this->video_fifo, 0); + + this->video_fifo->put(this->video_fifo, buf); + } + this->status = DEMUX_OK; } diff --git a/src/input/input_v4l.c b/src/input/input_v4l.c index 9f56b975e..2789777f2 100644 --- a/src/input/input_v4l.c +++ b/src/input/input_v4l.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003 the xine project + * Copyright (C) 2003-2004 the xine project * Copyright (C) 2003 J.Asselman <j.asselman@itsec-ps.nl> * * This file is part of xine, a free video player. @@ -79,15 +79,17 @@ /* Our CPU can't handle de-interlacing at 768. */ #define MAX_RES 640 -static struct { +typedef struct { int width; int height; -} resolutions[] = { +} resolution_t; + +static const resolution_t resolutions[] = { { 768, 576 }, { 640, 480 }, { 384, 288 }, { 320, 240 }, - { 160, 120 }, + { 160, 120 } }; #define NUM_RESOLUTIONS (sizeof(resolutions)/sizeof(resolutions[0])) @@ -150,12 +152,14 @@ typedef struct { int64_t pts_aud_start; #endif + int audio_header_sent; + int rate; /* Sample rate */ int periods; /* Number of periods */ int periodsize; /* Periodsize in bytes */ int bits; -/* Video */ + /* Video */ buf_element_t *vid_frames; pthread_mutex_t vid_frames_lock; pthread_cond_t vid_frame_freed; @@ -178,7 +182,11 @@ typedef struct { struct video_audio audio; struct video_audio audio_saved; struct video_mbuf gb_buffers; + + int video_header_sent; + int frame_format; + const resolution_t *resolution; int frame_size; int use_mmap; uint8_t *video_buf; @@ -715,9 +723,8 @@ static void allocate_audio_frames(v4l_input_plugin_t *this) /* 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->type = BUF_AUDIO_LPCM_LE; frame->source = this; frame->free_buffer = store_aud_frame; frame->extra_info = xine_xmalloc(sizeof(extra_info_t)); @@ -768,9 +775,6 @@ static int open_radio_capture_device(v4l_input_plugin_t *this) 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); @@ -840,11 +844,8 @@ static int open_video_capture_device(v4l_input_plugin_t *this) 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, 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); + this->resolution = &resolutions[j]; + _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_AUDIO, 1); _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_VIDEO, 1); @@ -852,22 +853,6 @@ static int open_video_capture_device(v4l_input_plugin_t *this) * done during capture */ allocate_audio_frames(this); - for (i = 0; i < NUM_FRAMES; i++) { - buf_element_t *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); - } - /* Unmute audio off video capture device */ unmute_audio(this); @@ -961,16 +946,28 @@ static int open_video_capture_device(v4l_input_plugin_t *this) switch(this->frame_format) { case VIDEO_PALETTE_YUV420P: + this->frame_format = BUF_VIDEO_I420; this->frame_size = (resolutions[j].width * resolutions[j].height * 3) / 2; break; case VIDEO_PALETTE_YUV422: + this->frame_format = BUF_VIDEO_YUY2; 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); + for (i = 0; i < NUM_FRAMES; i++) { + buf_element_t *frame; + + frame = xine_xmalloc (sizeof (buf_element_t)); + + frame->content = xine_xmalloc (this->frame_size); + frame->type = this->frame_format; + frame->source = this; + frame->free_buffer = store_vid_frame; + frame->extra_info = xine_xmalloc(sizeof(extra_info_t)); + + store_vid_frame(frame); + } /* Using deinterlaceing is highly recommended. Setting to true */ this->old_interlace = xine_get_param(this->stream, XINE_PARAM_VO_DEINTERLACE); @@ -1235,6 +1232,47 @@ static buf_element_t *v4l_plugin_read_block (input_plugin_t *this_gen, fifo_buff v4l_event_handler(this); +#ifdef HAVE_ALSA + if (!this->audio_header_sent) { + lprintf("sending audio header\n"); + + buf = alloc_aud_frame (this); + + buf->size = 0; + buf->decoder_flags = BUF_FLAG_HEADER|BUF_FLAG_STDHEADER|BUF_FLAG_FRAME_END; + + buf->decoder_info[0] = 0; + buf->decoder_info[1] = this->exact_rate; + buf->decoder_info[2] = this->bits; + buf->decoder_info[3] = 2; + + this->audio_header_sent = 1; + + return buf; + } +#endif + + if (!this->audio_only && !this->video_header_sent) { + xine_bmiheader bih; + + lprintf("sending video header"); + + bih.biSize = sizeof(xine_bmiheader); + bih.biWidth = this->resolution->width; + bih.biHeight = this->resolution->height; + + buf = alloc_vid_frame (this); + + buf->size = sizeof(xine_bmiheader); + buf->decoder_flags = BUF_FLAG_HEADER|BUF_FLAG_STDHEADER|BUF_FLAG_FRAME_END; + + memcpy(buf->content, &bih, sizeof(xine_bmiheader)); + + this->video_header_sent = 1; + + return buf; + } + if (!this->audio_only) { if (!v4l_adjust_realtime_speed(this, fifo, speed)) { return NULL; @@ -1255,6 +1293,8 @@ static buf_element_t *v4l_plugin_read_block (input_plugin_t *this_gen, fifo_buff if (video) { /* Capture video */ buf = alloc_vid_frame (this); + buf->decoder_flags = BUF_FLAG_FRAME_START|BUF_FLAG_FRAME_END; + this->gb_buf.frame = this->gb_frame; lprintf("VIDIOCMCAPTURE\n"); @@ -1316,13 +1356,11 @@ static buf_element_t *v4l_plugin_read_block (input_plugin_t *this_gen, fifo_buff } } else { /* Succesfully read audio data */ - if (this->rate != this->exact_rate) - xprintf(this->stream->xine, XINE_VERBOSITY_LOG, - "input_v4l: HELP: Should pass sample rate %d instead of %d\n", - this->exact_rate, this->rate); - if (this->pts_aud_start) + if (this->pts_aud_start) { buf = alloc_aud_frame (this); + buf->decoder_flags = 0; + } /* 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 @@ -1347,12 +1385,11 @@ static buf_element_t *v4l_plugin_read_block (input_plugin_t *this_gen, fifo_buff /* Tell decoder the number of bytes we have read */ - buf->decoder_info[0] = pcmreturn; - buf->type = BUF_AUDIO_RAWPCM; + buf->size = pcmreturn<<2; this->curpos++; - xine_fast_memcpy(buf->content, this->pcm_data, this->periodsize); + xine_fast_memcpy(buf->content, this->pcm_data, buf->size); } } #endif |