Commit 6b9376db authored by Sam Hocevar's avatar Sam Hocevar

* ./modules/codec/dv/dv.c: decoder for the DV format, uses libdv.

parent ec435327
......@@ -98,6 +98,7 @@ beos_LDFLAGS = @beos_LDFLAGS@
i420_rgb_LDFLAGS = @i420_rgb_LDFLAGS@
directx_LDFLAGS = @directx_LDFLAGS@
dsp_LDFLAGS = @dsp_LDFLAGS@
dv_LDFLAGS = @dv_LDFLAGS@
dvd_LDFLAGS = @dvd_LDFLAGS@
dvdread_LDFLAGS = @dvdread_LDFLAGS@
dvdplay_LDFLAGS = @dvdplay_LDFLAGS@
......
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -1135,6 +1135,19 @@ then
],[])
fi
dnl
dnl DV plugin
dnl
AC_ARG_ENABLE(dv,
[ --enable-dv DV decoder support (default disabled)])
if test "x${enable_dv}" = "xyes"
then
AC_CHECK_HEADERS(libdv/dv.h, [
BUILTINS="${BUILTINS} codec/dv/dv"
dv_LDFLAGS="${dv_LDFLAGS} -ldv"
],[])
fi
dnl
dnl Video plugins
dnl
......@@ -1933,6 +1946,7 @@ AC_SUBST(beos_LDFLAGS)
AC_SUBST(i420_rgb_LDFLAGS)
AC_SUBST(directx_LDFLAGS)
AC_SUBST(dsp_LDFLAGS)
AC_SUBST(dv_LDFLAGS)
AC_SUBST(dvd_LDFLAGS)
AC_SUBST(dvdread_LDFLAGS)
AC_SUBST(dvdplay_LDFLAGS)
......
/* include/defs.h.in. Generated automatically from configure.in by autoheader 2.13. */
/* include/defs.h.in. Generated automatically from configure.in by autoheader. */
/* Define if using alloca.c. */
#undef C_ALLOCA
......@@ -235,6 +235,9 @@
/* Define if you have the <kernel/scheduler.h> header file. */
#undef HAVE_KERNEL_SCHEDULER_H
/* Define if you have the <libdv/dv.h> header file. */
#undef HAVE_LIBDV_DV_H
/* Define if you have the <limits.h> header file. */
#undef HAVE_LIMITS_H
......
.dep
*.lo
*.o.*
*.lo.*
/*****************************************************************************
* dv.c: a decoder for DV video
*****************************************************************************
* Copyright (C) 2002 VideoLAN
* $Id: dv.c,v 1.1 2002/08/05 15:16:18 sam Exp $
*
* Authors: Samuel Hocevar <sam@zoy.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
/*****************************************************************************
* Preamble
*****************************************************************************/
#include <vlc/vlc.h>
#include <vlc/vout.h>
#include <vlc/decoder.h>
#include <libdv/dv_types.h>
#include <libdv/dv.h>
/*****************************************************************************
* Local prototypes
*****************************************************************************/
static int RunDecoder ( decoder_fifo_t * );
static int OpenDecoder ( vlc_object_t * );
static u32 GetFourCC ( dv_sample_t );
static pes_packet_t *GetFirstPES( decoder_fifo_t * );
/*****************************************************************************
* Module descriptor
*****************************************************************************/
vlc_module_begin();
set_description( _("DV video decoder") );
set_capability( "decoder", 70 );
set_callbacks( OpenDecoder, NULL );
vlc_module_end();
/*****************************************************************************
* OpenDecoder: probe the decoder and return score
*****************************************************************************
* The fourcc format for DV is "dvsd"
*****************************************************************************/
static int OpenDecoder ( vlc_object_t *p_this )
{
decoder_fifo_t *p_fifo = (decoder_fifo_t*) p_this;
if( p_fifo->i_fourcc != VLC_FOURCC('d','v','s','d') )
{
return VLC_EGENERIC;
}
p_fifo->pf_run = RunDecoder;
return VLC_SUCCESS;
}
/*****************************************************************************
* RunDecoder: this function is called just after the thread is created
*****************************************************************************/
static int RunDecoder ( decoder_fifo_t *p_fifo )
{
u8 *p_buffer;
int i_data = 120000;
int i_aspect;
bit_stream_t bit_stream;
dv_decoder_t * p_decoder;
vout_thread_t * p_vout;
p_buffer = malloc( i_data );
if( !p_buffer )
{
msg_Err( p_fifo, "out of memory" );
p_fifo->b_error = 1;
DecoderError( p_fifo );
return -1;
}
p_decoder = dv_decoder_new( TRUE, FALSE, FALSE );
if( !p_decoder )
{
msg_Err( p_fifo, "cannot create DV decoder" );
free( p_buffer );
p_fifo->b_error = 1;
DecoderError( p_fifo );
return -1;
}
InitBitstream( &bit_stream, p_fifo, NULL, NULL );
/* Fill the buffer */
GetChunk( &bit_stream, p_buffer, i_data );
while( !p_fifo->b_die && !p_fifo->b_error )
{
/* Parsing the beginning of the stream */
if( dv_parse_header( p_decoder, p_buffer ) < 0 )
{
fprintf(stderr, "parse error\n");
p_fifo->b_error = 1;
break;
}
if( dv_format_wide( p_decoder ) )
{
msg_Dbg( p_fifo, "aspect is 4:3" );
i_aspect = VOUT_ASPECT_FACTOR * 4 / 3;
}
else if( dv_format_normal( p_decoder ) )
{
msg_Dbg( p_fifo, "aspect is 16:9" );
i_aspect = VOUT_ASPECT_FACTOR * 4/3;//16 / 9;
}
else
{
msg_Dbg( p_fifo, "aspect is square pixels" );
i_aspect = VOUT_ASPECT_FACTOR
* p_decoder->width / p_decoder->height;
}
if( p_decoder->frame_size <= i_data )
{
/* XXX: what to do? */
i_data = p_decoder->frame_size;
}
else
{
p_buffer = realloc( p_buffer, p_decoder->frame_size );
}
/* Don't trust the sucker */
//p_decoder->quality = p_decoder->video->quality;
p_decoder->quality = DV_QUALITY_BEST;
p_decoder->prev_frame_decoded = 0;
/* Spawn a video output if there is none. First we look amongst our
* children, then we look for any other vout that might be available */
p_vout = vlc_object_find( p_fifo, VLC_OBJECT_VOUT, FIND_CHILD );
if( !p_vout )
{
p_vout = vlc_object_find( p_fifo, VLC_OBJECT_VOUT, FIND_ANYWHERE );
}
if( p_vout )
{
if( p_vout->render.i_width != p_decoder->width
|| p_vout->render.i_height != p_decoder->height
|| p_vout->render.i_chroma != GetFourCC( p_decoder->sampling )
|| p_vout->render.i_aspect != i_aspect )
{
/* We are not interested in this format, close this vout */
vlc_object_detach_all( p_vout );
vlc_object_release( p_vout );
vout_DestroyThread( p_vout );
p_vout = NULL;
}
else
{
/* This video output is cool! Hijack it. */
vlc_object_detach_all( p_vout );
vlc_object_attach( p_vout, p_fifo );
vlc_object_release( p_vout );
}
}
if( !p_vout )
{
msg_Dbg( p_fifo, "no vout present, spawning one" );
p_vout = vout_CreateThread( p_fifo,
p_decoder->width, p_decoder->height,
GetFourCC( p_decoder->sampling ),
i_aspect );
}
/* Main loop */
while( !p_fifo->b_die && !p_fifo->b_error )
{
mtime_t i_pts = 0;
pes_packet_t *p_pes;
GetChunk( &bit_stream, p_buffer + i_data,
p_decoder->frame_size - i_data );
i_data = p_decoder->frame_size;
p_pes = GetFirstPES( p_fifo );
if( p_pes )
{
/* Don't trust the sucker */
//i_pts = p_pes->i_pts + DEFAULT_PTS_DELAY;
i_pts = mdate() + DEFAULT_PTS_DELAY;
}
if( p_fifo->b_die || p_fifo->b_error )
{
break;
}
if( dv_parse_header( p_decoder, p_buffer ) > 0 )
{
fprintf(stderr, "size changed\n");
}
if( p_vout && ( !p_decoder->prev_frame_decoded
|| dv_frame_changed( p_decoder ) ) )
{
picture_t *p_pic;
u8 *pixels[3];
int pitches[3], i;
while( !(p_pic = vout_CreatePicture( p_vout, 0, 0, 0 ) ) )
{
if( p_fifo->b_die || p_fifo->b_error )
{
break;
}
msleep( VOUT_OUTMEM_SLEEP );
}
if( !p_pic )
{
break;
}
for( i = 0 ; i < p_pic->i_planes ; i++ )
{
pixels[i] = p_pic->p[i].p_pixels;
pitches[i] = p_pic->p[i].i_pitch;
}
dv_decode_full_frame( p_decoder, p_buffer,
e_dv_color_yuv, pixels, pitches );
p_decoder->prev_frame_decoded = 1;
vout_DatePicture( p_vout, p_pic, i_pts );
vout_DisplayPicture( p_vout, p_pic );
}
i_data = 0;
}
if( p_vout )
{
vout_DestroyThread( p_vout );
}
}
free( p_buffer );
if( p_fifo->b_error )
{
DecoderError( p_fifo );
return -1;
}
return 0;
}
static u32 GetFourCC( dv_sample_t x )
{
switch( x )
{
case e_dv_sample_411: return VLC_FOURCC('Y','U','Y','2');
case e_dv_sample_420: return VLC_FOURCC('Y','U','Y','2');
case e_dv_sample_422: return VLC_FOURCC('Y','U','Y','2');
default: return 0;
}
}
static pes_packet_t *GetFirstPES( decoder_fifo_t *p_fifo )
{
pes_packet_t *p_pes;
vlc_mutex_lock( &p_fifo->data_lock );
/* if fifo is empty wait */
while( !p_fifo->p_first )
{
if( p_fifo->b_die )
{
vlc_mutex_unlock( &p_fifo->data_lock );
return NULL;
}
vlc_cond_wait( &p_fifo->data_wait, &p_fifo->data_lock );
}
p_pes = p_fifo->p_first;
vlc_mutex_unlock( &p_fifo->data_lock );
return p_pes;
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment