Path: blob/21.2-virgl/src/gallium/auxiliary/vl/vl_mpeg12_bitstream.c
4565 views
/**************************************************************************1*2* Copyright 2011 Maarten Lankhorst3* Copyright 2011 Christian König4* All Rights Reserved.5*6* Permission is hereby granted, free of charge, to any person obtaining a7* copy of this software and associated documentation files (the8* "Software"), to deal in the Software without restriction, including9* without limitation the rights to use, copy, modify, merge, publish,10* distribute, sub license, and/or sell copies of the Software, and to11* permit persons to whom the Software is furnished to do so, subject to12* the following conditions:13*14* The above copyright notice and this permission notice (including the15* next paragraph) shall be included in all copies or substantial portions16* of the Software.17*18* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS19* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF20* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.21* IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR22* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,23* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE24* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.25*26**************************************************************************/2728#include "pipe/p_video_codec.h"29#include "util/u_memory.h"3031#include "vl_vlc.h"32#include "vl_mpeg12_bitstream.h"3334enum {35dct_End_of_Block = 0xFF,36dct_Escape = 0xFE,37dct_DC = 0xFD,38dct_AC = 0xFC39};4041struct dct_coeff42{43uint8_t length;44uint8_t run;45int16_t level;46};4748struct dct_coeff_compressed49{50uint32_t bitcode;51struct dct_coeff coeff;52};5354/* coding table as found in the spec annex B.5 table B-1 */55static const struct vl_vlc_compressed macroblock_address_increment[] = {56{ 0x8000, { 1, 1 } },57{ 0x6000, { 3, 2 } },58{ 0x4000, { 3, 3 } },59{ 0x3000, { 4, 4 } },60{ 0x2000, { 4, 5 } },61{ 0x1800, { 5, 6 } },62{ 0x1000, { 5, 7 } },63{ 0x0e00, { 7, 8 } },64{ 0x0c00, { 7, 9 } },65{ 0x0b00, { 8, 10 } },66{ 0x0a00, { 8, 11 } },67{ 0x0900, { 8, 12 } },68{ 0x0800, { 8, 13 } },69{ 0x0700, { 8, 14 } },70{ 0x0600, { 8, 15 } },71{ 0x05c0, { 10, 16 } },72{ 0x0580, { 10, 17 } },73{ 0x0540, { 10, 18 } },74{ 0x0500, { 10, 19 } },75{ 0x04c0, { 10, 20 } },76{ 0x0480, { 10, 21 } },77{ 0x0460, { 11, 22 } },78{ 0x0440, { 11, 23 } },79{ 0x0420, { 11, 24 } },80{ 0x0400, { 11, 25 } },81{ 0x03e0, { 11, 26 } },82{ 0x03c0, { 11, 27 } },83{ 0x03a0, { 11, 28 } },84{ 0x0380, { 11, 29 } },85{ 0x0360, { 11, 30 } },86{ 0x0340, { 11, 31 } },87{ 0x0320, { 11, 32 } },88{ 0x0300, { 11, 33 } }89};9091#define Q PIPE_MPEG12_MB_TYPE_QUANT92#define F PIPE_MPEG12_MB_TYPE_MOTION_FORWARD93#define B PIPE_MPEG12_MB_TYPE_MOTION_BACKWARD94#define P PIPE_MPEG12_MB_TYPE_PATTERN95#define I PIPE_MPEG12_MB_TYPE_INTRA9697/* coding table as found in the spec annex B.5 table B-2 */98static const struct vl_vlc_compressed macroblock_type_i[] = {99{ 0x8000, { 1, I } },100{ 0x4000, { 2, Q|I } }101};102103/* coding table as found in the spec annex B.5 table B-3 */104static const struct vl_vlc_compressed macroblock_type_p[] = {105{ 0x8000, { 1, F|P } },106{ 0x4000, { 2, P } },107{ 0x2000, { 3, F } },108{ 0x1800, { 5, I } },109{ 0x1000, { 5, Q|F|P } },110{ 0x0800, { 5, Q|P } },111{ 0x0400, { 6, Q|I } }112};113114/* coding table as found in the spec annex B.5 table B-4 */115static const struct vl_vlc_compressed macroblock_type_b[] = {116{ 0x8000, { 2, F|B } },117{ 0xC000, { 2, F|B|P } },118{ 0x4000, { 3, B } },119{ 0x6000, { 3, B|P } },120{ 0x2000, { 4, F } },121{ 0x3000, { 4, F|P } },122{ 0x1800, { 5, I } },123{ 0x1000, { 5, Q|F|B|P } },124{ 0x0C00, { 6, Q|F|P } },125{ 0x0800, { 6, Q|B|P } },126{ 0x0400, { 6, Q|I } }127};128129#undef Q130#undef F131#undef B132#undef P133#undef I134135/* coding table as found in the spec annex B.5 table B-9 */136static const struct vl_vlc_compressed coded_block_pattern[] = {137{ 0xE000, { 3, 60 } },138{ 0xD000, { 4, 4 } },139{ 0xC000, { 4, 8 } },140{ 0xB000, { 4, 16 } },141{ 0xA000, { 4, 32 } },142{ 0x9800, { 5, 12 } },143{ 0x9000, { 5, 48 } },144{ 0x8800, { 5, 20 } },145{ 0x8000, { 5, 40 } },146{ 0x7800, { 5, 28 } },147{ 0x7000, { 5, 44 } },148{ 0x6800, { 5, 52 } },149{ 0x6000, { 5, 56 } },150{ 0x5800, { 5, 1 } },151{ 0x5000, { 5, 61 } },152{ 0x4800, { 5, 2 } },153{ 0x4000, { 5, 62 } },154{ 0x3C00, { 6, 24 } },155{ 0x3800, { 6, 36 } },156{ 0x3400, { 6, 3 } },157{ 0x3000, { 6, 63 } },158{ 0x2E00, { 7, 5 } },159{ 0x2C00, { 7, 9 } },160{ 0x2A00, { 7, 17 } },161{ 0x2800, { 7, 33 } },162{ 0x2600, { 7, 6 } },163{ 0x2400, { 7, 10 } },164{ 0x2200, { 7, 18 } },165{ 0x2000, { 7, 34 } },166{ 0x1F00, { 8, 7 } },167{ 0x1E00, { 8, 11 } },168{ 0x1D00, { 8, 19 } },169{ 0x1C00, { 8, 35 } },170{ 0x1B00, { 8, 13 } },171{ 0x1A00, { 8, 49 } },172{ 0x1900, { 8, 21 } },173{ 0x1800, { 8, 41 } },174{ 0x1700, { 8, 14 } },175{ 0x1600, { 8, 50 } },176{ 0x1500, { 8, 22 } },177{ 0x1400, { 8, 42 } },178{ 0x1300, { 8, 15 } },179{ 0x1200, { 8, 51 } },180{ 0x1100, { 8, 23 } },181{ 0x1000, { 8, 43 } },182{ 0x0F00, { 8, 25 } },183{ 0x0E00, { 8, 37 } },184{ 0x0D00, { 8, 26 } },185{ 0x0C00, { 8, 38 } },186{ 0x0B00, { 8, 29 } },187{ 0x0A00, { 8, 45 } },188{ 0x0900, { 8, 53 } },189{ 0x0800, { 8, 57 } },190{ 0x0700, { 8, 30 } },191{ 0x0600, { 8, 46 } },192{ 0x0500, { 8, 54 } },193{ 0x0400, { 8, 58 } },194{ 0x0380, { 9, 31 } },195{ 0x0300, { 9, 47 } },196{ 0x0280, { 9, 55 } },197{ 0x0200, { 9, 59 } },198{ 0x0180, { 9, 27 } },199{ 0x0100, { 9, 39 } },200{ 0x0080, { 9, 0 } }201};202203/* coding table as found in the spec annex B.5 table B-10 */204static const struct vl_vlc_compressed motion_code[] = {205{ 0x0320, { 11, -16 } },206{ 0x0360, { 11, -15 } },207{ 0x03a0, { 11, -14 } },208{ 0x03e0, { 11, -13 } },209{ 0x0420, { 11, -12 } },210{ 0x0460, { 11, -11 } },211{ 0x04c0, { 10, -10 } },212{ 0x0540, { 10, -9 } },213{ 0x05c0, { 10, -8 } },214{ 0x0700, { 8, -7 } },215{ 0x0900, { 8, -6 } },216{ 0x0b00, { 8, -5 } },217{ 0x0e00, { 7, -4 } },218{ 0x1800, { 5, -3 } },219{ 0x3000, { 4, -2 } },220{ 0x6000, { 3, -1 } },221{ 0x8000, { 1, 0 } },222{ 0x4000, { 3, 1 } },223{ 0x2000, { 4, 2 } },224{ 0x1000, { 5, 3 } },225{ 0x0c00, { 7, 4 } },226{ 0x0a00, { 8, 5 } },227{ 0x0800, { 8, 6 } },228{ 0x0600, { 8, 7 } },229{ 0x0580, { 10, 8 } },230{ 0x0500, { 10, 9 } },231{ 0x0480, { 10, 10 } },232{ 0x0440, { 11, 11 } },233{ 0x0400, { 11, 12 } },234{ 0x03c0, { 11, 13 } },235{ 0x0380, { 11, 14 } },236{ 0x0340, { 11, 15 } },237{ 0x0300, { 11, 16 } }238};239240/* coding table as found in the spec annex B.5 table B-11 */241static const struct vl_vlc_compressed dmvector[] = {242{ 0x0000, { 1, 0 } },243{ 0x8000, { 2, 1 } },244{ 0xc000, { 2, -1 } }245};246247/* coding table as found in the spec annex B.5 table B-12 */248static const struct vl_vlc_compressed dct_dc_size_luminance[] = {249{ 0x8000, { 3, 0 } },250{ 0x0000, { 2, 1 } },251{ 0x4000, { 2, 2 } },252{ 0xA000, { 3, 3 } },253{ 0xC000, { 3, 4 } },254{ 0xE000, { 4, 5 } },255{ 0xF000, { 5, 6 } },256{ 0xF800, { 6, 7 } },257{ 0xFC00, { 7, 8 } },258{ 0xFE00, { 8, 9 } },259{ 0xFF00, { 9, 10 } },260{ 0xFF80, { 9, 11 } }261};262263/* coding table as found in the spec annex B.5 table B-13 */264static const struct vl_vlc_compressed dct_dc_size_chrominance[] = {265{ 0x0000, { 2, 0 } },266{ 0x4000, { 2, 1 } },267{ 0x8000, { 2, 2 } },268{ 0xC000, { 3, 3 } },269{ 0xE000, { 4, 4 } },270{ 0xF000, { 5, 5 } },271{ 0xF800, { 6, 6 } },272{ 0xFC00, { 7, 7 } },273{ 0xFE00, { 8, 8 } },274{ 0xFF00, { 9, 9 } },275{ 0xFF80, { 10, 10 } },276{ 0xFFC0, { 10, 11 } }277};278279/* coding table as found in the spec annex B.5 table B-14 */280static const struct dct_coeff_compressed dct_coeff_tbl_zero[] = {281{ 0x8000, { 2, dct_End_of_Block, 0 } },282{ 0x8000, { 1, dct_DC, 1 } },283{ 0xC000, { 2, dct_AC, 1 } },284{ 0x6000, { 3, 1, 1 } },285{ 0x4000, { 4, 0, 2 } },286{ 0x5000, { 4, 2, 1 } },287{ 0x2800, { 5, 0, 3 } },288{ 0x3800, { 5, 3, 1 } },289{ 0x3000, { 5, 4, 1 } },290{ 0x1800, { 6, 1, 2 } },291{ 0x1C00, { 6, 5, 1 } },292{ 0x1400, { 6, 6, 1 } },293{ 0x1000, { 6, 7, 1 } },294{ 0x0C00, { 7, 0, 4 } },295{ 0x0800, { 7, 2, 2 } },296{ 0x0E00, { 7, 8, 1 } },297{ 0x0A00, { 7, 9, 1 } },298{ 0x0400, { 6, dct_Escape, 0 } },299{ 0x2600, { 8, 0, 5 } },300{ 0x2100, { 8, 0, 6 } },301{ 0x2500, { 8, 1, 3 } },302{ 0x2400, { 8, 3, 2 } },303{ 0x2700, { 8, 10, 1 } },304{ 0x2300, { 8, 11, 1 } },305{ 0x2200, { 8, 12, 1 } },306{ 0x2000, { 8, 13, 1 } },307{ 0x0280, { 10, 0, 7 } },308{ 0x0300, { 10, 1, 4 } },309{ 0x02C0, { 10, 2, 3 } },310{ 0x03C0, { 10, 4, 2 } },311{ 0x0240, { 10, 5, 2 } },312{ 0x0380, { 10, 14, 1 } },313{ 0x0340, { 10, 15, 1 } },314{ 0x0200, { 10, 16, 1 } },315{ 0x01D0, { 12, 0, 8 } },316{ 0x0180, { 12, 0, 9 } },317{ 0x0130, { 12, 0, 10 } },318{ 0x0100, { 12, 0, 11 } },319{ 0x01B0, { 12, 1, 5 } },320{ 0x0140, { 12, 2, 4 } },321{ 0x01C0, { 12, 3, 3 } },322{ 0x0120, { 12, 4, 3 } },323{ 0x01E0, { 12, 6, 2 } },324{ 0x0150, { 12, 7, 2 } },325{ 0x0110, { 12, 8, 2 } },326{ 0x01F0, { 12, 17, 1 } },327{ 0x01A0, { 12, 18, 1 } },328{ 0x0190, { 12, 19, 1 } },329{ 0x0170, { 12, 20, 1 } },330{ 0x0160, { 12, 21, 1 } },331{ 0x00D0, { 13, 0, 12 } },332{ 0x00C8, { 13, 0, 13 } },333{ 0x00C0, { 13, 0, 14 } },334{ 0x00B8, { 13, 0, 15 } },335{ 0x00B0, { 13, 1, 6 } },336{ 0x00A8, { 13, 1, 7 } },337{ 0x00A0, { 13, 2, 5 } },338{ 0x0098, { 13, 3, 4 } },339{ 0x0090, { 13, 5, 3 } },340{ 0x0088, { 13, 9, 2 } },341{ 0x0080, { 13, 10, 2 } },342{ 0x00F8, { 13, 22, 1 } },343{ 0x00F0, { 13, 23, 1 } },344{ 0x00E8, { 13, 24, 1 } },345{ 0x00E0, { 13, 25, 1 } },346{ 0x00D8, { 13, 26, 1 } },347{ 0x007C, { 14, 0, 16 } },348{ 0x0078, { 14, 0, 17 } },349{ 0x0074, { 14, 0, 18 } },350{ 0x0070, { 14, 0, 19 } },351{ 0x006C, { 14, 0, 20 } },352{ 0x0068, { 14, 0, 21 } },353{ 0x0064, { 14, 0, 22 } },354{ 0x0060, { 14, 0, 23 } },355{ 0x005C, { 14, 0, 24 } },356{ 0x0058, { 14, 0, 25 } },357{ 0x0054, { 14, 0, 26 } },358{ 0x0050, { 14, 0, 27 } },359{ 0x004C, { 14, 0, 28 } },360{ 0x0048, { 14, 0, 29 } },361{ 0x0044, { 14, 0, 30 } },362{ 0x0040, { 14, 0, 31 } },363{ 0x0030, { 15, 0, 32 } },364{ 0x002E, { 15, 0, 33 } },365{ 0x002C, { 15, 0, 34 } },366{ 0x002A, { 15, 0, 35 } },367{ 0x0028, { 15, 0, 36 } },368{ 0x0026, { 15, 0, 37 } },369{ 0x0024, { 15, 0, 38 } },370{ 0x0022, { 15, 0, 39 } },371{ 0x0020, { 15, 0, 40 } },372{ 0x003E, { 15, 1, 8 } },373{ 0x003C, { 15, 1, 9 } },374{ 0x003A, { 15, 1, 10 } },375{ 0x0038, { 15, 1, 11 } },376{ 0x0036, { 15, 1, 12 } },377{ 0x0034, { 15, 1, 13 } },378{ 0x0032, { 15, 1, 14 } },379{ 0x0013, { 16, 1, 15 } },380{ 0x0012, { 16, 1, 16 } },381{ 0x0011, { 16, 1, 17 } },382{ 0x0010, { 16, 1, 18 } },383{ 0x0014, { 16, 6, 3 } },384{ 0x001A, { 16, 11, 2 } },385{ 0x0019, { 16, 12, 2 } },386{ 0x0018, { 16, 13, 2 } },387{ 0x0017, { 16, 14, 2 } },388{ 0x0016, { 16, 15, 2 } },389{ 0x0015, { 16, 16, 2 } },390{ 0x001F, { 16, 27, 1 } },391{ 0x001E, { 16, 28, 1 } },392{ 0x001D, { 16, 29, 1 } },393{ 0x001C, { 16, 30, 1 } },394{ 0x001B, { 16, 31, 1 } }395};396397/* coding table as found in the spec annex B.5 table B-15 */398static const struct dct_coeff_compressed dct_coeff_tbl_one[] = {399{ 0x6000, { 4, dct_End_of_Block, 0 } },400{ 0x8000, { 2, 0, 1 } },401{ 0x4000, { 3, 1, 1 } },402{ 0xC000, { 3, 0, 2 } },403{ 0x2800, { 5, 2, 1 } },404{ 0x7000, { 4, 0, 3 } },405{ 0x3800, { 5, 3, 1 } },406{ 0x1800, { 6, 4, 1 } },407{ 0x3000, { 5, 1, 2 } },408{ 0x1C00, { 6, 5, 1 } },409{ 0x0C00, { 7, 6, 1 } },410{ 0x0800, { 7, 7, 1 } },411{ 0xE000, { 5, 0, 4 } },412{ 0x0E00, { 7, 2, 2 } },413{ 0x0A00, { 7, 8, 1 } },414{ 0xF000, { 7, 9, 1 } },415{ 0x0400, { 6, dct_Escape, 0 } },416{ 0xE800, { 5, 0, 5 } },417{ 0x1400, { 6, 0, 6 } },418{ 0xF200, { 7, 1, 3 } },419{ 0x2600, { 8, 3, 2 } },420{ 0xF400, { 7, 10, 1 } },421{ 0x2100, { 8, 11, 1 } },422{ 0x2500, { 8, 12, 1 } },423{ 0x2400, { 8, 13, 1 } },424{ 0x1000, { 6, 0, 7 } },425{ 0x2700, { 8, 1, 4 } },426{ 0xFC00, { 8, 2, 3 } },427{ 0xFD00, { 8, 4, 2 } },428{ 0x0200, { 9, 5, 2 } },429{ 0x0280, { 9, 14, 1 } },430{ 0x0380, { 9, 15, 1 } },431{ 0x0340, { 10, 16, 1 } },432{ 0xF600, { 7, 0, 8 } },433{ 0xF800, { 7, 0, 9 } },434{ 0x2300, { 8, 0, 10 } },435{ 0x2200, { 8, 0, 11 } },436{ 0x2000, { 8, 1, 5 } },437{ 0x0300, { 10, 2, 4 } },438{ 0x01C0, { 12, 3, 3 } },439{ 0x0120, { 12, 4, 3 } },440{ 0x01E0, { 12, 6, 2 } },441{ 0x0150, { 12, 7, 2 } },442{ 0x0110, { 12, 8, 2 } },443{ 0x01F0, { 12, 17, 1 } },444{ 0x01A0, { 12, 18, 1 } },445{ 0x0190, { 12, 19, 1 } },446{ 0x0170, { 12, 20, 1 } },447{ 0x0160, { 12, 21, 1 } },448{ 0xFA00, { 8, 0, 12 } },449{ 0xFB00, { 8, 0, 13 } },450{ 0xFE00, { 8, 0, 14 } },451{ 0xFF00, { 8, 0, 15 } },452{ 0x00B0, { 13, 1, 6 } },453{ 0x00A8, { 13, 1, 7 } },454{ 0x00A0, { 13, 2, 5 } },455{ 0x0098, { 13, 3, 4 } },456{ 0x0090, { 13, 5, 3 } },457{ 0x0088, { 13, 9, 2 } },458{ 0x0080, { 13, 10, 2 } },459{ 0x00F8, { 13, 22, 1 } },460{ 0x00F0, { 13, 23, 1 } },461{ 0x00E8, { 13, 24, 1 } },462{ 0x00E0, { 13, 25, 1 } },463{ 0x00D8, { 13, 26, 1 } },464{ 0x007C, { 14, 0, 16 } },465{ 0x0078, { 14, 0, 17 } },466{ 0x0074, { 14, 0, 18 } },467{ 0x0070, { 14, 0, 19 } },468{ 0x006C, { 14, 0, 20 } },469{ 0x0068, { 14, 0, 21 } },470{ 0x0064, { 14, 0, 22 } },471{ 0x0060, { 14, 0, 23 } },472{ 0x005C, { 14, 0, 24 } },473{ 0x0058, { 14, 0, 25 } },474{ 0x0054, { 14, 0, 26 } },475{ 0x0050, { 14, 0, 27 } },476{ 0x004C, { 14, 0, 28 } },477{ 0x0048, { 14, 0, 29 } },478{ 0x0044, { 14, 0, 30 } },479{ 0x0040, { 14, 0, 31 } },480{ 0x0030, { 15, 0, 32 } },481{ 0x002E, { 15, 0, 33 } },482{ 0x002C, { 15, 0, 34 } },483{ 0x002A, { 15, 0, 35 } },484{ 0x0028, { 15, 0, 36 } },485{ 0x0026, { 15, 0, 37 } },486{ 0x0024, { 15, 0, 38 } },487{ 0x0022, { 15, 0, 39 } },488{ 0x0020, { 15, 0, 40 } },489{ 0x003E, { 15, 1, 8 } },490{ 0x003C, { 15, 1, 9 } },491{ 0x003A, { 15, 1, 10 } },492{ 0x0038, { 15, 1, 11 } },493{ 0x0036, { 15, 1, 12 } },494{ 0x0034, { 15, 1, 13 } },495{ 0x0032, { 15, 1, 14 } },496{ 0x0013, { 16, 1, 15 } },497{ 0x0012, { 16, 1, 16 } },498{ 0x0011, { 16, 1, 17 } },499{ 0x0010, { 16, 1, 18 } },500{ 0x0014, { 16, 6, 3 } },501{ 0x001A, { 16, 11, 2 } },502{ 0x0019, { 16, 12, 2 } },503{ 0x0018, { 16, 13, 2 } },504{ 0x0017, { 16, 14, 2 } },505{ 0x0016, { 16, 15, 2 } },506{ 0x0015, { 16, 16, 2 } },507{ 0x001F, { 16, 27, 1 } },508{ 0x001E, { 16, 28, 1 } },509{ 0x001D, { 16, 29, 1 } },510{ 0x001C, { 16, 30, 1 } },511{ 0x001B, { 16, 31, 1 } }512};513514/* q_scale_type */515static const unsigned quant_scale[2][32] = {516{ 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30,51732, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62 },518{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 18, 20, 22, 24,51928, 32, 36, 40, 44, 48, 52, 56, 64, 72, 80, 88, 96, 104, 112 }520};521522static struct vl_vlc_entry tbl_B1[1 << 11];523static struct vl_vlc_entry tbl_B2[1 << 2];524static struct vl_vlc_entry tbl_B3[1 << 6];525static struct vl_vlc_entry tbl_B4[1 << 6];526static struct vl_vlc_entry tbl_B9[1 << 9];527static struct vl_vlc_entry tbl_B10[1 << 11];528static struct vl_vlc_entry tbl_B11[1 << 2];529static struct vl_vlc_entry tbl_B12[1 << 10];530static struct vl_vlc_entry tbl_B13[1 << 10];531static struct dct_coeff tbl_B14_DC[1 << 17];532static struct dct_coeff tbl_B14_AC[1 << 17];533static struct dct_coeff tbl_B15[1 << 17];534535static inline void536init_dct_coeff_table(struct dct_coeff *dst, const struct dct_coeff_compressed *src,537unsigned size, bool is_DC)538{539unsigned i;540541for (i=0;i<(1<<17);++i) {542dst[i].length = 0;543dst[i].level = 0;544dst[i].run = dct_End_of_Block;545}546547for(; size > 0; --size, ++src) {548struct dct_coeff coeff = src->coeff;549bool has_sign = true;550551switch (coeff.run) {552case dct_End_of_Block:553if (is_DC)554continue;555556has_sign = false;557break;558559case dct_Escape:560has_sign = false;561break;562563case dct_DC:564if (!is_DC)565continue;566567coeff.length += 1;568coeff.run = 1;569break;570571case dct_AC:572if (is_DC)573continue;574575coeff.length += 1;576coeff.run = 1;577break;578579default:580coeff.length += 1;581coeff.run += 1;582break;583}584585for(i = 0; i < (1u << (17 - coeff.length)); ++i)586dst[src->bitcode << 1 | i] = coeff;587588if (has_sign) {589coeff.level = -coeff.level;590for(; i < (1u << (18 - coeff.length)); ++i)591dst[src->bitcode << 1 | i] = coeff;592}593}594}595596static inline void597init_tables()598{599vl_vlc_init_table(tbl_B1, ARRAY_SIZE(tbl_B1), macroblock_address_increment, ARRAY_SIZE(macroblock_address_increment));600vl_vlc_init_table(tbl_B2, ARRAY_SIZE(tbl_B2), macroblock_type_i, ARRAY_SIZE(macroblock_type_i));601vl_vlc_init_table(tbl_B3, ARRAY_SIZE(tbl_B3), macroblock_type_p, ARRAY_SIZE(macroblock_type_p));602vl_vlc_init_table(tbl_B4, ARRAY_SIZE(tbl_B4), macroblock_type_b, ARRAY_SIZE(macroblock_type_b));603vl_vlc_init_table(tbl_B9, ARRAY_SIZE(tbl_B9), coded_block_pattern, ARRAY_SIZE(coded_block_pattern));604vl_vlc_init_table(tbl_B10, ARRAY_SIZE(tbl_B10), motion_code, ARRAY_SIZE(motion_code));605vl_vlc_init_table(tbl_B11, ARRAY_SIZE(tbl_B11), dmvector, ARRAY_SIZE(dmvector));606vl_vlc_init_table(tbl_B12, ARRAY_SIZE(tbl_B12), dct_dc_size_luminance, ARRAY_SIZE(dct_dc_size_luminance));607vl_vlc_init_table(tbl_B13, ARRAY_SIZE(tbl_B13), dct_dc_size_chrominance, ARRAY_SIZE(dct_dc_size_chrominance));608init_dct_coeff_table(tbl_B14_DC, dct_coeff_tbl_zero, ARRAY_SIZE(dct_coeff_tbl_zero), true);609init_dct_coeff_table(tbl_B14_AC, dct_coeff_tbl_zero, ARRAY_SIZE(dct_coeff_tbl_zero), false);610init_dct_coeff_table(tbl_B15, dct_coeff_tbl_one, ARRAY_SIZE(dct_coeff_tbl_one), false);611}612613static inline int614DIV2DOWN(int todiv)615{616return (todiv&~1)/2;617}618619static inline void620motion_vector(struct vl_mpg12_bs *bs, int r, int s, int dmv, short delta[2], short dmvector[2])621{622int t;623for (t = 0; t < 2; ++t) {624int motion_code;625int r_size = bs->desc->f_code[s][t];626627vl_vlc_fillbits(&bs->vlc);628motion_code = vl_vlc_get_vlclbf(&bs->vlc, tbl_B10, 11);629630assert(r_size >= 0);631if (r_size && motion_code) {632int residual = vl_vlc_get_uimsbf(&bs->vlc, r_size) + 1;633delta[t] = ((abs(motion_code) - 1) << r_size) + residual;634if (motion_code < 0)635delta[t] = -delta[t];636} else637delta[t] = motion_code;638if (dmv)639dmvector[t] = vl_vlc_get_vlclbf(&bs->vlc, tbl_B11, 2);640}641}642643static inline int644wrap(short f, int shift)645{646if (f < (-16 << shift))647return f + (32 << shift);648else if (f >= 16 << shift)649return f - (32 << shift);650else651return f;652}653654static inline void655motion_vector_frame(struct vl_mpg12_bs *bs, int s, struct pipe_mpeg12_macroblock *mb)656{657int dmv = mb->macroblock_modes.bits.frame_motion_type == PIPE_MPEG12_MO_TYPE_DUAL_PRIME;658short dmvector[2], delta[2];659660if (mb->macroblock_modes.bits.frame_motion_type == PIPE_MPEG12_MO_TYPE_FIELD) {661mb->motion_vertical_field_select |= vl_vlc_get_uimsbf(&bs->vlc, 1) << s;662motion_vector(bs, 0, s, dmv, delta, dmvector);663mb->PMV[0][s][0] = wrap(mb->PMV[0][s][0] + delta[0], bs->desc->f_code[s][0]);664mb->PMV[0][s][1] = wrap(DIV2DOWN(mb->PMV[0][s][1]) + delta[1], bs->desc->f_code[s][1]) * 2;665666mb->motion_vertical_field_select |= vl_vlc_get_uimsbf(&bs->vlc, 1) << (s + 2);667motion_vector(bs, 1, s, dmv, delta, dmvector);668mb->PMV[1][s][0] = wrap(mb->PMV[1][s][0] + delta[0], bs->desc->f_code[s][0]);669mb->PMV[1][s][1] = wrap(DIV2DOWN(mb->PMV[1][s][1]) + delta[1], bs->desc->f_code[s][1]) * 2;670671} else {672motion_vector(bs, 0, s, dmv, delta, dmvector);673mb->PMV[0][s][0] = wrap(mb->PMV[0][s][0] + delta[0], bs->desc->f_code[s][0]);674mb->PMV[0][s][1] = wrap(mb->PMV[0][s][1] + delta[1], bs->desc->f_code[s][1]);675}676}677678static inline void679motion_vector_field(struct vl_mpg12_bs *bs, int s, struct pipe_mpeg12_macroblock *mb)680{681int dmv = mb->macroblock_modes.bits.field_motion_type == PIPE_MPEG12_MO_TYPE_DUAL_PRIME;682short dmvector[2], delta[2];683684if (mb->macroblock_modes.bits.field_motion_type == PIPE_MPEG12_MO_TYPE_16x8) {685mb->motion_vertical_field_select |= vl_vlc_get_uimsbf(&bs->vlc, 1) << s;686motion_vector(bs, 0, s, dmv, delta, dmvector);687688mb->motion_vertical_field_select |= vl_vlc_get_uimsbf(&bs->vlc, 1) << (s + 2);689motion_vector(bs, 1, s, dmv, delta, dmvector);690} else {691if (!dmv)692mb->motion_vertical_field_select |= vl_vlc_get_uimsbf(&bs->vlc, 1) << s;693motion_vector(bs, 0, s, dmv, delta, dmvector);694}695}696697static inline void698reset_predictor(struct vl_mpg12_bs *bs) {699bs->pred_dc[0] = bs->pred_dc[1] = bs->pred_dc[2] = 0;700}701702static inline void703decode_dct(struct vl_mpg12_bs *bs, struct pipe_mpeg12_macroblock *mb, int scale)704{705static const unsigned blk2cc[] = { 0, 0, 0, 0, 1, 2 };706static const struct vl_vlc_entry *blk2dcsize[] = {707tbl_B12, tbl_B12, tbl_B12, tbl_B12, tbl_B13, tbl_B13708};709710bool intra = mb->macroblock_type & PIPE_MPEG12_MB_TYPE_INTRA;711const struct dct_coeff *table = intra ? bs->intra_dct_tbl : tbl_B14_AC;712const struct dct_coeff *entry;713int i, cbp, blk = 0;714short *dst = mb->blocks;715716vl_vlc_fillbits(&bs->vlc);717mb->coded_block_pattern = cbp = intra ? 0x3F : vl_vlc_get_vlclbf(&bs->vlc, tbl_B9, 9);718719goto entry;720721while(1) {722vl_vlc_eatbits(&bs->vlc, entry->length);723if (entry->run == dct_End_of_Block) {724725next_d:726dst += 64;727cbp <<= 1;728cbp &= 0x3F;729blk++;730731entry:732if (!cbp)733break;734735while(!(cbp & 0x20)) {736cbp <<= 1;737blk++;738}739740vl_vlc_fillbits(&bs->vlc);741742if (intra) {743unsigned cc = blk2cc[blk];744unsigned size = vl_vlc_get_vlclbf(&bs->vlc, blk2dcsize[blk], 10);745746if (size) {747int dct_diff = vl_vlc_get_uimsbf(&bs->vlc, size);748int half_range = 1 << (size - 1);749if (dct_diff < half_range)750dct_diff = (dct_diff + 1) - (2 * half_range);751bs->pred_dc[cc] += dct_diff;752}753754dst[0] = bs->pred_dc[cc];755i = 0;756757if (bs->desc->picture_coding_type == PIPE_MPEG12_PICTURE_CODING_TYPE_D)758goto next_d;759} else {760entry = tbl_B14_DC + vl_vlc_peekbits(&bs->vlc, 17);761i = -1;762continue;763}764765} else if (entry->run == dct_Escape &&766bs->decoder->profile == PIPE_VIDEO_PROFILE_MPEG1) {767i += vl_vlc_get_uimsbf(&bs->vlc, 6) + 1;768if (i > 64)769break;770771dst[i] = vl_vlc_get_simsbf(&bs->vlc, 8);772if (dst[i] == -128)773dst[i] = vl_vlc_get_uimsbf(&bs->vlc, 8) - 256;774else if (dst[i] == 0)775dst[i] = vl_vlc_get_uimsbf(&bs->vlc, 8);776777dst[i] *= scale;778} else if (entry->run == dct_Escape) {779i += vl_vlc_get_uimsbf(&bs->vlc, 6) + 1;780if (i > 64)781break;782783dst[i] = vl_vlc_get_simsbf(&bs->vlc, 12) * scale;784785} else {786i += entry->run;787if (i > 64)788break;789790dst[i] = entry->level * scale;791}792793vl_vlc_fillbits(&bs->vlc);794entry = table + vl_vlc_peekbits(&bs->vlc, 17);795}796797if (bs->desc->picture_coding_type == PIPE_MPEG12_PICTURE_CODING_TYPE_D)798vl_vlc_eatbits(&bs->vlc, 1);799}800801static inline void802decode_slice(struct vl_mpg12_bs *bs, struct pipe_video_buffer *target)803{804struct pipe_mpeg12_macroblock mb;805short dct_blocks[64*6];806unsigned dct_scale;807signed x = -1;808809memset(&mb, 0, sizeof(mb));810mb.base.codec = PIPE_VIDEO_FORMAT_MPEG12;811mb.y = vl_vlc_get_uimsbf(&bs->vlc, 8) - 1;812mb.blocks = dct_blocks;813814reset_predictor(bs);815vl_vlc_fillbits(&bs->vlc);816dct_scale = quant_scale[bs->desc->q_scale_type][vl_vlc_get_uimsbf(&bs->vlc, 5)];817818if (vl_vlc_get_uimsbf(&bs->vlc, 1))819while (vl_vlc_get_uimsbf(&bs->vlc, 9) & 1)820vl_vlc_fillbits(&bs->vlc);821822vl_vlc_fillbits(&bs->vlc);823assert(vl_vlc_peekbits(&bs->vlc, 23));824do {825int inc = 0;826827while (1) {828/* MPEG-1 macroblock stuffing, can appear an arbitrary number of times. */829while (vl_vlc_peekbits(&bs->vlc, 11) == 15) {830vl_vlc_eatbits(&bs->vlc, 11);831vl_vlc_fillbits(&bs->vlc);832}833834if (vl_vlc_peekbits(&bs->vlc, 11) == 8) {835vl_vlc_eatbits(&bs->vlc, 11);836vl_vlc_fillbits(&bs->vlc);837inc += 33;838} else {839inc += vl_vlc_get_vlclbf(&bs->vlc, tbl_B1, 11);840break;841}842}843844if (x != -1) {845if (!inc)846return;847mb.num_skipped_macroblocks = inc - 1;848bs->decoder->decode_macroblock(bs->decoder, target, &bs->desc->base, &mb.base, 1);849}850mb.x = x += inc;851if (bs->decoder->profile == PIPE_VIDEO_PROFILE_MPEG1) {852int width = align(bs->decoder->width, 16) / 16;853mb.y += mb.x / width;854mb.x = x %= width;855}856857switch (bs->desc->picture_coding_type) {858case PIPE_MPEG12_PICTURE_CODING_TYPE_I:859mb.macroblock_type = vl_vlc_get_vlclbf(&bs->vlc, tbl_B2, 2);860break;861862case PIPE_MPEG12_PICTURE_CODING_TYPE_P:863mb.macroblock_type = vl_vlc_get_vlclbf(&bs->vlc, tbl_B3, 6);864break;865866case PIPE_MPEG12_PICTURE_CODING_TYPE_B:867mb.macroblock_type = vl_vlc_get_vlclbf(&bs->vlc, tbl_B4, 6);868break;869870case PIPE_MPEG12_PICTURE_CODING_TYPE_D:871vl_vlc_eatbits(&bs->vlc, 1);872mb.macroblock_type = PIPE_MPEG12_MB_TYPE_INTRA;873break;874}875876mb.macroblock_modes.value = 0;877if (mb.macroblock_type & (PIPE_MPEG12_MB_TYPE_MOTION_FORWARD | PIPE_MPEG12_MB_TYPE_MOTION_BACKWARD)) {878if (bs->desc->picture_structure == PIPE_MPEG12_PICTURE_STRUCTURE_FRAME) {879if (bs->desc->frame_pred_frame_dct == 0)880mb.macroblock_modes.bits.frame_motion_type = vl_vlc_get_uimsbf(&bs->vlc, 2);881else882mb.macroblock_modes.bits.frame_motion_type = 2;883} else884mb.macroblock_modes.bits.field_motion_type = vl_vlc_get_uimsbf(&bs->vlc, 2);885886} else if ((mb.macroblock_type & PIPE_MPEG12_MB_TYPE_INTRA) && bs->desc->concealment_motion_vectors) {887if (bs->desc->picture_structure == PIPE_MPEG12_PICTURE_STRUCTURE_FRAME)888mb.macroblock_modes.bits.frame_motion_type = 2;889else890mb.macroblock_modes.bits.field_motion_type = 1;891}892893if (bs->desc->picture_structure == PIPE_MPEG12_PICTURE_STRUCTURE_FRAME &&894bs->desc->frame_pred_frame_dct == 0 &&895mb.macroblock_type & (PIPE_MPEG12_MB_TYPE_INTRA | PIPE_MPEG12_MB_TYPE_PATTERN))896mb.macroblock_modes.bits.dct_type = vl_vlc_get_uimsbf(&bs->vlc, 1);897898if (mb.macroblock_type & PIPE_MPEG12_MB_TYPE_QUANT)899dct_scale = quant_scale[bs->desc->q_scale_type][vl_vlc_get_uimsbf(&bs->vlc, 5)];900901if (inc > 1 && bs->desc->picture_coding_type == PIPE_MPEG12_PICTURE_CODING_TYPE_P)902memset(mb.PMV, 0, sizeof(mb.PMV));903904mb.motion_vertical_field_select = 0;905if ((mb.macroblock_type & PIPE_MPEG12_MB_TYPE_MOTION_FORWARD) ||906(mb.macroblock_type & PIPE_MPEG12_MB_TYPE_INTRA && bs->desc->concealment_motion_vectors)) {907if (bs->desc->picture_structure == PIPE_MPEG12_PICTURE_STRUCTURE_FRAME)908motion_vector_frame(bs, 0, &mb);909else910motion_vector_field(bs, 0, &mb);911}912913if (mb.macroblock_type & PIPE_MPEG12_MB_TYPE_MOTION_BACKWARD) {914if (bs->desc->picture_structure == PIPE_MPEG12_PICTURE_STRUCTURE_FRAME)915motion_vector_frame(bs, 1, &mb);916else917motion_vector_field(bs, 1, &mb);918}919920if (mb.macroblock_type & PIPE_MPEG12_MB_TYPE_INTRA && bs->desc->concealment_motion_vectors) {921unsigned extra = vl_vlc_get_uimsbf(&bs->vlc, 1);922mb.PMV[1][0][0] = mb.PMV[0][0][0];923mb.PMV[1][0][1] = mb.PMV[0][0][1];924assert(extra);925(void) extra;926} else if (mb.macroblock_type & PIPE_MPEG12_MB_TYPE_INTRA ||927!(mb.macroblock_type & (PIPE_MPEG12_MB_TYPE_MOTION_FORWARD |928PIPE_MPEG12_MB_TYPE_MOTION_BACKWARD))) {929memset(mb.PMV, 0, sizeof(mb.PMV));930}931932if ((mb.macroblock_type & PIPE_MPEG12_MB_TYPE_MOTION_FORWARD &&933mb.macroblock_modes.bits.frame_motion_type == 2) ||934(mb.macroblock_modes.bits.frame_motion_type == 3)) {935mb.PMV[1][0][0] = mb.PMV[0][0][0];936mb.PMV[1][0][1] = mb.PMV[0][0][1];937}938939if (mb.macroblock_type & PIPE_MPEG12_MB_TYPE_MOTION_BACKWARD &&940mb.macroblock_modes.bits.frame_motion_type == 2) {941mb.PMV[1][1][0] = mb.PMV[0][1][0];942mb.PMV[1][1][1] = mb.PMV[0][1][1];943}944945if (inc > 1 || !(mb.macroblock_type & PIPE_MPEG12_MB_TYPE_INTRA))946reset_predictor(bs);947948if (mb.macroblock_type & (PIPE_MPEG12_MB_TYPE_INTRA | PIPE_MPEG12_MB_TYPE_PATTERN)) {949memset(dct_blocks, 0, sizeof(dct_blocks));950decode_dct(bs, &mb, dct_scale);951} else952mb.coded_block_pattern = 0;953954vl_vlc_fillbits(&bs->vlc);955} while (vl_vlc_bits_left(&bs->vlc) && vl_vlc_peekbits(&bs->vlc, 23));956957mb.num_skipped_macroblocks = 0;958bs->decoder->decode_macroblock(bs->decoder, target, &bs->desc->base, &mb.base, 1);959}960961void962vl_mpg12_bs_init(struct vl_mpg12_bs *bs, struct pipe_video_codec *decoder)963{964static bool tables_initialized = false;965966assert(bs);967968memset(bs, 0, sizeof(struct vl_mpg12_bs));969970bs->decoder = decoder;971972if (!tables_initialized) {973init_tables();974tables_initialized = true;975}976}977978void979vl_mpg12_bs_decode(struct vl_mpg12_bs *bs,980struct pipe_video_buffer *target,981struct pipe_mpeg12_picture_desc *picture,982unsigned num_buffers,983const void * const *buffers,984const unsigned *sizes)985{986assert(bs);987988bs->desc = picture;989bs->intra_dct_tbl = picture->intra_vlc_format ? tbl_B15 : tbl_B14_AC;990991vl_vlc_init(&bs->vlc, num_buffers, buffers, sizes);992while (vl_vlc_search_byte(&bs->vlc, ~0, 0x00) && vl_vlc_bits_left(&bs->vlc) > 32) {993uint32_t code = vl_vlc_peekbits(&bs->vlc, 32);994995if (code >= 0x101 && code <= 0x1AF) {996vl_vlc_eatbits(&bs->vlc, 24);997decode_slice(bs, target);998999/* align to a byte again */1000vl_vlc_eatbits(&bs->vlc, vl_vlc_valid_bits(&bs->vlc) & 7);10011002} else {1003vl_vlc_eatbits(&bs->vlc, 8);1004}10051006vl_vlc_fillbits(&bs->vlc);1007}1008}100910101011