Commit 3106fa79 authored by Laurent Aimar's avatar Laurent Aimar

* rawdv.c: ported to es_out_* and stream_*.

parent 40200aae
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* rawdv.c : raw dv input module for vlc * rawdv.c : raw dv input module for vlc
***************************************************************************** *****************************************************************************
* Copyright (C) 2001 VideoLAN * Copyright (C) 2001 VideoLAN
* $Id: rawdv.c,v 1.11 2003/11/24 00:39:01 fenrir Exp $ * $Id: rawdv.c,v 1.12 2003/11/24 19:19:02 fenrir Exp $
* *
* Authors: Gildas Bazin <gbazin@netcourrier.com> * Authors: Gildas Bazin <gbazin@netcourrier.com>
* *
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or * the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
...@@ -25,22 +25,30 @@ ...@@ -25,22 +25,30 @@
* Preamble * Preamble
*****************************************************************************/ *****************************************************************************/
#include <stdlib.h> /* malloc(), free() */ #include <stdlib.h> /* malloc(), free() */
#include <string.h> /* strdup() */
#include <errno.h>
#include <vlc/vlc.h> #include <vlc/vlc.h>
#include <vlc/input.h> #include <vlc/input.h>
#include <sys/types.h> /*****************************************************************************
* Module descriptor
*****************************************************************************/
static int Open ( vlc_object_t * );
static void Close( vlc_object_t * );
vlc_module_begin();
set_description( _("raw dv demuxer") );
set_capability( "demux", 2 );
set_callbacks( Open, Close );
add_shortcut( "rawdv" );
vlc_module_end();
#include <codecs.h> /* BITMAPINFOHEADER, WAVEFORMATEX */
/***************************************************************************** /*****************************************************************************
A little bit of background information (copied over from libdv glossary). A little bit of background information (copied over from libdv glossary).
- DIF block: A block of 80 bytes. This is the basic data framing unit of the - DIF block: A block of 80 bytes. This is the basic data framing unit of the
DVC tape format, analogous to sectors of hard disc. DVC tape format, analogous to sectors of hard disc.
- Video Section: Each DIF sequence contains a video section, consisting of - Video Section: Each DIF sequence contains a video section, consisting of
135 DIF blocks, which are further subdivided into Video Segments. 135 DIF blocks, which are further subdivided into Video Segments.
...@@ -81,12 +89,11 @@ struct demux_sys_t ...@@ -81,12 +89,11 @@ struct demux_sys_t
{ {
int frame_size; int frame_size;
es_descriptor_t *p_video_es; es_out_id_t *p_es_video;
es_descriptor_t *p_audio_es; es_format_t fmt_video;
/* codec specific stuff */ es_out_id_t *p_es_audio;
BITMAPINFOHEADER *p_bih; es_format_t fmt_audio;
WAVEFORMATEX *p_wf;
double f_rate; double f_rate;
int i_bitrate; int i_bitrate;
...@@ -98,29 +105,19 @@ struct demux_sys_t ...@@ -98,29 +105,19 @@ struct demux_sys_t
/***************************************************************************** /*****************************************************************************
* Local prototypes * Local prototypes
*****************************************************************************/ *****************************************************************************/
static int Activate ( vlc_object_t * );
static void Deactivate( vlc_object_t * );
static int Demux ( input_thread_t * ); static int Demux ( input_thread_t * );
/***************************************************************************** /*****************************************************************************
* Module descriptor * Open: initializes raw dv demux structures
*****************************************************************************/ *****************************************************************************/
vlc_module_begin(); static int Open( vlc_object_t * p_this )
set_description( _("raw dv demuxer") );
set_capability( "demux", 2 );
set_callbacks( Activate, NULL );
add_shortcut( "rawdv" );
vlc_module_end();
/*****************************************************************************
* Activate: initializes raw dv demux structures
*****************************************************************************/
static int Activate( vlc_object_t * p_this )
{ {
input_thread_t *p_input = (input_thread_t *)p_this; input_thread_t *p_input = (input_thread_t *)p_this;
demux_sys_t *p_sys;
byte_t *p_peek, *p_peek_backup; byte_t *p_peek, *p_peek_backup;
uint32_t i_dword; uint32_t i_dword;
demux_sys_t *p_rawdv;
dv_header_t dv_header; dv_header_t dv_header;
dv_id_t dv_id; dv_id_t dv_id;
char *psz_ext; char *psz_ext;
...@@ -135,18 +132,14 @@ static int Activate( vlc_object_t * p_this ) ...@@ -135,18 +132,14 @@ static int Activate( vlc_object_t * p_this )
if( ( !psz_ext || strcasecmp( psz_ext, ".dv") )&& if( ( !psz_ext || strcasecmp( psz_ext, ".dv") )&&
( !p_input->psz_demux || strcmp(p_input->psz_demux, "rawdv") ) ) ( !p_input->psz_demux || strcmp(p_input->psz_demux, "rawdv") ) )
{ {
return -1; return VLC_EGENERIC;
} }
p_input->pf_demux = Demux; if( stream_Peek( p_input->s, &p_peek, DV_PAL_FRAME_SIZE ) < DV_NTSC_FRAME_SIZE )
p_input->pf_demux_control = demux_vaControlDefault;
/* Have a peep at the show. */
if( input_Peek(p_input, &p_peek, DV_PAL_FRAME_SIZE) < DV_NTSC_FRAME_SIZE )
{ {
/* Stream too short ... */ /* Stream too short ... */
msg_Err( p_input, "cannot peek()" ); msg_Err( p_input, "cannot peek()" );
return -1; return VLC_EGENERIC;
} }
p_peek_backup = p_peek; p_peek_backup = p_peek;
...@@ -164,7 +157,7 @@ static int Activate( vlc_object_t * p_this ) ...@@ -164,7 +157,7 @@ static int Activate( vlc_object_t * p_this )
if( dv_id.sct != 0 ) if( dv_id.sct != 0 )
{ {
msg_Warn( p_input, "not a raw dv stream header" ); msg_Warn( p_input, "not a raw dv stream header" );
return -1; return VLC_EGENERIC;
} }
/* fill in the dv_header_t structure */ /* fill in the dv_header_t structure */
...@@ -173,7 +166,7 @@ static int Activate( vlc_object_t * p_this ) ...@@ -173,7 +166,7 @@ static int Activate( vlc_object_t * p_this )
if( i_dword >> (32 - 1) ) /* incorrect bit */ if( i_dword >> (32 - 1) ) /* incorrect bit */
{ {
msg_Warn( p_input, "incorrect bit" ); msg_Warn( p_input, "incorrect bit" );
return -1; return VLC_EGENERIC;
} }
i_dword = GetDWBE( p_peek ); p_peek += 4; i_dword = GetDWBE( p_peek ); p_peek += 4;
...@@ -195,45 +188,23 @@ static int Activate( vlc_object_t * p_this ) ...@@ -195,45 +188,23 @@ static int Activate( vlc_object_t * p_this )
p_peek += 72; /* skip rest of DIF block */ p_peek += 72; /* skip rest of DIF block */
/* Setup the structures for our demuxer */ /* Set p_input field */
if( !( p_rawdv = malloc( sizeof( demux_sys_t ) ) ) ) p_input->pf_demux = Demux;
{ p_input->pf_demux_control = demux_vaControlDefault;
msg_Err( p_input, "out of memory" ); p_input->p_demux_data = p_sys = malloc( sizeof( demux_sys_t ) );
return -1;
}
memset( p_rawdv, 0, sizeof( demux_sys_t ) );
p_rawdv->p_bih = NULL;
p_rawdv->p_wf = NULL;
p_input->p_demux_data = p_rawdv;
p_rawdv->p_bih = (BITMAPINFOHEADER *) malloc( sizeof(BITMAPINFOHEADER) ); p_sys->frame_size = dv_header.dsf ? 12 * 150 * 80 : 10 * 150 * 80;
if( !p_rawdv->p_bih ) p_sys->f_rate = dv_header.dsf ? 25 : 29.97;
{
msg_Err( p_input, "out of memory" ); p_sys->i_pcr = 0;
goto error; p_sys->p_es_video = NULL;
} p_sys->p_es_audio = NULL;
p_rawdv->p_bih->biSize = sizeof(BITMAPINFOHEADER);
p_rawdv->p_bih->biCompression = VLC_FOURCC( 'd','v','s','d' ); p_sys->i_bitrate = 0;
p_rawdv->p_bih->biSize = 40;
p_rawdv->p_bih->biWidth = 720; es_format_Init( &p_sys->fmt_video, VIDEO_ES, VLC_FOURCC( 'd','v','s','d' ) );
p_rawdv->p_bih->biHeight = dv_header.dsf ? 576 : 480; p_sys->fmt_video.video.i_width = 720;
p_rawdv->p_bih->biPlanes = 1; p_sys->fmt_video.video.i_height= dv_header.dsf ? 576 : 480;;
p_rawdv->p_bih->biBitCount = 24;
p_rawdv->p_bih->biSizeImage =
p_rawdv->p_bih->biWidth * p_rawdv->p_bih->biHeight
* (p_rawdv->p_bih->biBitCount >> 3);
/* Properties of our video */
if( dv_header.dsf )
{
p_rawdv->frame_size = 12 * 150 * 80;
p_rawdv->f_rate = 25;
}
else
{
p_rawdv->frame_size = 10 * 150 * 80;
p_rawdv->f_rate = 29.97;
}
/* Audio stuff */ /* Audio stuff */
#if 0 #if 0
...@@ -245,87 +216,43 @@ static int Activate( vlc_object_t * p_this ) ...@@ -245,87 +216,43 @@ static int Activate( vlc_object_t * p_this )
} }
#endif #endif
p_rawdv->p_wf = (WAVEFORMATEX *)malloc( sizeof(WAVEFORMATEX) ); es_format_Init( &p_sys->fmt_audio, AUDIO_ES, VLC_FOURCC( 'd','v','a','u' ) );
if( !p_rawdv->p_wf ) p_sys->fmt_audio.audio.i_channels = 2;
{ p_sys->fmt_audio.audio.i_rate = 44100; /* FIXME */
msg_Err( p_input, "out of memory" ); p_sys->fmt_audio.audio.i_bitspersample = 16;
goto error; p_sys->fmt_audio.audio.i_blockalign = p_sys->frame_size; /* ??? */
} p_sys->fmt_audio.i_bitrate = p_sys->f_rate * p_sys->frame_size; /* ??? */
p_rawdv->p_wf->wFormatTag = 0;
p_rawdv->p_wf->nChannels = 2;
p_rawdv->p_wf->nSamplesPerSec = 44100; /* FIXME */
p_rawdv->p_wf->nAvgBytesPerSec = p_rawdv->f_rate * p_rawdv->frame_size;
p_rawdv->p_wf->nBlockAlign = p_rawdv->frame_size;
p_rawdv->p_wf->wBitsPerSample = 16;
p_rawdv->p_wf->cbSize = 0;
/* necessary because input_SplitBuffer() will only get /* necessary because input_SplitBuffer() will only get
* INPUT_DEFAULT_BUFSIZE bytes at a time. */ * INPUT_DEFAULT_BUFSIZE bytes at a time. */
p_input->i_bufsize = p_rawdv->frame_size; p_input->i_bufsize = p_sys->frame_size;
/* Create one program */
vlc_mutex_lock( &p_input->stream.stream_lock ); vlc_mutex_lock( &p_input->stream.stream_lock );
if( input_InitStream( p_input, 0 ) == -1) if( input_InitStream( p_input, 0 ) == -1)
{ {
vlc_mutex_unlock( &p_input->stream.stream_lock ); vlc_mutex_unlock( &p_input->stream.stream_lock );
msg_Err( p_input, "cannot init stream" ); msg_Err( p_input, "cannot init stream" );
goto error; free( p_sys );
return VLC_EGENERIC;
} }
if( input_AddProgram( p_input, 0, 0) == NULL ) p_input->stream.i_mux_rate = p_sys->frame_size * p_sys->f_rate;
{
vlc_mutex_unlock( &p_input->stream.stream_lock );
msg_Err( p_input, "cannot add program" );
goto error;
}
p_input->stream.p_selected_program = p_input->stream.pp_programs[0];
p_input->stream.i_mux_rate = p_rawdv->frame_size * p_rawdv->f_rate;
vlc_mutex_unlock( &p_input->stream.stream_lock ); vlc_mutex_unlock( &p_input->stream.stream_lock );
/* Add video stream */ p_sys->p_es_video = es_out_Add( p_input->p_es_out, &p_sys->fmt_video );
vlc_mutex_lock( &p_input->stream.stream_lock ); p_sys->p_es_audio = es_out_Add( p_input->p_es_out, &p_sys->fmt_audio );
p_rawdv->p_video_es = input_AddES( p_input,
p_input->stream.p_selected_program,
1, VIDEO_ES, NULL, 0 );
p_rawdv->p_video_es->i_stream_id = 0;
p_rawdv->p_video_es->i_fourcc = VLC_FOURCC( 'd','v','s','d' );
p_rawdv->p_video_es->p_bitmapinfoheader = (void *)p_rawdv->p_bih;
input_SelectES( p_input, p_rawdv->p_video_es );
vlc_mutex_unlock( &p_input->stream.stream_lock );
/* Add audio stream */ return VLC_SUCCESS;
vlc_mutex_lock( &p_input->stream.stream_lock );
p_rawdv->p_audio_es = input_AddES( p_input,
p_input->stream.p_selected_program,
2, AUDIO_ES, NULL, 0 );
p_rawdv->p_audio_es->i_stream_id = 1;
p_rawdv->p_audio_es->i_fourcc = VLC_FOURCC( 'd','v','a','u' );
p_rawdv->p_audio_es->p_waveformatex = (void *)p_rawdv->p_wf;
input_SelectES( p_input, p_rawdv->p_audio_es );
vlc_mutex_unlock( &p_input->stream.stream_lock );
/* Init pcr */
p_rawdv->i_pcr = 0;
return 0;
error:
if( p_rawdv->p_bih ) free( p_rawdv->p_bih );
if( p_rawdv->p_wf ) free( p_rawdv->p_wf );
Deactivate( (vlc_object_t *)p_input );
return -1;
} }
/***************************************************************************** /*****************************************************************************
* Deactivate: frees unused data * Close: frees unused data
*****************************************************************************/ *****************************************************************************/
static void Deactivate( vlc_object_t *p_this ) static void Close( vlc_object_t *p_this )
{ {
input_thread_t *p_input = (input_thread_t *)p_this; input_thread_t *p_input = (input_thread_t *)p_this;
demux_sys_t *p_rawdv = (demux_sys_t *)p_input->p_demux_data; demux_sys_t *p_sys = p_input->p_demux_data;
free( p_rawdv ); free( p_sys );
} }
/***************************************************************************** /*****************************************************************************
...@@ -335,103 +262,75 @@ static void Deactivate( vlc_object_t *p_this ) ...@@ -335,103 +262,75 @@ static void Deactivate( vlc_object_t *p_this )
*****************************************************************************/ *****************************************************************************/
static int Demux( input_thread_t * p_input ) static int Demux( input_thread_t * p_input )
{ {
demux_sys_t *p_rawdv = (demux_sys_t *)p_input->p_demux_data; demux_sys_t *p_sys = p_input->p_demux_data;
pes_packet_t *p_pes = NULL; block_t *p_block;
pes_packet_t *p_audio_pes = NULL; vlc_bool_t b_audio, b_video;
data_packet_t *p_data;
ssize_t i_read;
if( p_input->stream.p_selected_program->i_synchro_state == SYNCHRO_REINIT ) if( p_input->stream.p_selected_program->i_synchro_state == SYNCHRO_REINIT )
{ {
off_t i_pos; off_t i_pos = stream_Tell( p_input->s );
msg_Warn( p_input, "synchro reinit" ); msg_Warn( p_input, "synchro reinit" );
/* If the user tried to seek in the stream, we need to make sure /* If the user tried to seek in the stream, we need to make sure
* the new position is at a DIF block boundary. */ * the new position is at a DIF block boundary. */
vlc_mutex_lock( &p_input->stream.stream_lock ); if( i_pos % p_sys->frame_size > 0 )
i_pos= p_input->stream.p_selected_area->i_tell;
vlc_mutex_unlock( &p_input->stream.stream_lock );
if( (i_pos % p_rawdv->frame_size) &&
p_input->stream.b_seekable &&
p_input->stream.i_method == INPUT_METHOD_FILE )
{ {
p_input->pf_seek( p_input, (i_pos / p_rawdv->frame_size) i_pos += p_sys->frame_size - i_pos % p_sys->frame_size;
* p_rawdv->frame_size );
input_AccessReinit( p_input ); if( stream_Seek( p_input->s, i_pos ) )
{
msg_Warn( p_input, "cannot resynch after seek (EOF?)" );
return -1;
}
} }
} }
/* Call the pace control */ /* Call the pace control */
input_ClockManageRef( p_input, p_input->stream.p_selected_program, input_ClockManageRef( p_input, p_input->stream.p_selected_program,
p_rawdv->i_pcr ); p_sys->i_pcr );
i_read = input_SplitBuffer( p_input, &p_data, p_rawdv->frame_size ); if( ( p_block = stream_Block( p_input->s, p_sys->frame_size ) ) == NULL )
if( i_read <= 0 )
{ {
return i_read; /* EOF */
return 0;
} }
/* Build video PES packet */ es_out_Control( p_input->p_es_out, ES_OUT_GET_SELECT,
if( p_rawdv->p_video_es->p_dec ) p_sys->p_es_audio, &b_audio );
es_out_Control( p_input->p_es_out, ES_OUT_GET_SELECT,
p_sys->p_es_video, &b_video );
p_block->i_dts =
p_block->i_pts = input_ClockGetTS( p_input,
p_input->stream.p_selected_program,
p_sys->i_pcr );
if( b_audio && b_video )
{ {
p_pes = input_NewPES( p_input->p_method_data ); block_t *p_dup = block_Duplicate( p_block );
if( p_pes == NULL )
es_out_Send( p_input->p_es_out, p_sys->p_es_video, p_block );
if( p_dup )
{ {
msg_Err( p_input, "out of memory" ); es_out_Send( p_input->p_es_out, p_sys->p_es_video, p_dup );
input_DeletePacket( p_input->p_method_data, p_data );
return -1;
} }
p_pes->i_rate = p_input->stream.control.i_rate;
p_pes->p_first = p_pes->p_last = p_data;
p_pes->i_pes_size = i_read;
p_pes->i_nb_data = 1;
p_pes->i_pts =
input_ClockGetTS( p_input, p_input->stream.p_selected_program,
p_rawdv->i_pcr );
} }
else if( b_audio )
/* Do the same for audio */
if( p_rawdv->p_audio_es->p_dec )
{ {
p_audio_pes = input_NewPES( p_input->p_method_data ); es_out_Send( p_input->p_es_out, p_sys->p_es_audio, p_block );
if( p_audio_pes == NULL ) }
{ else if( b_video )
msg_Err( p_input, "out of memory" ); {
input_DeletePacket( p_input->p_method_data, p_data ); es_out_Send( p_input->p_es_out, p_sys->p_es_video, p_block );
return -1; }
} else
p_audio_pes->i_rate = p_input->stream.control.i_rate; {
block_Release( p_block );
if( p_rawdv->p_video_es->p_dec )
p_audio_pes->p_first = p_audio_pes->p_last =
input_ShareBuffer( p_input->p_method_data, p_data->p_buffer );
else
p_audio_pes->p_first = p_audio_pes->p_last = p_data;
p_audio_pes->p_first->p_next = p_data->p_next;
p_audio_pes->p_first->p_payload_start = p_data->p_payload_start;
p_audio_pes->p_first->p_payload_end = p_data->p_payload_end;
p_audio_pes->i_pes_size = i_read;
p_audio_pes->i_nb_data = 1;
p_audio_pes->i_pts =
input_ClockGetTS( p_input, p_input->stream.p_selected_program,
p_rawdv->i_pcr );
} }
/* Decode PES packets if stream is selected */ p_sys->i_pcr += ( 90000 / p_sys->f_rate );
if( p_rawdv->p_video_es->p_dec )
input_DecodePES( p_rawdv->p_video_es->p_dec, p_pes );
if( p_rawdv->p_audio_es->p_dec )
input_DecodePES( p_rawdv->p_audio_es->p_dec, p_audio_pes );
p_rawdv->i_pcr += ( 90000 / p_rawdv->f_rate );
if( !p_rawdv->p_video_es->p_dec &&
!p_rawdv->p_audio_es->p_dec )
input_DeletePacket( p_input->p_method_data, p_data );
return 1; return 1;
} }
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