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