Commit 17f1d1d0 authored by Laurent Aimar's avatar Laurent Aimar

* transcode: accept and create raw video(I420,I422,I444,YUY2,RV24).

parent 85bc5997
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* transcode.c * transcode.c
***************************************************************************** *****************************************************************************
* Copyright (C) 2001, 2002 VideoLAN * Copyright (C) 2001, 2002 VideoLAN
* $Id: transcode.c,v 1.5 2003/04/29 22:44:08 fenrir Exp $ * $Id: transcode.c,v 1.6 2003/05/02 03:41:03 fenrir Exp $
* *
* Authors: Laurent Aimar <fenrir@via.ecp.fr> * Authors: Laurent Aimar <fenrir@via.ecp.fr>
* *
...@@ -329,9 +329,10 @@ static sout_stream_id_t * Add ( sout_stream_t *p_stream, sout_format_t *p_f ...@@ -329,9 +329,10 @@ static sout_stream_id_t * Add ( sout_stream_t *p_stream, sout_format_t *p_f
free( id ); free( id );
return NULL; return NULL;
} }
#if 0
/* open output stream */ /* open output stream */
id->id = p_sys->p_out->pf_add( p_sys->p_out, &id->f_dst ); id->id = p_sys->p_out->pf_add( p_sys->p_out, &id->f_dst );
#endif
id->b_transcode = VLC_TRUE; id->b_transcode = VLC_TRUE;
} }
else else
...@@ -395,10 +396,15 @@ static int Send ( sout_stream_t *p_stream, sout_stream_id_t *id, sout_bu ...@@ -395,10 +396,15 @@ static int Send ( sout_stream_t *p_stream, sout_stream_id_t *id, sout_bu
} }
return VLC_SUCCESS; return VLC_SUCCESS;
} }
else else if( id->id != NULL )
{ {
return p_sys->p_out->pf_send( p_sys->p_out, id->id, p_buffer ); return p_sys->p_out->pf_send( p_sys->p_out, id->id, p_buffer );
} }
else
{
sout_BufferDelete( p_stream->p_sout, p_buffer );
return VLC_EGENERIC;
}
} }
/**************************************************************************** /****************************************************************************
...@@ -433,6 +439,13 @@ static struct ...@@ -433,6 +439,13 @@ static struct
{ VLC_FOURCC( 'd', 'v', 's', 'l' ), CODEC_ID_DVVIDEO }, { VLC_FOURCC( 'd', 'v', 's', 'l' ), CODEC_ID_DVVIDEO },
{ VLC_FOURCC( 'S', 'V', 'Q', '1' ), CODEC_ID_SVQ1 }, { VLC_FOURCC( 'S', 'V', 'Q', '1' ), CODEC_ID_SVQ1 },
/* raw video code, only used for 'encoding' */
{ VLC_FOURCC( 'I', '4', '2', '0' ), CODEC_ID_RAWVIDEO },
{ VLC_FOURCC( 'I', '4', '2', '2' ), CODEC_ID_RAWVIDEO },
{ VLC_FOURCC( 'I', '4', '4', '4' ), CODEC_ID_RAWVIDEO },
{ VLC_FOURCC( 'R', 'V', '2', '4' ), CODEC_ID_RAWVIDEO },
{ VLC_FOURCC( 'Y', 'U', 'Y', '2' ), CODEC_ID_RAWVIDEO },
{ VLC_FOURCC( 0, 0, 0, 0 ), 0 } { VLC_FOURCC( 0, 0, 0, 0 ), 0 }
}; };
...@@ -451,6 +464,25 @@ static inline int get_ff_codec( vlc_fourcc_t i_fcc ) ...@@ -451,6 +464,25 @@ static inline int get_ff_codec( vlc_fourcc_t i_fcc )
return 0; return 0;
} }
static inline int get_ff_chroma( vlc_fourcc_t i_chroma )
{
switch( i_chroma )
{
case VLC_FOURCC( 'I', '4', '2', '0' ):
return PIX_FMT_YUV420P;
case VLC_FOURCC( 'I', '4', '2', '2' ):
return PIX_FMT_YUV422P;
case VLC_FOURCC( 'I', '4', '4', '4' ):
return PIX_FMT_YUV444P;
case VLC_FOURCC( 'R', 'V', '2', '4' ):
return PIX_FMT_RGB24;
case VLC_FOURCC( 'Y', 'U', 'Y', '2' ):
return PIX_FMT_YUV422;
default:
return 0;
}
}
static int transcode_audio_ffmpeg_new ( sout_stream_t *p_stream, sout_stream_id_t *id ) static int transcode_audio_ffmpeg_new ( sout_stream_t *p_stream, sout_stream_id_t *id )
{ {
int i_ff_codec; int i_ff_codec;
...@@ -641,50 +673,65 @@ static int transcode_video_ffmpeg_new ( sout_stream_t *p_stream, sout_stream_i ...@@ -641,50 +673,65 @@ static int transcode_video_ffmpeg_new ( sout_stream_t *p_stream, sout_stream_i
{ {
int i_ff_codec; int i_ff_codec;
/* find decoder */ if( id->f_src.i_fourcc == VLC_FOURCC( 'I', '4', '2', '0' ) ||
i_ff_codec = get_ff_codec( id->f_src.i_fourcc ); id->f_src.i_fourcc == VLC_FOURCC( 'I', '4', '2', '2' ) ||
if( i_ff_codec == 0 ) id->f_src.i_fourcc == VLC_FOURCC( 'I', '4', '4', '4' ) ||
id->f_src.i_fourcc == VLC_FOURCC( 'Y', 'U', 'Y', '2' ) ||
id->f_src.i_fourcc == VLC_FOURCC( 'R', 'V', '2', '4' ) )
{ {
msg_Err( p_stream, "cannot find decoder" ); id->ff_dec = NULL;
return VLC_EGENERIC; id->ff_dec_c = avcodec_alloc_context();
id->ff_dec_c->width = id->f_src.i_width;
id->ff_dec_c->height = id->f_src.i_height;
id->ff_dec_c->pix_fmt = get_ff_chroma( id->f_src.i_fourcc );
} }
else
id->ff_dec = avcodec_find_decoder( i_ff_codec );
if( !id->ff_dec )
{ {
msg_Err( p_stream, "cannot find decoder" ); /* find decoder */
return VLC_EGENERIC; i_ff_codec = get_ff_codec( id->f_src.i_fourcc );
} if( i_ff_codec == 0 )
{
msg_Err( p_stream, "cannot find decoder" );
return VLC_EGENERIC;
}
id->ff_dec_c = avcodec_alloc_context(); id->ff_dec = avcodec_find_decoder( i_ff_codec );
id->ff_dec_c->width = id->f_src.i_width; if( !id->ff_dec )
id->ff_dec_c->height = id->f_src.i_height; {
/* id->ff_dec_c->bit_rate = id->f_src.i_bitrate; */ msg_Err( p_stream, "cannot find decoder" );
id->ff_dec_c->extradata_size= id->f_src.i_extra_data; return VLC_EGENERIC;
id->ff_dec_c->extradata = id->f_src.p_extra_data; }
id->ff_dec_c->workaround_bugs = FF_BUG_AUTODETECT;
id->ff_dec_c->error_resilience= -1;
if( id->ff_dec->capabilities & CODEC_CAP_TRUNCATED )
{
id->ff_dec_c->flags |= CODEC_FLAG_TRUNCATED;
}
if( avcodec_open( id->ff_dec_c, id->ff_dec ) < 0 ) id->ff_dec_c = avcodec_alloc_context();
{ id->ff_dec_c->width = id->f_src.i_width;
msg_Err( p_stream, "cannot open decoder" ); id->ff_dec_c->height = id->f_src.i_height;
return VLC_EGENERIC; /* id->ff_dec_c->bit_rate = id->f_src.i_bitrate; */
} id->ff_dec_c->extradata_size= id->f_src.i_extra_data;
#if 1 id->ff_dec_c->extradata = id->f_src.p_extra_data;
if( i_ff_codec == CODEC_ID_MPEG4 && id->ff_dec_c->extradata_size > 0 ) id->ff_dec_c->workaround_bugs = FF_BUG_AUTODETECT;
{ id->ff_dec_c->error_resilience= -1;
int b_gotpicture; if( id->ff_dec->capabilities & CODEC_CAP_TRUNCATED )
AVFrame frame; {
id->ff_dec_c->flags |= CODEC_FLAG_TRUNCATED;
}
if( avcodec_open( id->ff_dec_c, id->ff_dec ) < 0 )
{
msg_Err( p_stream, "cannot open decoder" );
return VLC_EGENERIC;
}
avcodec_decode_video( id->ff_dec_c, &frame, if( i_ff_codec == CODEC_ID_MPEG4 && id->ff_dec_c->extradata_size > 0 )
&b_gotpicture, {
id->ff_dec_c->extradata, id->ff_dec_c->extradata_size ); int b_gotpicture;
AVFrame frame;
avcodec_decode_video( id->ff_dec_c, &frame,
&b_gotpicture,
id->ff_dec_c->extradata, id->ff_dec_c->extradata_size );
}
} }
#endif
/* find encoder */ /* find encoder */
i_ff_codec = get_ff_codec( id->f_dst.i_fourcc ); i_ff_codec = get_ff_codec( id->f_dst.i_fourcc );
...@@ -714,14 +761,12 @@ static int transcode_video_ffmpeg_new ( sout_stream_t *p_stream, sout_stream_i ...@@ -714,14 +761,12 @@ static int transcode_video_ffmpeg_new ( sout_stream_t *p_stream, sout_stream_i
id->ff_enc_c->gop_size = 25; id->ff_enc_c->gop_size = 25;
id->ff_enc_c->qmin = 2; id->ff_enc_c->qmin = 2;
id->ff_enc_c->qmax = 31; id->ff_enc_c->qmax = 31;
#if 0
/* XXX open it when we have the first frame */ if( i_ff_codec == CODEC_ID_RAWVIDEO )
if( avcodec_open( id->ff_enc_c, id->ff_enc ) )
{ {
msg_Err( p_stream, "cannot open encoder" ); id->ff_enc_c->pix_fmt = get_ff_chroma( id->f_dst.i_fourcc );
return VLC_EGENERIC;
} }
#endif /* XXX open it only when we have the first frame */
id->b_enc_inited = VLC_FALSE; id->b_enc_inited = VLC_FALSE;
id->i_buffer_in = 0; id->i_buffer_in = 0;
id->i_buffer_in_pos = 0; id->i_buffer_in_pos = 0;
...@@ -745,7 +790,10 @@ static int transcode_video_ffmpeg_new ( sout_stream_t *p_stream, sout_stream_i ...@@ -745,7 +790,10 @@ static int transcode_video_ffmpeg_new ( sout_stream_t *p_stream, sout_stream_i
static void transcode_video_ffmpeg_close ( sout_stream_t *p_stream, sout_stream_id_t *id ) static void transcode_video_ffmpeg_close ( sout_stream_t *p_stream, sout_stream_id_t *id )
{ {
avcodec_close( id->ff_dec_c ); if( id->ff_dec )
{
avcodec_close( id->ff_dec_c );
}
if( id->b_enc_inited ) if( id->b_enc_inited )
{ {
avcodec_close( id->ff_enc_c ); avcodec_close( id->ff_enc_c );
...@@ -802,9 +850,22 @@ static int transcode_video_ffmpeg_process( sout_stream_t *p_stream, sout_stream_ ...@@ -802,9 +850,22 @@ static int transcode_video_ffmpeg_process( sout_stream_t *p_stream, sout_stream_
{ {
/* decode frame */ /* decode frame */
frame = id->p_ff_pic; frame = id->p_ff_pic;
i_used = avcodec_decode_video( id->ff_dec_c, frame, if( id->ff_dec )
&b_gotpicture, {
p_data, i_data ); i_used = avcodec_decode_video( id->ff_dec_c, frame,
&b_gotpicture,
p_data, i_data );
}
else
{
/* raw video */
avpicture_fill( (AVPicture*)frame,
p_data,
id->ff_dec_c->pix_fmt,
id->ff_dec_c->width, id->ff_dec_c->height );
i_used = i_data;
b_gotpicture = 1;
}
if( i_used < 0 ) if( i_used < 0 )
{ {
...@@ -823,10 +884,10 @@ static int transcode_video_ffmpeg_process( sout_stream_t *p_stream, sout_stream_ ...@@ -823,10 +884,10 @@ static int transcode_video_ffmpeg_process( sout_stream_t *p_stream, sout_stream_
{ {
/* XXX hack because of copy packetizer and mpeg4video that can failed /* XXX hack because of copy packetizer and mpeg4video that can failed
detecting size */ detecting size */
if( id->ff_enc_c->width == 0 || id->ff_enc_c->height == 0 ) if( id->ff_enc_c->width <= 0 || id->ff_enc_c->height <= 0 )
{ {
id->ff_enc_c->width = id->ff_dec_c->width; id->ff_enc_c->width = id->f_dst.i_width = id->ff_dec_c->width;
id->ff_enc_c->height = id->ff_dec_c->height; id->ff_enc_c->height = id->f_dst.i_height = id->ff_dec_c->height;
} }
if( avcodec_open( id->ff_enc_c, id->ff_enc ) ) if( avcodec_open( id->ff_enc_c, id->ff_enc ) )
...@@ -834,6 +895,14 @@ static int transcode_video_ffmpeg_process( sout_stream_t *p_stream, sout_stream_ ...@@ -834,6 +895,14 @@ static int transcode_video_ffmpeg_process( sout_stream_t *p_stream, sout_stream_
msg_Err( p_stream, "cannot open encoder" ); msg_Err( p_stream, "cannot open encoder" );
return VLC_EGENERIC; return VLC_EGENERIC;
} }
if( !( id->id = p_stream->p_sys->p_out->pf_add( p_stream->p_sys->p_out, &id->f_dst ) ) )
{
msg_Err( p_stream, "cannot add this stream" );
transcode_video_ffmpeg_close( p_stream, id );
id->b_transcode = VLC_FALSE;
return VLC_EGENERIC;
}
id->b_enc_inited = VLC_TRUE; id->b_enc_inited = VLC_TRUE;
} }
...@@ -920,9 +989,7 @@ static int transcode_video_ffmpeg_process( sout_stream_t *p_stream, sout_stream_ ...@@ -920,9 +989,7 @@ static int transcode_video_ffmpeg_process( sout_stream_t *p_stream, sout_stream_
frame = id->p_ff_pic_tmp2; frame = id->p_ff_pic_tmp2;
} }
/* encode frame */
i_out = avcodec_encode_video( id->ff_enc_c, id->p_buffer, id->i_buffer, frame ); i_out = avcodec_encode_video( id->ff_enc_c, id->p_buffer, id->i_buffer, frame );
if( i_out > 0 ) if( i_out > 0 )
{ {
sout_buffer_t *p_out; sout_buffer_t *p_out;
......
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