chroma: move cvpx_i420 to cxpx
[vlc.git] / modules / video_chroma / cvpx.c
1 /*****************************************************************************
2  * cvpx.c: core video buffer to picture converter
3  *****************************************************************************
4  * Copyright (C) 2015-2017 VLC authors, VideoLAN and VideoLabs
5  *
6  * Authors: Felix Paul K├╝hne <fkuehne at videolan dot org>
7  *
8  * This program is free software; you can redistribute it and/or modify it
9  * under the terms of the GNU Lesser General Public License as published by
10  * the Free Software Foundation; either version 2.1 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public License
19  * along with this program; if not, write to the Free Software Foundation,
20  * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
21  *****************************************************************************/
22
23 #include <QuartzCore/QuartzCore.h>
24 #include <VideoToolbox/VideoToolbox.h>
25
26 #ifdef HAVE_CONFIG_H
27 # include "config.h"
28 #endif
29
30 #include <vlc_common.h>
31 #include <vlc_plugin.h>
32 #include <vlc_filter.h>
33 #include <vlc_picture.h>
34 #include "copy.h"
35
36 struct picture_sys_t {
37     CVPixelBufferRef pixelBuffer;
38 };
39
40 static int  Activate(vlc_object_t * );
41 static void CVPX_I420(filter_t *, picture_t *, picture_t *);
42 static picture_t *CVPX_I420_Filter( filter_t *, picture_t * );
43
44 vlc_module_begin ()
45 set_description( N_("Conversions from CoreVideo buffers to I420") )
46 set_capability( "video converter", 10 )
47 set_callbacks( Activate, NULL )
48 vlc_module_end ()
49
50 static int Activate(vlc_object_t *obj)
51 {
52     filter_t *p_filter = (filter_t *)obj;
53     if (p_filter->fmt_in.video.i_chroma != VLC_CODEC_CVPX_NV12)
54         return VLC_EGENERIC;
55
56     if (p_filter->fmt_in.video.i_height != p_filter->fmt_out.video.i_height
57         || p_filter->fmt_in.video.i_width != p_filter->fmt_out.video.i_width)
58         return VLC_EGENERIC;
59
60     if (p_filter->fmt_out.video.i_chroma != VLC_CODEC_I420)
61         return VLC_EGENERIC;
62
63     p_filter->pf_video_filter = CVPX_I420_Filter;
64
65     return VLC_SUCCESS;
66 }
67
68 VIDEO_FILTER_WRAPPER( CVPX_I420 )
69
70 static void CVPX_I420(filter_t *p_filter, picture_t *sourcePicture, picture_t *destinationPicture)
71 {
72     VLC_UNUSED(p_filter);
73     picture_sys_t *picsys = sourcePicture->p_sys;
74
75     if (picsys == NULL)
76         return;
77
78     if (picsys->pixelBuffer == nil)
79         return;
80
81     unsigned width = CVPixelBufferGetWidthOfPlane(picsys->pixelBuffer, 0);
82     unsigned height = CVPixelBufferGetHeightOfPlane(picsys->pixelBuffer, 0);
83
84     if (width == 0 || height == 0)
85         return;
86
87     uint8_t *pp_plane[2];
88     size_t pi_pitch[2];
89
90     CVPixelBufferLockBaseAddress(picsys->pixelBuffer, kCVPixelBufferLock_ReadOnly);
91
92     for (int i = 0; i < 2; i++) {
93         pp_plane[i] = CVPixelBufferGetBaseAddressOfPlane(picsys->pixelBuffer, i);
94         pi_pitch[i] = CVPixelBufferGetBytesPerRowOfPlane(picsys->pixelBuffer, i);
95     }
96
97     copy_cache_t cache;
98
99     if (CopyInitCache(&cache, width))
100         return;
101
102     CopyFromNv12ToI420(destinationPicture, pp_plane, pi_pitch, height, &cache);
103
104     CopyCleanCache(&cache);
105
106     CVPixelBufferUnlockBaseAddress(picsys->pixelBuffer, kCVPixelBufferLock_ReadOnly);
107 }