1 /*****************************************************************************
2 * dv.c: a decoder for DV video
3 *****************************************************************************
4 * Copyright (C) 2002 VideoLAN
5 * $Id: dv.c,v 1.3 2002/11/28 17:34:59 sam Exp $
7 * Authors: Samuel Hocevar <sam@zoy.org>
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
22 *****************************************************************************/
24 /*****************************************************************************
26 *****************************************************************************/
29 #include <vlc/decoder.h>
31 #undef vlc_error /*vlc_error is defined in the libdv headers, but not
32 * used in thes file */
33 #include <libdv/dv_types.h>
36 /*****************************************************************************
38 *****************************************************************************/
39 static int RunDecoder ( decoder_fifo_t * );
40 static int OpenDecoder ( vlc_object_t * );
42 static vlc_fourcc_t GetFourCC ( dv_sample_t );
44 /*****************************************************************************
46 *****************************************************************************/
48 set_description( _("DV video decoder") );
49 set_capability( "decoder", 70 );
50 set_callbacks( OpenDecoder, NULL );
53 /*****************************************************************************
54 * OpenDecoder: probe the decoder and return score
55 *****************************************************************************
56 * The fourcc format for DV is "dvsd"
57 *****************************************************************************/
58 static int OpenDecoder ( vlc_object_t *p_this )
60 decoder_fifo_t *p_fifo = (decoder_fifo_t*) p_this;
62 if( p_fifo->i_fourcc != VLC_FOURCC('d','v','s','d') )
67 p_fifo->pf_run = RunDecoder;
71 /*****************************************************************************
72 * RunDecoder: this function is called just after the thread is created
73 *****************************************************************************/
74 static int RunDecoder ( decoder_fifo_t *p_fifo )
77 pes_packet_t *p_pes = NULL;
81 bit_stream_t bit_stream;
82 dv_decoder_t * p_decoder;
83 vout_thread_t * p_vout;
85 p_buffer = malloc( i_data );
88 msg_Err( p_fifo, "out of memory" );
90 DecoderError( p_fifo );
94 p_decoder = dv_decoder_new( TRUE, FALSE, FALSE );
97 msg_Err( p_fifo, "cannot create DV decoder" );
100 DecoderError( p_fifo );
104 if( InitBitstream( &bit_stream, p_fifo, NULL, NULL ) != VLC_SUCCESS )
106 msg_Err( p_fifo, "cannot initialise bitstream" );
109 DecoderError( p_fifo );
113 /* Fill the buffer */
114 GetChunk( &bit_stream, p_buffer, i_data );
116 while( !p_fifo->b_die && !p_fifo->b_error )
118 /* Parsing the beginning of the stream */
119 if( dv_parse_header( p_decoder, p_buffer ) < 0 )
121 fprintf(stderr, "parse error\n");
126 if( dv_format_wide( p_decoder ) )
128 msg_Dbg( p_fifo, "aspect is 4:3" );
129 i_aspect = VOUT_ASPECT_FACTOR * 4 / 3;
131 else if( dv_format_normal( p_decoder ) )
133 msg_Dbg( p_fifo, "aspect is 16:9" );
134 i_aspect = VOUT_ASPECT_FACTOR * 4/3;//16 / 9;
138 msg_Dbg( p_fifo, "aspect is square pixels" );
139 i_aspect = VOUT_ASPECT_FACTOR
140 * p_decoder->width / p_decoder->height;
143 if( p_decoder->frame_size <= i_data )
145 /* XXX: what to do? */
146 i_data = p_decoder->frame_size;
150 p_buffer = realloc( p_buffer, p_decoder->frame_size );
153 /* Don't trust the sucker */
154 //p_decoder->quality = p_decoder->video->quality;
155 p_decoder->quality = DV_QUALITY_BEST;
156 p_decoder->prev_frame_decoded = 0;
158 /* Spawn a video output if there is none. First we look amongst our
159 * children, then we look for any other vout that might be available */
160 p_vout = vout_Request( p_fifo, NULL,
161 p_decoder->width, p_decoder->height,
162 GetFourCC( p_decoder->sampling ), i_aspect );
165 while( !p_fifo->b_die && !p_fifo->b_error )
169 GetChunk( &bit_stream, p_buffer + i_data,
170 p_decoder->frame_size - i_data );
171 i_data = p_decoder->frame_size;
175 input_DeletePES( p_fifo->p_packets_mgt, p_pes );
178 input_ExtractPES( p_fifo, &p_pes );
181 /* Don't trust the sucker */
182 //i_pts = p_pes->i_pts + DEFAULT_PTS_DELAY;
183 i_pts = mdate() + DEFAULT_PTS_DELAY;
186 if( p_fifo->b_die || p_fifo->b_error )
191 if( dv_parse_header( p_decoder, p_buffer ) > 0 )
193 fprintf(stderr, "size changed\n");
196 if( p_vout && ( !p_decoder->prev_frame_decoded
197 || dv_frame_changed( p_decoder ) ) )
203 while( !(p_pic = vout_CreatePicture( p_vout, 0, 0, 0 ) ) )
205 if( p_fifo->b_die || p_fifo->b_error )
209 msleep( VOUT_OUTMEM_SLEEP );
217 for( i = 0 ; i < p_pic->i_planes ; i++ )
219 pixels[i] = p_pic->p[i].p_pixels;
220 pitches[i] = p_pic->p[i].i_pitch;
223 dv_decode_full_frame( p_decoder, p_buffer,
224 e_dv_color_yuv, pixels, pitches );
225 p_decoder->prev_frame_decoded = 1;
227 vout_DatePicture( p_vout, p_pic, i_pts );
228 vout_DisplayPicture( p_vout, p_pic );
234 vout_Request( p_fifo, p_vout, 0, 0, 0, 0 );
239 input_DeletePES( p_fifo->p_packets_mgt, p_pes );
243 CloseBitstream( &bit_stream );
245 if( p_fifo->b_error )
247 DecoderError( p_fifo );
254 static vlc_fourcc_t GetFourCC( dv_sample_t x )
258 case e_dv_sample_411: return VLC_FOURCC('Y','U','Y','2');
259 case e_dv_sample_420: return VLC_FOURCC('Y','U','Y','2');
260 case e_dv_sample_422: return VLC_FOURCC('Y','U','Y','2');