1848b8605Smrg/**************************************************************************
2848b8605Smrg *
3848b8605Smrg * Copyright 2009 Younes Manton.
4848b8605Smrg * All Rights Reserved.
5848b8605Smrg *
6848b8605Smrg * Permission is hereby granted, free of charge, to any person obtaining a
7848b8605Smrg * copy of this software and associated documentation files (the
8848b8605Smrg * "Software"), to deal in the Software without restriction, including
9848b8605Smrg * without limitation the rights to use, copy, modify, merge, publish,
10848b8605Smrg * distribute, sub license, and/or sell copies of the Software, and to
11848b8605Smrg * permit persons to whom the Software is furnished to do so, subject to
12848b8605Smrg * the following conditions:
13848b8605Smrg *
14848b8605Smrg * The above copyright notice and this permission notice (including the
15848b8605Smrg * next paragraph) shall be included in all copies or substantial portions
16848b8605Smrg * of the Software.
17848b8605Smrg *
18848b8605Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19848b8605Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20848b8605Smrg * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21848b8605Smrg * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
22848b8605Smrg * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23848b8605Smrg * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24848b8605Smrg * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25848b8605Smrg *
26848b8605Smrg **************************************************************************/
27848b8605Smrg
28848b8605Smrg#ifndef U_VIDEO_H
29848b8605Smrg#define U_VIDEO_H
30848b8605Smrg
31848b8605Smrg#include "pipe/p_defines.h"
32848b8605Smrg#include "pipe/p_video_enums.h"
33848b8605Smrg
34848b8605Smrg/* u_reduce_video_profile() needs these */
35848b8605Smrg#include "pipe/p_compiler.h"
36848b8605Smrg#include "util/u_debug.h"
37b8e80941Smrg#include "util/u_math.h"
38848b8605Smrg
39b8e80941Smrg#ifdef __cplusplus
40b8e80941Smrgextern "C" {
41b8e80941Smrg#endif
42b8e80941Smrg
43b8e80941Smrgstatic inline enum pipe_video_format
44848b8605Smrgu_reduce_video_profile(enum pipe_video_profile profile)
45848b8605Smrg{
46848b8605Smrg   switch (profile)
47848b8605Smrg   {
48848b8605Smrg      case PIPE_VIDEO_PROFILE_MPEG1:
49848b8605Smrg      case PIPE_VIDEO_PROFILE_MPEG2_SIMPLE:
50848b8605Smrg      case PIPE_VIDEO_PROFILE_MPEG2_MAIN:
51848b8605Smrg         return PIPE_VIDEO_FORMAT_MPEG12;
52848b8605Smrg
53848b8605Smrg      case PIPE_VIDEO_PROFILE_MPEG4_SIMPLE:
54848b8605Smrg      case PIPE_VIDEO_PROFILE_MPEG4_ADVANCED_SIMPLE:
55848b8605Smrg         return PIPE_VIDEO_FORMAT_MPEG4;
56848b8605Smrg
57848b8605Smrg      case PIPE_VIDEO_PROFILE_VC1_SIMPLE:
58848b8605Smrg      case PIPE_VIDEO_PROFILE_VC1_MAIN:
59848b8605Smrg      case PIPE_VIDEO_PROFILE_VC1_ADVANCED:
60848b8605Smrg         return PIPE_VIDEO_FORMAT_VC1;
61848b8605Smrg
62848b8605Smrg      case PIPE_VIDEO_PROFILE_MPEG4_AVC_BASELINE:
63b8e80941Smrg      case PIPE_VIDEO_PROFILE_MPEG4_AVC_CONSTRAINED_BASELINE:
64848b8605Smrg      case PIPE_VIDEO_PROFILE_MPEG4_AVC_MAIN:
65848b8605Smrg      case PIPE_VIDEO_PROFILE_MPEG4_AVC_EXTENDED:
66848b8605Smrg      case PIPE_VIDEO_PROFILE_MPEG4_AVC_HIGH:
67848b8605Smrg      case PIPE_VIDEO_PROFILE_MPEG4_AVC_HIGH10:
68848b8605Smrg      case PIPE_VIDEO_PROFILE_MPEG4_AVC_HIGH422:
69848b8605Smrg      case PIPE_VIDEO_PROFILE_MPEG4_AVC_HIGH444:
70848b8605Smrg         return PIPE_VIDEO_FORMAT_MPEG4_AVC;
71848b8605Smrg
72b8e80941Smrg      case PIPE_VIDEO_PROFILE_HEVC_MAIN:
73b8e80941Smrg      case PIPE_VIDEO_PROFILE_HEVC_MAIN_10:
74b8e80941Smrg      case PIPE_VIDEO_PROFILE_HEVC_MAIN_STILL:
75b8e80941Smrg      case PIPE_VIDEO_PROFILE_HEVC_MAIN_12:
76b8e80941Smrg      case PIPE_VIDEO_PROFILE_HEVC_MAIN_444:
77b8e80941Smrg         return PIPE_VIDEO_FORMAT_HEVC;
78b8e80941Smrg
79b8e80941Smrg      case PIPE_VIDEO_PROFILE_JPEG_BASELINE:
80b8e80941Smrg         return PIPE_VIDEO_FORMAT_JPEG;
81b8e80941Smrg
82b8e80941Smrg      case PIPE_VIDEO_PROFILE_VP9_PROFILE0:
83b8e80941Smrg      case PIPE_VIDEO_PROFILE_VP9_PROFILE2:
84b8e80941Smrg         return PIPE_VIDEO_FORMAT_VP9;
85b8e80941Smrg
86848b8605Smrg      default:
87848b8605Smrg         return PIPE_VIDEO_FORMAT_UNKNOWN;
88848b8605Smrg   }
89848b8605Smrg}
90848b8605Smrg
91b8e80941Smrgstatic inline void
92b8e80941Smrgu_copy_nv12_to_yv12(void *const *destination_data,
93b8e80941Smrg                    uint32_t const *destination_pitches,
94b8e80941Smrg                    int src_plane, int src_field,
95b8e80941Smrg                    int src_stride, int num_fields,
96b8e80941Smrg                    uint8_t const *src,
97b8e80941Smrg                    int width, int height)
98b8e80941Smrg{
99b8e80941Smrg   int x, y;
100b8e80941Smrg   unsigned u_stride = destination_pitches[2] * num_fields;
101b8e80941Smrg   unsigned v_stride = destination_pitches[1] * num_fields;
102b8e80941Smrg   uint8_t *u_dst = (uint8_t *)destination_data[2] + destination_pitches[2] * src_field;
103b8e80941Smrg   uint8_t *v_dst = (uint8_t *)destination_data[1] + destination_pitches[1] * src_field;
104b8e80941Smrg
105b8e80941Smrg   /* TODO: SIMD */
106b8e80941Smrg   for (y = 0; y < height; y++) {
107b8e80941Smrg      for (x = 0; x < width; x++) {
108b8e80941Smrg         u_dst[x] = src[2*x];
109b8e80941Smrg         v_dst[x] = src[2*x+1];
110b8e80941Smrg      }
111b8e80941Smrg      u_dst += u_stride;
112b8e80941Smrg      v_dst += v_stride;
113b8e80941Smrg      src += src_stride;
114b8e80941Smrg   }
115b8e80941Smrg}
116b8e80941Smrg
117b8e80941Smrg/**
118b8e80941Smrg * \brief  Copy YV12 chroma data while converting it NV12
119b8e80941Smrg *
120b8e80941Smrg * Given a set of YV12 source pointers and -pitches, copy the data to a
121b8e80941Smrg * layout typical for NV12 video buffers.
122b8e80941Smrg *
123b8e80941Smrg * \param source data[in]  The plane data pointers. Array of 3.
124b8e80941Smrg * \param source_pitches[in]  The plane pitches. Array of 3.
125b8e80941Smrg * \param dst_plane[in]  The destination plane to copy to. For NV12 always 1.
126b8e80941Smrg * \param dst_field[in]  The destination field if interlaced.
127b8e80941Smrg * \param dst_stride[in]  The destination stride for this plane.
128b8e80941Smrg * \param num_fields[in]  The number of fields in the video buffer.
129b8e80941Smrg * \param dst[in]  The destination plane pointer.
130b8e80941Smrg * \param width[in]  The source plane width.
131b8e80941Smrg * \param height[in]  The source plane height.
132b8e80941Smrg */
133b8e80941Smrgstatic inline void
134b8e80941Smrgu_copy_nv12_from_yv12(const void *const *source_data,
135b8e80941Smrg                      uint32_t const *source_pitches,
136b8e80941Smrg                      int dst_plane, int dst_field,
137b8e80941Smrg                      int dst_stride, int num_fields,
138b8e80941Smrg                      uint8_t *dst,
139b8e80941Smrg                      int width, int height)
140b8e80941Smrg{
141b8e80941Smrg   int x, y;
142b8e80941Smrg   unsigned u_stride = source_pitches[2] * num_fields;
143b8e80941Smrg   unsigned v_stride = source_pitches[1] * num_fields;
144b8e80941Smrg   uint8_t *u_src = (uint8_t *)source_data[2] + source_pitches[2] * dst_field;
145b8e80941Smrg   uint8_t *v_src = (uint8_t *)source_data[1] + source_pitches[1] * dst_field;
146b8e80941Smrg
147b8e80941Smrg   /* TODO: SIMD */
148b8e80941Smrg   for (y = 0; y < height; y++) {
149b8e80941Smrg      for (x = 0; x < width; x++) {
150b8e80941Smrg         dst[2*x] = u_src[x];
151b8e80941Smrg         dst[2*x+1] = v_src[x];
152b8e80941Smrg      }
153b8e80941Smrg      u_src += u_stride;
154b8e80941Smrg      v_src += v_stride;
155b8e80941Smrg      dst += dst_stride;
156b8e80941Smrg   }
157b8e80941Smrg}
158b8e80941Smrg
159b8e80941Smrgstatic inline void
160b8e80941Smrgu_copy_yv12_to_nv12(void *const *destination_data,
161b8e80941Smrg                    uint32_t const *destination_pitches,
162b8e80941Smrg                    int src_plane, int src_field,
163b8e80941Smrg                    int src_stride, int num_fields,
164b8e80941Smrg                    uint8_t const *src,
165b8e80941Smrg                    int width, int height)
166b8e80941Smrg{
167b8e80941Smrg   int x, y;
168b8e80941Smrg   unsigned offset = 2 - src_plane;
169b8e80941Smrg   unsigned stride = destination_pitches[1] * num_fields;
170b8e80941Smrg   uint8_t *dst = (uint8_t *)destination_data[1] + destination_pitches[1] * src_field;
171b8e80941Smrg
172b8e80941Smrg   /* TODO: SIMD */
173b8e80941Smrg   for (y = 0; y < height; y++) {
174b8e80941Smrg      for (x = 0; x < 2 * width; x += 2) {
175b8e80941Smrg         dst[x+offset] = src[x>>1];
176b8e80941Smrg      }
177b8e80941Smrg      dst += stride;
178b8e80941Smrg      src += src_stride;
179b8e80941Smrg   }
180b8e80941Smrg}
181b8e80941Smrg
182b8e80941Smrgstatic inline void
183b8e80941Smrgu_copy_swap422_packed(void *const *destination_data,
184b8e80941Smrg                       uint32_t const *destination_pitches,
185b8e80941Smrg                       int src_plane, int src_field,
186b8e80941Smrg                       int src_stride, int num_fields,
187b8e80941Smrg                       uint8_t const *src,
188b8e80941Smrg                       int width, int height)
189b8e80941Smrg{
190b8e80941Smrg   int x, y;
191b8e80941Smrg   unsigned stride = destination_pitches[0] * num_fields;
192b8e80941Smrg   uint8_t *dst = (uint8_t *)destination_data[0] + destination_pitches[0] * src_field;
193b8e80941Smrg
194b8e80941Smrg   /* TODO: SIMD */
195b8e80941Smrg   for (y = 0; y < height; y++) {
196b8e80941Smrg      for (x = 0; x < 4 * width; x += 4) {
197b8e80941Smrg         dst[x+0] = src[x+1];
198b8e80941Smrg         dst[x+1] = src[x+0];
199b8e80941Smrg         dst[x+2] = src[x+3];
200b8e80941Smrg         dst[x+3] = src[x+2];
201b8e80941Smrg      }
202b8e80941Smrg      dst += stride;
203b8e80941Smrg      src += src_stride;
204b8e80941Smrg   }
205b8e80941Smrg}
206b8e80941Smrg
207b8e80941Smrgstatic inline uint32_t
208b8e80941Smrgu_get_h264_level(uint32_t width, uint32_t height, uint32_t *max_reference)
209b8e80941Smrg{
210b8e80941Smrg   uint32_t max_dpb_mbs;
211b8e80941Smrg
212b8e80941Smrg   width = align(width, 16);
213b8e80941Smrg   height = align(height, 16);
214b8e80941Smrg
215b8e80941Smrg   /* Max references will be used for caculation of number of DPB buffers
216b8e80941Smrg      in the UVD driver, limitation of max references is 16. Some client
217b8e80941Smrg      like mpv application for VA-API, it requires references more than that,
218b8e80941Smrg      so we have to set max of references to 16 here. */
219b8e80941Smrg   *max_reference = MIN2(*max_reference, 16);
220b8e80941Smrg   max_dpb_mbs = (width / 16) * (height / 16) * *max_reference;
221b8e80941Smrg
222b8e80941Smrg   /* The calculation is based on "Decoded picture buffering" section
223b8e80941Smrg      from http://en.wikipedia.org/wiki/H.264/MPEG-4_AVC */
224b8e80941Smrg   if (max_dpb_mbs <= 8100)
225b8e80941Smrg      return 30;
226b8e80941Smrg   else if (max_dpb_mbs <= 18000)
227b8e80941Smrg      return 31;
228b8e80941Smrg   else if (max_dpb_mbs <= 20480)
229b8e80941Smrg      return 32;
230b8e80941Smrg   else if (max_dpb_mbs <= 32768)
231b8e80941Smrg      return 41;
232b8e80941Smrg   else if (max_dpb_mbs <= 34816)
233b8e80941Smrg      return 42;
234b8e80941Smrg   else if (max_dpb_mbs <= 110400)
235b8e80941Smrg      return 50;
236b8e80941Smrg   else if (max_dpb_mbs <= 184320)
237b8e80941Smrg      return 51;
238b8e80941Smrg   else
239b8e80941Smrg      return 52;
240b8e80941Smrg}
241b8e80941Smrg
242b8e80941Smrgstatic inline uint32_t
243b8e80941Smrgu_get_h264_profile_idc(enum pipe_video_profile profile)
244b8e80941Smrg{
245b8e80941Smrg   switch (profile) {
246b8e80941Smrg      case PIPE_VIDEO_PROFILE_MPEG4_AVC_CONSTRAINED_BASELINE:
247b8e80941Smrg      case PIPE_VIDEO_PROFILE_MPEG4_AVC_BASELINE:
248b8e80941Smrg         return 66;
249b8e80941Smrg      case PIPE_VIDEO_PROFILE_MPEG4_AVC_MAIN:
250b8e80941Smrg         return 77;
251b8e80941Smrg      case PIPE_VIDEO_PROFILE_MPEG4_AVC_EXTENDED:
252b8e80941Smrg         return 88;
253b8e80941Smrg      case PIPE_VIDEO_PROFILE_MPEG4_AVC_HIGH:
254b8e80941Smrg         return 100;
255b8e80941Smrg      case PIPE_VIDEO_PROFILE_MPEG4_AVC_HIGH10:
256b8e80941Smrg         return 110;
257b8e80941Smrg      case PIPE_VIDEO_PROFILE_MPEG4_AVC_HIGH422:
258b8e80941Smrg         return 122;
259b8e80941Smrg      case PIPE_VIDEO_PROFILE_MPEG4_AVC_HIGH444:
260b8e80941Smrg         return 244;
261b8e80941Smrg      default:
262b8e80941Smrg         return 66; //use baseline profile instead
263b8e80941Smrg   }
264b8e80941Smrg}
265b8e80941Smrg
266848b8605Smrg#ifdef __cplusplus
267848b8605Smrg}
268848b8605Smrg#endif
269848b8605Smrg
270848b8605Smrg#endif /* U_VIDEO_H */
271