Commit d44f9d26 authored by Gildas Bazin's avatar Gildas Bazin

* include/vlc_codec.h: defines decoders/encoders related structures here.
* include/vlc_video.h: new video_frame_format_t structure which defines the properties of a video frame.
* include/vlc/decoder.h: include vlc_codec.h
* src/misc/objects.c: added VLC_OBJECT_PACKETIZER and VLC_OBJECT_ENCODER object types.
* modules/stream_out/transcode.c, modules/codec/theora.c: experimental theora video encoder.
* src/input/*: some cleanup.
parent c28682f6
......@@ -91,6 +91,7 @@ HEADERS_include = \
include/video_output.h \
include/vlc_block.h \
include/vlc_block_helper.h \
include/vlc_codec.h \
include/vlc_common.h \
include/vlc_config.h \
include/vlc_cpu.h \
......
......@@ -2,7 +2,7 @@
* audio_output.h : audio output interface
*****************************************************************************
* Copyright (C) 2002 VideoLAN
* $Id: audio_output.h,v 1.82 2003/08/14 11:47:32 gbazin Exp $
* $Id: audio_output.h,v 1.83 2003/10/08 21:01:07 gbazin Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
*
......@@ -20,6 +20,8 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
#ifndef _VLC_AUDIO_OUTPUT_H
#define _VLC_AUDIO_OUTPUT_H 1
/*****************************************************************************
* audio_sample_format_t
......@@ -208,3 +210,4 @@ VLC_EXPORT( int, aout_Restart, ( aout_instance_t * p_aout ) );
VLC_EXPORT( int, aout_FindAndRestart, ( vlc_object_t *, const char *, vlc_value_t, vlc_value_t, void * ) );
VLC_EXPORT( int, aout_ChannelsRestart, ( vlc_object_t *, const char *, vlc_value_t, vlc_value_t, void * ) );
#endif /* _VLC_AUDIO_OUTPUT_H */
......@@ -2,7 +2,7 @@
* input_ext-dec.h: structures exported to the VideoLAN decoders
*****************************************************************************
* Copyright (C) 1999-2001 VideoLAN
* $Id: input_ext-dec.h,v 1.80 2003/09/02 20:19:25 gbazin Exp $
* $Id: input_ext-dec.h,v 1.81 2003/10/08 21:01:07 gbazin Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
* Michel Kaempf <maxx@via.ecp.fr>
......@@ -113,29 +113,6 @@ struct decoder_fifo_t
decoder_t * p_dec;
};
/*****************************************************************************
* decoder_t
*****************************************************************************
* The decoder descriptor.
*****************************************************************************/
struct decoder_t
{
VLC_COMMON_MEMBERS
/* Module properties */
module_t * p_module;
decoder_sys_t * p_sys;
int ( * pf_init ) ( decoder_t * );
int ( * pf_decode )( decoder_t *, block_t * );
int ( * pf_end ) ( decoder_t * );
/* Input properties */
decoder_fifo_t * p_fifo; /* stores the PES stream data */
/* Tmp field for old decoder api */
int ( * pf_run ) ( decoder_fifo_t * );
};
/*****************************************************************************
* bit_fifo_t : bit fifo descriptor
*****************************************************************************
......
......@@ -2,7 +2,7 @@
* decoder.h: header for vlc decoders
*****************************************************************************
* Copyright (C) 2002 VideoLAN
* $Id: decoder.h,v 1.2 2003/09/02 20:19:25 gbazin Exp $
* $Id: decoder.h,v 1.3 2003/10/08 21:01:07 gbazin Exp $
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
......@@ -37,6 +37,9 @@ extern "C" {
#include "vlc_block.h"
#include "stream_control.h"
#include "input_ext-dec.h"
#include "vlc_video.h"
#include "audio_output.h"
#include "vlc_codec.h"
# ifdef __cplusplus
}
......
/*****************************************************************************
* vlc_codec.h: codec related structures
*****************************************************************************
* Copyright (C) 1999-2003 VideoLAN
* $Id: vlc_codec.h,v 1.1 2003/10/08 21:01:07 gbazin Exp $
*
* Authors: Gildas Bazin <gbazin@netcourrier.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
#ifndef _VLC_CODEC_H
#define _VLC_CODEC_H 1
/**
* \file
* This file defines the structure and types used by decoders and encoders
*/
/**
* \defgroup decoder Decoder
*
* The structure describing a decoder
*
* @{
*/
struct decoder_t
{
VLC_COMMON_MEMBERS
/* Module properties */
module_t * p_module;
decoder_sys_t * p_sys;
int ( * pf_init ) ( decoder_t * );
int ( * pf_decode )( decoder_t *, block_t * );
int ( * pf_end ) ( decoder_t * );
/* Input properties */
decoder_fifo_t * p_fifo; /* stores the PES stream data */
/* Tmp field for old decoder api */
int ( * pf_run ) ( decoder_fifo_t * );
};
/**
* @}
*/
/**
* \defgroup decoder Encoder
*
* The structure describing a Encoder
*
* @{
*/
struct encoder_t
{
VLC_COMMON_MEMBERS
/* Module properties */
module_t * p_module;
encoder_sys_t * p_sys;
block_t * ( * pf_header )( encoder_t * );
block_t * ( * pf_encode_video )( encoder_t *, picture_t * );
block_t * ( * pf_encode_audio )( encoder_t *, aout_buffer_t * );
/* Properties of the input data fed to the encoder */
union {
audio_sample_format_t audio;
video_frame_format_t video;
} format;
/* Properties of the output of the encoder */
vlc_fourcc_t i_fourcc;
int i_bitrate;
};
/**
* @}
*/
#endif /* _VLC_CODEC_H */
......@@ -2,7 +2,7 @@
* hotkeys.h: keycode defines
*****************************************************************************
* Copyright (C) 2003 VideoLAN
* $Id: vlc_keys.h,v 1.1 2003/08/14 19:25:55 sigmunau Exp $
* $Id: vlc_keys.h,v 1.2 2003/10/08 21:01:07 gbazin Exp $
*
* Authors: Sigmund Augdal <sigmunau@idi.ntnu.no>
*
......@@ -58,12 +58,15 @@
#define KEY_ASCII 0x0000007F
#define KEY_UNSET 0
typedef struct key_descriptor_s
{
char *psz_key_string;
int i_key_code;
} key_descriptor_t;
#define ADD_KEY(a) { a, *a }
static const struct key_descriptor_s modifiers[] =
{
{ "Alt", KEY_MODIFIER_ALT },
......
......@@ -2,7 +2,7 @@
* vlc_objects.h: vlc_object_t definition.
*****************************************************************************
* Copyright (C) 2002 VideoLAN
* $Id: vlc_objects.h,v 1.18 2003/09/18 17:54:02 zorglub Exp $
* $Id: vlc_objects.h,v 1.19 2003/10/08 21:01:07 gbazin Exp $
*
* Authors: Samuel Hocevar <sam@zoy.org>
*
......@@ -46,6 +46,8 @@
#define VLC_OBJECT_AOUT (-10)
#define VLC_OBJECT_SOUT (-11)
#define VLC_OBJECT_HTTPD (-12)
#define VLC_OBJECT_PACKETIZER (-13)
#define VLC_OBJECT_ENCODER (-14)
#define VLC_OBJECT_GENERIC (-666)
......
......@@ -4,7 +4,7 @@
* includes all common video types and constants.
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
* $Id: vlc_video.h,v 1.3 2003/10/04 15:51:22 sigmunau Exp $
* $Id: vlc_video.h,v 1.4 2003/10/08 21:01:07 gbazin Exp $
*
* Authors: Vincent Seguin <seguin@via.ecp.fr>
*
......@@ -22,6 +22,20 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
#ifndef _VLC_VIDEO_H
#define _VLC_VIDEO_H 1
/**
* Description of a video frame
*/
typedef struct video_frame_format_t
{
unsigned int i_width; /**< picture width */
unsigned int i_height; /**< picture height */
vlc_fourcc_t i_chroma; /**< picture chroma */
unsigned int i_aspect; /**< aspect ratio */
} video_frame_format_t;
/**
* Description of a planar graphic field
......@@ -247,3 +261,5 @@ struct subpicture_t
#define READY_SUBPICTURE 2 /* ready for display */
/**@}*/
#endif /* _VLC_VIDEO_H */
......@@ -2,7 +2,7 @@
* theora.c: theora decoder module making use of libtheora.
*****************************************************************************
* Copyright (C) 1999-2001 VideoLAN
* $Id: theora.c,v 1.8 2003/09/28 21:54:20 gbazin Exp $
* $Id: theora.c,v 1.9 2003/10/08 21:01:07 gbazin Exp $
*
* Authors: Gildas Bazin <gbazin@netcourrier.com>
*
......@@ -90,9 +90,13 @@ static int DecodePacket ( decoder_t *, ogg_packet * );
static int SendPacket ( decoder_t *, ogg_packet * );
static void ParseTheoraComments( decoder_t * );
static void theora_CopyPicture( decoder_t *, picture_t *, yuv_buffer * );
static int OpenEncoder( vlc_object_t *p_this );
static void CloseEncoder( vlc_object_t *p_this );
static block_t *Headers( encoder_t *p_enc );
static block_t *Encode( encoder_t *p_enc, picture_t *p_pict );
/*****************************************************************************
* Module descriptor
*****************************************************************************/
......@@ -107,6 +111,12 @@ vlc_module_begin();
set_capability( "packetizer", 100 );
set_callbacks( OpenPacketizer, NULL );
add_shortcut( "theora" );
add_submodule();
set_description( _("Theora video encoder") );
set_capability( "video encoder", 100 );
set_callbacks( OpenEncoder, CloseEncoder );
add_shortcut( "theora" );
vlc_module_end();
/*****************************************************************************
......@@ -515,3 +525,193 @@ static void theora_CopyPicture( decoder_t *p_dec, picture_t *p_pic,
}
}
}
/*****************************************************************************
* encoder_sys_t : theora encoder descriptor
*****************************************************************************/
struct encoder_sys_t
{
/*
* Input properties
*/
int i_headers;
/*
* Theora properties
*/
theora_info ti; /* theora bitstream settings */
theora_comment tc; /* theora comment header */
theora_state td; /* theora bitstream user comments */
/*
* Packetizer output properties
*/
sout_packetizer_input_t *p_sout_input;
sout_format_t sout_format;
/*
* Common properties
*/
mtime_t i_pts;
};
/*****************************************************************************
* OpenEncoder: probe the encoder and return score
*****************************************************************************/
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;
if( p_enc->i_fourcc != VLC_FOURCC('t','h','e','o') )
{
return VLC_EGENERIC;
}
/* Allocate the memory needed to store the decoder's structure */
if( ( p_sys = (encoder_sys_t *)malloc(sizeof(encoder_sys_t)) ) == NULL )
{
msg_Err( p_enc, "out of memory" );
return VLC_EGENERIC;
}
p_enc->p_sys = p_sys;
p_enc->pf_header = Headers;
p_enc->pf_encode_video = Encode;
p_enc->format.video.i_chroma = VLC_FOURCC('I','4','2','0');
#define frame_x_offset 0
#define frame_y_offset 0
#define video_hzn 25
#define video_hzd 1
#define video_an 4
#define video_ad 3
#define video_q 5
theora_info_init( &p_sys->ti );
p_sys->ti.width = p_enc->format.video.i_width;
p_sys->ti.height = p_enc->format.video.i_height;
p_sys->ti.frame_width = p_enc->format.video.i_width;
p_sys->ti.frame_height = p_enc->format.video.i_height;
p_sys->ti.offset_x = frame_x_offset;
p_sys->ti.offset_y = frame_y_offset;
p_sys->ti.fps_numerator = video_hzn;
p_sys->ti.fps_denominator = video_hzd;
p_sys->ti.aspect_numerator = video_an;
p_sys->ti.aspect_denominator = video_ad;
p_sys->ti.colorspace = not_specified;
p_sys->ti.target_bitrate = p_enc->i_bitrate;
p_sys->ti.quality = video_q;
p_sys->ti.dropframes_p = 0;
p_sys->ti.quick_p = 1;
p_sys->ti.keyframe_auto_p = 1;
p_sys->ti.keyframe_frequency = 64;
p_sys->ti.keyframe_frequency_force = 64;
p_sys->ti.keyframe_data_target_bitrate = p_enc->i_bitrate * 1.5;
p_sys->ti.keyframe_auto_threshold = 80;
p_sys->ti.keyframe_mindistance = 8;
p_sys->ti.noise_sensitivity = 1;
theora_encode_init( &p_sys->td, &p_sys->ti );
theora_info_clear( &p_sys->ti );
p_sys->i_headers = 0;
return VLC_SUCCESS;
}
/****************************************************************************
* Encode: the whole thing
****************************************************************************
* This function spits out ogg packets.
****************************************************************************/
static block_t *Headers( encoder_t *p_enc )
{
encoder_sys_t *p_sys = p_enc->p_sys;
ogg_packet oggpacket;
block_t *p_block;
/* Create theora headers */
switch( p_sys->i_headers )
{
case 0:
theora_encode_header( &p_sys->td, &oggpacket );
break;
case 1:
theora_comment_init( &p_sys->tc );
theora_encode_comment( &p_sys->tc, &oggpacket );
break;
case 2:
theora_encode_tables( &p_sys->td, &oggpacket );
break;
default:
}
p_sys->i_headers++;
if( p_sys->i_headers > 3 ) return NULL;
/* Ogg packet to block */
p_block = block_New( p_enc, oggpacket.bytes );
p_block->p_buffer = oggpacket.packet;
p_block->i_buffer = oggpacket.bytes;
p_block->i_dts = oggpacket.granulepos;
return p_block;
}
/****************************************************************************
* Encode: the whole thing
****************************************************************************
* This function spits out ogg packets.
****************************************************************************/
static block_t *Encode( encoder_t *p_enc, picture_t *p_pict )
{
encoder_sys_t *p_sys = p_enc->p_sys;
ogg_packet oggpacket;
block_t *p_block;
yuv_buffer yuv;
int i_ret;
/* Theora is a one-frame-in, one-frame-out system. Submit a frame
* for compression and pull out the packet. */
yuv.y_width = p_pict->p[0].i_visible_pitch;
yuv.y_height = p_pict->p[0].i_lines;
yuv.y_stride = p_pict->p[0].i_pitch;
yuv.uv_width = p_pict->p[1].i_visible_pitch;
yuv.uv_height = p_pict->p[1].i_lines;
yuv.uv_stride = p_pict->p[1].i_pitch;
yuv.y = p_pict->p[0].p_pixels;
yuv.u = p_pict->p[1].p_pixels;
yuv.v = p_pict->p[2].p_pixels;
theora_encode_YUVin( &p_sys->td, &yuv );
theora_encode_packetout( &p_sys->td, 0, &oggpacket );
/* Ogg packet to block */
p_block = block_New( p_enc, oggpacket.bytes );
p_block->p_buffer = oggpacket.packet;
p_block->i_buffer = oggpacket.bytes;
p_block->i_dts = oggpacket.granulepos;
return p_block;
}
/*****************************************************************************
* CloseEncoder: theora encoder destruction
*****************************************************************************/
static void CloseEncoder( vlc_object_t *p_this )
{
encoder_t *p_enc = (encoder_t *)p_this;
encoder_sys_t *p_sys = p_enc->p_sys;
theora_info_clear( &p_sys->ti );
theora_comment_clear( &p_sys->tc );
free( p_sys );
}
......@@ -2,7 +2,7 @@
* transcode.c
*****************************************************************************
* Copyright (C) 2001, 2002 VideoLAN
* $Id: transcode.c,v 1.34 2003/10/04 10:54:45 gbazin Exp $
* $Id: transcode.c,v 1.35 2003/10/08 21:01:07 gbazin Exp $
*
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
*
......@@ -30,6 +30,8 @@
#include <vlc/vlc.h>
#include <vlc/input.h>
#include <vlc/sout.h>
#include <vlc/vout.h>
#include <vlc/decoder.h>
/* ffmpeg header */
#ifdef HAVE_FFMPEG_AVCODEC_H
......@@ -320,6 +322,9 @@ struct sout_stream_id_t
/* id of the out stream */
void *id;
/* Encoder */
encoder_t *p_encoder;
/* ffmpeg part */
AVCodec *ff_dec;
AVCodecContext *ff_dec_c;
......@@ -373,6 +378,8 @@ static sout_stream_id_t * Add( sout_stream_t *p_stream, sout_format_t *p_fmt )
id = malloc( sizeof( sout_stream_id_t ) );
id->i_dts = 0;
id->id = NULL;
id->p_encoder = NULL;
if( p_fmt->i_cat == AUDIO_ES && p_sys->i_acodec != 0 )
{
msg_Dbg( p_stream,
......@@ -1215,20 +1222,78 @@ static int transcode_video_ffmpeg_new( sout_stream_t *p_stream,
/* find encoder */
id->ff_enc = NULL;
i_ff_codec = get_ff_codec( id->f_dst.i_fourcc );
if( i_ff_codec == 0 )
if( i_ff_codec != 0 )
{
msg_Err( p_stream, "cannot find encoder" );
return VLC_EGENERIC;
id->ff_enc = avcodec_find_encoder( i_ff_codec );
}
id->ff_enc = avcodec_find_encoder( i_ff_codec );
/* Hack for external encoders */
if( !id->ff_enc )
{
id->p_encoder = vlc_object_create( p_stream, VLC_OBJECT_ENCODER );
id->p_encoder->i_fourcc = id->f_dst.i_fourcc;
id->p_encoder->format.video.i_width = p_sys->i_width;
id->p_encoder->format.video.i_height = p_sys->i_height;
id->p_encoder->i_bitrate = p_sys->i_vbitrate;
if( id->p_encoder->format.video.i_width <= 0 )
{
id->p_encoder->format.video.i_width = id->f_dst.i_width =
id->ff_dec_c->width - p_sys->i_crop_left -
p_sys->i_crop_right;
}
if( id->p_encoder->format.video.i_height <= 0 )
{
id->p_encoder->format.video.i_height = id->f_dst.i_height =
id->ff_dec_c->height - p_sys->i_crop_top -
p_sys->i_crop_bottom;
}
id->p_encoder->p_module =
module_Need( id->p_encoder, "video encoder", NULL );
if( !id->p_encoder->p_module )
{
free( id->p_encoder );
id->p_encoder = NULL;
}
}
/* End hack for external encoders */
if( !id->ff_enc && !id->p_encoder )
{
msg_Err( p_stream, "cannot find encoder" );
return VLC_EGENERIC;
}
/* XXX open it only when we have the first frame */
id->b_enc_inited = VLC_FALSE;
id->i_buffer_in = 0;
id->i_buffer_in_pos = 0;
id->p_buffer_in = NULL;
id->i_buffer = 3*1024*1024;
id->i_buffer_pos = 0;
id->p_buffer = malloc( id->i_buffer );
id->i_buffer_out = 0;
id->i_buffer_out_pos = 0;
id->p_buffer_out = NULL;
id->p_ff_pic = avcodec_alloc_frame();
id->p_ff_pic_tmp0 = NULL;
id->p_ff_pic_tmp1 = NULL;
id->p_ff_pic_tmp2 = NULL;
id->p_vresample = NULL;
p_sys->i_last_ref_pts = 0;
p_sys->i_buggy_pts_detect = 0;
/* This is enough for external encoders */
if( id->p_encoder->p_module ) return VLC_SUCCESS;
if( id->f_dst.i_fourcc == VLC_FOURCC( 'm','p','1','v' )||
id->f_dst.i_fourcc == VLC_FOURCC( 'm','p','2','v' ) )
{
......@@ -1282,28 +1347,6 @@ static int transcode_video_ffmpeg_new( sout_stream_t *p_stream,
{
id->ff_enc_c->pix_fmt = get_ff_chroma( id->f_dst.i_fourcc );
}
/* XXX open it only when we have the first frame */
id->b_enc_inited = VLC_FALSE;
id->i_buffer_in = 0;
id->i_buffer_in_pos = 0;
id->p_buffer_in = NULL;
id->i_buffer = 3*1024*1024;
id->i_buffer_pos = 0;
id->p_buffer = malloc( id->i_buffer );
id->i_buffer_out = 0;
id->i_buffer_out_pos = 0;
id->p_buffer_out = NULL;
id->p_ff_pic = avcodec_alloc_frame();
id->p_ff_pic_tmp0 = NULL;
id->p_ff_pic_tmp1 = NULL;
id->p_ff_pic_tmp2 = NULL;
id->p_vresample = NULL;
p_sys->i_last_ref_pts = 0;
p_sys->i_buggy_pts_detect = 0;
return VLC_SUCCESS;
}
......@@ -1314,7 +1357,13 @@ static void transcode_video_ffmpeg_close ( sout_stream_t *p_stream, sout_stream_
{
avcodec_close( id->ff_dec_c );
}
if( id->b_enc_inited )
if( id->p_encoder )
{
/* External encoding */
module_Unneed( p_stream, id->p_encoder->p_module );
vlc_object_destroy( id->p_encoder->p_module );
}
else if( id->b_enc_inited )
{
avcodec_close( id->ff_enc_c );
}
......@@ -1346,7 +1395,6 @@ static void transcode_video_ffmpeg_close ( sout_stream_t *p_stream, sout_stream_
free( id->ff_dec_c );
free( id->ff_enc_c );
free( id->p_buffer );
}
......@@ -1412,10 +1460,50 @@ static int transcode_video_ffmpeg_process( sout_stream_t *p_stream,
p_sys->i_output_pts = frame->pts;
}
if( !id->b_enc_inited )
if( !id->b_enc_inited && id->p_encoder )
{
/* XXX hack because of copy packetizer and mpeg4video that can failed
detecting size */
block_t *p_block;
/* XXX hack because of copy packetizer and mpeg4video that can fail
* detecting size */
#if 0
if( id->p_encoder->i_width <= 0 )
{
id->p_encoder->i_width = id->f_dst.i_width =
id->ff_dec_c->width - p_sys->i_crop_left -
p_sys->i_crop_right;
}
if( id->p_encoder->i_height <= 0 )
{
id->p_encoder->i_height = id->f_dst.i_height =
id->ff_dec_c->height - p_sys->i_crop_top -
p_sys->i_crop_bottom;
}
#endif
id->p_encoder->i_bitrate = p_sys->i_vbitrate;
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" );
id->b_transcode = VLC_FALSE;
return VLC_EGENERIC;
}
while( (p_block = id->p_encoder->pf_header( id->p_encoder )) )
{
sout_buffer_t *p_out;
p_out = sout_BufferNew( p_stream->p_sout, p_block->i_buffer );
memcpy( p_out->p_buffer, p_block->p_buffer, p_block->i_buffer);
sout_BufferChain( out, p_out );
}
id->b_enc_inited = VLC_TRUE;
}
else if( !id->b_enc_inited )
{
/* XXX hack because of copy packetizer and mpeg4video that can fail
* detecting size */
if( id->ff_enc_c->width <= 0 )
{
id->ff_enc_c->width =
......@@ -1479,6 +1567,7 @@ static int transcode_video_ffmpeg_process( sout_stream_t *p_stream,
}
/* convert pix format */
if( !id->p_encoder )
if( id->ff_dec_c->pix_fmt != id->ff_enc_c->pix_fmt )
{
if( id->p_ff_pic_tmp1 == NULL )
......@@ -1504,6 +1593,7 @@ static int transcode_video_ffmpeg_process( sout_stream_t *p_stream,
}
/* convert size and crop */
if( !id->p_encoder )
if( id->ff_dec_c->width != id->ff_enc_c->width ||
id->ff_dec_c->height != id->ff_enc_c->height ||