Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * This file is part of MPlayer.
  3.  *
  4.  * MPlayer is free software; you can redistribute it and/or modify
  5.  * it under the terms of the GNU General Public License as published by
  6.  * the Free Software Foundation; either version 2 of the License, or
  7.  * (at your option) any later version.
  8.  *
  9.  * MPlayer is distributed in the hope that it will be useful,
  10.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.  * GNU General Public License for more details.
  13.  *
  14.  * You should have received a copy of the GNU General Public License along
  15.  * with MPlayer; if not, write to the Free Software Foundation, Inc.,
  16.  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  17.  */
  18.  
  19. #include "config.h"
  20.  
  21. #include <stdio.h>
  22. #include <stdlib.h>
  23. #include <string.h>
  24.  
  25. #if HAVE_MALLOC_H
  26. #include <malloc.h>
  27. #endif
  28.  
  29. #include "img_format.h"
  30. #include "mp_image.h"
  31.  
  32. #include "libvo/fastmemcpy.h"
  33. //#include "libavutil/mem.h"
  34. #include "libavutil/imgutils.h"
  35.  
  36. void ff_mp_image_alloc_planes(mp_image_t *mpi) {
  37.     uint32_t temp[256];
  38.     if (avpriv_set_systematic_pal2(temp, ff_mp2ff_pix_fmt(mpi->imgfmt)) >= 0)
  39.         mpi->flags |= MP_IMGFLAG_RGB_PALETTE;
  40.  
  41.   // IF09 - allocate space for 4. plane delta info - unused
  42.   if (mpi->imgfmt == IMGFMT_IF09) {
  43.     mpi->planes[0]=av_malloc(mpi->bpp*mpi->width*(mpi->height+2)/8+
  44.                             mpi->chroma_width*mpi->chroma_height);
  45.   } else
  46.     mpi->planes[0]=av_malloc(mpi->bpp*mpi->width*(mpi->height+2)/8);
  47.   if (mpi->flags&MP_IMGFLAG_PLANAR) {
  48.     int bpp = IMGFMT_IS_YUVP16(mpi->imgfmt)? 2 : 1;
  49.     // YV12/I420/YVU9/IF09. feel free to add other planar formats here...
  50.     mpi->stride[0]=mpi->stride[3]=bpp*mpi->width;
  51.     if(mpi->num_planes > 2){
  52.       mpi->stride[1]=mpi->stride[2]=bpp*mpi->chroma_width;
  53.       if(mpi->flags&MP_IMGFLAG_SWAPPED){
  54.         // I420/IYUV  (Y,U,V)
  55.         mpi->planes[1]=mpi->planes[0]+mpi->stride[0]*mpi->height;
  56.         mpi->planes[2]=mpi->planes[1]+mpi->stride[1]*mpi->chroma_height;
  57.         if (mpi->num_planes > 3)
  58.             mpi->planes[3]=mpi->planes[2]+mpi->stride[2]*mpi->chroma_height;
  59.       } else {
  60.         // YV12,YVU9,IF09  (Y,V,U)
  61.         mpi->planes[2]=mpi->planes[0]+mpi->stride[0]*mpi->height;
  62.         mpi->planes[1]=mpi->planes[2]+mpi->stride[1]*mpi->chroma_height;
  63.         if (mpi->num_planes > 3)
  64.             mpi->planes[3]=mpi->planes[1]+mpi->stride[1]*mpi->chroma_height;
  65.       }
  66.     } else {
  67.       // NV12/NV21
  68.       mpi->stride[1]=mpi->chroma_width;
  69.       mpi->planes[1]=mpi->planes[0]+mpi->stride[0]*mpi->height;
  70.     }
  71.   } else {
  72.     mpi->stride[0]=mpi->width*mpi->bpp/8;
  73.     if (mpi->flags & MP_IMGFLAG_RGB_PALETTE) {
  74.       mpi->planes[1] = av_malloc(1024);
  75.       memcpy(mpi->planes[1], temp, 1024);
  76.     }
  77.   }
  78.   mpi->flags|=MP_IMGFLAG_ALLOCATED;
  79. }
  80.  
  81. mp_image_t* ff_alloc_mpi(int w, int h, unsigned long int fmt) {
  82.   mp_image_t* mpi = ff_new_mp_image(w,h);
  83.  
  84.   ff_mp_image_setfmt(mpi,fmt);
  85.   ff_mp_image_alloc_planes(mpi);
  86.  
  87.   return mpi;
  88. }
  89.  
  90. void ff_copy_mpi(mp_image_t *dmpi, mp_image_t *mpi) {
  91.   if(mpi->flags&MP_IMGFLAG_PLANAR){
  92.     memcpy_pic(dmpi->planes[0],mpi->planes[0], mpi->w, mpi->h,
  93.                dmpi->stride[0],mpi->stride[0]);
  94.     memcpy_pic(dmpi->planes[1],mpi->planes[1], mpi->chroma_width, mpi->chroma_height,
  95.                dmpi->stride[1],mpi->stride[1]);
  96.     memcpy_pic(dmpi->planes[2], mpi->planes[2], mpi->chroma_width, mpi->chroma_height,
  97.                dmpi->stride[2],mpi->stride[2]);
  98.   } else {
  99.     memcpy_pic(dmpi->planes[0],mpi->planes[0],
  100.                mpi->w*(dmpi->bpp/8), mpi->h,
  101.                dmpi->stride[0],mpi->stride[0]);
  102.   }
  103. }
  104.  
  105. void ff_mp_image_setfmt(mp_image_t* mpi,unsigned int out_fmt){
  106.     mpi->flags&=~(MP_IMGFLAG_PLANAR|MP_IMGFLAG_YUV|MP_IMGFLAG_SWAPPED);
  107.     mpi->imgfmt=out_fmt;
  108.     // compressed formats
  109.     if(out_fmt == IMGFMT_MPEGPES ||
  110.        out_fmt == IMGFMT_ZRMJPEGNI || out_fmt == IMGFMT_ZRMJPEGIT || out_fmt == IMGFMT_ZRMJPEGIB ||
  111.        IMGFMT_IS_HWACCEL(out_fmt)){
  112.         mpi->bpp=0;
  113.         return;
  114.     }
  115.     mpi->num_planes=1;
  116.     if (IMGFMT_IS_RGB(out_fmt)) {
  117.         if (IMGFMT_RGB_DEPTH(out_fmt) < 8 && !(out_fmt&128))
  118.             mpi->bpp = IMGFMT_RGB_DEPTH(out_fmt);
  119.         else
  120.             mpi->bpp=(IMGFMT_RGB_DEPTH(out_fmt)+7)&(~7);
  121.         return;
  122.     }
  123.     if (IMGFMT_IS_BGR(out_fmt)) {
  124.         if (IMGFMT_BGR_DEPTH(out_fmt) < 8 && !(out_fmt&128))
  125.             mpi->bpp = IMGFMT_BGR_DEPTH(out_fmt);
  126.         else
  127.             mpi->bpp=(IMGFMT_BGR_DEPTH(out_fmt)+7)&(~7);
  128.         mpi->flags|=MP_IMGFLAG_SWAPPED;
  129.         return;
  130.     }
  131.     mpi->num_planes=3;
  132.     if (out_fmt == IMGFMT_GBR24P) {
  133.         mpi->bpp=24;
  134.         mpi->flags|=MP_IMGFLAG_PLANAR;
  135.         return;
  136.     } else if (out_fmt == IMGFMT_GBR12P) {
  137.         mpi->bpp=36;
  138.         mpi->flags|=MP_IMGFLAG_PLANAR;
  139.         return;
  140.     } else if (out_fmt == IMGFMT_GBR14P) {
  141.         mpi->bpp=42;
  142.         mpi->flags|=MP_IMGFLAG_PLANAR;
  143.         return;
  144.     }
  145.     mpi->flags|=MP_IMGFLAG_YUV;
  146.     if (ff_mp_get_chroma_shift(out_fmt, NULL, NULL, NULL)) {
  147.         mpi->flags|=MP_IMGFLAG_PLANAR;
  148.         mpi->bpp = ff_mp_get_chroma_shift(out_fmt, &mpi->chroma_x_shift, &mpi->chroma_y_shift, NULL);
  149.         mpi->chroma_width  = mpi->width  >> mpi->chroma_x_shift;
  150.         mpi->chroma_height = mpi->height >> mpi->chroma_y_shift;
  151.     }
  152.     switch(out_fmt){
  153.     case IMGFMT_I420:
  154.     case IMGFMT_IYUV:
  155.         mpi->flags|=MP_IMGFLAG_SWAPPED;
  156.     case IMGFMT_YV12:
  157.         return;
  158.     case IMGFMT_420A:
  159.     case IMGFMT_422A:
  160.     case IMGFMT_444A:
  161.     case IMGFMT_IF09:
  162.         mpi->num_planes=4;
  163.     case IMGFMT_YVU9:
  164.     case IMGFMT_444P:
  165.     case IMGFMT_422P:
  166.     case IMGFMT_411P:
  167.     case IMGFMT_440P:
  168.     case IMGFMT_444P16_LE:
  169.     case IMGFMT_444P16_BE:
  170.     case IMGFMT_444P14_LE:
  171.     case IMGFMT_444P14_BE:
  172.     case IMGFMT_444P12_LE:
  173.     case IMGFMT_444P12_BE:
  174.     case IMGFMT_444P10_LE:
  175.     case IMGFMT_444P10_BE:
  176.     case IMGFMT_444P9_LE:
  177.     case IMGFMT_444P9_BE:
  178.     case IMGFMT_422P16_LE:
  179.     case IMGFMT_422P16_BE:
  180.     case IMGFMT_422P14_LE:
  181.     case IMGFMT_422P14_BE:
  182.     case IMGFMT_422P12_LE:
  183.     case IMGFMT_422P12_BE:
  184.     case IMGFMT_422P10_LE:
  185.     case IMGFMT_422P10_BE:
  186.     case IMGFMT_422P9_LE:
  187.     case IMGFMT_422P9_BE:
  188.     case IMGFMT_420P16_LE:
  189.     case IMGFMT_420P16_BE:
  190.     case IMGFMT_420P14_LE:
  191.     case IMGFMT_420P14_BE:
  192.     case IMGFMT_420P12_LE:
  193.     case IMGFMT_420P12_BE:
  194.     case IMGFMT_420P10_LE:
  195.     case IMGFMT_420P10_BE:
  196.     case IMGFMT_420P9_LE:
  197.     case IMGFMT_420P9_BE:
  198.         return;
  199.     case IMGFMT_Y16_LE:
  200.     case IMGFMT_Y16_BE:
  201.         mpi->bpp=16;
  202.     case IMGFMT_Y800:
  203.     case IMGFMT_Y8:
  204.         /* they're planar ones, but for easier handling use them as packed */
  205.         mpi->flags&=~MP_IMGFLAG_PLANAR;
  206.         mpi->num_planes=1;
  207.         return;
  208.     case IMGFMT_Y8A:
  209.         mpi->num_planes=2;
  210.         return;
  211.     case IMGFMT_UYVY:
  212.         mpi->flags|=MP_IMGFLAG_SWAPPED;
  213.     case IMGFMT_YUY2:
  214.         mpi->chroma_x_shift = 1;
  215.         mpi->bpp=16;
  216.         mpi->num_planes=1;
  217.         return;
  218.     case IMGFMT_NV12:
  219.         mpi->flags|=MP_IMGFLAG_SWAPPED;
  220.     case IMGFMT_NV21:
  221.         mpi->flags|=MP_IMGFLAG_PLANAR;
  222.         mpi->bpp=12;
  223.         mpi->num_planes=2;
  224.         mpi->chroma_width=(mpi->width>>0);
  225.         mpi->chroma_height=(mpi->height>>1);
  226.         mpi->chroma_x_shift=0;
  227.         mpi->chroma_y_shift=1;
  228.         return;
  229.     }
  230.     ff_mp_msg(MSGT_DECVIDEO,MSGL_WARN,"mp_image: unknown out_fmt: 0x%X\n",out_fmt);
  231.     mpi->bpp=0;
  232. }
  233.  
  234. mp_image_t* ff_new_mp_image(int w,int h){
  235.     mp_image_t* mpi = malloc(sizeof(mp_image_t));
  236.     if(!mpi) return NULL; // error!
  237.     memset(mpi,0,sizeof(mp_image_t));
  238.     mpi->width=mpi->w=w;
  239.     mpi->height=mpi->h=h;
  240.     return mpi;
  241. }
  242.  
  243. void ff_free_mp_image(mp_image_t* mpi){
  244.     if(!mpi) return;
  245.     if(mpi->flags&MP_IMGFLAG_ALLOCATED){
  246.         /* becouse we allocate the whole image in once */
  247.         av_free(mpi->planes[0]);
  248.         if (mpi->flags & MP_IMGFLAG_RGB_PALETTE)
  249.             av_free(mpi->planes[1]);
  250.     }
  251.     free(mpi);
  252. }
  253.  
  254.