Main Page | Modules | Class Hierarchy | Class List | Directories | File List | Class Members | File Members | Related Pages

vout_pictures.c

00001 /*****************************************************************************
00002  * vout_pictures.c : picture management functions
00003  *****************************************************************************
00004  * Copyright (C) 2000-2004 the VideoLAN team
00005  * $Id: vout_pictures.c 13026 2005-10-30 15:32:11Z gbazin $
00006  *
00007  * Authors: Vincent Seguin <[email protected]>
00008  *          Samuel Hocevar <[email protected]>
00009  *
00010  * This program is free software; you can redistribute it and/or modify
00011  * it under the terms of the GNU General Public License as published by
00012  * the Free Software Foundation; either version 2 of the License, or
00013  * (at your option) any later version.
00014  *
00015  * This program is distributed in the hope that it will be useful,
00016  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018  * GNU General Public License for more details.
00019  *
00020  * You should have received a copy of the GNU General Public License
00021  * along with this program; if not, write to the Free Software
00022  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
00023  *****************************************************************************/
00024 
00025 /*****************************************************************************
00026  * Preamble
00027  *****************************************************************************/
00028 #include <stdlib.h>                                                /* free() */
00029 #include <stdio.h>                                              /* sprintf() */
00030 #include <string.h>                                            /* strerror() */
00031 
00032 #include <vlc/vlc.h>
00033 
00034 #include "vlc_video.h"
00035 #include "video_output.h"
00036 #include "vlc_spu.h"
00037 
00038 #include "vout_pictures.h"
00039 
00047 void vout_DisplayPicture( vout_thread_t *p_vout, picture_t *p_pic )
00048 {
00049     vlc_mutex_lock( &p_vout->picture_lock );
00050     switch( p_pic->i_status )
00051     {
00052     case RESERVED_PICTURE:
00053         p_pic->i_status = RESERVED_DISP_PICTURE;
00054         break;
00055     case RESERVED_DATED_PICTURE:
00056         p_pic->i_status = READY_PICTURE;
00057         break;
00058     default:
00059         msg_Err( p_vout, "picture to display %p has invalid status %d",
00060                          p_pic, p_pic->i_status );
00061         break;
00062     }
00063 
00064     vlc_mutex_unlock( &p_vout->picture_lock );
00065 }
00066 
00077 void vout_DatePicture( vout_thread_t *p_vout,
00078                        picture_t *p_pic, mtime_t date )
00079 {
00080     vlc_mutex_lock( &p_vout->picture_lock );
00081     p_pic->date = date;
00082     switch( p_pic->i_status )
00083     {
00084     case RESERVED_PICTURE:
00085         p_pic->i_status = RESERVED_DATED_PICTURE;
00086         break;
00087     case RESERVED_DISP_PICTURE:
00088         p_pic->i_status = READY_PICTURE;
00089         break;
00090     default:
00091         msg_Err( p_vout, "picture to date %p has invalid status %d",
00092                          p_pic, p_pic->i_status );
00093         break;
00094     }
00095 
00096     vlc_mutex_unlock( &p_vout->picture_lock );
00097 }
00098 
00108 picture_t *vout_CreatePicture( vout_thread_t *p_vout,
00109                                vlc_bool_t b_progressive,
00110                                vlc_bool_t b_top_field_first,
00111                                unsigned int i_nb_fields )
00112 {
00113     int         i_pic;                                      /* picture index */
00114     picture_t * p_pic;
00115     picture_t * p_freepic = NULL;                      /* first free picture */
00116 
00117     /* Get lock */
00118     vlc_mutex_lock( &p_vout->picture_lock );
00119 
00120     /*
00121      * Look for an empty place in the picture heap.
00122      */
00123     for( i_pic = 0; i_pic < I_RENDERPICTURES; i_pic++ )
00124     {
00125         p_pic = PP_RENDERPICTURE[(p_vout->render.i_last_used_pic + i_pic + 1)
00126                                  % I_RENDERPICTURES];
00127 
00128         switch( p_pic->i_status )
00129         {
00130             case DESTROYED_PICTURE:
00131                 /* Memory will not be reallocated, and function can end
00132                  * immediately - this is the best possible case, since no
00133                  * memory allocation needs to be done */
00134                 p_pic->i_status   = RESERVED_PICTURE;
00135                 p_pic->i_refcount = 0;
00136                 p_pic->b_force    = 0;
00137 
00138                 p_pic->b_progressive        = b_progressive;
00139                 p_pic->i_nb_fields          = i_nb_fields;
00140                 p_pic->b_top_field_first    = b_top_field_first;
00141 
00142                 p_vout->i_heap_size++;
00143                 p_vout->render.i_last_used_pic =
00144                     ( p_vout->render.i_last_used_pic + i_pic + 1 )
00145                     % I_RENDERPICTURES;
00146                 vlc_mutex_unlock( &p_vout->picture_lock );
00147                 return( p_pic );
00148 
00149             case FREE_PICTURE:
00150                 /* Picture is empty and ready for allocation */
00151                 p_vout->render.i_last_used_pic =
00152                     ( p_vout->render.i_last_used_pic + i_pic + 1 )
00153                     % I_RENDERPICTURES;
00154                 p_freepic = p_pic;
00155                 break;
00156 
00157             default:
00158                 break;
00159         }
00160     }
00161 
00162     /*
00163      * Prepare picture
00164      */
00165     if( p_freepic != NULL )
00166     {
00167         vout_AllocatePicture( VLC_OBJECT(p_vout),
00168                               p_freepic, p_vout->render.i_chroma,
00169                               p_vout->render.i_width, p_vout->render.i_height,
00170                               p_vout->render.i_aspect );
00171 
00172         if( p_freepic->i_planes )
00173         {
00174             /* Copy picture information, set some default values */
00175             p_freepic->i_status   = RESERVED_PICTURE;
00176             p_freepic->i_type     = MEMORY_PICTURE;
00177             p_freepic->b_slow     = 0;
00178 
00179             p_freepic->i_refcount = 0;
00180             p_freepic->b_force = 0;
00181 
00182             p_freepic->b_progressive        = b_progressive;
00183             p_freepic->i_nb_fields          = i_nb_fields;
00184             p_freepic->b_top_field_first    = b_top_field_first;
00185 
00186             p_freepic->i_matrix_coefficients = 1;
00187 
00188             p_vout->i_heap_size++;
00189         }
00190         else
00191         {
00192             /* Memory allocation failed : set picture as empty */
00193             p_freepic->i_status = FREE_PICTURE;
00194             p_freepic = NULL;
00195 
00196             msg_Err( p_vout, "picture allocation failed" );
00197         }
00198 
00199         vlc_mutex_unlock( &p_vout->picture_lock );
00200 
00201         return( p_freepic );
00202     }
00203 
00204     /* No free or destroyed picture could be found, but the decoder
00205      * will try again in a while. */
00206     vlc_mutex_unlock( &p_vout->picture_lock );
00207 
00208     return( NULL );
00209 }
00210 
00218 void vout_DestroyPicture( vout_thread_t *p_vout, picture_t *p_pic )
00219 {
00220     vlc_mutex_lock( &p_vout->picture_lock );
00221 
00222 #ifdef DEBUG
00223     /* Check if picture status is valid */
00224     if( (p_pic->i_status != RESERVED_PICTURE) &&
00225         (p_pic->i_status != RESERVED_DATED_PICTURE) &&
00226         (p_pic->i_status != RESERVED_DISP_PICTURE) )
00227     {
00228         msg_Err( p_vout, "picture to destroy %p has invalid status %d",
00229                          p_pic, p_pic->i_status );
00230     }
00231 #endif
00232 
00233     p_pic->i_status = DESTROYED_PICTURE;
00234     p_vout->i_heap_size--;
00235 
00236     vlc_mutex_unlock( &p_vout->picture_lock );
00237 }
00238 
00245 void vout_LinkPicture( vout_thread_t *p_vout, picture_t *p_pic )
00246 {
00247     vlc_mutex_lock( &p_vout->picture_lock );
00248     p_pic->i_refcount++;
00249     vlc_mutex_unlock( &p_vout->picture_lock );
00250 }
00251 
00257 void vout_UnlinkPicture( vout_thread_t *p_vout, picture_t *p_pic )
00258 {
00259     vlc_mutex_lock( &p_vout->picture_lock );
00260     p_pic->i_refcount--;
00261 
00262     if( p_pic->i_refcount < 0 )
00263     {
00264         msg_Err( p_vout, "picture %p refcount is %i",
00265                  p_pic, p_pic->i_refcount );
00266         p_pic->i_refcount = 0;
00267     }
00268 
00269     if( ( p_pic->i_refcount == 0 ) &&
00270         ( p_pic->i_status == DISPLAYED_PICTURE ) )
00271     {
00272         p_pic->i_status = DESTROYED_PICTURE;
00273         p_vout->i_heap_size--;
00274     }
00275 
00276     vlc_mutex_unlock( &p_vout->picture_lock );
00277 }
00278 
00286 picture_t * vout_RenderPicture( vout_thread_t *p_vout, picture_t *p_pic,
00287                                                        subpicture_t *p_subpic )
00288 {
00289     int i_scale_width, i_scale_height;
00290 
00291     if( p_pic == NULL )
00292     {
00293         /* XXX: subtitles */
00294         return NULL;
00295     }
00296 
00297     i_scale_width = p_vout->fmt_out.i_visible_width * 1000 /
00298         p_vout->fmt_in.i_visible_width;
00299     i_scale_height = p_vout->fmt_out.i_visible_height * 1000 /
00300         p_vout->fmt_in.i_visible_height;
00301 
00302     if( p_pic->i_type == DIRECT_PICTURE )
00303     {
00304         if( !p_vout->render.b_allow_modify_pics || p_pic->i_refcount ||
00305             p_pic->b_force )
00306         {
00307             /* Picture is in a direct buffer and is still in use,
00308              * we need to copy it to another direct buffer before
00309              * displaying it if there are subtitles. */
00310             if( p_subpic != NULL )
00311             {
00312                 /* We have subtitles. First copy the picture to
00313                  * the spare direct buffer, then render the
00314                  * subtitles. */
00315                 vout_CopyPicture( p_vout, PP_OUTPUTPICTURE[0], p_pic );
00316 
00317                 spu_RenderSubpictures( p_vout->p_spu, &p_vout->fmt_out,
00318                                        PP_OUTPUTPICTURE[0], p_pic, p_subpic,
00319                                        i_scale_width, i_scale_height );
00320 
00321                 return PP_OUTPUTPICTURE[0];
00322             }
00323 
00324             /* No subtitles, picture is in a directbuffer so
00325              * we can display it directly even if it is still
00326              * in use. */
00327             return p_pic;
00328         }
00329 
00330         /* Picture is in a direct buffer but isn't used by the
00331          * decoder. We can safely render subtitles on it and
00332          * display it. */
00333         spu_RenderSubpictures( p_vout->p_spu, &p_vout->fmt_out, p_pic, p_pic,
00334                                p_subpic, i_scale_width, i_scale_height );
00335 
00336         return p_pic;
00337     }
00338 
00339     /* Not a direct buffer. We either need to copy it to a direct buffer,
00340      * or render it if the chroma isn't the same. */
00341     if( p_vout->b_direct )
00342     {
00343         /* Picture is not in a direct buffer, but is exactly the
00344          * same size as the direct buffers. A memcpy() is enough,
00345          * then render the subtitles. */
00346 
00347         if( PP_OUTPUTPICTURE[0]->pf_lock )
00348             if( PP_OUTPUTPICTURE[0]->pf_lock( p_vout, PP_OUTPUTPICTURE[0] ) )
00349                 return NULL;
00350 
00351         vout_CopyPicture( p_vout, PP_OUTPUTPICTURE[0], p_pic );
00352         spu_RenderSubpictures( p_vout->p_spu, &p_vout->fmt_out,
00353                                PP_OUTPUTPICTURE[0], p_pic,
00354                                p_subpic, i_scale_width, i_scale_height );
00355 
00356         if( PP_OUTPUTPICTURE[0]->pf_unlock )
00357             PP_OUTPUTPICTURE[0]->pf_unlock( p_vout, PP_OUTPUTPICTURE[0] );
00358 
00359         return PP_OUTPUTPICTURE[0];
00360     }
00361 
00362     /* Picture is not in a direct buffer, and needs to be converted to
00363      * another size/chroma. Then the subtitles need to be rendered as
00364      * well. This usually means software YUV, or hardware YUV with a
00365      * different chroma. */
00366 
00367     if( p_subpic != NULL && p_vout->p_picture[0].b_slow )
00368     {
00369         /* The picture buffer is in slow memory. We'll use
00370          * the "2 * VOUT_MAX_PICTURES + 1" picture as a temporary
00371          * one for subpictures rendering. */
00372         picture_t *p_tmp_pic = &p_vout->p_picture[2 * VOUT_MAX_PICTURES];
00373         if( p_tmp_pic->i_status == FREE_PICTURE )
00374         {
00375             vout_AllocatePicture( VLC_OBJECT(p_vout),
00376                                   p_tmp_pic, p_vout->fmt_out.i_chroma,
00377                                   p_vout->fmt_out.i_width,
00378                                   p_vout->fmt_out.i_height,
00379                                   p_vout->fmt_out.i_aspect );
00380             p_tmp_pic->i_type = MEMORY_PICTURE;
00381             p_tmp_pic->i_status = RESERVED_PICTURE;
00382         }
00383 
00384         /* Convert image to the first direct buffer */
00385         p_vout->chroma.pf_convert( p_vout, p_pic, p_tmp_pic );
00386 
00387         /* Render subpictures on the first direct buffer */
00388         spu_RenderSubpictures( p_vout->p_spu, &p_vout->fmt_out, p_tmp_pic,
00389                                p_tmp_pic, p_subpic,
00390                                i_scale_width, i_scale_height );
00391 
00392         if( p_vout->p_picture[0].pf_lock )
00393             if( p_vout->p_picture[0].pf_lock( p_vout, &p_vout->p_picture[0] ) )
00394                 return NULL;
00395 
00396         vout_CopyPicture( p_vout, &p_vout->p_picture[0], p_tmp_pic );
00397     }
00398     else
00399     {
00400         if( p_vout->p_picture[0].pf_lock )
00401             if( p_vout->p_picture[0].pf_lock( p_vout, &p_vout->p_picture[0] ) )
00402                 return NULL;
00403 
00404         /* Convert image to the first direct buffer */
00405         p_vout->chroma.pf_convert( p_vout, p_pic, &p_vout->p_picture[0] );
00406 
00407         /* Render subpictures on the first direct buffer */
00408         spu_RenderSubpictures( p_vout->p_spu, &p_vout->fmt_out,
00409                                &p_vout->p_picture[0], &p_vout->p_picture[0],
00410                                p_subpic, i_scale_width, i_scale_height );
00411     }
00412 
00413     if( p_vout->p_picture[0].pf_unlock )
00414         p_vout->p_picture[0].pf_unlock( p_vout, &p_vout->p_picture[0] );
00415 
00416     return &p_vout->p_picture[0];
00417 }
00418 
00425 void vout_PlacePicture( vout_thread_t *p_vout,
00426                         unsigned int i_width, unsigned int i_height,
00427                         unsigned int *pi_x, unsigned int *pi_y,
00428                         unsigned int *pi_width, unsigned int *pi_height )
00429 {
00430     if( (i_width <= 0) || (i_height <=0) )
00431     {
00432         *pi_width = *pi_height = *pi_x = *pi_y = 0;
00433         return;
00434     }
00435 
00436     if( p_vout->b_scale )
00437     {
00438         *pi_width = i_width;
00439         *pi_height = i_height;
00440     }
00441     else
00442     {
00443         *pi_width = __MIN( i_width, p_vout->fmt_in.i_visible_width );
00444         *pi_height = __MIN( i_height, p_vout->fmt_in.i_visible_height );
00445     }
00446 
00447     if( p_vout->fmt_in.i_visible_width * (int64_t)p_vout->fmt_in.i_sar_num *
00448         *pi_height / p_vout->fmt_in.i_visible_height /
00449         p_vout->fmt_in.i_sar_den > *pi_width )
00450     {
00451         *pi_height = p_vout->fmt_in.i_visible_height *
00452             (int64_t)p_vout->fmt_in.i_sar_den * *pi_width /
00453             p_vout->fmt_in.i_visible_width / p_vout->fmt_in.i_sar_num;
00454     }
00455     else
00456     {
00457         *pi_width = p_vout->fmt_in.i_visible_width *
00458             (int64_t)p_vout->fmt_in.i_sar_num * *pi_height /
00459             p_vout->fmt_in.i_visible_height / p_vout->fmt_in.i_sar_den;
00460     }
00461 
00462     switch( p_vout->i_alignment & VOUT_ALIGN_HMASK )
00463     {
00464     case VOUT_ALIGN_LEFT:
00465         *pi_x = 0;
00466         break;
00467     case VOUT_ALIGN_RIGHT:
00468         *pi_x = i_width - *pi_width;
00469         break;
00470     default:
00471         *pi_x = ( i_width - *pi_width ) / 2;
00472     }
00473 
00474     switch( p_vout->i_alignment & VOUT_ALIGN_VMASK )
00475     {
00476     case VOUT_ALIGN_TOP:
00477         *pi_y = 0;
00478         break;
00479     case VOUT_ALIGN_BOTTOM:
00480         *pi_y = i_height - *pi_height;
00481         break;
00482     default:
00483         *pi_y = ( i_height - *pi_height ) / 2;
00484     }
00485 }
00486 
00494 int __vout_AllocatePicture( vlc_object_t *p_this, picture_t *p_pic,
00495                             vlc_fourcc_t i_chroma,
00496                             int i_width, int i_height, int i_aspect )
00497 {
00498     int i_bytes, i_index, i_width_aligned, i_height_aligned;
00499 
00500     /* Make sure the real dimensions are a multiple of 16 */
00501     i_width_aligned = (i_width + 15) >> 4 << 4;
00502     i_height_aligned = (i_height + 15) >> 4 << 4;
00503 
00504     if( vout_InitPicture( p_this, p_pic, i_chroma,
00505                           i_width, i_height, i_aspect ) != VLC_SUCCESS )
00506     {
00507         p_pic->i_planes = 0;
00508         return VLC_EGENERIC;
00509     }
00510 
00511     /* Calculate how big the new image should be */
00512     i_bytes = p_pic->format.i_bits_per_pixel *
00513         i_width_aligned * i_height_aligned / 8;
00514 
00515     p_pic->p_data = vlc_memalign( &p_pic->p_data_orig, 16, i_bytes );
00516 
00517     if( p_pic->p_data == NULL )
00518     {
00519         p_pic->i_planes = 0;
00520         return VLC_EGENERIC;
00521     }
00522 
00523     /* Fill the p_pixels field for each plane */
00524     p_pic->p[ 0 ].p_pixels = p_pic->p_data;
00525 
00526     for( i_index = 1; i_index < p_pic->i_planes; i_index++ )
00527     {
00528         p_pic->p[i_index].p_pixels = p_pic->p[i_index-1].p_pixels +
00529             p_pic->p[i_index-1].i_lines * p_pic->p[i_index-1].i_pitch;
00530     }
00531 
00532     return VLC_SUCCESS;
00533 }
00534 
00546 void vout_InitFormat( video_frame_format_t *p_format, vlc_fourcc_t i_chroma,
00547                       int i_width, int i_height, int i_aspect )
00548 {
00549     p_format->i_chroma   = i_chroma;
00550     p_format->i_width    = p_format->i_visible_width  = i_width;
00551     p_format->i_height   = p_format->i_visible_height = i_height;
00552     p_format->i_x_offset = p_format->i_y_offset = 0;
00553     p_format->i_aspect   = i_aspect;
00554 
00555 #if 0
00556     /* Assume we have square pixels */
00557     if( i_width && i_height )
00558         p_format->i_aspect = i_width * VOUT_ASPECT_FACTOR / i_height;
00559     else
00560         p_format->i_aspect = 0;
00561 #endif
00562 
00563     switch( i_chroma )
00564     {
00565         case FOURCC_YUVA:
00566             p_format->i_bits_per_pixel = 32;
00567             break;
00568         case FOURCC_I444:
00569         case FOURCC_J444:
00570             p_format->i_bits_per_pixel = 24;
00571             break;
00572         case FOURCC_I422:
00573         case FOURCC_YUY2:
00574         case FOURCC_UYVY:
00575         case FOURCC_J422:
00576             p_format->i_bits_per_pixel = 16;
00577             p_format->i_bits_per_pixel = 16;
00578             break;
00579         case FOURCC_I411:
00580         case FOURCC_YV12:
00581         case FOURCC_I420:
00582         case FOURCC_J420:
00583         case FOURCC_IYUV:
00584             p_format->i_bits_per_pixel = 12;
00585             break;
00586         case FOURCC_I410:
00587         case FOURCC_YVU9:
00588             p_format->i_bits_per_pixel = 9;
00589             break;
00590         case FOURCC_Y211:
00591             p_format->i_bits_per_pixel = 8;
00592             break;
00593         case FOURCC_YUVP:
00594             p_format->i_bits_per_pixel = 8;
00595             break;
00596 
00597         case FOURCC_RV32:
00598             p_format->i_bits_per_pixel = 32;
00599             break;
00600         case FOURCC_RV24:
00601             p_format->i_bits_per_pixel = 24;
00602             break;
00603         case FOURCC_RV15:
00604         case FOURCC_RV16:
00605             p_format->i_bits_per_pixel = 16;
00606             break;
00607         case FOURCC_RGB2:
00608             p_format->i_bits_per_pixel = 8;
00609             break;
00610         default:
00611             p_format->i_bits_per_pixel = 0;
00612             break;
00613     }
00614 }
00615 
00628 int __vout_InitPicture( vlc_object_t *p_this, picture_t *p_pic,
00629                         vlc_fourcc_t i_chroma,
00630                         int i_width, int i_height, int i_aspect )
00631 {
00632     int i_index, i_width_aligned, i_height_aligned;
00633 
00634     /* Store default values */
00635     for( i_index = 0; i_index < VOUT_MAX_PLANES; i_index++ )
00636     {
00637         p_pic->p[i_index].p_pixels = NULL;
00638         p_pic->p[i_index].i_pixel_pitch = 1;
00639     }
00640 
00641     p_pic->pf_release = 0;
00642     p_pic->pf_lock = 0;
00643     p_pic->pf_unlock = 0;
00644     p_pic->i_refcount = 0;
00645 
00646     vout_InitFormat( &p_pic->format, i_chroma, i_width, i_height, i_aspect );
00647 
00648     /* Make sure the real dimensions are a multiple of 16 */
00649     i_width_aligned = (i_width + 15) >> 4 << 4;
00650     i_height_aligned = (i_height + 15) >> 4 << 4;
00651 
00652     /* Calculate coordinates */
00653     switch( i_chroma )
00654     {
00655         case FOURCC_I411:
00656             p_pic->p[ Y_PLANE ].i_lines = i_height_aligned;
00657             p_pic->p[ Y_PLANE ].i_visible_lines = i_height;
00658             p_pic->p[ Y_PLANE ].i_pitch = i_width_aligned;
00659             p_pic->p[ Y_PLANE ].i_visible_pitch = i_width;
00660             p_pic->p[ U_PLANE ].i_lines = i_height_aligned;
00661             p_pic->p[ U_PLANE ].i_visible_lines = i_height;
00662             p_pic->p[ U_PLANE ].i_pitch = i_width_aligned / 4;
00663             p_pic->p[ U_PLANE ].i_visible_pitch = i_width / 4;
00664             p_pic->p[ V_PLANE ].i_lines = i_height_aligned;
00665             p_pic->p[ V_PLANE ].i_visible_lines = i_height;
00666             p_pic->p[ V_PLANE ].i_pitch = i_width_aligned / 4;
00667             p_pic->p[ V_PLANE ].i_visible_pitch = i_width / 4;
00668             p_pic->i_planes = 3;
00669             break;
00670 
00671         case FOURCC_I410:
00672         case FOURCC_YVU9:
00673             p_pic->p[ Y_PLANE ].i_lines = i_height_aligned;
00674             p_pic->p[ Y_PLANE ].i_visible_lines = i_height;
00675             p_pic->p[ Y_PLANE ].i_pitch = i_width_aligned;
00676             p_pic->p[ Y_PLANE ].i_visible_pitch = i_width;
00677             p_pic->p[ U_PLANE ].i_lines = i_height_aligned / 4;
00678             p_pic->p[ U_PLANE ].i_visible_lines = i_height / 4;
00679             p_pic->p[ U_PLANE ].i_pitch = i_width_aligned / 4;
00680             p_pic->p[ U_PLANE ].i_visible_pitch = i_width / 4;
00681             p_pic->p[ V_PLANE ].i_lines = i_height_aligned / 4;
00682             p_pic->p[ V_PLANE ].i_visible_lines = i_height / 4;
00683             p_pic->p[ V_PLANE ].i_pitch = i_width_aligned / 4;
00684             p_pic->p[ V_PLANE ].i_visible_pitch = i_width / 4;
00685             p_pic->i_planes = 3;
00686             break;
00687 
00688         case FOURCC_YV12:
00689         case FOURCC_I420:
00690         case FOURCC_IYUV:
00691         case FOURCC_J420:
00692             p_pic->p[ Y_PLANE ].i_lines = i_height_aligned;
00693             p_pic->p[ Y_PLANE ].i_visible_lines = i_height;
00694             p_pic->p[ Y_PLANE ].i_pitch = i_width_aligned;
00695             p_pic->p[ Y_PLANE ].i_visible_pitch = i_width;
00696             p_pic->p[ U_PLANE ].i_lines = i_height_aligned / 2;
00697             p_pic->p[ U_PLANE ].i_visible_lines = i_height / 2;
00698             p_pic->p[ U_PLANE ].i_pitch = i_width_aligned / 2;
00699             p_pic->p[ U_PLANE ].i_visible_pitch = i_width / 2;
00700             p_pic->p[ V_PLANE ].i_lines = i_height_aligned / 2;
00701             p_pic->p[ V_PLANE ].i_visible_lines = i_height / 2;
00702             p_pic->p[ V_PLANE ].i_pitch = i_width_aligned / 2;
00703             p_pic->p[ V_PLANE ].i_visible_pitch = i_width / 2;
00704             p_pic->i_planes = 3;
00705             break;
00706 
00707         case FOURCC_I422:
00708         case FOURCC_J422:
00709             p_pic->p[ Y_PLANE ].i_lines = i_height_aligned;
00710             p_pic->p[ Y_PLANE ].i_visible_lines = i_height;
00711             p_pic->p[ Y_PLANE ].i_pitch = i_width_aligned;
00712             p_pic->p[ Y_PLANE ].i_visible_pitch = i_width;
00713             p_pic->p[ U_PLANE ].i_lines = i_height_aligned;
00714             p_pic->p[ U_PLANE ].i_visible_lines = i_height;
00715             p_pic->p[ U_PLANE ].i_pitch = i_width_aligned / 2;
00716             p_pic->p[ U_PLANE ].i_visible_pitch = i_width / 2;
00717             p_pic->p[ V_PLANE ].i_lines = i_height_aligned;
00718             p_pic->p[ V_PLANE ].i_visible_lines = i_height;
00719             p_pic->p[ V_PLANE ].i_pitch = i_width_aligned / 2;
00720             p_pic->p[ V_PLANE ].i_visible_pitch = i_width / 2;
00721             p_pic->i_planes = 3;
00722             break;
00723 
00724         case FOURCC_I444:
00725         case FOURCC_J444:
00726             p_pic->p[ Y_PLANE ].i_lines = i_height_aligned;
00727             p_pic->p[ Y_PLANE ].i_visible_lines = i_height;
00728             p_pic->p[ Y_PLANE ].i_pitch = i_width_aligned;
00729             p_pic->p[ Y_PLANE ].i_visible_pitch = i_width;
00730             p_pic->p[ U_PLANE ].i_lines = i_height_aligned;
00731             p_pic->p[ U_PLANE ].i_visible_lines = i_height;
00732             p_pic->p[ U_PLANE ].i_pitch = i_width_aligned;
00733             p_pic->p[ U_PLANE ].i_visible_pitch = i_width;
00734             p_pic->p[ V_PLANE ].i_lines = i_height_aligned;
00735             p_pic->p[ V_PLANE ].i_visible_lines = i_height;
00736             p_pic->p[ V_PLANE ].i_pitch = i_width_aligned;
00737             p_pic->p[ V_PLANE ].i_visible_pitch = i_width;
00738             p_pic->i_planes = 3;
00739             break;
00740 
00741         case FOURCC_YUVA:
00742             p_pic->p[ Y_PLANE ].i_lines = i_height_aligned;
00743             p_pic->p[ Y_PLANE ].i_visible_lines = i_height;
00744             p_pic->p[ Y_PLANE ].i_pitch = i_width_aligned;
00745             p_pic->p[ Y_PLANE ].i_visible_pitch = i_width;
00746             p_pic->p[ U_PLANE ].i_lines = i_height_aligned;
00747             p_pic->p[ U_PLANE ].i_visible_lines = i_height;
00748             p_pic->p[ U_PLANE ].i_pitch = i_width_aligned;
00749             p_pic->p[ U_PLANE ].i_visible_pitch = i_width;
00750             p_pic->p[ V_PLANE ].i_lines = i_height_aligned;
00751             p_pic->p[ V_PLANE ].i_visible_lines = i_height;
00752             p_pic->p[ V_PLANE ].i_pitch = i_width_aligned;
00753             p_pic->p[ V_PLANE ].i_visible_pitch = i_width;
00754             p_pic->p[ A_PLANE ].i_lines = i_height_aligned;
00755             p_pic->p[ A_PLANE ].i_visible_lines = i_height;
00756             p_pic->p[ A_PLANE ].i_pitch = i_width_aligned;
00757             p_pic->p[ A_PLANE ].i_visible_pitch = i_width;
00758             p_pic->i_planes = 4;
00759             break;
00760 
00761         case FOURCC_YUVP:
00762             p_pic->p->i_lines = i_height_aligned;
00763             p_pic->p->i_visible_lines = i_height;
00764             p_pic->p->i_pitch = i_width_aligned;
00765             p_pic->p->i_visible_pitch = i_width;
00766             p_pic->p->i_pixel_pitch = 8;
00767             p_pic->i_planes = 1;
00768             break;
00769 
00770         case FOURCC_Y211:
00771             p_pic->p->i_lines = i_height_aligned;
00772             p_pic->p->i_visible_lines = i_height;
00773             p_pic->p->i_pitch = i_width_aligned;
00774             p_pic->p->i_visible_pitch = i_width;
00775             p_pic->p->i_pixel_pitch = 4;
00776             p_pic->i_planes = 1;
00777             break;
00778 
00779         case FOURCC_UYVY:
00780         case FOURCC_YUY2:
00781             p_pic->p->i_lines = i_height_aligned;
00782             p_pic->p->i_visible_lines = i_height;
00783             p_pic->p->i_pitch = i_width_aligned * 2;
00784             p_pic->p->i_visible_pitch = i_width * 2;
00785             p_pic->p->i_pixel_pitch = 4;
00786             p_pic->i_planes = 1;
00787             break;
00788 
00789         case FOURCC_RGB2:
00790             p_pic->p->i_lines = i_height_aligned;
00791             p_pic->p->i_visible_lines = i_height;
00792             p_pic->p->i_pitch = i_width_aligned;
00793             p_pic->p->i_visible_pitch = i_width;
00794             p_pic->p->i_pixel_pitch = 1;
00795             p_pic->i_planes = 1;
00796             break;
00797 
00798         case FOURCC_RV15:
00799             p_pic->p->i_lines = i_height_aligned;
00800             p_pic->p->i_visible_lines = i_height;
00801             p_pic->p->i_pitch = i_width_aligned * 2;
00802             p_pic->p->i_visible_pitch = i_width * 2;
00803             p_pic->p->i_pixel_pitch = 2;
00804             p_pic->i_planes = 1;
00805             break;
00806 
00807         case FOURCC_RV16:
00808             p_pic->p->i_lines = i_height_aligned;
00809             p_pic->p->i_visible_lines = i_height;
00810             p_pic->p->i_pitch = i_width_aligned * 2;
00811             p_pic->p->i_visible_pitch = i_width * 2;
00812             p_pic->p->i_pixel_pitch = 2;
00813             p_pic->i_planes = 1;
00814             break;
00815 
00816         case FOURCC_RV24:
00817             p_pic->p->i_lines = i_height_aligned;
00818             p_pic->p->i_visible_lines = i_height;
00819             p_pic->p->i_pitch = i_width_aligned * 3;
00820             p_pic->p->i_visible_pitch = i_width * 3;
00821             p_pic->p->i_pixel_pitch = 3;
00822             p_pic->i_planes = 1;
00823             break;
00824 
00825         case FOURCC_RV32:
00826             p_pic->p->i_lines = i_height_aligned;
00827             p_pic->p->i_visible_lines = i_height;
00828             p_pic->p->i_pitch = i_width_aligned * 4;
00829             p_pic->p->i_visible_pitch = i_width * 4;
00830             p_pic->p->i_pixel_pitch = 4;
00831             p_pic->i_planes = 1;
00832             break;
00833 
00834         default:
00835             msg_Err( p_this, "unknown chroma type 0x%.8x (%4.4s)",
00836                              i_chroma, (char*)&i_chroma );
00837             p_pic->i_planes = 0;
00838             return VLC_EGENERIC;
00839     }
00840 
00841     return VLC_SUCCESS;
00842 }
00843 
00850 int vout_ChromaCmp( vlc_fourcc_t i_chroma, vlc_fourcc_t i_amorhc )
00851 {
00852     /* If they are the same, they are the same ! */
00853     if( i_chroma == i_amorhc )
00854     {
00855         return 1;
00856     }
00857 
00858     /* Check for equivalence classes */
00859     switch( i_chroma )
00860     {
00861         case FOURCC_I420:
00862         case FOURCC_IYUV:
00863         case FOURCC_YV12:
00864             switch( i_amorhc )
00865             {
00866                 case FOURCC_I420:
00867                 case FOURCC_IYUV:
00868                 case FOURCC_YV12:
00869                     return 1;
00870 
00871                 default:
00872                     return 0;
00873             }
00874 
00875         case FOURCC_UYVY:
00876         case FOURCC_UYNV:
00877         case FOURCC_Y422:
00878             switch( i_amorhc )
00879             {
00880                 case FOURCC_UYVY:
00881                 case FOURCC_UYNV:
00882                 case FOURCC_Y422:
00883                     return 1;
00884 
00885                 default:
00886                     return 0;
00887             }
00888 
00889         case FOURCC_YUY2:
00890         case FOURCC_YUNV:
00891             switch( i_amorhc )
00892             {
00893                 case FOURCC_YUY2:
00894                 case FOURCC_YUNV:
00895                     return 1;
00896 
00897                 default:
00898                     return 0;
00899             }
00900 
00901         default:
00902             return 0;
00903     }
00904 }
00905 
00906 /*****************************************************************************
00907  * vout_CopyPicture: copy a picture to another one
00908  *****************************************************************************
00909  * This function takes advantage of the image format, and reduces the
00910  * number of calls to memcpy() to the minimum. Source and destination
00911  * images must have same width (hence i_visible_pitch), height, and chroma.
00912  *****************************************************************************/
00913 void __vout_CopyPicture( vlc_object_t *p_this,
00914                          picture_t *p_dest, picture_t *p_src )
00915 {
00916     int i;
00917 
00918     for( i = 0; i < p_src->i_planes ; i++ )
00919     {
00920         if( p_src->p[i].i_pitch == p_dest->p[i].i_pitch )
00921         {
00922             /* There are margins, but with the same width : perfect ! */
00923             p_this->p_vlc->pf_memcpy(
00924                          p_dest->p[i].p_pixels, p_src->p[i].p_pixels,
00925                          p_src->p[i].i_pitch * p_src->p[i].i_visible_lines );
00926         }
00927         else
00928         {
00929             /* We need to proceed line by line */
00930             uint8_t *p_in = p_src->p[i].p_pixels;
00931             uint8_t *p_out = p_dest->p[i].p_pixels;
00932             int i_line;
00933 
00934             for( i_line = p_src->p[i].i_visible_lines; i_line--; )
00935             {
00936                 p_this->p_vlc->pf_memcpy( p_out, p_in,
00937                                           p_src->p[i].i_visible_pitch );
00938                 p_in += p_src->p[i].i_pitch;
00939                 p_out += p_dest->p[i].i_pitch;
00940             }
00941         }
00942     }
00943 
00944     p_dest->date = p_src->date;
00945     p_dest->b_force = p_src->b_force;
00946     p_dest->i_nb_fields = p_src->i_nb_fields;
00947     p_dest->b_progressive = p_src->b_progressive;
00948     p_dest->b_top_field_first = p_src->b_top_field_first;
00949 }

Generated on Tue Dec 20 10:15:02 2005 for vlc-0.8.4a by  doxygen 1.4.2