1cabdff1aSopenharmony_ci/* 2cabdff1aSopenharmony_ci * SpeedHQ encoder 3cabdff1aSopenharmony_ci * Copyright (c) 2000, 2001 Fabrice Bellard 4cabdff1aSopenharmony_ci * Copyright (c) 2003 Alex Beregszaszi 5cabdff1aSopenharmony_ci * Copyright (c) 2003-2004 Michael Niedermayer 6cabdff1aSopenharmony_ci * Copyright (c) 2020 FFmpeg 7cabdff1aSopenharmony_ci * 8cabdff1aSopenharmony_ci * This file is part of FFmpeg. 9cabdff1aSopenharmony_ci * 10cabdff1aSopenharmony_ci * FFmpeg is free software; you can redistribute it and/or 11cabdff1aSopenharmony_ci * modify it under the terms of the GNU Lesser General Public 12cabdff1aSopenharmony_ci * License as published by the Free Software Foundation; either 13cabdff1aSopenharmony_ci * version 2.1 of the License, or (at your option) any later version. 14cabdff1aSopenharmony_ci * 15cabdff1aSopenharmony_ci * FFmpeg is distributed in the hope that it will be useful, 16cabdff1aSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of 17cabdff1aSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 18cabdff1aSopenharmony_ci * Lesser General Public License for more details. 19cabdff1aSopenharmony_ci * 20cabdff1aSopenharmony_ci * You should have received a copy of the GNU Lesser General Public 21cabdff1aSopenharmony_ci * License along with FFmpeg; if not, write to the Free Software 22cabdff1aSopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 23cabdff1aSopenharmony_ci */ 24cabdff1aSopenharmony_ci 25cabdff1aSopenharmony_ci/** 26cabdff1aSopenharmony_ci * @file 27cabdff1aSopenharmony_ci * SpeedHQ encoder. 28cabdff1aSopenharmony_ci */ 29cabdff1aSopenharmony_ci 30cabdff1aSopenharmony_ci#include "config_components.h" 31cabdff1aSopenharmony_ci 32cabdff1aSopenharmony_ci#include "libavutil/thread.h" 33cabdff1aSopenharmony_ci 34cabdff1aSopenharmony_ci#include "avcodec.h" 35cabdff1aSopenharmony_ci#include "codec_internal.h" 36cabdff1aSopenharmony_ci#include "mpeg12data.h" 37cabdff1aSopenharmony_ci#include "mpeg12enc.h" 38cabdff1aSopenharmony_ci#include "mpegvideo.h" 39cabdff1aSopenharmony_ci#include "mpegvideoenc.h" 40cabdff1aSopenharmony_ci#include "speedhqenc.h" 41cabdff1aSopenharmony_ci 42cabdff1aSopenharmony_ciextern RLTable ff_rl_speedhq; 43cabdff1aSopenharmony_cistatic uint8_t speedhq_static_rl_table_store[2][2*MAX_RUN + MAX_LEVEL + 3]; 44cabdff1aSopenharmony_ci 45cabdff1aSopenharmony_ci/* Exactly the same as MPEG-2, except little-endian. */ 46cabdff1aSopenharmony_cistatic const uint16_t mpeg12_vlc_dc_lum_code_reversed[12] = { 47cabdff1aSopenharmony_ci 0x1, 0x0, 0x2, 0x5, 0x3, 0x7, 0xF, 0x1F, 0x3F, 0x7F, 0xFF, 0x1FF 48cabdff1aSopenharmony_ci}; 49cabdff1aSopenharmony_cistatic const uint16_t mpeg12_vlc_dc_chroma_code_reversed[12] = { 50cabdff1aSopenharmony_ci 0x0, 0x2, 0x1, 0x3, 0x7, 0xF, 0x1F, 0x3F, 0x7F, 0xFF, 0x1FF, 0x3FF 51cabdff1aSopenharmony_ci}; 52cabdff1aSopenharmony_ci 53cabdff1aSopenharmony_ci/* simple include everything table for dc, first byte is bits 54cabdff1aSopenharmony_ci * number next 3 are code */ 55cabdff1aSopenharmony_cistatic uint32_t speedhq_lum_dc_uni[512]; 56cabdff1aSopenharmony_cistatic uint32_t speedhq_chr_dc_uni[512]; 57cabdff1aSopenharmony_ci 58cabdff1aSopenharmony_cistatic uint8_t uni_speedhq_ac_vlc_len[64 * 64 * 2]; 59cabdff1aSopenharmony_ci 60cabdff1aSopenharmony_citypedef struct SpeedHQEncContext { 61cabdff1aSopenharmony_ci MpegEncContext m; 62cabdff1aSopenharmony_ci 63cabdff1aSopenharmony_ci int slice_start; 64cabdff1aSopenharmony_ci} SpeedHQEncContext; 65cabdff1aSopenharmony_ci 66cabdff1aSopenharmony_cistatic av_cold void speedhq_init_static_data(void) 67cabdff1aSopenharmony_ci{ 68cabdff1aSopenharmony_ci ff_rl_init(&ff_rl_speedhq, speedhq_static_rl_table_store); 69cabdff1aSopenharmony_ci 70cabdff1aSopenharmony_ci /* build unified dc encoding tables */ 71cabdff1aSopenharmony_ci for (int i = -255; i < 256; i++) { 72cabdff1aSopenharmony_ci int adiff, index; 73cabdff1aSopenharmony_ci int bits, code; 74cabdff1aSopenharmony_ci int diff = i; 75cabdff1aSopenharmony_ci 76cabdff1aSopenharmony_ci adiff = FFABS(diff); 77cabdff1aSopenharmony_ci if (diff < 0) 78cabdff1aSopenharmony_ci diff--; 79cabdff1aSopenharmony_ci index = av_log2(2 * adiff); 80cabdff1aSopenharmony_ci 81cabdff1aSopenharmony_ci bits = ff_mpeg12_vlc_dc_lum_bits[index] + index; 82cabdff1aSopenharmony_ci code = mpeg12_vlc_dc_lum_code_reversed[index] + 83cabdff1aSopenharmony_ci (av_mod_uintp2(diff, index) << ff_mpeg12_vlc_dc_lum_bits[index]); 84cabdff1aSopenharmony_ci speedhq_lum_dc_uni[i + 255] = bits + (code << 8); 85cabdff1aSopenharmony_ci 86cabdff1aSopenharmony_ci bits = ff_mpeg12_vlc_dc_chroma_bits[index] + index; 87cabdff1aSopenharmony_ci code = mpeg12_vlc_dc_chroma_code_reversed[index] + 88cabdff1aSopenharmony_ci (av_mod_uintp2(diff, index) << ff_mpeg12_vlc_dc_chroma_bits[index]); 89cabdff1aSopenharmony_ci speedhq_chr_dc_uni[i + 255] = bits + (code << 8); 90cabdff1aSopenharmony_ci } 91cabdff1aSopenharmony_ci 92cabdff1aSopenharmony_ci ff_mpeg1_init_uni_ac_vlc(&ff_rl_speedhq, uni_speedhq_ac_vlc_len); 93cabdff1aSopenharmony_ci} 94cabdff1aSopenharmony_ci 95cabdff1aSopenharmony_ciav_cold int ff_speedhq_encode_init(MpegEncContext *s) 96cabdff1aSopenharmony_ci{ 97cabdff1aSopenharmony_ci static AVOnce init_static_once = AV_ONCE_INIT; 98cabdff1aSopenharmony_ci 99cabdff1aSopenharmony_ci if (s->width > 65500 || s->height > 65500) { 100cabdff1aSopenharmony_ci av_log(s, AV_LOG_ERROR, "SpeedHQ does not support resolutions above 65500x65500\n"); 101cabdff1aSopenharmony_ci return AVERROR(EINVAL); 102cabdff1aSopenharmony_ci } 103cabdff1aSopenharmony_ci 104cabdff1aSopenharmony_ci s->min_qcoeff = -2048; 105cabdff1aSopenharmony_ci s->max_qcoeff = 2047; 106cabdff1aSopenharmony_ci 107cabdff1aSopenharmony_ci ff_thread_once(&init_static_once, speedhq_init_static_data); 108cabdff1aSopenharmony_ci 109cabdff1aSopenharmony_ci s->intra_ac_vlc_length = 110cabdff1aSopenharmony_ci s->intra_ac_vlc_last_length = 111cabdff1aSopenharmony_ci s->intra_chroma_ac_vlc_length = 112cabdff1aSopenharmony_ci s->intra_chroma_ac_vlc_last_length = uni_speedhq_ac_vlc_len; 113cabdff1aSopenharmony_ci 114cabdff1aSopenharmony_ci switch (s->avctx->pix_fmt) { 115cabdff1aSopenharmony_ci case AV_PIX_FMT_YUV420P: 116cabdff1aSopenharmony_ci s->avctx->codec_tag = MKTAG('S','H','Q','0'); 117cabdff1aSopenharmony_ci break; 118cabdff1aSopenharmony_ci case AV_PIX_FMT_YUV422P: 119cabdff1aSopenharmony_ci s->avctx->codec_tag = MKTAG('S','H','Q','2'); 120cabdff1aSopenharmony_ci break; 121cabdff1aSopenharmony_ci case AV_PIX_FMT_YUV444P: 122cabdff1aSopenharmony_ci s->avctx->codec_tag = MKTAG('S','H','Q','4'); 123cabdff1aSopenharmony_ci break; 124cabdff1aSopenharmony_ci default: 125cabdff1aSopenharmony_ci av_assert0(0); 126cabdff1aSopenharmony_ci } 127cabdff1aSopenharmony_ci 128cabdff1aSopenharmony_ci return 0; 129cabdff1aSopenharmony_ci} 130cabdff1aSopenharmony_ci 131cabdff1aSopenharmony_civoid ff_speedhq_encode_picture_header(MpegEncContext *s) 132cabdff1aSopenharmony_ci{ 133cabdff1aSopenharmony_ci SpeedHQEncContext *ctx = (SpeedHQEncContext*)s; 134cabdff1aSopenharmony_ci 135cabdff1aSopenharmony_ci put_bits_le(&s->pb, 8, 100 - s->qscale * 2); /* FIXME why doubled */ 136cabdff1aSopenharmony_ci put_bits_le(&s->pb, 24, 4); /* no second field */ 137cabdff1aSopenharmony_ci 138cabdff1aSopenharmony_ci ctx->slice_start = 4; 139cabdff1aSopenharmony_ci /* length of first slice, will be filled out later */ 140cabdff1aSopenharmony_ci put_bits_le(&s->pb, 24, 0); 141cabdff1aSopenharmony_ci} 142cabdff1aSopenharmony_ci 143cabdff1aSopenharmony_civoid ff_speedhq_end_slice(MpegEncContext *s) 144cabdff1aSopenharmony_ci{ 145cabdff1aSopenharmony_ci SpeedHQEncContext *ctx = (SpeedHQEncContext*)s; 146cabdff1aSopenharmony_ci int slice_len; 147cabdff1aSopenharmony_ci 148cabdff1aSopenharmony_ci flush_put_bits_le(&s->pb); 149cabdff1aSopenharmony_ci slice_len = put_bytes_output(&s->pb) - ctx->slice_start; 150cabdff1aSopenharmony_ci AV_WL24(s->pb.buf + ctx->slice_start, slice_len); 151cabdff1aSopenharmony_ci 152cabdff1aSopenharmony_ci /* length of next slice, will be filled out later */ 153cabdff1aSopenharmony_ci ctx->slice_start = put_bytes_output(&s->pb); 154cabdff1aSopenharmony_ci put_bits_le(&s->pb, 24, 0); 155cabdff1aSopenharmony_ci} 156cabdff1aSopenharmony_ci 157cabdff1aSopenharmony_cistatic inline void encode_dc(PutBitContext *pb, int diff, int component) 158cabdff1aSopenharmony_ci{ 159cabdff1aSopenharmony_ci unsigned int diff_u = diff + 255; 160cabdff1aSopenharmony_ci if (diff_u >= 511) { 161cabdff1aSopenharmony_ci int index; 162cabdff1aSopenharmony_ci 163cabdff1aSopenharmony_ci if (diff < 0) { 164cabdff1aSopenharmony_ci index = av_log2_16bit(-2 * diff); 165cabdff1aSopenharmony_ci diff--; 166cabdff1aSopenharmony_ci } else { 167cabdff1aSopenharmony_ci index = av_log2_16bit(2 * diff); 168cabdff1aSopenharmony_ci } 169cabdff1aSopenharmony_ci if (component == 0) 170cabdff1aSopenharmony_ci put_bits_le(pb, 171cabdff1aSopenharmony_ci ff_mpeg12_vlc_dc_lum_bits[index] + index, 172cabdff1aSopenharmony_ci mpeg12_vlc_dc_lum_code_reversed[index] + 173cabdff1aSopenharmony_ci (av_mod_uintp2(diff, index) << ff_mpeg12_vlc_dc_lum_bits[index])); 174cabdff1aSopenharmony_ci else 175cabdff1aSopenharmony_ci put_bits_le(pb, 176cabdff1aSopenharmony_ci ff_mpeg12_vlc_dc_chroma_bits[index] + index, 177cabdff1aSopenharmony_ci mpeg12_vlc_dc_chroma_code_reversed[index] + 178cabdff1aSopenharmony_ci (av_mod_uintp2(diff, index) << ff_mpeg12_vlc_dc_chroma_bits[index])); 179cabdff1aSopenharmony_ci } else { 180cabdff1aSopenharmony_ci if (component == 0) 181cabdff1aSopenharmony_ci put_bits_le(pb, 182cabdff1aSopenharmony_ci speedhq_lum_dc_uni[diff + 255] & 0xFF, 183cabdff1aSopenharmony_ci speedhq_lum_dc_uni[diff + 255] >> 8); 184cabdff1aSopenharmony_ci else 185cabdff1aSopenharmony_ci put_bits_le(pb, 186cabdff1aSopenharmony_ci speedhq_chr_dc_uni[diff + 255] & 0xFF, 187cabdff1aSopenharmony_ci speedhq_chr_dc_uni[diff + 255] >> 8); 188cabdff1aSopenharmony_ci } 189cabdff1aSopenharmony_ci} 190cabdff1aSopenharmony_ci 191cabdff1aSopenharmony_cistatic void encode_block(MpegEncContext *s, int16_t *block, int n) 192cabdff1aSopenharmony_ci{ 193cabdff1aSopenharmony_ci int alevel, level, last_non_zero, dc, i, j, run, last_index, sign; 194cabdff1aSopenharmony_ci int code; 195cabdff1aSopenharmony_ci int component, val; 196cabdff1aSopenharmony_ci 197cabdff1aSopenharmony_ci /* DC coef */ 198cabdff1aSopenharmony_ci component = (n <= 3 ? 0 : (n&1) + 1); 199cabdff1aSopenharmony_ci dc = block[0]; /* overflow is impossible */ 200cabdff1aSopenharmony_ci val = s->last_dc[component] - dc; /* opposite of most codecs */ 201cabdff1aSopenharmony_ci encode_dc(&s->pb, val, component); 202cabdff1aSopenharmony_ci s->last_dc[component] = dc; 203cabdff1aSopenharmony_ci 204cabdff1aSopenharmony_ci /* now quantify & encode AC coefs */ 205cabdff1aSopenharmony_ci last_non_zero = 0; 206cabdff1aSopenharmony_ci last_index = s->block_last_index[n]; 207cabdff1aSopenharmony_ci 208cabdff1aSopenharmony_ci for (i = 1; i <= last_index; i++) { 209cabdff1aSopenharmony_ci j = s->intra_scantable.permutated[i]; 210cabdff1aSopenharmony_ci level = block[j]; 211cabdff1aSopenharmony_ci 212cabdff1aSopenharmony_ci /* encode using VLC */ 213cabdff1aSopenharmony_ci if (level != 0) { 214cabdff1aSopenharmony_ci run = i - last_non_zero - 1; 215cabdff1aSopenharmony_ci 216cabdff1aSopenharmony_ci alevel = level; 217cabdff1aSopenharmony_ci MASK_ABS(sign, alevel); 218cabdff1aSopenharmony_ci sign &= 1; 219cabdff1aSopenharmony_ci 220cabdff1aSopenharmony_ci if (alevel <= ff_rl_speedhq.max_level[0][run]) { 221cabdff1aSopenharmony_ci code = ff_rl_speedhq.index_run[0][run] + alevel - 1; 222cabdff1aSopenharmony_ci /* store the VLC & sign at once */ 223cabdff1aSopenharmony_ci put_bits_le(&s->pb, ff_rl_speedhq.table_vlc[code][1] + 1, 224cabdff1aSopenharmony_ci ff_rl_speedhq.table_vlc[code][0] + (sign << ff_rl_speedhq.table_vlc[code][1])); 225cabdff1aSopenharmony_ci } else { 226cabdff1aSopenharmony_ci /* escape seems to be pretty rare <5% so I do not optimize it; 227cabdff1aSopenharmony_ci * the values correspond to ff_rl_speedhq.table_vlc[121] */ 228cabdff1aSopenharmony_ci put_bits_le(&s->pb, 6, 32); 229cabdff1aSopenharmony_ci /* escape: only clip in this case */ 230cabdff1aSopenharmony_ci put_bits_le(&s->pb, 6, run); 231cabdff1aSopenharmony_ci put_bits_le(&s->pb, 12, level + 2048); 232cabdff1aSopenharmony_ci } 233cabdff1aSopenharmony_ci last_non_zero = i; 234cabdff1aSopenharmony_ci } 235cabdff1aSopenharmony_ci } 236cabdff1aSopenharmony_ci /* end of block; the values correspond to ff_rl_speedhq.table_vlc[122] */ 237cabdff1aSopenharmony_ci put_bits_le(&s->pb, 4, 6); 238cabdff1aSopenharmony_ci} 239cabdff1aSopenharmony_ci 240cabdff1aSopenharmony_civoid ff_speedhq_encode_mb(MpegEncContext *s, int16_t block[12][64]) 241cabdff1aSopenharmony_ci{ 242cabdff1aSopenharmony_ci int i; 243cabdff1aSopenharmony_ci for(i=0;i<6;i++) { 244cabdff1aSopenharmony_ci encode_block(s, block[i], i); 245cabdff1aSopenharmony_ci } 246cabdff1aSopenharmony_ci if (s->chroma_format == CHROMA_444) { 247cabdff1aSopenharmony_ci encode_block(s, block[8], 8); 248cabdff1aSopenharmony_ci encode_block(s, block[9], 9); 249cabdff1aSopenharmony_ci 250cabdff1aSopenharmony_ci encode_block(s, block[6], 6); 251cabdff1aSopenharmony_ci encode_block(s, block[7], 7); 252cabdff1aSopenharmony_ci 253cabdff1aSopenharmony_ci encode_block(s, block[10], 10); 254cabdff1aSopenharmony_ci encode_block(s, block[11], 11); 255cabdff1aSopenharmony_ci } else if (s->chroma_format == CHROMA_422) { 256cabdff1aSopenharmony_ci encode_block(s, block[6], 6); 257cabdff1aSopenharmony_ci encode_block(s, block[7], 7); 258cabdff1aSopenharmony_ci } 259cabdff1aSopenharmony_ci 260cabdff1aSopenharmony_ci s->i_tex_bits += get_bits_diff(s); 261cabdff1aSopenharmony_ci} 262cabdff1aSopenharmony_ci 263cabdff1aSopenharmony_cistatic int ff_speedhq_mb_rows_in_slice(int slice_num, int mb_height) 264cabdff1aSopenharmony_ci{ 265cabdff1aSopenharmony_ci return mb_height / 4 + (slice_num < (mb_height % 4)); 266cabdff1aSopenharmony_ci} 267cabdff1aSopenharmony_ci 268cabdff1aSopenharmony_ciint ff_speedhq_mb_y_order_to_mb(int mb_y_order, int mb_height, int *first_in_slice) 269cabdff1aSopenharmony_ci{ 270cabdff1aSopenharmony_ci int slice_num = 0; 271cabdff1aSopenharmony_ci while (mb_y_order >= ff_speedhq_mb_rows_in_slice(slice_num, mb_height)) { 272cabdff1aSopenharmony_ci mb_y_order -= ff_speedhq_mb_rows_in_slice(slice_num, mb_height); 273cabdff1aSopenharmony_ci slice_num++; 274cabdff1aSopenharmony_ci } 275cabdff1aSopenharmony_ci *first_in_slice = (mb_y_order == 0); 276cabdff1aSopenharmony_ci return mb_y_order * 4 + slice_num; 277cabdff1aSopenharmony_ci} 278cabdff1aSopenharmony_ci 279cabdff1aSopenharmony_ci#if CONFIG_SPEEDHQ_ENCODER 280cabdff1aSopenharmony_ciconst FFCodec ff_speedhq_encoder = { 281cabdff1aSopenharmony_ci .p.name = "speedhq", 282cabdff1aSopenharmony_ci .p.long_name = NULL_IF_CONFIG_SMALL("NewTek SpeedHQ"), 283cabdff1aSopenharmony_ci .p.type = AVMEDIA_TYPE_VIDEO, 284cabdff1aSopenharmony_ci .p.id = AV_CODEC_ID_SPEEDHQ, 285cabdff1aSopenharmony_ci .p.priv_class = &ff_mpv_enc_class, 286cabdff1aSopenharmony_ci .priv_data_size = sizeof(SpeedHQEncContext), 287cabdff1aSopenharmony_ci .init = ff_mpv_encode_init, 288cabdff1aSopenharmony_ci FF_CODEC_ENCODE_CB(ff_mpv_encode_picture), 289cabdff1aSopenharmony_ci .close = ff_mpv_encode_end, 290cabdff1aSopenharmony_ci .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP, 291cabdff1aSopenharmony_ci .p.pix_fmts = (const enum AVPixelFormat[]) { 292cabdff1aSopenharmony_ci AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV444P, 293cabdff1aSopenharmony_ci AV_PIX_FMT_NONE 294cabdff1aSopenharmony_ci }, 295cabdff1aSopenharmony_ci}; 296cabdff1aSopenharmony_ci#endif 297