Commit 14054532 authored by Ilkka Ollakka's avatar Ilkka Ollakka

transcoding video, sends NULL when ending. Should fix sending all the encoded frames to sout

Sends NULL-pict to encode when it's closing time, then encoder knows to
flush buffers and check that it has outputted all the frames.

Contains changes to x264/avcodec-module to implement that on encoder-side.
Add quick check on omxil/dirac/theora for that, so they don't crash.
And add likely-macro to x264/avcodec in check of NULL

If someone more familiar with dirac/theora/omxil encoder-modules could
check if they have buffers that need to be outputted, would be nice.

Fixes some tickets, but I failed to find any of those in trac.
parent d8bc8db8
...@@ -720,6 +720,7 @@ static block_t *EncodeVideo( encoder_t *p_enc, picture_t *p_pict ) ...@@ -720,6 +720,7 @@ static block_t *EncodeVideo( encoder_t *p_enc, picture_t *p_pict )
memset( &frame, 0, sizeof( AVFrame ) ); memset( &frame, 0, sizeof( AVFrame ) );
if( likely(p_pict) ) {
for( i_plane = 0; i_plane < p_pict->i_planes; i_plane++ ) for( i_plane = 0; i_plane < p_pict->i_planes; i_plane++ )
{ {
frame.data[i_plane] = p_pict->p[i_plane].p_pixels; frame.data[i_plane] = p_pict->p[i_plane].p_pixels;
...@@ -814,6 +815,12 @@ static block_t *EncodeVideo( encoder_t *p_enc, picture_t *p_pict ) ...@@ -814,6 +815,12 @@ static block_t *EncodeVideo( encoder_t *p_enc, picture_t *p_pict )
i_out = avcodec_encode_video( p_sys->p_context, p_sys->p_buffer_out, i_out = avcodec_encode_video( p_sys->p_context, p_sys->p_buffer_out,
p_sys->i_buffer_out, &frame ); p_sys->i_buffer_out, &frame );
}
else
{
i_out = avcodec_encode_video( p_sys->p_context, p_sys->p_buffer_out,
p_sys->i_buffer_out, NULL);
}
if( i_out > 0 ) if( i_out > 0 )
{ {
......
...@@ -781,6 +781,7 @@ static block_t *Encode( encoder_t *p_enc, picture_t *p_pic ) ...@@ -781,6 +781,7 @@ static block_t *Encode( encoder_t *p_enc, picture_t *p_pic )
int i_plane, i_line, i_width, i_src_stride; int i_plane, i_line, i_width, i_src_stride;
uint8_t *p_dst; uint8_t *p_dst;
if( !p_pic ) return NULL;
/* we only know if the sequence is interlaced when the first /* we only know if the sequence is interlaced when the first
* picture arrives, so final setup is done here */ * picture arrives, so final setup is done here */
/* XXX todo, detect change of interlace */ /* XXX todo, detect change of interlace */
......
...@@ -1302,11 +1302,13 @@ static block_t *EncodeVideo( encoder_t *p_enc, picture_t *p_pic ) ...@@ -1302,11 +1302,13 @@ static block_t *EncodeVideo( encoder_t *p_enc, picture_t *p_pic )
OMX_BUFFERHEADERTYPE *p_header; OMX_BUFFERHEADERTYPE *p_header;
block_t *p_block = 0; block_t *p_block = 0;
if( !p_pic ) return NULL;
/* Check for errors from codec */ /* Check for errors from codec */
if(p_sys->b_error) if(p_sys->b_error)
{ {
msg_Dbg(p_dec, "error during encoding"); msg_Dbg(p_dec, "error during encoding");
return 0; return NULL;
} }
/* Send the input buffer to the component */ /* Send the input buffer to the component */
......
...@@ -676,6 +676,7 @@ static block_t *Encode( encoder_t *p_enc, picture_t *p_pict ) ...@@ -676,6 +676,7 @@ static block_t *Encode( encoder_t *p_enc, picture_t *p_pict )
yuv_buffer yuv; yuv_buffer yuv;
int i; int i;
if( !p_pict ) return NULL;
/* Sanity check */ /* Sanity check */
if( p_pict->p[0].i_pitch < (int)p_sys->i_width || if( p_pict->p[0].i_pitch < (int)p_sys->i_width ||
p_pict->p[0].i_lines < (int)p_sys->i_height ) p_pict->p[0].i_lines < (int)p_sys->i_height )
......
...@@ -1292,10 +1292,11 @@ static block_t *Encode( encoder_t *p_enc, picture_t *p_pict ) ...@@ -1292,10 +1292,11 @@ static block_t *Encode( encoder_t *p_enc, picture_t *p_pict )
x264_picture_t pic; x264_picture_t pic;
x264_nal_t *nal; x264_nal_t *nal;
block_t *p_block; block_t *p_block;
int i_nal, i_out, i; int i_nal=0, i_out=0, i=0;
/* init pic */ /* init pic */
memset( &pic, 0, sizeof( x264_picture_t ) ); memset( &pic, 0, sizeof( x264_picture_t ) );
if( likely(p_pict) ) {
pic.i_pts = p_pict->date; pic.i_pts = p_pict->date;
pic.img.i_csp = X264_CSP_I420; pic.img.i_csp = X264_CSP_I420;
pic.img.i_plane = p_pict->i_planes; pic.img.i_plane = p_pict->i_planes;
...@@ -1306,6 +1307,11 @@ static block_t *Encode( encoder_t *p_enc, picture_t *p_pict ) ...@@ -1306,6 +1307,11 @@ static block_t *Encode( encoder_t *p_enc, picture_t *p_pict )
} }
x264_encoder_encode( p_sys->h, &nal, &i_nal, &pic, &pic ); x264_encoder_encode( p_sys->h, &nal, &i_nal, &pic, &pic );
} else {
if( x264_encoder_delayed_frames( p_sys->h ) ) {
x264_encoder_encode( p_sys->h, &nal, &i_nal, NULL, &pic );
}
}
if( !i_nal ) return NULL; if( !i_nal ) return NULL;
......
...@@ -637,6 +637,7 @@ static int Del( sout_stream_t *p_stream, sout_stream_id_t *id ) ...@@ -637,6 +637,7 @@ static int Del( sout_stream_t *p_stream, sout_stream_id_t *id )
transcode_audio_close( id ); transcode_audio_close( id );
break; break;
case VIDEO_ES: case VIDEO_ES:
Send( p_stream, id, NULL );
transcode_video_close( p_stream, id ); transcode_video_close( p_stream, id );
break; break;
case SPU_ES: case SPU_ES:
......
...@@ -535,6 +535,19 @@ int transcode_video_process( sout_stream_t *p_stream, sout_stream_id_t *id, ...@@ -535,6 +535,19 @@ int transcode_video_process( sout_stream_t *p_stream, sout_stream_id_t *id,
picture_t *p_pic, *p_pic2 = NULL; picture_t *p_pic, *p_pic2 = NULL;
*out = NULL; *out = NULL;
if( in == NULL )
{
block_t *p_block;
do {
video_timer_start( id->p_encoder );
p_block = id->p_encoder->pf_encode_video(id->p_encoder, NULL );
video_timer_stop( id->p_encoder );
block_ChainAppend( out, p_block );
} while( p_block );
return VLC_SUCCESS;
}
while( (p_pic = id->p_decoder->pf_decode_video( id->p_decoder, &in )) ) while( (p_pic = id->p_decoder->pf_decode_video( id->p_decoder, &in )) )
{ {
subpicture_t *p_subpic = NULL; subpicture_t *p_subpic = NULL;
......
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