Commit 6f67ff83 authored by Laurent Aimar's avatar Laurent Aimar

* cinepak: add a new fourcc

 * ffmpeg and mp4: some clean up and change the way ffmpeg is
initialised.
parent d5eeda89
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* cinepak.c: cinepak video decoder * cinepak.c: cinepak video decoder
***************************************************************************** *****************************************************************************
* Copyright (C) 1999-2001 VideoLAN * Copyright (C) 1999-2001 VideoLAN
* $Id: cinepak.c,v 1.3 2002/07/23 00:39:16 sam Exp $ * $Id: cinepak.c,v 1.4 2002/07/23 17:19:02 fenrir Exp $
* *
* Authors: Laurent Aimar <fenrir@via.ecp.fr> * Authors: Laurent Aimar <fenrir@via.ecp.fr>
* *
...@@ -92,7 +92,14 @@ MODULE_DEACTIVATE_STOP ...@@ -92,7 +92,14 @@ MODULE_DEACTIVATE_STOP
*****************************************************************************/ *****************************************************************************/
static int decoder_Probe( vlc_fourcc_t *pi_type ) static int decoder_Probe( vlc_fourcc_t *pi_type )
{ {
return( ( *pi_type == VLC_FOURCC('c','v','i','d') ) ? 0 : -1 ); switch( *pi_type )
{
case( VLC_FOURCC('c','v','i','d') ):
case( VLC_FOURCC('C','V','I','D') ):
return( 0);
default:
return( -1 );
}
} }
/***************************************************************************** /*****************************************************************************
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* ffmpeg.c: video decoder using ffmpeg library * ffmpeg.c: video decoder using ffmpeg library
***************************************************************************** *****************************************************************************
* Copyright (C) 1999-2001 VideoLAN * Copyright (C) 1999-2001 VideoLAN
* $Id: ffmpeg.c,v 1.19 2002/07/23 00:39:17 sam Exp $ * $Id: ffmpeg.c,v 1.20 2002/07/23 17:19:02 fenrir Exp $
* *
* Authors: Laurent Aimar <fenrir@via.ecp.fr> * Authors: Laurent Aimar <fenrir@via.ecp.fr>
* *
...@@ -174,19 +174,33 @@ static int decoder_Run ( decoder_fifo_t * p_fifo ) ...@@ -174,19 +174,33 @@ static int decoder_Run ( decoder_fifo_t * p_fifo )
( *(u8*)(p) + ( *((u8*)(p)+1) << 8 ) + \ ( *(u8*)(p) + ( *((u8*)(p)+1) << 8 ) + \
( *((u8*)(p)+2) << 16 ) + ( *((u8*)(p)+3) << 24 ) ) ( *((u8*)(p)+2) << 16 ) + ( *((u8*)(p)+3) << 24 ) )
static void __ParseBitMapInfoHeader( bitmapinfoheader_t *h, byte_t *p_data ) static void ffmpeg_ParseBitMapInfoHeader( bitmapinfoheader_t *p_bh,
u8 *p_data )
{ {
h->i_size = GetDWLE( p_data ); p_bh->i_size = GetDWLE( p_data );
h->i_width = GetDWLE( p_data + 4 ); p_bh->i_width = GetDWLE( p_data + 4 );
h->i_height = GetDWLE( p_data + 8 ); p_bh->i_height = GetDWLE( p_data + 8 );
h->i_planes = GetWLE( p_data + 12 ); p_bh->i_planes = GetWLE( p_data + 12 );
h->i_bitcount = GetWLE( p_data + 14 ); p_bh->i_bitcount = GetWLE( p_data + 14 );
h->i_compression = GetDWLE( p_data + 16 ); p_bh->i_compression = GetDWLE( p_data + 16 );
h->i_sizeimage = GetDWLE( p_data + 20 ); p_bh->i_sizeimage = GetDWLE( p_data + 20 );
h->i_xpelspermeter = GetDWLE( p_data + 24 ); p_bh->i_xpelspermeter = GetDWLE( p_data + 24 );
h->i_ypelspermeter = GetDWLE( p_data + 28 ); p_bh->i_ypelspermeter = GetDWLE( p_data + 28 );
h->i_clrused = GetDWLE( p_data + 32 ); p_bh->i_clrused = GetDWLE( p_data + 32 );
h->i_clrimportant = GetDWLE( p_data + 36 ); p_bh->i_clrimportant = GetDWLE( p_data + 36 );
if( p_bh->i_size > 40 )
{
p_bh->i_data = p_bh->i_size - 40;
p_bh->p_data = malloc( p_bh->i_data );
memcpy( p_bh->p_data, p_data + 40, p_bh->i_data );
}
else
{
p_bh->i_data = 0;
p_bh->p_data = NULL;
}
} }
/* get the first pes from fifo */ /* get the first pes from fifo */
static pes_packet_t *__PES_GET( decoder_fifo_t *p_fifo ) static pes_packet_t *__PES_GET( decoder_fifo_t *p_fifo )
...@@ -423,89 +437,6 @@ static vout_thread_t *ffmpeg_CreateVout( videodec_thread_t *p_vdec, ...@@ -423,89 +437,6 @@ static vout_thread_t *ffmpeg_CreateVout( videodec_thread_t *p_vdec,
return( p_vout ); return( p_vout );
} }
#if 0
/* segfault some^Wevery times*/
static void ffmpeg_ConvertPictureI410toI420( picture_t *p_pic,
AVPicture *p_avpicture,
videodec_thread_t *p_vdec )
{
int i_plane;
int i_x, i_y;
int i_x_max, i_y_max;
int i_width;
int i_height;
int i_dst_stride;
int i_src_stride;
u8 *p_dest;
u8 *p_src;
i_width = p_vdec->p_context->width;
i_height= p_vdec->p_context->height;
p_dest = p_pic->p[0].p_pixels;
p_src = p_avpicture->data[0];
i_src_stride = p_avpicture->linesize[0];
i_dst_stride = p_pic->p[0].i_pitch;
if( i_src_stride == i_dst_stride )
{
p_vdec->p_fifo->p_vlc->pf_memcpy( p_dest, p_src, i_src_stride * i_height );
}
else
{
for( i_y = 0; i_y < i_height; i_y++ )
{
p_vdec->p_fifo->p_vlc->pf_memcpy( p_dest, p_src, i_width );
p_dest += i_dst_stride;
p_src += i_src_stride;
}
}
for( i_plane = 1; i_plane < 3; i_plane++ )
{
i_y_max = p_pic->p[i_plane].i_lines;
p_src = p_avpicture->data[i_plane];
p_dest = p_pic->p[i_plane].p_pixels;
i_dst_stride = p_pic->p[i_plane].i_pitch;
i_src_stride = p_avpicture->linesize[i_plane];
i_x_max = __MIN( i_dst_stride / 2, i_src_stride );
for( i_y = 0; i_y <( i_y_max + 1 ) / 2 ; i_y++ )
{
for( i_x = 0; i_x < i_x_max - 1; i_x++ )
{
p_dest[2 * i_x ] = p_src[i_x];
p_dest[2 * i_x + 1] = ( p_src[i_x] + p_src[i_x + 1] ) / 2;
}
p_dest[2 * i_x_max - 2] = p_src[i_x];
p_dest[2 * i_x_max - 1] = p_src[i_x];
p_dest += 2 * i_dst_stride;
p_src += i_src_stride;
}
p_src = p_pic->p[i_plane].p_pixels;
p_dest = p_src + i_dst_stride;
for( i_y = 0; i_y < ( i_y_max + 1 ) / 2 ; i_y++ )
{
p_vdec->p_fifo->p_vlc->pf_memcpy( p_dest, p_src, i_dst_stride );
p_dest += 2*i_dst_stride;
p_src += 2*i_dst_stride;
}
}
}
#endif
/* FIXME FIXME FIXME this is a big shit /* FIXME FIXME FIXME this is a big shit
does someone want to rewrite this function ? does someone want to rewrite this function ?
or said to me how write a better thing or said to me how write a better thing
...@@ -679,8 +610,8 @@ static int InitThread( videodec_thread_t *p_vdec ) ...@@ -679,8 +610,8 @@ static int InitThread( videodec_thread_t *p_vdec )
if( p_vdec->p_fifo->p_demux_data ) if( p_vdec->p_fifo->p_demux_data )
{ {
__ParseBitMapInfoHeader( &p_vdec->format, ffmpeg_ParseBitMapInfoHeader( &p_vdec->format,
(byte_t*)p_vdec->p_fifo->p_demux_data ); (u8*)p_vdec->p_fifo->p_demux_data );
} }
else else
{ {
...@@ -755,10 +686,29 @@ static int InitThread( videodec_thread_t *p_vdec ) ...@@ -755,10 +686,29 @@ static int InitThread( videodec_thread_t *p_vdec )
msg_Dbg( p_vdec->p_fifo, "ffmpeg codec (%s) started", msg_Dbg( p_vdec->p_fifo, "ffmpeg codec (%s) started",
p_vdec->psz_namecodec ); p_vdec->psz_namecodec );
} }
/* first give init data */
if( p_vdec->format.i_data )
{
AVPicture avpicture;
int b_gotpicture;
switch( i_ffmpeg_codec )
{
case( CODEC_ID_MPEG4 ):
avcodec_decode_video( p_vdec->p_context, &avpicture,
&b_gotpicture,
p_vdec->format.p_data,
p_vdec->format.i_data );
break;
default:
break;
}
}
/* This will be created after the first decoded frame */ /* This will be created after the first decoded frame */
p_vdec->p_vout = NULL; p_vdec->p_vout = NULL;
return( 0 ); return( 0 );
} }
...@@ -921,6 +871,11 @@ static void EndThread( videodec_thread_t *p_vdec ) ...@@ -921,6 +871,11 @@ static void EndThread( videodec_thread_t *p_vdec )
vlc_object_detach( p_vdec->p_vout, p_vdec->p_fifo ); vlc_object_detach( p_vdec->p_vout, p_vdec->p_fifo );
vlc_object_attach( p_vdec->p_vout, p_vdec->p_fifo->p_vlc ); vlc_object_attach( p_vdec->p_vout, p_vdec->p_fifo->p_vlc );
} }
if( p_vdec->format.p_data != NULL)
{
free( p_vdec->format.p_data );
}
free( p_vdec ); free( p_vdec );
} }
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* ffmpeg_vdec.h: video decoder using ffmpeg library * ffmpeg_vdec.h: video decoder using ffmpeg library
***************************************************************************** *****************************************************************************
* Copyright (C) 2001 VideoLAN * Copyright (C) 2001 VideoLAN
* $Id: ffmpeg.h,v 1.7 2002/07/23 00:39:17 sam Exp $ * $Id: ffmpeg.h,v 1.8 2002/07/23 17:19:02 fenrir Exp $
* *
* Authors: Laurent Aimar <fenrir@via.ecp.fr> * Authors: Laurent Aimar <fenrir@via.ecp.fr>
* *
...@@ -35,6 +35,10 @@ typedef struct bitmapinfoheader_s ...@@ -35,6 +35,10 @@ typedef struct bitmapinfoheader_s
u32 i_ypelspermeter; u32 i_ypelspermeter;
u32 i_clrused; u32 i_clrused;
u32 i_clrimportant; u32 i_clrimportant;
int i_data;
u8 *p_data;
} bitmapinfoheader_t; } bitmapinfoheader_t;
/* MPEG4 video */ /* MPEG4 video */
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* libmp4.c : LibMP4 library for mp4 module for vlc * libmp4.c : LibMP4 library for mp4 module for vlc
***************************************************************************** *****************************************************************************
* Copyright (C) 2001 VideoLAN * Copyright (C) 2001 VideoLAN
* $Id: libmp4.c,v 1.4 2002/07/23 00:39:17 sam Exp $ * $Id: libmp4.c,v 1.5 2002/07/23 17:19:02 fenrir Exp $
* Authors: Laurent Aimar <fenrir@via.ecp.fr> * Authors: Laurent Aimar <fenrir@via.ecp.fr>
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
...@@ -1208,6 +1208,9 @@ int MP4_ReadBox_sample_soun( MP4_Stream_t *p_stream, MP4_Box_t *p_box ) ...@@ -1208,6 +1208,9 @@ int MP4_ReadBox_sample_soun( MP4_Stream_t *p_stream, MP4_Box_t *p_box )
MP4_GET2BYTES( p_box->data.p_sample_soun->i_sampleratehi ); MP4_GET2BYTES( p_box->data.p_sample_soun->i_sampleratehi );
MP4_GET2BYTES( p_box->data.p_sample_soun->i_sampleratelo ); MP4_GET2BYTES( p_box->data.p_sample_soun->i_sampleratelo );
MP4_SeekStream( p_stream, p_box->i_pos + MP4_BOX_HEADERSIZE( p_box ) + 28 );
MP4_ReadBoxContainerRaw( p_stream, p_box ); /* esds */
#ifdef MP4_VERBOSE #ifdef MP4_VERBOSE
msg_Dbg( p_stream->p_input, "Read Box: \"soun\" in stsd channel %d sample size %d sampl rate %f", msg_Dbg( p_stream->p_input, "Read Box: \"soun\" in stsd channel %d sample size %d sampl rate %f",
p_box->data.p_sample_soun->i_channelcount, p_box->data.p_sample_soun->i_channelcount,
...@@ -1219,6 +1222,7 @@ int MP4_ReadBox_sample_soun( MP4_Stream_t *p_stream, MP4_Box_t *p_box ) ...@@ -1219,6 +1222,7 @@ int MP4_ReadBox_sample_soun( MP4_Stream_t *p_stream, MP4_Box_t *p_box )
MP4_READBOX_EXIT( 1 ); MP4_READBOX_EXIT( 1 );
} }
#if 0
int MP4_ReadBox_sample_mp4a( MP4_Stream_t *p_stream, MP4_Box_t *p_box ) int MP4_ReadBox_sample_mp4a( MP4_Stream_t *p_stream, MP4_Box_t *p_box )
{ {
int i; int i;
...@@ -1257,6 +1261,7 @@ int MP4_ReadBox_sample_mp4a( MP4_Stream_t *p_stream, MP4_Box_t *p_box ) ...@@ -1257,6 +1261,7 @@ int MP4_ReadBox_sample_mp4a( MP4_Stream_t *p_stream, MP4_Box_t *p_box )
#endif #endif
MP4_READBOX_EXIT( 1 ); MP4_READBOX_EXIT( 1 );
} }
#endif
int MP4_ReadBox_sample_vide( MP4_Stream_t *p_stream, MP4_Box_t *p_box ) int MP4_ReadBox_sample_vide( MP4_Stream_t *p_stream, MP4_Box_t *p_box )
{ {
...@@ -1991,7 +1996,7 @@ static struct ...@@ -1991,7 +1996,7 @@ static struct
/* for codecs */ /* for codecs */
{ FOURCC_soun, MP4_ReadBox_sample_soun, MP4_FreeBox_Common }, { FOURCC_soun, MP4_ReadBox_sample_soun, MP4_FreeBox_Common },
{ FOURCC__mp3, MP4_ReadBox_sample_soun, MP4_FreeBox_Common }, { FOURCC__mp3, MP4_ReadBox_sample_soun, MP4_FreeBox_Common },
{ FOURCC_mp4a, MP4_ReadBox_sample_mp4a, MP4_FreeBox_Common }, { FOURCC_mp4a, MP4_ReadBox_sample_soun, MP4_FreeBox_Common },
{ FOURCC_vide, MP4_ReadBox_sample_vide, MP4_FreeBox_Common }, { FOURCC_vide, MP4_ReadBox_sample_vide, MP4_FreeBox_Common },
{ FOURCC_mp4v, MP4_ReadBox_sample_vide, MP4_FreeBox_Common }, { FOURCC_mp4v, MP4_ReadBox_sample_vide, MP4_FreeBox_Common },
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* libmp4.h : LibMP4 library for mp4 module for vlc * libmp4.h : LibMP4 library for mp4 module for vlc
***************************************************************************** *****************************************************************************
* Copyright (C) 2001 VideoLAN * Copyright (C) 2001 VideoLAN
* $Id: libmp4.h,v 1.4 2002/07/23 00:39:17 sam Exp $ * $Id: libmp4.h,v 1.5 2002/07/23 17:19:02 fenrir Exp $
* Authors: Laurent Aimar <fenrir@via.ecp.fr> * Authors: Laurent Aimar <fenrir@via.ecp.fr>
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
...@@ -321,22 +321,6 @@ typedef struct MP4_Box_data_sample_soun_s ...@@ -321,22 +321,6 @@ typedef struct MP4_Box_data_sample_soun_s
} MP4_Box_data_sample_soun_t; } MP4_Box_data_sample_soun_t;
typedef struct MP4_Box_data_sample_mp4a_s
{
u8 i_reserved1[6];
u16 i_data_reference_index;
u32 i_reserved2[2];
u16 i_channelcount;
u16 i_samplesize;
u16 i_predefined;
u16 i_reserved3;
u16 i_sampleratehi; /* timescale of track */
u16 i_sampleratelo;
} MP4_Box_data_sample_mp4a_t;
typedef struct MP4_Box_data_sample_vide_s typedef struct MP4_Box_data_sample_vide_s
{ {
u8 i_reserved1[6]; u8 i_reserved1[6];
...@@ -362,34 +346,6 @@ typedef struct MP4_Box_data_sample_vide_s ...@@ -362,34 +346,6 @@ typedef struct MP4_Box_data_sample_vide_s
} MP4_Box_data_sample_vide_t; } MP4_Box_data_sample_vide_t;
/*
typedef struct MP4_Box_data_sample_mp4v_s
{
u8 i_reserved1[6];
u16 i_data_reference_index;
u16 i_predefined1;
u16 i_reserved2;
u32 i_predefined2[3];
s16 i_width;
s16 i_height;
u32 i_horizresolution;
u32 i_vertresolution;
u32 i_reserved3;
u16 i_predefined3;
u8 i_compressorname[32];
s16 i_depth;
s16 i_predefined4;
} MP4_Box_data_sample_mp4v_t;
*/
typedef struct MP4_Box_data_sample_hint_s typedef struct MP4_Box_data_sample_hint_s
{ {
u8 i_reserved1[6]; u8 i_reserved1[6];
...@@ -648,9 +604,7 @@ typedef union MP4_Box_data_s ...@@ -648,9 +604,7 @@ typedef union MP4_Box_data_s
MP4_Box_data_ctts_t *p_ctts; MP4_Box_data_ctts_t *p_ctts;
MP4_Box_data_stsd_t *p_stsd; MP4_Box_data_stsd_t *p_stsd;
MP4_Box_data_sample_vide_t *p_sample_vide; MP4_Box_data_sample_vide_t *p_sample_vide;
MP4_Box_data_sample_vide_t *p_sample_mp4v;
MP4_Box_data_sample_soun_t *p_sample_soun; MP4_Box_data_sample_soun_t *p_sample_soun;
MP4_Box_data_sample_soun_t *p_sample_mp4a;
MP4_Box_data_sample_hint_t *p_sample_hint; MP4_Box_data_sample_hint_t *p_sample_hint;
MP4_Box_data_esds_t *p_esds; MP4_Box_data_esds_t *p_esds;
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* mp4.c : MP4 file input module for vlc * mp4.c : MP4 file input module for vlc
***************************************************************************** *****************************************************************************
* Copyright (C) 2001 VideoLAN * Copyright (C) 2001 VideoLAN
* $Id: mp4.c,v 1.5 2002/07/23 00:39:17 sam Exp $ * $Id: mp4.c,v 1.6 2002/07/23 17:19:02 fenrir Exp $
* Authors: Laurent Aimar <fenrir@via.ecp.fr> * Authors: Laurent Aimar <fenrir@via.ecp.fr>
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
...@@ -89,7 +89,7 @@ static int MP4_ReadSample(); ...@@ -89,7 +89,7 @@ static int MP4_ReadSample();
static int MP4_DecodeSample(); static int MP4_DecodeSample();
#define MP4_Set4BytesLE( p, dw ) \ #define MP4_Set4BytesLE( p, dw ) \
*((u8*)p) = ( dw&0xff ); \ *((u8*)p) = ( (dw)&0xff ); \
*((u8*)p+1) = ( ((dw)>> 8)&0xff ); \ *((u8*)p+1) = ( ((dw)>> 8)&0xff ); \
*((u8*)p+2) = ( ((dw)>>16)&0xff ); \ *((u8*)p+2) = ( ((dw)>>16)&0xff ); \
*((u8*)p+3) = ( ((dw)>>24)&0xff ) *((u8*)p+3) = ( ((dw)>>24)&0xff )
...@@ -186,7 +186,11 @@ static int MP4Init( input_thread_t *p_input ) ...@@ -186,7 +186,11 @@ static int MP4Init( input_thread_t *p_input )
break; break;
default: default:
msg_Info( p_input, msg_Info( p_input,
"Unrecognize major file specification." ); "Unrecognize major file specification (%c%c%c%c).",
p_ftyp->data.p_ftyp->i_major_brand&0xff,
( p_ftyp->data.p_ftyp->i_major_brand >> 8)&0xff,
( p_ftyp->data.p_ftyp->i_major_brand >> 16 )&0xff,
( p_ftyp->data.p_ftyp->i_major_brand >> 24 )&0xff );
break; break;
} }
} }
...@@ -406,14 +410,7 @@ static void MP4End( input_thread_t *p_input ) ...@@ -406,14 +410,7 @@ static void MP4End( input_thread_t *p_input )
FREE(p_demux->track[i_track].chunk[i_chunk].p_sample_delta_dts ); FREE(p_demux->track[i_track].chunk[i_chunk].p_sample_delta_dts );
} }
} }
#if 0
/* if( p_demux->track->p_data_init )
{
input_DeletePacket( p_input->p_method_data,
p_demux->track->p_data_init );
}
*/
#endif
if( !p_demux->track[i_track].i_sample_size ) if( !p_demux->track[i_track].i_sample_size )
{ {
FREE( p_demux->track[i_track].p_sample_size ); FREE( p_demux->track[i_track].p_sample_size );
...@@ -754,7 +751,11 @@ static void MP4_StartDecoder( input_thread_t *p_input, ...@@ -754,7 +751,11 @@ static void MP4_StartDecoder( input_thread_t *p_input,
MP4_Box_t *p_sample; MP4_Box_t *p_sample;
int i; int i;
int i_chunk; int i_chunk;
u8 *p_bmih;
int i_decoder_specific_info_len;
u8 *p_decoder_specific_info;
u8 *p_init;
MP4_Box_t *p_esds; MP4_Box_t *p_esds;
...@@ -772,20 +773,29 @@ static void MP4_StartDecoder( input_thread_t *p_input, ...@@ -772,20 +773,29 @@ static void MP4_StartDecoder( input_thread_t *p_input,
if( !p_demux_track->chunk[i_chunk].i_sample_description_index ) if( !p_demux_track->chunk[i_chunk].i_sample_description_index )
{ {
msg_Warn( p_input, "invalid SampleEntry index for this track i_cat %d" ); msg_Warn( p_input,
"invalid SampleEntry index (track ID 0x%x)",
p_demux_track->i_track_ID );
return; return;
} }
p_sample = MP4_FindNbBox( p_demux_track->p_stsd, p_sample = MP4_FindNbBox( p_demux_track->p_stsd,
p_demux_track->chunk[i_chunk].i_sample_description_index - 1); p_demux_track->chunk[i_chunk].i_sample_description_index - 1);
if( !p_sample ) if( ( !p_sample )||( !p_sample->data.p_data ) )
{ {
msg_Warn( p_input, "cannot find SampleEntry for this track" ); msg_Warn( p_input,
"cannot find SampleEntry (track ID 0x%x)",
p_demux_track->i_track_ID );
return; return;
} }
if( !p_sample->data.p_data )
{
printf( "\nAhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh %.4s\n",
&p_sample->i_type );
return;
}
vlc_mutex_lock( &p_input->stream.stream_lock ); vlc_mutex_lock( &p_input->stream.stream_lock );
p_demux_track->p_es = input_AddES( p_input, p_demux_track->p_es = input_AddES( p_input,
p_input->stream.p_selected_program, p_input->stream.p_selected_program,
...@@ -803,68 +813,149 @@ static void MP4_StartDecoder( input_thread_t *p_input, ...@@ -803,68 +813,149 @@ static void MP4_StartDecoder( input_thread_t *p_input,
p_demux_track->p_es->i_fourcc = p_sample->i_type; p_demux_track->p_es->i_fourcc = p_sample->i_type;
p_demux_track->p_es->i_cat = p_demux_track->i_cat; p_demux_track->p_es->i_cat = p_demux_track->i_cat;
i_decoder_specific_info_len = 0;
p_decoder_specific_info = NULL;
/* now see if esds is present and if so create a data packet /* now see if esds is present and if so create a data packet
with decoder_specific_info */ with decoder_specific_info */
#define p_decconfig p_esds->data.p_esds->es_descriptor.p_decConfigDescr #define p_decconfig p_esds->data.p_esds->es_descriptor.p_decConfigDescr
if( ( p_esds = MP4_FindBox( p_sample, FOURCC_esds ) ) if( ( p_esds = MP4_FindBox( p_sample, FOURCC_esds ) )&&
&& p_decconfig && p_decconfig->i_decoder_specific_info_len ) ( p_esds->data.p_esds )&&
( p_decconfig ) )
{ {
data_packet_t *p_data; /* First update information based on i_objectTypeIndication */
int i_size = p_decconfig->i_decoder_specific_info_len; switch( p_decconfig->i_objectTypeIndication )
/* data packet for the data */
if( !(p_data = input_NewPacket( p_input->p_method_data, i_size ) ) )
{ {
return; case( 0x20 ): /* MPEG4 VIDEO */
p_demux_track->p_es->i_fourcc = VLC_FOURCC( 'm','p','4','v' );
break;
case( 0x40):
p_demux_track->p_es->i_fourcc = VLC_FOURCC( 'm','p','4','a' );
break;
case( 0x60):
case( 0x61):
case( 0x62):
case( 0x63):
case( 0x64):
case( 0x65): /* MPEG2 video */
p_demux_track->p_es->i_fourcc = VLC_FOURCC( 'm','p','g','v' );
break;
/* Theses are MPEG2-AAC (what is this codec ?) */
case( 0x66): /* main profile */
case( 0x67): /* Low complexity profile */
case( 0x68): /* Scaleable Sampling rate profile */
p_demux_track->p_es->i_fourcc = VLC_FOURCC( 'm','p','4','a' );
break;
/* true MPEG 2 audio */
case( 0x69):
p_demux_track->p_es->i_fourcc = VLC_FOURCC( 'm','p','g','a' );
break;
case( 0x6a): /* MPEG1 video */
p_demux_track->p_es->i_fourcc = VLC_FOURCC( 'm','p','g','v' );
break;
case( 0x6b): /* MPEG1 audio */
p_demux_track->p_es->i_fourcc = VLC_FOURCC( 'm','p','g','a' );
break;
case( 0x6c ): /* jpeg */
p_demux_track->p_es->i_fourcc = VLC_FOURCC( 'j','p','e','g' );
break;
default:
/* Unknown entry, but don't touch i_fourcc */
msg_Warn( p_input,
"objectTypeIndication(0x%x) unknow (Track ID 0x%x)",
p_decconfig->i_objectTypeIndication,
p_demux_track->i_track_ID );
break;
} }
i_decoder_specific_info_len =
memcpy( p_data->p_payload_start, p_decconfig->i_decoder_specific_info_len;
p_decconfig->p_decoder_specific_info, p_decoder_specific_info =
i_size ); p_decconfig->p_decoder_specific_info;
p_demux_track->p_data_init = p_data;
} }
#undef p_decconfig #undef p_decconfig
/* some last initialisation */ /* some last initialisation */
/* XXX I create a bitmapinfoheader_t or
waveformatex_t for each stream, up to now it's the best thing
I've found but it could exist a better solution :) as something
like adding some new fields in p_es ...
XXX I don't set all values, only thoses that are interesting or known
--> bitmapinfoheader_t : width and height
--> waveformatex_t : channels, samplerate, bitspersample
and at the end I add p_decoder_specific_info
TODO set more values
*/
switch( p_demux_track->i_cat ) switch( p_demux_track->i_cat )
{ {
case( VIDEO_ES ): case( VIDEO_ES ):
/* now create a bitmapinfoheader_t for decoder */ /* now create a bitmapinfoheader_t for decoder and
p_bmih = malloc( 40 ); add information found in p_esds */
memset( p_bmih, 0, 40); p_init = malloc( 40 + i_decoder_specific_info_len);
MP4_Set4BytesLE( p_bmih, 40 ); memset( p_init, 0, 40 + i_decoder_specific_info_len);
if( p_sample->data.p_sample_mp4v MP4_Set4BytesLE( p_init, 40 + i_decoder_specific_info_len );
&& p_sample->data.p_sample_mp4v->i_width ) if( p_sample->data.p_sample_vide->i_width )
{ {
MP4_Set4BytesLE( p_bmih + 4, MP4_Set4BytesLE( p_init + 4,
p_sample->data.p_sample_mp4v->i_width ); p_sample->data.p_sample_vide->i_width );
} }
else else
{ {
/* use display size */ /* use display size */
MP4_Set4BytesLE( p_bmih + 4, p_demux_track->i_width ); MP4_Set4BytesLE( p_init + 4, p_demux_track->i_width );
} }
if( p_sample->data.p_sample_mp4v if( p_sample->data.p_sample_vide->i_height )
&& p_sample->data.p_sample_mp4v->i_height )
{ {
MP4_Set4BytesLE( p_bmih + 8, MP4_Set4BytesLE( p_init + 8,
p_sample->data.p_sample_mp4v->i_height ); p_sample->data.p_sample_vide->i_height );
} }
else else
{ {
MP4_Set4BytesLE( p_bmih + 8, p_demux_track->i_height ); MP4_Set4BytesLE( p_init + 8, p_demux_track->i_height );
}
if( i_decoder_specific_info_len )
{
memcpy( p_init + 40,
p_decoder_specific_info,
i_decoder_specific_info_len);
} }
p_demux_track->p_es->p_demux_data = p_bmih;
break; break;
case( AUDIO_ES ): case( AUDIO_ES ):
p_init = malloc( 18 + i_decoder_specific_info_len);
memset( p_init, 0, 18 + i_decoder_specific_info_len);
MP4_Set2BytesLE( p_init + 2, /* i_channel */
p_sample->data.p_sample_soun->i_channelcount );
MP4_Set4BytesLE( p_init + 4, /* samplepersec */
p_sample->data.p_sample_soun->i_sampleratehi );
MP4_Set4BytesLE( p_init + 8, /* avgbytespersec */
p_sample->data.p_sample_soun->i_channelcount *
p_sample->data.p_sample_soun->i_sampleratehi *
(p_sample->data.p_sample_soun->i_samplesize/8) );
MP4_Set2BytesLE( p_init + 14, /* bits/sample */
p_sample->data.p_sample_soun->i_samplesize );
MP4_Set2BytesLE( p_init + 16, /* i_size, specific info len*/
i_decoder_specific_info_len );
if( i_decoder_specific_info_len )
{
memcpy( p_init + 18,
p_decoder_specific_info,
i_decoder_specific_info_len);
}
break; break;
default: default:
p_init = NULL;
break; break;
} }
p_demux_track->p_es->p_demux_data = p_init;
vlc_mutex_lock( &p_input->stream.stream_lock ); vlc_mutex_lock( &p_input->stream.stream_lock );
input_SelectES( p_input, p_demux_track->p_es ); input_SelectES( p_input, p_demux_track->p_es );
vlc_mutex_unlock( &p_input->stream.stream_lock ); vlc_mutex_unlock( &p_input->stream.stream_lock );
...@@ -872,7 +963,6 @@ static void MP4_StartDecoder( input_thread_t *p_input, ...@@ -872,7 +963,6 @@ static void MP4_StartDecoder( input_thread_t *p_input,
p_demux_track->b_ok = 1; p_demux_track->b_ok = 1;
} }
static void MP4_StopDecoder( input_thread_t *p_input, static void MP4_StopDecoder( input_thread_t *p_input,
track_data_mp4_t *p_demux_track ) track_data_mp4_t *p_demux_track )
{ {
...@@ -881,13 +971,6 @@ static void MP4_StopDecoder( input_thread_t *p_input, ...@@ -881,13 +971,6 @@ static void MP4_StopDecoder( input_thread_t *p_input,
input_UnselectES( p_input, p_demux_track->p_es ); input_UnselectES( p_input, p_demux_track->p_es );
p_demux_track->p_es = NULL; p_demux_track->p_es = NULL;
if( p_demux_track->p_data_init )
{
input_DeletePacket( p_input->p_method_data,
p_demux_track->p_data_init );
p_demux_track->p_data_init = NULL;
}
} }
static int MP4_ReadSample( input_thread_t *p_input, static int MP4_ReadSample( input_thread_t *p_input,
...@@ -908,7 +991,8 @@ static int MP4_ReadSample( input_thread_t *p_input, ...@@ -908,7 +991,8 @@ static int MP4_ReadSample( input_thread_t *p_input,
} }
/* caculate size and position for this sample */ /* caculate size and position for this sample */
i_size = p_demux_track->i_sample_size ? i_size = p_demux_track->i_sample_size ?
p_demux_track->i_sample_size : p_demux_track->p_sample_size[p_demux_track->i_sample]; p_demux_track->i_sample_size :
p_demux_track->p_sample_size[p_demux_track->i_sample];
/* TODO */ /* TODO */
i_pos = MP4_GetTrackPos( p_demux_track ); i_pos = MP4_GetTrackPos( p_demux_track );
...@@ -974,28 +1058,6 @@ static int MP4_DecodeSample( input_thread_t *p_input, ...@@ -974,28 +1058,6 @@ static int MP4_DecodeSample( input_thread_t *p_input,
p_pes->i_pts * 9/100); p_pes->i_pts * 9/100);
if( p_demux_track->p_data_init )
{
pes_packet_t *p_pes_init;
/* create a pes packet containing decoder initialisation
with the one we will send to decoder */
if( !(p_pes_init = input_NewPES( p_input->p_method_data ) ) )
{
msg_Err( p_input, "out of memory" );
return( 0 );
}
p_pes_init->p_first =
p_pes_init->p_last = p_demux_track->p_data_init;
p_pes_init->i_pes_size = p_demux_track->p_data_init->p_payload_end -
p_demux_track->p_data_init->p_payload_start;
p_pes_init->i_nb_data = 1;
input_DecodePES( p_demux_track->p_es->p_decoder_fifo, p_pes_init );
p_demux_track->p_data_init = NULL;
}
input_DecodePES( p_demux_track->p_es->p_decoder_fifo, p_pes ); input_DecodePES( p_demux_track->p_es->p_decoder_fifo, p_pes );
/* now update sample position */ /* now update sample position */
...@@ -1020,8 +1082,10 @@ static int MP4_DecodeSample( input_thread_t *p_input, ...@@ -1020,8 +1082,10 @@ static int MP4_DecodeSample( input_thread_t *p_input,
!= p_demux_track->chunk[p_demux_track->i_chunk].i_sample_description_index ) != p_demux_track->chunk[p_demux_track->i_chunk].i_sample_description_index )
{ {
/* FIXME */ /* FIXME */
msg_Err( p_input, "I need to change the decoder but not yet implemented" ); msg_Warn( p_input,
return( 0 ); "SampleEntry have changed, starting a new decoder" );
MP4_StopDecoder( p_input, p_demux_track );
MP4_StartDecoder( p_input, p_demux_track );
} }
} }
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* mp4.h : MP4 file input module for vlc * mp4.h : MP4 file input module for vlc
***************************************************************************** *****************************************************************************
* Copyright (C) 2001 VideoLAN * Copyright (C) 2001 VideoLAN
* $Id: mp4.h,v 1.5 2002/07/23 00:39:17 sam Exp $ * $Id: mp4.h,v 1.6 2002/07/23 17:19:02 fenrir Exp $
* Authors: Laurent Aimar <fenrir@via.ecp.fr> * Authors: Laurent Aimar <fenrir@via.ecp.fr>
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
...@@ -23,12 +23,11 @@ ...@@ -23,12 +23,11 @@
/***************************************************************************** /*****************************************************************************
* Structure needed for ffmpeg decoder * Structure needed for decoder
*****************************************************************************/ *****************************************************************************/
typedef struct bitmapinfoheader_s typedef struct bitmapinfoheader_s
{ {
u32 i_size; /* size of header */ u32 i_size; /* size of header 40 + size of data follwoing this header */
u32 i_width; u32 i_width;
u32 i_height; u32 i_height;
u16 i_planes; u16 i_planes;
...@@ -41,7 +40,17 @@ typedef struct bitmapinfoheader_s ...@@ -41,7 +40,17 @@ typedef struct bitmapinfoheader_s
u32 i_clrimportant; u32 i_clrimportant;
} bitmapinfoheader_t; } bitmapinfoheader_t;
typedef struct waveformatex_s
{
u16 i_format;
u16 i_channels;
u32 i_samplepersec;
u32 i_avgbytespersec;
u16 i_blockalign;
u16 i_bitspersample;
u16 i_size; /* This give size of data
imediatly following this header. */
} waveformatex_t;
/***************************************************************************** /*****************************************************************************
* Contain all information about a chunk * Contain all information about a chunk
...@@ -103,8 +112,6 @@ typedef struct track_data_mp4_s ...@@ -103,8 +112,6 @@ typedef struct track_data_mp4_s
too much time to do sumations each time*/ too much time to do sumations each time*/
es_descriptor_t *p_es; /* vlc es for this track */ es_descriptor_t *p_es; /* vlc es for this track */
data_packet_t *p_data_init; /* send this with the first packet,
and then discarded it*/
MP4_Box_t *p_stbl; /* will contain all timing information */ MP4_Box_t *p_stbl; /* will contain all timing information */
MP4_Box_t *p_stsd; /* will contain all data to initialize decoder */ MP4_Box_t *p_stsd; /* will contain all data to initialize decoder */
...@@ -199,4 +206,3 @@ static inline mtime_t MP4_GetMoviePTS(demux_data_mp4_t *p_demux ) ...@@ -199,4 +206,3 @@ static inline mtime_t MP4_GetMoviePTS(demux_data_mp4_t *p_demux )
(mtime_t)p_demux->i_timescale ) (mtime_t)p_demux->i_timescale )
); );
} }
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