1 /*
2  * This file is part of mpv.
3  *
4  * mpv is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * mpv 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 Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with mpv.  If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 #include <libavutil/pixdesc.h>
19 #include <libavutil/avutil.h>
20 
21 #include "video/img_format.h"
22 #include "fmt-conversion.h"
23 #include "config.h"
24 
25 static const struct {
26     int fmt;
27     enum AVPixelFormat pix_fmt;
28 } conversion_map[] = {
29     {IMGFMT_ARGB, AV_PIX_FMT_ARGB},
30     {IMGFMT_BGRA, AV_PIX_FMT_BGRA},
31     {IMGFMT_BGR24, AV_PIX_FMT_BGR24},
32     {IMGFMT_RGB565, AV_PIX_FMT_RGB565},
33     {IMGFMT_ABGR, AV_PIX_FMT_ABGR},
34     {IMGFMT_RGBA, AV_PIX_FMT_RGBA},
35     {IMGFMT_RGB24, AV_PIX_FMT_RGB24},
36     {IMGFMT_PAL8,  AV_PIX_FMT_PAL8},
37     {IMGFMT_UYVY,  AV_PIX_FMT_UYVY422},
38     {IMGFMT_NV12,  AV_PIX_FMT_NV12},
39     {IMGFMT_Y8,    AV_PIX_FMT_GRAY8},
40     {IMGFMT_Y16, AV_PIX_FMT_GRAY16},
41     {IMGFMT_420P,  AV_PIX_FMT_YUV420P},
42     {IMGFMT_444P,  AV_PIX_FMT_YUV444P},
43 
44     // YUVJ are YUV formats that use the full Y range. Decoder color range
45     // information is used instead. Deprecated in ffmpeg.
46     {IMGFMT_420P,  AV_PIX_FMT_YUVJ420P},
47     {IMGFMT_444P,  AV_PIX_FMT_YUVJ444P},
48 
49     {IMGFMT_BGR0,  AV_PIX_FMT_BGR0},
50     {IMGFMT_0RGB,  AV_PIX_FMT_0RGB},
51     {IMGFMT_RGB0,  AV_PIX_FMT_RGB0},
52     {IMGFMT_0BGR,  AV_PIX_FMT_0BGR},
53 
54     {IMGFMT_RGBA64, AV_PIX_FMT_RGBA64},
55 
56 #ifdef AV_PIX_FMT_X2RGB10
57     {IMGFMT_RGB30,  AV_PIX_FMT_X2RGB10},
58 #endif
59 
60     {IMGFMT_VDPAU, AV_PIX_FMT_VDPAU},
61     {IMGFMT_VIDEOTOOLBOX,   AV_PIX_FMT_VIDEOTOOLBOX},
62     {IMGFMT_MEDIACODEC, AV_PIX_FMT_MEDIACODEC},
63     {IMGFMT_VAAPI, AV_PIX_FMT_VAAPI},
64     {IMGFMT_DXVA2, AV_PIX_FMT_DXVA2_VLD},
65     {IMGFMT_D3D11, AV_PIX_FMT_D3D11},
66     {IMGFMT_MMAL, AV_PIX_FMT_MMAL},
67     {IMGFMT_CUDA, AV_PIX_FMT_CUDA},
68     {IMGFMT_P010, AV_PIX_FMT_P010},
69     {IMGFMT_DRMPRIME, AV_PIX_FMT_DRM_PRIME},
70 
71     {0, AV_PIX_FMT_NONE}
72 };
73 
imgfmt2pixfmt(int fmt)74 enum AVPixelFormat imgfmt2pixfmt(int fmt)
75 {
76     if (fmt == IMGFMT_NONE)
77         return AV_PIX_FMT_NONE;
78 
79     if (fmt >= IMGFMT_AVPIXFMT_START && fmt < IMGFMT_AVPIXFMT_END) {
80         enum AVPixelFormat pixfmt = fmt - IMGFMT_AVPIXFMT_START;
81         // Avoid duplicate format - each format must be unique.
82         int mpfmt = pixfmt2imgfmt(pixfmt);
83         if (mpfmt == fmt && av_pix_fmt_desc_get(pixfmt))
84             return pixfmt;
85         return AV_PIX_FMT_NONE;
86     }
87 
88     for (int i = 0; conversion_map[i].fmt; i++) {
89         if (conversion_map[i].fmt == fmt)
90             return conversion_map[i].pix_fmt;
91     }
92     return AV_PIX_FMT_NONE;
93 }
94 
pixfmt2imgfmt(enum AVPixelFormat pix_fmt)95 int pixfmt2imgfmt(enum AVPixelFormat pix_fmt)
96 {
97     if (pix_fmt == AV_PIX_FMT_NONE)
98         return IMGFMT_NONE;
99 
100     for (int i = 0; conversion_map[i].pix_fmt != AV_PIX_FMT_NONE; i++) {
101         if (conversion_map[i].pix_fmt == pix_fmt)
102             return conversion_map[i].fmt;
103     }
104 
105     int generic = IMGFMT_AVPIXFMT_START + pix_fmt;
106     if (generic < IMGFMT_AVPIXFMT_END && av_pix_fmt_desc_get(pix_fmt))
107         return generic;
108 
109     return 0;
110 }
111