1cabdff1aSopenharmony_ci/* 2cabdff1aSopenharmony_ci * This file is part of FFmpeg. 3cabdff1aSopenharmony_ci * 4cabdff1aSopenharmony_ci * FFmpeg is free software; you can redistribute it and/or 5cabdff1aSopenharmony_ci * modify it under the terms of the GNU Lesser General Public 6cabdff1aSopenharmony_ci * License as published by the Free Software Foundation; either 7cabdff1aSopenharmony_ci * version 2.1 of the License, or (at your option) any later version. 8cabdff1aSopenharmony_ci * 9cabdff1aSopenharmony_ci * FFmpeg is distributed in the hope that it will be useful, 10cabdff1aSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of 11cabdff1aSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12cabdff1aSopenharmony_ci * Lesser General Public License for more details. 13cabdff1aSopenharmony_ci * 14cabdff1aSopenharmony_ci * You should have received a copy of the GNU Lesser General Public 15cabdff1aSopenharmony_ci * License along with FFmpeg; if not, write to the Free Software 16cabdff1aSopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17cabdff1aSopenharmony_ci */ 18cabdff1aSopenharmony_ci 19cabdff1aSopenharmony_ci#include "libavutil/attributes.h" 20cabdff1aSopenharmony_ci#include "libavutil/avassert.h" 21cabdff1aSopenharmony_ci 22cabdff1aSopenharmony_ci#include "bytestream.h" 23cabdff1aSopenharmony_ci#include "cbs.h" 24cabdff1aSopenharmony_ci#include "cbs_internal.h" 25cabdff1aSopenharmony_ci#include "cbs_h264.h" 26cabdff1aSopenharmony_ci#include "cbs_h265.h" 27cabdff1aSopenharmony_ci#include "h264.h" 28cabdff1aSopenharmony_ci#include "h2645_parse.h" 29cabdff1aSopenharmony_ci#include "hevc.h" 30cabdff1aSopenharmony_ci 31cabdff1aSopenharmony_ci 32cabdff1aSopenharmony_cistatic int cbs_read_ue_golomb(CodedBitstreamContext *ctx, GetBitContext *gbc, 33cabdff1aSopenharmony_ci const char *name, const int *subscripts, 34cabdff1aSopenharmony_ci uint32_t *write_to, 35cabdff1aSopenharmony_ci uint32_t range_min, uint32_t range_max) 36cabdff1aSopenharmony_ci{ 37cabdff1aSopenharmony_ci uint32_t value; 38cabdff1aSopenharmony_ci int position, i, j; 39cabdff1aSopenharmony_ci unsigned int k; 40cabdff1aSopenharmony_ci char bits[65]; 41cabdff1aSopenharmony_ci 42cabdff1aSopenharmony_ci position = get_bits_count(gbc); 43cabdff1aSopenharmony_ci 44cabdff1aSopenharmony_ci for (i = 0; i < 32; i++) { 45cabdff1aSopenharmony_ci if (get_bits_left(gbc) < i + 1) { 46cabdff1aSopenharmony_ci av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid ue-golomb code at " 47cabdff1aSopenharmony_ci "%s: bitstream ended.\n", name); 48cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 49cabdff1aSopenharmony_ci } 50cabdff1aSopenharmony_ci k = get_bits1(gbc); 51cabdff1aSopenharmony_ci bits[i] = k ? '1' : '0'; 52cabdff1aSopenharmony_ci if (k) 53cabdff1aSopenharmony_ci break; 54cabdff1aSopenharmony_ci } 55cabdff1aSopenharmony_ci if (i >= 32) { 56cabdff1aSopenharmony_ci av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid ue-golomb code at " 57cabdff1aSopenharmony_ci "%s: more than 31 zeroes.\n", name); 58cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 59cabdff1aSopenharmony_ci } 60cabdff1aSopenharmony_ci value = 1; 61cabdff1aSopenharmony_ci for (j = 0; j < i; j++) { 62cabdff1aSopenharmony_ci k = get_bits1(gbc); 63cabdff1aSopenharmony_ci bits[i + j + 1] = k ? '1' : '0'; 64cabdff1aSopenharmony_ci value = value << 1 | k; 65cabdff1aSopenharmony_ci } 66cabdff1aSopenharmony_ci bits[i + j + 1] = 0; 67cabdff1aSopenharmony_ci --value; 68cabdff1aSopenharmony_ci 69cabdff1aSopenharmony_ci if (ctx->trace_enable) 70cabdff1aSopenharmony_ci ff_cbs_trace_syntax_element(ctx, position, name, subscripts, 71cabdff1aSopenharmony_ci bits, value); 72cabdff1aSopenharmony_ci 73cabdff1aSopenharmony_ci if (value < range_min || value > range_max) { 74cabdff1aSopenharmony_ci av_log(ctx->log_ctx, AV_LOG_ERROR, "%s out of range: " 75cabdff1aSopenharmony_ci "%"PRIu32", but must be in [%"PRIu32",%"PRIu32"].\n", 76cabdff1aSopenharmony_ci name, value, range_min, range_max); 77cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 78cabdff1aSopenharmony_ci } 79cabdff1aSopenharmony_ci 80cabdff1aSopenharmony_ci *write_to = value; 81cabdff1aSopenharmony_ci return 0; 82cabdff1aSopenharmony_ci} 83cabdff1aSopenharmony_ci 84cabdff1aSopenharmony_cistatic int cbs_read_se_golomb(CodedBitstreamContext *ctx, GetBitContext *gbc, 85cabdff1aSopenharmony_ci const char *name, const int *subscripts, 86cabdff1aSopenharmony_ci int32_t *write_to, 87cabdff1aSopenharmony_ci int32_t range_min, int32_t range_max) 88cabdff1aSopenharmony_ci{ 89cabdff1aSopenharmony_ci int32_t value; 90cabdff1aSopenharmony_ci int position, i, j; 91cabdff1aSopenharmony_ci unsigned int k; 92cabdff1aSopenharmony_ci uint32_t v; 93cabdff1aSopenharmony_ci char bits[65]; 94cabdff1aSopenharmony_ci 95cabdff1aSopenharmony_ci position = get_bits_count(gbc); 96cabdff1aSopenharmony_ci 97cabdff1aSopenharmony_ci for (i = 0; i < 32; i++) { 98cabdff1aSopenharmony_ci if (get_bits_left(gbc) < i + 1) { 99cabdff1aSopenharmony_ci av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid se-golomb code at " 100cabdff1aSopenharmony_ci "%s: bitstream ended.\n", name); 101cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 102cabdff1aSopenharmony_ci } 103cabdff1aSopenharmony_ci k = get_bits1(gbc); 104cabdff1aSopenharmony_ci bits[i] = k ? '1' : '0'; 105cabdff1aSopenharmony_ci if (k) 106cabdff1aSopenharmony_ci break; 107cabdff1aSopenharmony_ci } 108cabdff1aSopenharmony_ci if (i >= 32) { 109cabdff1aSopenharmony_ci av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid se-golomb code at " 110cabdff1aSopenharmony_ci "%s: more than 31 zeroes.\n", name); 111cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 112cabdff1aSopenharmony_ci } 113cabdff1aSopenharmony_ci v = 1; 114cabdff1aSopenharmony_ci for (j = 0; j < i; j++) { 115cabdff1aSopenharmony_ci k = get_bits1(gbc); 116cabdff1aSopenharmony_ci bits[i + j + 1] = k ? '1' : '0'; 117cabdff1aSopenharmony_ci v = v << 1 | k; 118cabdff1aSopenharmony_ci } 119cabdff1aSopenharmony_ci bits[i + j + 1] = 0; 120cabdff1aSopenharmony_ci if (v & 1) 121cabdff1aSopenharmony_ci value = -(int32_t)(v / 2); 122cabdff1aSopenharmony_ci else 123cabdff1aSopenharmony_ci value = v / 2; 124cabdff1aSopenharmony_ci 125cabdff1aSopenharmony_ci if (ctx->trace_enable) 126cabdff1aSopenharmony_ci ff_cbs_trace_syntax_element(ctx, position, name, subscripts, 127cabdff1aSopenharmony_ci bits, value); 128cabdff1aSopenharmony_ci 129cabdff1aSopenharmony_ci if (value < range_min || value > range_max) { 130cabdff1aSopenharmony_ci av_log(ctx->log_ctx, AV_LOG_ERROR, "%s out of range: " 131cabdff1aSopenharmony_ci "%"PRId32", but must be in [%"PRId32",%"PRId32"].\n", 132cabdff1aSopenharmony_ci name, value, range_min, range_max); 133cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 134cabdff1aSopenharmony_ci } 135cabdff1aSopenharmony_ci 136cabdff1aSopenharmony_ci *write_to = value; 137cabdff1aSopenharmony_ci return 0; 138cabdff1aSopenharmony_ci} 139cabdff1aSopenharmony_ci 140cabdff1aSopenharmony_cistatic int cbs_write_ue_golomb(CodedBitstreamContext *ctx, PutBitContext *pbc, 141cabdff1aSopenharmony_ci const char *name, const int *subscripts, 142cabdff1aSopenharmony_ci uint32_t value, 143cabdff1aSopenharmony_ci uint32_t range_min, uint32_t range_max) 144cabdff1aSopenharmony_ci{ 145cabdff1aSopenharmony_ci int len; 146cabdff1aSopenharmony_ci 147cabdff1aSopenharmony_ci if (value < range_min || value > range_max) { 148cabdff1aSopenharmony_ci av_log(ctx->log_ctx, AV_LOG_ERROR, "%s out of range: " 149cabdff1aSopenharmony_ci "%"PRIu32", but must be in [%"PRIu32",%"PRIu32"].\n", 150cabdff1aSopenharmony_ci name, value, range_min, range_max); 151cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 152cabdff1aSopenharmony_ci } 153cabdff1aSopenharmony_ci av_assert0(value != UINT32_MAX); 154cabdff1aSopenharmony_ci 155cabdff1aSopenharmony_ci len = av_log2(value + 1); 156cabdff1aSopenharmony_ci if (put_bits_left(pbc) < 2 * len + 1) 157cabdff1aSopenharmony_ci return AVERROR(ENOSPC); 158cabdff1aSopenharmony_ci 159cabdff1aSopenharmony_ci if (ctx->trace_enable) { 160cabdff1aSopenharmony_ci char bits[65]; 161cabdff1aSopenharmony_ci int i; 162cabdff1aSopenharmony_ci 163cabdff1aSopenharmony_ci for (i = 0; i < len; i++) 164cabdff1aSopenharmony_ci bits[i] = '0'; 165cabdff1aSopenharmony_ci bits[len] = '1'; 166cabdff1aSopenharmony_ci for (i = 0; i < len; i++) 167cabdff1aSopenharmony_ci bits[len + i + 1] = (value + 1) >> (len - i - 1) & 1 ? '1' : '0'; 168cabdff1aSopenharmony_ci bits[len + len + 1] = 0; 169cabdff1aSopenharmony_ci 170cabdff1aSopenharmony_ci ff_cbs_trace_syntax_element(ctx, put_bits_count(pbc), 171cabdff1aSopenharmony_ci name, subscripts, bits, value); 172cabdff1aSopenharmony_ci } 173cabdff1aSopenharmony_ci 174cabdff1aSopenharmony_ci put_bits(pbc, len, 0); 175cabdff1aSopenharmony_ci if (len + 1 < 32) 176cabdff1aSopenharmony_ci put_bits(pbc, len + 1, value + 1); 177cabdff1aSopenharmony_ci else 178cabdff1aSopenharmony_ci put_bits32(pbc, value + 1); 179cabdff1aSopenharmony_ci 180cabdff1aSopenharmony_ci return 0; 181cabdff1aSopenharmony_ci} 182cabdff1aSopenharmony_ci 183cabdff1aSopenharmony_cistatic int cbs_write_se_golomb(CodedBitstreamContext *ctx, PutBitContext *pbc, 184cabdff1aSopenharmony_ci const char *name, const int *subscripts, 185cabdff1aSopenharmony_ci int32_t value, 186cabdff1aSopenharmony_ci int32_t range_min, int32_t range_max) 187cabdff1aSopenharmony_ci{ 188cabdff1aSopenharmony_ci int len; 189cabdff1aSopenharmony_ci uint32_t uvalue; 190cabdff1aSopenharmony_ci 191cabdff1aSopenharmony_ci if (value < range_min || value > range_max) { 192cabdff1aSopenharmony_ci av_log(ctx->log_ctx, AV_LOG_ERROR, "%s out of range: " 193cabdff1aSopenharmony_ci "%"PRId32", but must be in [%"PRId32",%"PRId32"].\n", 194cabdff1aSopenharmony_ci name, value, range_min, range_max); 195cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 196cabdff1aSopenharmony_ci } 197cabdff1aSopenharmony_ci av_assert0(value != INT32_MIN); 198cabdff1aSopenharmony_ci 199cabdff1aSopenharmony_ci if (value == 0) 200cabdff1aSopenharmony_ci uvalue = 0; 201cabdff1aSopenharmony_ci else if (value > 0) 202cabdff1aSopenharmony_ci uvalue = 2 * (uint32_t)value - 1; 203cabdff1aSopenharmony_ci else 204cabdff1aSopenharmony_ci uvalue = 2 * (uint32_t)-value; 205cabdff1aSopenharmony_ci 206cabdff1aSopenharmony_ci len = av_log2(uvalue + 1); 207cabdff1aSopenharmony_ci if (put_bits_left(pbc) < 2 * len + 1) 208cabdff1aSopenharmony_ci return AVERROR(ENOSPC); 209cabdff1aSopenharmony_ci 210cabdff1aSopenharmony_ci if (ctx->trace_enable) { 211cabdff1aSopenharmony_ci char bits[65]; 212cabdff1aSopenharmony_ci int i; 213cabdff1aSopenharmony_ci 214cabdff1aSopenharmony_ci for (i = 0; i < len; i++) 215cabdff1aSopenharmony_ci bits[i] = '0'; 216cabdff1aSopenharmony_ci bits[len] = '1'; 217cabdff1aSopenharmony_ci for (i = 0; i < len; i++) 218cabdff1aSopenharmony_ci bits[len + i + 1] = (uvalue + 1) >> (len - i - 1) & 1 ? '1' : '0'; 219cabdff1aSopenharmony_ci bits[len + len + 1] = 0; 220cabdff1aSopenharmony_ci 221cabdff1aSopenharmony_ci ff_cbs_trace_syntax_element(ctx, put_bits_count(pbc), 222cabdff1aSopenharmony_ci name, subscripts, bits, value); 223cabdff1aSopenharmony_ci } 224cabdff1aSopenharmony_ci 225cabdff1aSopenharmony_ci put_bits(pbc, len, 0); 226cabdff1aSopenharmony_ci if (len + 1 < 32) 227cabdff1aSopenharmony_ci put_bits(pbc, len + 1, uvalue + 1); 228cabdff1aSopenharmony_ci else 229cabdff1aSopenharmony_ci put_bits32(pbc, uvalue + 1); 230cabdff1aSopenharmony_ci 231cabdff1aSopenharmony_ci return 0; 232cabdff1aSopenharmony_ci} 233cabdff1aSopenharmony_ci 234cabdff1aSopenharmony_ci// payload_extension_present() - true if we are before the last 1-bit 235cabdff1aSopenharmony_ci// in the payload structure, which must be in the last byte. 236cabdff1aSopenharmony_cistatic int cbs_h265_payload_extension_present(GetBitContext *gbc, uint32_t payload_size, 237cabdff1aSopenharmony_ci int cur_pos) 238cabdff1aSopenharmony_ci{ 239cabdff1aSopenharmony_ci int bits_left = payload_size * 8 - cur_pos; 240cabdff1aSopenharmony_ci return (bits_left > 0 && 241cabdff1aSopenharmony_ci (bits_left > 7 || show_bits(gbc, bits_left) & MAX_UINT_BITS(bits_left - 1))); 242cabdff1aSopenharmony_ci} 243cabdff1aSopenharmony_ci 244cabdff1aSopenharmony_ci#define HEADER(name) do { \ 245cabdff1aSopenharmony_ci ff_cbs_trace_header(ctx, name); \ 246cabdff1aSopenharmony_ci } while (0) 247cabdff1aSopenharmony_ci 248cabdff1aSopenharmony_ci#define CHECK(call) do { \ 249cabdff1aSopenharmony_ci err = (call); \ 250cabdff1aSopenharmony_ci if (err < 0) \ 251cabdff1aSopenharmony_ci return err; \ 252cabdff1aSopenharmony_ci } while (0) 253cabdff1aSopenharmony_ci 254cabdff1aSopenharmony_ci#define FUNC_NAME2(rw, codec, name) cbs_ ## codec ## _ ## rw ## _ ## name 255cabdff1aSopenharmony_ci#define FUNC_NAME1(rw, codec, name) FUNC_NAME2(rw, codec, name) 256cabdff1aSopenharmony_ci#define FUNC_H264(name) FUNC_NAME1(READWRITE, h264, name) 257cabdff1aSopenharmony_ci#define FUNC_H265(name) FUNC_NAME1(READWRITE, h265, name) 258cabdff1aSopenharmony_ci#define FUNC_SEI(name) FUNC_NAME1(READWRITE, sei, name) 259cabdff1aSopenharmony_ci 260cabdff1aSopenharmony_ci#define SUBSCRIPTS(subs, ...) (subs > 0 ? ((int[subs + 1]){ subs, __VA_ARGS__ }) : NULL) 261cabdff1aSopenharmony_ci 262cabdff1aSopenharmony_ci#define u(width, name, range_min, range_max) \ 263cabdff1aSopenharmony_ci xu(width, name, current->name, range_min, range_max, 0, ) 264cabdff1aSopenharmony_ci#define ub(width, name) \ 265cabdff1aSopenharmony_ci xu(width, name, current->name, 0, MAX_UINT_BITS(width), 0, ) 266cabdff1aSopenharmony_ci#define flag(name) ub(1, name) 267cabdff1aSopenharmony_ci#define ue(name, range_min, range_max) \ 268cabdff1aSopenharmony_ci xue(name, current->name, range_min, range_max, 0, ) 269cabdff1aSopenharmony_ci#define i(width, name, range_min, range_max) \ 270cabdff1aSopenharmony_ci xi(width, name, current->name, range_min, range_max, 0, ) 271cabdff1aSopenharmony_ci#define ib(width, name) \ 272cabdff1aSopenharmony_ci xi(width, name, current->name, MIN_INT_BITS(width), MAX_INT_BITS(width), 0, ) 273cabdff1aSopenharmony_ci#define se(name, range_min, range_max) \ 274cabdff1aSopenharmony_ci xse(name, current->name, range_min, range_max, 0, ) 275cabdff1aSopenharmony_ci 276cabdff1aSopenharmony_ci#define us(width, name, range_min, range_max, subs, ...) \ 277cabdff1aSopenharmony_ci xu(width, name, current->name, range_min, range_max, subs, __VA_ARGS__) 278cabdff1aSopenharmony_ci#define ubs(width, name, subs, ...) \ 279cabdff1aSopenharmony_ci xu(width, name, current->name, 0, MAX_UINT_BITS(width), subs, __VA_ARGS__) 280cabdff1aSopenharmony_ci#define flags(name, subs, ...) \ 281cabdff1aSopenharmony_ci xu(1, name, current->name, 0, 1, subs, __VA_ARGS__) 282cabdff1aSopenharmony_ci#define ues(name, range_min, range_max, subs, ...) \ 283cabdff1aSopenharmony_ci xue(name, current->name, range_min, range_max, subs, __VA_ARGS__) 284cabdff1aSopenharmony_ci#define is(width, name, range_min, range_max, subs, ...) \ 285cabdff1aSopenharmony_ci xi(width, name, current->name, range_min, range_max, subs, __VA_ARGS__) 286cabdff1aSopenharmony_ci#define ibs(width, name, subs, ...) \ 287cabdff1aSopenharmony_ci xi(width, name, current->name, MIN_INT_BITS(width), MAX_INT_BITS(width), subs, __VA_ARGS__) 288cabdff1aSopenharmony_ci#define ses(name, range_min, range_max, subs, ...) \ 289cabdff1aSopenharmony_ci xse(name, current->name, range_min, range_max, subs, __VA_ARGS__) 290cabdff1aSopenharmony_ci 291cabdff1aSopenharmony_ci#define fixed(width, name, value) do { \ 292cabdff1aSopenharmony_ci av_unused uint32_t fixed_value = value; \ 293cabdff1aSopenharmony_ci xu(width, name, fixed_value, value, value, 0, ); \ 294cabdff1aSopenharmony_ci } while (0) 295cabdff1aSopenharmony_ci 296cabdff1aSopenharmony_ci 297cabdff1aSopenharmony_ci#define READ 298cabdff1aSopenharmony_ci#define READWRITE read 299cabdff1aSopenharmony_ci#define RWContext GetBitContext 300cabdff1aSopenharmony_ci 301cabdff1aSopenharmony_ci#define xu(width, name, var, range_min, range_max, subs, ...) do { \ 302cabdff1aSopenharmony_ci uint32_t value; \ 303cabdff1aSopenharmony_ci CHECK(ff_cbs_read_unsigned(ctx, rw, width, #name, \ 304cabdff1aSopenharmony_ci SUBSCRIPTS(subs, __VA_ARGS__), \ 305cabdff1aSopenharmony_ci &value, range_min, range_max)); \ 306cabdff1aSopenharmony_ci var = value; \ 307cabdff1aSopenharmony_ci } while (0) 308cabdff1aSopenharmony_ci#define xue(name, var, range_min, range_max, subs, ...) do { \ 309cabdff1aSopenharmony_ci uint32_t value; \ 310cabdff1aSopenharmony_ci CHECK(cbs_read_ue_golomb(ctx, rw, #name, \ 311cabdff1aSopenharmony_ci SUBSCRIPTS(subs, __VA_ARGS__), \ 312cabdff1aSopenharmony_ci &value, range_min, range_max)); \ 313cabdff1aSopenharmony_ci var = value; \ 314cabdff1aSopenharmony_ci } while (0) 315cabdff1aSopenharmony_ci#define xi(width, name, var, range_min, range_max, subs, ...) do { \ 316cabdff1aSopenharmony_ci int32_t value; \ 317cabdff1aSopenharmony_ci CHECK(ff_cbs_read_signed(ctx, rw, width, #name, \ 318cabdff1aSopenharmony_ci SUBSCRIPTS(subs, __VA_ARGS__), \ 319cabdff1aSopenharmony_ci &value, range_min, range_max)); \ 320cabdff1aSopenharmony_ci var = value; \ 321cabdff1aSopenharmony_ci } while (0) 322cabdff1aSopenharmony_ci#define xse(name, var, range_min, range_max, subs, ...) do { \ 323cabdff1aSopenharmony_ci int32_t value; \ 324cabdff1aSopenharmony_ci CHECK(cbs_read_se_golomb(ctx, rw, #name, \ 325cabdff1aSopenharmony_ci SUBSCRIPTS(subs, __VA_ARGS__), \ 326cabdff1aSopenharmony_ci &value, range_min, range_max)); \ 327cabdff1aSopenharmony_ci var = value; \ 328cabdff1aSopenharmony_ci } while (0) 329cabdff1aSopenharmony_ci 330cabdff1aSopenharmony_ci 331cabdff1aSopenharmony_ci#define infer(name, value) do { \ 332cabdff1aSopenharmony_ci current->name = value; \ 333cabdff1aSopenharmony_ci } while (0) 334cabdff1aSopenharmony_ci 335cabdff1aSopenharmony_cistatic int cbs_h2645_read_more_rbsp_data(GetBitContext *gbc) 336cabdff1aSopenharmony_ci{ 337cabdff1aSopenharmony_ci int bits_left = get_bits_left(gbc); 338cabdff1aSopenharmony_ci if (bits_left > 8) 339cabdff1aSopenharmony_ci return 1; 340cabdff1aSopenharmony_ci if (bits_left == 0) 341cabdff1aSopenharmony_ci return 0; 342cabdff1aSopenharmony_ci if (show_bits(gbc, bits_left) & MAX_UINT_BITS(bits_left - 1)) 343cabdff1aSopenharmony_ci return 1; 344cabdff1aSopenharmony_ci return 0; 345cabdff1aSopenharmony_ci} 346cabdff1aSopenharmony_ci 347cabdff1aSopenharmony_ci#define more_rbsp_data(var) ((var) = cbs_h2645_read_more_rbsp_data(rw)) 348cabdff1aSopenharmony_ci 349cabdff1aSopenharmony_ci#define bit_position(rw) (get_bits_count(rw)) 350cabdff1aSopenharmony_ci#define byte_alignment(rw) (get_bits_count(rw) % 8) 351cabdff1aSopenharmony_ci 352cabdff1aSopenharmony_ci#define allocate(name, size) do { \ 353cabdff1aSopenharmony_ci name ## _ref = av_buffer_allocz(size + \ 354cabdff1aSopenharmony_ci AV_INPUT_BUFFER_PADDING_SIZE); \ 355cabdff1aSopenharmony_ci if (!name ## _ref) \ 356cabdff1aSopenharmony_ci return AVERROR(ENOMEM); \ 357cabdff1aSopenharmony_ci name = name ## _ref->data; \ 358cabdff1aSopenharmony_ci } while (0) 359cabdff1aSopenharmony_ci 360cabdff1aSopenharmony_ci#define FUNC(name) FUNC_SEI(name) 361cabdff1aSopenharmony_ci#include "cbs_sei_syntax_template.c" 362cabdff1aSopenharmony_ci#undef FUNC 363cabdff1aSopenharmony_ci 364cabdff1aSopenharmony_ci#define FUNC(name) FUNC_H264(name) 365cabdff1aSopenharmony_ci#include "cbs_h264_syntax_template.c" 366cabdff1aSopenharmony_ci#undef FUNC 367cabdff1aSopenharmony_ci 368cabdff1aSopenharmony_ci#define FUNC(name) FUNC_H265(name) 369cabdff1aSopenharmony_ci#include "cbs_h265_syntax_template.c" 370cabdff1aSopenharmony_ci#undef FUNC 371cabdff1aSopenharmony_ci 372cabdff1aSopenharmony_ci#undef READ 373cabdff1aSopenharmony_ci#undef READWRITE 374cabdff1aSopenharmony_ci#undef RWContext 375cabdff1aSopenharmony_ci#undef xu 376cabdff1aSopenharmony_ci#undef xi 377cabdff1aSopenharmony_ci#undef xue 378cabdff1aSopenharmony_ci#undef xse 379cabdff1aSopenharmony_ci#undef infer 380cabdff1aSopenharmony_ci#undef more_rbsp_data 381cabdff1aSopenharmony_ci#undef bit_position 382cabdff1aSopenharmony_ci#undef byte_alignment 383cabdff1aSopenharmony_ci#undef allocate 384cabdff1aSopenharmony_ci 385cabdff1aSopenharmony_ci 386cabdff1aSopenharmony_ci#define WRITE 387cabdff1aSopenharmony_ci#define READWRITE write 388cabdff1aSopenharmony_ci#define RWContext PutBitContext 389cabdff1aSopenharmony_ci 390cabdff1aSopenharmony_ci#define xu(width, name, var, range_min, range_max, subs, ...) do { \ 391cabdff1aSopenharmony_ci uint32_t value = var; \ 392cabdff1aSopenharmony_ci CHECK(ff_cbs_write_unsigned(ctx, rw, width, #name, \ 393cabdff1aSopenharmony_ci SUBSCRIPTS(subs, __VA_ARGS__), \ 394cabdff1aSopenharmony_ci value, range_min, range_max)); \ 395cabdff1aSopenharmony_ci } while (0) 396cabdff1aSopenharmony_ci#define xue(name, var, range_min, range_max, subs, ...) do { \ 397cabdff1aSopenharmony_ci uint32_t value = var; \ 398cabdff1aSopenharmony_ci CHECK(cbs_write_ue_golomb(ctx, rw, #name, \ 399cabdff1aSopenharmony_ci SUBSCRIPTS(subs, __VA_ARGS__), \ 400cabdff1aSopenharmony_ci value, range_min, range_max)); \ 401cabdff1aSopenharmony_ci } while (0) 402cabdff1aSopenharmony_ci#define xi(width, name, var, range_min, range_max, subs, ...) do { \ 403cabdff1aSopenharmony_ci int32_t value = var; \ 404cabdff1aSopenharmony_ci CHECK(ff_cbs_write_signed(ctx, rw, width, #name, \ 405cabdff1aSopenharmony_ci SUBSCRIPTS(subs, __VA_ARGS__), \ 406cabdff1aSopenharmony_ci value, range_min, range_max)); \ 407cabdff1aSopenharmony_ci } while (0) 408cabdff1aSopenharmony_ci#define xse(name, var, range_min, range_max, subs, ...) do { \ 409cabdff1aSopenharmony_ci int32_t value = var; \ 410cabdff1aSopenharmony_ci CHECK(cbs_write_se_golomb(ctx, rw, #name, \ 411cabdff1aSopenharmony_ci SUBSCRIPTS(subs, __VA_ARGS__), \ 412cabdff1aSopenharmony_ci value, range_min, range_max)); \ 413cabdff1aSopenharmony_ci } while (0) 414cabdff1aSopenharmony_ci 415cabdff1aSopenharmony_ci#define infer(name, value) do { \ 416cabdff1aSopenharmony_ci if (current->name != (value)) { \ 417cabdff1aSopenharmony_ci av_log(ctx->log_ctx, AV_LOG_ERROR, \ 418cabdff1aSopenharmony_ci "%s does not match inferred value: " \ 419cabdff1aSopenharmony_ci "%"PRId64", but should be %"PRId64".\n", \ 420cabdff1aSopenharmony_ci #name, (int64_t)current->name, (int64_t)(value)); \ 421cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; \ 422cabdff1aSopenharmony_ci } \ 423cabdff1aSopenharmony_ci } while (0) 424cabdff1aSopenharmony_ci 425cabdff1aSopenharmony_ci#define more_rbsp_data(var) (var) 426cabdff1aSopenharmony_ci 427cabdff1aSopenharmony_ci#define bit_position(rw) (put_bits_count(rw)) 428cabdff1aSopenharmony_ci#define byte_alignment(rw) (put_bits_count(rw) % 8) 429cabdff1aSopenharmony_ci 430cabdff1aSopenharmony_ci#define allocate(name, size) do { \ 431cabdff1aSopenharmony_ci if (!name) { \ 432cabdff1aSopenharmony_ci av_log(ctx->log_ctx, AV_LOG_ERROR, "%s must be set " \ 433cabdff1aSopenharmony_ci "for writing.\n", #name); \ 434cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; \ 435cabdff1aSopenharmony_ci } \ 436cabdff1aSopenharmony_ci } while (0) 437cabdff1aSopenharmony_ci 438cabdff1aSopenharmony_ci#define FUNC(name) FUNC_SEI(name) 439cabdff1aSopenharmony_ci#include "cbs_sei_syntax_template.c" 440cabdff1aSopenharmony_ci#undef FUNC 441cabdff1aSopenharmony_ci 442cabdff1aSopenharmony_ci#define FUNC(name) FUNC_H264(name) 443cabdff1aSopenharmony_ci#include "cbs_h264_syntax_template.c" 444cabdff1aSopenharmony_ci#undef FUNC 445cabdff1aSopenharmony_ci 446cabdff1aSopenharmony_ci#define FUNC(name) FUNC_H265(name) 447cabdff1aSopenharmony_ci#include "cbs_h265_syntax_template.c" 448cabdff1aSopenharmony_ci#undef FUNC 449cabdff1aSopenharmony_ci 450cabdff1aSopenharmony_ci#undef WRITE 451cabdff1aSopenharmony_ci#undef READWRITE 452cabdff1aSopenharmony_ci#undef RWContext 453cabdff1aSopenharmony_ci#undef xu 454cabdff1aSopenharmony_ci#undef xi 455cabdff1aSopenharmony_ci#undef xue 456cabdff1aSopenharmony_ci#undef xse 457cabdff1aSopenharmony_ci#undef u 458cabdff1aSopenharmony_ci#undef i 459cabdff1aSopenharmony_ci#undef flag 460cabdff1aSopenharmony_ci#undef ue 461cabdff1aSopenharmony_ci#undef se 462cabdff1aSopenharmony_ci#undef infer 463cabdff1aSopenharmony_ci#undef more_rbsp_data 464cabdff1aSopenharmony_ci#undef bit_position 465cabdff1aSopenharmony_ci#undef byte_alignment 466cabdff1aSopenharmony_ci#undef allocate 467cabdff1aSopenharmony_ci 468cabdff1aSopenharmony_ci 469cabdff1aSopenharmony_cistatic int cbs_h2645_fragment_add_nals(CodedBitstreamContext *ctx, 470cabdff1aSopenharmony_ci CodedBitstreamFragment *frag, 471cabdff1aSopenharmony_ci const H2645Packet *packet) 472cabdff1aSopenharmony_ci{ 473cabdff1aSopenharmony_ci int err, i; 474cabdff1aSopenharmony_ci 475cabdff1aSopenharmony_ci for (i = 0; i < packet->nb_nals; i++) { 476cabdff1aSopenharmony_ci const H2645NAL *nal = &packet->nals[i]; 477cabdff1aSopenharmony_ci AVBufferRef *ref; 478cabdff1aSopenharmony_ci size_t size = nal->size; 479cabdff1aSopenharmony_ci 480cabdff1aSopenharmony_ci if (nal->nuh_layer_id > 0) 481cabdff1aSopenharmony_ci continue; 482cabdff1aSopenharmony_ci 483cabdff1aSopenharmony_ci // Remove trailing zeroes. 484cabdff1aSopenharmony_ci while (size > 0 && nal->data[size - 1] == 0) 485cabdff1aSopenharmony_ci --size; 486cabdff1aSopenharmony_ci if (size == 0) { 487cabdff1aSopenharmony_ci av_log(ctx->log_ctx, AV_LOG_VERBOSE, "Discarding empty 0 NAL unit\n"); 488cabdff1aSopenharmony_ci continue; 489cabdff1aSopenharmony_ci } 490cabdff1aSopenharmony_ci 491cabdff1aSopenharmony_ci ref = (nal->data == nal->raw_data) ? frag->data_ref 492cabdff1aSopenharmony_ci : packet->rbsp.rbsp_buffer_ref; 493cabdff1aSopenharmony_ci 494cabdff1aSopenharmony_ci err = ff_cbs_append_unit_data(frag, nal->type, 495cabdff1aSopenharmony_ci (uint8_t*)nal->data, size, ref); 496cabdff1aSopenharmony_ci if (err < 0) 497cabdff1aSopenharmony_ci return err; 498cabdff1aSopenharmony_ci } 499cabdff1aSopenharmony_ci 500cabdff1aSopenharmony_ci return 0; 501cabdff1aSopenharmony_ci} 502cabdff1aSopenharmony_ci 503cabdff1aSopenharmony_cistatic int cbs_h2645_split_fragment(CodedBitstreamContext *ctx, 504cabdff1aSopenharmony_ci CodedBitstreamFragment *frag, 505cabdff1aSopenharmony_ci int header) 506cabdff1aSopenharmony_ci{ 507cabdff1aSopenharmony_ci enum AVCodecID codec_id = ctx->codec->codec_id; 508cabdff1aSopenharmony_ci CodedBitstreamH2645Context *priv = ctx->priv_data; 509cabdff1aSopenharmony_ci GetByteContext gbc; 510cabdff1aSopenharmony_ci int err; 511cabdff1aSopenharmony_ci 512cabdff1aSopenharmony_ci av_assert0(frag->data && frag->nb_units == 0); 513cabdff1aSopenharmony_ci if (frag->data_size == 0) 514cabdff1aSopenharmony_ci return 0; 515cabdff1aSopenharmony_ci 516cabdff1aSopenharmony_ci if (header && frag->data[0] && codec_id == AV_CODEC_ID_H264) { 517cabdff1aSopenharmony_ci // AVCC header. 518cabdff1aSopenharmony_ci size_t size, start, end; 519cabdff1aSopenharmony_ci int i, count, version; 520cabdff1aSopenharmony_ci 521cabdff1aSopenharmony_ci priv->mp4 = 1; 522cabdff1aSopenharmony_ci 523cabdff1aSopenharmony_ci bytestream2_init(&gbc, frag->data, frag->data_size); 524cabdff1aSopenharmony_ci 525cabdff1aSopenharmony_ci if (bytestream2_get_bytes_left(&gbc) < 6) 526cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 527cabdff1aSopenharmony_ci 528cabdff1aSopenharmony_ci version = bytestream2_get_byte(&gbc); 529cabdff1aSopenharmony_ci if (version != 1) { 530cabdff1aSopenharmony_ci av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid AVCC header: " 531cabdff1aSopenharmony_ci "first byte %u.\n", version); 532cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 533cabdff1aSopenharmony_ci } 534cabdff1aSopenharmony_ci 535cabdff1aSopenharmony_ci bytestream2_skip(&gbc, 3); 536cabdff1aSopenharmony_ci priv->nal_length_size = (bytestream2_get_byte(&gbc) & 3) + 1; 537cabdff1aSopenharmony_ci 538cabdff1aSopenharmony_ci // SPS array. 539cabdff1aSopenharmony_ci count = bytestream2_get_byte(&gbc) & 0x1f; 540cabdff1aSopenharmony_ci start = bytestream2_tell(&gbc); 541cabdff1aSopenharmony_ci for (i = 0; i < count; i++) { 542cabdff1aSopenharmony_ci if (bytestream2_get_bytes_left(&gbc) < 2 * (count - i)) 543cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 544cabdff1aSopenharmony_ci size = bytestream2_get_be16(&gbc); 545cabdff1aSopenharmony_ci if (bytestream2_get_bytes_left(&gbc) < size) 546cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 547cabdff1aSopenharmony_ci bytestream2_skip(&gbc, size); 548cabdff1aSopenharmony_ci } 549cabdff1aSopenharmony_ci end = bytestream2_tell(&gbc); 550cabdff1aSopenharmony_ci 551cabdff1aSopenharmony_ci err = ff_h2645_packet_split(&priv->read_packet, 552cabdff1aSopenharmony_ci frag->data + start, end - start, 553cabdff1aSopenharmony_ci ctx->log_ctx, 1, 2, AV_CODEC_ID_H264, 1, 1); 554cabdff1aSopenharmony_ci if (err < 0) { 555cabdff1aSopenharmony_ci av_log(ctx->log_ctx, AV_LOG_ERROR, "Failed to split AVCC SPS array.\n"); 556cabdff1aSopenharmony_ci return err; 557cabdff1aSopenharmony_ci } 558cabdff1aSopenharmony_ci err = cbs_h2645_fragment_add_nals(ctx, frag, &priv->read_packet); 559cabdff1aSopenharmony_ci if (err < 0) 560cabdff1aSopenharmony_ci return err; 561cabdff1aSopenharmony_ci 562cabdff1aSopenharmony_ci // PPS array. 563cabdff1aSopenharmony_ci count = bytestream2_get_byte(&gbc); 564cabdff1aSopenharmony_ci start = bytestream2_tell(&gbc); 565cabdff1aSopenharmony_ci for (i = 0; i < count; i++) { 566cabdff1aSopenharmony_ci if (bytestream2_get_bytes_left(&gbc) < 2 * (count - i)) 567cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 568cabdff1aSopenharmony_ci size = bytestream2_get_be16(&gbc); 569cabdff1aSopenharmony_ci if (bytestream2_get_bytes_left(&gbc) < size) 570cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 571cabdff1aSopenharmony_ci bytestream2_skip(&gbc, size); 572cabdff1aSopenharmony_ci } 573cabdff1aSopenharmony_ci end = bytestream2_tell(&gbc); 574cabdff1aSopenharmony_ci 575cabdff1aSopenharmony_ci err = ff_h2645_packet_split(&priv->read_packet, 576cabdff1aSopenharmony_ci frag->data + start, end - start, 577cabdff1aSopenharmony_ci ctx->log_ctx, 1, 2, AV_CODEC_ID_H264, 1, 1); 578cabdff1aSopenharmony_ci if (err < 0) { 579cabdff1aSopenharmony_ci av_log(ctx->log_ctx, AV_LOG_ERROR, "Failed to split AVCC PPS array.\n"); 580cabdff1aSopenharmony_ci return err; 581cabdff1aSopenharmony_ci } 582cabdff1aSopenharmony_ci err = cbs_h2645_fragment_add_nals(ctx, frag, &priv->read_packet); 583cabdff1aSopenharmony_ci if (err < 0) 584cabdff1aSopenharmony_ci return err; 585cabdff1aSopenharmony_ci 586cabdff1aSopenharmony_ci if (bytestream2_get_bytes_left(&gbc) > 0) { 587cabdff1aSopenharmony_ci av_log(ctx->log_ctx, AV_LOG_WARNING, "%u bytes left at end of AVCC " 588cabdff1aSopenharmony_ci "header.\n", bytestream2_get_bytes_left(&gbc)); 589cabdff1aSopenharmony_ci } 590cabdff1aSopenharmony_ci 591cabdff1aSopenharmony_ci } else if (header && frag->data[0] && codec_id == AV_CODEC_ID_HEVC) { 592cabdff1aSopenharmony_ci // HVCC header. 593cabdff1aSopenharmony_ci size_t size, start, end; 594cabdff1aSopenharmony_ci int i, j, nb_arrays, nal_unit_type, nb_nals, version; 595cabdff1aSopenharmony_ci 596cabdff1aSopenharmony_ci priv->mp4 = 1; 597cabdff1aSopenharmony_ci 598cabdff1aSopenharmony_ci bytestream2_init(&gbc, frag->data, frag->data_size); 599cabdff1aSopenharmony_ci 600cabdff1aSopenharmony_ci if (bytestream2_get_bytes_left(&gbc) < 23) 601cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 602cabdff1aSopenharmony_ci 603cabdff1aSopenharmony_ci version = bytestream2_get_byte(&gbc); 604cabdff1aSopenharmony_ci if (version != 1) { 605cabdff1aSopenharmony_ci av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid HVCC header: " 606cabdff1aSopenharmony_ci "first byte %u.\n", version); 607cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 608cabdff1aSopenharmony_ci } 609cabdff1aSopenharmony_ci 610cabdff1aSopenharmony_ci bytestream2_skip(&gbc, 20); 611cabdff1aSopenharmony_ci priv->nal_length_size = (bytestream2_get_byte(&gbc) & 3) + 1; 612cabdff1aSopenharmony_ci 613cabdff1aSopenharmony_ci nb_arrays = bytestream2_get_byte(&gbc); 614cabdff1aSopenharmony_ci for (i = 0; i < nb_arrays; i++) { 615cabdff1aSopenharmony_ci nal_unit_type = bytestream2_get_byte(&gbc) & 0x3f; 616cabdff1aSopenharmony_ci nb_nals = bytestream2_get_be16(&gbc); 617cabdff1aSopenharmony_ci 618cabdff1aSopenharmony_ci start = bytestream2_tell(&gbc); 619cabdff1aSopenharmony_ci for (j = 0; j < nb_nals; j++) { 620cabdff1aSopenharmony_ci if (bytestream2_get_bytes_left(&gbc) < 2) 621cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 622cabdff1aSopenharmony_ci size = bytestream2_get_be16(&gbc); 623cabdff1aSopenharmony_ci if (bytestream2_get_bytes_left(&gbc) < size) 624cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 625cabdff1aSopenharmony_ci bytestream2_skip(&gbc, size); 626cabdff1aSopenharmony_ci } 627cabdff1aSopenharmony_ci end = bytestream2_tell(&gbc); 628cabdff1aSopenharmony_ci 629cabdff1aSopenharmony_ci err = ff_h2645_packet_split(&priv->read_packet, 630cabdff1aSopenharmony_ci frag->data + start, end - start, 631cabdff1aSopenharmony_ci ctx->log_ctx, 1, 2, AV_CODEC_ID_HEVC, 1, 1); 632cabdff1aSopenharmony_ci if (err < 0) { 633cabdff1aSopenharmony_ci av_log(ctx->log_ctx, AV_LOG_ERROR, "Failed to split " 634cabdff1aSopenharmony_ci "HVCC array %d (%d NAL units of type %d).\n", 635cabdff1aSopenharmony_ci i, nb_nals, nal_unit_type); 636cabdff1aSopenharmony_ci return err; 637cabdff1aSopenharmony_ci } 638cabdff1aSopenharmony_ci err = cbs_h2645_fragment_add_nals(ctx, frag, &priv->read_packet); 639cabdff1aSopenharmony_ci if (err < 0) 640cabdff1aSopenharmony_ci return err; 641cabdff1aSopenharmony_ci } 642cabdff1aSopenharmony_ci 643cabdff1aSopenharmony_ci } else { 644cabdff1aSopenharmony_ci // Annex B, or later MP4 with already-known parameters. 645cabdff1aSopenharmony_ci 646cabdff1aSopenharmony_ci err = ff_h2645_packet_split(&priv->read_packet, 647cabdff1aSopenharmony_ci frag->data, frag->data_size, 648cabdff1aSopenharmony_ci ctx->log_ctx, 649cabdff1aSopenharmony_ci priv->mp4, priv->nal_length_size, 650cabdff1aSopenharmony_ci codec_id, 1, 1); 651cabdff1aSopenharmony_ci if (err < 0) 652cabdff1aSopenharmony_ci return err; 653cabdff1aSopenharmony_ci 654cabdff1aSopenharmony_ci err = cbs_h2645_fragment_add_nals(ctx, frag, &priv->read_packet); 655cabdff1aSopenharmony_ci if (err < 0) 656cabdff1aSopenharmony_ci return err; 657cabdff1aSopenharmony_ci } 658cabdff1aSopenharmony_ci 659cabdff1aSopenharmony_ci return 0; 660cabdff1aSopenharmony_ci} 661cabdff1aSopenharmony_ci 662cabdff1aSopenharmony_ci#define cbs_h2645_replace_ps(h26n, ps_name, ps_var, id_element) \ 663cabdff1aSopenharmony_cistatic int cbs_h26 ## h26n ## _replace_ ## ps_var(CodedBitstreamContext *ctx, \ 664cabdff1aSopenharmony_ci CodedBitstreamUnit *unit) \ 665cabdff1aSopenharmony_ci{ \ 666cabdff1aSopenharmony_ci CodedBitstreamH26 ## h26n ## Context *priv = ctx->priv_data; \ 667cabdff1aSopenharmony_ci H26 ## h26n ## Raw ## ps_name *ps_var = unit->content; \ 668cabdff1aSopenharmony_ci unsigned int id = ps_var->id_element; \ 669cabdff1aSopenharmony_ci int err; \ 670cabdff1aSopenharmony_ci if (id >= FF_ARRAY_ELEMS(priv->ps_var)) { \ 671cabdff1aSopenharmony_ci av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid " #ps_name \ 672cabdff1aSopenharmony_ci " id : %d.\n", id); \ 673cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; \ 674cabdff1aSopenharmony_ci } \ 675cabdff1aSopenharmony_ci err = ff_cbs_make_unit_refcounted(ctx, unit); \ 676cabdff1aSopenharmony_ci if (err < 0) \ 677cabdff1aSopenharmony_ci return err; \ 678cabdff1aSopenharmony_ci if (priv->ps_var[id] == priv->active_ ## ps_var) \ 679cabdff1aSopenharmony_ci priv->active_ ## ps_var = NULL ; \ 680cabdff1aSopenharmony_ci av_buffer_unref(&priv->ps_var ## _ref[id]); \ 681cabdff1aSopenharmony_ci av_assert0(unit->content_ref); \ 682cabdff1aSopenharmony_ci priv->ps_var ## _ref[id] = av_buffer_ref(unit->content_ref); \ 683cabdff1aSopenharmony_ci if (!priv->ps_var ## _ref[id]) \ 684cabdff1aSopenharmony_ci return AVERROR(ENOMEM); \ 685cabdff1aSopenharmony_ci priv->ps_var[id] = (H26 ## h26n ## Raw ## ps_name *)priv->ps_var ## _ref[id]->data; \ 686cabdff1aSopenharmony_ci return 0; \ 687cabdff1aSopenharmony_ci} 688cabdff1aSopenharmony_ci 689cabdff1aSopenharmony_cicbs_h2645_replace_ps(4, SPS, sps, seq_parameter_set_id) 690cabdff1aSopenharmony_cicbs_h2645_replace_ps(4, PPS, pps, pic_parameter_set_id) 691cabdff1aSopenharmony_cicbs_h2645_replace_ps(5, VPS, vps, vps_video_parameter_set_id) 692cabdff1aSopenharmony_cicbs_h2645_replace_ps(5, SPS, sps, sps_seq_parameter_set_id) 693cabdff1aSopenharmony_cicbs_h2645_replace_ps(5, PPS, pps, pps_pic_parameter_set_id) 694cabdff1aSopenharmony_ci 695cabdff1aSopenharmony_cistatic int cbs_h264_read_nal_unit(CodedBitstreamContext *ctx, 696cabdff1aSopenharmony_ci CodedBitstreamUnit *unit) 697cabdff1aSopenharmony_ci{ 698cabdff1aSopenharmony_ci GetBitContext gbc; 699cabdff1aSopenharmony_ci int err; 700cabdff1aSopenharmony_ci 701cabdff1aSopenharmony_ci err = init_get_bits(&gbc, unit->data, 8 * unit->data_size); 702cabdff1aSopenharmony_ci if (err < 0) 703cabdff1aSopenharmony_ci return err; 704cabdff1aSopenharmony_ci 705cabdff1aSopenharmony_ci err = ff_cbs_alloc_unit_content2(ctx, unit); 706cabdff1aSopenharmony_ci if (err < 0) 707cabdff1aSopenharmony_ci return err; 708cabdff1aSopenharmony_ci 709cabdff1aSopenharmony_ci switch (unit->type) { 710cabdff1aSopenharmony_ci case H264_NAL_SPS: 711cabdff1aSopenharmony_ci { 712cabdff1aSopenharmony_ci H264RawSPS *sps = unit->content; 713cabdff1aSopenharmony_ci 714cabdff1aSopenharmony_ci err = cbs_h264_read_sps(ctx, &gbc, sps); 715cabdff1aSopenharmony_ci if (err < 0) 716cabdff1aSopenharmony_ci return err; 717cabdff1aSopenharmony_ci 718cabdff1aSopenharmony_ci err = cbs_h264_replace_sps(ctx, unit); 719cabdff1aSopenharmony_ci if (err < 0) 720cabdff1aSopenharmony_ci return err; 721cabdff1aSopenharmony_ci } 722cabdff1aSopenharmony_ci break; 723cabdff1aSopenharmony_ci 724cabdff1aSopenharmony_ci case H264_NAL_SPS_EXT: 725cabdff1aSopenharmony_ci { 726cabdff1aSopenharmony_ci err = cbs_h264_read_sps_extension(ctx, &gbc, unit->content); 727cabdff1aSopenharmony_ci if (err < 0) 728cabdff1aSopenharmony_ci return err; 729cabdff1aSopenharmony_ci } 730cabdff1aSopenharmony_ci break; 731cabdff1aSopenharmony_ci 732cabdff1aSopenharmony_ci case H264_NAL_PPS: 733cabdff1aSopenharmony_ci { 734cabdff1aSopenharmony_ci H264RawPPS *pps = unit->content; 735cabdff1aSopenharmony_ci 736cabdff1aSopenharmony_ci err = cbs_h264_read_pps(ctx, &gbc, pps); 737cabdff1aSopenharmony_ci if (err < 0) 738cabdff1aSopenharmony_ci return err; 739cabdff1aSopenharmony_ci 740cabdff1aSopenharmony_ci err = cbs_h264_replace_pps(ctx, unit); 741cabdff1aSopenharmony_ci if (err < 0) 742cabdff1aSopenharmony_ci return err; 743cabdff1aSopenharmony_ci } 744cabdff1aSopenharmony_ci break; 745cabdff1aSopenharmony_ci 746cabdff1aSopenharmony_ci case H264_NAL_SLICE: 747cabdff1aSopenharmony_ci case H264_NAL_IDR_SLICE: 748cabdff1aSopenharmony_ci case H264_NAL_AUXILIARY_SLICE: 749cabdff1aSopenharmony_ci { 750cabdff1aSopenharmony_ci H264RawSlice *slice = unit->content; 751cabdff1aSopenharmony_ci int pos, len; 752cabdff1aSopenharmony_ci 753cabdff1aSopenharmony_ci err = cbs_h264_read_slice_header(ctx, &gbc, &slice->header); 754cabdff1aSopenharmony_ci if (err < 0) 755cabdff1aSopenharmony_ci return err; 756cabdff1aSopenharmony_ci 757cabdff1aSopenharmony_ci if (!cbs_h2645_read_more_rbsp_data(&gbc)) 758cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 759cabdff1aSopenharmony_ci 760cabdff1aSopenharmony_ci pos = get_bits_count(&gbc); 761cabdff1aSopenharmony_ci len = unit->data_size; 762cabdff1aSopenharmony_ci 763cabdff1aSopenharmony_ci slice->data_size = len - pos / 8; 764cabdff1aSopenharmony_ci slice->data_ref = av_buffer_ref(unit->data_ref); 765cabdff1aSopenharmony_ci if (!slice->data_ref) 766cabdff1aSopenharmony_ci return AVERROR(ENOMEM); 767cabdff1aSopenharmony_ci slice->data = unit->data + pos / 8; 768cabdff1aSopenharmony_ci slice->data_bit_start = pos % 8; 769cabdff1aSopenharmony_ci } 770cabdff1aSopenharmony_ci break; 771cabdff1aSopenharmony_ci 772cabdff1aSopenharmony_ci case H264_NAL_AUD: 773cabdff1aSopenharmony_ci { 774cabdff1aSopenharmony_ci err = cbs_h264_read_aud(ctx, &gbc, unit->content); 775cabdff1aSopenharmony_ci if (err < 0) 776cabdff1aSopenharmony_ci return err; 777cabdff1aSopenharmony_ci } 778cabdff1aSopenharmony_ci break; 779cabdff1aSopenharmony_ci 780cabdff1aSopenharmony_ci case H264_NAL_SEI: 781cabdff1aSopenharmony_ci { 782cabdff1aSopenharmony_ci err = cbs_h264_read_sei(ctx, &gbc, unit->content); 783cabdff1aSopenharmony_ci if (err < 0) 784cabdff1aSopenharmony_ci return err; 785cabdff1aSopenharmony_ci } 786cabdff1aSopenharmony_ci break; 787cabdff1aSopenharmony_ci 788cabdff1aSopenharmony_ci case H264_NAL_FILLER_DATA: 789cabdff1aSopenharmony_ci { 790cabdff1aSopenharmony_ci err = cbs_h264_read_filler(ctx, &gbc, unit->content); 791cabdff1aSopenharmony_ci if (err < 0) 792cabdff1aSopenharmony_ci return err; 793cabdff1aSopenharmony_ci } 794cabdff1aSopenharmony_ci break; 795cabdff1aSopenharmony_ci 796cabdff1aSopenharmony_ci case H264_NAL_END_SEQUENCE: 797cabdff1aSopenharmony_ci case H264_NAL_END_STREAM: 798cabdff1aSopenharmony_ci { 799cabdff1aSopenharmony_ci err = (unit->type == H264_NAL_END_SEQUENCE ? 800cabdff1aSopenharmony_ci cbs_h264_read_end_of_sequence : 801cabdff1aSopenharmony_ci cbs_h264_read_end_of_stream)(ctx, &gbc, unit->content); 802cabdff1aSopenharmony_ci if (err < 0) 803cabdff1aSopenharmony_ci return err; 804cabdff1aSopenharmony_ci } 805cabdff1aSopenharmony_ci break; 806cabdff1aSopenharmony_ci 807cabdff1aSopenharmony_ci default: 808cabdff1aSopenharmony_ci return AVERROR(ENOSYS); 809cabdff1aSopenharmony_ci } 810cabdff1aSopenharmony_ci 811cabdff1aSopenharmony_ci return 0; 812cabdff1aSopenharmony_ci} 813cabdff1aSopenharmony_ci 814cabdff1aSopenharmony_cistatic int cbs_h265_read_nal_unit(CodedBitstreamContext *ctx, 815cabdff1aSopenharmony_ci CodedBitstreamUnit *unit) 816cabdff1aSopenharmony_ci{ 817cabdff1aSopenharmony_ci GetBitContext gbc; 818cabdff1aSopenharmony_ci int err; 819cabdff1aSopenharmony_ci 820cabdff1aSopenharmony_ci err = init_get_bits(&gbc, unit->data, 8 * unit->data_size); 821cabdff1aSopenharmony_ci if (err < 0) 822cabdff1aSopenharmony_ci return err; 823cabdff1aSopenharmony_ci 824cabdff1aSopenharmony_ci err = ff_cbs_alloc_unit_content2(ctx, unit); 825cabdff1aSopenharmony_ci if (err < 0) 826cabdff1aSopenharmony_ci return err; 827cabdff1aSopenharmony_ci 828cabdff1aSopenharmony_ci switch (unit->type) { 829cabdff1aSopenharmony_ci case HEVC_NAL_VPS: 830cabdff1aSopenharmony_ci { 831cabdff1aSopenharmony_ci H265RawVPS *vps = unit->content; 832cabdff1aSopenharmony_ci 833cabdff1aSopenharmony_ci err = cbs_h265_read_vps(ctx, &gbc, vps); 834cabdff1aSopenharmony_ci if (err < 0) 835cabdff1aSopenharmony_ci return err; 836cabdff1aSopenharmony_ci 837cabdff1aSopenharmony_ci err = cbs_h265_replace_vps(ctx, unit); 838cabdff1aSopenharmony_ci if (err < 0) 839cabdff1aSopenharmony_ci return err; 840cabdff1aSopenharmony_ci } 841cabdff1aSopenharmony_ci break; 842cabdff1aSopenharmony_ci case HEVC_NAL_SPS: 843cabdff1aSopenharmony_ci { 844cabdff1aSopenharmony_ci H265RawSPS *sps = unit->content; 845cabdff1aSopenharmony_ci 846cabdff1aSopenharmony_ci err = cbs_h265_read_sps(ctx, &gbc, sps); 847cabdff1aSopenharmony_ci if (err < 0) 848cabdff1aSopenharmony_ci return err; 849cabdff1aSopenharmony_ci 850cabdff1aSopenharmony_ci err = cbs_h265_replace_sps(ctx, unit); 851cabdff1aSopenharmony_ci if (err < 0) 852cabdff1aSopenharmony_ci return err; 853cabdff1aSopenharmony_ci } 854cabdff1aSopenharmony_ci break; 855cabdff1aSopenharmony_ci 856cabdff1aSopenharmony_ci case HEVC_NAL_PPS: 857cabdff1aSopenharmony_ci { 858cabdff1aSopenharmony_ci H265RawPPS *pps = unit->content; 859cabdff1aSopenharmony_ci 860cabdff1aSopenharmony_ci err = cbs_h265_read_pps(ctx, &gbc, pps); 861cabdff1aSopenharmony_ci if (err < 0) 862cabdff1aSopenharmony_ci return err; 863cabdff1aSopenharmony_ci 864cabdff1aSopenharmony_ci err = cbs_h265_replace_pps(ctx, unit); 865cabdff1aSopenharmony_ci if (err < 0) 866cabdff1aSopenharmony_ci return err; 867cabdff1aSopenharmony_ci } 868cabdff1aSopenharmony_ci break; 869cabdff1aSopenharmony_ci 870cabdff1aSopenharmony_ci case HEVC_NAL_TRAIL_N: 871cabdff1aSopenharmony_ci case HEVC_NAL_TRAIL_R: 872cabdff1aSopenharmony_ci case HEVC_NAL_TSA_N: 873cabdff1aSopenharmony_ci case HEVC_NAL_TSA_R: 874cabdff1aSopenharmony_ci case HEVC_NAL_STSA_N: 875cabdff1aSopenharmony_ci case HEVC_NAL_STSA_R: 876cabdff1aSopenharmony_ci case HEVC_NAL_RADL_N: 877cabdff1aSopenharmony_ci case HEVC_NAL_RADL_R: 878cabdff1aSopenharmony_ci case HEVC_NAL_RASL_N: 879cabdff1aSopenharmony_ci case HEVC_NAL_RASL_R: 880cabdff1aSopenharmony_ci case HEVC_NAL_BLA_W_LP: 881cabdff1aSopenharmony_ci case HEVC_NAL_BLA_W_RADL: 882cabdff1aSopenharmony_ci case HEVC_NAL_BLA_N_LP: 883cabdff1aSopenharmony_ci case HEVC_NAL_IDR_W_RADL: 884cabdff1aSopenharmony_ci case HEVC_NAL_IDR_N_LP: 885cabdff1aSopenharmony_ci case HEVC_NAL_CRA_NUT: 886cabdff1aSopenharmony_ci { 887cabdff1aSopenharmony_ci H265RawSlice *slice = unit->content; 888cabdff1aSopenharmony_ci int pos, len; 889cabdff1aSopenharmony_ci 890cabdff1aSopenharmony_ci err = cbs_h265_read_slice_segment_header(ctx, &gbc, &slice->header); 891cabdff1aSopenharmony_ci if (err < 0) 892cabdff1aSopenharmony_ci return err; 893cabdff1aSopenharmony_ci 894cabdff1aSopenharmony_ci if (!cbs_h2645_read_more_rbsp_data(&gbc)) 895cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 896cabdff1aSopenharmony_ci 897cabdff1aSopenharmony_ci pos = get_bits_count(&gbc); 898cabdff1aSopenharmony_ci len = unit->data_size; 899cabdff1aSopenharmony_ci 900cabdff1aSopenharmony_ci slice->data_size = len - pos / 8; 901cabdff1aSopenharmony_ci slice->data_ref = av_buffer_ref(unit->data_ref); 902cabdff1aSopenharmony_ci if (!slice->data_ref) 903cabdff1aSopenharmony_ci return AVERROR(ENOMEM); 904cabdff1aSopenharmony_ci slice->data = unit->data + pos / 8; 905cabdff1aSopenharmony_ci slice->data_bit_start = pos % 8; 906cabdff1aSopenharmony_ci } 907cabdff1aSopenharmony_ci break; 908cabdff1aSopenharmony_ci 909cabdff1aSopenharmony_ci case HEVC_NAL_AUD: 910cabdff1aSopenharmony_ci { 911cabdff1aSopenharmony_ci err = cbs_h265_read_aud(ctx, &gbc, unit->content); 912cabdff1aSopenharmony_ci if (err < 0) 913cabdff1aSopenharmony_ci return err; 914cabdff1aSopenharmony_ci } 915cabdff1aSopenharmony_ci break; 916cabdff1aSopenharmony_ci 917cabdff1aSopenharmony_ci case HEVC_NAL_SEI_PREFIX: 918cabdff1aSopenharmony_ci case HEVC_NAL_SEI_SUFFIX: 919cabdff1aSopenharmony_ci { 920cabdff1aSopenharmony_ci err = cbs_h265_read_sei(ctx, &gbc, unit->content, 921cabdff1aSopenharmony_ci unit->type == HEVC_NAL_SEI_PREFIX); 922cabdff1aSopenharmony_ci 923cabdff1aSopenharmony_ci if (err < 0) 924cabdff1aSopenharmony_ci return err; 925cabdff1aSopenharmony_ci } 926cabdff1aSopenharmony_ci break; 927cabdff1aSopenharmony_ci 928cabdff1aSopenharmony_ci default: 929cabdff1aSopenharmony_ci return AVERROR(ENOSYS); 930cabdff1aSopenharmony_ci } 931cabdff1aSopenharmony_ci 932cabdff1aSopenharmony_ci return 0; 933cabdff1aSopenharmony_ci} 934cabdff1aSopenharmony_ci 935cabdff1aSopenharmony_cistatic int cbs_h2645_write_slice_data(CodedBitstreamContext *ctx, 936cabdff1aSopenharmony_ci PutBitContext *pbc, const uint8_t *data, 937cabdff1aSopenharmony_ci size_t data_size, int data_bit_start) 938cabdff1aSopenharmony_ci{ 939cabdff1aSopenharmony_ci size_t rest = data_size - (data_bit_start + 7) / 8; 940cabdff1aSopenharmony_ci const uint8_t *pos = data + data_bit_start / 8; 941cabdff1aSopenharmony_ci 942cabdff1aSopenharmony_ci av_assert0(data_bit_start >= 0 && 943cabdff1aSopenharmony_ci data_size > data_bit_start / 8); 944cabdff1aSopenharmony_ci 945cabdff1aSopenharmony_ci if (data_size * 8 + 8 > put_bits_left(pbc)) 946cabdff1aSopenharmony_ci return AVERROR(ENOSPC); 947cabdff1aSopenharmony_ci 948cabdff1aSopenharmony_ci if (!rest) 949cabdff1aSopenharmony_ci goto rbsp_stop_one_bit; 950cabdff1aSopenharmony_ci 951cabdff1aSopenharmony_ci // First copy the remaining bits of the first byte 952cabdff1aSopenharmony_ci // The above check ensures that we do not accidentally 953cabdff1aSopenharmony_ci // copy beyond the rbsp_stop_one_bit. 954cabdff1aSopenharmony_ci if (data_bit_start % 8) 955cabdff1aSopenharmony_ci put_bits(pbc, 8 - data_bit_start % 8, 956cabdff1aSopenharmony_ci *pos++ & MAX_UINT_BITS(8 - data_bit_start % 8)); 957cabdff1aSopenharmony_ci 958cabdff1aSopenharmony_ci if (put_bits_count(pbc) % 8 == 0) { 959cabdff1aSopenharmony_ci // If the writer is aligned at this point, 960cabdff1aSopenharmony_ci // memcpy can be used to improve performance. 961cabdff1aSopenharmony_ci // This happens normally for CABAC. 962cabdff1aSopenharmony_ci flush_put_bits(pbc); 963cabdff1aSopenharmony_ci memcpy(put_bits_ptr(pbc), pos, rest); 964cabdff1aSopenharmony_ci skip_put_bytes(pbc, rest); 965cabdff1aSopenharmony_ci } else { 966cabdff1aSopenharmony_ci // If not, we have to copy manually. 967cabdff1aSopenharmony_ci // rbsp_stop_one_bit forces us to special-case 968cabdff1aSopenharmony_ci // the last byte. 969cabdff1aSopenharmony_ci uint8_t temp; 970cabdff1aSopenharmony_ci int i; 971cabdff1aSopenharmony_ci 972cabdff1aSopenharmony_ci for (; rest > 4; rest -= 4, pos += 4) 973cabdff1aSopenharmony_ci put_bits32(pbc, AV_RB32(pos)); 974cabdff1aSopenharmony_ci 975cabdff1aSopenharmony_ci for (; rest > 1; rest--, pos++) 976cabdff1aSopenharmony_ci put_bits(pbc, 8, *pos); 977cabdff1aSopenharmony_ci 978cabdff1aSopenharmony_ci rbsp_stop_one_bit: 979cabdff1aSopenharmony_ci temp = rest ? *pos : *pos & MAX_UINT_BITS(8 - data_bit_start % 8); 980cabdff1aSopenharmony_ci 981cabdff1aSopenharmony_ci av_assert0(temp); 982cabdff1aSopenharmony_ci i = ff_ctz(*pos); 983cabdff1aSopenharmony_ci temp = temp >> i; 984cabdff1aSopenharmony_ci i = rest ? (8 - i) : (8 - i - data_bit_start % 8); 985cabdff1aSopenharmony_ci put_bits(pbc, i, temp); 986cabdff1aSopenharmony_ci if (put_bits_count(pbc) % 8) 987cabdff1aSopenharmony_ci put_bits(pbc, 8 - put_bits_count(pbc) % 8, 0); 988cabdff1aSopenharmony_ci } 989cabdff1aSopenharmony_ci 990cabdff1aSopenharmony_ci return 0; 991cabdff1aSopenharmony_ci} 992cabdff1aSopenharmony_ci 993cabdff1aSopenharmony_cistatic int cbs_h264_write_nal_unit(CodedBitstreamContext *ctx, 994cabdff1aSopenharmony_ci CodedBitstreamUnit *unit, 995cabdff1aSopenharmony_ci PutBitContext *pbc) 996cabdff1aSopenharmony_ci{ 997cabdff1aSopenharmony_ci int err; 998cabdff1aSopenharmony_ci 999cabdff1aSopenharmony_ci switch (unit->type) { 1000cabdff1aSopenharmony_ci case H264_NAL_SPS: 1001cabdff1aSopenharmony_ci { 1002cabdff1aSopenharmony_ci H264RawSPS *sps = unit->content; 1003cabdff1aSopenharmony_ci 1004cabdff1aSopenharmony_ci err = cbs_h264_write_sps(ctx, pbc, sps); 1005cabdff1aSopenharmony_ci if (err < 0) 1006cabdff1aSopenharmony_ci return err; 1007cabdff1aSopenharmony_ci 1008cabdff1aSopenharmony_ci err = cbs_h264_replace_sps(ctx, unit); 1009cabdff1aSopenharmony_ci if (err < 0) 1010cabdff1aSopenharmony_ci return err; 1011cabdff1aSopenharmony_ci } 1012cabdff1aSopenharmony_ci break; 1013cabdff1aSopenharmony_ci 1014cabdff1aSopenharmony_ci case H264_NAL_SPS_EXT: 1015cabdff1aSopenharmony_ci { 1016cabdff1aSopenharmony_ci H264RawSPSExtension *sps_ext = unit->content; 1017cabdff1aSopenharmony_ci 1018cabdff1aSopenharmony_ci err = cbs_h264_write_sps_extension(ctx, pbc, sps_ext); 1019cabdff1aSopenharmony_ci if (err < 0) 1020cabdff1aSopenharmony_ci return err; 1021cabdff1aSopenharmony_ci } 1022cabdff1aSopenharmony_ci break; 1023cabdff1aSopenharmony_ci 1024cabdff1aSopenharmony_ci case H264_NAL_PPS: 1025cabdff1aSopenharmony_ci { 1026cabdff1aSopenharmony_ci H264RawPPS *pps = unit->content; 1027cabdff1aSopenharmony_ci 1028cabdff1aSopenharmony_ci err = cbs_h264_write_pps(ctx, pbc, pps); 1029cabdff1aSopenharmony_ci if (err < 0) 1030cabdff1aSopenharmony_ci return err; 1031cabdff1aSopenharmony_ci 1032cabdff1aSopenharmony_ci err = cbs_h264_replace_pps(ctx, unit); 1033cabdff1aSopenharmony_ci if (err < 0) 1034cabdff1aSopenharmony_ci return err; 1035cabdff1aSopenharmony_ci } 1036cabdff1aSopenharmony_ci break; 1037cabdff1aSopenharmony_ci 1038cabdff1aSopenharmony_ci case H264_NAL_SLICE: 1039cabdff1aSopenharmony_ci case H264_NAL_IDR_SLICE: 1040cabdff1aSopenharmony_ci case H264_NAL_AUXILIARY_SLICE: 1041cabdff1aSopenharmony_ci { 1042cabdff1aSopenharmony_ci H264RawSlice *slice = unit->content; 1043cabdff1aSopenharmony_ci 1044cabdff1aSopenharmony_ci err = cbs_h264_write_slice_header(ctx, pbc, &slice->header); 1045cabdff1aSopenharmony_ci if (err < 0) 1046cabdff1aSopenharmony_ci return err; 1047cabdff1aSopenharmony_ci 1048cabdff1aSopenharmony_ci if (slice->data) { 1049cabdff1aSopenharmony_ci err = cbs_h2645_write_slice_data(ctx, pbc, slice->data, 1050cabdff1aSopenharmony_ci slice->data_size, 1051cabdff1aSopenharmony_ci slice->data_bit_start); 1052cabdff1aSopenharmony_ci if (err < 0) 1053cabdff1aSopenharmony_ci return err; 1054cabdff1aSopenharmony_ci } else { 1055cabdff1aSopenharmony_ci // No slice data - that was just the header. 1056cabdff1aSopenharmony_ci // (Bitstream may be unaligned!) 1057cabdff1aSopenharmony_ci } 1058cabdff1aSopenharmony_ci } 1059cabdff1aSopenharmony_ci break; 1060cabdff1aSopenharmony_ci 1061cabdff1aSopenharmony_ci case H264_NAL_AUD: 1062cabdff1aSopenharmony_ci { 1063cabdff1aSopenharmony_ci err = cbs_h264_write_aud(ctx, pbc, unit->content); 1064cabdff1aSopenharmony_ci if (err < 0) 1065cabdff1aSopenharmony_ci return err; 1066cabdff1aSopenharmony_ci } 1067cabdff1aSopenharmony_ci break; 1068cabdff1aSopenharmony_ci 1069cabdff1aSopenharmony_ci case H264_NAL_SEI: 1070cabdff1aSopenharmony_ci { 1071cabdff1aSopenharmony_ci err = cbs_h264_write_sei(ctx, pbc, unit->content); 1072cabdff1aSopenharmony_ci if (err < 0) 1073cabdff1aSopenharmony_ci return err; 1074cabdff1aSopenharmony_ci } 1075cabdff1aSopenharmony_ci break; 1076cabdff1aSopenharmony_ci 1077cabdff1aSopenharmony_ci case H264_NAL_FILLER_DATA: 1078cabdff1aSopenharmony_ci { 1079cabdff1aSopenharmony_ci err = cbs_h264_write_filler(ctx, pbc, unit->content); 1080cabdff1aSopenharmony_ci if (err < 0) 1081cabdff1aSopenharmony_ci return err; 1082cabdff1aSopenharmony_ci } 1083cabdff1aSopenharmony_ci break; 1084cabdff1aSopenharmony_ci 1085cabdff1aSopenharmony_ci case H264_NAL_END_SEQUENCE: 1086cabdff1aSopenharmony_ci { 1087cabdff1aSopenharmony_ci err = cbs_h264_write_end_of_sequence(ctx, pbc, unit->content); 1088cabdff1aSopenharmony_ci if (err < 0) 1089cabdff1aSopenharmony_ci return err; 1090cabdff1aSopenharmony_ci } 1091cabdff1aSopenharmony_ci break; 1092cabdff1aSopenharmony_ci 1093cabdff1aSopenharmony_ci case H264_NAL_END_STREAM: 1094cabdff1aSopenharmony_ci { 1095cabdff1aSopenharmony_ci err = cbs_h264_write_end_of_stream(ctx, pbc, unit->content); 1096cabdff1aSopenharmony_ci if (err < 0) 1097cabdff1aSopenharmony_ci return err; 1098cabdff1aSopenharmony_ci } 1099cabdff1aSopenharmony_ci break; 1100cabdff1aSopenharmony_ci 1101cabdff1aSopenharmony_ci default: 1102cabdff1aSopenharmony_ci av_log(ctx->log_ctx, AV_LOG_ERROR, "Write unimplemented for " 1103cabdff1aSopenharmony_ci "NAL unit type %"PRIu32".\n", unit->type); 1104cabdff1aSopenharmony_ci return AVERROR_PATCHWELCOME; 1105cabdff1aSopenharmony_ci } 1106cabdff1aSopenharmony_ci 1107cabdff1aSopenharmony_ci return 0; 1108cabdff1aSopenharmony_ci} 1109cabdff1aSopenharmony_ci 1110cabdff1aSopenharmony_cistatic int cbs_h265_write_nal_unit(CodedBitstreamContext *ctx, 1111cabdff1aSopenharmony_ci CodedBitstreamUnit *unit, 1112cabdff1aSopenharmony_ci PutBitContext *pbc) 1113cabdff1aSopenharmony_ci{ 1114cabdff1aSopenharmony_ci int err; 1115cabdff1aSopenharmony_ci 1116cabdff1aSopenharmony_ci switch (unit->type) { 1117cabdff1aSopenharmony_ci case HEVC_NAL_VPS: 1118cabdff1aSopenharmony_ci { 1119cabdff1aSopenharmony_ci H265RawVPS *vps = unit->content; 1120cabdff1aSopenharmony_ci 1121cabdff1aSopenharmony_ci err = cbs_h265_write_vps(ctx, pbc, vps); 1122cabdff1aSopenharmony_ci if (err < 0) 1123cabdff1aSopenharmony_ci return err; 1124cabdff1aSopenharmony_ci 1125cabdff1aSopenharmony_ci err = cbs_h265_replace_vps(ctx, unit); 1126cabdff1aSopenharmony_ci if (err < 0) 1127cabdff1aSopenharmony_ci return err; 1128cabdff1aSopenharmony_ci } 1129cabdff1aSopenharmony_ci break; 1130cabdff1aSopenharmony_ci 1131cabdff1aSopenharmony_ci case HEVC_NAL_SPS: 1132cabdff1aSopenharmony_ci { 1133cabdff1aSopenharmony_ci H265RawSPS *sps = unit->content; 1134cabdff1aSopenharmony_ci 1135cabdff1aSopenharmony_ci err = cbs_h265_write_sps(ctx, pbc, sps); 1136cabdff1aSopenharmony_ci if (err < 0) 1137cabdff1aSopenharmony_ci return err; 1138cabdff1aSopenharmony_ci 1139cabdff1aSopenharmony_ci err = cbs_h265_replace_sps(ctx, unit); 1140cabdff1aSopenharmony_ci if (err < 0) 1141cabdff1aSopenharmony_ci return err; 1142cabdff1aSopenharmony_ci } 1143cabdff1aSopenharmony_ci break; 1144cabdff1aSopenharmony_ci 1145cabdff1aSopenharmony_ci case HEVC_NAL_PPS: 1146cabdff1aSopenharmony_ci { 1147cabdff1aSopenharmony_ci H265RawPPS *pps = unit->content; 1148cabdff1aSopenharmony_ci 1149cabdff1aSopenharmony_ci err = cbs_h265_write_pps(ctx, pbc, pps); 1150cabdff1aSopenharmony_ci if (err < 0) 1151cabdff1aSopenharmony_ci return err; 1152cabdff1aSopenharmony_ci 1153cabdff1aSopenharmony_ci err = cbs_h265_replace_pps(ctx, unit); 1154cabdff1aSopenharmony_ci if (err < 0) 1155cabdff1aSopenharmony_ci return err; 1156cabdff1aSopenharmony_ci } 1157cabdff1aSopenharmony_ci break; 1158cabdff1aSopenharmony_ci 1159cabdff1aSopenharmony_ci case HEVC_NAL_TRAIL_N: 1160cabdff1aSopenharmony_ci case HEVC_NAL_TRAIL_R: 1161cabdff1aSopenharmony_ci case HEVC_NAL_TSA_N: 1162cabdff1aSopenharmony_ci case HEVC_NAL_TSA_R: 1163cabdff1aSopenharmony_ci case HEVC_NAL_STSA_N: 1164cabdff1aSopenharmony_ci case HEVC_NAL_STSA_R: 1165cabdff1aSopenharmony_ci case HEVC_NAL_RADL_N: 1166cabdff1aSopenharmony_ci case HEVC_NAL_RADL_R: 1167cabdff1aSopenharmony_ci case HEVC_NAL_RASL_N: 1168cabdff1aSopenharmony_ci case HEVC_NAL_RASL_R: 1169cabdff1aSopenharmony_ci case HEVC_NAL_BLA_W_LP: 1170cabdff1aSopenharmony_ci case HEVC_NAL_BLA_W_RADL: 1171cabdff1aSopenharmony_ci case HEVC_NAL_BLA_N_LP: 1172cabdff1aSopenharmony_ci case HEVC_NAL_IDR_W_RADL: 1173cabdff1aSopenharmony_ci case HEVC_NAL_IDR_N_LP: 1174cabdff1aSopenharmony_ci case HEVC_NAL_CRA_NUT: 1175cabdff1aSopenharmony_ci { 1176cabdff1aSopenharmony_ci H265RawSlice *slice = unit->content; 1177cabdff1aSopenharmony_ci 1178cabdff1aSopenharmony_ci err = cbs_h265_write_slice_segment_header(ctx, pbc, &slice->header); 1179cabdff1aSopenharmony_ci if (err < 0) 1180cabdff1aSopenharmony_ci return err; 1181cabdff1aSopenharmony_ci 1182cabdff1aSopenharmony_ci if (slice->data) { 1183cabdff1aSopenharmony_ci err = cbs_h2645_write_slice_data(ctx, pbc, slice->data, 1184cabdff1aSopenharmony_ci slice->data_size, 1185cabdff1aSopenharmony_ci slice->data_bit_start); 1186cabdff1aSopenharmony_ci if (err < 0) 1187cabdff1aSopenharmony_ci return err; 1188cabdff1aSopenharmony_ci } else { 1189cabdff1aSopenharmony_ci // No slice data - that was just the header. 1190cabdff1aSopenharmony_ci } 1191cabdff1aSopenharmony_ci } 1192cabdff1aSopenharmony_ci break; 1193cabdff1aSopenharmony_ci 1194cabdff1aSopenharmony_ci case HEVC_NAL_AUD: 1195cabdff1aSopenharmony_ci { 1196cabdff1aSopenharmony_ci err = cbs_h265_write_aud(ctx, pbc, unit->content); 1197cabdff1aSopenharmony_ci if (err < 0) 1198cabdff1aSopenharmony_ci return err; 1199cabdff1aSopenharmony_ci } 1200cabdff1aSopenharmony_ci break; 1201cabdff1aSopenharmony_ci 1202cabdff1aSopenharmony_ci case HEVC_NAL_SEI_PREFIX: 1203cabdff1aSopenharmony_ci case HEVC_NAL_SEI_SUFFIX: 1204cabdff1aSopenharmony_ci { 1205cabdff1aSopenharmony_ci err = cbs_h265_write_sei(ctx, pbc, unit->content, 1206cabdff1aSopenharmony_ci unit->type == HEVC_NAL_SEI_PREFIX); 1207cabdff1aSopenharmony_ci 1208cabdff1aSopenharmony_ci if (err < 0) 1209cabdff1aSopenharmony_ci return err; 1210cabdff1aSopenharmony_ci } 1211cabdff1aSopenharmony_ci break; 1212cabdff1aSopenharmony_ci 1213cabdff1aSopenharmony_ci default: 1214cabdff1aSopenharmony_ci av_log(ctx->log_ctx, AV_LOG_ERROR, "Write unimplemented for " 1215cabdff1aSopenharmony_ci "NAL unit type %"PRIu32".\n", unit->type); 1216cabdff1aSopenharmony_ci return AVERROR_PATCHWELCOME; 1217cabdff1aSopenharmony_ci } 1218cabdff1aSopenharmony_ci 1219cabdff1aSopenharmony_ci return 0; 1220cabdff1aSopenharmony_ci} 1221cabdff1aSopenharmony_ci 1222cabdff1aSopenharmony_cistatic int cbs_h2645_unit_requires_zero_byte(enum AVCodecID codec_id, 1223cabdff1aSopenharmony_ci CodedBitstreamUnitType type, 1224cabdff1aSopenharmony_ci int nal_unit_index) 1225cabdff1aSopenharmony_ci{ 1226cabdff1aSopenharmony_ci // Section B.1.2 in H.264, section B.2.2 in H.265. 1227cabdff1aSopenharmony_ci if (nal_unit_index == 0) { 1228cabdff1aSopenharmony_ci // Assume that this is the first NAL unit in an access unit. 1229cabdff1aSopenharmony_ci return 1; 1230cabdff1aSopenharmony_ci } 1231cabdff1aSopenharmony_ci if (codec_id == AV_CODEC_ID_H264) 1232cabdff1aSopenharmony_ci return type == H264_NAL_SPS || type == H264_NAL_PPS; 1233cabdff1aSopenharmony_ci if (codec_id == AV_CODEC_ID_HEVC) 1234cabdff1aSopenharmony_ci return type == HEVC_NAL_VPS || type == HEVC_NAL_SPS || type == HEVC_NAL_PPS; 1235cabdff1aSopenharmony_ci return 0; 1236cabdff1aSopenharmony_ci} 1237cabdff1aSopenharmony_ci 1238cabdff1aSopenharmony_cistatic int cbs_h2645_assemble_fragment(CodedBitstreamContext *ctx, 1239cabdff1aSopenharmony_ci CodedBitstreamFragment *frag) 1240cabdff1aSopenharmony_ci{ 1241cabdff1aSopenharmony_ci uint8_t *data; 1242cabdff1aSopenharmony_ci size_t max_size, dp, sp; 1243cabdff1aSopenharmony_ci int err, i, zero_run; 1244cabdff1aSopenharmony_ci 1245cabdff1aSopenharmony_ci for (i = 0; i < frag->nb_units; i++) { 1246cabdff1aSopenharmony_ci // Data should already all have been written when we get here. 1247cabdff1aSopenharmony_ci av_assert0(frag->units[i].data); 1248cabdff1aSopenharmony_ci } 1249cabdff1aSopenharmony_ci 1250cabdff1aSopenharmony_ci max_size = 0; 1251cabdff1aSopenharmony_ci for (i = 0; i < frag->nb_units; i++) { 1252cabdff1aSopenharmony_ci // Start code + content with worst-case emulation prevention. 1253cabdff1aSopenharmony_ci max_size += 4 + frag->units[i].data_size * 3 / 2; 1254cabdff1aSopenharmony_ci } 1255cabdff1aSopenharmony_ci 1256cabdff1aSopenharmony_ci data = av_realloc(NULL, max_size + AV_INPUT_BUFFER_PADDING_SIZE); 1257cabdff1aSopenharmony_ci if (!data) 1258cabdff1aSopenharmony_ci return AVERROR(ENOMEM); 1259cabdff1aSopenharmony_ci 1260cabdff1aSopenharmony_ci dp = 0; 1261cabdff1aSopenharmony_ci for (i = 0; i < frag->nb_units; i++) { 1262cabdff1aSopenharmony_ci CodedBitstreamUnit *unit = &frag->units[i]; 1263cabdff1aSopenharmony_ci 1264cabdff1aSopenharmony_ci if (unit->data_bit_padding > 0) { 1265cabdff1aSopenharmony_ci if (i < frag->nb_units - 1) 1266cabdff1aSopenharmony_ci av_log(ctx->log_ctx, AV_LOG_WARNING, "Probably invalid " 1267cabdff1aSopenharmony_ci "unaligned padding on non-final NAL unit.\n"); 1268cabdff1aSopenharmony_ci else 1269cabdff1aSopenharmony_ci frag->data_bit_padding = unit->data_bit_padding; 1270cabdff1aSopenharmony_ci } 1271cabdff1aSopenharmony_ci 1272cabdff1aSopenharmony_ci if (cbs_h2645_unit_requires_zero_byte(ctx->codec->codec_id, unit->type, i)) { 1273cabdff1aSopenharmony_ci // zero_byte 1274cabdff1aSopenharmony_ci data[dp++] = 0; 1275cabdff1aSopenharmony_ci } 1276cabdff1aSopenharmony_ci // start_code_prefix_one_3bytes 1277cabdff1aSopenharmony_ci data[dp++] = 0; 1278cabdff1aSopenharmony_ci data[dp++] = 0; 1279cabdff1aSopenharmony_ci data[dp++] = 1; 1280cabdff1aSopenharmony_ci 1281cabdff1aSopenharmony_ci zero_run = 0; 1282cabdff1aSopenharmony_ci for (sp = 0; sp < unit->data_size; sp++) { 1283cabdff1aSopenharmony_ci if (zero_run < 2) { 1284cabdff1aSopenharmony_ci if (unit->data[sp] == 0) 1285cabdff1aSopenharmony_ci ++zero_run; 1286cabdff1aSopenharmony_ci else 1287cabdff1aSopenharmony_ci zero_run = 0; 1288cabdff1aSopenharmony_ci } else { 1289cabdff1aSopenharmony_ci if ((unit->data[sp] & ~3) == 0) { 1290cabdff1aSopenharmony_ci // emulation_prevention_three_byte 1291cabdff1aSopenharmony_ci data[dp++] = 3; 1292cabdff1aSopenharmony_ci } 1293cabdff1aSopenharmony_ci zero_run = unit->data[sp] == 0; 1294cabdff1aSopenharmony_ci } 1295cabdff1aSopenharmony_ci data[dp++] = unit->data[sp]; 1296cabdff1aSopenharmony_ci } 1297cabdff1aSopenharmony_ci } 1298cabdff1aSopenharmony_ci 1299cabdff1aSopenharmony_ci av_assert0(dp <= max_size); 1300cabdff1aSopenharmony_ci err = av_reallocp(&data, dp + AV_INPUT_BUFFER_PADDING_SIZE); 1301cabdff1aSopenharmony_ci if (err) 1302cabdff1aSopenharmony_ci return err; 1303cabdff1aSopenharmony_ci memset(data + dp, 0, AV_INPUT_BUFFER_PADDING_SIZE); 1304cabdff1aSopenharmony_ci 1305cabdff1aSopenharmony_ci frag->data_ref = av_buffer_create(data, dp + AV_INPUT_BUFFER_PADDING_SIZE, 1306cabdff1aSopenharmony_ci NULL, NULL, 0); 1307cabdff1aSopenharmony_ci if (!frag->data_ref) { 1308cabdff1aSopenharmony_ci av_freep(&data); 1309cabdff1aSopenharmony_ci return AVERROR(ENOMEM); 1310cabdff1aSopenharmony_ci } 1311cabdff1aSopenharmony_ci 1312cabdff1aSopenharmony_ci frag->data = data; 1313cabdff1aSopenharmony_ci frag->data_size = dp; 1314cabdff1aSopenharmony_ci 1315cabdff1aSopenharmony_ci return 0; 1316cabdff1aSopenharmony_ci} 1317cabdff1aSopenharmony_ci 1318cabdff1aSopenharmony_cistatic void cbs_h264_flush(CodedBitstreamContext *ctx) 1319cabdff1aSopenharmony_ci{ 1320cabdff1aSopenharmony_ci CodedBitstreamH264Context *h264 = ctx->priv_data; 1321cabdff1aSopenharmony_ci 1322cabdff1aSopenharmony_ci for (int i = 0; i < FF_ARRAY_ELEMS(h264->sps); i++) { 1323cabdff1aSopenharmony_ci av_buffer_unref(&h264->sps_ref[i]); 1324cabdff1aSopenharmony_ci h264->sps[i] = NULL; 1325cabdff1aSopenharmony_ci } 1326cabdff1aSopenharmony_ci for (int i = 0; i < FF_ARRAY_ELEMS(h264->pps); i++) { 1327cabdff1aSopenharmony_ci av_buffer_unref(&h264->pps_ref[i]); 1328cabdff1aSopenharmony_ci h264->pps[i] = NULL; 1329cabdff1aSopenharmony_ci } 1330cabdff1aSopenharmony_ci 1331cabdff1aSopenharmony_ci h264->active_sps = NULL; 1332cabdff1aSopenharmony_ci h264->active_pps = NULL; 1333cabdff1aSopenharmony_ci h264->last_slice_nal_unit_type = 0; 1334cabdff1aSopenharmony_ci} 1335cabdff1aSopenharmony_ci 1336cabdff1aSopenharmony_cistatic void cbs_h264_close(CodedBitstreamContext *ctx) 1337cabdff1aSopenharmony_ci{ 1338cabdff1aSopenharmony_ci CodedBitstreamH264Context *h264 = ctx->priv_data; 1339cabdff1aSopenharmony_ci int i; 1340cabdff1aSopenharmony_ci 1341cabdff1aSopenharmony_ci ff_h2645_packet_uninit(&h264->common.read_packet); 1342cabdff1aSopenharmony_ci 1343cabdff1aSopenharmony_ci for (i = 0; i < FF_ARRAY_ELEMS(h264->sps); i++) 1344cabdff1aSopenharmony_ci av_buffer_unref(&h264->sps_ref[i]); 1345cabdff1aSopenharmony_ci for (i = 0; i < FF_ARRAY_ELEMS(h264->pps); i++) 1346cabdff1aSopenharmony_ci av_buffer_unref(&h264->pps_ref[i]); 1347cabdff1aSopenharmony_ci} 1348cabdff1aSopenharmony_ci 1349cabdff1aSopenharmony_cistatic void cbs_h265_flush(CodedBitstreamContext *ctx) 1350cabdff1aSopenharmony_ci{ 1351cabdff1aSopenharmony_ci CodedBitstreamH265Context *h265 = ctx->priv_data; 1352cabdff1aSopenharmony_ci 1353cabdff1aSopenharmony_ci for (int i = 0; i < FF_ARRAY_ELEMS(h265->vps); i++) { 1354cabdff1aSopenharmony_ci av_buffer_unref(&h265->vps_ref[i]); 1355cabdff1aSopenharmony_ci h265->vps[i] = NULL; 1356cabdff1aSopenharmony_ci } 1357cabdff1aSopenharmony_ci for (int i = 0; i < FF_ARRAY_ELEMS(h265->sps); i++) { 1358cabdff1aSopenharmony_ci av_buffer_unref(&h265->sps_ref[i]); 1359cabdff1aSopenharmony_ci h265->sps[i] = NULL; 1360cabdff1aSopenharmony_ci } 1361cabdff1aSopenharmony_ci for (int i = 0; i < FF_ARRAY_ELEMS(h265->pps); i++) { 1362cabdff1aSopenharmony_ci av_buffer_unref(&h265->pps_ref[i]); 1363cabdff1aSopenharmony_ci h265->pps[i] = NULL; 1364cabdff1aSopenharmony_ci } 1365cabdff1aSopenharmony_ci 1366cabdff1aSopenharmony_ci h265->active_vps = NULL; 1367cabdff1aSopenharmony_ci h265->active_sps = NULL; 1368cabdff1aSopenharmony_ci h265->active_pps = NULL; 1369cabdff1aSopenharmony_ci} 1370cabdff1aSopenharmony_ci 1371cabdff1aSopenharmony_cistatic void cbs_h265_close(CodedBitstreamContext *ctx) 1372cabdff1aSopenharmony_ci{ 1373cabdff1aSopenharmony_ci CodedBitstreamH265Context *h265 = ctx->priv_data; 1374cabdff1aSopenharmony_ci int i; 1375cabdff1aSopenharmony_ci 1376cabdff1aSopenharmony_ci ff_h2645_packet_uninit(&h265->common.read_packet); 1377cabdff1aSopenharmony_ci 1378cabdff1aSopenharmony_ci for (i = 0; i < FF_ARRAY_ELEMS(h265->vps); i++) 1379cabdff1aSopenharmony_ci av_buffer_unref(&h265->vps_ref[i]); 1380cabdff1aSopenharmony_ci for (i = 0; i < FF_ARRAY_ELEMS(h265->sps); i++) 1381cabdff1aSopenharmony_ci av_buffer_unref(&h265->sps_ref[i]); 1382cabdff1aSopenharmony_ci for (i = 0; i < FF_ARRAY_ELEMS(h265->pps); i++) 1383cabdff1aSopenharmony_ci av_buffer_unref(&h265->pps_ref[i]); 1384cabdff1aSopenharmony_ci} 1385cabdff1aSopenharmony_ci 1386cabdff1aSopenharmony_cistatic void cbs_h264_free_sei(void *opaque, uint8_t *content) 1387cabdff1aSopenharmony_ci{ 1388cabdff1aSopenharmony_ci H264RawSEI *sei = (H264RawSEI*)content; 1389cabdff1aSopenharmony_ci ff_cbs_sei_free_message_list(&sei->message_list); 1390cabdff1aSopenharmony_ci av_free(content); 1391cabdff1aSopenharmony_ci} 1392cabdff1aSopenharmony_ci 1393cabdff1aSopenharmony_cistatic const CodedBitstreamUnitTypeDescriptor cbs_h264_unit_types[] = { 1394cabdff1aSopenharmony_ci CBS_UNIT_TYPE_POD(H264_NAL_SPS, H264RawSPS), 1395cabdff1aSopenharmony_ci CBS_UNIT_TYPE_POD(H264_NAL_SPS_EXT, H264RawSPSExtension), 1396cabdff1aSopenharmony_ci 1397cabdff1aSopenharmony_ci CBS_UNIT_TYPE_INTERNAL_REF(H264_NAL_PPS, H264RawPPS, slice_group_id), 1398cabdff1aSopenharmony_ci 1399cabdff1aSopenharmony_ci { 1400cabdff1aSopenharmony_ci .nb_unit_types = 3, 1401cabdff1aSopenharmony_ci .unit_types = { 1402cabdff1aSopenharmony_ci H264_NAL_IDR_SLICE, 1403cabdff1aSopenharmony_ci H264_NAL_SLICE, 1404cabdff1aSopenharmony_ci H264_NAL_AUXILIARY_SLICE, 1405cabdff1aSopenharmony_ci }, 1406cabdff1aSopenharmony_ci .content_type = CBS_CONTENT_TYPE_INTERNAL_REFS, 1407cabdff1aSopenharmony_ci .content_size = sizeof(H264RawSlice), 1408cabdff1aSopenharmony_ci .nb_ref_offsets = 1, 1409cabdff1aSopenharmony_ci .ref_offsets = { offsetof(H264RawSlice, data) }, 1410cabdff1aSopenharmony_ci }, 1411cabdff1aSopenharmony_ci 1412cabdff1aSopenharmony_ci CBS_UNIT_TYPE_POD(H264_NAL_AUD, H264RawAUD), 1413cabdff1aSopenharmony_ci CBS_UNIT_TYPE_POD(H264_NAL_FILLER_DATA, H264RawFiller), 1414cabdff1aSopenharmony_ci CBS_UNIT_TYPE_POD(H264_NAL_END_SEQUENCE, H264RawNALUnitHeader), 1415cabdff1aSopenharmony_ci CBS_UNIT_TYPE_POD(H264_NAL_END_STREAM, H264RawNALUnitHeader), 1416cabdff1aSopenharmony_ci 1417cabdff1aSopenharmony_ci CBS_UNIT_TYPE_COMPLEX(H264_NAL_SEI, H264RawSEI, &cbs_h264_free_sei), 1418cabdff1aSopenharmony_ci 1419cabdff1aSopenharmony_ci CBS_UNIT_TYPE_END_OF_LIST 1420cabdff1aSopenharmony_ci}; 1421cabdff1aSopenharmony_ci 1422cabdff1aSopenharmony_cistatic void cbs_h265_free_sei(void *opaque, uint8_t *content) 1423cabdff1aSopenharmony_ci{ 1424cabdff1aSopenharmony_ci H265RawSEI *sei = (H265RawSEI*)content; 1425cabdff1aSopenharmony_ci ff_cbs_sei_free_message_list(&sei->message_list); 1426cabdff1aSopenharmony_ci av_free(content); 1427cabdff1aSopenharmony_ci} 1428cabdff1aSopenharmony_ci 1429cabdff1aSopenharmony_cistatic const CodedBitstreamUnitTypeDescriptor cbs_h265_unit_types[] = { 1430cabdff1aSopenharmony_ci CBS_UNIT_TYPE_INTERNAL_REF(HEVC_NAL_VPS, H265RawVPS, extension_data.data), 1431cabdff1aSopenharmony_ci CBS_UNIT_TYPE_INTERNAL_REF(HEVC_NAL_SPS, H265RawSPS, extension_data.data), 1432cabdff1aSopenharmony_ci CBS_UNIT_TYPE_INTERNAL_REF(HEVC_NAL_PPS, H265RawPPS, extension_data.data), 1433cabdff1aSopenharmony_ci 1434cabdff1aSopenharmony_ci CBS_UNIT_TYPE_POD(HEVC_NAL_AUD, H265RawAUD), 1435cabdff1aSopenharmony_ci 1436cabdff1aSopenharmony_ci { 1437cabdff1aSopenharmony_ci // Slices of non-IRAP pictures. 1438cabdff1aSopenharmony_ci .nb_unit_types = CBS_UNIT_TYPE_RANGE, 1439cabdff1aSopenharmony_ci .unit_type_range_start = HEVC_NAL_TRAIL_N, 1440cabdff1aSopenharmony_ci .unit_type_range_end = HEVC_NAL_RASL_R, 1441cabdff1aSopenharmony_ci 1442cabdff1aSopenharmony_ci .content_type = CBS_CONTENT_TYPE_INTERNAL_REFS, 1443cabdff1aSopenharmony_ci .content_size = sizeof(H265RawSlice), 1444cabdff1aSopenharmony_ci .nb_ref_offsets = 1, 1445cabdff1aSopenharmony_ci .ref_offsets = { offsetof(H265RawSlice, data) }, 1446cabdff1aSopenharmony_ci }, 1447cabdff1aSopenharmony_ci 1448cabdff1aSopenharmony_ci { 1449cabdff1aSopenharmony_ci // Slices of IRAP pictures. 1450cabdff1aSopenharmony_ci .nb_unit_types = CBS_UNIT_TYPE_RANGE, 1451cabdff1aSopenharmony_ci .unit_type_range_start = HEVC_NAL_BLA_W_LP, 1452cabdff1aSopenharmony_ci .unit_type_range_end = HEVC_NAL_CRA_NUT, 1453cabdff1aSopenharmony_ci 1454cabdff1aSopenharmony_ci .content_type = CBS_CONTENT_TYPE_INTERNAL_REFS, 1455cabdff1aSopenharmony_ci .content_size = sizeof(H265RawSlice), 1456cabdff1aSopenharmony_ci .nb_ref_offsets = 1, 1457cabdff1aSopenharmony_ci .ref_offsets = { offsetof(H265RawSlice, data) }, 1458cabdff1aSopenharmony_ci }, 1459cabdff1aSopenharmony_ci 1460cabdff1aSopenharmony_ci { 1461cabdff1aSopenharmony_ci .nb_unit_types = 2, 1462cabdff1aSopenharmony_ci .unit_types = { 1463cabdff1aSopenharmony_ci HEVC_NAL_SEI_PREFIX, 1464cabdff1aSopenharmony_ci HEVC_NAL_SEI_SUFFIX 1465cabdff1aSopenharmony_ci }, 1466cabdff1aSopenharmony_ci .content_type = CBS_CONTENT_TYPE_COMPLEX, 1467cabdff1aSopenharmony_ci .content_size = sizeof(H265RawSEI), 1468cabdff1aSopenharmony_ci .content_free = &cbs_h265_free_sei, 1469cabdff1aSopenharmony_ci }, 1470cabdff1aSopenharmony_ci 1471cabdff1aSopenharmony_ci CBS_UNIT_TYPE_END_OF_LIST 1472cabdff1aSopenharmony_ci}; 1473cabdff1aSopenharmony_ci 1474cabdff1aSopenharmony_ciconst CodedBitstreamType ff_cbs_type_h264 = { 1475cabdff1aSopenharmony_ci .codec_id = AV_CODEC_ID_H264, 1476cabdff1aSopenharmony_ci 1477cabdff1aSopenharmony_ci .priv_data_size = sizeof(CodedBitstreamH264Context), 1478cabdff1aSopenharmony_ci 1479cabdff1aSopenharmony_ci .unit_types = cbs_h264_unit_types, 1480cabdff1aSopenharmony_ci 1481cabdff1aSopenharmony_ci .split_fragment = &cbs_h2645_split_fragment, 1482cabdff1aSopenharmony_ci .read_unit = &cbs_h264_read_nal_unit, 1483cabdff1aSopenharmony_ci .write_unit = &cbs_h264_write_nal_unit, 1484cabdff1aSopenharmony_ci .assemble_fragment = &cbs_h2645_assemble_fragment, 1485cabdff1aSopenharmony_ci 1486cabdff1aSopenharmony_ci .flush = &cbs_h264_flush, 1487cabdff1aSopenharmony_ci .close = &cbs_h264_close, 1488cabdff1aSopenharmony_ci}; 1489cabdff1aSopenharmony_ci 1490cabdff1aSopenharmony_ciconst CodedBitstreamType ff_cbs_type_h265 = { 1491cabdff1aSopenharmony_ci .codec_id = AV_CODEC_ID_HEVC, 1492cabdff1aSopenharmony_ci 1493cabdff1aSopenharmony_ci .priv_data_size = sizeof(CodedBitstreamH265Context), 1494cabdff1aSopenharmony_ci 1495cabdff1aSopenharmony_ci .unit_types = cbs_h265_unit_types, 1496cabdff1aSopenharmony_ci 1497cabdff1aSopenharmony_ci .split_fragment = &cbs_h2645_split_fragment, 1498cabdff1aSopenharmony_ci .read_unit = &cbs_h265_read_nal_unit, 1499cabdff1aSopenharmony_ci .write_unit = &cbs_h265_write_nal_unit, 1500cabdff1aSopenharmony_ci .assemble_fragment = &cbs_h2645_assemble_fragment, 1501cabdff1aSopenharmony_ci 1502cabdff1aSopenharmony_ci .flush = &cbs_h265_flush, 1503cabdff1aSopenharmony_ci .close = &cbs_h265_close, 1504cabdff1aSopenharmony_ci}; 1505cabdff1aSopenharmony_ci 1506cabdff1aSopenharmony_cistatic const SEIMessageTypeDescriptor cbs_sei_common_types[] = { 1507cabdff1aSopenharmony_ci { 1508cabdff1aSopenharmony_ci SEI_TYPE_FILLER_PAYLOAD, 1509cabdff1aSopenharmony_ci 1, 1, 1510cabdff1aSopenharmony_ci sizeof(SEIRawFillerPayload), 1511cabdff1aSopenharmony_ci SEI_MESSAGE_RW(sei, filler_payload), 1512cabdff1aSopenharmony_ci }, 1513cabdff1aSopenharmony_ci { 1514cabdff1aSopenharmony_ci SEI_TYPE_USER_DATA_REGISTERED_ITU_T_T35, 1515cabdff1aSopenharmony_ci 1, 1, 1516cabdff1aSopenharmony_ci sizeof(SEIRawUserDataRegistered), 1517cabdff1aSopenharmony_ci SEI_MESSAGE_RW(sei, user_data_registered), 1518cabdff1aSopenharmony_ci }, 1519cabdff1aSopenharmony_ci { 1520cabdff1aSopenharmony_ci SEI_TYPE_USER_DATA_UNREGISTERED, 1521cabdff1aSopenharmony_ci 1, 1, 1522cabdff1aSopenharmony_ci sizeof(SEIRawUserDataUnregistered), 1523cabdff1aSopenharmony_ci SEI_MESSAGE_RW(sei, user_data_unregistered), 1524cabdff1aSopenharmony_ci }, 1525cabdff1aSopenharmony_ci { 1526cabdff1aSopenharmony_ci SEI_TYPE_MASTERING_DISPLAY_COLOUR_VOLUME, 1527cabdff1aSopenharmony_ci 1, 0, 1528cabdff1aSopenharmony_ci sizeof(SEIRawMasteringDisplayColourVolume), 1529cabdff1aSopenharmony_ci SEI_MESSAGE_RW(sei, mastering_display_colour_volume), 1530cabdff1aSopenharmony_ci }, 1531cabdff1aSopenharmony_ci { 1532cabdff1aSopenharmony_ci SEI_TYPE_CONTENT_LIGHT_LEVEL_INFO, 1533cabdff1aSopenharmony_ci 1, 0, 1534cabdff1aSopenharmony_ci sizeof(SEIRawContentLightLevelInfo), 1535cabdff1aSopenharmony_ci SEI_MESSAGE_RW(sei, content_light_level_info), 1536cabdff1aSopenharmony_ci }, 1537cabdff1aSopenharmony_ci { 1538cabdff1aSopenharmony_ci SEI_TYPE_ALTERNATIVE_TRANSFER_CHARACTERISTICS, 1539cabdff1aSopenharmony_ci 1, 0, 1540cabdff1aSopenharmony_ci sizeof(SEIRawAlternativeTransferCharacteristics), 1541cabdff1aSopenharmony_ci SEI_MESSAGE_RW(sei, alternative_transfer_characteristics), 1542cabdff1aSopenharmony_ci }, 1543cabdff1aSopenharmony_ci SEI_MESSAGE_TYPE_END, 1544cabdff1aSopenharmony_ci}; 1545cabdff1aSopenharmony_ci 1546cabdff1aSopenharmony_cistatic const SEIMessageTypeDescriptor cbs_sei_h264_types[] = { 1547cabdff1aSopenharmony_ci { 1548cabdff1aSopenharmony_ci SEI_TYPE_BUFFERING_PERIOD, 1549cabdff1aSopenharmony_ci 1, 0, 1550cabdff1aSopenharmony_ci sizeof(H264RawSEIBufferingPeriod), 1551cabdff1aSopenharmony_ci SEI_MESSAGE_RW(h264, sei_buffering_period), 1552cabdff1aSopenharmony_ci }, 1553cabdff1aSopenharmony_ci { 1554cabdff1aSopenharmony_ci SEI_TYPE_PIC_TIMING, 1555cabdff1aSopenharmony_ci 1, 0, 1556cabdff1aSopenharmony_ci sizeof(H264RawSEIPicTiming), 1557cabdff1aSopenharmony_ci SEI_MESSAGE_RW(h264, sei_pic_timing), 1558cabdff1aSopenharmony_ci }, 1559cabdff1aSopenharmony_ci { 1560cabdff1aSopenharmony_ci SEI_TYPE_PAN_SCAN_RECT, 1561cabdff1aSopenharmony_ci 1, 0, 1562cabdff1aSopenharmony_ci sizeof(H264RawSEIPanScanRect), 1563cabdff1aSopenharmony_ci SEI_MESSAGE_RW(h264, sei_pan_scan_rect), 1564cabdff1aSopenharmony_ci }, 1565cabdff1aSopenharmony_ci { 1566cabdff1aSopenharmony_ci SEI_TYPE_RECOVERY_POINT, 1567cabdff1aSopenharmony_ci 1, 0, 1568cabdff1aSopenharmony_ci sizeof(H264RawSEIRecoveryPoint), 1569cabdff1aSopenharmony_ci SEI_MESSAGE_RW(h264, sei_recovery_point), 1570cabdff1aSopenharmony_ci }, 1571cabdff1aSopenharmony_ci { 1572cabdff1aSopenharmony_ci SEI_TYPE_FILM_GRAIN_CHARACTERISTICS, 1573cabdff1aSopenharmony_ci 1, 0, 1574cabdff1aSopenharmony_ci sizeof(H264RawFilmGrainCharacteristics), 1575cabdff1aSopenharmony_ci SEI_MESSAGE_RW(h264, film_grain_characteristics), 1576cabdff1aSopenharmony_ci }, 1577cabdff1aSopenharmony_ci { 1578cabdff1aSopenharmony_ci SEI_TYPE_DISPLAY_ORIENTATION, 1579cabdff1aSopenharmony_ci 1, 0, 1580cabdff1aSopenharmony_ci sizeof(H264RawSEIDisplayOrientation), 1581cabdff1aSopenharmony_ci SEI_MESSAGE_RW(h264, sei_display_orientation), 1582cabdff1aSopenharmony_ci }, 1583cabdff1aSopenharmony_ci SEI_MESSAGE_TYPE_END 1584cabdff1aSopenharmony_ci}; 1585cabdff1aSopenharmony_ci 1586cabdff1aSopenharmony_cistatic const SEIMessageTypeDescriptor cbs_sei_h265_types[] = { 1587cabdff1aSopenharmony_ci { 1588cabdff1aSopenharmony_ci SEI_TYPE_BUFFERING_PERIOD, 1589cabdff1aSopenharmony_ci 1, 0, 1590cabdff1aSopenharmony_ci sizeof(H265RawSEIBufferingPeriod), 1591cabdff1aSopenharmony_ci SEI_MESSAGE_RW(h265, sei_buffering_period), 1592cabdff1aSopenharmony_ci }, 1593cabdff1aSopenharmony_ci { 1594cabdff1aSopenharmony_ci SEI_TYPE_PIC_TIMING, 1595cabdff1aSopenharmony_ci 1, 0, 1596cabdff1aSopenharmony_ci sizeof(H265RawSEIPicTiming), 1597cabdff1aSopenharmony_ci SEI_MESSAGE_RW(h265, sei_pic_timing), 1598cabdff1aSopenharmony_ci }, 1599cabdff1aSopenharmony_ci { 1600cabdff1aSopenharmony_ci SEI_TYPE_PAN_SCAN_RECT, 1601cabdff1aSopenharmony_ci 1, 0, 1602cabdff1aSopenharmony_ci sizeof(H265RawSEIPanScanRect), 1603cabdff1aSopenharmony_ci SEI_MESSAGE_RW(h265, sei_pan_scan_rect), 1604cabdff1aSopenharmony_ci }, 1605cabdff1aSopenharmony_ci { 1606cabdff1aSopenharmony_ci SEI_TYPE_RECOVERY_POINT, 1607cabdff1aSopenharmony_ci 1, 0, 1608cabdff1aSopenharmony_ci sizeof(H265RawSEIRecoveryPoint), 1609cabdff1aSopenharmony_ci SEI_MESSAGE_RW(h265, sei_recovery_point), 1610cabdff1aSopenharmony_ci }, 1611cabdff1aSopenharmony_ci { 1612cabdff1aSopenharmony_ci SEI_TYPE_FILM_GRAIN_CHARACTERISTICS, 1613cabdff1aSopenharmony_ci 1, 0, 1614cabdff1aSopenharmony_ci sizeof(H265RawFilmGrainCharacteristics), 1615cabdff1aSopenharmony_ci SEI_MESSAGE_RW(h265, film_grain_characteristics), 1616cabdff1aSopenharmony_ci }, 1617cabdff1aSopenharmony_ci { 1618cabdff1aSopenharmony_ci SEI_TYPE_DISPLAY_ORIENTATION, 1619cabdff1aSopenharmony_ci 1, 0, 1620cabdff1aSopenharmony_ci sizeof(H265RawSEIDisplayOrientation), 1621cabdff1aSopenharmony_ci SEI_MESSAGE_RW(h265, sei_display_orientation), 1622cabdff1aSopenharmony_ci }, 1623cabdff1aSopenharmony_ci { 1624cabdff1aSopenharmony_ci SEI_TYPE_ACTIVE_PARAMETER_SETS, 1625cabdff1aSopenharmony_ci 1, 0, 1626cabdff1aSopenharmony_ci sizeof(H265RawSEIActiveParameterSets), 1627cabdff1aSopenharmony_ci SEI_MESSAGE_RW(h265, sei_active_parameter_sets), 1628cabdff1aSopenharmony_ci }, 1629cabdff1aSopenharmony_ci { 1630cabdff1aSopenharmony_ci SEI_TYPE_DECODED_PICTURE_HASH, 1631cabdff1aSopenharmony_ci 0, 1, 1632cabdff1aSopenharmony_ci sizeof(H265RawSEIDecodedPictureHash), 1633cabdff1aSopenharmony_ci SEI_MESSAGE_RW(h265, sei_decoded_picture_hash), 1634cabdff1aSopenharmony_ci }, 1635cabdff1aSopenharmony_ci { 1636cabdff1aSopenharmony_ci SEI_TYPE_TIME_CODE, 1637cabdff1aSopenharmony_ci 1, 0, 1638cabdff1aSopenharmony_ci sizeof(H265RawSEITimeCode), 1639cabdff1aSopenharmony_ci SEI_MESSAGE_RW(h265, sei_time_code), 1640cabdff1aSopenharmony_ci }, 1641cabdff1aSopenharmony_ci { 1642cabdff1aSopenharmony_ci SEI_TYPE_ALPHA_CHANNEL_INFO, 1643cabdff1aSopenharmony_ci 1, 0, 1644cabdff1aSopenharmony_ci sizeof(H265RawSEIAlphaChannelInfo), 1645cabdff1aSopenharmony_ci SEI_MESSAGE_RW(h265, sei_alpha_channel_info), 1646cabdff1aSopenharmony_ci }, 1647cabdff1aSopenharmony_ci SEI_MESSAGE_TYPE_END 1648cabdff1aSopenharmony_ci}; 1649cabdff1aSopenharmony_ci 1650cabdff1aSopenharmony_ciconst SEIMessageTypeDescriptor *ff_cbs_sei_find_type(CodedBitstreamContext *ctx, 1651cabdff1aSopenharmony_ci int payload_type) 1652cabdff1aSopenharmony_ci{ 1653cabdff1aSopenharmony_ci const SEIMessageTypeDescriptor *codec_list; 1654cabdff1aSopenharmony_ci int i; 1655cabdff1aSopenharmony_ci 1656cabdff1aSopenharmony_ci for (i = 0; cbs_sei_common_types[i].type >= 0; i++) { 1657cabdff1aSopenharmony_ci if (cbs_sei_common_types[i].type == payload_type) 1658cabdff1aSopenharmony_ci return &cbs_sei_common_types[i]; 1659cabdff1aSopenharmony_ci } 1660cabdff1aSopenharmony_ci 1661cabdff1aSopenharmony_ci switch (ctx->codec->codec_id) { 1662cabdff1aSopenharmony_ci case AV_CODEC_ID_H264: 1663cabdff1aSopenharmony_ci codec_list = cbs_sei_h264_types; 1664cabdff1aSopenharmony_ci break; 1665cabdff1aSopenharmony_ci case AV_CODEC_ID_H265: 1666cabdff1aSopenharmony_ci codec_list = cbs_sei_h265_types; 1667cabdff1aSopenharmony_ci break; 1668cabdff1aSopenharmony_ci default: 1669cabdff1aSopenharmony_ci return NULL; 1670cabdff1aSopenharmony_ci } 1671cabdff1aSopenharmony_ci 1672cabdff1aSopenharmony_ci for (i = 0; codec_list[i].type >= 0; i++) { 1673cabdff1aSopenharmony_ci if (codec_list[i].type == payload_type) 1674cabdff1aSopenharmony_ci return &codec_list[i]; 1675cabdff1aSopenharmony_ci } 1676cabdff1aSopenharmony_ci 1677cabdff1aSopenharmony_ci return NULL; 1678cabdff1aSopenharmony_ci} 1679