1bf215546Sopenharmony_ci/************************************************************************** 2bf215546Sopenharmony_ci * 3bf215546Sopenharmony_ci * Copyright 2009 Younes Manton. 4bf215546Sopenharmony_ci * All Rights Reserved. 5bf215546Sopenharmony_ci * 6bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 7bf215546Sopenharmony_ci * copy of this software and associated documentation files (the 8bf215546Sopenharmony_ci * "Software"), to deal in the Software without restriction, including 9bf215546Sopenharmony_ci * without limitation the rights to use, copy, modify, merge, publish, 10bf215546Sopenharmony_ci * distribute, sub license, and/or sell copies of the Software, and to 11bf215546Sopenharmony_ci * permit persons to whom the Software is furnished to do so, subject to 12bf215546Sopenharmony_ci * the following conditions: 13bf215546Sopenharmony_ci * 14bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the 15bf215546Sopenharmony_ci * next paragraph) shall be included in all copies or substantial portions 16bf215546Sopenharmony_ci * of the Software. 17bf215546Sopenharmony_ci * 18bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19bf215546Sopenharmony_ci * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20bf215546Sopenharmony_ci * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 21bf215546Sopenharmony_ci * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR 22bf215546Sopenharmony_ci * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 23bf215546Sopenharmony_ci * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24bf215546Sopenharmony_ci * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25bf215546Sopenharmony_ci * 26bf215546Sopenharmony_ci **************************************************************************/ 27bf215546Sopenharmony_ci 28bf215546Sopenharmony_ci#ifndef U_VIDEO_H 29bf215546Sopenharmony_ci#define U_VIDEO_H 30bf215546Sopenharmony_ci 31bf215546Sopenharmony_ci#include "pipe/p_defines.h" 32bf215546Sopenharmony_ci#include "pipe/p_video_enums.h" 33bf215546Sopenharmony_ci 34bf215546Sopenharmony_ci/* u_reduce_video_profile() needs these */ 35bf215546Sopenharmony_ci#include "pipe/p_compiler.h" 36bf215546Sopenharmony_ci#include "util/u_debug.h" 37bf215546Sopenharmony_ci#include "util/u_math.h" 38bf215546Sopenharmony_ci 39bf215546Sopenharmony_ci#ifdef __cplusplus 40bf215546Sopenharmony_ciextern "C" { 41bf215546Sopenharmony_ci#endif 42bf215546Sopenharmony_ci 43bf215546Sopenharmony_cistatic inline enum pipe_video_format 44bf215546Sopenharmony_ciu_reduce_video_profile(enum pipe_video_profile profile) 45bf215546Sopenharmony_ci{ 46bf215546Sopenharmony_ci switch (profile) 47bf215546Sopenharmony_ci { 48bf215546Sopenharmony_ci case PIPE_VIDEO_PROFILE_MPEG1: 49bf215546Sopenharmony_ci case PIPE_VIDEO_PROFILE_MPEG2_SIMPLE: 50bf215546Sopenharmony_ci case PIPE_VIDEO_PROFILE_MPEG2_MAIN: 51bf215546Sopenharmony_ci return PIPE_VIDEO_FORMAT_MPEG12; 52bf215546Sopenharmony_ci 53bf215546Sopenharmony_ci case PIPE_VIDEO_PROFILE_MPEG4_SIMPLE: 54bf215546Sopenharmony_ci case PIPE_VIDEO_PROFILE_MPEG4_ADVANCED_SIMPLE: 55bf215546Sopenharmony_ci return PIPE_VIDEO_FORMAT_MPEG4; 56bf215546Sopenharmony_ci 57bf215546Sopenharmony_ci case PIPE_VIDEO_PROFILE_VC1_SIMPLE: 58bf215546Sopenharmony_ci case PIPE_VIDEO_PROFILE_VC1_MAIN: 59bf215546Sopenharmony_ci case PIPE_VIDEO_PROFILE_VC1_ADVANCED: 60bf215546Sopenharmony_ci return PIPE_VIDEO_FORMAT_VC1; 61bf215546Sopenharmony_ci 62bf215546Sopenharmony_ci case PIPE_VIDEO_PROFILE_MPEG4_AVC_BASELINE: 63bf215546Sopenharmony_ci case PIPE_VIDEO_PROFILE_MPEG4_AVC_CONSTRAINED_BASELINE: 64bf215546Sopenharmony_ci case PIPE_VIDEO_PROFILE_MPEG4_AVC_MAIN: 65bf215546Sopenharmony_ci case PIPE_VIDEO_PROFILE_MPEG4_AVC_EXTENDED: 66bf215546Sopenharmony_ci case PIPE_VIDEO_PROFILE_MPEG4_AVC_HIGH: 67bf215546Sopenharmony_ci case PIPE_VIDEO_PROFILE_MPEG4_AVC_HIGH10: 68bf215546Sopenharmony_ci case PIPE_VIDEO_PROFILE_MPEG4_AVC_HIGH422: 69bf215546Sopenharmony_ci case PIPE_VIDEO_PROFILE_MPEG4_AVC_HIGH444: 70bf215546Sopenharmony_ci return PIPE_VIDEO_FORMAT_MPEG4_AVC; 71bf215546Sopenharmony_ci 72bf215546Sopenharmony_ci case PIPE_VIDEO_PROFILE_HEVC_MAIN: 73bf215546Sopenharmony_ci case PIPE_VIDEO_PROFILE_HEVC_MAIN_10: 74bf215546Sopenharmony_ci case PIPE_VIDEO_PROFILE_HEVC_MAIN_STILL: 75bf215546Sopenharmony_ci case PIPE_VIDEO_PROFILE_HEVC_MAIN_12: 76bf215546Sopenharmony_ci case PIPE_VIDEO_PROFILE_HEVC_MAIN_444: 77bf215546Sopenharmony_ci return PIPE_VIDEO_FORMAT_HEVC; 78bf215546Sopenharmony_ci 79bf215546Sopenharmony_ci case PIPE_VIDEO_PROFILE_JPEG_BASELINE: 80bf215546Sopenharmony_ci return PIPE_VIDEO_FORMAT_JPEG; 81bf215546Sopenharmony_ci 82bf215546Sopenharmony_ci case PIPE_VIDEO_PROFILE_VP9_PROFILE0: 83bf215546Sopenharmony_ci case PIPE_VIDEO_PROFILE_VP9_PROFILE2: 84bf215546Sopenharmony_ci return PIPE_VIDEO_FORMAT_VP9; 85bf215546Sopenharmony_ci 86bf215546Sopenharmony_ci case PIPE_VIDEO_PROFILE_AV1_MAIN: 87bf215546Sopenharmony_ci return PIPE_VIDEO_FORMAT_AV1; 88bf215546Sopenharmony_ci 89bf215546Sopenharmony_ci default: 90bf215546Sopenharmony_ci return PIPE_VIDEO_FORMAT_UNKNOWN; 91bf215546Sopenharmony_ci } 92bf215546Sopenharmony_ci} 93bf215546Sopenharmony_ci 94bf215546Sopenharmony_cistatic inline void 95bf215546Sopenharmony_ciu_copy_nv12_to_yv12(void *const *destination_data, 96bf215546Sopenharmony_ci uint32_t const *destination_pitches, 97bf215546Sopenharmony_ci int src_plane, int src_field, 98bf215546Sopenharmony_ci int src_stride, int num_fields, 99bf215546Sopenharmony_ci uint8_t const *src, 100bf215546Sopenharmony_ci int width, int height) 101bf215546Sopenharmony_ci{ 102bf215546Sopenharmony_ci int x, y; 103bf215546Sopenharmony_ci unsigned u_stride = destination_pitches[2] * num_fields; 104bf215546Sopenharmony_ci unsigned v_stride = destination_pitches[1] * num_fields; 105bf215546Sopenharmony_ci uint8_t *u_dst = (uint8_t *)destination_data[2] + destination_pitches[2] * src_field; 106bf215546Sopenharmony_ci uint8_t *v_dst = (uint8_t *)destination_data[1] + destination_pitches[1] * src_field; 107bf215546Sopenharmony_ci 108bf215546Sopenharmony_ci /* TODO: SIMD */ 109bf215546Sopenharmony_ci for (y = 0; y < height; y++) { 110bf215546Sopenharmony_ci for (x = 0; x < width; x++) { 111bf215546Sopenharmony_ci u_dst[x] = src[2*x]; 112bf215546Sopenharmony_ci v_dst[x] = src[2*x+1]; 113bf215546Sopenharmony_ci } 114bf215546Sopenharmony_ci u_dst += u_stride; 115bf215546Sopenharmony_ci v_dst += v_stride; 116bf215546Sopenharmony_ci src += src_stride; 117bf215546Sopenharmony_ci } 118bf215546Sopenharmony_ci} 119bf215546Sopenharmony_ci 120bf215546Sopenharmony_ci/** 121bf215546Sopenharmony_ci * \brief Copy YV12 chroma data while converting it NV12 122bf215546Sopenharmony_ci * 123bf215546Sopenharmony_ci * Given a set of YV12 source pointers and -pitches, copy the data to a 124bf215546Sopenharmony_ci * layout typical for NV12 video buffers. 125bf215546Sopenharmony_ci * 126bf215546Sopenharmony_ci * \param source data[in] The plane data pointers. Array of 3. 127bf215546Sopenharmony_ci * \param source_pitches[in] The plane pitches. Array of 3. 128bf215546Sopenharmony_ci * \param dst_plane[in] The destination plane to copy to. For NV12 always 1. 129bf215546Sopenharmony_ci * \param dst_field[in] The destination field if interlaced. 130bf215546Sopenharmony_ci * \param dst_stride[in] The destination stride for this plane. 131bf215546Sopenharmony_ci * \param num_fields[in] The number of fields in the video buffer. 132bf215546Sopenharmony_ci * \param dst[in] The destination plane pointer. 133bf215546Sopenharmony_ci * \param width[in] The source plane width. 134bf215546Sopenharmony_ci * \param height[in] The source plane height. 135bf215546Sopenharmony_ci */ 136bf215546Sopenharmony_cistatic inline void 137bf215546Sopenharmony_ciu_copy_nv12_from_yv12(const void *const *source_data, 138bf215546Sopenharmony_ci uint32_t const *source_pitches, 139bf215546Sopenharmony_ci int dst_plane, int dst_field, 140bf215546Sopenharmony_ci int dst_stride, int num_fields, 141bf215546Sopenharmony_ci uint8_t *dst, 142bf215546Sopenharmony_ci int width, int height) 143bf215546Sopenharmony_ci{ 144bf215546Sopenharmony_ci int x, y; 145bf215546Sopenharmony_ci unsigned u_stride = source_pitches[2] * num_fields; 146bf215546Sopenharmony_ci unsigned v_stride = source_pitches[1] * num_fields; 147bf215546Sopenharmony_ci uint8_t *u_src = (uint8_t *)source_data[2] + source_pitches[2] * dst_field; 148bf215546Sopenharmony_ci uint8_t *v_src = (uint8_t *)source_data[1] + source_pitches[1] * dst_field; 149bf215546Sopenharmony_ci 150bf215546Sopenharmony_ci /* TODO: SIMD */ 151bf215546Sopenharmony_ci for (y = 0; y < height; y++) { 152bf215546Sopenharmony_ci for (x = 0; x < width; x++) { 153bf215546Sopenharmony_ci dst[2*x] = u_src[x]; 154bf215546Sopenharmony_ci dst[2*x+1] = v_src[x]; 155bf215546Sopenharmony_ci } 156bf215546Sopenharmony_ci u_src += u_stride; 157bf215546Sopenharmony_ci v_src += v_stride; 158bf215546Sopenharmony_ci dst += dst_stride; 159bf215546Sopenharmony_ci } 160bf215546Sopenharmony_ci} 161bf215546Sopenharmony_ci 162bf215546Sopenharmony_cistatic inline void 163bf215546Sopenharmony_ciu_copy_yv12_to_nv12(void *const *destination_data, 164bf215546Sopenharmony_ci uint32_t const *destination_pitches, 165bf215546Sopenharmony_ci int src_plane, int src_field, 166bf215546Sopenharmony_ci int src_stride, int num_fields, 167bf215546Sopenharmony_ci uint8_t const *src, 168bf215546Sopenharmony_ci int width, int height) 169bf215546Sopenharmony_ci{ 170bf215546Sopenharmony_ci int x, y; 171bf215546Sopenharmony_ci unsigned offset = 2 - src_plane; 172bf215546Sopenharmony_ci unsigned stride = destination_pitches[1] * num_fields; 173bf215546Sopenharmony_ci uint8_t *dst = (uint8_t *)destination_data[1] + destination_pitches[1] * src_field; 174bf215546Sopenharmony_ci 175bf215546Sopenharmony_ci /* TODO: SIMD */ 176bf215546Sopenharmony_ci for (y = 0; y < height; y++) { 177bf215546Sopenharmony_ci for (x = 0; x < 2 * width; x += 2) { 178bf215546Sopenharmony_ci dst[x+offset] = src[x>>1]; 179bf215546Sopenharmony_ci } 180bf215546Sopenharmony_ci dst += stride; 181bf215546Sopenharmony_ci src += src_stride; 182bf215546Sopenharmony_ci } 183bf215546Sopenharmony_ci} 184bf215546Sopenharmony_ci 185bf215546Sopenharmony_cistatic inline void 186bf215546Sopenharmony_ciu_copy_swap422_packed(void *const *destination_data, 187bf215546Sopenharmony_ci uint32_t const *destination_pitches, 188bf215546Sopenharmony_ci int src_plane, int src_field, 189bf215546Sopenharmony_ci int src_stride, int num_fields, 190bf215546Sopenharmony_ci uint8_t const *src, 191bf215546Sopenharmony_ci int width, int height) 192bf215546Sopenharmony_ci{ 193bf215546Sopenharmony_ci int x, y; 194bf215546Sopenharmony_ci unsigned stride = destination_pitches[0] * num_fields; 195bf215546Sopenharmony_ci uint8_t *dst = (uint8_t *)destination_data[0] + destination_pitches[0] * src_field; 196bf215546Sopenharmony_ci 197bf215546Sopenharmony_ci /* TODO: SIMD */ 198bf215546Sopenharmony_ci for (y = 0; y < height; y++) { 199bf215546Sopenharmony_ci for (x = 0; x < 4 * width; x += 4) { 200bf215546Sopenharmony_ci dst[x+0] = src[x+1]; 201bf215546Sopenharmony_ci dst[x+1] = src[x+0]; 202bf215546Sopenharmony_ci dst[x+2] = src[x+3]; 203bf215546Sopenharmony_ci dst[x+3] = src[x+2]; 204bf215546Sopenharmony_ci } 205bf215546Sopenharmony_ci dst += stride; 206bf215546Sopenharmony_ci src += src_stride; 207bf215546Sopenharmony_ci } 208bf215546Sopenharmony_ci} 209bf215546Sopenharmony_ci 210bf215546Sopenharmony_cistatic inline uint32_t 211bf215546Sopenharmony_ciu_get_h264_level(uint32_t width, uint32_t height, uint32_t *max_reference) 212bf215546Sopenharmony_ci{ 213bf215546Sopenharmony_ci uint32_t max_dpb_mbs; 214bf215546Sopenharmony_ci 215bf215546Sopenharmony_ci width = align(width, 16); 216bf215546Sopenharmony_ci height = align(height, 16); 217bf215546Sopenharmony_ci 218bf215546Sopenharmony_ci /* Max references will be used for caculation of number of DPB buffers 219bf215546Sopenharmony_ci in the UVD driver, limitation of max references is 16. Some client 220bf215546Sopenharmony_ci like mpv application for VA-API, it requires references more than that, 221bf215546Sopenharmony_ci so we have to set max of references to 16 here. */ 222bf215546Sopenharmony_ci *max_reference = MIN2(*max_reference, 16); 223bf215546Sopenharmony_ci max_dpb_mbs = (width / 16) * (height / 16) * *max_reference; 224bf215546Sopenharmony_ci 225bf215546Sopenharmony_ci /* The calculation is based on "Decoded picture buffering" section 226bf215546Sopenharmony_ci from http://en.wikipedia.org/wiki/H.264/MPEG-4_AVC */ 227bf215546Sopenharmony_ci if (max_dpb_mbs <= 8100) 228bf215546Sopenharmony_ci return 30; 229bf215546Sopenharmony_ci else if (max_dpb_mbs <= 18000) 230bf215546Sopenharmony_ci return 31; 231bf215546Sopenharmony_ci else if (max_dpb_mbs <= 20480) 232bf215546Sopenharmony_ci return 32; 233bf215546Sopenharmony_ci else if (max_dpb_mbs <= 32768) 234bf215546Sopenharmony_ci return 41; 235bf215546Sopenharmony_ci else if (max_dpb_mbs <= 34816) 236bf215546Sopenharmony_ci return 42; 237bf215546Sopenharmony_ci else if (max_dpb_mbs <= 110400) 238bf215546Sopenharmony_ci return 50; 239bf215546Sopenharmony_ci else if (max_dpb_mbs <= 184320) 240bf215546Sopenharmony_ci return 51; 241bf215546Sopenharmony_ci else 242bf215546Sopenharmony_ci return 52; 243bf215546Sopenharmony_ci} 244bf215546Sopenharmony_ci 245bf215546Sopenharmony_cistatic inline uint32_t 246bf215546Sopenharmony_ciu_get_h264_profile_idc(enum pipe_video_profile profile) 247bf215546Sopenharmony_ci{ 248bf215546Sopenharmony_ci switch (profile) { 249bf215546Sopenharmony_ci case PIPE_VIDEO_PROFILE_MPEG4_AVC_CONSTRAINED_BASELINE: 250bf215546Sopenharmony_ci case PIPE_VIDEO_PROFILE_MPEG4_AVC_BASELINE: 251bf215546Sopenharmony_ci return 66; 252bf215546Sopenharmony_ci case PIPE_VIDEO_PROFILE_MPEG4_AVC_MAIN: 253bf215546Sopenharmony_ci return 77; 254bf215546Sopenharmony_ci case PIPE_VIDEO_PROFILE_MPEG4_AVC_EXTENDED: 255bf215546Sopenharmony_ci return 88; 256bf215546Sopenharmony_ci case PIPE_VIDEO_PROFILE_MPEG4_AVC_HIGH: 257bf215546Sopenharmony_ci return 100; 258bf215546Sopenharmony_ci case PIPE_VIDEO_PROFILE_MPEG4_AVC_HIGH10: 259bf215546Sopenharmony_ci return 110; 260bf215546Sopenharmony_ci case PIPE_VIDEO_PROFILE_MPEG4_AVC_HIGH422: 261bf215546Sopenharmony_ci return 122; 262bf215546Sopenharmony_ci case PIPE_VIDEO_PROFILE_MPEG4_AVC_HIGH444: 263bf215546Sopenharmony_ci return 244; 264bf215546Sopenharmony_ci default: 265bf215546Sopenharmony_ci return 66; //use baseline profile instead 266bf215546Sopenharmony_ci } 267bf215546Sopenharmony_ci} 268bf215546Sopenharmony_ci 269bf215546Sopenharmony_ci#ifdef __cplusplus 270bf215546Sopenharmony_ci} 271bf215546Sopenharmony_ci#endif 272bf215546Sopenharmony_ci 273bf215546Sopenharmony_ci#endif /* U_VIDEO_H */ 274