1cabdff1aSopenharmony_ci/* 2cabdff1aSopenharmony_ci * Copyright (c) 2020 Paul B Mahol 3cabdff1aSopenharmony_ci * 4cabdff1aSopenharmony_ci * This file is part of FFmpeg. 5cabdff1aSopenharmony_ci * 6cabdff1aSopenharmony_ci * FFmpeg is free software; you can redistribute it and/or 7cabdff1aSopenharmony_ci * modify it under the terms of the GNU Lesser General Public 8cabdff1aSopenharmony_ci * License as published by the Free Software Foundation; either 9cabdff1aSopenharmony_ci * version 2.1 of the License, or (at your option) any later version. 10cabdff1aSopenharmony_ci * 11cabdff1aSopenharmony_ci * FFmpeg is distributed in the hope that it will be useful, 12cabdff1aSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of 13cabdff1aSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14cabdff1aSopenharmony_ci * Lesser General Public License for more details. 15cabdff1aSopenharmony_ci * 16cabdff1aSopenharmony_ci * You should have received a copy of the GNU Lesser General Public 17cabdff1aSopenharmony_ci * License along with FFmpeg; if not, write to the Free Software 18cabdff1aSopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19cabdff1aSopenharmony_ci */ 20cabdff1aSopenharmony_ci 21cabdff1aSopenharmony_ci/** 22cabdff1aSopenharmony_ci * @file 23cabdff1aSopenharmony_ci * Cineform HD video encoder 24cabdff1aSopenharmony_ci */ 25cabdff1aSopenharmony_ci 26cabdff1aSopenharmony_ci#include <stdlib.h> 27cabdff1aSopenharmony_ci#include <string.h> 28cabdff1aSopenharmony_ci 29cabdff1aSopenharmony_ci#include "libavutil/imgutils.h" 30cabdff1aSopenharmony_ci#include "libavutil/opt.h" 31cabdff1aSopenharmony_ci 32cabdff1aSopenharmony_ci#include "avcodec.h" 33cabdff1aSopenharmony_ci#include "bytestream.h" 34cabdff1aSopenharmony_ci#include "cfhd.h" 35cabdff1aSopenharmony_ci#include "cfhdencdsp.h" 36cabdff1aSopenharmony_ci#include "codec_internal.h" 37cabdff1aSopenharmony_ci#include "encode.h" 38cabdff1aSopenharmony_ci#include "put_bits.h" 39cabdff1aSopenharmony_ci#include "thread.h" 40cabdff1aSopenharmony_ci 41cabdff1aSopenharmony_ci/* Derived from existing tables from decoder */ 42cabdff1aSopenharmony_cistatic const unsigned codebook[256][2] = { 43cabdff1aSopenharmony_ci { 1, 0x00000000 }, { 2, 0x00000002 }, { 3, 0x00000007 }, { 5, 0x00000019 }, { 6, 0x00000030 }, 44cabdff1aSopenharmony_ci { 6, 0x00000036 }, { 7, 0x00000063 }, { 7, 0x0000006B }, { 7, 0x0000006F }, { 8, 0x000000D4 }, 45cabdff1aSopenharmony_ci { 8, 0x000000DC }, { 9, 0x00000189 }, { 9, 0x000001A0 }, { 9, 0x000001AB }, {10, 0x00000310 }, 46cabdff1aSopenharmony_ci {10, 0x00000316 }, {10, 0x00000354 }, {10, 0x00000375 }, {10, 0x00000377 }, {11, 0x00000623 }, 47cabdff1aSopenharmony_ci {11, 0x00000684 }, {11, 0x000006AB }, {11, 0x000006EC }, {12, 0x00000C44 }, {12, 0x00000C5C }, 48cabdff1aSopenharmony_ci {12, 0x00000C5E }, {12, 0x00000D55 }, {12, 0x00000DD1 }, {12, 0x00000DD3 }, {12, 0x00000DDB }, 49cabdff1aSopenharmony_ci {13, 0x0000188B }, {13, 0x000018BB }, {13, 0x00001AA8 }, {13, 0x00001BA0 }, {13, 0x00001BA4 }, 50cabdff1aSopenharmony_ci {13, 0x00001BB5 }, {14, 0x00003115 }, {14, 0x00003175 }, {14, 0x0000317D }, {14, 0x00003553 }, 51cabdff1aSopenharmony_ci {14, 0x00003768 }, {15, 0x00006228 }, {15, 0x000062E8 }, {15, 0x000062F8 }, {15, 0x00006AA4 }, 52cabdff1aSopenharmony_ci {15, 0x00006E85 }, {15, 0x00006E87 }, {15, 0x00006ED3 }, {16, 0x0000C453 }, {16, 0x0000C5D3 }, 53cabdff1aSopenharmony_ci {16, 0x0000C5F3 }, {16, 0x0000DD08 }, {16, 0x0000DD0C }, {16, 0x0000DDA4 }, {17, 0x000188A4 }, 54cabdff1aSopenharmony_ci {17, 0x00018BA5 }, {17, 0x00018BE5 }, {17, 0x0001AA95 }, {17, 0x0001AA97 }, {17, 0x0001BA13 }, 55cabdff1aSopenharmony_ci {17, 0x0001BB4A }, {17, 0x0001BB4B }, {18, 0x00031748 }, {18, 0x000317C8 }, {18, 0x00035528 }, 56cabdff1aSopenharmony_ci {18, 0x0003552C }, {18, 0x00037424 }, {18, 0x00037434 }, {18, 0x00037436 }, {19, 0x00062294 }, 57cabdff1aSopenharmony_ci {19, 0x00062E92 }, {19, 0x00062F92 }, {19, 0x0006AA52 }, {19, 0x0006AA5A }, {19, 0x0006E84A }, 58cabdff1aSopenharmony_ci {19, 0x0006E86A }, {19, 0x0006E86E }, {20, 0x000C452A }, {20, 0x000C5D27 }, {20, 0x000C5F26 }, 59cabdff1aSopenharmony_ci {20, 0x000D54A6 }, {20, 0x000D54B6 }, {20, 0x000DD096 }, {20, 0x000DD0D6 }, {20, 0x000DD0DE }, 60cabdff1aSopenharmony_ci {21, 0x00188A56 }, {21, 0x0018BA4D }, {21, 0x0018BE4E }, {21, 0x0018BE4F }, {21, 0x001AA96E }, 61cabdff1aSopenharmony_ci {21, 0x001BA12E }, {21, 0x001BA12F }, {21, 0x001BA1AF }, {21, 0x001BA1BF }, {22, 0x00317498 }, 62cabdff1aSopenharmony_ci {22, 0x0035529C }, {22, 0x0035529D }, {22, 0x003552DE }, {22, 0x003552DF }, {22, 0x0037435D }, 63cabdff1aSopenharmony_ci {22, 0x0037437D }, {23, 0x0062295D }, {23, 0x0062E933 }, {23, 0x006AA53D }, {23, 0x006AA53E }, 64cabdff1aSopenharmony_ci {23, 0x006AA53F }, {23, 0x006E86B9 }, {23, 0x006E86F8 }, {24, 0x00C452B8 }, {24, 0x00C5D265 }, 65cabdff1aSopenharmony_ci {24, 0x00D54A78 }, {24, 0x00D54A79 }, {24, 0x00DD0D70 }, {24, 0x00DD0D71 }, {24, 0x00DD0DF2 }, 66cabdff1aSopenharmony_ci {24, 0x00DD0DF3 }, {26, 0x03114BA2 }, {25, 0x0188A5B1 }, {25, 0x0188A58B }, {25, 0x0188A595 }, 67cabdff1aSopenharmony_ci {25, 0x0188A5D6 }, {25, 0x0188A5D7 }, {25, 0x0188A5A8 }, {25, 0x0188A5AE }, {25, 0x0188A5AF }, 68cabdff1aSopenharmony_ci {25, 0x0188A5C4 }, {25, 0x0188A5C5 }, {25, 0x0188A587 }, {25, 0x0188A584 }, {25, 0x0188A585 }, 69cabdff1aSopenharmony_ci {25, 0x0188A5C6 }, {25, 0x0188A5C7 }, {25, 0x0188A5CC }, {25, 0x0188A5CD }, {25, 0x0188A581 }, 70cabdff1aSopenharmony_ci {25, 0x0188A582 }, {25, 0x0188A583 }, {25, 0x0188A5CE }, {25, 0x0188A5CF }, {25, 0x0188A5C2 }, 71cabdff1aSopenharmony_ci {25, 0x0188A5C3 }, {25, 0x0188A5C1 }, {25, 0x0188A5B4 }, {25, 0x0188A5B5 }, {25, 0x0188A5E6 }, 72cabdff1aSopenharmony_ci {25, 0x0188A5E7 }, {25, 0x0188A5E4 }, {25, 0x0188A5E5 }, {25, 0x0188A5AB }, {25, 0x0188A5E0 }, 73cabdff1aSopenharmony_ci {25, 0x0188A5E1 }, {25, 0x0188A5E2 }, {25, 0x0188A5E3 }, {25, 0x0188A5B6 }, {25, 0x0188A5B7 }, 74cabdff1aSopenharmony_ci {25, 0x0188A5FD }, {25, 0x0188A57E }, {25, 0x0188A57F }, {25, 0x0188A5EC }, {25, 0x0188A5ED }, 75cabdff1aSopenharmony_ci {25, 0x0188A5FE }, {25, 0x0188A5FF }, {25, 0x0188A57D }, {25, 0x0188A59C }, {25, 0x0188A59D }, 76cabdff1aSopenharmony_ci {25, 0x0188A5E8 }, {25, 0x0188A5E9 }, {25, 0x0188A5EA }, {25, 0x0188A5EB }, {25, 0x0188A5EF }, 77cabdff1aSopenharmony_ci {25, 0x0188A57A }, {25, 0x0188A57B }, {25, 0x0188A578 }, {25, 0x0188A579 }, {25, 0x0188A5BA }, 78cabdff1aSopenharmony_ci {25, 0x0188A5BB }, {25, 0x0188A5B8 }, {25, 0x0188A5B9 }, {25, 0x0188A588 }, {25, 0x0188A589 }, 79cabdff1aSopenharmony_ci {25, 0x018BA4C8 }, {25, 0x018BA4C9 }, {25, 0x0188A5FA }, {25, 0x0188A5FB }, {25, 0x0188A5BC }, 80cabdff1aSopenharmony_ci {25, 0x0188A5BD }, {25, 0x0188A598 }, {25, 0x0188A599 }, {25, 0x0188A5F4 }, {25, 0x0188A5F5 }, 81cabdff1aSopenharmony_ci {25, 0x0188A59B }, {25, 0x0188A5DE }, {25, 0x0188A5DF }, {25, 0x0188A596 }, {25, 0x0188A597 }, 82cabdff1aSopenharmony_ci {25, 0x0188A5F8 }, {25, 0x0188A5F9 }, {25, 0x0188A5F1 }, {25, 0x0188A58E }, {25, 0x0188A58F }, 83cabdff1aSopenharmony_ci {25, 0x0188A5DC }, {25, 0x0188A5DD }, {25, 0x0188A5F2 }, {25, 0x0188A5F3 }, {25, 0x0188A58C }, 84cabdff1aSopenharmony_ci {25, 0x0188A58D }, {25, 0x0188A5A4 }, {25, 0x0188A5F0 }, {25, 0x0188A5A5 }, {25, 0x0188A5A6 }, 85cabdff1aSopenharmony_ci {25, 0x0188A5A7 }, {25, 0x0188A59A }, {25, 0x0188A5A2 }, {25, 0x0188A5A3 }, {25, 0x0188A58A }, 86cabdff1aSopenharmony_ci {25, 0x0188A5B0 }, {25, 0x0188A5A0 }, {25, 0x0188A5A1 }, {25, 0x0188A5DA }, {25, 0x0188A5DB }, 87cabdff1aSopenharmony_ci {25, 0x0188A59E }, {25, 0x0188A59F }, {25, 0x0188A5D8 }, {25, 0x0188A5EE }, {25, 0x0188A5D9 }, 88cabdff1aSopenharmony_ci {25, 0x0188A5F6 }, {25, 0x0188A5F7 }, {25, 0x0188A57C }, {25, 0x0188A5C8 }, {25, 0x0188A5C9 }, 89cabdff1aSopenharmony_ci {25, 0x0188A594 }, {25, 0x0188A5FC }, {25, 0x0188A5CA }, {25, 0x0188A5CB }, {25, 0x0188A5B2 }, 90cabdff1aSopenharmony_ci {25, 0x0188A5AA }, {25, 0x0188A5B3 }, {25, 0x0188A572 }, {25, 0x0188A573 }, {25, 0x0188A5C0 }, 91cabdff1aSopenharmony_ci {25, 0x0188A5BE }, {25, 0x0188A5BF }, {25, 0x0188A592 }, {25, 0x0188A580 }, {25, 0x0188A593 }, 92cabdff1aSopenharmony_ci {25, 0x0188A590 }, {25, 0x0188A591 }, {25, 0x0188A586 }, {25, 0x0188A5A9 }, {25, 0x0188A5D2 }, 93cabdff1aSopenharmony_ci {25, 0x0188A5D3 }, {25, 0x0188A5D4 }, {25, 0x0188A5D5 }, {25, 0x0188A5AC }, {25, 0x0188A5AD }, 94cabdff1aSopenharmony_ci {25, 0x0188A5D0 }, 95cabdff1aSopenharmony_ci}; 96cabdff1aSopenharmony_ci 97cabdff1aSopenharmony_ci/* Derived by extracting runcodes from existing tables from decoder */ 98cabdff1aSopenharmony_cistatic const uint16_t runbook[18][3] = { 99cabdff1aSopenharmony_ci {1, 0x0000, 1}, {2, 0x0000, 2}, {3, 0x0000, 3}, {4, 0x0000, 4}, 100cabdff1aSopenharmony_ci {5, 0x0000, 5}, {6, 0x0000, 6}, {7, 0x0000, 7}, {8, 0x0000, 8}, 101cabdff1aSopenharmony_ci {9, 0x0000, 9}, {10, 0x0000, 10}, {11, 0x0000, 11}, 102cabdff1aSopenharmony_ci {7, 0x0069, 12}, {8, 0x00D1, 20}, {9, 0x018A, 32}, 103cabdff1aSopenharmony_ci {10, 0x0343, 60}, {11, 0x0685, 100}, {13, 0x18BF, 180}, {13, 0x1BA5, 320}, 104cabdff1aSopenharmony_ci}; 105cabdff1aSopenharmony_ci 106cabdff1aSopenharmony_ci/* 107cabdff1aSopenharmony_ci * Derived by inspecting various quality encodes 108cabdff1aSopenharmony_ci * and adding some more from scratch. 109cabdff1aSopenharmony_ci */ 110cabdff1aSopenharmony_cistatic const uint16_t quantization_per_subband[2][3][13][9] = { 111cabdff1aSopenharmony_ci {{ 112cabdff1aSopenharmony_ci { 16, 16, 8, 4, 4, 2, 6, 6, 9, }, // film3+ 113cabdff1aSopenharmony_ci { 16, 16, 8, 4, 4, 2, 6, 6, 9, }, // film3 114cabdff1aSopenharmony_ci { 16, 16, 8, 4, 4, 2, 7, 7, 10, }, // film2+ 115cabdff1aSopenharmony_ci { 16, 16, 8, 4, 4, 2, 8, 8, 12, }, // film2 116cabdff1aSopenharmony_ci { 16, 16, 8, 4, 4, 2, 16, 16, 26, }, // film1++ 117cabdff1aSopenharmony_ci { 24, 24, 12, 6, 6, 3, 24, 24, 36, }, // film1+ 118cabdff1aSopenharmony_ci { 24, 24, 12, 6, 6, 3, 24, 24, 36, }, // film1 119cabdff1aSopenharmony_ci { 32, 32, 24, 8, 8, 6, 32, 32, 48, }, // high+ 120cabdff1aSopenharmony_ci { 32, 32, 24, 8, 8, 6, 32, 32, 48, }, // high 121cabdff1aSopenharmony_ci { 48, 48, 32, 12, 12, 8, 64, 64, 96, }, // medium+ 122cabdff1aSopenharmony_ci { 48, 48, 32, 12, 12, 8, 64, 64, 96, }, // medium 123cabdff1aSopenharmony_ci { 64, 64, 48, 16, 16, 12, 96, 96, 144, }, // low+ 124cabdff1aSopenharmony_ci { 64, 64, 48, 16, 16, 12, 128, 128, 192, }, // low 125cabdff1aSopenharmony_ci }, 126cabdff1aSopenharmony_ci { 127cabdff1aSopenharmony_ci { 16, 16, 8, 4, 4, 2, 6, 6, 9, }, // film3+ 128cabdff1aSopenharmony_ci { 16, 16, 8, 4, 4, 2, 6, 6, 12, }, // film3 129cabdff1aSopenharmony_ci { 16, 16, 8, 4, 4, 2, 7, 7, 14, }, // film2+ 130cabdff1aSopenharmony_ci { 16, 16, 8, 4, 4, 2, 8, 8, 16, }, // film2 131cabdff1aSopenharmony_ci { 16, 16, 8, 4, 4, 2, 16, 16, 26, }, // film1++ 132cabdff1aSopenharmony_ci { 24, 24, 12, 6, 6, 3, 24, 24, 36, }, // film1+ 133cabdff1aSopenharmony_ci { 24, 24, 12, 6, 6, 3, 24, 24, 48, }, // film1 134cabdff1aSopenharmony_ci { 32, 32, 24, 8, 8, 6, 32, 32, 48, }, // high+ 135cabdff1aSopenharmony_ci { 48, 48, 32, 12, 12, 8, 32, 32, 64, }, // high 136cabdff1aSopenharmony_ci { 48, 48, 32, 12, 12, 8, 64, 64, 96, }, // medium+ 137cabdff1aSopenharmony_ci { 48, 48, 32, 12, 12, 8, 64, 64, 128, }, // medium 138cabdff1aSopenharmony_ci { 64, 64, 48, 16, 16, 12, 96, 96, 160, }, // low+ 139cabdff1aSopenharmony_ci { 64, 64, 48, 16, 16, 12, 128, 128, 192, }, // low 140cabdff1aSopenharmony_ci }, 141cabdff1aSopenharmony_ci { 142cabdff1aSopenharmony_ci { 16, 16, 8, 4, 4, 2, 6, 6, 9, }, // film3+ 143cabdff1aSopenharmony_ci { 16, 16, 8, 4, 4, 2, 6, 6, 12, }, // film3 144cabdff1aSopenharmony_ci { 16, 16, 8, 4, 4, 2, 7, 7, 14, }, // film2+ 145cabdff1aSopenharmony_ci { 16, 16, 8, 4, 4, 2, 8, 8, 16, }, // film2 146cabdff1aSopenharmony_ci { 16, 16, 8, 4, 4, 2, 16, 16, 26, }, // film1++ 147cabdff1aSopenharmony_ci { 24, 24, 12, 6, 6, 3, 24, 24, 36, }, // film1+ 148cabdff1aSopenharmony_ci { 24, 24, 12, 6, 6, 3, 24, 24, 48, }, // film1 149cabdff1aSopenharmony_ci { 32, 32, 24, 8, 8, 6, 32, 32, 48, }, // high+ 150cabdff1aSopenharmony_ci { 48, 48, 32, 12, 12, 8, 32, 32, 64, }, // high 151cabdff1aSopenharmony_ci { 48, 48, 32, 12, 12, 8, 64, 64, 96, }, // medium+ 152cabdff1aSopenharmony_ci { 48, 48, 32, 12, 12, 8, 64, 64, 128, }, // medium 153cabdff1aSopenharmony_ci { 64, 64, 48, 16, 16, 12, 96, 96, 160, }, // low+ 154cabdff1aSopenharmony_ci { 64, 64, 48, 16, 16, 12, 128, 128, 192, }, // low 155cabdff1aSopenharmony_ci }}, 156cabdff1aSopenharmony_ci {{ 157cabdff1aSopenharmony_ci { 16, 16, 8, 16, 16, 8, 24, 24, 36, }, // film3+ 158cabdff1aSopenharmony_ci { 16, 16, 8, 16, 16, 8, 24, 24, 36, }, // film3 159cabdff1aSopenharmony_ci { 16, 16, 8, 16, 16, 8, 32, 32, 48, }, // film2+ 160cabdff1aSopenharmony_ci { 16, 16, 8, 16, 16, 8, 32, 32, 48, }, // film2 161cabdff1aSopenharmony_ci { 16, 16, 8, 20, 20, 10, 80, 80, 128, }, // film1++ 162cabdff1aSopenharmony_ci { 24, 24, 12, 24, 24, 12, 96, 96, 144, }, // film1+ 163cabdff1aSopenharmony_ci { 24, 24, 12, 24, 24, 12, 96, 96, 144, }, // film1 164cabdff1aSopenharmony_ci { 32, 32, 24, 32, 32, 24, 128, 128, 192, }, // high+ 165cabdff1aSopenharmony_ci { 32, 32, 24, 32, 32, 24, 128, 128, 192, }, // high 166cabdff1aSopenharmony_ci { 48, 48, 32, 48, 48, 32, 256, 256, 384, }, // medium+ 167cabdff1aSopenharmony_ci { 48, 48, 32, 48, 48, 32, 256, 256, 384, }, // medium 168cabdff1aSopenharmony_ci { 56, 56, 40, 56, 56, 40, 512, 512, 768, }, // low+ 169cabdff1aSopenharmony_ci { 64, 64, 48, 64, 64, 48, 512, 512, 768, }, // low 170cabdff1aSopenharmony_ci }, 171cabdff1aSopenharmony_ci { 172cabdff1aSopenharmony_ci { 16, 16, 8, 16, 16, 8, 24, 24, 36, }, // film3+ 173cabdff1aSopenharmony_ci { 16, 16, 8, 16, 16, 8, 48, 48, 72, }, // film3 174cabdff1aSopenharmony_ci { 16, 16, 8, 16, 16, 8, 48, 48, 72, }, // film2+ 175cabdff1aSopenharmony_ci { 16, 16, 8, 16, 16, 8, 64, 64, 96, }, // film2 176cabdff1aSopenharmony_ci { 16, 16, 8, 20, 20, 10, 80, 80, 128, }, // film1++ 177cabdff1aSopenharmony_ci { 24, 24, 12, 24, 24, 12, 96, 96, 144, }, // film1+ 178cabdff1aSopenharmony_ci { 24, 24, 12, 24, 24, 12, 192, 192, 288, }, // film1 179cabdff1aSopenharmony_ci { 32, 32, 24, 32, 32, 24, 128, 128, 192, }, // high+ 180cabdff1aSopenharmony_ci { 32, 32, 24, 32, 32, 24, 256, 256, 384, }, // high 181cabdff1aSopenharmony_ci { 48, 48, 32, 48, 48, 32, 256, 256, 384, }, // medium+ 182cabdff1aSopenharmony_ci { 48, 48, 32, 48, 48, 32, 512, 512, 768, }, // medium 183cabdff1aSopenharmony_ci { 56, 56, 40, 56, 56, 40, 512, 512, 768, }, // low+ 184cabdff1aSopenharmony_ci { 64, 64, 48, 64, 64, 48,1024,1024,1536, }, // low 185cabdff1aSopenharmony_ci }, 186cabdff1aSopenharmony_ci { 187cabdff1aSopenharmony_ci { 16, 16, 8, 16, 16, 8, 24, 24, 36, }, // film3+ 188cabdff1aSopenharmony_ci { 16, 16, 8, 16, 16, 8, 48, 48, 72, }, // film3 189cabdff1aSopenharmony_ci { 16, 16, 8, 16, 16, 8, 48, 48, 72, }, // film2+ 190cabdff1aSopenharmony_ci { 16, 16, 8, 16, 16, 8, 64, 64, 96, }, // film2 191cabdff1aSopenharmony_ci { 16, 16, 10, 20, 20, 10, 80, 80, 128, }, // film1++ 192cabdff1aSopenharmony_ci { 24, 24, 12, 24, 24, 12, 96, 96, 144, }, // film1+ 193cabdff1aSopenharmony_ci { 24, 24, 12, 24, 24, 12, 192, 192, 288, }, // film1 194cabdff1aSopenharmony_ci { 32, 32, 24, 32, 32, 24, 128, 128, 192, }, // high+ 195cabdff1aSopenharmony_ci { 32, 32, 24, 32, 32, 24, 256, 256, 384, }, // high 196cabdff1aSopenharmony_ci { 48, 48, 32, 48, 48, 32, 256, 256, 384, }, // medium+ 197cabdff1aSopenharmony_ci { 48, 48, 32, 48, 48, 32, 512, 512, 768, }, // medium 198cabdff1aSopenharmony_ci { 56, 56, 40, 56, 56, 40, 512, 512, 768, }, // low+ 199cabdff1aSopenharmony_ci { 64, 64, 48, 64, 64, 48,1024,1024,1536, }, // low 200cabdff1aSopenharmony_ci }}, 201cabdff1aSopenharmony_ci}; 202cabdff1aSopenharmony_ci 203cabdff1aSopenharmony_citypedef struct Codebook { 204cabdff1aSopenharmony_ci unsigned bits; 205cabdff1aSopenharmony_ci unsigned size; 206cabdff1aSopenharmony_ci} Codebook; 207cabdff1aSopenharmony_ci 208cabdff1aSopenharmony_citypedef struct Runbook { 209cabdff1aSopenharmony_ci unsigned size; 210cabdff1aSopenharmony_ci unsigned bits; 211cabdff1aSopenharmony_ci unsigned run; 212cabdff1aSopenharmony_ci} Runbook; 213cabdff1aSopenharmony_ci 214cabdff1aSopenharmony_citypedef struct PlaneEnc { 215cabdff1aSopenharmony_ci unsigned size; 216cabdff1aSopenharmony_ci 217cabdff1aSopenharmony_ci int16_t *dwt_buf; 218cabdff1aSopenharmony_ci int16_t *dwt_tmp; 219cabdff1aSopenharmony_ci 220cabdff1aSopenharmony_ci unsigned quantization[SUBBAND_COUNT]; 221cabdff1aSopenharmony_ci int16_t *subband[SUBBAND_COUNT]; 222cabdff1aSopenharmony_ci int16_t *l_h[8]; 223cabdff1aSopenharmony_ci 224cabdff1aSopenharmony_ci SubBand band[DWT_LEVELS][4]; 225cabdff1aSopenharmony_ci} PlaneEnc; 226cabdff1aSopenharmony_ci 227cabdff1aSopenharmony_citypedef struct CFHDEncContext { 228cabdff1aSopenharmony_ci const AVClass *class; 229cabdff1aSopenharmony_ci 230cabdff1aSopenharmony_ci PutBitContext pb; 231cabdff1aSopenharmony_ci PutByteContext pby; 232cabdff1aSopenharmony_ci 233cabdff1aSopenharmony_ci int quality; 234cabdff1aSopenharmony_ci int planes; 235cabdff1aSopenharmony_ci int chroma_h_shift; 236cabdff1aSopenharmony_ci int chroma_v_shift; 237cabdff1aSopenharmony_ci PlaneEnc plane[4]; 238cabdff1aSopenharmony_ci 239cabdff1aSopenharmony_ci uint16_t lut[1024]; 240cabdff1aSopenharmony_ci Runbook rb[321]; 241cabdff1aSopenharmony_ci Codebook cb[513]; 242cabdff1aSopenharmony_ci int16_t *alpha; 243cabdff1aSopenharmony_ci 244cabdff1aSopenharmony_ci CFHDEncDSPContext dsp; 245cabdff1aSopenharmony_ci} CFHDEncContext; 246cabdff1aSopenharmony_ci 247cabdff1aSopenharmony_cistatic av_cold int cfhd_encode_init(AVCodecContext *avctx) 248cabdff1aSopenharmony_ci{ 249cabdff1aSopenharmony_ci CFHDEncContext *s = avctx->priv_data; 250cabdff1aSopenharmony_ci const int sign_mask = 256; 251cabdff1aSopenharmony_ci const int twos_complement = -sign_mask; 252cabdff1aSopenharmony_ci const int mag_mask = sign_mask - 1; 253cabdff1aSopenharmony_ci int ret, last = 0; 254cabdff1aSopenharmony_ci 255cabdff1aSopenharmony_ci ret = av_pix_fmt_get_chroma_sub_sample(avctx->pix_fmt, 256cabdff1aSopenharmony_ci &s->chroma_h_shift, 257cabdff1aSopenharmony_ci &s->chroma_v_shift); 258cabdff1aSopenharmony_ci if (ret < 0) 259cabdff1aSopenharmony_ci return ret; 260cabdff1aSopenharmony_ci 261cabdff1aSopenharmony_ci if (avctx->width & 15) { 262cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, "Width must be multiple of 16.\n"); 263cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 264cabdff1aSopenharmony_ci } 265cabdff1aSopenharmony_ci 266cabdff1aSopenharmony_ci s->planes = av_pix_fmt_count_planes(avctx->pix_fmt); 267cabdff1aSopenharmony_ci 268cabdff1aSopenharmony_ci for (int i = 0; i < s->planes; i++) { 269cabdff1aSopenharmony_ci int w8, h8, w4, h4, w2, h2; 270cabdff1aSopenharmony_ci int width = i ? avctx->width >> s->chroma_h_shift : avctx->width; 271cabdff1aSopenharmony_ci int height = i ? FFALIGN(avctx->height >> s->chroma_v_shift, 8) : 272cabdff1aSopenharmony_ci FFALIGN(avctx->height >> s->chroma_v_shift, 8); 273cabdff1aSopenharmony_ci ptrdiff_t stride = (FFALIGN(width / 8, 8) + 64) * 8; 274cabdff1aSopenharmony_ci 275cabdff1aSopenharmony_ci w8 = FFALIGN(width / 8, 8) + 64; 276cabdff1aSopenharmony_ci h8 = FFALIGN(height, 8) / 8; 277cabdff1aSopenharmony_ci w4 = w8 * 2; 278cabdff1aSopenharmony_ci h4 = h8 * 2; 279cabdff1aSopenharmony_ci w2 = w4 * 2; 280cabdff1aSopenharmony_ci h2 = h4 * 2; 281cabdff1aSopenharmony_ci 282cabdff1aSopenharmony_ci s->plane[i].dwt_buf = 283cabdff1aSopenharmony_ci av_calloc(height * stride, sizeof(*s->plane[i].dwt_buf)); 284cabdff1aSopenharmony_ci s->plane[i].dwt_tmp = 285cabdff1aSopenharmony_ci av_malloc_array(height * stride, sizeof(*s->plane[i].dwt_tmp)); 286cabdff1aSopenharmony_ci if (!s->plane[i].dwt_buf || !s->plane[i].dwt_tmp) 287cabdff1aSopenharmony_ci return AVERROR(ENOMEM); 288cabdff1aSopenharmony_ci 289cabdff1aSopenharmony_ci s->plane[i].subband[0] = s->plane[i].dwt_buf; 290cabdff1aSopenharmony_ci s->plane[i].subband[1] = s->plane[i].dwt_buf + 2 * w8 * h8; 291cabdff1aSopenharmony_ci s->plane[i].subband[2] = s->plane[i].dwt_buf + 1 * w8 * h8; 292cabdff1aSopenharmony_ci s->plane[i].subband[3] = s->plane[i].dwt_buf + 3 * w8 * h8; 293cabdff1aSopenharmony_ci s->plane[i].subband[4] = s->plane[i].dwt_buf + 2 * w4 * h4; 294cabdff1aSopenharmony_ci s->plane[i].subband[5] = s->plane[i].dwt_buf + 1 * w4 * h4; 295cabdff1aSopenharmony_ci s->plane[i].subband[6] = s->plane[i].dwt_buf + 3 * w4 * h4; 296cabdff1aSopenharmony_ci s->plane[i].subband[7] = s->plane[i].dwt_buf + 2 * w2 * h2; 297cabdff1aSopenharmony_ci s->plane[i].subband[8] = s->plane[i].dwt_buf + 1 * w2 * h2; 298cabdff1aSopenharmony_ci s->plane[i].subband[9] = s->plane[i].dwt_buf + 3 * w2 * h2; 299cabdff1aSopenharmony_ci 300cabdff1aSopenharmony_ci for (int j = 0; j < DWT_LEVELS; j++) { 301cabdff1aSopenharmony_ci for (int k = 0; k < FF_ARRAY_ELEMS(s->plane[i].band[j]); k++) { 302cabdff1aSopenharmony_ci s->plane[i].band[j][k].width = (width / 8) << j; 303cabdff1aSopenharmony_ci s->plane[i].band[j][k].height = (height / 8) << j; 304cabdff1aSopenharmony_ci s->plane[i].band[j][k].a_width = w8 << j; 305cabdff1aSopenharmony_ci s->plane[i].band[j][k].a_height = h8 << j; 306cabdff1aSopenharmony_ci } 307cabdff1aSopenharmony_ci } 308cabdff1aSopenharmony_ci 309cabdff1aSopenharmony_ci /* ll2 and ll1 commented out because they are done in-place */ 310cabdff1aSopenharmony_ci s->plane[i].l_h[0] = s->plane[i].dwt_tmp; 311cabdff1aSopenharmony_ci s->plane[i].l_h[1] = s->plane[i].dwt_tmp + 2 * w8 * h8; 312cabdff1aSopenharmony_ci // s->plane[i].l_h[2] = ll2; 313cabdff1aSopenharmony_ci s->plane[i].l_h[3] = s->plane[i].dwt_tmp; 314cabdff1aSopenharmony_ci s->plane[i].l_h[4] = s->plane[i].dwt_tmp + 2 * w4 * h4; 315cabdff1aSopenharmony_ci // s->plane[i].l_h[5] = ll1; 316cabdff1aSopenharmony_ci s->plane[i].l_h[6] = s->plane[i].dwt_tmp; 317cabdff1aSopenharmony_ci s->plane[i].l_h[7] = s->plane[i].dwt_tmp + 2 * w2 * h2; 318cabdff1aSopenharmony_ci } 319cabdff1aSopenharmony_ci 320cabdff1aSopenharmony_ci for (int i = 0; i < 512; i++) { 321cabdff1aSopenharmony_ci int value = (i & sign_mask) ? twos_complement + (i & mag_mask): i; 322cabdff1aSopenharmony_ci int mag = FFMIN(FFABS(value), 255); 323cabdff1aSopenharmony_ci 324cabdff1aSopenharmony_ci if (mag) { 325cabdff1aSopenharmony_ci s->cb[i].bits = (codebook[mag][1] << 1) | (value > 0 ? 0 : 1); 326cabdff1aSopenharmony_ci s->cb[i].size = codebook[mag][0] + 1; 327cabdff1aSopenharmony_ci } else { 328cabdff1aSopenharmony_ci s->cb[i].bits = codebook[mag][1]; 329cabdff1aSopenharmony_ci s->cb[i].size = codebook[mag][0]; 330cabdff1aSopenharmony_ci } 331cabdff1aSopenharmony_ci } 332cabdff1aSopenharmony_ci 333cabdff1aSopenharmony_ci s->cb[512].bits = 0x3114ba3; 334cabdff1aSopenharmony_ci s->cb[512].size = 26; 335cabdff1aSopenharmony_ci 336cabdff1aSopenharmony_ci s->rb[0].run = 0; 337cabdff1aSopenharmony_ci 338cabdff1aSopenharmony_ci for (int i = 1, j = 0; i < 320 && j < 17; j++) { 339cabdff1aSopenharmony_ci int run = runbook[j][2]; 340cabdff1aSopenharmony_ci int end = runbook[j+1][2]; 341cabdff1aSopenharmony_ci 342cabdff1aSopenharmony_ci while (i < end) { 343cabdff1aSopenharmony_ci s->rb[i].run = run; 344cabdff1aSopenharmony_ci s->rb[i].bits = runbook[j][1]; 345cabdff1aSopenharmony_ci s->rb[i++].size = runbook[j][0]; 346cabdff1aSopenharmony_ci } 347cabdff1aSopenharmony_ci } 348cabdff1aSopenharmony_ci 349cabdff1aSopenharmony_ci s->rb[320].bits = runbook[17][1]; 350cabdff1aSopenharmony_ci s->rb[320].size = runbook[17][0]; 351cabdff1aSopenharmony_ci s->rb[320].run = 320; 352cabdff1aSopenharmony_ci 353cabdff1aSopenharmony_ci for (int i = 0; i < 256; i++) { 354cabdff1aSopenharmony_ci int idx = i + ((768LL * i * i * i) / (256 * 256 * 256)); 355cabdff1aSopenharmony_ci 356cabdff1aSopenharmony_ci s->lut[idx] = i; 357cabdff1aSopenharmony_ci } 358cabdff1aSopenharmony_ci for (int i = 0; i < 1024; i++) { 359cabdff1aSopenharmony_ci if (s->lut[i]) 360cabdff1aSopenharmony_ci last = s->lut[i]; 361cabdff1aSopenharmony_ci else 362cabdff1aSopenharmony_ci s->lut[i] = last; 363cabdff1aSopenharmony_ci } 364cabdff1aSopenharmony_ci 365cabdff1aSopenharmony_ci ff_cfhdencdsp_init(&s->dsp); 366cabdff1aSopenharmony_ci 367cabdff1aSopenharmony_ci if (s->planes != 4) 368cabdff1aSopenharmony_ci return 0; 369cabdff1aSopenharmony_ci 370cabdff1aSopenharmony_ci s->alpha = av_calloc(avctx->width * avctx->height, sizeof(*s->alpha)); 371cabdff1aSopenharmony_ci if (!s->alpha) 372cabdff1aSopenharmony_ci return AVERROR(ENOMEM); 373cabdff1aSopenharmony_ci 374cabdff1aSopenharmony_ci return 0; 375cabdff1aSopenharmony_ci} 376cabdff1aSopenharmony_ci 377cabdff1aSopenharmony_cistatic void quantize_band(int16_t *input, int width, int a_width, 378cabdff1aSopenharmony_ci int height, unsigned quantization) 379cabdff1aSopenharmony_ci{ 380cabdff1aSopenharmony_ci const int16_t factor = (uint32_t)(1U << 15) / quantization; 381cabdff1aSopenharmony_ci 382cabdff1aSopenharmony_ci for (int i = 0; i < height; i++) { 383cabdff1aSopenharmony_ci for (int j = 0; j < width; j++) 384cabdff1aSopenharmony_ci input[j] = av_clip_intp2(((input[j] * factor + 16384 * FFSIGN(input[j])) / 32768), 10); 385cabdff1aSopenharmony_ci input += a_width; 386cabdff1aSopenharmony_ci } 387cabdff1aSopenharmony_ci} 388cabdff1aSopenharmony_ci 389cabdff1aSopenharmony_cistatic int put_runcode(PutBitContext *pb, int count, const Runbook *const rb) 390cabdff1aSopenharmony_ci{ 391cabdff1aSopenharmony_ci while (count > 0) { 392cabdff1aSopenharmony_ci const int index = FFMIN(320, count); 393cabdff1aSopenharmony_ci 394cabdff1aSopenharmony_ci put_bits(pb, rb[index].size, rb[index].bits); 395cabdff1aSopenharmony_ci count -= rb[index].run; 396cabdff1aSopenharmony_ci } 397cabdff1aSopenharmony_ci 398cabdff1aSopenharmony_ci return 0; 399cabdff1aSopenharmony_ci} 400cabdff1aSopenharmony_ci 401cabdff1aSopenharmony_cistatic void process_alpha(const int16_t *src, int width, int height, ptrdiff_t stride, int16_t *dst) 402cabdff1aSopenharmony_ci{ 403cabdff1aSopenharmony_ci for (int i = 0; i < height; i++) { 404cabdff1aSopenharmony_ci for (int j = 0; j < width; j++) { 405cabdff1aSopenharmony_ci int alpha = src[j]; 406cabdff1aSopenharmony_ci 407cabdff1aSopenharmony_ci if (alpha > 0 && alpha < 4080) { 408cabdff1aSopenharmony_ci alpha *= 223; 409cabdff1aSopenharmony_ci alpha += 128; 410cabdff1aSopenharmony_ci alpha >>= 8; 411cabdff1aSopenharmony_ci alpha += 256; 412cabdff1aSopenharmony_ci } 413cabdff1aSopenharmony_ci 414cabdff1aSopenharmony_ci dst[j] = av_clip_uintp2(alpha, 12); 415cabdff1aSopenharmony_ci } 416cabdff1aSopenharmony_ci 417cabdff1aSopenharmony_ci src += stride; 418cabdff1aSopenharmony_ci dst += width; 419cabdff1aSopenharmony_ci } 420cabdff1aSopenharmony_ci} 421cabdff1aSopenharmony_ci 422cabdff1aSopenharmony_cistatic int cfhd_encode_frame(AVCodecContext *avctx, AVPacket *pkt, 423cabdff1aSopenharmony_ci const AVFrame *frame, int *got_packet) 424cabdff1aSopenharmony_ci{ 425cabdff1aSopenharmony_ci CFHDEncContext *s = avctx->priv_data; 426cabdff1aSopenharmony_ci CFHDEncDSPContext *dsp = &s->dsp; 427cabdff1aSopenharmony_ci PutByteContext *pby = &s->pby; 428cabdff1aSopenharmony_ci PutBitContext *pb = &s->pb; 429cabdff1aSopenharmony_ci const Codebook *const cb = s->cb; 430cabdff1aSopenharmony_ci const Runbook *const rb = s->rb; 431cabdff1aSopenharmony_ci const uint16_t *lut = s->lut; 432cabdff1aSopenharmony_ci unsigned pos; 433cabdff1aSopenharmony_ci int ret; 434cabdff1aSopenharmony_ci 435cabdff1aSopenharmony_ci for (int plane = 0; plane < s->planes; plane++) { 436cabdff1aSopenharmony_ci int width = s->plane[plane].band[2][0].width; 437cabdff1aSopenharmony_ci int a_width = s->plane[plane].band[2][0].a_width; 438cabdff1aSopenharmony_ci int height = s->plane[plane].band[2][0].height; 439cabdff1aSopenharmony_ci int act_plane = plane == 1 ? 2 : plane == 2 ? 1 : plane; 440cabdff1aSopenharmony_ci int16_t *input = (int16_t *)frame->data[act_plane]; 441cabdff1aSopenharmony_ci int16_t *low = s->plane[plane].l_h[6]; 442cabdff1aSopenharmony_ci int16_t *high = s->plane[plane].l_h[7]; 443cabdff1aSopenharmony_ci ptrdiff_t in_stride = frame->linesize[act_plane] / 2; 444cabdff1aSopenharmony_ci int low_stride, high_stride; 445cabdff1aSopenharmony_ci 446cabdff1aSopenharmony_ci if (plane == 3) { 447cabdff1aSopenharmony_ci process_alpha(input, avctx->width, avctx->height, 448cabdff1aSopenharmony_ci in_stride, s->alpha); 449cabdff1aSopenharmony_ci input = s->alpha; 450cabdff1aSopenharmony_ci in_stride = avctx->width; 451cabdff1aSopenharmony_ci } 452cabdff1aSopenharmony_ci 453cabdff1aSopenharmony_ci dsp->horiz_filter(input, low, high, 454cabdff1aSopenharmony_ci in_stride, a_width, a_width, 455cabdff1aSopenharmony_ci width * 2, height * 2); 456cabdff1aSopenharmony_ci 457cabdff1aSopenharmony_ci input = s->plane[plane].l_h[7]; 458cabdff1aSopenharmony_ci low = s->plane[plane].subband[7]; 459cabdff1aSopenharmony_ci low_stride = s->plane[plane].band[2][0].a_width; 460cabdff1aSopenharmony_ci high = s->plane[plane].subband[9]; 461cabdff1aSopenharmony_ci high_stride = s->plane[plane].band[2][0].a_width; 462cabdff1aSopenharmony_ci 463cabdff1aSopenharmony_ci dsp->vert_filter(input, low, high, 464cabdff1aSopenharmony_ci a_width, low_stride, high_stride, 465cabdff1aSopenharmony_ci width, height * 2); 466cabdff1aSopenharmony_ci 467cabdff1aSopenharmony_ci input = s->plane[plane].l_h[6]; 468cabdff1aSopenharmony_ci low = s->plane[plane].l_h[7]; 469cabdff1aSopenharmony_ci high = s->plane[plane].subband[8]; 470cabdff1aSopenharmony_ci 471cabdff1aSopenharmony_ci dsp->vert_filter(input, low, high, 472cabdff1aSopenharmony_ci a_width, low_stride, high_stride, 473cabdff1aSopenharmony_ci width, height * 2); 474cabdff1aSopenharmony_ci 475cabdff1aSopenharmony_ci a_width = s->plane[plane].band[1][0].a_width; 476cabdff1aSopenharmony_ci width = s->plane[plane].band[1][0].width; 477cabdff1aSopenharmony_ci height = s->plane[plane].band[1][0].height; 478cabdff1aSopenharmony_ci input = s->plane[plane].l_h[7]; 479cabdff1aSopenharmony_ci low = s->plane[plane].l_h[3]; 480cabdff1aSopenharmony_ci low_stride = s->plane[plane].band[1][0].a_width; 481cabdff1aSopenharmony_ci high = s->plane[plane].l_h[4]; 482cabdff1aSopenharmony_ci high_stride = s->plane[plane].band[1][0].a_width; 483cabdff1aSopenharmony_ci 484cabdff1aSopenharmony_ci for (int i = 0; i < height * 2; i++) { 485cabdff1aSopenharmony_ci for (int j = 0; j < width * 2; j++) 486cabdff1aSopenharmony_ci input[j] /= 4; 487cabdff1aSopenharmony_ci input += a_width * 2; 488cabdff1aSopenharmony_ci } 489cabdff1aSopenharmony_ci 490cabdff1aSopenharmony_ci input = s->plane[plane].l_h[7]; 491cabdff1aSopenharmony_ci dsp->horiz_filter(input, low, high, 492cabdff1aSopenharmony_ci a_width * 2, low_stride, high_stride, 493cabdff1aSopenharmony_ci width * 2, height * 2); 494cabdff1aSopenharmony_ci 495cabdff1aSopenharmony_ci input = s->plane[plane].l_h[4]; 496cabdff1aSopenharmony_ci low = s->plane[plane].subband[4]; 497cabdff1aSopenharmony_ci high = s->plane[plane].subband[6]; 498cabdff1aSopenharmony_ci 499cabdff1aSopenharmony_ci dsp->vert_filter(input, low, high, 500cabdff1aSopenharmony_ci a_width, low_stride, high_stride, 501cabdff1aSopenharmony_ci width, height * 2); 502cabdff1aSopenharmony_ci 503cabdff1aSopenharmony_ci input = s->plane[plane].l_h[3]; 504cabdff1aSopenharmony_ci low = s->plane[plane].l_h[4]; 505cabdff1aSopenharmony_ci high = s->plane[plane].subband[5]; 506cabdff1aSopenharmony_ci 507cabdff1aSopenharmony_ci dsp->vert_filter(input, low, high, 508cabdff1aSopenharmony_ci a_width, low_stride, high_stride, 509cabdff1aSopenharmony_ci width, height * 2); 510cabdff1aSopenharmony_ci 511cabdff1aSopenharmony_ci a_width = s->plane[plane].band[0][0].a_width; 512cabdff1aSopenharmony_ci width = s->plane[plane].band[0][0].width; 513cabdff1aSopenharmony_ci height = s->plane[plane].band[0][0].height; 514cabdff1aSopenharmony_ci input = s->plane[plane].l_h[4]; 515cabdff1aSopenharmony_ci low = s->plane[plane].l_h[0]; 516cabdff1aSopenharmony_ci low_stride = s->plane[plane].band[0][0].a_width; 517cabdff1aSopenharmony_ci high = s->plane[plane].l_h[1]; 518cabdff1aSopenharmony_ci high_stride = s->plane[plane].band[0][0].a_width; 519cabdff1aSopenharmony_ci 520cabdff1aSopenharmony_ci if (avctx->pix_fmt != AV_PIX_FMT_YUV422P10) { 521cabdff1aSopenharmony_ci for (int i = 0; i < height * 2; i++) { 522cabdff1aSopenharmony_ci for (int j = 0; j < width * 2; j++) 523cabdff1aSopenharmony_ci input[j] /= 4; 524cabdff1aSopenharmony_ci input += a_width * 2; 525cabdff1aSopenharmony_ci } 526cabdff1aSopenharmony_ci } 527cabdff1aSopenharmony_ci 528cabdff1aSopenharmony_ci input = s->plane[plane].l_h[4]; 529cabdff1aSopenharmony_ci dsp->horiz_filter(input, low, high, 530cabdff1aSopenharmony_ci a_width * 2, low_stride, high_stride, 531cabdff1aSopenharmony_ci width * 2, height * 2); 532cabdff1aSopenharmony_ci 533cabdff1aSopenharmony_ci low = s->plane[plane].subband[1]; 534cabdff1aSopenharmony_ci high = s->plane[plane].subband[3]; 535cabdff1aSopenharmony_ci input = s->plane[plane].l_h[1]; 536cabdff1aSopenharmony_ci 537cabdff1aSopenharmony_ci dsp->vert_filter(input, low, high, 538cabdff1aSopenharmony_ci a_width, low_stride, high_stride, 539cabdff1aSopenharmony_ci width, height * 2); 540cabdff1aSopenharmony_ci 541cabdff1aSopenharmony_ci low = s->plane[plane].subband[0]; 542cabdff1aSopenharmony_ci high = s->plane[plane].subband[2]; 543cabdff1aSopenharmony_ci input = s->plane[plane].l_h[0]; 544cabdff1aSopenharmony_ci 545cabdff1aSopenharmony_ci dsp->vert_filter(input, low, high, 546cabdff1aSopenharmony_ci a_width, low_stride, high_stride, 547cabdff1aSopenharmony_ci width, height * 2); 548cabdff1aSopenharmony_ci } 549cabdff1aSopenharmony_ci 550cabdff1aSopenharmony_ci ret = ff_alloc_packet(avctx, pkt, 64LL + s->planes * (2LL * avctx->width * avctx->height + 1000LL)); 551cabdff1aSopenharmony_ci if (ret < 0) 552cabdff1aSopenharmony_ci return ret; 553cabdff1aSopenharmony_ci 554cabdff1aSopenharmony_ci bytestream2_init_writer(pby, pkt->data, pkt->size); 555cabdff1aSopenharmony_ci 556cabdff1aSopenharmony_ci bytestream2_put_be16(pby, SampleType); 557cabdff1aSopenharmony_ci bytestream2_put_be16(pby, 9); 558cabdff1aSopenharmony_ci 559cabdff1aSopenharmony_ci bytestream2_put_be16(pby, SampleIndexTable); 560cabdff1aSopenharmony_ci bytestream2_put_be16(pby, s->planes); 561cabdff1aSopenharmony_ci 562cabdff1aSopenharmony_ci for (int i = 0; i < s->planes; i++) 563cabdff1aSopenharmony_ci bytestream2_put_be32(pby, 0); 564cabdff1aSopenharmony_ci 565cabdff1aSopenharmony_ci bytestream2_put_be16(pby, TransformType); 566cabdff1aSopenharmony_ci bytestream2_put_be16(pby, 0); 567cabdff1aSopenharmony_ci 568cabdff1aSopenharmony_ci bytestream2_put_be16(pby, NumFrames); 569cabdff1aSopenharmony_ci bytestream2_put_be16(pby, 1); 570cabdff1aSopenharmony_ci 571cabdff1aSopenharmony_ci bytestream2_put_be16(pby, ChannelCount); 572cabdff1aSopenharmony_ci bytestream2_put_be16(pby, s->planes); 573cabdff1aSopenharmony_ci 574cabdff1aSopenharmony_ci bytestream2_put_be16(pby, EncodedFormat); 575cabdff1aSopenharmony_ci bytestream2_put_be16(pby, avctx->pix_fmt == AV_PIX_FMT_YUV422P10 ? 1 : 3 + (s->planes == 4)); 576cabdff1aSopenharmony_ci 577cabdff1aSopenharmony_ci bytestream2_put_be16(pby, WaveletCount); 578cabdff1aSopenharmony_ci bytestream2_put_be16(pby, 3); 579cabdff1aSopenharmony_ci 580cabdff1aSopenharmony_ci bytestream2_put_be16(pby, SubbandCount); 581cabdff1aSopenharmony_ci bytestream2_put_be16(pby, SUBBAND_COUNT); 582cabdff1aSopenharmony_ci 583cabdff1aSopenharmony_ci bytestream2_put_be16(pby, NumSpatial); 584cabdff1aSopenharmony_ci bytestream2_put_be16(pby, 2); 585cabdff1aSopenharmony_ci 586cabdff1aSopenharmony_ci bytestream2_put_be16(pby, FirstWavelet); 587cabdff1aSopenharmony_ci bytestream2_put_be16(pby, 3); 588cabdff1aSopenharmony_ci 589cabdff1aSopenharmony_ci bytestream2_put_be16(pby, ImageWidth); 590cabdff1aSopenharmony_ci bytestream2_put_be16(pby, avctx->width); 591cabdff1aSopenharmony_ci 592cabdff1aSopenharmony_ci bytestream2_put_be16(pby, ImageHeight); 593cabdff1aSopenharmony_ci bytestream2_put_be16(pby, avctx->height); 594cabdff1aSopenharmony_ci 595cabdff1aSopenharmony_ci bytestream2_put_be16(pby, -FrameNumber); 596cabdff1aSopenharmony_ci bytestream2_put_be16(pby, frame->pts & 0xFFFF); 597cabdff1aSopenharmony_ci 598cabdff1aSopenharmony_ci bytestream2_put_be16(pby, Precision); 599cabdff1aSopenharmony_ci bytestream2_put_be16(pby, avctx->pix_fmt == AV_PIX_FMT_YUV422P10 ? 10 : 12); 600cabdff1aSopenharmony_ci 601cabdff1aSopenharmony_ci bytestream2_put_be16(pby, PrescaleTable); 602cabdff1aSopenharmony_ci bytestream2_put_be16(pby, avctx->pix_fmt == AV_PIX_FMT_YUV422P10 ? 0x2000 : 0x2800); 603cabdff1aSopenharmony_ci 604cabdff1aSopenharmony_ci bytestream2_put_be16(pby, SampleFlags); 605cabdff1aSopenharmony_ci bytestream2_put_be16(pby, 1); 606cabdff1aSopenharmony_ci 607cabdff1aSopenharmony_ci for (int p = 0; p < s->planes; p++) { 608cabdff1aSopenharmony_ci int width = s->plane[p].band[0][0].width; 609cabdff1aSopenharmony_ci int a_width = s->plane[p].band[0][0].a_width; 610cabdff1aSopenharmony_ci int height = s->plane[p].band[0][0].height; 611cabdff1aSopenharmony_ci int16_t *data = s->plane[p].subband[0]; 612cabdff1aSopenharmony_ci 613cabdff1aSopenharmony_ci if (p) { 614cabdff1aSopenharmony_ci bytestream2_put_be16(pby, SampleType); 615cabdff1aSopenharmony_ci bytestream2_put_be16(pby, 3); 616cabdff1aSopenharmony_ci 617cabdff1aSopenharmony_ci bytestream2_put_be16(pby, ChannelNumber); 618cabdff1aSopenharmony_ci bytestream2_put_be16(pby, p); 619cabdff1aSopenharmony_ci } 620cabdff1aSopenharmony_ci 621cabdff1aSopenharmony_ci bytestream2_put_be16(pby, BitstreamMarker); 622cabdff1aSopenharmony_ci bytestream2_put_be16(pby, 0x1a4a); 623cabdff1aSopenharmony_ci 624cabdff1aSopenharmony_ci pos = bytestream2_tell_p(pby); 625cabdff1aSopenharmony_ci 626cabdff1aSopenharmony_ci bytestream2_put_be16(pby, LowpassSubband); 627cabdff1aSopenharmony_ci bytestream2_put_be16(pby, 0); 628cabdff1aSopenharmony_ci 629cabdff1aSopenharmony_ci bytestream2_put_be16(pby, NumLevels); 630cabdff1aSopenharmony_ci bytestream2_put_be16(pby, 3); 631cabdff1aSopenharmony_ci 632cabdff1aSopenharmony_ci bytestream2_put_be16(pby, LowpassWidth); 633cabdff1aSopenharmony_ci bytestream2_put_be16(pby, width); 634cabdff1aSopenharmony_ci 635cabdff1aSopenharmony_ci bytestream2_put_be16(pby, LowpassHeight); 636cabdff1aSopenharmony_ci bytestream2_put_be16(pby, height); 637cabdff1aSopenharmony_ci 638cabdff1aSopenharmony_ci bytestream2_put_be16(pby, PixelOffset); 639cabdff1aSopenharmony_ci bytestream2_put_be16(pby, 0); 640cabdff1aSopenharmony_ci 641cabdff1aSopenharmony_ci bytestream2_put_be16(pby, LowpassQuantization); 642cabdff1aSopenharmony_ci bytestream2_put_be16(pby, 1); 643cabdff1aSopenharmony_ci 644cabdff1aSopenharmony_ci bytestream2_put_be16(pby, LowpassPrecision); 645cabdff1aSopenharmony_ci bytestream2_put_be16(pby, 16); 646cabdff1aSopenharmony_ci 647cabdff1aSopenharmony_ci bytestream2_put_be16(pby, BitstreamMarker); 648cabdff1aSopenharmony_ci bytestream2_put_be16(pby, 0x0f0f); 649cabdff1aSopenharmony_ci 650cabdff1aSopenharmony_ci for (int i = 0; i < height; i++) { 651cabdff1aSopenharmony_ci for (int j = 0; j < width; j++) 652cabdff1aSopenharmony_ci bytestream2_put_be16(pby, data[j]); 653cabdff1aSopenharmony_ci data += a_width; 654cabdff1aSopenharmony_ci } 655cabdff1aSopenharmony_ci 656cabdff1aSopenharmony_ci bytestream2_put_be16(pby, BitstreamMarker); 657cabdff1aSopenharmony_ci bytestream2_put_be16(pby, 0x1b4b); 658cabdff1aSopenharmony_ci 659cabdff1aSopenharmony_ci for (int l = 0; l < 3; l++) { 660cabdff1aSopenharmony_ci for (int i = 0; i < 3; i++) { 661cabdff1aSopenharmony_ci s->plane[p].quantization[1 + l * 3 + i] = quantization_per_subband[avctx->pix_fmt != AV_PIX_FMT_YUV422P10][p >= 3 ? 0 : p][s->quality][l * 3 + i]; 662cabdff1aSopenharmony_ci } 663cabdff1aSopenharmony_ci } 664cabdff1aSopenharmony_ci 665cabdff1aSopenharmony_ci for (int l = 0; l < 3; l++) { 666cabdff1aSopenharmony_ci int a_width = s->plane[p].band[l][0].a_width; 667cabdff1aSopenharmony_ci int width = s->plane[p].band[l][0].width; 668cabdff1aSopenharmony_ci int stride = FFALIGN(width, 8); 669cabdff1aSopenharmony_ci int height = s->plane[p].band[l][0].height; 670cabdff1aSopenharmony_ci 671cabdff1aSopenharmony_ci bytestream2_put_be16(pby, BitstreamMarker); 672cabdff1aSopenharmony_ci bytestream2_put_be16(pby, 0x0d0d); 673cabdff1aSopenharmony_ci 674cabdff1aSopenharmony_ci bytestream2_put_be16(pby, WaveletType); 675cabdff1aSopenharmony_ci bytestream2_put_be16(pby, 3 + 2 * (l == 2)); 676cabdff1aSopenharmony_ci 677cabdff1aSopenharmony_ci bytestream2_put_be16(pby, WaveletNumber); 678cabdff1aSopenharmony_ci bytestream2_put_be16(pby, 3 - l); 679cabdff1aSopenharmony_ci 680cabdff1aSopenharmony_ci bytestream2_put_be16(pby, WaveletLevel); 681cabdff1aSopenharmony_ci bytestream2_put_be16(pby, 3 - l); 682cabdff1aSopenharmony_ci 683cabdff1aSopenharmony_ci bytestream2_put_be16(pby, NumBands); 684cabdff1aSopenharmony_ci bytestream2_put_be16(pby, 4); 685cabdff1aSopenharmony_ci 686cabdff1aSopenharmony_ci bytestream2_put_be16(pby, HighpassWidth); 687cabdff1aSopenharmony_ci bytestream2_put_be16(pby, width); 688cabdff1aSopenharmony_ci 689cabdff1aSopenharmony_ci bytestream2_put_be16(pby, HighpassHeight); 690cabdff1aSopenharmony_ci bytestream2_put_be16(pby, height); 691cabdff1aSopenharmony_ci 692cabdff1aSopenharmony_ci bytestream2_put_be16(pby, LowpassBorder); 693cabdff1aSopenharmony_ci bytestream2_put_be16(pby, 0); 694cabdff1aSopenharmony_ci 695cabdff1aSopenharmony_ci bytestream2_put_be16(pby, HighpassBorder); 696cabdff1aSopenharmony_ci bytestream2_put_be16(pby, 0); 697cabdff1aSopenharmony_ci 698cabdff1aSopenharmony_ci bytestream2_put_be16(pby, LowpassScale); 699cabdff1aSopenharmony_ci bytestream2_put_be16(pby, 1); 700cabdff1aSopenharmony_ci 701cabdff1aSopenharmony_ci bytestream2_put_be16(pby, LowpassDivisor); 702cabdff1aSopenharmony_ci bytestream2_put_be16(pby, 1); 703cabdff1aSopenharmony_ci 704cabdff1aSopenharmony_ci for (int i = 0; i < 3; i++) { 705cabdff1aSopenharmony_ci int16_t *data = s->plane[p].subband[1 + l * 3 + i]; 706cabdff1aSopenharmony_ci int count = 0, padd = 0; 707cabdff1aSopenharmony_ci 708cabdff1aSopenharmony_ci bytestream2_put_be16(pby, BitstreamMarker); 709cabdff1aSopenharmony_ci bytestream2_put_be16(pby, 0x0e0e); 710cabdff1aSopenharmony_ci 711cabdff1aSopenharmony_ci bytestream2_put_be16(pby, SubbandNumber); 712cabdff1aSopenharmony_ci bytestream2_put_be16(pby, i + 1); 713cabdff1aSopenharmony_ci 714cabdff1aSopenharmony_ci bytestream2_put_be16(pby, BandCodingFlags); 715cabdff1aSopenharmony_ci bytestream2_put_be16(pby, 1); 716cabdff1aSopenharmony_ci 717cabdff1aSopenharmony_ci bytestream2_put_be16(pby, BandWidth); 718cabdff1aSopenharmony_ci bytestream2_put_be16(pby, width); 719cabdff1aSopenharmony_ci 720cabdff1aSopenharmony_ci bytestream2_put_be16(pby, BandHeight); 721cabdff1aSopenharmony_ci bytestream2_put_be16(pby, height); 722cabdff1aSopenharmony_ci 723cabdff1aSopenharmony_ci bytestream2_put_be16(pby, SubbandBand); 724cabdff1aSopenharmony_ci bytestream2_put_be16(pby, 1 + l * 3 + i); 725cabdff1aSopenharmony_ci 726cabdff1aSopenharmony_ci bytestream2_put_be16(pby, BandEncoding); 727cabdff1aSopenharmony_ci bytestream2_put_be16(pby, 3); 728cabdff1aSopenharmony_ci 729cabdff1aSopenharmony_ci bytestream2_put_be16(pby, Quantization); 730cabdff1aSopenharmony_ci bytestream2_put_be16(pby, s->plane[p].quantization[1 + l * 3 + i]); 731cabdff1aSopenharmony_ci 732cabdff1aSopenharmony_ci bytestream2_put_be16(pby, BandScale); 733cabdff1aSopenharmony_ci bytestream2_put_be16(pby, 1); 734cabdff1aSopenharmony_ci 735cabdff1aSopenharmony_ci bytestream2_put_be16(pby, BandHeader); 736cabdff1aSopenharmony_ci bytestream2_put_be16(pby, 0); 737cabdff1aSopenharmony_ci 738cabdff1aSopenharmony_ci quantize_band(data, width, a_width, height, 739cabdff1aSopenharmony_ci s->plane[p].quantization[1 + l * 3 + i]); 740cabdff1aSopenharmony_ci 741cabdff1aSopenharmony_ci init_put_bits(pb, pkt->data + bytestream2_tell_p(pby), bytestream2_get_bytes_left_p(pby)); 742cabdff1aSopenharmony_ci 743cabdff1aSopenharmony_ci for (int m = 0; m < height; m++) { 744cabdff1aSopenharmony_ci for (int j = 0; j < stride; j++) { 745cabdff1aSopenharmony_ci int16_t index = j >= width ? 0 : FFSIGN(data[j]) * lut[FFABS(data[j])]; 746cabdff1aSopenharmony_ci 747cabdff1aSopenharmony_ci if (index < 0) 748cabdff1aSopenharmony_ci index += 512; 749cabdff1aSopenharmony_ci if (index == 0) { 750cabdff1aSopenharmony_ci count++; 751cabdff1aSopenharmony_ci continue; 752cabdff1aSopenharmony_ci } else if (count > 0) { 753cabdff1aSopenharmony_ci count = put_runcode(pb, count, rb); 754cabdff1aSopenharmony_ci } 755cabdff1aSopenharmony_ci 756cabdff1aSopenharmony_ci put_bits(pb, cb[index].size, cb[index].bits); 757cabdff1aSopenharmony_ci } 758cabdff1aSopenharmony_ci 759cabdff1aSopenharmony_ci data += a_width; 760cabdff1aSopenharmony_ci } 761cabdff1aSopenharmony_ci 762cabdff1aSopenharmony_ci if (count > 0) { 763cabdff1aSopenharmony_ci count = put_runcode(pb, count, rb); 764cabdff1aSopenharmony_ci } 765cabdff1aSopenharmony_ci 766cabdff1aSopenharmony_ci put_bits(pb, cb[512].size, cb[512].bits); 767cabdff1aSopenharmony_ci 768cabdff1aSopenharmony_ci flush_put_bits(pb); 769cabdff1aSopenharmony_ci bytestream2_skip_p(pby, put_bytes_output(pb)); 770cabdff1aSopenharmony_ci padd = (4 - (bytestream2_tell_p(pby) & 3)) & 3; 771cabdff1aSopenharmony_ci while (padd--) 772cabdff1aSopenharmony_ci bytestream2_put_byte(pby, 0); 773cabdff1aSopenharmony_ci 774cabdff1aSopenharmony_ci bytestream2_put_be16(pby, BandTrailer); 775cabdff1aSopenharmony_ci bytestream2_put_be16(pby, 0); 776cabdff1aSopenharmony_ci } 777cabdff1aSopenharmony_ci 778cabdff1aSopenharmony_ci bytestream2_put_be16(pby, BitstreamMarker); 779cabdff1aSopenharmony_ci bytestream2_put_be16(pby, 0x0c0c); 780cabdff1aSopenharmony_ci } 781cabdff1aSopenharmony_ci 782cabdff1aSopenharmony_ci s->plane[p].size = bytestream2_tell_p(pby) - pos; 783cabdff1aSopenharmony_ci } 784cabdff1aSopenharmony_ci 785cabdff1aSopenharmony_ci bytestream2_put_be16(pby, GroupTrailer); 786cabdff1aSopenharmony_ci bytestream2_put_be16(pby, 0); 787cabdff1aSopenharmony_ci 788cabdff1aSopenharmony_ci av_shrink_packet(pkt, bytestream2_tell_p(pby)); 789cabdff1aSopenharmony_ci 790cabdff1aSopenharmony_ci pkt->flags |= AV_PKT_FLAG_KEY; 791cabdff1aSopenharmony_ci 792cabdff1aSopenharmony_ci bytestream2_seek_p(pby, 8, SEEK_SET); 793cabdff1aSopenharmony_ci for (int i = 0; i < s->planes; i++) 794cabdff1aSopenharmony_ci bytestream2_put_be32(pby, s->plane[i].size); 795cabdff1aSopenharmony_ci 796cabdff1aSopenharmony_ci *got_packet = 1; 797cabdff1aSopenharmony_ci 798cabdff1aSopenharmony_ci return 0; 799cabdff1aSopenharmony_ci} 800cabdff1aSopenharmony_ci 801cabdff1aSopenharmony_cistatic av_cold int cfhd_encode_close(AVCodecContext *avctx) 802cabdff1aSopenharmony_ci{ 803cabdff1aSopenharmony_ci CFHDEncContext *s = avctx->priv_data; 804cabdff1aSopenharmony_ci 805cabdff1aSopenharmony_ci for (int i = 0; i < s->planes; i++) { 806cabdff1aSopenharmony_ci av_freep(&s->plane[i].dwt_buf); 807cabdff1aSopenharmony_ci av_freep(&s->plane[i].dwt_tmp); 808cabdff1aSopenharmony_ci 809cabdff1aSopenharmony_ci for (int j = 0; j < SUBBAND_COUNT; j++) 810cabdff1aSopenharmony_ci s->plane[i].subband[j] = NULL; 811cabdff1aSopenharmony_ci 812cabdff1aSopenharmony_ci for (int j = 0; j < 8; j++) 813cabdff1aSopenharmony_ci s->plane[i].l_h[j] = NULL; 814cabdff1aSopenharmony_ci } 815cabdff1aSopenharmony_ci 816cabdff1aSopenharmony_ci av_freep(&s->alpha); 817cabdff1aSopenharmony_ci 818cabdff1aSopenharmony_ci return 0; 819cabdff1aSopenharmony_ci} 820cabdff1aSopenharmony_ci 821cabdff1aSopenharmony_ci#define OFFSET(x) offsetof(CFHDEncContext, x) 822cabdff1aSopenharmony_ci#define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM 823cabdff1aSopenharmony_cistatic const AVOption options[] = { 824cabdff1aSopenharmony_ci { "quality", "set quality", OFFSET(quality), AV_OPT_TYPE_INT, {.i64= 0}, 0, 12, VE, "q" }, 825cabdff1aSopenharmony_ci { "film3+", NULL, 0, AV_OPT_TYPE_CONST, {.i64= 0}, 0, 0, VE, "q" }, 826cabdff1aSopenharmony_ci { "film3", NULL, 0, AV_OPT_TYPE_CONST, {.i64= 1}, 0, 0, VE, "q" }, 827cabdff1aSopenharmony_ci { "film2+", NULL, 0, AV_OPT_TYPE_CONST, {.i64= 2}, 0, 0, VE, "q" }, 828cabdff1aSopenharmony_ci { "film2", NULL, 0, AV_OPT_TYPE_CONST, {.i64= 3}, 0, 0, VE, "q" }, 829cabdff1aSopenharmony_ci { "film1.5", NULL, 0, AV_OPT_TYPE_CONST, {.i64= 4}, 0, 0, VE, "q" }, 830cabdff1aSopenharmony_ci { "film1+", NULL, 0, AV_OPT_TYPE_CONST, {.i64= 5}, 0, 0, VE, "q" }, 831cabdff1aSopenharmony_ci { "film1", NULL, 0, AV_OPT_TYPE_CONST, {.i64= 6}, 0, 0, VE, "q" }, 832cabdff1aSopenharmony_ci { "high+", NULL, 0, AV_OPT_TYPE_CONST, {.i64= 7}, 0, 0, VE, "q" }, 833cabdff1aSopenharmony_ci { "high", NULL, 0, AV_OPT_TYPE_CONST, {.i64= 8}, 0, 0, VE, "q" }, 834cabdff1aSopenharmony_ci { "medium+", NULL, 0, AV_OPT_TYPE_CONST, {.i64= 9}, 0, 0, VE, "q" }, 835cabdff1aSopenharmony_ci { "medium", NULL, 0, AV_OPT_TYPE_CONST, {.i64=10}, 0, 0, VE, "q" }, 836cabdff1aSopenharmony_ci { "low+", NULL, 0, AV_OPT_TYPE_CONST, {.i64=11}, 0, 0, VE, "q" }, 837cabdff1aSopenharmony_ci { "low", NULL, 0, AV_OPT_TYPE_CONST, {.i64=12}, 0, 0, VE, "q" }, 838cabdff1aSopenharmony_ci { NULL}, 839cabdff1aSopenharmony_ci}; 840cabdff1aSopenharmony_ci 841cabdff1aSopenharmony_cistatic const AVClass cfhd_class = { 842cabdff1aSopenharmony_ci .class_name = "cfhd", 843cabdff1aSopenharmony_ci .item_name = av_default_item_name, 844cabdff1aSopenharmony_ci .option = options, 845cabdff1aSopenharmony_ci .version = LIBAVUTIL_VERSION_INT, 846cabdff1aSopenharmony_ci}; 847cabdff1aSopenharmony_ci 848cabdff1aSopenharmony_ciconst FFCodec ff_cfhd_encoder = { 849cabdff1aSopenharmony_ci .p.name = "cfhd", 850cabdff1aSopenharmony_ci .p.long_name = NULL_IF_CONFIG_SMALL("GoPro CineForm HD"), 851cabdff1aSopenharmony_ci .p.type = AVMEDIA_TYPE_VIDEO, 852cabdff1aSopenharmony_ci .p.id = AV_CODEC_ID_CFHD, 853cabdff1aSopenharmony_ci .priv_data_size = sizeof(CFHDEncContext), 854cabdff1aSopenharmony_ci .p.priv_class = &cfhd_class, 855cabdff1aSopenharmony_ci .init = cfhd_encode_init, 856cabdff1aSopenharmony_ci .close = cfhd_encode_close, 857cabdff1aSopenharmony_ci FF_CODEC_ENCODE_CB(cfhd_encode_frame), 858cabdff1aSopenharmony_ci .p.capabilities = AV_CODEC_CAP_FRAME_THREADS, 859cabdff1aSopenharmony_ci .p.pix_fmts = (const enum AVPixelFormat[]) { 860cabdff1aSopenharmony_ci AV_PIX_FMT_YUV422P10, 861cabdff1aSopenharmony_ci AV_PIX_FMT_GBRP12, 862cabdff1aSopenharmony_ci AV_PIX_FMT_GBRAP12, 863cabdff1aSopenharmony_ci AV_PIX_FMT_NONE 864cabdff1aSopenharmony_ci }, 865cabdff1aSopenharmony_ci .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP, 866cabdff1aSopenharmony_ci}; 867