You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

787 lines
26KB

  1. /*
  2. * Copyright (c) 2011 Michael Niedermayer
  3. *
  4. * This file is part of FFmpeg.
  5. *
  6. * FFmpeg is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation; either version 2 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * FFmpeg is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with FFmpeg; if not, write to the Free Software
  18. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  19. *
  20. * Parts of this file have been stolen from mplayer
  21. */
  22. /**
  23. * @file
  24. */
  25. #include "avfilter.h"
  26. #include "video.h"
  27. #include "formats.h"
  28. #include "internal.h"
  29. #include "libavutil/avassert.h"
  30. #include "libavutil/pixdesc.h"
  31. #include "libavutil/intreadwrite.h"
  32. #include "libavutil/imgutils.h"
  33. #include "libavutil/opt.h"
  34. #include "libmpcodecs/vf.h"
  35. #include "libmpcodecs/img_format.h"
  36. #include "libmpcodecs/cpudetect.h"
  37. #include "libmpcodecs/av_helpers.h"
  38. #include "libmpcodecs/libvo/fastmemcpy.h"
  39. #include "libswscale/swscale.h"
  40. //FIXME maybe link the orig in
  41. //XXX: identical pix_fmt must be following with each others
  42. static const struct {
  43. int fmt;
  44. enum AVPixelFormat pix_fmt;
  45. } conversion_map[] = {
  46. {IMGFMT_ARGB, AV_PIX_FMT_ARGB},
  47. {IMGFMT_BGRA, AV_PIX_FMT_BGRA},
  48. {IMGFMT_BGR24, AV_PIX_FMT_BGR24},
  49. {IMGFMT_BGR16BE, AV_PIX_FMT_RGB565BE},
  50. {IMGFMT_BGR16LE, AV_PIX_FMT_RGB565LE},
  51. {IMGFMT_BGR15BE, AV_PIX_FMT_RGB555BE},
  52. {IMGFMT_BGR15LE, AV_PIX_FMT_RGB555LE},
  53. {IMGFMT_BGR12BE, AV_PIX_FMT_RGB444BE},
  54. {IMGFMT_BGR12LE, AV_PIX_FMT_RGB444LE},
  55. {IMGFMT_BGR8, AV_PIX_FMT_RGB8},
  56. {IMGFMT_BGR4, AV_PIX_FMT_RGB4},
  57. {IMGFMT_BGR1, AV_PIX_FMT_MONOBLACK},
  58. {IMGFMT_RGB1, AV_PIX_FMT_MONOBLACK},
  59. {IMGFMT_RG4B, AV_PIX_FMT_BGR4_BYTE},
  60. {IMGFMT_BG4B, AV_PIX_FMT_RGB4_BYTE},
  61. {IMGFMT_RGB48LE, AV_PIX_FMT_RGB48LE},
  62. {IMGFMT_RGB48BE, AV_PIX_FMT_RGB48BE},
  63. {IMGFMT_ABGR, AV_PIX_FMT_ABGR},
  64. {IMGFMT_RGBA, AV_PIX_FMT_RGBA},
  65. {IMGFMT_RGB24, AV_PIX_FMT_RGB24},
  66. {IMGFMT_RGB16BE, AV_PIX_FMT_BGR565BE},
  67. {IMGFMT_RGB16LE, AV_PIX_FMT_BGR565LE},
  68. {IMGFMT_RGB15BE, AV_PIX_FMT_BGR555BE},
  69. {IMGFMT_RGB15LE, AV_PIX_FMT_BGR555LE},
  70. {IMGFMT_RGB12BE, AV_PIX_FMT_BGR444BE},
  71. {IMGFMT_RGB12LE, AV_PIX_FMT_BGR444LE},
  72. {IMGFMT_RGB8, AV_PIX_FMT_BGR8},
  73. {IMGFMT_RGB4, AV_PIX_FMT_BGR4},
  74. {IMGFMT_BGR8, AV_PIX_FMT_PAL8},
  75. {IMGFMT_YUY2, AV_PIX_FMT_YUYV422},
  76. {IMGFMT_UYVY, AV_PIX_FMT_UYVY422},
  77. {IMGFMT_NV12, AV_PIX_FMT_NV12},
  78. {IMGFMT_NV21, AV_PIX_FMT_NV21},
  79. {IMGFMT_Y800, AV_PIX_FMT_GRAY8},
  80. {IMGFMT_Y8, AV_PIX_FMT_GRAY8},
  81. {IMGFMT_YVU9, AV_PIX_FMT_YUV410P},
  82. {IMGFMT_IF09, AV_PIX_FMT_YUV410P},
  83. {IMGFMT_YV12, AV_PIX_FMT_YUV420P},
  84. {IMGFMT_I420, AV_PIX_FMT_YUV420P},
  85. {IMGFMT_IYUV, AV_PIX_FMT_YUV420P},
  86. {IMGFMT_411P, AV_PIX_FMT_YUV411P},
  87. {IMGFMT_422P, AV_PIX_FMT_YUV422P},
  88. {IMGFMT_444P, AV_PIX_FMT_YUV444P},
  89. {IMGFMT_440P, AV_PIX_FMT_YUV440P},
  90. {IMGFMT_420A, AV_PIX_FMT_YUVA420P},
  91. {IMGFMT_420P16_LE, AV_PIX_FMT_YUV420P16LE},
  92. {IMGFMT_420P16_BE, AV_PIX_FMT_YUV420P16BE},
  93. {IMGFMT_422P16_LE, AV_PIX_FMT_YUV422P16LE},
  94. {IMGFMT_422P16_BE, AV_PIX_FMT_YUV422P16BE},
  95. {IMGFMT_444P16_LE, AV_PIX_FMT_YUV444P16LE},
  96. {IMGFMT_444P16_BE, AV_PIX_FMT_YUV444P16BE},
  97. // YUVJ are YUV formats that use the full Y range and not just
  98. // 16 - 235 (see colorspaces.txt).
  99. // Currently they are all treated the same way.
  100. {IMGFMT_YV12, AV_PIX_FMT_YUVJ420P},
  101. {IMGFMT_422P, AV_PIX_FMT_YUVJ422P},
  102. {IMGFMT_444P, AV_PIX_FMT_YUVJ444P},
  103. {IMGFMT_440P, AV_PIX_FMT_YUVJ440P},
  104. #if FF_API_XVMC
  105. {IMGFMT_XVMC_MOCO_MPEG2, AV_PIX_FMT_XVMC_MPEG2_MC},
  106. {IMGFMT_XVMC_IDCT_MPEG2, AV_PIX_FMT_XVMC_MPEG2_IDCT},
  107. #endif /* FF_API_XVMC */
  108. {IMGFMT_VDPAU_MPEG1, AV_PIX_FMT_VDPAU_MPEG1},
  109. {IMGFMT_VDPAU_MPEG2, AV_PIX_FMT_VDPAU_MPEG2},
  110. {IMGFMT_VDPAU_H264, AV_PIX_FMT_VDPAU_H264},
  111. {IMGFMT_VDPAU_WMV3, AV_PIX_FMT_VDPAU_WMV3},
  112. {IMGFMT_VDPAU_VC1, AV_PIX_FMT_VDPAU_VC1},
  113. {IMGFMT_VDPAU_MPEG4, AV_PIX_FMT_VDPAU_MPEG4},
  114. {0, AV_PIX_FMT_NONE}
  115. };
  116. extern const vf_info_t ff_vf_info_eq2;
  117. extern const vf_info_t ff_vf_info_eq;
  118. extern const vf_info_t ff_vf_info_ilpack;
  119. extern const vf_info_t ff_vf_info_pp7;
  120. extern const vf_info_t ff_vf_info_softpulldown;
  121. static const vf_info_t* const filters[]={
  122. &ff_vf_info_eq2,
  123. &ff_vf_info_eq,
  124. &ff_vf_info_ilpack,
  125. &ff_vf_info_pp7,
  126. &ff_vf_info_softpulldown,
  127. NULL
  128. };
  129. /*
  130. Unsupported filters
  131. 1bpp
  132. ass
  133. bmovl
  134. crop
  135. dvbscale
  136. flip
  137. expand
  138. format
  139. halfpack
  140. lavc
  141. lavcdeint
  142. noformat
  143. pp
  144. scale
  145. tfields
  146. vo
  147. yadif
  148. zrmjpeg
  149. */
  150. CpuCaps ff_gCpuCaps; //FIXME initialize this so optims work
  151. enum AVPixelFormat ff_mp2ff_pix_fmt(int mp){
  152. int i;
  153. for(i=0; conversion_map[i].fmt && mp != conversion_map[i].fmt; i++)
  154. ;
  155. return mp == conversion_map[i].fmt ? conversion_map[i].pix_fmt : AV_PIX_FMT_NONE;
  156. }
  157. typedef struct {
  158. const AVClass *class;
  159. vf_instance_t vf;
  160. vf_instance_t next_vf;
  161. AVFilterContext *avfctx;
  162. int frame_returned;
  163. char *filter;
  164. enum AVPixelFormat in_pix_fmt;
  165. } MPContext;
  166. #define OFFSET(x) offsetof(MPContext, x)
  167. #define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
  168. static const AVOption mp_options[] = {
  169. { "filter", "set MPlayer filter name and parameters", OFFSET(filter), AV_OPT_TYPE_STRING, {.str=NULL}, .flags = FLAGS },
  170. { NULL }
  171. };
  172. AVFILTER_DEFINE_CLASS(mp);
  173. void ff_mp_msg(int mod, int lev, const char *format, ... ){
  174. va_list va;
  175. va_start(va, format);
  176. //FIXME convert lev/mod
  177. av_vlog(NULL, AV_LOG_DEBUG, format, va);
  178. va_end(va);
  179. }
  180. int ff_mp_msg_test(int mod, int lev){
  181. return 123;
  182. }
  183. void ff_init_avcodec(void)
  184. {
  185. //we maybe should init but its kinda 1. unneeded 2. a bit impolite from here
  186. }
  187. //Exact copy of vf.c
  188. void ff_vf_clone_mpi_attributes(mp_image_t* dst, mp_image_t* src){
  189. dst->pict_type= src->pict_type;
  190. dst->fields = src->fields;
  191. dst->qscale_type= src->qscale_type;
  192. if(dst->width == src->width && dst->height == src->height){
  193. dst->qstride= src->qstride;
  194. dst->qscale= src->qscale;
  195. }
  196. }
  197. //Exact copy of vf.c
  198. void ff_vf_next_draw_slice(struct vf_instance *vf,unsigned char** src, int * stride,int w, int h, int x, int y){
  199. if (vf->next->draw_slice) {
  200. vf->next->draw_slice(vf->next,src,stride,w,h,x,y);
  201. return;
  202. }
  203. if (!vf->dmpi) {
  204. ff_mp_msg(MSGT_VFILTER,MSGL_ERR,"draw_slice: dmpi not stored by vf_%s\n", vf->info->name);
  205. return;
  206. }
  207. if (!(vf->dmpi->flags & MP_IMGFLAG_PLANAR)) {
  208. memcpy_pic(vf->dmpi->planes[0]+y*vf->dmpi->stride[0]+vf->dmpi->bpp/8*x,
  209. src[0], vf->dmpi->bpp/8*w, h, vf->dmpi->stride[0], stride[0]);
  210. return;
  211. }
  212. memcpy_pic(vf->dmpi->planes[0]+y*vf->dmpi->stride[0]+x, src[0],
  213. w, h, vf->dmpi->stride[0], stride[0]);
  214. memcpy_pic(vf->dmpi->planes[1]+(y>>vf->dmpi->chroma_y_shift)*vf->dmpi->stride[1]+(x>>vf->dmpi->chroma_x_shift),
  215. src[1], w>>vf->dmpi->chroma_x_shift, h>>vf->dmpi->chroma_y_shift, vf->dmpi->stride[1], stride[1]);
  216. memcpy_pic(vf->dmpi->planes[2]+(y>>vf->dmpi->chroma_y_shift)*vf->dmpi->stride[2]+(x>>vf->dmpi->chroma_x_shift),
  217. src[2], w>>vf->dmpi->chroma_x_shift, h>>vf->dmpi->chroma_y_shift, vf->dmpi->stride[2], stride[2]);
  218. }
  219. //Exact copy of vf.c
  220. void ff_vf_mpi_clear(mp_image_t* mpi,int x0,int y0,int w,int h){
  221. int y;
  222. if(mpi->flags&MP_IMGFLAG_PLANAR){
  223. y0&=~1;h+=h&1;
  224. if(x0==0 && w==mpi->width){
  225. // full width clear:
  226. memset(mpi->planes[0]+mpi->stride[0]*y0,0,mpi->stride[0]*h);
  227. memset(mpi->planes[1]+mpi->stride[1]*(y0>>mpi->chroma_y_shift),128,mpi->stride[1]*(h>>mpi->chroma_y_shift));
  228. memset(mpi->planes[2]+mpi->stride[2]*(y0>>mpi->chroma_y_shift),128,mpi->stride[2]*(h>>mpi->chroma_y_shift));
  229. } else
  230. for(y=y0;y<y0+h;y+=2){
  231. memset(mpi->planes[0]+x0+mpi->stride[0]*y,0,w);
  232. memset(mpi->planes[0]+x0+mpi->stride[0]*(y+1),0,w);
  233. memset(mpi->planes[1]+(x0>>mpi->chroma_x_shift)+mpi->stride[1]*(y>>mpi->chroma_y_shift),128,(w>>mpi->chroma_x_shift));
  234. memset(mpi->planes[2]+(x0>>mpi->chroma_x_shift)+mpi->stride[2]*(y>>mpi->chroma_y_shift),128,(w>>mpi->chroma_x_shift));
  235. }
  236. return;
  237. }
  238. // packed:
  239. for(y=y0;y<y0+h;y++){
  240. unsigned char* dst=mpi->planes[0]+mpi->stride[0]*y+(mpi->bpp>>3)*x0;
  241. if(mpi->flags&MP_IMGFLAG_YUV){
  242. unsigned int* p=(unsigned int*) dst;
  243. int size=(mpi->bpp>>3)*w/4;
  244. int i;
  245. #if HAVE_BIGENDIAN
  246. #define CLEAR_PACKEDYUV_PATTERN 0x00800080
  247. #define CLEAR_PACKEDYUV_PATTERN_SWAPPED 0x80008000
  248. #else
  249. #define CLEAR_PACKEDYUV_PATTERN 0x80008000
  250. #define CLEAR_PACKEDYUV_PATTERN_SWAPPED 0x00800080
  251. #endif
  252. if(mpi->flags&MP_IMGFLAG_SWAPPED){
  253. for(i=0;i<size-3;i+=4) p[i]=p[i+1]=p[i+2]=p[i+3]=CLEAR_PACKEDYUV_PATTERN_SWAPPED;
  254. for(;i<size;i++) p[i]=CLEAR_PACKEDYUV_PATTERN_SWAPPED;
  255. } else {
  256. for(i=0;i<size-3;i+=4) p[i]=p[i+1]=p[i+2]=p[i+3]=CLEAR_PACKEDYUV_PATTERN;
  257. for(;i<size;i++) p[i]=CLEAR_PACKEDYUV_PATTERN;
  258. }
  259. } else
  260. memset(dst,0,(mpi->bpp>>3)*w);
  261. }
  262. }
  263. int ff_vf_next_query_format(struct vf_instance *vf, unsigned int fmt){
  264. return 1;
  265. }
  266. //used by delogo
  267. unsigned int ff_vf_match_csp(vf_instance_t** vfp,const unsigned int* list,unsigned int preferred){
  268. return preferred;
  269. }
  270. mp_image_t* ff_vf_get_image(vf_instance_t* vf, unsigned int outfmt, int mp_imgtype, int mp_imgflag, int w, int h){
  271. MPContext *m= (MPContext*)(((uint8_t*)vf) - offsetof(MPContext, next_vf));
  272. mp_image_t* mpi=NULL;
  273. int w2;
  274. int number = mp_imgtype >> 16;
  275. av_assert0(vf->next == NULL); // all existing filters call this just on next
  276. //vf_dint needs these as it calls ff_vf_get_image() before configuring the output
  277. if(vf->w==0 && w>0) vf->w=w;
  278. if(vf->h==0 && h>0) vf->h=h;
  279. av_assert0(w == -1 || w >= vf->w);
  280. av_assert0(h == -1 || h >= vf->h);
  281. av_assert0(vf->w > 0);
  282. av_assert0(vf->h > 0);
  283. av_log(m->avfctx, AV_LOG_DEBUG, "get_image: %d:%d, vf: %d:%d\n", w,h,vf->w,vf->h);
  284. if (w == -1) w = vf->w;
  285. if (h == -1) h = vf->h;
  286. w2=(mp_imgflag&MP_IMGFLAG_ACCEPT_ALIGNED_STRIDE)?((w+15)&(~15)):w;
  287. // Note: we should call libvo first to check if it supports direct rendering
  288. // and if not, then fallback to software buffers:
  289. switch(mp_imgtype & 0xff){
  290. case MP_IMGTYPE_EXPORT:
  291. if(!vf->imgctx.export_images[0]) vf->imgctx.export_images[0]=ff_new_mp_image(w2,h);
  292. mpi=vf->imgctx.export_images[0];
  293. break;
  294. case MP_IMGTYPE_STATIC:
  295. if(!vf->imgctx.static_images[0]) vf->imgctx.static_images[0]=ff_new_mp_image(w2,h);
  296. mpi=vf->imgctx.static_images[0];
  297. break;
  298. case MP_IMGTYPE_TEMP:
  299. if(!vf->imgctx.temp_images[0]) vf->imgctx.temp_images[0]=ff_new_mp_image(w2,h);
  300. mpi=vf->imgctx.temp_images[0];
  301. break;
  302. case MP_IMGTYPE_IPB:
  303. if(!(mp_imgflag&MP_IMGFLAG_READABLE)){ // B frame:
  304. if(!vf->imgctx.temp_images[0]) vf->imgctx.temp_images[0]=ff_new_mp_image(w2,h);
  305. mpi=vf->imgctx.temp_images[0];
  306. break;
  307. }
  308. case MP_IMGTYPE_IP:
  309. if(!vf->imgctx.static_images[vf->imgctx.static_idx]) vf->imgctx.static_images[vf->imgctx.static_idx]=ff_new_mp_image(w2,h);
  310. mpi=vf->imgctx.static_images[vf->imgctx.static_idx];
  311. vf->imgctx.static_idx^=1;
  312. break;
  313. case MP_IMGTYPE_NUMBERED:
  314. if (number == -1) {
  315. int i;
  316. for (i = 0; i < NUM_NUMBERED_MPI; i++)
  317. if (!vf->imgctx.numbered_images[i] || !vf->imgctx.numbered_images[i]->usage_count)
  318. break;
  319. number = i;
  320. }
  321. if (number < 0 || number >= NUM_NUMBERED_MPI) return NULL;
  322. if (!vf->imgctx.numbered_images[number]) vf->imgctx.numbered_images[number] = ff_new_mp_image(w2,h);
  323. mpi = vf->imgctx.numbered_images[number];
  324. mpi->number = number;
  325. break;
  326. }
  327. if(mpi){
  328. mpi->type=mp_imgtype;
  329. mpi->w=vf->w; mpi->h=vf->h;
  330. // keep buffer allocation status & color flags only:
  331. // mpi->flags&=~(MP_IMGFLAG_PRESERVE|MP_IMGFLAG_READABLE|MP_IMGFLAG_DIRECT);
  332. mpi->flags&=MP_IMGFLAG_ALLOCATED|MP_IMGFLAG_TYPE_DISPLAYED|MP_IMGFLAGMASK_COLORS;
  333. // accept restrictions, draw_slice and palette flags only:
  334. mpi->flags|=mp_imgflag&(MP_IMGFLAGMASK_RESTRICTIONS|MP_IMGFLAG_DRAW_CALLBACK|MP_IMGFLAG_RGB_PALETTE);
  335. if(!vf->draw_slice) mpi->flags&=~MP_IMGFLAG_DRAW_CALLBACK;
  336. if(mpi->width!=w2 || mpi->height!=h){
  337. // printf("vf.c: MPI parameters changed! %dx%d -> %dx%d \n", mpi->width,mpi->height,w2,h);
  338. if(mpi->flags&MP_IMGFLAG_ALLOCATED){
  339. if(mpi->width<w2 || mpi->height<h){
  340. // need to re-allocate buffer memory:
  341. av_free(mpi->planes[0]);
  342. mpi->flags&=~MP_IMGFLAG_ALLOCATED;
  343. ff_mp_msg(MSGT_VFILTER,MSGL_V,"vf.c: have to REALLOCATE buffer memory :(\n");
  344. }
  345. // } else {
  346. } {
  347. mpi->width=w2; mpi->chroma_width=(w2 + (1<<mpi->chroma_x_shift) - 1)>>mpi->chroma_x_shift;
  348. mpi->height=h; mpi->chroma_height=(h + (1<<mpi->chroma_y_shift) - 1)>>mpi->chroma_y_shift;
  349. }
  350. }
  351. if(!mpi->bpp) ff_mp_image_setfmt(mpi,outfmt);
  352. if(!(mpi->flags&MP_IMGFLAG_ALLOCATED) && mpi->type>MP_IMGTYPE_EXPORT){
  353. av_assert0(!vf->get_image);
  354. // check libvo first!
  355. if(vf->get_image) vf->get_image(vf,mpi);
  356. if(!(mpi->flags&MP_IMGFLAG_DIRECT)){
  357. // non-direct and not yet allocated image. allocate it!
  358. if (!mpi->bpp) { // no way we can allocate this
  359. ff_mp_msg(MSGT_DECVIDEO, MSGL_FATAL,
  360. "ff_vf_get_image: Tried to allocate a format that can not be allocated!\n");
  361. return NULL;
  362. }
  363. // check if codec prefer aligned stride:
  364. if(mp_imgflag&MP_IMGFLAG_PREFER_ALIGNED_STRIDE){
  365. int align=(mpi->flags&MP_IMGFLAG_PLANAR &&
  366. mpi->flags&MP_IMGFLAG_YUV) ?
  367. (8<<mpi->chroma_x_shift)-1 : 15; // -- maybe FIXME
  368. w2=((w+align)&(~align));
  369. if(mpi->width!=w2){
  370. #if 0
  371. // we have to change width... check if we CAN co it:
  372. int flags=vf->query_format(vf,outfmt); // should not fail
  373. if(!(flags&3)) ff_mp_msg(MSGT_DECVIDEO,MSGL_WARN,"??? ff_vf_get_image{vf->query_format(outfmt)} failed!\n");
  374. // printf("query -> 0x%X \n",flags);
  375. if(flags&VFCAP_ACCEPT_STRIDE){
  376. #endif
  377. mpi->width=w2;
  378. mpi->chroma_width=(w2 + (1<<mpi->chroma_x_shift) - 1)>>mpi->chroma_x_shift;
  379. // }
  380. }
  381. }
  382. ff_mp_image_alloc_planes(mpi);
  383. // printf("clearing img!\n");
  384. ff_vf_mpi_clear(mpi,0,0,mpi->width,mpi->height);
  385. }
  386. }
  387. av_assert0(!vf->start_slice);
  388. if(mpi->flags&MP_IMGFLAG_DRAW_CALLBACK)
  389. if(vf->start_slice) vf->start_slice(vf,mpi);
  390. if(!(mpi->flags&MP_IMGFLAG_TYPE_DISPLAYED)){
  391. ff_mp_msg(MSGT_DECVIDEO,MSGL_V,"*** [%s] %s%s mp_image_t, %dx%dx%dbpp %s %s, %d bytes\n",
  392. "NULL"/*vf->info->name*/,
  393. (mpi->type==MP_IMGTYPE_EXPORT)?"Exporting":
  394. ((mpi->flags&MP_IMGFLAG_DIRECT)?"Direct Rendering":"Allocating"),
  395. (mpi->flags&MP_IMGFLAG_DRAW_CALLBACK)?" (slices)":"",
  396. mpi->width,mpi->height,mpi->bpp,
  397. (mpi->flags&MP_IMGFLAG_YUV)?"YUV":((mpi->flags&MP_IMGFLAG_SWAPPED)?"BGR":"RGB"),
  398. (mpi->flags&MP_IMGFLAG_PLANAR)?"planar":"packed",
  399. mpi->bpp*mpi->width*mpi->height/8);
  400. ff_mp_msg(MSGT_DECVIDEO,MSGL_DBG2,"(imgfmt: %x, planes: %p,%p,%p strides: %d,%d,%d, chroma: %dx%d, shift: h:%d,v:%d)\n",
  401. mpi->imgfmt, mpi->planes[0], mpi->planes[1], mpi->planes[2],
  402. mpi->stride[0], mpi->stride[1], mpi->stride[2],
  403. mpi->chroma_width, mpi->chroma_height, mpi->chroma_x_shift, mpi->chroma_y_shift);
  404. mpi->flags|=MP_IMGFLAG_TYPE_DISPLAYED;
  405. }
  406. mpi->qscale = NULL;
  407. mpi->usage_count++;
  408. }
  409. // printf("\rVF_MPI: %p %p %p %d %d %d \n",
  410. // mpi->planes[0],mpi->planes[1],mpi->planes[2],
  411. // mpi->stride[0],mpi->stride[1],mpi->stride[2]);
  412. return mpi;
  413. }
  414. int ff_vf_next_put_image(struct vf_instance *vf,mp_image_t *mpi, double pts){
  415. MPContext *m= (MPContext*)(((uint8_t*)vf) - offsetof(MPContext, vf));
  416. AVFilterLink *outlink = m->avfctx->outputs[0];
  417. AVFrame *picref = av_frame_alloc();
  418. int i;
  419. av_assert0(vf->next);
  420. av_log(m->avfctx, AV_LOG_DEBUG, "ff_vf_next_put_image\n");
  421. if (!picref)
  422. goto fail;
  423. picref->width = mpi->w;
  424. picref->height = mpi->h;
  425. for(i=0; conversion_map[i].fmt && mpi->imgfmt != conversion_map[i].fmt; i++);
  426. picref->format = conversion_map[i].pix_fmt;
  427. for(i=0; conversion_map[i].fmt && m->in_pix_fmt != conversion_map[i].pix_fmt; i++);
  428. if (mpi->imgfmt == conversion_map[i].fmt)
  429. picref->format = conversion_map[i].pix_fmt;
  430. memcpy(picref->linesize, mpi->stride, FFMIN(sizeof(picref->linesize), sizeof(mpi->stride)));
  431. for(i=0; i<4 && mpi->stride[i]; i++){
  432. picref->data[i] = mpi->planes[i];
  433. }
  434. if(pts != MP_NOPTS_VALUE)
  435. picref->pts= pts * av_q2d(outlink->time_base);
  436. if(1) { // mp buffers are currently unsupported in libavfilter, we thus must copy
  437. AVFrame *tofree = picref;
  438. picref = av_frame_clone(picref);
  439. av_frame_free(&tofree);
  440. }
  441. ff_filter_frame(outlink, picref);
  442. m->frame_returned++;
  443. return 1;
  444. fail:
  445. av_frame_free(&picref);
  446. return 0;
  447. }
  448. int ff_vf_next_config(struct vf_instance *vf,
  449. int width, int height, int d_width, int d_height,
  450. unsigned int voflags, unsigned int outfmt){
  451. av_assert0(width>0 && height>0);
  452. vf->next->w = width; vf->next->h = height;
  453. return 1;
  454. #if 0
  455. int flags=vf->next->query_format(vf->next,outfmt);
  456. if(!flags){
  457. // hmm. colorspace mismatch!!!
  458. //this is fatal for us ATM
  459. return 0;
  460. }
  461. ff_mp_msg(MSGT_VFILTER,MSGL_V,"REQ: flags=0x%X req=0x%X \n",flags,vf->default_reqs);
  462. miss=vf->default_reqs - (flags&vf->default_reqs);
  463. if(miss&VFCAP_ACCEPT_STRIDE){
  464. // vf requires stride support but vf->next doesn't support it!
  465. // let's insert the 'expand' filter, it does the job for us:
  466. vf_instance_t* vf2=vf_open_filter(vf->next,"expand",NULL);
  467. if(!vf2) return 0; // shouldn't happen!
  468. vf->next=vf2;
  469. }
  470. vf->next->w = width; vf->next->h = height;
  471. return 1;
  472. #endif
  473. }
  474. int ff_vf_next_control(struct vf_instance *vf, int request, void* data){
  475. MPContext *m= (MPContext*)(((uint8_t*)vf) - offsetof(MPContext, vf));
  476. av_log(m->avfctx, AV_LOG_DEBUG, "Received control %d\n", request);
  477. return 0;
  478. }
  479. static int vf_default_query_format(struct vf_instance *vf, unsigned int fmt){
  480. MPContext *m= (MPContext*)(((uint8_t*)vf) - offsetof(MPContext, vf));
  481. int i;
  482. av_log(m->avfctx, AV_LOG_DEBUG, "query %X\n", fmt);
  483. for(i=0; conversion_map[i].fmt; i++){
  484. if(fmt==conversion_map[i].fmt)
  485. return 1; //we suport all
  486. }
  487. return 0;
  488. }
  489. static av_cold int init(AVFilterContext *ctx)
  490. {
  491. MPContext *m = ctx->priv;
  492. int cpu_flags = av_get_cpu_flags();
  493. char name[256];
  494. const char *args;
  495. int i;
  496. ff_gCpuCaps.hasMMX = cpu_flags & AV_CPU_FLAG_MMX;
  497. ff_gCpuCaps.hasMMX2 = cpu_flags & AV_CPU_FLAG_MMX2;
  498. ff_gCpuCaps.hasSSE = cpu_flags & AV_CPU_FLAG_SSE;
  499. ff_gCpuCaps.hasSSE2 = cpu_flags & AV_CPU_FLAG_SSE2;
  500. ff_gCpuCaps.hasSSE3 = cpu_flags & AV_CPU_FLAG_SSE3;
  501. ff_gCpuCaps.hasSSSE3 = cpu_flags & AV_CPU_FLAG_SSSE3;
  502. ff_gCpuCaps.hasSSE4 = cpu_flags & AV_CPU_FLAG_SSE4;
  503. ff_gCpuCaps.hasSSE42 = cpu_flags & AV_CPU_FLAG_SSE42;
  504. ff_gCpuCaps.hasAVX = cpu_flags & AV_CPU_FLAG_AVX;
  505. ff_gCpuCaps.has3DNow = cpu_flags & AV_CPU_FLAG_3DNOW;
  506. ff_gCpuCaps.has3DNowExt = cpu_flags & AV_CPU_FLAG_3DNOWEXT;
  507. m->avfctx= ctx;
  508. args = m->filter;
  509. if(!args || 1!=sscanf(args, "%255[^:=]", name)){
  510. av_log(ctx, AV_LOG_ERROR, "Invalid parameter.\n");
  511. return AVERROR(EINVAL);
  512. }
  513. args += strlen(name);
  514. if (args[0] == '=')
  515. args++;
  516. for(i=0; ;i++){
  517. if(!filters[i] || !strcmp(name, filters[i]->name))
  518. break;
  519. }
  520. if(!filters[i]){
  521. av_log(ctx, AV_LOG_ERROR, "Unknown filter %s\n", name);
  522. return AVERROR(EINVAL);
  523. }
  524. av_log(ctx, AV_LOG_WARNING,
  525. "'%s' is a wrapped MPlayer filter (libmpcodecs). This filter may be removed\n"
  526. "once it has been ported to a native libavfilter.\n", name);
  527. memset(&m->vf,0,sizeof(m->vf));
  528. m->vf.info= filters[i];
  529. m->vf.next = &m->next_vf;
  530. m->vf.put_image = ff_vf_next_put_image;
  531. m->vf.config = ff_vf_next_config;
  532. m->vf.query_format= vf_default_query_format;
  533. m->vf.control = ff_vf_next_control;
  534. m->vf.default_caps=VFCAP_ACCEPT_STRIDE;
  535. m->vf.default_reqs=0;
  536. if(m->vf.info->opts)
  537. av_log(ctx, AV_LOG_ERROR, "opts / m_struct_set is unsupported\n");
  538. #if 0
  539. if(vf->info->opts) { // vf_vo get some special argument
  540. const m_struct_t* st = vf->info->opts;
  541. void* vf_priv = m_struct_alloc(st);
  542. int n;
  543. for(n = 0 ; args && args[2*n] ; n++)
  544. m_struct_set(st,vf_priv,args[2*n],args[2*n+1]);
  545. vf->priv = vf_priv;
  546. args = NULL;
  547. } else // Otherwise we should have the '_oldargs_'
  548. if(args && !strcmp(args[0],"_oldargs_"))
  549. args = (char**)args[1];
  550. else
  551. args = NULL;
  552. #endif
  553. if(m->vf.info->vf_open(&m->vf, (char*)args)<=0){
  554. av_log(ctx, AV_LOG_ERROR, "vf_open() of %s with arg=%s failed\n", name, args);
  555. return -1;
  556. }
  557. return 0;
  558. }
  559. static av_cold void uninit(AVFilterContext *ctx)
  560. {
  561. MPContext *m = ctx->priv;
  562. vf_instance_t *vf = &m->vf;
  563. while(vf){
  564. vf_instance_t *next = vf->next;
  565. if(vf->uninit)
  566. vf->uninit(vf);
  567. ff_free_mp_image(vf->imgctx.static_images[0]);
  568. ff_free_mp_image(vf->imgctx.static_images[1]);
  569. ff_free_mp_image(vf->imgctx.temp_images[0]);
  570. ff_free_mp_image(vf->imgctx.export_images[0]);
  571. vf = next;
  572. }
  573. }
  574. static int query_formats(AVFilterContext *ctx)
  575. {
  576. AVFilterFormats *avfmts=NULL;
  577. MPContext *m = ctx->priv;
  578. enum AVPixelFormat lastpixfmt = AV_PIX_FMT_NONE;
  579. int i;
  580. for(i=0; conversion_map[i].fmt; i++){
  581. av_log(ctx, AV_LOG_DEBUG, "query: %X\n", conversion_map[i].fmt);
  582. if(m->vf.query_format(&m->vf, conversion_map[i].fmt)){
  583. av_log(ctx, AV_LOG_DEBUG, "supported,adding\n");
  584. if (conversion_map[i].pix_fmt != lastpixfmt) {
  585. ff_add_format(&avfmts, conversion_map[i].pix_fmt);
  586. lastpixfmt = conversion_map[i].pix_fmt;
  587. }
  588. }
  589. }
  590. if (!avfmts)
  591. return -1;
  592. //We assume all allowed input formats are also allowed output formats
  593. ff_set_common_formats(ctx, avfmts);
  594. return 0;
  595. }
  596. static int config_inprops(AVFilterLink *inlink)
  597. {
  598. MPContext *m = inlink->dst->priv;
  599. int i;
  600. for(i=0; conversion_map[i].fmt && conversion_map[i].pix_fmt != inlink->format; i++);
  601. av_assert0(conversion_map[i].fmt && inlink->w && inlink->h);
  602. m->vf.fmt.have_configured = 1;
  603. m->vf.fmt.orig_height = inlink->h;
  604. m->vf.fmt.orig_width = inlink->w;
  605. m->vf.fmt.orig_fmt = conversion_map[i].fmt;
  606. if(m->vf.config(&m->vf, inlink->w, inlink->h, inlink->w, inlink->h, 0, conversion_map[i].fmt)<=0)
  607. return -1;
  608. return 0;
  609. }
  610. static int config_outprops(AVFilterLink *outlink)
  611. {
  612. MPContext *m = outlink->src->priv;
  613. outlink->w = m->next_vf.w;
  614. outlink->h = m->next_vf.h;
  615. return 0;
  616. }
  617. static int request_frame(AVFilterLink *outlink)
  618. {
  619. MPContext *m = outlink->src->priv;
  620. int ret;
  621. av_log(m->avfctx, AV_LOG_DEBUG, "mp request_frame\n");
  622. for(m->frame_returned=0; !m->frame_returned;){
  623. ret=ff_request_frame(outlink->src->inputs[0]);
  624. if(ret<0)
  625. break;
  626. }
  627. av_log(m->avfctx, AV_LOG_DEBUG, "mp request_frame ret=%d\n", ret);
  628. return ret;
  629. }
  630. static int filter_frame(AVFilterLink *inlink, AVFrame *inpic)
  631. {
  632. MPContext *m = inlink->dst->priv;
  633. int i;
  634. double pts= MP_NOPTS_VALUE;
  635. mp_image_t* mpi = ff_new_mp_image(inpic->width, inpic->height);
  636. if(inpic->pts != AV_NOPTS_VALUE)
  637. pts= inpic->pts / av_q2d(inlink->time_base);
  638. for(i=0; conversion_map[i].fmt && conversion_map[i].pix_fmt != inlink->format; i++);
  639. ff_mp_image_setfmt(mpi,conversion_map[i].fmt);
  640. m->in_pix_fmt = inlink->format;
  641. memcpy(mpi->planes, inpic->data, FFMIN(sizeof(inpic->data) , sizeof(mpi->planes)));
  642. memcpy(mpi->stride, inpic->linesize, FFMIN(sizeof(inpic->linesize), sizeof(mpi->stride)));
  643. if (inpic->interlaced_frame)
  644. mpi->fields |= MP_IMGFIELD_INTERLACED;
  645. if (inpic->top_field_first)
  646. mpi->fields |= MP_IMGFIELD_TOP_FIRST;
  647. if (inpic->repeat_pict)
  648. mpi->fields |= MP_IMGFIELD_REPEAT_FIRST;
  649. // mpi->flags|=MP_IMGFLAG_ALLOCATED; ?
  650. mpi->flags |= MP_IMGFLAG_READABLE;
  651. if(!av_frame_is_writable(inpic))
  652. mpi->flags |= MP_IMGFLAG_PRESERVE;
  653. if(m->vf.put_image(&m->vf, mpi, pts) == 0){
  654. av_log(m->avfctx, AV_LOG_DEBUG, "put_image() says skip\n");
  655. }else{
  656. av_frame_free(&inpic);
  657. }
  658. ff_free_mp_image(mpi);
  659. return 0;
  660. }
  661. static const AVFilterPad mp_inputs[] = {
  662. {
  663. .name = "default",
  664. .type = AVMEDIA_TYPE_VIDEO,
  665. .filter_frame = filter_frame,
  666. .config_props = config_inprops,
  667. },
  668. { NULL }
  669. };
  670. static const AVFilterPad mp_outputs[] = {
  671. {
  672. .name = "default",
  673. .type = AVMEDIA_TYPE_VIDEO,
  674. .request_frame = request_frame,
  675. .config_props = config_outprops,
  676. },
  677. { NULL }
  678. };
  679. AVFilter ff_vf_mp = {
  680. .name = "mp",
  681. .description = NULL_IF_CONFIG_SMALL("Apply a libmpcodecs filter to the input video."),
  682. .init = init,
  683. .uninit = uninit,
  684. .priv_size = sizeof(MPContext),
  685. .query_formats = query_formats,
  686. .inputs = mp_inputs,
  687. .outputs = mp_outputs,
  688. .priv_class = &mp_class,
  689. };