1cabdff1aSopenharmony_ci/* 2cabdff1aSopenharmony_ci * FFV1 encoder 3cabdff1aSopenharmony_ci * 4cabdff1aSopenharmony_ci * Copyright (c) 2003-2013 Michael Niedermayer <michaelni@gmx.at> 5cabdff1aSopenharmony_ci * 6cabdff1aSopenharmony_ci * This file is part of FFmpeg. 7cabdff1aSopenharmony_ci * 8cabdff1aSopenharmony_ci * FFmpeg is free software; you can redistribute it and/or 9cabdff1aSopenharmony_ci * modify it under the terms of the GNU Lesser General Public 10cabdff1aSopenharmony_ci * License as published by the Free Software Foundation; either 11cabdff1aSopenharmony_ci * version 2.1 of the License, or (at your option) any later version. 12cabdff1aSopenharmony_ci * 13cabdff1aSopenharmony_ci * FFmpeg is distributed in the hope that it will be useful, 14cabdff1aSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of 15cabdff1aSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16cabdff1aSopenharmony_ci * Lesser General Public License for more details. 17cabdff1aSopenharmony_ci * 18cabdff1aSopenharmony_ci * You should have received a copy of the GNU Lesser General Public 19cabdff1aSopenharmony_ci * License along with FFmpeg; if not, write to the Free Software 20cabdff1aSopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 21cabdff1aSopenharmony_ci */ 22cabdff1aSopenharmony_ci 23cabdff1aSopenharmony_ci/** 24cabdff1aSopenharmony_ci * @file 25cabdff1aSopenharmony_ci * FF Video Codec 1 (a lossless codec) encoder 26cabdff1aSopenharmony_ci */ 27cabdff1aSopenharmony_ci 28cabdff1aSopenharmony_ci#include "libavutil/attributes.h" 29cabdff1aSopenharmony_ci#include "libavutil/avassert.h" 30cabdff1aSopenharmony_ci#include "libavutil/crc.h" 31cabdff1aSopenharmony_ci#include "libavutil/opt.h" 32cabdff1aSopenharmony_ci#include "libavutil/imgutils.h" 33cabdff1aSopenharmony_ci#include "libavutil/pixdesc.h" 34cabdff1aSopenharmony_ci 35cabdff1aSopenharmony_ci#include "avcodec.h" 36cabdff1aSopenharmony_ci#include "encode.h" 37cabdff1aSopenharmony_ci#include "codec_internal.h" 38cabdff1aSopenharmony_ci#include "put_bits.h" 39cabdff1aSopenharmony_ci#include "put_golomb.h" 40cabdff1aSopenharmony_ci#include "rangecoder.h" 41cabdff1aSopenharmony_ci#include "mathops.h" 42cabdff1aSopenharmony_ci#include "ffv1.h" 43cabdff1aSopenharmony_ci 44cabdff1aSopenharmony_cistatic const int8_t quant5_10bit[256] = { 45cabdff1aSopenharmony_ci 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 46cabdff1aSopenharmony_ci 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 47cabdff1aSopenharmony_ci 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 48cabdff1aSopenharmony_ci 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 49cabdff1aSopenharmony_ci 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 50cabdff1aSopenharmony_ci 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 51cabdff1aSopenharmony_ci 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 52cabdff1aSopenharmony_ci 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 53cabdff1aSopenharmony_ci -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, 54cabdff1aSopenharmony_ci -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, 55cabdff1aSopenharmony_ci -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, 56cabdff1aSopenharmony_ci -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, 57cabdff1aSopenharmony_ci -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -1, 58cabdff1aSopenharmony_ci -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 59cabdff1aSopenharmony_ci -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 60cabdff1aSopenharmony_ci -1, -1, -1, -1, -1, -1, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, 61cabdff1aSopenharmony_ci}; 62cabdff1aSopenharmony_ci 63cabdff1aSopenharmony_cistatic const int8_t quant5[256] = { 64cabdff1aSopenharmony_ci 0, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 65cabdff1aSopenharmony_ci 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 66cabdff1aSopenharmony_ci 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 67cabdff1aSopenharmony_ci 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 68cabdff1aSopenharmony_ci 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 69cabdff1aSopenharmony_ci 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 70cabdff1aSopenharmony_ci 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 71cabdff1aSopenharmony_ci 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 72cabdff1aSopenharmony_ci -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, 73cabdff1aSopenharmony_ci -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, 74cabdff1aSopenharmony_ci -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, 75cabdff1aSopenharmony_ci -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, 76cabdff1aSopenharmony_ci -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, 77cabdff1aSopenharmony_ci -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, 78cabdff1aSopenharmony_ci -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, 79cabdff1aSopenharmony_ci -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -1, -1, -1, 80cabdff1aSopenharmony_ci}; 81cabdff1aSopenharmony_ci 82cabdff1aSopenharmony_cistatic const int8_t quant9_10bit[256] = { 83cabdff1aSopenharmony_ci 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 84cabdff1aSopenharmony_ci 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 85cabdff1aSopenharmony_ci 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 86cabdff1aSopenharmony_ci 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 87cabdff1aSopenharmony_ci 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 88cabdff1aSopenharmony_ci 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 89cabdff1aSopenharmony_ci 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 90cabdff1aSopenharmony_ci 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 91cabdff1aSopenharmony_ci -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, 92cabdff1aSopenharmony_ci -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, 93cabdff1aSopenharmony_ci -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, 94cabdff1aSopenharmony_ci -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, 95cabdff1aSopenharmony_ci -4, -4, -4, -4, -4, -4, -4, -4, -4, -3, -3, -3, -3, -3, -3, -3, 96cabdff1aSopenharmony_ci -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, 97cabdff1aSopenharmony_ci -3, -3, -3, -3, -3, -3, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, 98cabdff1aSopenharmony_ci -2, -2, -2, -2, -1, -1, -1, -1, -1, -1, -1, -1, -0, -0, -0, -0, 99cabdff1aSopenharmony_ci}; 100cabdff1aSopenharmony_ci 101cabdff1aSopenharmony_cistatic const int8_t quant11[256] = { 102cabdff1aSopenharmony_ci 0, 1, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 103cabdff1aSopenharmony_ci 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 104cabdff1aSopenharmony_ci 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 105cabdff1aSopenharmony_ci 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 106cabdff1aSopenharmony_ci 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 107cabdff1aSopenharmony_ci 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 108cabdff1aSopenharmony_ci 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 109cabdff1aSopenharmony_ci 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 110cabdff1aSopenharmony_ci -5, -5, -5, -5, -5, -5, -5, -5, -5, -5, -5, -5, -5, -5, -5, -5, 111cabdff1aSopenharmony_ci -5, -5, -5, -5, -5, -5, -5, -5, -5, -5, -5, -5, -5, -5, -5, -5, 112cabdff1aSopenharmony_ci -5, -5, -5, -5, -5, -5, -5, -5, -5, -5, -5, -5, -5, -5, -5, -5, 113cabdff1aSopenharmony_ci -5, -5, -5, -5, -5, -5, -5, -5, -5, -5, -5, -5, -5, -5, -5, -5, 114cabdff1aSopenharmony_ci -5, -5, -5, -5, -5, -5, -5, -5, -5, -5, -5, -5, -5, -5, -5, -5, 115cabdff1aSopenharmony_ci -5, -5, -5, -5, -5, -5, -5, -5, -5, -5, -5, -5, -5, -5, -4, -4, 116cabdff1aSopenharmony_ci -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, 117cabdff1aSopenharmony_ci -4, -4, -4, -4, -4, -3, -3, -3, -3, -3, -3, -3, -2, -2, -2, -1, 118cabdff1aSopenharmony_ci}; 119cabdff1aSopenharmony_ci 120cabdff1aSopenharmony_cistatic const uint8_t ver2_state[256] = { 121cabdff1aSopenharmony_ci 0, 10, 10, 10, 10, 16, 16, 16, 28, 16, 16, 29, 42, 49, 20, 49, 122cabdff1aSopenharmony_ci 59, 25, 26, 26, 27, 31, 33, 33, 33, 34, 34, 37, 67, 38, 39, 39, 123cabdff1aSopenharmony_ci 40, 40, 41, 79, 43, 44, 45, 45, 48, 48, 64, 50, 51, 52, 88, 52, 124cabdff1aSopenharmony_ci 53, 74, 55, 57, 58, 58, 74, 60, 101, 61, 62, 84, 66, 66, 68, 69, 125cabdff1aSopenharmony_ci 87, 82, 71, 97, 73, 73, 82, 75, 111, 77, 94, 78, 87, 81, 83, 97, 126cabdff1aSopenharmony_ci 85, 83, 94, 86, 99, 89, 90, 99, 111, 92, 93, 134, 95, 98, 105, 98, 127cabdff1aSopenharmony_ci 105, 110, 102, 108, 102, 118, 103, 106, 106, 113, 109, 112, 114, 112, 116, 125, 128cabdff1aSopenharmony_ci 115, 116, 117, 117, 126, 119, 125, 121, 121, 123, 145, 124, 126, 131, 127, 129, 129cabdff1aSopenharmony_ci 165, 130, 132, 138, 133, 135, 145, 136, 137, 139, 146, 141, 143, 142, 144, 148, 130cabdff1aSopenharmony_ci 147, 155, 151, 149, 151, 150, 152, 157, 153, 154, 156, 168, 158, 162, 161, 160, 131cabdff1aSopenharmony_ci 172, 163, 169, 164, 166, 184, 167, 170, 177, 174, 171, 173, 182, 176, 180, 178, 132cabdff1aSopenharmony_ci 175, 189, 179, 181, 186, 183, 192, 185, 200, 187, 191, 188, 190, 197, 193, 196, 133cabdff1aSopenharmony_ci 197, 194, 195, 196, 198, 202, 199, 201, 210, 203, 207, 204, 205, 206, 208, 214, 134cabdff1aSopenharmony_ci 209, 211, 221, 212, 213, 215, 224, 216, 217, 218, 219, 220, 222, 228, 223, 225, 135cabdff1aSopenharmony_ci 226, 224, 227, 229, 240, 230, 231, 232, 233, 234, 235, 236, 238, 239, 237, 242, 136cabdff1aSopenharmony_ci 241, 243, 242, 244, 245, 246, 247, 248, 249, 250, 251, 252, 252, 253, 254, 255, 137cabdff1aSopenharmony_ci}; 138cabdff1aSopenharmony_ci 139cabdff1aSopenharmony_cistatic void find_best_state(uint8_t best_state[256][256], 140cabdff1aSopenharmony_ci const uint8_t one_state[256]) 141cabdff1aSopenharmony_ci{ 142cabdff1aSopenharmony_ci int i, j, k, m; 143cabdff1aSopenharmony_ci uint32_t l2tab[256]; 144cabdff1aSopenharmony_ci 145cabdff1aSopenharmony_ci for (i = 1; i < 256; i++) 146cabdff1aSopenharmony_ci l2tab[i] = -log2(i / 256.0) * ((1U << 31) / 8); 147cabdff1aSopenharmony_ci 148cabdff1aSopenharmony_ci for (i = 0; i < 256; i++) { 149cabdff1aSopenharmony_ci uint64_t best_len[256]; 150cabdff1aSopenharmony_ci 151cabdff1aSopenharmony_ci for (j = 0; j < 256; j++) 152cabdff1aSopenharmony_ci best_len[j] = UINT64_MAX; 153cabdff1aSopenharmony_ci 154cabdff1aSopenharmony_ci for (j = FFMAX(i - 10, 1); j < FFMIN(i + 11, 256); j++) { 155cabdff1aSopenharmony_ci uint32_t occ[256] = { 0 }; 156cabdff1aSopenharmony_ci uint64_t len = 0; 157cabdff1aSopenharmony_ci occ[j] = UINT32_MAX; 158cabdff1aSopenharmony_ci 159cabdff1aSopenharmony_ci if (!one_state[j]) 160cabdff1aSopenharmony_ci continue; 161cabdff1aSopenharmony_ci 162cabdff1aSopenharmony_ci for (k = 0; k < 256; k++) { 163cabdff1aSopenharmony_ci uint32_t newocc[256] = { 0 }; 164cabdff1aSopenharmony_ci for (m = 1; m < 256; m++) 165cabdff1aSopenharmony_ci if (occ[m]) { 166cabdff1aSopenharmony_ci len += (occ[m]*(( i *(uint64_t)l2tab[ m] 167cabdff1aSopenharmony_ci + (256-i)*(uint64_t)l2tab[256-m])>>8)) >> 8; 168cabdff1aSopenharmony_ci } 169cabdff1aSopenharmony_ci if (len < best_len[k]) { 170cabdff1aSopenharmony_ci best_len[k] = len; 171cabdff1aSopenharmony_ci best_state[i][k] = j; 172cabdff1aSopenharmony_ci } 173cabdff1aSopenharmony_ci for (m = 1; m < 256; m++) 174cabdff1aSopenharmony_ci if (occ[m]) { 175cabdff1aSopenharmony_ci newocc[ one_state[ m]] += occ[m] * (uint64_t) i >> 8; 176cabdff1aSopenharmony_ci newocc[256 - one_state[256 - m]] += occ[m] * (uint64_t)(256 - i) >> 8; 177cabdff1aSopenharmony_ci } 178cabdff1aSopenharmony_ci memcpy(occ, newocc, sizeof(occ)); 179cabdff1aSopenharmony_ci } 180cabdff1aSopenharmony_ci } 181cabdff1aSopenharmony_ci } 182cabdff1aSopenharmony_ci} 183cabdff1aSopenharmony_ci 184cabdff1aSopenharmony_cistatic av_always_inline av_flatten void put_symbol_inline(RangeCoder *c, 185cabdff1aSopenharmony_ci uint8_t *state, int v, 186cabdff1aSopenharmony_ci int is_signed, 187cabdff1aSopenharmony_ci uint64_t rc_stat[256][2], 188cabdff1aSopenharmony_ci uint64_t rc_stat2[32][2]) 189cabdff1aSopenharmony_ci{ 190cabdff1aSopenharmony_ci int i; 191cabdff1aSopenharmony_ci 192cabdff1aSopenharmony_ci#define put_rac(C, S, B) \ 193cabdff1aSopenharmony_ci do { \ 194cabdff1aSopenharmony_ci if (rc_stat) { \ 195cabdff1aSopenharmony_ci rc_stat[*(S)][B]++; \ 196cabdff1aSopenharmony_ci rc_stat2[(S) - state][B]++; \ 197cabdff1aSopenharmony_ci } \ 198cabdff1aSopenharmony_ci put_rac(C, S, B); \ 199cabdff1aSopenharmony_ci } while (0) 200cabdff1aSopenharmony_ci 201cabdff1aSopenharmony_ci if (v) { 202cabdff1aSopenharmony_ci const int a = FFABS(v); 203cabdff1aSopenharmony_ci const int e = av_log2(a); 204cabdff1aSopenharmony_ci put_rac(c, state + 0, 0); 205cabdff1aSopenharmony_ci if (e <= 9) { 206cabdff1aSopenharmony_ci for (i = 0; i < e; i++) 207cabdff1aSopenharmony_ci put_rac(c, state + 1 + i, 1); // 1..10 208cabdff1aSopenharmony_ci put_rac(c, state + 1 + i, 0); 209cabdff1aSopenharmony_ci 210cabdff1aSopenharmony_ci for (i = e - 1; i >= 0; i--) 211cabdff1aSopenharmony_ci put_rac(c, state + 22 + i, (a >> i) & 1); // 22..31 212cabdff1aSopenharmony_ci 213cabdff1aSopenharmony_ci if (is_signed) 214cabdff1aSopenharmony_ci put_rac(c, state + 11 + e, v < 0); // 11..21 215cabdff1aSopenharmony_ci } else { 216cabdff1aSopenharmony_ci for (i = 0; i < e; i++) 217cabdff1aSopenharmony_ci put_rac(c, state + 1 + FFMIN(i, 9), 1); // 1..10 218cabdff1aSopenharmony_ci put_rac(c, state + 1 + 9, 0); 219cabdff1aSopenharmony_ci 220cabdff1aSopenharmony_ci for (i = e - 1; i >= 0; i--) 221cabdff1aSopenharmony_ci put_rac(c, state + 22 + FFMIN(i, 9), (a >> i) & 1); // 22..31 222cabdff1aSopenharmony_ci 223cabdff1aSopenharmony_ci if (is_signed) 224cabdff1aSopenharmony_ci put_rac(c, state + 11 + 10, v < 0); // 11..21 225cabdff1aSopenharmony_ci } 226cabdff1aSopenharmony_ci } else { 227cabdff1aSopenharmony_ci put_rac(c, state + 0, 1); 228cabdff1aSopenharmony_ci } 229cabdff1aSopenharmony_ci#undef put_rac 230cabdff1aSopenharmony_ci} 231cabdff1aSopenharmony_ci 232cabdff1aSopenharmony_cistatic av_noinline void put_symbol(RangeCoder *c, uint8_t *state, 233cabdff1aSopenharmony_ci int v, int is_signed) 234cabdff1aSopenharmony_ci{ 235cabdff1aSopenharmony_ci put_symbol_inline(c, state, v, is_signed, NULL, NULL); 236cabdff1aSopenharmony_ci} 237cabdff1aSopenharmony_ci 238cabdff1aSopenharmony_ci 239cabdff1aSopenharmony_cistatic inline void put_vlc_symbol(PutBitContext *pb, VlcState *const state, 240cabdff1aSopenharmony_ci int v, int bits) 241cabdff1aSopenharmony_ci{ 242cabdff1aSopenharmony_ci int i, k, code; 243cabdff1aSopenharmony_ci v = fold(v - state->bias, bits); 244cabdff1aSopenharmony_ci 245cabdff1aSopenharmony_ci i = state->count; 246cabdff1aSopenharmony_ci k = 0; 247cabdff1aSopenharmony_ci while (i < state->error_sum) { // FIXME: optimize 248cabdff1aSopenharmony_ci k++; 249cabdff1aSopenharmony_ci i += i; 250cabdff1aSopenharmony_ci } 251cabdff1aSopenharmony_ci 252cabdff1aSopenharmony_ci av_assert2(k <= 13); 253cabdff1aSopenharmony_ci 254cabdff1aSopenharmony_ci code = v ^ ((2 * state->drift + state->count) >> 31); 255cabdff1aSopenharmony_ci 256cabdff1aSopenharmony_ci ff_dlog(NULL, "v:%d/%d bias:%d error:%d drift:%d count:%d k:%d\n", v, code, 257cabdff1aSopenharmony_ci state->bias, state->error_sum, state->drift, state->count, k); 258cabdff1aSopenharmony_ci set_sr_golomb(pb, code, k, 12, bits); 259cabdff1aSopenharmony_ci 260cabdff1aSopenharmony_ci update_vlc_state(state, v); 261cabdff1aSopenharmony_ci} 262cabdff1aSopenharmony_ci 263cabdff1aSopenharmony_ci#define TYPE int16_t 264cabdff1aSopenharmony_ci#define RENAME(name) name 265cabdff1aSopenharmony_ci#include "ffv1enc_template.c" 266cabdff1aSopenharmony_ci#undef TYPE 267cabdff1aSopenharmony_ci#undef RENAME 268cabdff1aSopenharmony_ci 269cabdff1aSopenharmony_ci#define TYPE int32_t 270cabdff1aSopenharmony_ci#define RENAME(name) name ## 32 271cabdff1aSopenharmony_ci#include "ffv1enc_template.c" 272cabdff1aSopenharmony_ci 273cabdff1aSopenharmony_cistatic int encode_plane(FFV1Context *s, uint8_t *src, int w, int h, 274cabdff1aSopenharmony_ci int stride, int plane_index, int pixel_stride) 275cabdff1aSopenharmony_ci{ 276cabdff1aSopenharmony_ci int x, y, i, ret; 277cabdff1aSopenharmony_ci const int ring_size = s->context_model ? 3 : 2; 278cabdff1aSopenharmony_ci int16_t *sample[3]; 279cabdff1aSopenharmony_ci s->run_index = 0; 280cabdff1aSopenharmony_ci 281cabdff1aSopenharmony_ci memset(s->sample_buffer, 0, ring_size * (w + 6) * sizeof(*s->sample_buffer)); 282cabdff1aSopenharmony_ci 283cabdff1aSopenharmony_ci for (y = 0; y < h; y++) { 284cabdff1aSopenharmony_ci for (i = 0; i < ring_size; i++) 285cabdff1aSopenharmony_ci sample[i] = s->sample_buffer + (w + 6) * ((h + i - y) % ring_size) + 3; 286cabdff1aSopenharmony_ci 287cabdff1aSopenharmony_ci sample[0][-1]= sample[1][0 ]; 288cabdff1aSopenharmony_ci sample[1][ w]= sample[1][w-1]; 289cabdff1aSopenharmony_ci if (s->bits_per_raw_sample <= 8) { 290cabdff1aSopenharmony_ci for (x = 0; x < w; x++) 291cabdff1aSopenharmony_ci sample[0][x] = src[x * pixel_stride + stride * y]; 292cabdff1aSopenharmony_ci if((ret = encode_line(s, w, sample, plane_index, 8)) < 0) 293cabdff1aSopenharmony_ci return ret; 294cabdff1aSopenharmony_ci } else { 295cabdff1aSopenharmony_ci if (s->packed_at_lsb) { 296cabdff1aSopenharmony_ci for (x = 0; x < w; x++) { 297cabdff1aSopenharmony_ci sample[0][x] = ((uint16_t*)(src + stride*y))[x]; 298cabdff1aSopenharmony_ci } 299cabdff1aSopenharmony_ci } else { 300cabdff1aSopenharmony_ci for (x = 0; x < w; x++) { 301cabdff1aSopenharmony_ci sample[0][x] = ((uint16_t*)(src + stride*y))[x] >> (16 - s->bits_per_raw_sample); 302cabdff1aSopenharmony_ci } 303cabdff1aSopenharmony_ci } 304cabdff1aSopenharmony_ci if((ret = encode_line(s, w, sample, plane_index, s->bits_per_raw_sample)) < 0) 305cabdff1aSopenharmony_ci return ret; 306cabdff1aSopenharmony_ci } 307cabdff1aSopenharmony_ci } 308cabdff1aSopenharmony_ci return 0; 309cabdff1aSopenharmony_ci} 310cabdff1aSopenharmony_ci 311cabdff1aSopenharmony_cistatic void write_quant_table(RangeCoder *c, int16_t *quant_table) 312cabdff1aSopenharmony_ci{ 313cabdff1aSopenharmony_ci int last = 0; 314cabdff1aSopenharmony_ci int i; 315cabdff1aSopenharmony_ci uint8_t state[CONTEXT_SIZE]; 316cabdff1aSopenharmony_ci memset(state, 128, sizeof(state)); 317cabdff1aSopenharmony_ci 318cabdff1aSopenharmony_ci for (i = 1; i < 128; i++) 319cabdff1aSopenharmony_ci if (quant_table[i] != quant_table[i - 1]) { 320cabdff1aSopenharmony_ci put_symbol(c, state, i - last - 1, 0); 321cabdff1aSopenharmony_ci last = i; 322cabdff1aSopenharmony_ci } 323cabdff1aSopenharmony_ci put_symbol(c, state, i - last - 1, 0); 324cabdff1aSopenharmony_ci} 325cabdff1aSopenharmony_ci 326cabdff1aSopenharmony_cistatic void write_quant_tables(RangeCoder *c, 327cabdff1aSopenharmony_ci int16_t quant_table[MAX_CONTEXT_INPUTS][256]) 328cabdff1aSopenharmony_ci{ 329cabdff1aSopenharmony_ci int i; 330cabdff1aSopenharmony_ci for (i = 0; i < 5; i++) 331cabdff1aSopenharmony_ci write_quant_table(c, quant_table[i]); 332cabdff1aSopenharmony_ci} 333cabdff1aSopenharmony_ci 334cabdff1aSopenharmony_cistatic int contains_non_128(uint8_t (*initial_state)[CONTEXT_SIZE], 335cabdff1aSopenharmony_ci int nb_contexts) 336cabdff1aSopenharmony_ci{ 337cabdff1aSopenharmony_ci if (!initial_state) 338cabdff1aSopenharmony_ci return 0; 339cabdff1aSopenharmony_ci for (int i = 0; i < nb_contexts; i++) 340cabdff1aSopenharmony_ci for (int j = 0; j < CONTEXT_SIZE; j++) 341cabdff1aSopenharmony_ci if (initial_state[i][j] != 128) 342cabdff1aSopenharmony_ci return 1; 343cabdff1aSopenharmony_ci return 0; 344cabdff1aSopenharmony_ci} 345cabdff1aSopenharmony_ci 346cabdff1aSopenharmony_cistatic void write_header(FFV1Context *f) 347cabdff1aSopenharmony_ci{ 348cabdff1aSopenharmony_ci uint8_t state[CONTEXT_SIZE]; 349cabdff1aSopenharmony_ci int i, j; 350cabdff1aSopenharmony_ci RangeCoder *const c = &f->slice_context[0]->c; 351cabdff1aSopenharmony_ci 352cabdff1aSopenharmony_ci memset(state, 128, sizeof(state)); 353cabdff1aSopenharmony_ci 354cabdff1aSopenharmony_ci if (f->version < 2) { 355cabdff1aSopenharmony_ci put_symbol(c, state, f->version, 0); 356cabdff1aSopenharmony_ci put_symbol(c, state, f->ac, 0); 357cabdff1aSopenharmony_ci if (f->ac == AC_RANGE_CUSTOM_TAB) { 358cabdff1aSopenharmony_ci for (i = 1; i < 256; i++) 359cabdff1aSopenharmony_ci put_symbol(c, state, 360cabdff1aSopenharmony_ci f->state_transition[i] - c->one_state[i], 1); 361cabdff1aSopenharmony_ci } 362cabdff1aSopenharmony_ci put_symbol(c, state, f->colorspace, 0); //YUV cs type 363cabdff1aSopenharmony_ci if (f->version > 0) 364cabdff1aSopenharmony_ci put_symbol(c, state, f->bits_per_raw_sample, 0); 365cabdff1aSopenharmony_ci put_rac(c, state, f->chroma_planes); 366cabdff1aSopenharmony_ci put_symbol(c, state, f->chroma_h_shift, 0); 367cabdff1aSopenharmony_ci put_symbol(c, state, f->chroma_v_shift, 0); 368cabdff1aSopenharmony_ci put_rac(c, state, f->transparency); 369cabdff1aSopenharmony_ci 370cabdff1aSopenharmony_ci write_quant_tables(c, f->quant_table); 371cabdff1aSopenharmony_ci } else if (f->version < 3) { 372cabdff1aSopenharmony_ci put_symbol(c, state, f->slice_count, 0); 373cabdff1aSopenharmony_ci for (i = 0; i < f->slice_count; i++) { 374cabdff1aSopenharmony_ci FFV1Context *fs = f->slice_context[i]; 375cabdff1aSopenharmony_ci put_symbol(c, state, 376cabdff1aSopenharmony_ci (fs->slice_x + 1) * f->num_h_slices / f->width, 0); 377cabdff1aSopenharmony_ci put_symbol(c, state, 378cabdff1aSopenharmony_ci (fs->slice_y + 1) * f->num_v_slices / f->height, 0); 379cabdff1aSopenharmony_ci put_symbol(c, state, 380cabdff1aSopenharmony_ci (fs->slice_width + 1) * f->num_h_slices / f->width - 1, 381cabdff1aSopenharmony_ci 0); 382cabdff1aSopenharmony_ci put_symbol(c, state, 383cabdff1aSopenharmony_ci (fs->slice_height + 1) * f->num_v_slices / f->height - 1, 384cabdff1aSopenharmony_ci 0); 385cabdff1aSopenharmony_ci for (j = 0; j < f->plane_count; j++) { 386cabdff1aSopenharmony_ci put_symbol(c, state, f->plane[j].quant_table_index, 0); 387cabdff1aSopenharmony_ci av_assert0(f->plane[j].quant_table_index == f->context_model); 388cabdff1aSopenharmony_ci } 389cabdff1aSopenharmony_ci } 390cabdff1aSopenharmony_ci } 391cabdff1aSopenharmony_ci} 392cabdff1aSopenharmony_ci 393cabdff1aSopenharmony_cistatic int write_extradata(FFV1Context *f) 394cabdff1aSopenharmony_ci{ 395cabdff1aSopenharmony_ci RangeCoder *const c = &f->c; 396cabdff1aSopenharmony_ci uint8_t state[CONTEXT_SIZE]; 397cabdff1aSopenharmony_ci int i, j, k; 398cabdff1aSopenharmony_ci uint8_t state2[32][CONTEXT_SIZE]; 399cabdff1aSopenharmony_ci unsigned v; 400cabdff1aSopenharmony_ci 401cabdff1aSopenharmony_ci memset(state2, 128, sizeof(state2)); 402cabdff1aSopenharmony_ci memset(state, 128, sizeof(state)); 403cabdff1aSopenharmony_ci 404cabdff1aSopenharmony_ci f->avctx->extradata_size = 10000 + 4 + 405cabdff1aSopenharmony_ci (11 * 11 * 5 * 5 * 5 + 11 * 11 * 11) * 32; 406cabdff1aSopenharmony_ci f->avctx->extradata = av_malloc(f->avctx->extradata_size + AV_INPUT_BUFFER_PADDING_SIZE); 407cabdff1aSopenharmony_ci if (!f->avctx->extradata) 408cabdff1aSopenharmony_ci return AVERROR(ENOMEM); 409cabdff1aSopenharmony_ci ff_init_range_encoder(c, f->avctx->extradata, f->avctx->extradata_size); 410cabdff1aSopenharmony_ci ff_build_rac_states(c, 0.05 * (1LL << 32), 256 - 8); 411cabdff1aSopenharmony_ci 412cabdff1aSopenharmony_ci put_symbol(c, state, f->version, 0); 413cabdff1aSopenharmony_ci if (f->version > 2) { 414cabdff1aSopenharmony_ci if (f->version == 3) { 415cabdff1aSopenharmony_ci f->micro_version = 4; 416cabdff1aSopenharmony_ci } else if (f->version == 4) 417cabdff1aSopenharmony_ci f->micro_version = 2; 418cabdff1aSopenharmony_ci put_symbol(c, state, f->micro_version, 0); 419cabdff1aSopenharmony_ci } 420cabdff1aSopenharmony_ci 421cabdff1aSopenharmony_ci put_symbol(c, state, f->ac, 0); 422cabdff1aSopenharmony_ci if (f->ac == AC_RANGE_CUSTOM_TAB) 423cabdff1aSopenharmony_ci for (i = 1; i < 256; i++) 424cabdff1aSopenharmony_ci put_symbol(c, state, f->state_transition[i] - c->one_state[i], 1); 425cabdff1aSopenharmony_ci 426cabdff1aSopenharmony_ci put_symbol(c, state, f->colorspace, 0); // YUV cs type 427cabdff1aSopenharmony_ci put_symbol(c, state, f->bits_per_raw_sample, 0); 428cabdff1aSopenharmony_ci put_rac(c, state, f->chroma_planes); 429cabdff1aSopenharmony_ci put_symbol(c, state, f->chroma_h_shift, 0); 430cabdff1aSopenharmony_ci put_symbol(c, state, f->chroma_v_shift, 0); 431cabdff1aSopenharmony_ci put_rac(c, state, f->transparency); 432cabdff1aSopenharmony_ci put_symbol(c, state, f->num_h_slices - 1, 0); 433cabdff1aSopenharmony_ci put_symbol(c, state, f->num_v_slices - 1, 0); 434cabdff1aSopenharmony_ci 435cabdff1aSopenharmony_ci put_symbol(c, state, f->quant_table_count, 0); 436cabdff1aSopenharmony_ci for (i = 0; i < f->quant_table_count; i++) 437cabdff1aSopenharmony_ci write_quant_tables(c, f->quant_tables[i]); 438cabdff1aSopenharmony_ci 439cabdff1aSopenharmony_ci for (i = 0; i < f->quant_table_count; i++) { 440cabdff1aSopenharmony_ci if (contains_non_128(f->initial_states[i], f->context_count[i])) { 441cabdff1aSopenharmony_ci put_rac(c, state, 1); 442cabdff1aSopenharmony_ci for (j = 0; j < f->context_count[i]; j++) 443cabdff1aSopenharmony_ci for (k = 0; k < CONTEXT_SIZE; k++) { 444cabdff1aSopenharmony_ci int pred = j ? f->initial_states[i][j - 1][k] : 128; 445cabdff1aSopenharmony_ci put_symbol(c, state2[k], 446cabdff1aSopenharmony_ci (int8_t)(f->initial_states[i][j][k] - pred), 1); 447cabdff1aSopenharmony_ci } 448cabdff1aSopenharmony_ci } else { 449cabdff1aSopenharmony_ci put_rac(c, state, 0); 450cabdff1aSopenharmony_ci } 451cabdff1aSopenharmony_ci } 452cabdff1aSopenharmony_ci 453cabdff1aSopenharmony_ci if (f->version > 2) { 454cabdff1aSopenharmony_ci put_symbol(c, state, f->ec, 0); 455cabdff1aSopenharmony_ci put_symbol(c, state, f->intra = (f->avctx->gop_size < 2), 0); 456cabdff1aSopenharmony_ci } 457cabdff1aSopenharmony_ci 458cabdff1aSopenharmony_ci f->avctx->extradata_size = ff_rac_terminate(c, 0); 459cabdff1aSopenharmony_ci v = av_crc(av_crc_get_table(AV_CRC_32_IEEE), 0, f->avctx->extradata, f->avctx->extradata_size); 460cabdff1aSopenharmony_ci AV_WL32(f->avctx->extradata + f->avctx->extradata_size, v); 461cabdff1aSopenharmony_ci f->avctx->extradata_size += 4; 462cabdff1aSopenharmony_ci 463cabdff1aSopenharmony_ci return 0; 464cabdff1aSopenharmony_ci} 465cabdff1aSopenharmony_ci 466cabdff1aSopenharmony_cistatic int sort_stt(FFV1Context *s, uint8_t stt[256]) 467cabdff1aSopenharmony_ci{ 468cabdff1aSopenharmony_ci int i, i2, changed, print = 0; 469cabdff1aSopenharmony_ci 470cabdff1aSopenharmony_ci do { 471cabdff1aSopenharmony_ci changed = 0; 472cabdff1aSopenharmony_ci for (i = 12; i < 244; i++) { 473cabdff1aSopenharmony_ci for (i2 = i + 1; i2 < 245 && i2 < i + 4; i2++) { 474cabdff1aSopenharmony_ci 475cabdff1aSopenharmony_ci#define COST(old, new) \ 476cabdff1aSopenharmony_ci s->rc_stat[old][0] * -log2((256 - (new)) / 256.0) + \ 477cabdff1aSopenharmony_ci s->rc_stat[old][1] * -log2((new) / 256.0) 478cabdff1aSopenharmony_ci 479cabdff1aSopenharmony_ci#define COST2(old, new) \ 480cabdff1aSopenharmony_ci COST(old, new) + COST(256 - (old), 256 - (new)) 481cabdff1aSopenharmony_ci 482cabdff1aSopenharmony_ci double size0 = COST2(i, i) + COST2(i2, i2); 483cabdff1aSopenharmony_ci double sizeX = COST2(i, i2) + COST2(i2, i); 484cabdff1aSopenharmony_ci if (size0 - sizeX > size0*(1e-14) && i != 128 && i2 != 128) { 485cabdff1aSopenharmony_ci int j; 486cabdff1aSopenharmony_ci FFSWAP(int, stt[i], stt[i2]); 487cabdff1aSopenharmony_ci FFSWAP(int, s->rc_stat[i][0], s->rc_stat[i2][0]); 488cabdff1aSopenharmony_ci FFSWAP(int, s->rc_stat[i][1], s->rc_stat[i2][1]); 489cabdff1aSopenharmony_ci if (i != 256 - i2) { 490cabdff1aSopenharmony_ci FFSWAP(int, stt[256 - i], stt[256 - i2]); 491cabdff1aSopenharmony_ci FFSWAP(int, s->rc_stat[256 - i][0], s->rc_stat[256 - i2][0]); 492cabdff1aSopenharmony_ci FFSWAP(int, s->rc_stat[256 - i][1], s->rc_stat[256 - i2][1]); 493cabdff1aSopenharmony_ci } 494cabdff1aSopenharmony_ci for (j = 1; j < 256; j++) { 495cabdff1aSopenharmony_ci if (stt[j] == i) 496cabdff1aSopenharmony_ci stt[j] = i2; 497cabdff1aSopenharmony_ci else if (stt[j] == i2) 498cabdff1aSopenharmony_ci stt[j] = i; 499cabdff1aSopenharmony_ci if (i != 256 - i2) { 500cabdff1aSopenharmony_ci if (stt[256 - j] == 256 - i) 501cabdff1aSopenharmony_ci stt[256 - j] = 256 - i2; 502cabdff1aSopenharmony_ci else if (stt[256 - j] == 256 - i2) 503cabdff1aSopenharmony_ci stt[256 - j] = 256 - i; 504cabdff1aSopenharmony_ci } 505cabdff1aSopenharmony_ci } 506cabdff1aSopenharmony_ci print = changed = 1; 507cabdff1aSopenharmony_ci } 508cabdff1aSopenharmony_ci } 509cabdff1aSopenharmony_ci } 510cabdff1aSopenharmony_ci } while (changed); 511cabdff1aSopenharmony_ci return print; 512cabdff1aSopenharmony_ci} 513cabdff1aSopenharmony_ci 514cabdff1aSopenharmony_cistatic av_cold int encode_init(AVCodecContext *avctx) 515cabdff1aSopenharmony_ci{ 516cabdff1aSopenharmony_ci FFV1Context *s = avctx->priv_data; 517cabdff1aSopenharmony_ci const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt); 518cabdff1aSopenharmony_ci int i, j, k, m, ret; 519cabdff1aSopenharmony_ci 520cabdff1aSopenharmony_ci if ((ret = ff_ffv1_common_init(avctx)) < 0) 521cabdff1aSopenharmony_ci return ret; 522cabdff1aSopenharmony_ci 523cabdff1aSopenharmony_ci s->version = 0; 524cabdff1aSopenharmony_ci 525cabdff1aSopenharmony_ci if ((avctx->flags & (AV_CODEC_FLAG_PASS1 | AV_CODEC_FLAG_PASS2)) || 526cabdff1aSopenharmony_ci avctx->slices > 1) 527cabdff1aSopenharmony_ci s->version = FFMAX(s->version, 2); 528cabdff1aSopenharmony_ci 529cabdff1aSopenharmony_ci // Unspecified level & slices, we choose version 1.2+ to ensure multithreaded decodability 530cabdff1aSopenharmony_ci if (avctx->slices == 0 && avctx->level < 0 && avctx->width * avctx->height > 720*576) 531cabdff1aSopenharmony_ci s->version = FFMAX(s->version, 2); 532cabdff1aSopenharmony_ci 533cabdff1aSopenharmony_ci if (avctx->level <= 0 && s->version == 2) { 534cabdff1aSopenharmony_ci s->version = 3; 535cabdff1aSopenharmony_ci } 536cabdff1aSopenharmony_ci if (avctx->level >= 0 && avctx->level <= 4) { 537cabdff1aSopenharmony_ci if (avctx->level < s->version) { 538cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, "Version %d needed for requested features but %d requested\n", s->version, avctx->level); 539cabdff1aSopenharmony_ci return AVERROR(EINVAL); 540cabdff1aSopenharmony_ci } 541cabdff1aSopenharmony_ci s->version = avctx->level; 542cabdff1aSopenharmony_ci } 543cabdff1aSopenharmony_ci 544cabdff1aSopenharmony_ci if (s->ec < 0) { 545cabdff1aSopenharmony_ci s->ec = (s->version >= 3); 546cabdff1aSopenharmony_ci } 547cabdff1aSopenharmony_ci 548cabdff1aSopenharmony_ci // CRC requires version 3+ 549cabdff1aSopenharmony_ci if (s->ec) 550cabdff1aSopenharmony_ci s->version = FFMAX(s->version, 3); 551cabdff1aSopenharmony_ci 552cabdff1aSopenharmony_ci if ((s->version == 2 || s->version>3) && avctx->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL) { 553cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, "Version 2 needed for requested features but version 2 is experimental and not enabled\n"); 554cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 555cabdff1aSopenharmony_ci } 556cabdff1aSopenharmony_ci 557cabdff1aSopenharmony_ci if (s->ac == 1) // Compatbility with common command line usage 558cabdff1aSopenharmony_ci s->ac = AC_RANGE_CUSTOM_TAB; 559cabdff1aSopenharmony_ci else if (s->ac == AC_RANGE_DEFAULT_TAB_FORCE) 560cabdff1aSopenharmony_ci s->ac = AC_RANGE_DEFAULT_TAB; 561cabdff1aSopenharmony_ci 562cabdff1aSopenharmony_ci s->plane_count = 3; 563cabdff1aSopenharmony_ci switch(avctx->pix_fmt) { 564cabdff1aSopenharmony_ci case AV_PIX_FMT_GRAY9: 565cabdff1aSopenharmony_ci case AV_PIX_FMT_YUV444P9: 566cabdff1aSopenharmony_ci case AV_PIX_FMT_YUV422P9: 567cabdff1aSopenharmony_ci case AV_PIX_FMT_YUV420P9: 568cabdff1aSopenharmony_ci case AV_PIX_FMT_YUVA444P9: 569cabdff1aSopenharmony_ci case AV_PIX_FMT_YUVA422P9: 570cabdff1aSopenharmony_ci case AV_PIX_FMT_YUVA420P9: 571cabdff1aSopenharmony_ci if (!avctx->bits_per_raw_sample) 572cabdff1aSopenharmony_ci s->bits_per_raw_sample = 9; 573cabdff1aSopenharmony_ci case AV_PIX_FMT_GRAY10: 574cabdff1aSopenharmony_ci case AV_PIX_FMT_YUV444P10: 575cabdff1aSopenharmony_ci case AV_PIX_FMT_YUV440P10: 576cabdff1aSopenharmony_ci case AV_PIX_FMT_YUV420P10: 577cabdff1aSopenharmony_ci case AV_PIX_FMT_YUV422P10: 578cabdff1aSopenharmony_ci case AV_PIX_FMT_YUVA444P10: 579cabdff1aSopenharmony_ci case AV_PIX_FMT_YUVA422P10: 580cabdff1aSopenharmony_ci case AV_PIX_FMT_YUVA420P10: 581cabdff1aSopenharmony_ci if (!avctx->bits_per_raw_sample && !s->bits_per_raw_sample) 582cabdff1aSopenharmony_ci s->bits_per_raw_sample = 10; 583cabdff1aSopenharmony_ci case AV_PIX_FMT_GRAY12: 584cabdff1aSopenharmony_ci case AV_PIX_FMT_YUV444P12: 585cabdff1aSopenharmony_ci case AV_PIX_FMT_YUV440P12: 586cabdff1aSopenharmony_ci case AV_PIX_FMT_YUV420P12: 587cabdff1aSopenharmony_ci case AV_PIX_FMT_YUV422P12: 588cabdff1aSopenharmony_ci if (!avctx->bits_per_raw_sample && !s->bits_per_raw_sample) 589cabdff1aSopenharmony_ci s->bits_per_raw_sample = 12; 590cabdff1aSopenharmony_ci case AV_PIX_FMT_YUV444P14: 591cabdff1aSopenharmony_ci case AV_PIX_FMT_YUV420P14: 592cabdff1aSopenharmony_ci case AV_PIX_FMT_YUV422P14: 593cabdff1aSopenharmony_ci if (!avctx->bits_per_raw_sample && !s->bits_per_raw_sample) 594cabdff1aSopenharmony_ci s->bits_per_raw_sample = 14; 595cabdff1aSopenharmony_ci s->packed_at_lsb = 1; 596cabdff1aSopenharmony_ci case AV_PIX_FMT_GRAY16: 597cabdff1aSopenharmony_ci case AV_PIX_FMT_YUV444P16: 598cabdff1aSopenharmony_ci case AV_PIX_FMT_YUV422P16: 599cabdff1aSopenharmony_ci case AV_PIX_FMT_YUV420P16: 600cabdff1aSopenharmony_ci case AV_PIX_FMT_YUVA444P16: 601cabdff1aSopenharmony_ci case AV_PIX_FMT_YUVA422P16: 602cabdff1aSopenharmony_ci case AV_PIX_FMT_YUVA420P16: 603cabdff1aSopenharmony_ci if (!avctx->bits_per_raw_sample && !s->bits_per_raw_sample) { 604cabdff1aSopenharmony_ci s->bits_per_raw_sample = 16; 605cabdff1aSopenharmony_ci } else if (!s->bits_per_raw_sample) { 606cabdff1aSopenharmony_ci s->bits_per_raw_sample = avctx->bits_per_raw_sample; 607cabdff1aSopenharmony_ci } 608cabdff1aSopenharmony_ci if (s->bits_per_raw_sample <= 8) { 609cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, "bits_per_raw_sample invalid\n"); 610cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 611cabdff1aSopenharmony_ci } 612cabdff1aSopenharmony_ci s->version = FFMAX(s->version, 1); 613cabdff1aSopenharmony_ci case AV_PIX_FMT_GRAY8: 614cabdff1aSopenharmony_ci case AV_PIX_FMT_YA8: 615cabdff1aSopenharmony_ci case AV_PIX_FMT_YUV444P: 616cabdff1aSopenharmony_ci case AV_PIX_FMT_YUV440P: 617cabdff1aSopenharmony_ci case AV_PIX_FMT_YUV422P: 618cabdff1aSopenharmony_ci case AV_PIX_FMT_YUV420P: 619cabdff1aSopenharmony_ci case AV_PIX_FMT_YUV411P: 620cabdff1aSopenharmony_ci case AV_PIX_FMT_YUV410P: 621cabdff1aSopenharmony_ci case AV_PIX_FMT_YUVA444P: 622cabdff1aSopenharmony_ci case AV_PIX_FMT_YUVA422P: 623cabdff1aSopenharmony_ci case AV_PIX_FMT_YUVA420P: 624cabdff1aSopenharmony_ci s->chroma_planes = desc->nb_components < 3 ? 0 : 1; 625cabdff1aSopenharmony_ci s->colorspace = 0; 626cabdff1aSopenharmony_ci s->transparency = !!(desc->flags & AV_PIX_FMT_FLAG_ALPHA); 627cabdff1aSopenharmony_ci if (!avctx->bits_per_raw_sample && !s->bits_per_raw_sample) 628cabdff1aSopenharmony_ci s->bits_per_raw_sample = 8; 629cabdff1aSopenharmony_ci else if (!s->bits_per_raw_sample) 630cabdff1aSopenharmony_ci s->bits_per_raw_sample = 8; 631cabdff1aSopenharmony_ci break; 632cabdff1aSopenharmony_ci case AV_PIX_FMT_RGB32: 633cabdff1aSopenharmony_ci s->colorspace = 1; 634cabdff1aSopenharmony_ci s->transparency = 1; 635cabdff1aSopenharmony_ci s->chroma_planes = 1; 636cabdff1aSopenharmony_ci s->bits_per_raw_sample = 8; 637cabdff1aSopenharmony_ci break; 638cabdff1aSopenharmony_ci case AV_PIX_FMT_RGBA64: 639cabdff1aSopenharmony_ci s->colorspace = 1; 640cabdff1aSopenharmony_ci s->transparency = 1; 641cabdff1aSopenharmony_ci s->chroma_planes = 1; 642cabdff1aSopenharmony_ci s->bits_per_raw_sample = 16; 643cabdff1aSopenharmony_ci s->use32bit = 1; 644cabdff1aSopenharmony_ci s->version = FFMAX(s->version, 1); 645cabdff1aSopenharmony_ci break; 646cabdff1aSopenharmony_ci case AV_PIX_FMT_RGB48: 647cabdff1aSopenharmony_ci s->colorspace = 1; 648cabdff1aSopenharmony_ci s->chroma_planes = 1; 649cabdff1aSopenharmony_ci s->bits_per_raw_sample = 16; 650cabdff1aSopenharmony_ci s->use32bit = 1; 651cabdff1aSopenharmony_ci s->version = FFMAX(s->version, 1); 652cabdff1aSopenharmony_ci break; 653cabdff1aSopenharmony_ci case AV_PIX_FMT_0RGB32: 654cabdff1aSopenharmony_ci s->colorspace = 1; 655cabdff1aSopenharmony_ci s->chroma_planes = 1; 656cabdff1aSopenharmony_ci s->bits_per_raw_sample = 8; 657cabdff1aSopenharmony_ci break; 658cabdff1aSopenharmony_ci case AV_PIX_FMT_GBRP9: 659cabdff1aSopenharmony_ci if (!avctx->bits_per_raw_sample) 660cabdff1aSopenharmony_ci s->bits_per_raw_sample = 9; 661cabdff1aSopenharmony_ci case AV_PIX_FMT_GBRP10: 662cabdff1aSopenharmony_ci case AV_PIX_FMT_GBRAP10: 663cabdff1aSopenharmony_ci if (!avctx->bits_per_raw_sample && !s->bits_per_raw_sample) 664cabdff1aSopenharmony_ci s->bits_per_raw_sample = 10; 665cabdff1aSopenharmony_ci case AV_PIX_FMT_GBRP12: 666cabdff1aSopenharmony_ci case AV_PIX_FMT_GBRAP12: 667cabdff1aSopenharmony_ci if (!avctx->bits_per_raw_sample && !s->bits_per_raw_sample) 668cabdff1aSopenharmony_ci s->bits_per_raw_sample = 12; 669cabdff1aSopenharmony_ci case AV_PIX_FMT_GBRP14: 670cabdff1aSopenharmony_ci if (!avctx->bits_per_raw_sample && !s->bits_per_raw_sample) 671cabdff1aSopenharmony_ci s->bits_per_raw_sample = 14; 672cabdff1aSopenharmony_ci case AV_PIX_FMT_GBRP16: 673cabdff1aSopenharmony_ci case AV_PIX_FMT_GBRAP16: 674cabdff1aSopenharmony_ci if (!avctx->bits_per_raw_sample && !s->bits_per_raw_sample) 675cabdff1aSopenharmony_ci s->bits_per_raw_sample = 16; 676cabdff1aSopenharmony_ci else if (!s->bits_per_raw_sample) 677cabdff1aSopenharmony_ci s->bits_per_raw_sample = avctx->bits_per_raw_sample; 678cabdff1aSopenharmony_ci s->transparency = !!(desc->flags & AV_PIX_FMT_FLAG_ALPHA); 679cabdff1aSopenharmony_ci s->colorspace = 1; 680cabdff1aSopenharmony_ci s->chroma_planes = 1; 681cabdff1aSopenharmony_ci if (s->bits_per_raw_sample >= 16) { 682cabdff1aSopenharmony_ci s->use32bit = 1; 683cabdff1aSopenharmony_ci } 684cabdff1aSopenharmony_ci s->version = FFMAX(s->version, 1); 685cabdff1aSopenharmony_ci break; 686cabdff1aSopenharmony_ci default: 687cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, "format not supported\n"); 688cabdff1aSopenharmony_ci return AVERROR(ENOSYS); 689cabdff1aSopenharmony_ci } 690cabdff1aSopenharmony_ci av_assert0(s->bits_per_raw_sample >= 8); 691cabdff1aSopenharmony_ci 692cabdff1aSopenharmony_ci if (s->bits_per_raw_sample > 8) { 693cabdff1aSopenharmony_ci if (s->ac == AC_GOLOMB_RICE) { 694cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_INFO, 695cabdff1aSopenharmony_ci "bits_per_raw_sample > 8, forcing range coder\n"); 696cabdff1aSopenharmony_ci s->ac = AC_RANGE_CUSTOM_TAB; 697cabdff1aSopenharmony_ci } 698cabdff1aSopenharmony_ci } 699cabdff1aSopenharmony_ci 700cabdff1aSopenharmony_ci if (s->ac == AC_RANGE_CUSTOM_TAB) { 701cabdff1aSopenharmony_ci for (i = 1; i < 256; i++) 702cabdff1aSopenharmony_ci s->state_transition[i] = ver2_state[i]; 703cabdff1aSopenharmony_ci } else { 704cabdff1aSopenharmony_ci RangeCoder c; 705cabdff1aSopenharmony_ci ff_build_rac_states(&c, 0.05 * (1LL << 32), 256 - 8); 706cabdff1aSopenharmony_ci for (i = 1; i < 256; i++) 707cabdff1aSopenharmony_ci s->state_transition[i] = c.one_state[i]; 708cabdff1aSopenharmony_ci } 709cabdff1aSopenharmony_ci 710cabdff1aSopenharmony_ci for (i = 0; i < 256; i++) { 711cabdff1aSopenharmony_ci s->quant_table_count = 2; 712cabdff1aSopenharmony_ci if (s->bits_per_raw_sample <= 8) { 713cabdff1aSopenharmony_ci s->quant_tables[0][0][i]= quant11[i]; 714cabdff1aSopenharmony_ci s->quant_tables[0][1][i]= 11*quant11[i]; 715cabdff1aSopenharmony_ci s->quant_tables[0][2][i]= 11*11*quant11[i]; 716cabdff1aSopenharmony_ci s->quant_tables[1][0][i]= quant11[i]; 717cabdff1aSopenharmony_ci s->quant_tables[1][1][i]= 11*quant11[i]; 718cabdff1aSopenharmony_ci s->quant_tables[1][2][i]= 11*11*quant5 [i]; 719cabdff1aSopenharmony_ci s->quant_tables[1][3][i]= 5*11*11*quant5 [i]; 720cabdff1aSopenharmony_ci s->quant_tables[1][4][i]= 5*5*11*11*quant5 [i]; 721cabdff1aSopenharmony_ci } else { 722cabdff1aSopenharmony_ci s->quant_tables[0][0][i]= quant9_10bit[i]; 723cabdff1aSopenharmony_ci s->quant_tables[0][1][i]= 11*quant9_10bit[i]; 724cabdff1aSopenharmony_ci s->quant_tables[0][2][i]= 11*11*quant9_10bit[i]; 725cabdff1aSopenharmony_ci s->quant_tables[1][0][i]= quant9_10bit[i]; 726cabdff1aSopenharmony_ci s->quant_tables[1][1][i]= 11*quant9_10bit[i]; 727cabdff1aSopenharmony_ci s->quant_tables[1][2][i]= 11*11*quant5_10bit[i]; 728cabdff1aSopenharmony_ci s->quant_tables[1][3][i]= 5*11*11*quant5_10bit[i]; 729cabdff1aSopenharmony_ci s->quant_tables[1][4][i]= 5*5*11*11*quant5_10bit[i]; 730cabdff1aSopenharmony_ci } 731cabdff1aSopenharmony_ci } 732cabdff1aSopenharmony_ci s->context_count[0] = (11 * 11 * 11 + 1) / 2; 733cabdff1aSopenharmony_ci s->context_count[1] = (11 * 11 * 5 * 5 * 5 + 1) / 2; 734cabdff1aSopenharmony_ci memcpy(s->quant_table, s->quant_tables[s->context_model], 735cabdff1aSopenharmony_ci sizeof(s->quant_table)); 736cabdff1aSopenharmony_ci 737cabdff1aSopenharmony_ci for (i = 0; i < s->plane_count; i++) { 738cabdff1aSopenharmony_ci PlaneContext *const p = &s->plane[i]; 739cabdff1aSopenharmony_ci 740cabdff1aSopenharmony_ci memcpy(p->quant_table, s->quant_table, sizeof(p->quant_table)); 741cabdff1aSopenharmony_ci p->quant_table_index = s->context_model; 742cabdff1aSopenharmony_ci p->context_count = s->context_count[p->quant_table_index]; 743cabdff1aSopenharmony_ci } 744cabdff1aSopenharmony_ci 745cabdff1aSopenharmony_ci if ((ret = ff_ffv1_allocate_initial_states(s)) < 0) 746cabdff1aSopenharmony_ci return ret; 747cabdff1aSopenharmony_ci 748cabdff1aSopenharmony_ci if (!s->transparency) 749cabdff1aSopenharmony_ci s->plane_count = 2; 750cabdff1aSopenharmony_ci if (!s->chroma_planes && s->version > 3) 751cabdff1aSopenharmony_ci s->plane_count--; 752cabdff1aSopenharmony_ci 753cabdff1aSopenharmony_ci ret = av_pix_fmt_get_chroma_sub_sample (avctx->pix_fmt, &s->chroma_h_shift, &s->chroma_v_shift); 754cabdff1aSopenharmony_ci if (ret) 755cabdff1aSopenharmony_ci return ret; 756cabdff1aSopenharmony_ci 757cabdff1aSopenharmony_ci s->picture_number = 0; 758cabdff1aSopenharmony_ci 759cabdff1aSopenharmony_ci if (avctx->flags & (AV_CODEC_FLAG_PASS1 | AV_CODEC_FLAG_PASS2)) { 760cabdff1aSopenharmony_ci for (i = 0; i < s->quant_table_count; i++) { 761cabdff1aSopenharmony_ci s->rc_stat2[i] = av_mallocz(s->context_count[i] * 762cabdff1aSopenharmony_ci sizeof(*s->rc_stat2[i])); 763cabdff1aSopenharmony_ci if (!s->rc_stat2[i]) 764cabdff1aSopenharmony_ci return AVERROR(ENOMEM); 765cabdff1aSopenharmony_ci } 766cabdff1aSopenharmony_ci } 767cabdff1aSopenharmony_ci if (avctx->stats_in) { 768cabdff1aSopenharmony_ci char *p = avctx->stats_in; 769cabdff1aSopenharmony_ci uint8_t (*best_state)[256] = av_malloc_array(256, 256); 770cabdff1aSopenharmony_ci int gob_count = 0; 771cabdff1aSopenharmony_ci char *next; 772cabdff1aSopenharmony_ci if (!best_state) 773cabdff1aSopenharmony_ci return AVERROR(ENOMEM); 774cabdff1aSopenharmony_ci 775cabdff1aSopenharmony_ci av_assert0(s->version >= 2); 776cabdff1aSopenharmony_ci 777cabdff1aSopenharmony_ci for (;;) { 778cabdff1aSopenharmony_ci for (j = 0; j < 256; j++) 779cabdff1aSopenharmony_ci for (i = 0; i < 2; i++) { 780cabdff1aSopenharmony_ci s->rc_stat[j][i] = strtol(p, &next, 0); 781cabdff1aSopenharmony_ci if (next == p) { 782cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, 783cabdff1aSopenharmony_ci "2Pass file invalid at %d %d [%s]\n", j, i, p); 784cabdff1aSopenharmony_ci av_freep(&best_state); 785cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 786cabdff1aSopenharmony_ci } 787cabdff1aSopenharmony_ci p = next; 788cabdff1aSopenharmony_ci } 789cabdff1aSopenharmony_ci for (i = 0; i < s->quant_table_count; i++) 790cabdff1aSopenharmony_ci for (j = 0; j < s->context_count[i]; j++) { 791cabdff1aSopenharmony_ci for (k = 0; k < 32; k++) 792cabdff1aSopenharmony_ci for (m = 0; m < 2; m++) { 793cabdff1aSopenharmony_ci s->rc_stat2[i][j][k][m] = strtol(p, &next, 0); 794cabdff1aSopenharmony_ci if (next == p) { 795cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, 796cabdff1aSopenharmony_ci "2Pass file invalid at %d %d %d %d [%s]\n", 797cabdff1aSopenharmony_ci i, j, k, m, p); 798cabdff1aSopenharmony_ci av_freep(&best_state); 799cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 800cabdff1aSopenharmony_ci } 801cabdff1aSopenharmony_ci p = next; 802cabdff1aSopenharmony_ci } 803cabdff1aSopenharmony_ci } 804cabdff1aSopenharmony_ci gob_count = strtol(p, &next, 0); 805cabdff1aSopenharmony_ci if (next == p || gob_count <= 0) { 806cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, "2Pass file invalid\n"); 807cabdff1aSopenharmony_ci av_freep(&best_state); 808cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 809cabdff1aSopenharmony_ci } 810cabdff1aSopenharmony_ci p = next; 811cabdff1aSopenharmony_ci while (*p == '\n' || *p == ' ') 812cabdff1aSopenharmony_ci p++; 813cabdff1aSopenharmony_ci if (p[0] == 0) 814cabdff1aSopenharmony_ci break; 815cabdff1aSopenharmony_ci } 816cabdff1aSopenharmony_ci if (s->ac == AC_RANGE_CUSTOM_TAB) 817cabdff1aSopenharmony_ci sort_stt(s, s->state_transition); 818cabdff1aSopenharmony_ci 819cabdff1aSopenharmony_ci find_best_state(best_state, s->state_transition); 820cabdff1aSopenharmony_ci 821cabdff1aSopenharmony_ci for (i = 0; i < s->quant_table_count; i++) { 822cabdff1aSopenharmony_ci for (k = 0; k < 32; k++) { 823cabdff1aSopenharmony_ci double a=0, b=0; 824cabdff1aSopenharmony_ci int jp = 0; 825cabdff1aSopenharmony_ci for (j = 0; j < s->context_count[i]; j++) { 826cabdff1aSopenharmony_ci double p = 128; 827cabdff1aSopenharmony_ci if (s->rc_stat2[i][j][k][0] + s->rc_stat2[i][j][k][1] > 200 && j || a+b > 200) { 828cabdff1aSopenharmony_ci if (a+b) 829cabdff1aSopenharmony_ci p = 256.0 * b / (a + b); 830cabdff1aSopenharmony_ci s->initial_states[i][jp][k] = 831cabdff1aSopenharmony_ci best_state[av_clip(round(p), 1, 255)][av_clip_uint8((a + b) / gob_count)]; 832cabdff1aSopenharmony_ci for(jp++; jp<j; jp++) 833cabdff1aSopenharmony_ci s->initial_states[i][jp][k] = s->initial_states[i][jp-1][k]; 834cabdff1aSopenharmony_ci a=b=0; 835cabdff1aSopenharmony_ci } 836cabdff1aSopenharmony_ci a += s->rc_stat2[i][j][k][0]; 837cabdff1aSopenharmony_ci b += s->rc_stat2[i][j][k][1]; 838cabdff1aSopenharmony_ci if (a+b) { 839cabdff1aSopenharmony_ci p = 256.0 * b / (a + b); 840cabdff1aSopenharmony_ci } 841cabdff1aSopenharmony_ci s->initial_states[i][j][k] = 842cabdff1aSopenharmony_ci best_state[av_clip(round(p), 1, 255)][av_clip_uint8((a + b) / gob_count)]; 843cabdff1aSopenharmony_ci } 844cabdff1aSopenharmony_ci } 845cabdff1aSopenharmony_ci } 846cabdff1aSopenharmony_ci av_freep(&best_state); 847cabdff1aSopenharmony_ci } 848cabdff1aSopenharmony_ci 849cabdff1aSopenharmony_ci if (s->version > 1) { 850cabdff1aSopenharmony_ci int plane_count = 1 + 2*s->chroma_planes + s->transparency; 851cabdff1aSopenharmony_ci int max_h_slices = AV_CEIL_RSHIFT(avctx->width , s->chroma_h_shift); 852cabdff1aSopenharmony_ci int max_v_slices = AV_CEIL_RSHIFT(avctx->height, s->chroma_v_shift); 853cabdff1aSopenharmony_ci s->num_v_slices = (avctx->width > 352 || avctx->height > 288 || !avctx->slices) ? 2 : 1; 854cabdff1aSopenharmony_ci 855cabdff1aSopenharmony_ci s->num_v_slices = FFMIN(s->num_v_slices, max_v_slices); 856cabdff1aSopenharmony_ci 857cabdff1aSopenharmony_ci for (; s->num_v_slices < 32; s->num_v_slices++) { 858cabdff1aSopenharmony_ci for (s->num_h_slices = s->num_v_slices; s->num_h_slices < 2*s->num_v_slices; s->num_h_slices++) { 859cabdff1aSopenharmony_ci int maxw = (avctx->width + s->num_h_slices - 1) / s->num_h_slices; 860cabdff1aSopenharmony_ci int maxh = (avctx->height + s->num_v_slices - 1) / s->num_v_slices; 861cabdff1aSopenharmony_ci if (s->num_h_slices > max_h_slices || s->num_v_slices > max_v_slices) 862cabdff1aSopenharmony_ci continue; 863cabdff1aSopenharmony_ci if (maxw * maxh * (int64_t)(s->bits_per_raw_sample+1) * plane_count > 8<<24) 864cabdff1aSopenharmony_ci continue; 865cabdff1aSopenharmony_ci if (avctx->slices == s->num_h_slices * s->num_v_slices && avctx->slices <= MAX_SLICES || !avctx->slices) 866cabdff1aSopenharmony_ci goto slices_ok; 867cabdff1aSopenharmony_ci } 868cabdff1aSopenharmony_ci } 869cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, 870cabdff1aSopenharmony_ci "Unsupported number %d of slices requested, please specify a " 871cabdff1aSopenharmony_ci "supported number with -slices (ex:4,6,9,12,16, ...)\n", 872cabdff1aSopenharmony_ci avctx->slices); 873cabdff1aSopenharmony_ci return AVERROR(ENOSYS); 874cabdff1aSopenharmony_cislices_ok: 875cabdff1aSopenharmony_ci if ((ret = write_extradata(s)) < 0) 876cabdff1aSopenharmony_ci return ret; 877cabdff1aSopenharmony_ci } 878cabdff1aSopenharmony_ci 879cabdff1aSopenharmony_ci if ((ret = ff_ffv1_init_slice_contexts(s)) < 0) 880cabdff1aSopenharmony_ci return ret; 881cabdff1aSopenharmony_ci s->slice_count = s->max_slice_count; 882cabdff1aSopenharmony_ci if ((ret = ff_ffv1_init_slices_state(s)) < 0) 883cabdff1aSopenharmony_ci return ret; 884cabdff1aSopenharmony_ci 885cabdff1aSopenharmony_ci#define STATS_OUT_SIZE 1024 * 1024 * 6 886cabdff1aSopenharmony_ci if (avctx->flags & AV_CODEC_FLAG_PASS1) { 887cabdff1aSopenharmony_ci avctx->stats_out = av_mallocz(STATS_OUT_SIZE); 888cabdff1aSopenharmony_ci if (!avctx->stats_out) 889cabdff1aSopenharmony_ci return AVERROR(ENOMEM); 890cabdff1aSopenharmony_ci for (i = 0; i < s->quant_table_count; i++) 891cabdff1aSopenharmony_ci for (j = 0; j < s->max_slice_count; j++) { 892cabdff1aSopenharmony_ci FFV1Context *sf = s->slice_context[j]; 893cabdff1aSopenharmony_ci av_assert0(!sf->rc_stat2[i]); 894cabdff1aSopenharmony_ci sf->rc_stat2[i] = av_mallocz(s->context_count[i] * 895cabdff1aSopenharmony_ci sizeof(*sf->rc_stat2[i])); 896cabdff1aSopenharmony_ci if (!sf->rc_stat2[i]) 897cabdff1aSopenharmony_ci return AVERROR(ENOMEM); 898cabdff1aSopenharmony_ci } 899cabdff1aSopenharmony_ci } 900cabdff1aSopenharmony_ci 901cabdff1aSopenharmony_ci return 0; 902cabdff1aSopenharmony_ci} 903cabdff1aSopenharmony_ci 904cabdff1aSopenharmony_cistatic void encode_slice_header(FFV1Context *f, FFV1Context *fs) 905cabdff1aSopenharmony_ci{ 906cabdff1aSopenharmony_ci RangeCoder *c = &fs->c; 907cabdff1aSopenharmony_ci uint8_t state[CONTEXT_SIZE]; 908cabdff1aSopenharmony_ci int j; 909cabdff1aSopenharmony_ci memset(state, 128, sizeof(state)); 910cabdff1aSopenharmony_ci 911cabdff1aSopenharmony_ci put_symbol(c, state, (fs->slice_x +1)*f->num_h_slices / f->width , 0); 912cabdff1aSopenharmony_ci put_symbol(c, state, (fs->slice_y +1)*f->num_v_slices / f->height , 0); 913cabdff1aSopenharmony_ci put_symbol(c, state, (fs->slice_width +1)*f->num_h_slices / f->width -1, 0); 914cabdff1aSopenharmony_ci put_symbol(c, state, (fs->slice_height+1)*f->num_v_slices / f->height-1, 0); 915cabdff1aSopenharmony_ci for (j=0; j<f->plane_count; j++) { 916cabdff1aSopenharmony_ci put_symbol(c, state, f->plane[j].quant_table_index, 0); 917cabdff1aSopenharmony_ci av_assert0(f->plane[j].quant_table_index == f->context_model); 918cabdff1aSopenharmony_ci } 919cabdff1aSopenharmony_ci if (!f->picture.f->interlaced_frame) 920cabdff1aSopenharmony_ci put_symbol(c, state, 3, 0); 921cabdff1aSopenharmony_ci else 922cabdff1aSopenharmony_ci put_symbol(c, state, 1 + !f->picture.f->top_field_first, 0); 923cabdff1aSopenharmony_ci put_symbol(c, state, f->picture.f->sample_aspect_ratio.num, 0); 924cabdff1aSopenharmony_ci put_symbol(c, state, f->picture.f->sample_aspect_ratio.den, 0); 925cabdff1aSopenharmony_ci if (f->version > 3) { 926cabdff1aSopenharmony_ci put_rac(c, state, fs->slice_coding_mode == 1); 927cabdff1aSopenharmony_ci if (fs->slice_coding_mode == 1) 928cabdff1aSopenharmony_ci ff_ffv1_clear_slice_state(f, fs); 929cabdff1aSopenharmony_ci put_symbol(c, state, fs->slice_coding_mode, 0); 930cabdff1aSopenharmony_ci if (fs->slice_coding_mode != 1) { 931cabdff1aSopenharmony_ci put_symbol(c, state, fs->slice_rct_by_coef, 0); 932cabdff1aSopenharmony_ci put_symbol(c, state, fs->slice_rct_ry_coef, 0); 933cabdff1aSopenharmony_ci } 934cabdff1aSopenharmony_ci } 935cabdff1aSopenharmony_ci} 936cabdff1aSopenharmony_ci 937cabdff1aSopenharmony_cistatic void choose_rct_params(FFV1Context *fs, const uint8_t *src[3], const int stride[3], int w, int h) 938cabdff1aSopenharmony_ci{ 939cabdff1aSopenharmony_ci#define NB_Y_COEFF 15 940cabdff1aSopenharmony_ci static const int rct_y_coeff[15][2] = { 941cabdff1aSopenharmony_ci {0, 0}, // 4G 942cabdff1aSopenharmony_ci {1, 1}, // R + 2G + B 943cabdff1aSopenharmony_ci {2, 2}, // 2R + 2B 944cabdff1aSopenharmony_ci {0, 2}, // 2G + 2B 945cabdff1aSopenharmony_ci {2, 0}, // 2R + 2G 946cabdff1aSopenharmony_ci {4, 0}, // 4R 947cabdff1aSopenharmony_ci {0, 4}, // 4B 948cabdff1aSopenharmony_ci 949cabdff1aSopenharmony_ci {0, 3}, // 1G + 3B 950cabdff1aSopenharmony_ci {3, 0}, // 3R + 1G 951cabdff1aSopenharmony_ci {3, 1}, // 3R + B 952cabdff1aSopenharmony_ci {1, 3}, // R + 3B 953cabdff1aSopenharmony_ci {1, 2}, // R + G + 2B 954cabdff1aSopenharmony_ci {2, 1}, // 2R + G + B 955cabdff1aSopenharmony_ci {0, 1}, // 3G + B 956cabdff1aSopenharmony_ci {1, 0}, // R + 3G 957cabdff1aSopenharmony_ci }; 958cabdff1aSopenharmony_ci 959cabdff1aSopenharmony_ci int stat[NB_Y_COEFF] = {0}; 960cabdff1aSopenharmony_ci int x, y, i, p, best; 961cabdff1aSopenharmony_ci int16_t *sample[3]; 962cabdff1aSopenharmony_ci int lbd = fs->bits_per_raw_sample <= 8; 963cabdff1aSopenharmony_ci 964cabdff1aSopenharmony_ci for (y = 0; y < h; y++) { 965cabdff1aSopenharmony_ci int lastr=0, lastg=0, lastb=0; 966cabdff1aSopenharmony_ci for (p = 0; p < 3; p++) 967cabdff1aSopenharmony_ci sample[p] = fs->sample_buffer + p*w; 968cabdff1aSopenharmony_ci 969cabdff1aSopenharmony_ci for (x = 0; x < w; x++) { 970cabdff1aSopenharmony_ci int b, g, r; 971cabdff1aSopenharmony_ci int ab, ag, ar; 972cabdff1aSopenharmony_ci if (lbd) { 973cabdff1aSopenharmony_ci unsigned v = *((const uint32_t*)(src[0] + x*4 + stride[0]*y)); 974cabdff1aSopenharmony_ci b = v & 0xFF; 975cabdff1aSopenharmony_ci g = (v >> 8) & 0xFF; 976cabdff1aSopenharmony_ci r = (v >> 16) & 0xFF; 977cabdff1aSopenharmony_ci } else { 978cabdff1aSopenharmony_ci b = *((const uint16_t*)(src[0] + x*2 + stride[0]*y)); 979cabdff1aSopenharmony_ci g = *((const uint16_t*)(src[1] + x*2 + stride[1]*y)); 980cabdff1aSopenharmony_ci r = *((const uint16_t*)(src[2] + x*2 + stride[2]*y)); 981cabdff1aSopenharmony_ci } 982cabdff1aSopenharmony_ci 983cabdff1aSopenharmony_ci ar = r - lastr; 984cabdff1aSopenharmony_ci ag = g - lastg; 985cabdff1aSopenharmony_ci ab = b - lastb; 986cabdff1aSopenharmony_ci if (x && y) { 987cabdff1aSopenharmony_ci int bg = ag - sample[0][x]; 988cabdff1aSopenharmony_ci int bb = ab - sample[1][x]; 989cabdff1aSopenharmony_ci int br = ar - sample[2][x]; 990cabdff1aSopenharmony_ci 991cabdff1aSopenharmony_ci br -= bg; 992cabdff1aSopenharmony_ci bb -= bg; 993cabdff1aSopenharmony_ci 994cabdff1aSopenharmony_ci for (i = 0; i<NB_Y_COEFF; i++) { 995cabdff1aSopenharmony_ci stat[i] += FFABS(bg + ((br*rct_y_coeff[i][0] + bb*rct_y_coeff[i][1])>>2)); 996cabdff1aSopenharmony_ci } 997cabdff1aSopenharmony_ci 998cabdff1aSopenharmony_ci } 999cabdff1aSopenharmony_ci sample[0][x] = ag; 1000cabdff1aSopenharmony_ci sample[1][x] = ab; 1001cabdff1aSopenharmony_ci sample[2][x] = ar; 1002cabdff1aSopenharmony_ci 1003cabdff1aSopenharmony_ci lastr = r; 1004cabdff1aSopenharmony_ci lastg = g; 1005cabdff1aSopenharmony_ci lastb = b; 1006cabdff1aSopenharmony_ci } 1007cabdff1aSopenharmony_ci } 1008cabdff1aSopenharmony_ci 1009cabdff1aSopenharmony_ci best = 0; 1010cabdff1aSopenharmony_ci for (i=1; i<NB_Y_COEFF; i++) { 1011cabdff1aSopenharmony_ci if (stat[i] < stat[best]) 1012cabdff1aSopenharmony_ci best = i; 1013cabdff1aSopenharmony_ci } 1014cabdff1aSopenharmony_ci 1015cabdff1aSopenharmony_ci fs->slice_rct_by_coef = rct_y_coeff[best][1]; 1016cabdff1aSopenharmony_ci fs->slice_rct_ry_coef = rct_y_coeff[best][0]; 1017cabdff1aSopenharmony_ci} 1018cabdff1aSopenharmony_ci 1019cabdff1aSopenharmony_cistatic int encode_slice(AVCodecContext *c, void *arg) 1020cabdff1aSopenharmony_ci{ 1021cabdff1aSopenharmony_ci FFV1Context *fs = *(void **)arg; 1022cabdff1aSopenharmony_ci FFV1Context *f = fs->avctx->priv_data; 1023cabdff1aSopenharmony_ci int width = fs->slice_width; 1024cabdff1aSopenharmony_ci int height = fs->slice_height; 1025cabdff1aSopenharmony_ci int x = fs->slice_x; 1026cabdff1aSopenharmony_ci int y = fs->slice_y; 1027cabdff1aSopenharmony_ci const AVFrame *const p = f->picture.f; 1028cabdff1aSopenharmony_ci const int ps = av_pix_fmt_desc_get(c->pix_fmt)->comp[0].step; 1029cabdff1aSopenharmony_ci int ret; 1030cabdff1aSopenharmony_ci RangeCoder c_bak = fs->c; 1031cabdff1aSopenharmony_ci const uint8_t *planes[4] = {p->data[0] + ps*x + y*p->linesize[0], 1032cabdff1aSopenharmony_ci p->data[1] ? p->data[1] + ps*x + y*p->linesize[1] : NULL, 1033cabdff1aSopenharmony_ci p->data[2] ? p->data[2] + ps*x + y*p->linesize[2] : NULL, 1034cabdff1aSopenharmony_ci p->data[3] ? p->data[3] + ps*x + y*p->linesize[3] : NULL}; 1035cabdff1aSopenharmony_ci 1036cabdff1aSopenharmony_ci fs->slice_coding_mode = 0; 1037cabdff1aSopenharmony_ci if (f->version > 3) { 1038cabdff1aSopenharmony_ci choose_rct_params(fs, planes, p->linesize, width, height); 1039cabdff1aSopenharmony_ci } else { 1040cabdff1aSopenharmony_ci fs->slice_rct_by_coef = 1; 1041cabdff1aSopenharmony_ci fs->slice_rct_ry_coef = 1; 1042cabdff1aSopenharmony_ci } 1043cabdff1aSopenharmony_ci 1044cabdff1aSopenharmony_ciretry: 1045cabdff1aSopenharmony_ci if (f->key_frame) 1046cabdff1aSopenharmony_ci ff_ffv1_clear_slice_state(f, fs); 1047cabdff1aSopenharmony_ci if (f->version > 2) { 1048cabdff1aSopenharmony_ci encode_slice_header(f, fs); 1049cabdff1aSopenharmony_ci } 1050cabdff1aSopenharmony_ci if (fs->ac == AC_GOLOMB_RICE) { 1051cabdff1aSopenharmony_ci fs->ac_byte_count = f->version > 2 || (!x && !y) ? ff_rac_terminate(&fs->c, f->version > 2) : 0; 1052cabdff1aSopenharmony_ci init_put_bits(&fs->pb, 1053cabdff1aSopenharmony_ci fs->c.bytestream_start + fs->ac_byte_count, 1054cabdff1aSopenharmony_ci fs->c.bytestream_end - fs->c.bytestream_start - fs->ac_byte_count); 1055cabdff1aSopenharmony_ci } 1056cabdff1aSopenharmony_ci 1057cabdff1aSopenharmony_ci if (f->colorspace == 0 && c->pix_fmt != AV_PIX_FMT_YA8) { 1058cabdff1aSopenharmony_ci const int chroma_width = AV_CEIL_RSHIFT(width, f->chroma_h_shift); 1059cabdff1aSopenharmony_ci const int chroma_height = AV_CEIL_RSHIFT(height, f->chroma_v_shift); 1060cabdff1aSopenharmony_ci const int cx = x >> f->chroma_h_shift; 1061cabdff1aSopenharmony_ci const int cy = y >> f->chroma_v_shift; 1062cabdff1aSopenharmony_ci 1063cabdff1aSopenharmony_ci ret = encode_plane(fs, p->data[0] + ps*x + y*p->linesize[0], width, height, p->linesize[0], 0, 1); 1064cabdff1aSopenharmony_ci 1065cabdff1aSopenharmony_ci if (f->chroma_planes) { 1066cabdff1aSopenharmony_ci ret |= encode_plane(fs, p->data[1] + ps*cx+cy*p->linesize[1], chroma_width, chroma_height, p->linesize[1], 1, 1); 1067cabdff1aSopenharmony_ci ret |= encode_plane(fs, p->data[2] + ps*cx+cy*p->linesize[2], chroma_width, chroma_height, p->linesize[2], 1, 1); 1068cabdff1aSopenharmony_ci } 1069cabdff1aSopenharmony_ci if (fs->transparency) 1070cabdff1aSopenharmony_ci ret |= encode_plane(fs, p->data[3] + ps*x + y*p->linesize[3], width, height, p->linesize[3], 2, 1); 1071cabdff1aSopenharmony_ci } else if (c->pix_fmt == AV_PIX_FMT_YA8) { 1072cabdff1aSopenharmony_ci ret = encode_plane(fs, p->data[0] + ps*x + y*p->linesize[0], width, height, p->linesize[0], 0, 2); 1073cabdff1aSopenharmony_ci ret |= encode_plane(fs, p->data[0] + 1 + ps*x + y*p->linesize[0], width, height, p->linesize[0], 1, 2); 1074cabdff1aSopenharmony_ci } else if (f->use32bit) { 1075cabdff1aSopenharmony_ci ret = encode_rgb_frame32(fs, planes, width, height, p->linesize); 1076cabdff1aSopenharmony_ci } else { 1077cabdff1aSopenharmony_ci ret = encode_rgb_frame(fs, planes, width, height, p->linesize); 1078cabdff1aSopenharmony_ci } 1079cabdff1aSopenharmony_ci emms_c(); 1080cabdff1aSopenharmony_ci 1081cabdff1aSopenharmony_ci if (ret < 0) { 1082cabdff1aSopenharmony_ci av_assert0(fs->slice_coding_mode == 0); 1083cabdff1aSopenharmony_ci if (fs->version < 4 || !fs->ac) { 1084cabdff1aSopenharmony_ci av_log(c, AV_LOG_ERROR, "Buffer too small\n"); 1085cabdff1aSopenharmony_ci return ret; 1086cabdff1aSopenharmony_ci } 1087cabdff1aSopenharmony_ci av_log(c, AV_LOG_DEBUG, "Coding slice as PCM\n"); 1088cabdff1aSopenharmony_ci fs->slice_coding_mode = 1; 1089cabdff1aSopenharmony_ci fs->c = c_bak; 1090cabdff1aSopenharmony_ci goto retry; 1091cabdff1aSopenharmony_ci } 1092cabdff1aSopenharmony_ci 1093cabdff1aSopenharmony_ci return 0; 1094cabdff1aSopenharmony_ci} 1095cabdff1aSopenharmony_ci 1096cabdff1aSopenharmony_cistatic int encode_frame(AVCodecContext *avctx, AVPacket *pkt, 1097cabdff1aSopenharmony_ci const AVFrame *pict, int *got_packet) 1098cabdff1aSopenharmony_ci{ 1099cabdff1aSopenharmony_ci FFV1Context *f = avctx->priv_data; 1100cabdff1aSopenharmony_ci RangeCoder *const c = &f->slice_context[0]->c; 1101cabdff1aSopenharmony_ci AVFrame *const p = f->picture.f; 1102cabdff1aSopenharmony_ci uint8_t keystate = 128; 1103cabdff1aSopenharmony_ci uint8_t *buf_p; 1104cabdff1aSopenharmony_ci int i, ret; 1105cabdff1aSopenharmony_ci int64_t maxsize = AV_INPUT_BUFFER_MIN_SIZE 1106cabdff1aSopenharmony_ci + avctx->width*avctx->height*37LL*4; 1107cabdff1aSopenharmony_ci 1108cabdff1aSopenharmony_ci if(!pict) { 1109cabdff1aSopenharmony_ci if (avctx->flags & AV_CODEC_FLAG_PASS1) { 1110cabdff1aSopenharmony_ci int j, k, m; 1111cabdff1aSopenharmony_ci char *p = avctx->stats_out; 1112cabdff1aSopenharmony_ci char *end = p + STATS_OUT_SIZE; 1113cabdff1aSopenharmony_ci 1114cabdff1aSopenharmony_ci memset(f->rc_stat, 0, sizeof(f->rc_stat)); 1115cabdff1aSopenharmony_ci for (i = 0; i < f->quant_table_count; i++) 1116cabdff1aSopenharmony_ci memset(f->rc_stat2[i], 0, f->context_count[i] * sizeof(*f->rc_stat2[i])); 1117cabdff1aSopenharmony_ci 1118cabdff1aSopenharmony_ci av_assert0(f->slice_count == f->max_slice_count); 1119cabdff1aSopenharmony_ci for (j = 0; j < f->slice_count; j++) { 1120cabdff1aSopenharmony_ci FFV1Context *fs = f->slice_context[j]; 1121cabdff1aSopenharmony_ci for (i = 0; i < 256; i++) { 1122cabdff1aSopenharmony_ci f->rc_stat[i][0] += fs->rc_stat[i][0]; 1123cabdff1aSopenharmony_ci f->rc_stat[i][1] += fs->rc_stat[i][1]; 1124cabdff1aSopenharmony_ci } 1125cabdff1aSopenharmony_ci for (i = 0; i < f->quant_table_count; i++) { 1126cabdff1aSopenharmony_ci for (k = 0; k < f->context_count[i]; k++) 1127cabdff1aSopenharmony_ci for (m = 0; m < 32; m++) { 1128cabdff1aSopenharmony_ci f->rc_stat2[i][k][m][0] += fs->rc_stat2[i][k][m][0]; 1129cabdff1aSopenharmony_ci f->rc_stat2[i][k][m][1] += fs->rc_stat2[i][k][m][1]; 1130cabdff1aSopenharmony_ci } 1131cabdff1aSopenharmony_ci } 1132cabdff1aSopenharmony_ci } 1133cabdff1aSopenharmony_ci 1134cabdff1aSopenharmony_ci for (j = 0; j < 256; j++) { 1135cabdff1aSopenharmony_ci snprintf(p, end - p, "%" PRIu64 " %" PRIu64 " ", 1136cabdff1aSopenharmony_ci f->rc_stat[j][0], f->rc_stat[j][1]); 1137cabdff1aSopenharmony_ci p += strlen(p); 1138cabdff1aSopenharmony_ci } 1139cabdff1aSopenharmony_ci snprintf(p, end - p, "\n"); 1140cabdff1aSopenharmony_ci 1141cabdff1aSopenharmony_ci for (i = 0; i < f->quant_table_count; i++) { 1142cabdff1aSopenharmony_ci for (j = 0; j < f->context_count[i]; j++) 1143cabdff1aSopenharmony_ci for (m = 0; m < 32; m++) { 1144cabdff1aSopenharmony_ci snprintf(p, end - p, "%" PRIu64 " %" PRIu64 " ", 1145cabdff1aSopenharmony_ci f->rc_stat2[i][j][m][0], f->rc_stat2[i][j][m][1]); 1146cabdff1aSopenharmony_ci p += strlen(p); 1147cabdff1aSopenharmony_ci } 1148cabdff1aSopenharmony_ci } 1149cabdff1aSopenharmony_ci snprintf(p, end - p, "%d\n", f->gob_count); 1150cabdff1aSopenharmony_ci } 1151cabdff1aSopenharmony_ci return 0; 1152cabdff1aSopenharmony_ci } 1153cabdff1aSopenharmony_ci 1154cabdff1aSopenharmony_ci if (f->version > 3) 1155cabdff1aSopenharmony_ci maxsize = AV_INPUT_BUFFER_MIN_SIZE + avctx->width*avctx->height*3LL*4; 1156cabdff1aSopenharmony_ci 1157cabdff1aSopenharmony_ci if (maxsize > INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE - 32) { 1158cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_WARNING, "Cannot allocate worst case packet size, the encoding could fail\n"); 1159cabdff1aSopenharmony_ci maxsize = INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE - 32; 1160cabdff1aSopenharmony_ci } 1161cabdff1aSopenharmony_ci 1162cabdff1aSopenharmony_ci if ((ret = ff_alloc_packet(avctx, pkt, maxsize)) < 0) 1163cabdff1aSopenharmony_ci return ret; 1164cabdff1aSopenharmony_ci 1165cabdff1aSopenharmony_ci ff_init_range_encoder(c, pkt->data, pkt->size); 1166cabdff1aSopenharmony_ci ff_build_rac_states(c, 0.05 * (1LL << 32), 256 - 8); 1167cabdff1aSopenharmony_ci 1168cabdff1aSopenharmony_ci av_frame_unref(p); 1169cabdff1aSopenharmony_ci if ((ret = av_frame_ref(p, pict)) < 0) 1170cabdff1aSopenharmony_ci return ret; 1171cabdff1aSopenharmony_ci 1172cabdff1aSopenharmony_ci if (avctx->gop_size == 0 || f->picture_number % avctx->gop_size == 0) { 1173cabdff1aSopenharmony_ci put_rac(c, &keystate, 1); 1174cabdff1aSopenharmony_ci f->key_frame = 1; 1175cabdff1aSopenharmony_ci f->gob_count++; 1176cabdff1aSopenharmony_ci write_header(f); 1177cabdff1aSopenharmony_ci } else { 1178cabdff1aSopenharmony_ci put_rac(c, &keystate, 0); 1179cabdff1aSopenharmony_ci f->key_frame = 0; 1180cabdff1aSopenharmony_ci } 1181cabdff1aSopenharmony_ci 1182cabdff1aSopenharmony_ci if (f->ac == AC_RANGE_CUSTOM_TAB) { 1183cabdff1aSopenharmony_ci int i; 1184cabdff1aSopenharmony_ci for (i = 1; i < 256; i++) { 1185cabdff1aSopenharmony_ci c->one_state[i] = f->state_transition[i]; 1186cabdff1aSopenharmony_ci c->zero_state[256 - i] = 256 - c->one_state[i]; 1187cabdff1aSopenharmony_ci } 1188cabdff1aSopenharmony_ci } 1189cabdff1aSopenharmony_ci 1190cabdff1aSopenharmony_ci for (i = 0; i < f->slice_count; i++) { 1191cabdff1aSopenharmony_ci FFV1Context *fs = f->slice_context[i]; 1192cabdff1aSopenharmony_ci uint8_t *start = pkt->data + pkt->size * (int64_t)i / f->slice_count; 1193cabdff1aSopenharmony_ci int len = pkt->size / f->slice_count; 1194cabdff1aSopenharmony_ci if (i) { 1195cabdff1aSopenharmony_ci ff_init_range_encoder(&fs->c, start, len); 1196cabdff1aSopenharmony_ci } else { 1197cabdff1aSopenharmony_ci av_assert0(fs->c.bytestream_end >= fs->c.bytestream_start + len); 1198cabdff1aSopenharmony_ci av_assert0(fs->c.bytestream < fs->c.bytestream_start + len); 1199cabdff1aSopenharmony_ci fs->c.bytestream_end = fs->c.bytestream_start + len; 1200cabdff1aSopenharmony_ci } 1201cabdff1aSopenharmony_ci } 1202cabdff1aSopenharmony_ci avctx->execute(avctx, encode_slice, &f->slice_context[0], NULL, 1203cabdff1aSopenharmony_ci f->slice_count, sizeof(void *)); 1204cabdff1aSopenharmony_ci 1205cabdff1aSopenharmony_ci buf_p = pkt->data; 1206cabdff1aSopenharmony_ci for (i = 0; i < f->slice_count; i++) { 1207cabdff1aSopenharmony_ci FFV1Context *fs = f->slice_context[i]; 1208cabdff1aSopenharmony_ci int bytes; 1209cabdff1aSopenharmony_ci 1210cabdff1aSopenharmony_ci if (fs->ac != AC_GOLOMB_RICE) { 1211cabdff1aSopenharmony_ci bytes = ff_rac_terminate(&fs->c, 1); 1212cabdff1aSopenharmony_ci } else { 1213cabdff1aSopenharmony_ci flush_put_bits(&fs->pb); // FIXME: nicer padding 1214cabdff1aSopenharmony_ci bytes = fs->ac_byte_count + put_bytes_output(&fs->pb); 1215cabdff1aSopenharmony_ci } 1216cabdff1aSopenharmony_ci if (i > 0 || f->version > 2) { 1217cabdff1aSopenharmony_ci av_assert0(bytes < pkt->size / f->slice_count); 1218cabdff1aSopenharmony_ci memmove(buf_p, fs->c.bytestream_start, bytes); 1219cabdff1aSopenharmony_ci av_assert0(bytes < (1 << 24)); 1220cabdff1aSopenharmony_ci AV_WB24(buf_p + bytes, bytes); 1221cabdff1aSopenharmony_ci bytes += 3; 1222cabdff1aSopenharmony_ci } 1223cabdff1aSopenharmony_ci if (f->ec) { 1224cabdff1aSopenharmony_ci unsigned v; 1225cabdff1aSopenharmony_ci buf_p[bytes++] = 0; 1226cabdff1aSopenharmony_ci v = av_crc(av_crc_get_table(AV_CRC_32_IEEE), 0, buf_p, bytes); 1227cabdff1aSopenharmony_ci AV_WL32(buf_p + bytes, v); 1228cabdff1aSopenharmony_ci bytes += 4; 1229cabdff1aSopenharmony_ci } 1230cabdff1aSopenharmony_ci buf_p += bytes; 1231cabdff1aSopenharmony_ci } 1232cabdff1aSopenharmony_ci 1233cabdff1aSopenharmony_ci if (avctx->flags & AV_CODEC_FLAG_PASS1) 1234cabdff1aSopenharmony_ci avctx->stats_out[0] = '\0'; 1235cabdff1aSopenharmony_ci 1236cabdff1aSopenharmony_ci f->picture_number++; 1237cabdff1aSopenharmony_ci pkt->size = buf_p - pkt->data; 1238cabdff1aSopenharmony_ci pkt->pts = 1239cabdff1aSopenharmony_ci pkt->dts = pict->pts; 1240cabdff1aSopenharmony_ci pkt->flags |= AV_PKT_FLAG_KEY * f->key_frame; 1241cabdff1aSopenharmony_ci *got_packet = 1; 1242cabdff1aSopenharmony_ci 1243cabdff1aSopenharmony_ci return 0; 1244cabdff1aSopenharmony_ci} 1245cabdff1aSopenharmony_ci 1246cabdff1aSopenharmony_cistatic av_cold int encode_close(AVCodecContext *avctx) 1247cabdff1aSopenharmony_ci{ 1248cabdff1aSopenharmony_ci ff_ffv1_close(avctx); 1249cabdff1aSopenharmony_ci return 0; 1250cabdff1aSopenharmony_ci} 1251cabdff1aSopenharmony_ci 1252cabdff1aSopenharmony_ci#define OFFSET(x) offsetof(FFV1Context, x) 1253cabdff1aSopenharmony_ci#define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM 1254cabdff1aSopenharmony_cistatic const AVOption options[] = { 1255cabdff1aSopenharmony_ci { "slicecrc", "Protect slices with CRCs", OFFSET(ec), AV_OPT_TYPE_BOOL, { .i64 = -1 }, -1, 1, VE }, 1256cabdff1aSopenharmony_ci { "coder", "Coder type", OFFSET(ac), AV_OPT_TYPE_INT, 1257cabdff1aSopenharmony_ci { .i64 = 0 }, -2, 2, VE, "coder" }, 1258cabdff1aSopenharmony_ci { "rice", "Golomb rice", 0, AV_OPT_TYPE_CONST, 1259cabdff1aSopenharmony_ci { .i64 = AC_GOLOMB_RICE }, INT_MIN, INT_MAX, VE, "coder" }, 1260cabdff1aSopenharmony_ci { "range_def", "Range with default table", 0, AV_OPT_TYPE_CONST, 1261cabdff1aSopenharmony_ci { .i64 = AC_RANGE_DEFAULT_TAB_FORCE }, INT_MIN, INT_MAX, VE, "coder" }, 1262cabdff1aSopenharmony_ci { "range_tab", "Range with custom table", 0, AV_OPT_TYPE_CONST, 1263cabdff1aSopenharmony_ci { .i64 = AC_RANGE_CUSTOM_TAB }, INT_MIN, INT_MAX, VE, "coder" }, 1264cabdff1aSopenharmony_ci { "ac", "Range with custom table (the ac option exists for compatibility and is deprecated)", 0, AV_OPT_TYPE_CONST, 1265cabdff1aSopenharmony_ci { .i64 = 1 }, INT_MIN, INT_MAX, VE, "coder" }, 1266cabdff1aSopenharmony_ci { "context", "Context model", OFFSET(context_model), AV_OPT_TYPE_INT, 1267cabdff1aSopenharmony_ci { .i64 = 0 }, 0, 1, VE }, 1268cabdff1aSopenharmony_ci 1269cabdff1aSopenharmony_ci { NULL } 1270cabdff1aSopenharmony_ci}; 1271cabdff1aSopenharmony_ci 1272cabdff1aSopenharmony_cistatic const AVClass ffv1_class = { 1273cabdff1aSopenharmony_ci .class_name = "ffv1 encoder", 1274cabdff1aSopenharmony_ci .item_name = av_default_item_name, 1275cabdff1aSopenharmony_ci .option = options, 1276cabdff1aSopenharmony_ci .version = LIBAVUTIL_VERSION_INT, 1277cabdff1aSopenharmony_ci}; 1278cabdff1aSopenharmony_ci 1279cabdff1aSopenharmony_ciconst FFCodec ff_ffv1_encoder = { 1280cabdff1aSopenharmony_ci .p.name = "ffv1", 1281cabdff1aSopenharmony_ci .p.long_name = NULL_IF_CONFIG_SMALL("FFmpeg video codec #1"), 1282cabdff1aSopenharmony_ci .p.type = AVMEDIA_TYPE_VIDEO, 1283cabdff1aSopenharmony_ci .p.id = AV_CODEC_ID_FFV1, 1284cabdff1aSopenharmony_ci .priv_data_size = sizeof(FFV1Context), 1285cabdff1aSopenharmony_ci .init = encode_init, 1286cabdff1aSopenharmony_ci FF_CODEC_ENCODE_CB(encode_frame), 1287cabdff1aSopenharmony_ci .close = encode_close, 1288cabdff1aSopenharmony_ci .p.capabilities = AV_CODEC_CAP_SLICE_THREADS | AV_CODEC_CAP_DELAY, 1289cabdff1aSopenharmony_ci .p.pix_fmts = (const enum AVPixelFormat[]) { 1290cabdff1aSopenharmony_ci AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUVA420P, AV_PIX_FMT_YUVA422P, AV_PIX_FMT_YUV444P, 1291cabdff1aSopenharmony_ci AV_PIX_FMT_YUVA444P, AV_PIX_FMT_YUV440P, AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV411P, 1292cabdff1aSopenharmony_ci AV_PIX_FMT_YUV410P, AV_PIX_FMT_0RGB32, AV_PIX_FMT_RGB32, AV_PIX_FMT_YUV420P16, 1293cabdff1aSopenharmony_ci AV_PIX_FMT_YUV422P16, AV_PIX_FMT_YUV444P16, AV_PIX_FMT_YUV444P9, AV_PIX_FMT_YUV422P9, 1294cabdff1aSopenharmony_ci AV_PIX_FMT_YUV420P9, AV_PIX_FMT_YUV420P10, AV_PIX_FMT_YUV422P10, AV_PIX_FMT_YUV444P10, 1295cabdff1aSopenharmony_ci AV_PIX_FMT_YUV420P12, AV_PIX_FMT_YUV422P12, AV_PIX_FMT_YUV444P12, 1296cabdff1aSopenharmony_ci AV_PIX_FMT_YUVA444P16, AV_PIX_FMT_YUVA422P16, AV_PIX_FMT_YUVA420P16, 1297cabdff1aSopenharmony_ci AV_PIX_FMT_YUVA444P10, AV_PIX_FMT_YUVA422P10, AV_PIX_FMT_YUVA420P10, 1298cabdff1aSopenharmony_ci AV_PIX_FMT_YUVA444P9, AV_PIX_FMT_YUVA422P9, AV_PIX_FMT_YUVA420P9, 1299cabdff1aSopenharmony_ci AV_PIX_FMT_GRAY16, AV_PIX_FMT_GRAY8, AV_PIX_FMT_GBRP9, AV_PIX_FMT_GBRP10, 1300cabdff1aSopenharmony_ci AV_PIX_FMT_GBRP12, AV_PIX_FMT_GBRP14, 1301cabdff1aSopenharmony_ci AV_PIX_FMT_GBRAP10, AV_PIX_FMT_GBRAP12, 1302cabdff1aSopenharmony_ci AV_PIX_FMT_YA8, 1303cabdff1aSopenharmony_ci AV_PIX_FMT_GRAY10, AV_PIX_FMT_GRAY12, 1304cabdff1aSopenharmony_ci AV_PIX_FMT_GBRP16, AV_PIX_FMT_RGB48, 1305cabdff1aSopenharmony_ci AV_PIX_FMT_GBRAP16, AV_PIX_FMT_RGBA64, 1306cabdff1aSopenharmony_ci AV_PIX_FMT_GRAY9, 1307cabdff1aSopenharmony_ci AV_PIX_FMT_YUV420P14, AV_PIX_FMT_YUV422P14, AV_PIX_FMT_YUV444P14, 1308cabdff1aSopenharmony_ci AV_PIX_FMT_YUV440P10, AV_PIX_FMT_YUV440P12, 1309cabdff1aSopenharmony_ci AV_PIX_FMT_NONE 1310cabdff1aSopenharmony_ci 1311cabdff1aSopenharmony_ci }, 1312cabdff1aSopenharmony_ci .p.priv_class = &ffv1_class, 1313cabdff1aSopenharmony_ci .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP, 1314cabdff1aSopenharmony_ci}; 1315