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