vf_pp.c 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  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. #include <stdio.h>
  19. #include <stdlib.h>
  20. #include <string.h>
  21. #include <inttypes.h>
  22. #include <errno.h>
  23. #include "config.h"
  24. #include "mp_msg.h"
  25. #include "cpudetect.h"
  26. #if HAVE_MALLOC_H
  27. #include <malloc.h>
  28. #endif
  29. #include "img_format.h"
  30. #include "mp_image.h"
  31. #include "vf.h"
  32. #include "libpostproc/postprocess.h"
  33. #ifdef CONFIG_FFMPEG_A
  34. #define EMU_OLD
  35. #include "libpostproc/postprocess_internal.h"
  36. #endif
  37. #undef malloc
  38. struct vf_priv_s {
  39. int pp;
  40. pp_mode *ppMode[PP_QUALITY_MAX+1];
  41. void *context;
  42. unsigned int outfmt;
  43. };
  44. //===========================================================================//
  45. static int config(struct vf_instance *vf,
  46. int width, int height, int d_width, int d_height,
  47. unsigned int voflags, unsigned int outfmt){
  48. int flags=
  49. (gCpuCaps.hasMMX ? PP_CPU_CAPS_MMX : 0)
  50. | (gCpuCaps.hasMMX2 ? PP_CPU_CAPS_MMX2 : 0)
  51. | (gCpuCaps.has3DNow ? PP_CPU_CAPS_3DNOW : 0);
  52. switch(outfmt){
  53. case IMGFMT_444P: flags|= PP_FORMAT_444; break;
  54. case IMGFMT_422P: flags|= PP_FORMAT_422; break;
  55. case IMGFMT_411P: flags|= PP_FORMAT_411; break;
  56. default: flags|= PP_FORMAT_420; break;
  57. }
  58. if(vf->priv->context) pp_free_context(vf->priv->context);
  59. vf->priv->context= pp_get_context(width, height, flags);
  60. return vf_next_config(vf,width,height,d_width,d_height,voflags,outfmt);
  61. }
  62. static void uninit(struct vf_instance *vf){
  63. int i;
  64. for(i=0; i<=PP_QUALITY_MAX; i++){
  65. if(vf->priv->ppMode[i])
  66. pp_free_mode(vf->priv->ppMode[i]);
  67. }
  68. if(vf->priv->context) pp_free_context(vf->priv->context);
  69. free(vf->priv);
  70. }
  71. static int query_format(struct vf_instance *vf, unsigned int fmt){
  72. switch(fmt){
  73. case IMGFMT_YV12:
  74. case IMGFMT_I420:
  75. case IMGFMT_IYUV:
  76. case IMGFMT_444P:
  77. case IMGFMT_422P:
  78. case IMGFMT_411P:
  79. return vf_next_query_format(vf,fmt);
  80. }
  81. return 0;
  82. }
  83. static int control(struct vf_instance *vf, int request, void* data){
  84. switch(request){
  85. case VFCTRL_QUERY_MAX_PP_LEVEL:
  86. return PP_QUALITY_MAX;
  87. case VFCTRL_SET_PP_LEVEL:
  88. vf->priv->pp= *((unsigned int*)data);
  89. return CONTROL_TRUE;
  90. }
  91. return vf_next_control(vf,request,data);
  92. }
  93. static void get_image(struct vf_instance *vf, mp_image_t *mpi){
  94. if(vf->priv->pp&0xFFFF) return; // non-local filters enabled
  95. if((mpi->type==MP_IMGTYPE_IPB || vf->priv->pp) &&
  96. mpi->flags&MP_IMGFLAG_PRESERVE) return; // don't change
  97. if(!(mpi->flags&MP_IMGFLAG_ACCEPT_STRIDE) && mpi->imgfmt!=vf->priv->outfmt)
  98. return; // colorspace differ
  99. // ok, we can do pp in-place (or pp disabled):
  100. vf->dmpi=vf_get_image(vf->next,mpi->imgfmt,
  101. mpi->type, mpi->flags | MP_IMGFLAG_READABLE, mpi->width, mpi->height);
  102. mpi->planes[0]=vf->dmpi->planes[0];
  103. mpi->stride[0]=vf->dmpi->stride[0];
  104. mpi->width=vf->dmpi->width;
  105. if(mpi->flags&MP_IMGFLAG_PLANAR){
  106. mpi->planes[1]=vf->dmpi->planes[1];
  107. mpi->planes[2]=vf->dmpi->planes[2];
  108. mpi->stride[1]=vf->dmpi->stride[1];
  109. mpi->stride[2]=vf->dmpi->stride[2];
  110. }
  111. mpi->flags|=MP_IMGFLAG_DIRECT;
  112. }
  113. static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts){
  114. if(!(mpi->flags&MP_IMGFLAG_DIRECT)){
  115. // no DR, so get a new image! hope we'll get DR buffer:
  116. vf->dmpi=vf_get_image(vf->next,mpi->imgfmt,
  117. MP_IMGTYPE_TEMP, MP_IMGFLAG_ACCEPT_STRIDE |
  118. MP_IMGFLAG_PREFER_ALIGNED_STRIDE | MP_IMGFLAG_READABLE,
  119. // MP_IMGTYPE_TEMP, MP_IMGFLAG_ACCEPT_STRIDE,
  120. // mpi->w,mpi->h);
  121. (mpi->width+7)&(~7),(mpi->height+7)&(~7));
  122. vf->dmpi->w=mpi->w; vf->dmpi->h=mpi->h; // display w;h
  123. }
  124. if(vf->priv->pp || !(mpi->flags&MP_IMGFLAG_DIRECT)){
  125. // do the postprocessing! (or copy if no DR)
  126. pp_postprocess(mpi->planes ,mpi->stride,
  127. vf->dmpi->planes,vf->dmpi->stride,
  128. (mpi->w+7)&(~7),mpi->h,
  129. mpi->qscale, mpi->qstride,
  130. vf->priv->ppMode[ vf->priv->pp ], vf->priv->context,
  131. #ifdef PP_PICT_TYPE_QP2
  132. mpi->pict_type | (mpi->qscale_type ? PP_PICT_TYPE_QP2 : 0));
  133. #else
  134. mpi->pict_type);
  135. #endif
  136. }
  137. return vf_next_put_image(vf,vf->dmpi, pts);
  138. }
  139. //===========================================================================//
  140. static const unsigned int fmt_list[]={
  141. IMGFMT_YV12,
  142. IMGFMT_I420,
  143. IMGFMT_IYUV,
  144. IMGFMT_444P,
  145. IMGFMT_422P,
  146. IMGFMT_411P,
  147. 0
  148. };
  149. static int vf_open(vf_instance_t *vf, char *args){
  150. char *endptr, *name;
  151. int i;
  152. int hex_mode=0;
  153. vf->query_format=query_format;
  154. vf->control=control;
  155. vf->config=config;
  156. vf->get_image=get_image;
  157. vf->put_image=put_image;
  158. vf->uninit=uninit;
  159. vf->default_caps=VFCAP_ACCEPT_STRIDE|VFCAP_POSTPROC;
  160. vf->priv=malloc(sizeof(struct vf_priv_s));
  161. vf->priv->context=NULL;
  162. // check csp:
  163. vf->priv->outfmt=vf_match_csp(&vf->next,fmt_list,IMGFMT_YV12);
  164. if(!vf->priv->outfmt) return 0; // no csp match :(
  165. if(args && *args){
  166. hex_mode= strtol(args, &endptr, 0);
  167. if(*endptr){
  168. name= args;
  169. }else
  170. name= NULL;
  171. }else{
  172. name="de";
  173. }
  174. #ifdef EMU_OLD
  175. if(name){
  176. #endif
  177. for(i=0; i<=PP_QUALITY_MAX; i++){
  178. vf->priv->ppMode[i]= pp_get_mode_by_name_and_quality(name, i);
  179. if(vf->priv->ppMode[i]==NULL) return -1;
  180. }
  181. #ifdef EMU_OLD
  182. }else{
  183. /* hex mode for compatibility */
  184. for(i=0; i<=PP_QUALITY_MAX; i++){
  185. PPMode *ppMode;
  186. ppMode = av_malloc(sizeof(PPMode));
  187. ppMode->lumMode= hex_mode;
  188. ppMode->chromMode= ((hex_mode&0xFF)>>4) | (hex_mode&0xFFFFFF00);
  189. ppMode->maxTmpNoise[0]= 700;
  190. ppMode->maxTmpNoise[1]= 1500;
  191. ppMode->maxTmpNoise[2]= 3000;
  192. ppMode->maxAllowedY= 234;
  193. ppMode->minAllowedY= 16;
  194. ppMode->baseDcDiff= 256/4;
  195. ppMode->flatnessThreshold=40;
  196. vf->priv->ppMode[i]= ppMode;
  197. }
  198. }
  199. #endif
  200. vf->priv->pp=PP_QUALITY_MAX;
  201. return 1;
  202. }
  203. const vf_info_t vf_info_pp = {
  204. "postprocessing",
  205. "pp",
  206. "A'rpi",
  207. "",
  208. vf_open,
  209. NULL
  210. };
  211. //===========================================================================//