00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include <vlc/vlc.h>
00028 #include <vlc/vout.h>
00029
00030
00031 #ifdef HAVE_FFMPEG_AVCODEC_H
00032 # include <ffmpeg/avcodec.h>
00033 #else
00034 # include <avcodec.h>
00035 #endif
00036
00037 #include "ffmpeg.h"
00038
00039 void E_(InitLibavcodec) ( vlc_object_t *p_object );
00040 static void ChromaConversion( vout_thread_t *, picture_t *, picture_t * );
00041
00042
00043
00044
00045
00046
00047
00048 struct chroma_sys_t
00049 {
00050 int i_src_vlc_chroma;
00051 int i_src_ffmpeg_chroma;
00052 int i_dst_vlc_chroma;
00053 int i_dst_ffmpeg_chroma;
00054 AVPicture tmp_pic;
00055 ImgReSampleContext *p_rsc;
00056 };
00057
00058
00059
00060
00061
00062
00063 int E_(OpenChroma)( vlc_object_t *p_this )
00064 {
00065 vout_thread_t *p_vout = (vout_thread_t *)p_this;
00066 int i_ffmpeg_chroma[2], i_vlc_chroma[2], i;
00067
00068
00069
00070
00071 i_vlc_chroma[0] = p_vout->render.i_chroma;
00072 i_vlc_chroma[1] = p_vout->output.i_chroma;
00073 for( i = 0; i < 2; i++ )
00074 {
00075 i_ffmpeg_chroma[i] = E_(GetFfmpegChroma)( i_vlc_chroma[i] );
00076 if( i_ffmpeg_chroma[i] < 0 ) return VLC_EGENERIC;
00077 }
00078
00079 p_vout->chroma.pf_convert = ChromaConversion;
00080
00081 p_vout->chroma.p_sys = malloc( sizeof( chroma_sys_t ) );
00082 if( p_vout->chroma.p_sys == NULL )
00083 {
00084 return VLC_EGENERIC;
00085 }
00086
00087 p_vout->chroma.p_sys->i_src_vlc_chroma = p_vout->render.i_chroma;
00088 p_vout->chroma.p_sys->i_dst_vlc_chroma = p_vout->output.i_chroma;
00089 p_vout->chroma.p_sys->i_src_ffmpeg_chroma = i_ffmpeg_chroma[0];
00090 p_vout->chroma.p_sys->i_dst_ffmpeg_chroma = i_ffmpeg_chroma[1];
00091
00092 if( ( p_vout->render.i_height != p_vout->output.i_height ||
00093 p_vout->render.i_width != p_vout->output.i_width ) &&
00094 ( p_vout->chroma.p_sys->i_dst_vlc_chroma == VLC_FOURCC('I','4','2','0') ||
00095 p_vout->chroma.p_sys->i_dst_vlc_chroma == VLC_FOURCC('Y','V','1','2') ))
00096
00097 {
00098 msg_Dbg( p_vout, "preparing to resample picture" );
00099 p_vout->chroma.p_sys->p_rsc =
00100 img_resample_init( p_vout->output.i_width, p_vout->output.i_height,
00101 p_vout->render.i_width, p_vout->render.i_height );
00102 avpicture_alloc( &p_vout->chroma.p_sys->tmp_pic,
00103 p_vout->chroma.p_sys->i_dst_ffmpeg_chroma,
00104 p_vout->render.i_width, p_vout->render.i_height );
00105 }
00106 else
00107 {
00108 msg_Dbg( p_vout, "no resampling" );
00109 p_vout->chroma.p_sys->p_rsc = NULL;
00110 }
00111
00112
00113 E_(InitLibavcodec)(p_this);
00114
00115 return VLC_SUCCESS;
00116 }
00117
00118
00119
00120
00121 static void ChromaConversion( vout_thread_t *p_vout,
00122 picture_t *p_src, picture_t *p_dest )
00123 {
00124 AVPicture src_pic;
00125 AVPicture dest_pic;
00126 int i;
00127
00128
00129 for( i = 0; i < p_src->i_planes; i++ )
00130 {
00131 src_pic.data[i] = p_src->p[i].p_pixels;
00132 src_pic.linesize[i] = p_src->p[i].i_pitch;
00133 }
00134 for( i = 0; i < p_dest->i_planes; i++ )
00135 {
00136 dest_pic.data[i] = p_dest->p[i].p_pixels;
00137 dest_pic.linesize[i] = p_dest->p[i].i_pitch;
00138 }
00139
00140
00141 if( p_vout->chroma.p_sys->i_src_vlc_chroma == VLC_FOURCC('Y','V','1','2') ||
00142 p_vout->chroma.p_sys->i_src_vlc_chroma == VLC_FOURCC('Y','V','U','9') )
00143 {
00144
00145 src_pic.data[1] = p_src->p[2].p_pixels;
00146 src_pic.data[2] = p_src->p[1].p_pixels;
00147 }
00148 if( p_vout->chroma.p_sys->i_dst_vlc_chroma == VLC_FOURCC('Y','V','1','2') ||
00149 p_vout->chroma.p_sys->i_dst_vlc_chroma == VLC_FOURCC('Y','V','U','9') )
00150 {
00151
00152 dest_pic.data[1] = p_dest->p[2].p_pixels;
00153 dest_pic.data[2] = p_dest->p[1].p_pixels;
00154 }
00155 if( p_vout->chroma.p_sys->i_src_ffmpeg_chroma == PIX_FMT_RGB24 )
00156 if( p_vout->render.i_bmask == 0x00ff0000 )
00157 p_vout->chroma.p_sys->i_src_ffmpeg_chroma = PIX_FMT_BGR24;
00158
00159 if( p_vout->chroma.p_sys->p_rsc )
00160 {
00161 img_convert( &p_vout->chroma.p_sys->tmp_pic,
00162 p_vout->chroma.p_sys->i_dst_ffmpeg_chroma,
00163 &src_pic, p_vout->chroma.p_sys->i_src_ffmpeg_chroma,
00164 p_vout->render.i_width, p_vout->render.i_height );
00165 img_resample( p_vout->chroma.p_sys->p_rsc, &dest_pic,
00166 &p_vout->chroma.p_sys->tmp_pic );
00167 }
00168 else
00169 {
00170 img_convert( &dest_pic, p_vout->chroma.p_sys->i_dst_ffmpeg_chroma,
00171 &src_pic, p_vout->chroma.p_sys->i_src_ffmpeg_chroma,
00172 p_vout->render.i_width, p_vout->render.i_height );
00173 }
00174 }
00175
00176
00177
00178
00179
00180
00181 void E_(CloseChroma)( vlc_object_t *p_this )
00182 {
00183 vout_thread_t *p_vout = (vout_thread_t *)p_this;
00184 if( p_vout->chroma.p_sys->p_rsc )
00185 {
00186 img_resample_close( p_vout->chroma.p_sys->p_rsc );
00187 avpicture_free( &p_vout->chroma.p_sys->tmp_pic );
00188 }
00189 free( p_vout->chroma.p_sys );
00190 }