[vlc-devel] [PATCH 2/2] codec/dirac: Rewrite libdirac(-research) encoding support
Laurent Aimar
fenrir at via.ecp.fr
Mon Nov 10 21:29:25 CET 2008
Hi,
It seems to be missing my latest remarks, I will not repeat them
and will simply wait for a new version.
There are additionnal comments:
> +static mtime_t GetPicturePTS( encoder_t *p_enc, uint32_t u_pnum )
> +{
> + encoder_sys_t *p_sys = p_enc->p_sys;
> +
> + for( int i=0; i<PTS_TLB_SIZE; i++ ) {
> + if( (!p_sys->pts_tlb[i].i_empty) &&
> + (p_sys->pts_tlb[i].u_pnum == u_pnum)) {
Useless parenthesis.
> +/*****************************************************************************
> * OpenEncoder: probe the encoder and return score
> *****************************************************************************/
> static int OpenEncoder( vlc_object_t *p_this )
> @@ -95,7 +428,6 @@ static int OpenEncoder( vlc_object_t *p_this )
> encoder_t *p_enc = (encoder_t *)p_this;
> encoder_sys_t *p_sys = p_enc->p_sys;
> vlc_value_t val;
> - float f_quality;
>
> if( p_enc->fmt_out.i_codec != VLC_FOURCC('d','r','a','c') &&
> !p_enc->b_force )
> @@ -107,58 +439,319 @@ static int OpenEncoder( vlc_object_t *p_this )
> if( ( p_sys = (encoder_sys_t *)malloc(sizeof(encoder_sys_t)) ) == NULL )
Useless cast in C. Using sizeof(*p_sys) may be safer.
> memset( p_sys, 0, sizeof(encoder_sys_t) );
... missing * or use *p_sys or use calloc iof the above malloc.
> - dirac_encoder_context_init( &p_sys->ctx, VIDEO_FORMAT_CUSTOM );
> - /* */
> + /* guess the video format based upon number of lines and picture height */
> + int i = 0;
> + VideoFormat guessed_video_fmt = VIDEO_FORMAT_CUSTOM;
> + do {
> + if( dirac_format_guess[i].i_height != p_enc->fmt_in.video.i_height )
> + continue;
> + int src_fps = p_enc->fmt_in.video.i_frame_rate / p_enc->fmt_in.video.i_frame_rate_base;
You MUST check the frame rate validity (x/0 is allowed when the frame rate
information is not availaible or N/A).
Same a bit later for date_Init.
> + if ( !val.psz_string ) {}
> + else if ( !strcmp( val.psz_string, "420" ) ) {
> + p_enc->fmt_in.i_codec = VLC_FOURCC('I','4','2','0');
> + p_enc->fmt_in.video.i_bits_per_pixel = 12;
> + p_sys->ctx.src_params.chroma = format420;
> + p_sys->i_buffer_in = p_enc->fmt_in.video.i_width * p_enc->fmt_in.video.i_height * 3 / 2;
> + }
> + else if ( !strcmp( val.psz_string, "422" ) ) {
> + p_enc->fmt_in.i_codec = VLC_FOURCC('I','4','2','2');
> + p_enc->fmt_in.video.i_bits_per_pixel = 16;
> + p_sys->ctx.src_params.chroma = format422;
> + p_sys->i_buffer_in = p_enc->fmt_in.video.i_width * p_enc->fmt_in.video.i_height * 2;
> + }
> + else if ( !strcmp( val.psz_string, "444" ) ) {
> + p_enc->fmt_in.i_codec = VLC_FOURCC('I','4','4','4');
> + p_enc->fmt_in.video.i_bits_per_pixel = 24;
> + p_sys->ctx.src_params.chroma = format444;
> + p_sys->i_buffer_in = p_enc->fmt_in.video.i_width * p_enc->fmt_in.video.i_height * 3;
> + }
> + if( val.psz_string )
> + free( val.psz_string );
Some parameters seem not initialied to a valid value if !val.psz_string or
val.psz_string is not a valid value.
(Either handle this case as I420 or as a fatal error).
It seems to be the case for other string variables.
> /****************************************************************************
> * Encode: the whole thing
> ****************************************************************************
> - * This function spits out ogg packets.
> + * This function spits out encapsulation units.
> ****************************************************************************/
> static block_t *Encode( encoder_t *p_enc, picture_t *p_pic )
> {
> encoder_sys_t *p_sys = p_enc->p_sys;
> - block_t *p_block, *p_chain = NULL;
> + block_t *p_block, *p_output_chain = NULL;
> int i_plane, i_line, i_width, i_src_stride;
> uint8_t *p_dst;
>
> - /* Copy input picture in encoder input buffer (stride by stride) */
> + /* we only know if the sequence is interlaced when the first
> + * picture arrives, so final setup is done here */
> + /* XXX todo, detect change of interlace */
> + p_sys->ctx.src_params.topfieldfirst = p_pic->b_top_field_first;
> + p_sys->ctx.src_params.source_sampling = !p_pic->b_progressive;
> +
> + if( p_sys->b_auto_field_coding )
> + p_sys->ctx.enc_params.picture_coding_mode = !p_pic->b_progressive;
> +
> + if( !p_sys->p_dirac )
> + {
> + date_t date;
> + /* Initialise the encoder with the encoder context */
> + p_sys->p_dirac = dirac_encoder_init( &p_sys->ctx, 0 );
> + if( !p_sys->p_dirac )
> + {
> + msg_Err( p_enc, "Failed to initialize dirac encoder\n" );
> + p_enc->b_error = 1;
I think it will segfault after that as p_dirac is NULL.
> + /* store pts in a lookaside buffer, so that the same pts may
> + * be used for the picture in coded order */
> + StorePicturePTS( p_enc, p_sys->i_input_picnum, p_pic->date );
> + p_sys->i_input_picnum++;
> +
> + /* store dts in a queue, so that they appear in order in
> + * coded order */
> + p_block = block_New( p_enc, 1 );
> + p_block->i_dts = p_pic->date - p_sys->i_pts_offset;
p_block MUST be checked.
> + block_FifoPut( p_sys->p_dts_fifo, p_block );
> + p_block = NULL;
> +
> + /* for field coding mode, insert an extra value into both the
> + * pts lookaside buffer and dts queue, offset to correspond
> + * to a one field delay. */
> + if( 1 == p_sys->ctx.enc_params.picture_coding_mode ) {
> + StorePicturePTS( p_enc, p_sys->i_input_picnum, p_pic->date + p_sys->i_field_time );
> + p_sys->i_input_picnum++;
> +
> + p_block = block_New( p_enc, 1 );
> + p_block->i_dts = p_pic->date - p_sys->i_pts_offset + p_sys->i_field_time;
Same here.
> + block_FifoPut( p_sys->p_dts_fifo, p_block );
> + p_block = NULL;
> + }
> + dirac_encoder_state_t state;
> + /* Retrieve encoded frames from encoder */
> + do
> + p_sys->p_dirac->enc_buf.buffer = p_sys->p_buffer_out;
> + p_sys->p_dirac->enc_buf.size = ENC_BUFSIZE;
> + state = dirac_encoder_output( p_sys->p_dirac );
> + switch( state )
> + {
> + case ENC_STATE_AVAIL: {
> + uint32_t pic_num;
> +
> + /* extract data from encoder temporary buffer. */
> + p_block = block_New( p_enc, p_sys->p_dirac->enc_buf.size );
> + memcpy( p_block->p_buffer, p_sys->p_dirac->enc_buf.buffer,
> + p_sys->p_dirac->enc_buf.size );
Same here.
Regards,
--
fenrir
More information about the vlc-devel
mailing list