From 32769226e575319cfa5569b197e6ca463ad0be70 Mon Sep 17 00:00:00 2001 From: cfajardo Date: Thu, 10 Feb 2022 21:39:58 +0100 Subject: [PATCH 1/7] Remove CBS implementation to use FFMPEG one --- CMakeLists.txt | 24 +- sunshine/video.h | 2 + third-party/cbs/CMakeLists.txt | 69 - third-party/cbs/bytestream.h | 351 ---- third-party/cbs/cbs.c | 1050 ---------- third-party/cbs/cbs_av1.c | 1323 ------------ third-party/cbs/cbs_av1_syntax_template.c | 2063 ------------------- third-party/cbs/cbs_h2645.c | 1632 --------------- third-party/cbs/cbs_h264_syntax_template.c | 1175 ----------- third-party/cbs/cbs_h265_syntax_template.c | 2038 ------------------ third-party/cbs/cbs_internal.h | 220 -- third-party/cbs/cbs_jpeg.c | 482 ----- third-party/cbs/cbs_jpeg_syntax_template.c | 189 -- third-party/cbs/cbs_mpeg2.c | 469 ----- third-party/cbs/cbs_mpeg2_syntax_template.c | 413 ---- third-party/cbs/cbs_sei.c | 355 ---- third-party/cbs/cbs_sei_syntax_template.c | 310 --- third-party/cbs/cbs_vp9.c | 675 ------ third-party/cbs/cbs_vp9_syntax_template.c | 422 ---- third-party/cbs/config.h | 27 - third-party/cbs/defs.h | 51 - third-party/cbs/get_bits.h | 831 -------- third-party/cbs/h2645_parse.c | 535 ----- third-party/cbs/h264_ps.h | 173 -- third-party/cbs/h264_sei.h | 202 -- third-party/cbs/hevc_sei.h | 142 -- third-party/cbs/intmath.h | 152 -- third-party/cbs/mathops.h | 243 --- third-party/cbs/put_bits.h | 406 ---- third-party/cbs/video_levels.c | 349 ---- third-party/cbs/vlc.h | 140 -- 31 files changed, 14 insertions(+), 16499 deletions(-) delete mode 100644 third-party/cbs/CMakeLists.txt delete mode 100644 third-party/cbs/bytestream.h delete mode 100644 third-party/cbs/cbs.c delete mode 100644 third-party/cbs/cbs_av1.c delete mode 100644 third-party/cbs/cbs_av1_syntax_template.c delete mode 100644 third-party/cbs/cbs_h2645.c delete mode 100644 third-party/cbs/cbs_h264_syntax_template.c delete mode 100644 third-party/cbs/cbs_h265_syntax_template.c delete mode 100644 third-party/cbs/cbs_internal.h delete mode 100644 third-party/cbs/cbs_jpeg.c delete mode 100644 third-party/cbs/cbs_jpeg_syntax_template.c delete mode 100644 third-party/cbs/cbs_mpeg2.c delete mode 100644 third-party/cbs/cbs_mpeg2_syntax_template.c delete mode 100644 third-party/cbs/cbs_sei.c delete mode 100644 third-party/cbs/cbs_sei_syntax_template.c delete mode 100644 third-party/cbs/cbs_vp9.c delete mode 100644 third-party/cbs/cbs_vp9_syntax_template.c delete mode 100644 third-party/cbs/config.h delete mode 100644 third-party/cbs/defs.h delete mode 100644 third-party/cbs/get_bits.h delete mode 100644 third-party/cbs/h2645_parse.c delete mode 100644 third-party/cbs/h264_ps.h delete mode 100644 third-party/cbs/h264_sei.h delete mode 100644 third-party/cbs/hevc_sei.h delete mode 100644 third-party/cbs/intmath.h delete mode 100644 third-party/cbs/mathops.h delete mode 100644 third-party/cbs/put_bits.h delete mode 100644 third-party/cbs/video_levels.c delete mode 100644 third-party/cbs/vlc.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 20751568593..01a4178009d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -31,14 +31,14 @@ list(APPEND SUNSHINE_COMPILE_OPTIONS -Wall -Wno-missing-braces -Wno-maybe-uninit if(WIN32) enable_language(RC) set(CMAKE_RC_COMPILER windres) - file( - DOWNLOAD "https://github.com/TheElixZammuto/sunshine-prebuilt/releases/download/1.0.0/pre-compiled.zip" "${CMAKE_CURRENT_BINARY_DIR}/pre-compiled.zip" - TIMEOUT 60 - EXPECTED_HASH SHA256=5d59986bd7f619eaaf82b2dd56b5127b747c9cbe8db61e3b898ff6b485298ed6) - - file(ARCHIVE_EXTRACT - INPUT "${CMAKE_CURRENT_BINARY_DIR}/pre-compiled.zip" - DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/pre-compiled) + # file( + # DOWNLOAD "https://github.com/TheElixZammuto/sunshine-prebuilt/releases/download/1.0.0/pre-compiled.zip" "${CMAKE_CURRENT_BINARY_DIR}/pre-compiled.zip" + # TIMEOUT 60 + # EXPECTED_HASH SHA256=5d59986bd7f619eaaf82b2dd56b5127b747c9cbe8db61e3b898ff6b485298ed6) + + # file(ARCHIVE_EXTRACT + # INPUT "${CMAKE_CURRENT_BINARY_DIR}/pre-compiled.zip" + # DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/pre-compiled) set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static") if(NOT DEFINED SUNSHINE_PREPARED_BINARIES) @@ -320,7 +320,7 @@ include_directories( ${PLATFORM_INCLUDE_DIRS} ) -add_subdirectory(third-party/cbs) +# add_subdirectory(third-party/cbs) string(TOUPPER "x${CMAKE_BUILD_TYPE}" BUILD_TYPE) if("${BUILD_TYPE}" STREQUAL "XDEBUG") @@ -345,12 +345,12 @@ if(NOT SUNSHINE_DEFAULT_DIR) set(SUNSHINE_DEFAULT_DIR "${SUNSHINE_ASSETS_DIR}") endif() -list(APPEND CBS_EXTERNAL_LIBRARIES - cbs) +# list(APPEND CBS_EXTERNAL_LIBRARIES +# cbs) list(APPEND SUNSHINE_EXTERNAL_LIBRARIES libminiupnpc-static - ${CBS_EXTERNAL_LIBRARIES} + # ${CBS_EXTERNAL_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} stdc++fs enet diff --git a/sunshine/video.h b/sunshine/video.h index fab4ff76837..f26e1d3de2a 100644 --- a/sunshine/video.h +++ b/sunshine/video.h @@ -27,6 +27,8 @@ struct packet_raw_t : public AVPacket { buf = nullptr; side_data = nullptr; side_data_elems = 0; + opaque = nullptr; + opaque_ref = nullptr; } template diff --git a/third-party/cbs/CMakeLists.txt b/third-party/cbs/CMakeLists.txt deleted file mode 100644 index b30a8031341..00000000000 --- a/third-party/cbs/CMakeLists.txt +++ /dev/null @@ -1,69 +0,0 @@ -cmake_minimum_required(VERSION 3.0) - -project(CBS) - -SET(CBS_SOURCE_FILES -include/cbs/av1.h -include/cbs/cbs_av1.h -include/cbs/cbs_bsf.h -include/cbs/cbs.h -include/cbs/cbs_h2645.h -include/cbs/cbs_h264.h -include/cbs/cbs_h265.h -include/cbs/cbs_jpeg.h -include/cbs/cbs_mpeg2.h -include/cbs/cbs_sei.h -include/cbs/cbs_vp9.h -include/cbs/h2645_parse.h -include/cbs/h264.h -include/cbs/hevc.h -include/cbs/sei.h -include/cbs/video_levels.h - -cbs.c -cbs_h2645.c -cbs_av1.c -cbs_vp9.c -cbs_mpeg2.c -cbs_jpeg.c -cbs_sei.c -h2645_parse.c -video_levels.c - -bytestream.h -cbs_internal.h -defs.h -get_bits.h -h264_ps.h -h264_sei.h -hevc_sei.h -intmath.h -mathops.h -put_bits.h -vlc.h -config.h -) - -include_directories(include) - -if(DEFINED FFMPEG_INCLUDE_DIRS) -include_directories(${FFMPEG_INCLUDE_DIRS}) -endif() - -add_compile_definitions( - HAVE_THREADS=1 - HAVE_FAST_UNALIGNED - - PIC=1 - - CONFIG_CBS_AV1=1 - CONFIG_CBS_H264=1 - CONFIG_CBS_H265=1 - CONFIG_CBS_JPEG=1 - CONFIG_CBS_MPEG2=1 - CONFIG_CBS_VP9=1 - ) - - -add_library(cbs ${CBS_SOURCE_FILES}) -target_compile_options(cbs PRIVATE -Wall -Wno-incompatible-pointer-types -Wno-maybe-uninitialized -Wno-format -Wno-format-extra-args) \ No newline at end of file diff --git a/third-party/cbs/bytestream.h b/third-party/cbs/bytestream.h deleted file mode 100644 index 7892af92b11..00000000000 --- a/third-party/cbs/bytestream.h +++ /dev/null @@ -1,351 +0,0 @@ -/* - * Bytestream functions - * copyright (c) 2006 Baptiste Coudurier - * Copyright (c) 2012 Aneesh Dogra (lionaneesh) - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_BYTESTREAM_H -#define AVCODEC_BYTESTREAM_H - -#include "config.h" - -#include -#include - -#include -#include -#include - -typedef struct GetByteContext { - const uint8_t *buffer, *buffer_end, *buffer_start; -} GetByteContext; - -typedef struct PutByteContext { - uint8_t *buffer, *buffer_end, *buffer_start; - int eof; -} PutByteContext; - -#define DEF(type, name, bytes, read, write) \ - static av_always_inline type bytestream_get_##name(const uint8_t **b) { \ - (*b) += bytes; \ - return read(*b - bytes); \ - } \ - static av_always_inline void bytestream_put_##name(uint8_t **b, \ - const type value) { \ - write(*b, value); \ - (*b) += bytes; \ - } \ - static av_always_inline void bytestream2_put_##name##u(PutByteContext *p, \ - const type value) { \ - bytestream_put_##name(&p->buffer, value); \ - } \ - static av_always_inline void bytestream2_put_##name(PutByteContext *p, \ - const type value) { \ - if(!p->eof && (p->buffer_end - p->buffer >= bytes)) { \ - write(p->buffer, value); \ - p->buffer += bytes; \ - } \ - else \ - p->eof = 1; \ - } \ - static av_always_inline type bytestream2_get_##name##u(GetByteContext *g) { \ - return bytestream_get_##name(&g->buffer); \ - } \ - static av_always_inline type bytestream2_get_##name(GetByteContext *g) { \ - if(g->buffer_end - g->buffer < bytes) { \ - g->buffer = g->buffer_end; \ - return 0; \ - } \ - return bytestream2_get_##name##u(g); \ - } \ - static av_always_inline type bytestream2_peek_##name##u(GetByteContext *g) { \ - return read(g->buffer); \ - } \ - static av_always_inline type bytestream2_peek_##name(GetByteContext *g) { \ - if(g->buffer_end - g->buffer < bytes) \ - return 0; \ - return bytestream2_peek_##name##u(g); \ - } - -DEF(uint64_t, le64, 8, AV_RL64, AV_WL64) -DEF(unsigned int, le32, 4, AV_RL32, AV_WL32) -DEF(unsigned int, le24, 3, AV_RL24, AV_WL24) -DEF(unsigned int, le16, 2, AV_RL16, AV_WL16) -DEF(uint64_t, be64, 8, AV_RB64, AV_WB64) -DEF(unsigned int, be32, 4, AV_RB32, AV_WB32) -DEF(unsigned int, be24, 3, AV_RB24, AV_WB24) -DEF(unsigned int, be16, 2, AV_RB16, AV_WB16) -DEF(unsigned int, byte, 1, AV_RB8, AV_WB8) - -#if AV_HAVE_BIGENDIAN -#define bytestream2_get_ne16 bytestream2_get_be16 -#define bytestream2_get_ne24 bytestream2_get_be24 -#define bytestream2_get_ne32 bytestream2_get_be32 -#define bytestream2_get_ne64 bytestream2_get_be64 -#define bytestream2_get_ne16u bytestream2_get_be16u -#define bytestream2_get_ne24u bytestream2_get_be24u -#define bytestream2_get_ne32u bytestream2_get_be32u -#define bytestream2_get_ne64u bytestream2_get_be64u -#define bytestream2_put_ne16 bytestream2_put_be16 -#define bytestream2_put_ne24 bytestream2_put_be24 -#define bytestream2_put_ne32 bytestream2_put_be32 -#define bytestream2_put_ne64 bytestream2_put_be64 -#define bytestream2_peek_ne16 bytestream2_peek_be16 -#define bytestream2_peek_ne24 bytestream2_peek_be24 -#define bytestream2_peek_ne32 bytestream2_peek_be32 -#define bytestream2_peek_ne64 bytestream2_peek_be64 -#else -#define bytestream2_get_ne16 bytestream2_get_le16 -#define bytestream2_get_ne24 bytestream2_get_le24 -#define bytestream2_get_ne32 bytestream2_get_le32 -#define bytestream2_get_ne64 bytestream2_get_le64 -#define bytestream2_get_ne16u bytestream2_get_le16u -#define bytestream2_get_ne24u bytestream2_get_le24u -#define bytestream2_get_ne32u bytestream2_get_le32u -#define bytestream2_get_ne64u bytestream2_get_le64u -#define bytestream2_put_ne16 bytestream2_put_le16 -#define bytestream2_put_ne24 bytestream2_put_le24 -#define bytestream2_put_ne32 bytestream2_put_le32 -#define bytestream2_put_ne64 bytestream2_put_le64 -#define bytestream2_peek_ne16 bytestream2_peek_le16 -#define bytestream2_peek_ne24 bytestream2_peek_le24 -#define bytestream2_peek_ne32 bytestream2_peek_le32 -#define bytestream2_peek_ne64 bytestream2_peek_le64 -#endif - -static av_always_inline void bytestream2_init(GetByteContext *g, - const uint8_t *buf, - int buf_size) { - av_assert0(buf_size >= 0); - g->buffer = buf; - g->buffer_start = buf; - g->buffer_end = buf + buf_size; -} - -static av_always_inline void bytestream2_init_writer(PutByteContext *p, - uint8_t *buf, - int buf_size) { - av_assert0(buf_size >= 0); - p->buffer = buf; - p->buffer_start = buf; - p->buffer_end = buf + buf_size; - p->eof = 0; -} - -static av_always_inline int bytestream2_get_bytes_left(GetByteContext *g) { - return g->buffer_end - g->buffer; -} - -static av_always_inline int bytestream2_get_bytes_left_p(PutByteContext *p) { - return p->buffer_end - p->buffer; -} - -static av_always_inline void bytestream2_skip(GetByteContext *g, - unsigned int size) { - g->buffer += FFMIN(g->buffer_end - g->buffer, size); -} - -static av_always_inline void bytestream2_skipu(GetByteContext *g, - unsigned int size) { - g->buffer += size; -} - -static av_always_inline void bytestream2_skip_p(PutByteContext *p, - unsigned int size) { - int size2; - if(p->eof) - return; - size2 = FFMIN(p->buffer_end - p->buffer, size); - if(size2 != size) - p->eof = 1; - p->buffer += size2; -} - -static av_always_inline int bytestream2_tell(GetByteContext *g) { - return (int)(g->buffer - g->buffer_start); -} - -static av_always_inline int bytestream2_tell_p(PutByteContext *p) { - return (int)(p->buffer - p->buffer_start); -} - -static av_always_inline int bytestream2_size(GetByteContext *g) { - return (int)(g->buffer_end - g->buffer_start); -} - -static av_always_inline int bytestream2_size_p(PutByteContext *p) { - return (int)(p->buffer_end - p->buffer_start); -} - -static av_always_inline int bytestream2_seek(GetByteContext *g, - int offset, - int whence) { - switch(whence) { - case SEEK_CUR: - offset = av_clip(offset, -(g->buffer - g->buffer_start), - g->buffer_end - g->buffer); - g->buffer += offset; - break; - case SEEK_END: - offset = av_clip(offset, -(g->buffer_end - g->buffer_start), 0); - g->buffer = g->buffer_end + offset; - break; - case SEEK_SET: - offset = av_clip(offset, 0, g->buffer_end - g->buffer_start); - g->buffer = g->buffer_start + offset; - break; - default: - return AVERROR(EINVAL); - } - return bytestream2_tell(g); -} - -static av_always_inline int bytestream2_seek_p(PutByteContext *p, - int offset, - int whence) { - p->eof = 0; - switch(whence) { - case SEEK_CUR: - if(p->buffer_end - p->buffer < offset) - p->eof = 1; - offset = av_clip(offset, -(p->buffer - p->buffer_start), - p->buffer_end - p->buffer); - p->buffer += offset; - break; - case SEEK_END: - if(offset > 0) - p->eof = 1; - offset = av_clip(offset, -(p->buffer_end - p->buffer_start), 0); - p->buffer = p->buffer_end + offset; - break; - case SEEK_SET: - if(p->buffer_end - p->buffer_start < offset) - p->eof = 1; - offset = av_clip(offset, 0, p->buffer_end - p->buffer_start); - p->buffer = p->buffer_start + offset; - break; - default: - return AVERROR(EINVAL); - } - return bytestream2_tell_p(p); -} - -static av_always_inline unsigned int bytestream2_get_buffer(GetByteContext *g, - uint8_t *dst, - unsigned int size) { - int size2 = FFMIN(g->buffer_end - g->buffer, size); - memcpy(dst, g->buffer, size2); - g->buffer += size2; - return size2; -} - -static av_always_inline unsigned int bytestream2_get_bufferu(GetByteContext *g, - uint8_t *dst, - unsigned int size) { - memcpy(dst, g->buffer, size); - g->buffer += size; - return size; -} - -static av_always_inline unsigned int bytestream2_put_buffer(PutByteContext *p, - const uint8_t *src, - unsigned int size) { - int size2; - if(p->eof) - return 0; - size2 = FFMIN(p->buffer_end - p->buffer, size); - if(size2 != size) - p->eof = 1; - memcpy(p->buffer, src, size2); - p->buffer += size2; - return size2; -} - -static av_always_inline unsigned int bytestream2_put_bufferu(PutByteContext *p, - const uint8_t *src, - unsigned int size) { - memcpy(p->buffer, src, size); - p->buffer += size; - return size; -} - -static av_always_inline void bytestream2_set_buffer(PutByteContext *p, - const uint8_t c, - unsigned int size) { - int size2; - if(p->eof) - return; - size2 = FFMIN(p->buffer_end - p->buffer, size); - if(size2 != size) - p->eof = 1; - memset(p->buffer, c, size2); - p->buffer += size2; -} - -static av_always_inline void bytestream2_set_bufferu(PutByteContext *p, - const uint8_t c, - unsigned int size) { - memset(p->buffer, c, size); - p->buffer += size; -} - -static av_always_inline unsigned int bytestream2_get_eof(PutByteContext *p) { - return p->eof; -} - -static av_always_inline unsigned int bytestream2_copy_bufferu(PutByteContext *p, - GetByteContext *g, - unsigned int size) { - memcpy(p->buffer, g->buffer, size); - p->buffer += size; - g->buffer += size; - return size; -} - -static av_always_inline unsigned int bytestream2_copy_buffer(PutByteContext *p, - GetByteContext *g, - unsigned int size) { - int size2; - - if(p->eof) - return 0; - size = FFMIN(g->buffer_end - g->buffer, size); - size2 = FFMIN(p->buffer_end - p->buffer, size); - if(size2 != size) - p->eof = 1; - - return bytestream2_copy_bufferu(p, g, size2); -} - -static av_always_inline unsigned int bytestream_get_buffer(const uint8_t **b, - uint8_t *dst, - unsigned int size) { - memcpy(dst, *b, size); - (*b) += size; - return size; -} - -static av_always_inline void bytestream_put_buffer(uint8_t **b, - const uint8_t *src, - unsigned int size) { - memcpy(*b, src, size); - (*b) += size; -} - -#endif /* AVCODEC_BYTESTREAM_H */ diff --git a/third-party/cbs/cbs.c b/third-party/cbs/cbs.c deleted file mode 100644 index 456cac20b03..00000000000 --- a/third-party/cbs/cbs.c +++ /dev/null @@ -1,1050 +0,0 @@ -/* - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include - -#include -#include -#include -#include - -#include - -#include "cbs/cbs.h" -#include "cbs_internal.h" - -#include "get_bits.h" - - -static const CodedBitstreamType *const cbs_type_table[] = { -#if CONFIG_CBS_AV1 - &ff_cbs_type_av1, -#endif -#if CONFIG_CBS_H264 - &ff_cbs_type_h264, -#endif -#if CONFIG_CBS_H265 - &ff_cbs_type_h265, -#endif -#if CONFIG_CBS_JPEG - &ff_cbs_type_jpeg, -#endif -#if CONFIG_CBS_MPEG2 - &ff_cbs_type_mpeg2, -#endif -#if CONFIG_CBS_VP9 - &ff_cbs_type_vp9, -#endif -}; - -const enum AVCodecID ff_cbs_all_codec_ids[] = { -#if CONFIG_CBS_AV1 - AV_CODEC_ID_AV1, -#endif -#if CONFIG_CBS_H264 - AV_CODEC_ID_H264, -#endif -#if CONFIG_CBS_H265 - AV_CODEC_ID_H265, -#endif -#if CONFIG_CBS_JPEG - AV_CODEC_ID_MJPEG, -#endif -#if CONFIG_CBS_MPEG2 - AV_CODEC_ID_MPEG2VIDEO, -#endif -#if CONFIG_CBS_VP9 - AV_CODEC_ID_VP9, -#endif - AV_CODEC_ID_NONE -}; - -int ff_cbs_init(CodedBitstreamContext **ctx_ptr, - enum AVCodecID codec_id, void *log_ctx) { - CodedBitstreamContext *ctx; - const CodedBitstreamType *type; - int i; - - type = NULL; - for(i = 0; i < FF_ARRAY_ELEMS(cbs_type_table); i++) { - if(cbs_type_table[i]->codec_id == codec_id) { - type = cbs_type_table[i]; - break; - } - } - if(!type) - return AVERROR(EINVAL); - - ctx = av_mallocz(sizeof(*ctx)); - if(!ctx) - return AVERROR(ENOMEM); - - ctx->log_ctx = log_ctx; - ctx->codec = type; /* Must be before any error */ - - if(type->priv_data_size) { - ctx->priv_data = av_mallocz(ctx->codec->priv_data_size); - if(!ctx->priv_data) { - av_freep(&ctx); - return AVERROR(ENOMEM); - } - if(type->priv_class) { - *(const AVClass **)ctx->priv_data = type->priv_class; - av_opt_set_defaults(ctx->priv_data); - } - } - - ctx->decompose_unit_types = NULL; - - ctx->trace_enable = 0; - ctx->trace_level = AV_LOG_TRACE; - - *ctx_ptr = ctx; - return 0; -} - -void ff_cbs_flush(CodedBitstreamContext *ctx) { - if(ctx->codec->flush) - ctx->codec->flush(ctx); -} - -void ff_cbs_close(CodedBitstreamContext **ctx_ptr) { - CodedBitstreamContext *ctx = *ctx_ptr; - - if(!ctx) - return; - - if(ctx->codec->close) - ctx->codec->close(ctx); - - av_freep(&ctx->write_buffer); - - if(ctx->codec->priv_class && ctx->priv_data) - av_opt_free(ctx->priv_data); - - av_freep(&ctx->priv_data); - av_freep(ctx_ptr); -} - -static void cbs_unit_uninit(CodedBitstreamUnit *unit) { - av_buffer_unref(&unit->content_ref); - unit->content = NULL; - - av_buffer_unref(&unit->data_ref); - unit->data = NULL; - unit->data_size = 0; - unit->data_bit_padding = 0; -} - -void ff_cbs_fragment_reset(CodedBitstreamFragment *frag) { - int i; - - for(i = 0; i < frag->nb_units; i++) - cbs_unit_uninit(&frag->units[i]); - frag->nb_units = 0; - - av_buffer_unref(&frag->data_ref); - frag->data = NULL; - frag->data_size = 0; - frag->data_bit_padding = 0; -} - -void ff_cbs_fragment_free(CodedBitstreamFragment *frag) { - ff_cbs_fragment_reset(frag); - - av_freep(&frag->units); - frag->nb_units_allocated = 0; -} - -static int cbs_read_fragment_content(CodedBitstreamContext *ctx, - CodedBitstreamFragment *frag) { - int err, i, j; - - for(i = 0; i < frag->nb_units; i++) { - CodedBitstreamUnit *unit = &frag->units[i]; - - if(ctx->decompose_unit_types) { - for(j = 0; j < ctx->nb_decompose_unit_types; j++) { - if(ctx->decompose_unit_types[j] == unit->type) - break; - } - if(j >= ctx->nb_decompose_unit_types) - continue; - } - - av_buffer_unref(&unit->content_ref); - unit->content = NULL; - - av_assert0(unit->data && unit->data_ref); - - err = ctx->codec->read_unit(ctx, unit); - if(err == AVERROR(ENOSYS)) { - av_log(ctx->log_ctx, AV_LOG_VERBOSE, - "Decomposition unimplemented for unit %d " - "(type %" PRIu32 ").\n", - i, unit->type); - } - else if(err == AVERROR(EAGAIN)) { - av_log(ctx->log_ctx, AV_LOG_VERBOSE, - "Skipping decomposition of unit %d " - "(type %" PRIu32 ").\n", - i, unit->type); - av_buffer_unref(&unit->content_ref); - unit->content = NULL; - } - else if(err < 0) { - av_log(ctx->log_ctx, AV_LOG_ERROR, "Failed to read unit %d " - "(type %" PRIu32 ").\n", - i, unit->type); - return err; - } - } - - return 0; -} - -static int cbs_fill_fragment_data(CodedBitstreamFragment *frag, - const uint8_t *data, size_t size) { - av_assert0(!frag->data && !frag->data_ref); - - frag->data_ref = - av_buffer_alloc(size + AV_INPUT_BUFFER_PADDING_SIZE); - if(!frag->data_ref) - return AVERROR(ENOMEM); - - frag->data = frag->data_ref->data; - frag->data_size = size; - - memcpy(frag->data, data, size); - memset(frag->data + size, 0, - AV_INPUT_BUFFER_PADDING_SIZE); - - return 0; -} - -static int cbs_read_data(CodedBitstreamContext *ctx, - CodedBitstreamFragment *frag, - AVBufferRef *buf, - const uint8_t *data, size_t size, - int header) { - int err; - - if(buf) { - frag->data_ref = av_buffer_ref(buf); - if(!frag->data_ref) - return AVERROR(ENOMEM); - - frag->data = (uint8_t *)data; - frag->data_size = size; - } - else { - err = cbs_fill_fragment_data(frag, data, size); - if(err < 0) - return err; - } - - err = ctx->codec->split_fragment(ctx, frag, header); - if(err < 0) - return err; - - return cbs_read_fragment_content(ctx, frag); -} - -int ff_cbs_read_extradata(CodedBitstreamContext *ctx, - CodedBitstreamFragment *frag, - const AVCodecParameters *par) { - return cbs_read_data(ctx, frag, NULL, - par->extradata, - par->extradata_size, 1); -} - -int ff_cbs_read_extradata_from_codec(CodedBitstreamContext *ctx, - CodedBitstreamFragment *frag, - const AVCodecContext *avctx) { - return cbs_read_data(ctx, frag, NULL, - avctx->extradata, - avctx->extradata_size, 1); -} - -int ff_cbs_read_packet(CodedBitstreamContext *ctx, - CodedBitstreamFragment *frag, - const AVPacket *pkt) { - return cbs_read_data(ctx, frag, pkt->buf, - pkt->data, pkt->size, 0); -} - -int ff_cbs_read(CodedBitstreamContext *ctx, - CodedBitstreamFragment *frag, - const uint8_t *data, size_t size) { - return cbs_read_data(ctx, frag, NULL, - data, size, 0); -} - -static int cbs_write_unit_data(CodedBitstreamContext *ctx, - CodedBitstreamUnit *unit) { - PutBitContext pbc; - int ret; - - if(!ctx->write_buffer) { - // Initial write buffer size is 1MB. - ctx->write_buffer_size = 1024 * 1024; - - reallocate_and_try_again: - ret = av_reallocp(&ctx->write_buffer, ctx->write_buffer_size); - if(ret < 0) { - av_log(ctx->log_ctx, AV_LOG_ERROR, "Unable to allocate a " - "sufficiently large write buffer (last attempt " - "%zu bytes).\n", - ctx->write_buffer_size); - return ret; - } - } - - init_put_bits(&pbc, ctx->write_buffer, ctx->write_buffer_size); - - ret = ctx->codec->write_unit(ctx, unit, &pbc); - if(ret < 0) { - if(ret == AVERROR(ENOSPC)) { - // Overflow. - if(ctx->write_buffer_size == INT_MAX / 8) - return AVERROR(ENOMEM); - ctx->write_buffer_size = FFMIN(2 * ctx->write_buffer_size, INT_MAX / 8); - goto reallocate_and_try_again; - } - // Write failed for some other reason. - return ret; - } - - // Overflow but we didn't notice. - av_assert0(put_bits_count(&pbc) <= 8 * ctx->write_buffer_size); - - if(put_bits_count(&pbc) % 8) - unit->data_bit_padding = 8 - put_bits_count(&pbc) % 8; - else - unit->data_bit_padding = 0; - - flush_put_bits(&pbc); - - ret = ff_cbs_alloc_unit_data(unit, put_bytes_output(&pbc)); - if(ret < 0) - return ret; - - memcpy(unit->data, ctx->write_buffer, unit->data_size); - - return 0; -} - -int ff_cbs_write_fragment_data(CodedBitstreamContext *ctx, - CodedBitstreamFragment *frag) { - int err, i; - - for(i = 0; i < frag->nb_units; i++) { - CodedBitstreamUnit *unit = &frag->units[i]; - - if(!unit->content) - continue; - - av_buffer_unref(&unit->data_ref); - unit->data = NULL; - - err = cbs_write_unit_data(ctx, unit); - if(err < 0) { - av_log(ctx->log_ctx, AV_LOG_ERROR, "Failed to write unit %d " - "(type %" PRIu32 ").\n", - i, unit->type); - return err; - } - av_assert0(unit->data && unit->data_ref); - } - - av_buffer_unref(&frag->data_ref); - frag->data = NULL; - - err = ctx->codec->assemble_fragment(ctx, frag); - if(err < 0) { - av_log(ctx->log_ctx, AV_LOG_ERROR, "Failed to assemble fragment.\n"); - return err; - } - av_assert0(frag->data && frag->data_ref); - - return 0; -} - -int ff_cbs_write_extradata(CodedBitstreamContext *ctx, - AVCodecParameters *par, - CodedBitstreamFragment *frag) { - int err; - - err = ff_cbs_write_fragment_data(ctx, frag); - if(err < 0) - return err; - - av_freep(&par->extradata); - - par->extradata = av_malloc(frag->data_size + - AV_INPUT_BUFFER_PADDING_SIZE); - if(!par->extradata) - return AVERROR(ENOMEM); - - memcpy(par->extradata, frag->data, frag->data_size); - memset(par->extradata + frag->data_size, 0, - AV_INPUT_BUFFER_PADDING_SIZE); - par->extradata_size = frag->data_size; - - return 0; -} - -int ff_cbs_write_packet(CodedBitstreamContext *ctx, - AVPacket *pkt, - CodedBitstreamFragment *frag) { - AVBufferRef *buf; - int err; - - err = ff_cbs_write_fragment_data(ctx, frag); - if(err < 0) - return err; - - buf = av_buffer_ref(frag->data_ref); - if(!buf) - return AVERROR(ENOMEM); - - av_buffer_unref(&pkt->buf); - - pkt->buf = buf; - pkt->data = frag->data; - pkt->size = frag->data_size; - - return 0; -} - - -void ff_cbs_trace_header(CodedBitstreamContext *ctx, - const char *name) { - if(!ctx->trace_enable) - return; - - av_log(ctx->log_ctx, ctx->trace_level, "%s\n", name); -} - -void ff_cbs_trace_syntax_element(CodedBitstreamContext *ctx, int position, - const char *str, const int *subscripts, - const char *bits, int64_t value) { - char name[256]; - size_t name_len, bits_len; - int pad, subs, i, j, k, n; - - if(!ctx->trace_enable) - return; - - av_assert0(value >= INT_MIN && value <= UINT32_MAX); - - subs = subscripts ? subscripts[0] : 0; - n = 0; - for(i = j = 0; str[i];) { - if(str[i] == '[') { - if(n < subs) { - ++n; - k = snprintf(name + j, sizeof(name) - j, "[%d", subscripts[n]); - av_assert0(k > 0 && j + k < sizeof(name)); - j += k; - for(++i; str[i] && str[i] != ']'; i++) - ; - av_assert0(str[i] == ']'); - } - else { - while(str[i] && str[i] != ']') - name[j++] = str[i++]; - av_assert0(str[i] == ']'); - } - } - else { - av_assert0(j + 1 < sizeof(name)); - name[j++] = str[i++]; - } - } - av_assert0(j + 1 < sizeof(name)); - name[j] = 0; - av_assert0(n == subs); - - name_len = strlen(name); - bits_len = strlen(bits); - - if(name_len + bits_len > 60) - pad = bits_len + 2; - else - pad = 61 - name_len; - - av_log(ctx->log_ctx, ctx->trace_level, "%-10d %s%*s = %" PRId64 "\n", - position, name, pad, bits, value); -} - -int ff_cbs_read_unsigned(CodedBitstreamContext *ctx, GetBitContext *gbc, - int width, const char *name, - const int *subscripts, uint32_t *write_to, - uint32_t range_min, uint32_t range_max) { - uint32_t value; - int position; - - av_assert0(width > 0 && width <= 32); - - if(get_bits_left(gbc) < width) { - av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid value at " - "%s: bitstream ended.\n", - name); - return AVERROR_INVALIDDATA; - } - - if(ctx->trace_enable) - position = get_bits_count(gbc); - - value = get_bits_long(gbc, width); - - if(ctx->trace_enable) { - char bits[33]; - int i; - for(i = 0; i < width; i++) - bits[i] = value >> (width - i - 1) & 1 ? '1' : '0'; - bits[i] = 0; - - ff_cbs_trace_syntax_element(ctx, position, name, subscripts, - bits, value); - } - - if(value < range_min || value > range_max) { - av_log(ctx->log_ctx, AV_LOG_ERROR, "%s out of range: " - "%" PRIu32 ", but must be in [%" PRIu32 ",%" PRIu32 "].\n", - name, value, range_min, range_max); - return AVERROR_INVALIDDATA; - } - - *write_to = value; - return 0; -} - -int ff_cbs_write_unsigned(CodedBitstreamContext *ctx, PutBitContext *pbc, - int width, const char *name, - const int *subscripts, uint32_t value, - uint32_t range_min, uint32_t range_max) { - av_assert0(width > 0 && width <= 32); - - if(value < range_min || value > range_max) { - av_log(ctx->log_ctx, AV_LOG_ERROR, "%s out of range: " - "%" PRIu32 ", but must be in [%" PRIu32 ",%" PRIu32 "].\n", - name, value, range_min, range_max); - return AVERROR_INVALIDDATA; - } - - if(put_bits_left(pbc) < width) - return AVERROR(ENOSPC); - - if(ctx->trace_enable) { - char bits[33]; - int i; - for(i = 0; i < width; i++) - bits[i] = value >> (width - i - 1) & 1 ? '1' : '0'; - bits[i] = 0; - - ff_cbs_trace_syntax_element(ctx, put_bits_count(pbc), - name, subscripts, bits, value); - } - - if(width < 32) - put_bits(pbc, width, value); - else - put_bits32(pbc, value); - - return 0; -} - -int ff_cbs_read_signed(CodedBitstreamContext *ctx, GetBitContext *gbc, - int width, const char *name, - const int *subscripts, int32_t *write_to, - int32_t range_min, int32_t range_max) { - int32_t value; - int position; - - av_assert0(width > 0 && width <= 32); - - if(get_bits_left(gbc) < width) { - av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid value at " - "%s: bitstream ended.\n", - name); - return AVERROR_INVALIDDATA; - } - - if(ctx->trace_enable) - position = get_bits_count(gbc); - - value = get_sbits_long(gbc, width); - - if(ctx->trace_enable) { - char bits[33]; - int i; - for(i = 0; i < width; i++) - bits[i] = value & (1U << (width - i - 1)) ? '1' : '0'; - bits[i] = 0; - - ff_cbs_trace_syntax_element(ctx, position, name, subscripts, - bits, value); - } - - if(value < range_min || value > range_max) { - av_log(ctx->log_ctx, AV_LOG_ERROR, "%s out of range: " - "%" PRId32 ", but must be in [%" PRId32 ",%" PRId32 "].\n", - name, value, range_min, range_max); - return AVERROR_INVALIDDATA; - } - - *write_to = value; - return 0; -} - -int ff_cbs_write_signed(CodedBitstreamContext *ctx, PutBitContext *pbc, - int width, const char *name, - const int *subscripts, int32_t value, - int32_t range_min, int32_t range_max) { - av_assert0(width > 0 && width <= 32); - - if(value < range_min || value > range_max) { - av_log(ctx->log_ctx, AV_LOG_ERROR, "%s out of range: " - "%" PRId32 ", but must be in [%" PRId32 ",%" PRId32 "].\n", - name, value, range_min, range_max); - return AVERROR_INVALIDDATA; - } - - if(put_bits_left(pbc) < width) - return AVERROR(ENOSPC); - - if(ctx->trace_enable) { - char bits[33]; - int i; - for(i = 0; i < width; i++) - bits[i] = value & (1U << (width - i - 1)) ? '1' : '0'; - bits[i] = 0; - - ff_cbs_trace_syntax_element(ctx, put_bits_count(pbc), - name, subscripts, bits, value); - } - - if(width < 32) - put_sbits(pbc, width, value); - else - put_bits32(pbc, value); - - return 0; -} - - -int ff_cbs_alloc_unit_content(CodedBitstreamUnit *unit, - size_t size, - void (*free)(void *opaque, uint8_t *data)) { - av_assert0(!unit->content && !unit->content_ref); - - unit->content = av_mallocz(size); - if(!unit->content) - return AVERROR(ENOMEM); - - unit->content_ref = av_buffer_create(unit->content, size, - free, NULL, 0); - if(!unit->content_ref) { - av_freep(&unit->content); - return AVERROR(ENOMEM); - } - - return 0; -} - -int ff_cbs_alloc_unit_data(CodedBitstreamUnit *unit, - size_t size) { - av_assert0(!unit->data && !unit->data_ref); - - unit->data_ref = av_buffer_alloc(size + AV_INPUT_BUFFER_PADDING_SIZE); - if(!unit->data_ref) - return AVERROR(ENOMEM); - - unit->data = unit->data_ref->data; - unit->data_size = size; - - memset(unit->data + size, 0, AV_INPUT_BUFFER_PADDING_SIZE); - - return 0; -} - -static int cbs_insert_unit(CodedBitstreamFragment *frag, - int position) { - CodedBitstreamUnit *units; - - if(frag->nb_units < frag->nb_units_allocated) { - units = frag->units; - - if(position < frag->nb_units) - memmove(units + position + 1, units + position, - (frag->nb_units - position) * sizeof(*units)); - } - else { - units = av_malloc_array(frag->nb_units * 2 + 1, sizeof(*units)); - if(!units) - return AVERROR(ENOMEM); - - frag->nb_units_allocated = 2 * frag->nb_units_allocated + 1; - - if(position > 0) - memcpy(units, frag->units, position * sizeof(*units)); - - if(position < frag->nb_units) - memcpy(units + position + 1, frag->units + position, - (frag->nb_units - position) * sizeof(*units)); - } - - memset(units + position, 0, sizeof(*units)); - - if(units != frag->units) { - av_free(frag->units); - frag->units = units; - } - - ++frag->nb_units; - - return 0; -} - -int ff_cbs_insert_unit_content(CodedBitstreamFragment *frag, - int position, - CodedBitstreamUnitType type, - void *content, - AVBufferRef *content_buf) { - CodedBitstreamUnit *unit; - AVBufferRef *content_ref; - int err; - - if(position == -1) - position = frag->nb_units; - av_assert0(position >= 0 && position <= frag->nb_units); - - if(content_buf) { - content_ref = av_buffer_ref(content_buf); - if(!content_ref) - return AVERROR(ENOMEM); - } - else { - content_ref = NULL; - } - - err = cbs_insert_unit(frag, position); - if(err < 0) { - av_buffer_unref(&content_ref); - return err; - } - - unit = &frag->units[position]; - unit->type = type; - unit->content = content; - unit->content_ref = content_ref; - - return 0; -} - -int ff_cbs_insert_unit_data(CodedBitstreamFragment *frag, - int position, - CodedBitstreamUnitType type, - uint8_t *data, size_t data_size, - AVBufferRef *data_buf) { - CodedBitstreamUnit *unit; - AVBufferRef *data_ref; - int err; - - if(position == -1) - position = frag->nb_units; - av_assert0(position >= 0 && position <= frag->nb_units); - - if(data_buf) - data_ref = av_buffer_ref(data_buf); - else - data_ref = av_buffer_create(data, data_size, NULL, NULL, 0); - if(!data_ref) { - if(!data_buf) - av_free(data); - return AVERROR(ENOMEM); - } - - err = cbs_insert_unit(frag, position); - if(err < 0) { - av_buffer_unref(&data_ref); - return err; - } - - unit = &frag->units[position]; - unit->type = type; - unit->data = data; - unit->data_size = data_size; - unit->data_ref = data_ref; - - return 0; -} - -void ff_cbs_delete_unit(CodedBitstreamFragment *frag, - int position) { - av_assert0(0 <= position && position < frag->nb_units && "Unit to be deleted not in fragment."); - - cbs_unit_uninit(&frag->units[position]); - - --frag->nb_units; - - if(frag->nb_units > 0) - memmove(frag->units + position, - frag->units + position + 1, - (frag->nb_units - position) * sizeof(*frag->units)); -} - -static void cbs_default_free_unit_content(void *opaque, uint8_t *data) { - const CodedBitstreamUnitTypeDescriptor *desc = opaque; - if(desc->content_type == CBS_CONTENT_TYPE_INTERNAL_REFS) { - int i; - for(i = 0; i < desc->nb_ref_offsets; i++) { - void **ptr = (void **)(data + desc->ref_offsets[i]); - av_buffer_unref((AVBufferRef **)(ptr + 1)); - } - } - av_free(data); -} - -static const CodedBitstreamUnitTypeDescriptor - * - cbs_find_unit_type_desc(CodedBitstreamContext *ctx, - CodedBitstreamUnit *unit) { - const CodedBitstreamUnitTypeDescriptor *desc; - int i, j; - - if(!ctx->codec->unit_types) - return NULL; - - for(i = 0;; i++) { - desc = &ctx->codec->unit_types[i]; - if(desc->nb_unit_types == 0) - break; - if(desc->nb_unit_types == CBS_UNIT_TYPE_RANGE) { - if(unit->type >= desc->unit_type_range_start && - unit->type <= desc->unit_type_range_end) - return desc; - } - else { - for(j = 0; j < desc->nb_unit_types; j++) { - if(desc->unit_types[j] == unit->type) - return desc; - } - } - } - return NULL; -} - -int ff_cbs_alloc_unit_content2(CodedBitstreamContext *ctx, - CodedBitstreamUnit *unit) { - const CodedBitstreamUnitTypeDescriptor *desc; - - av_assert0(!unit->content && !unit->content_ref); - - desc = cbs_find_unit_type_desc(ctx, unit); - if(!desc) - return AVERROR(ENOSYS); - - unit->content = av_mallocz(desc->content_size); - if(!unit->content) - return AVERROR(ENOMEM); - - unit->content_ref = - av_buffer_create(unit->content, desc->content_size, - desc->content_free ? desc->content_free : cbs_default_free_unit_content, - (void *)desc, 0); - if(!unit->content_ref) { - av_freep(&unit->content); - return AVERROR(ENOMEM); - } - - return 0; -} - -static int cbs_clone_unit_content(AVBufferRef **clone_ref, - CodedBitstreamUnit *unit, - const CodedBitstreamUnitTypeDescriptor *desc) { - uint8_t *src, *copy; - uint8_t **src_ptr, **copy_ptr; - AVBufferRef **src_buf, **copy_buf; - int err, i; - - av_assert0(unit->content); - src = unit->content; - - copy = av_memdup(src, desc->content_size); - if(!copy) - return AVERROR(ENOMEM); - - for(i = 0; i < desc->nb_ref_offsets; i++) { - src_ptr = (uint8_t **)(src + desc->ref_offsets[i]); - src_buf = (AVBufferRef **)(src_ptr + 1); - copy_ptr = (uint8_t **)(copy + desc->ref_offsets[i]); - copy_buf = (AVBufferRef **)(copy_ptr + 1); - - if(!*src_ptr) { - av_assert0(!*src_buf); - continue; - } - if(!*src_buf) { - // We can't handle a non-refcounted pointer here - we don't - // have enough information to handle whatever structure lies - // at the other end of it. - err = AVERROR(EINVAL); - goto fail; - } - - // src_ptr is required to point somewhere inside src_buf. If it - // doesn't, there is a bug somewhere. - av_assert0(*src_ptr >= (*src_buf)->data && - *src_ptr < (*src_buf)->data + (*src_buf)->size); - - *copy_buf = av_buffer_ref(*src_buf); - if(!*copy_buf) { - err = AVERROR(ENOMEM); - goto fail; - } - *copy_ptr = (*copy_buf)->data + (*src_ptr - (*src_buf)->data); - } - - *clone_ref = av_buffer_create(copy, desc->content_size, - desc->content_free ? desc->content_free : - cbs_default_free_unit_content, - (void *)desc, 0); - if(!*clone_ref) { - err = AVERROR(ENOMEM); - goto fail; - } - - return 0; - -fail: - for(--i; i >= 0; i--) - av_buffer_unref((AVBufferRef **)(copy + desc->ref_offsets[i])); - av_freep(©); - *clone_ref = NULL; - return err; -} - -int ff_cbs_make_unit_refcounted(CodedBitstreamContext *ctx, - CodedBitstreamUnit *unit) { - const CodedBitstreamUnitTypeDescriptor *desc; - AVBufferRef *ref; - int err; - - av_assert0(unit->content); - if(unit->content_ref) { - // Already refcounted, nothing to do. - return 0; - } - - desc = cbs_find_unit_type_desc(ctx, unit); - if(!desc) - return AVERROR(ENOSYS); - - switch(desc->content_type) { - case CBS_CONTENT_TYPE_POD: - ref = av_buffer_alloc(desc->content_size); - if(!ref) - return AVERROR(ENOMEM); - memcpy(ref->data, unit->content, desc->content_size); - err = 0; - break; - - case CBS_CONTENT_TYPE_INTERNAL_REFS: - err = cbs_clone_unit_content(&ref, unit, desc); - break; - - case CBS_CONTENT_TYPE_COMPLEX: - if(!desc->content_clone) - return AVERROR_PATCHWELCOME; - err = desc->content_clone(&ref, unit); - break; - - default: - av_assert0(0 && "Invalid content type."); - } - - if(err < 0) - return err; - - unit->content_ref = ref; - unit->content = ref->data; - return 0; -} - -int ff_cbs_make_unit_writable(CodedBitstreamContext *ctx, - CodedBitstreamUnit *unit) { - const CodedBitstreamUnitTypeDescriptor *desc; - AVBufferRef *ref; - int err; - - // This can only be applied to refcounted units. - err = ff_cbs_make_unit_refcounted(ctx, unit); - if(err < 0) - return err; - av_assert0(unit->content && unit->content_ref); - - if(av_buffer_is_writable(unit->content_ref)) - return 0; - - desc = cbs_find_unit_type_desc(ctx, unit); - if(!desc) - return AVERROR(ENOSYS); - - switch(desc->content_type) { - case CBS_CONTENT_TYPE_POD: - err = av_buffer_make_writable(&unit->content_ref); - break; - - case CBS_CONTENT_TYPE_INTERNAL_REFS: - err = cbs_clone_unit_content(&ref, unit, desc); - break; - - case CBS_CONTENT_TYPE_COMPLEX: - if(!desc->content_clone) - return AVERROR_PATCHWELCOME; - err = desc->content_clone(&ref, unit); - break; - - default: - av_assert0(0 && "Invalid content type."); - } - if(err < 0) - return err; - - if(desc->content_type != CBS_CONTENT_TYPE_POD) { - av_buffer_unref(&unit->content_ref); - unit->content_ref = ref; - } - unit->content = unit->content_ref->data; - return 0; -} - -const uint8_t ff_log2_tab[256] = { - 0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7 -}; \ No newline at end of file diff --git a/third-party/cbs/cbs_av1.c b/third-party/cbs/cbs_av1.c deleted file mode 100644 index 7bb53b9342c..00000000000 --- a/third-party/cbs/cbs_av1.c +++ /dev/null @@ -1,1323 +0,0 @@ -/* - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include -#include - -#include "cbs/cbs.h" -#include "cbs/cbs_av1.h" - -#include "cbs_internal.h" - - -static int cbs_av1_read_uvlc(CodedBitstreamContext *ctx, GetBitContext *gbc, - const char *name, uint32_t *write_to, - uint32_t range_min, uint32_t range_max) { - uint32_t zeroes, bits_value, value; - int position; - - if(ctx->trace_enable) - position = get_bits_count(gbc); - - zeroes = 0; - while(1) { - if(get_bits_left(gbc) < 1) { - av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid uvlc code at " - "%s: bitstream ended.\n", - name); - return AVERROR_INVALIDDATA; - } - - if(get_bits1(gbc)) - break; - ++zeroes; - } - - if(zeroes >= 32) { - value = MAX_UINT_BITS(32); - } - else { - if(get_bits_left(gbc) < zeroes) { - av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid uvlc code at " - "%s: bitstream ended.\n", - name); - return AVERROR_INVALIDDATA; - } - - bits_value = get_bits_long(gbc, zeroes); - value = bits_value + (UINT32_C(1) << zeroes) - 1; - } - - if(ctx->trace_enable) { - char bits[65]; - int i, j, k; - - if(zeroes >= 32) { - while(zeroes > 32) { - k = FFMIN(zeroes - 32, 32); - for(i = 0; i < k; i++) - bits[i] = '0'; - bits[i] = 0; - ff_cbs_trace_syntax_element(ctx, position, name, - NULL, bits, 0); - zeroes -= k; - position += k; - } - } - - for(i = 0; i < zeroes; i++) - bits[i] = '0'; - bits[i++] = '1'; - - if(zeroes < 32) { - for(j = 0; j < zeroes; j++) - bits[i++] = (bits_value >> (zeroes - j - 1) & 1) ? '1' : '0'; - } - - bits[i] = 0; - ff_cbs_trace_syntax_element(ctx, position, name, - NULL, bits, value); - } - - if(value < range_min || value > range_max) { - av_log(ctx->log_ctx, AV_LOG_ERROR, "%s out of range: " - "%" PRIu32 ", but must be in [%" PRIu32 ",%" PRIu32 "].\n", - name, value, range_min, range_max); - return AVERROR_INVALIDDATA; - } - - *write_to = value; - return 0; -} - -static int cbs_av1_write_uvlc(CodedBitstreamContext *ctx, PutBitContext *pbc, - const char *name, uint32_t value, - uint32_t range_min, uint32_t range_max) { - uint32_t v; - int position, zeroes; - - if(value < range_min || value > range_max) { - av_log(ctx->log_ctx, AV_LOG_ERROR, "%s out of range: " - "%" PRIu32 ", but must be in [%" PRIu32 ",%" PRIu32 "].\n", - name, value, range_min, range_max); - return AVERROR_INVALIDDATA; - } - - if(ctx->trace_enable) - position = put_bits_count(pbc); - - zeroes = av_log2(value + 1); - v = value - (1U << zeroes) + 1; - put_bits(pbc, zeroes, 0); - put_bits(pbc, 1, 1); - put_bits(pbc, zeroes, v); - - if(ctx->trace_enable) { - char bits[65]; - int i, j; - i = 0; - for(j = 0; j < zeroes; j++) - bits[i++] = '0'; - bits[i++] = '1'; - for(j = 0; j < zeroes; j++) - bits[i++] = (v >> (zeroes - j - 1) & 1) ? '1' : '0'; - bits[i++] = 0; - ff_cbs_trace_syntax_element(ctx, position, name, NULL, - bits, value); - } - - return 0; -} - -static int cbs_av1_read_leb128(CodedBitstreamContext *ctx, GetBitContext *gbc, - const char *name, uint64_t *write_to) { - uint64_t value; - int position, err, i; - - if(ctx->trace_enable) - position = get_bits_count(gbc); - - value = 0; - for(i = 0; i < 8; i++) { - int subscript[2] = { 1, i }; - uint32_t byte; - err = ff_cbs_read_unsigned(ctx, gbc, 8, "leb128_byte[i]", subscript, - &byte, 0x00, 0xff); - if(err < 0) - return err; - - value |= (uint64_t)(byte & 0x7f) << (i * 7); - if(!(byte & 0x80)) - break; - } - - if(value > UINT32_MAX) - return AVERROR_INVALIDDATA; - - if(ctx->trace_enable) - ff_cbs_trace_syntax_element(ctx, position, name, NULL, "", value); - - *write_to = value; - return 0; -} - -static int cbs_av1_write_leb128(CodedBitstreamContext *ctx, PutBitContext *pbc, - const char *name, uint64_t value) { - int position, err, len, i; - uint8_t byte; - - len = (av_log2(value) + 7) / 7; - - if(ctx->trace_enable) - position = put_bits_count(pbc); - - for(i = 0; i < len; i++) { - int subscript[2] = { 1, i }; - - byte = value >> (7 * i) & 0x7f; - if(i < len - 1) - byte |= 0x80; - - err = ff_cbs_write_unsigned(ctx, pbc, 8, "leb128_byte[i]", subscript, - byte, 0x00, 0xff); - if(err < 0) - return err; - } - - if(ctx->trace_enable) - ff_cbs_trace_syntax_element(ctx, position, name, NULL, "", value); - - return 0; -} - -static int cbs_av1_read_ns(CodedBitstreamContext *ctx, GetBitContext *gbc, - uint32_t n, const char *name, - const int *subscripts, uint32_t *write_to) { - uint32_t m, v, extra_bit, value; - int position, w; - - av_assert0(n > 0); - - if(ctx->trace_enable) - position = get_bits_count(gbc); - - w = av_log2(n) + 1; - m = (1 << w) - n; - - if(get_bits_left(gbc) < w) { - av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid non-symmetric value at " - "%s: bitstream ended.\n", - name); - return AVERROR_INVALIDDATA; - } - - if(w - 1 > 0) - v = get_bits(gbc, w - 1); - else - v = 0; - - if(v < m) { - value = v; - } - else { - extra_bit = get_bits1(gbc); - value = (v << 1) - m + extra_bit; - } - - if(ctx->trace_enable) { - char bits[33]; - int i; - for(i = 0; i < w - 1; i++) - bits[i] = (v >> i & 1) ? '1' : '0'; - if(v >= m) - bits[i++] = extra_bit ? '1' : '0'; - bits[i] = 0; - - ff_cbs_trace_syntax_element(ctx, position, - name, subscripts, bits, value); - } - - *write_to = value; - return 0; -} - -static int cbs_av1_write_ns(CodedBitstreamContext *ctx, PutBitContext *pbc, - uint32_t n, const char *name, - const int *subscripts, uint32_t value) { - uint32_t w, m, v, extra_bit; - int position; - - if(value > n) { - av_log(ctx->log_ctx, AV_LOG_ERROR, "%s out of range: " - "%" PRIu32 ", but must be in [0,%" PRIu32 "].\n", - name, value, n); - return AVERROR_INVALIDDATA; - } - - if(ctx->trace_enable) - position = put_bits_count(pbc); - - w = av_log2(n) + 1; - m = (1 << w) - n; - - if(put_bits_left(pbc) < w) - return AVERROR(ENOSPC); - - if(value < m) { - v = value; - put_bits(pbc, w - 1, v); - } - else { - v = m + ((value - m) >> 1); - extra_bit = (value - m) & 1; - put_bits(pbc, w - 1, v); - put_bits(pbc, 1, extra_bit); - } - - if(ctx->trace_enable) { - char bits[33]; - int i; - for(i = 0; i < w - 1; i++) - bits[i] = (v >> i & 1) ? '1' : '0'; - if(value >= m) - bits[i++] = extra_bit ? '1' : '0'; - bits[i] = 0; - - ff_cbs_trace_syntax_element(ctx, position, - name, subscripts, bits, value); - } - - return 0; -} - -static int cbs_av1_read_increment(CodedBitstreamContext *ctx, GetBitContext *gbc, - uint32_t range_min, uint32_t range_max, - const char *name, uint32_t *write_to) { - uint32_t value; - int position, i; - char bits[33]; - - av_assert0(range_min <= range_max && range_max - range_min < sizeof(bits) - 1); - if(ctx->trace_enable) - position = get_bits_count(gbc); - - for(i = 0, value = range_min; value < range_max;) { - if(get_bits_left(gbc) < 1) { - av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid increment value at " - "%s: bitstream ended.\n", - name); - return AVERROR_INVALIDDATA; - } - if(get_bits1(gbc)) { - bits[i++] = '1'; - ++value; - } - else { - bits[i++] = '0'; - break; - } - } - - if(ctx->trace_enable) { - bits[i] = 0; - ff_cbs_trace_syntax_element(ctx, position, - name, NULL, bits, value); - } - - *write_to = value; - return 0; -} - -static int cbs_av1_write_increment(CodedBitstreamContext *ctx, PutBitContext *pbc, - uint32_t range_min, uint32_t range_max, - const char *name, uint32_t value) { - int len; - - av_assert0(range_min <= range_max && range_max - range_min < 32); - if(value < range_min || value > range_max) { - av_log(ctx->log_ctx, AV_LOG_ERROR, "%s out of range: " - "%" PRIu32 ", but must be in [%" PRIu32 ",%" PRIu32 "].\n", - name, value, range_min, range_max); - return AVERROR_INVALIDDATA; - } - - if(value == range_max) - len = range_max - range_min; - else - len = value - range_min + 1; - if(put_bits_left(pbc) < len) - return AVERROR(ENOSPC); - - if(ctx->trace_enable) { - char bits[33]; - int i; - for(i = 0; i < len; i++) { - if(range_min + i == value) - bits[i] = '0'; - else - bits[i] = '1'; - } - bits[i] = 0; - ff_cbs_trace_syntax_element(ctx, put_bits_count(pbc), - name, NULL, bits, value); - } - - if(len > 0) - put_bits(pbc, len, (1 << len) - 1 - (value != range_max)); - - return 0; -} - -static int cbs_av1_read_subexp(CodedBitstreamContext *ctx, GetBitContext *gbc, - uint32_t range_max, const char *name, - const int *subscripts, uint32_t *write_to) { - uint32_t value; - int position, err; - uint32_t max_len, len, range_offset, range_bits; - - if(ctx->trace_enable) - position = get_bits_count(gbc); - - av_assert0(range_max > 0); - max_len = av_log2(range_max - 1) - 3; - - err = cbs_av1_read_increment(ctx, gbc, 0, max_len, - "subexp_more_bits", &len); - if(err < 0) - return err; - - if(len) { - range_bits = 2 + len; - range_offset = 1 << range_bits; - } - else { - range_bits = 3; - range_offset = 0; - } - - if(len < max_len) { - err = ff_cbs_read_unsigned(ctx, gbc, range_bits, - "subexp_bits", NULL, &value, - 0, MAX_UINT_BITS(range_bits)); - if(err < 0) - return err; - } - else { - err = cbs_av1_read_ns(ctx, gbc, range_max - range_offset, - "subexp_final_bits", NULL, &value); - if(err < 0) - return err; - } - value += range_offset; - - if(ctx->trace_enable) - ff_cbs_trace_syntax_element(ctx, position, - name, subscripts, "", value); - - *write_to = value; - return err; -} - -static int cbs_av1_write_subexp(CodedBitstreamContext *ctx, PutBitContext *pbc, - uint32_t range_max, const char *name, - const int *subscripts, uint32_t value) { - int position, err; - uint32_t max_len, len, range_offset, range_bits; - - if(value > range_max) { - av_log(ctx->log_ctx, AV_LOG_ERROR, "%s out of range: " - "%" PRIu32 ", but must be in [0,%" PRIu32 "].\n", - name, value, range_max); - return AVERROR_INVALIDDATA; - } - - if(ctx->trace_enable) - position = put_bits_count(pbc); - - av_assert0(range_max > 0); - max_len = av_log2(range_max - 1) - 3; - - if(value < 8) { - range_bits = 3; - range_offset = 0; - len = 0; - } - else { - range_bits = av_log2(value); - len = range_bits - 2; - if(len > max_len) { - // The top bin is combined with the one below it. - av_assert0(len == max_len + 1); - --range_bits; - len = max_len; - } - range_offset = 1 << range_bits; - } - - err = cbs_av1_write_increment(ctx, pbc, 0, max_len, - "subexp_more_bits", len); - if(err < 0) - return err; - - if(len < max_len) { - err = ff_cbs_write_unsigned(ctx, pbc, range_bits, - "subexp_bits", NULL, - value - range_offset, - 0, MAX_UINT_BITS(range_bits)); - if(err < 0) - return err; - } - else { - err = cbs_av1_write_ns(ctx, pbc, range_max - range_offset, - "subexp_final_bits", NULL, - value - range_offset); - if(err < 0) - return err; - } - - if(ctx->trace_enable) - ff_cbs_trace_syntax_element(ctx, position, - name, subscripts, "", value); - - return err; -} - - -static int cbs_av1_tile_log2(int blksize, int target) { - int k; - for(k = 0; (blksize << k) < target; k++) - ; - return k; -} - -static int cbs_av1_get_relative_dist(const AV1RawSequenceHeader *seq, - unsigned int a, unsigned int b) { - unsigned int diff, m; - if(!seq->enable_order_hint) - return 0; - diff = a - b; - m = 1 << seq->order_hint_bits_minus_1; - diff = (diff & (m - 1)) - (diff & m); - return diff; -} - -static size_t cbs_av1_get_payload_bytes_left(GetBitContext *gbc) { - GetBitContext tmp = *gbc; - size_t size = 0; - for(int i = 0; get_bits_left(&tmp) >= 8; i++) { - if(get_bits(&tmp, 8)) - size = i; - } - return size; -} - - -#define HEADER(name) \ - do { \ - ff_cbs_trace_header(ctx, name); \ - } while(0) - -#define CHECK(call) \ - do { \ - err = (call); \ - if(err < 0) \ - return err; \ - } while(0) - -#define FUNC_NAME(rw, codec, name) cbs_##codec##_##rw##_##name -#define FUNC_AV1(rw, name) FUNC_NAME(rw, av1, name) -#define FUNC(name) FUNC_AV1(READWRITE, name) - -#define SUBSCRIPTS(subs, ...) (subs > 0 ? ((int[subs + 1]) { subs, __VA_ARGS__ }) : NULL) - -#define fb(width, name) \ - xf(width, name, current->name, 0, MAX_UINT_BITS(width), 0, ) -#define fc(width, name, range_min, range_max) \ - xf(width, name, current->name, range_min, range_max, 0, ) -#define flag(name) fb(1, name) -#define su(width, name) \ - xsu(width, name, current->name, 0, ) - -#define fbs(width, name, subs, ...) \ - xf(width, name, current->name, 0, MAX_UINT_BITS(width), subs, __VA_ARGS__) -#define fcs(width, name, range_min, range_max, subs, ...) \ - xf(width, name, current->name, range_min, range_max, subs, __VA_ARGS__) -#define flags(name, subs, ...) \ - xf(1, name, current->name, 0, 1, subs, __VA_ARGS__) -#define sus(width, name, subs, ...) \ - xsu(width, name, current->name, subs, __VA_ARGS__) - -#define fixed(width, name, value) \ - do { \ - av_unused uint32_t fixed_value = value; \ - xf(width, name, fixed_value, value, value, 0, ); \ - } while(0) - - -#define READ -#define READWRITE read -#define RWContext GetBitContext - -#define xf(width, name, var, range_min, range_max, subs, ...) \ - do { \ - uint32_t value; \ - CHECK(ff_cbs_read_unsigned(ctx, rw, width, #name, \ - SUBSCRIPTS(subs, __VA_ARGS__), \ - &value, range_min, range_max)); \ - var = value; \ - } while(0) - -#define xsu(width, name, var, subs, ...) \ - do { \ - int32_t value; \ - CHECK(ff_cbs_read_signed(ctx, rw, width, #name, \ - SUBSCRIPTS(subs, __VA_ARGS__), &value, \ - MIN_INT_BITS(width), \ - MAX_INT_BITS(width))); \ - var = value; \ - } while(0) - -#define uvlc(name, range_min, range_max) \ - do { \ - uint32_t value; \ - CHECK(cbs_av1_read_uvlc(ctx, rw, #name, \ - &value, range_min, range_max)); \ - current->name = value; \ - } while(0) - -#define ns(max_value, name, subs, ...) \ - do { \ - uint32_t value; \ - CHECK(cbs_av1_read_ns(ctx, rw, max_value, #name, \ - SUBSCRIPTS(subs, __VA_ARGS__), &value)); \ - current->name = value; \ - } while(0) - -#define increment(name, min, max) \ - do { \ - uint32_t value; \ - CHECK(cbs_av1_read_increment(ctx, rw, min, max, #name, &value)); \ - current->name = value; \ - } while(0) - -#define subexp(name, max, subs, ...) \ - do { \ - uint32_t value; \ - CHECK(cbs_av1_read_subexp(ctx, rw, max, #name, \ - SUBSCRIPTS(subs, __VA_ARGS__), &value)); \ - current->name = value; \ - } while(0) - -#define delta_q(name) \ - do { \ - uint8_t delta_coded; \ - int8_t delta_q; \ - xf(1, name.delta_coded, delta_coded, 0, 1, 0, ); \ - if(delta_coded) \ - xsu(1 + 6, name.delta_q, delta_q, 0, ); \ - else \ - delta_q = 0; \ - current->name = delta_q; \ - } while(0) - -#define leb128(name) \ - do { \ - uint64_t value; \ - CHECK(cbs_av1_read_leb128(ctx, rw, #name, &value)); \ - current->name = value; \ - } while(0) - -#define infer(name, value) \ - do { \ - current->name = value; \ - } while(0) - -#define byte_alignment(rw) (get_bits_count(rw) % 8) - -#include "cbs_av1_syntax_template.c" - -#undef READ -#undef READWRITE -#undef RWContext -#undef xf -#undef xsu -#undef uvlc -#undef ns -#undef increment -#undef subexp -#undef delta_q -#undef leb128 -#undef infer -#undef byte_alignment - - -#define WRITE -#define READWRITE write -#define RWContext PutBitContext - -#define xf(width, name, var, range_min, range_max, subs, ...) \ - do { \ - CHECK(ff_cbs_write_unsigned(ctx, rw, width, #name, \ - SUBSCRIPTS(subs, __VA_ARGS__), \ - var, range_min, range_max)); \ - } while(0) - -#define xsu(width, name, var, subs, ...) \ - do { \ - CHECK(ff_cbs_write_signed(ctx, rw, width, #name, \ - SUBSCRIPTS(subs, __VA_ARGS__), var, \ - MIN_INT_BITS(width), \ - MAX_INT_BITS(width))); \ - } while(0) - -#define uvlc(name, range_min, range_max) \ - do { \ - CHECK(cbs_av1_write_uvlc(ctx, rw, #name, current->name, \ - range_min, range_max)); \ - } while(0) - -#define ns(max_value, name, subs, ...) \ - do { \ - CHECK(cbs_av1_write_ns(ctx, rw, max_value, #name, \ - SUBSCRIPTS(subs, __VA_ARGS__), \ - current->name)); \ - } while(0) - -#define increment(name, min, max) \ - do { \ - CHECK(cbs_av1_write_increment(ctx, rw, min, max, #name, \ - current->name)); \ - } while(0) - -#define subexp(name, max, subs, ...) \ - do { \ - CHECK(cbs_av1_write_subexp(ctx, rw, max, #name, \ - SUBSCRIPTS(subs, __VA_ARGS__), \ - current->name)); \ - } while(0) - -#define delta_q(name) \ - do { \ - xf(1, name.delta_coded, current->name != 0, 0, 1, 0, ); \ - if(current->name) \ - xsu(1 + 6, name.delta_q, current->name, 0, ); \ - } while(0) - -#define leb128(name) \ - do { \ - CHECK(cbs_av1_write_leb128(ctx, rw, #name, current->name)); \ - } while(0) - -#define infer(name, value) \ - do { \ - if(current->name != (value)) { \ - av_log(ctx->log_ctx, AV_LOG_ERROR, \ - "%s does not match inferred value: " \ - "%" PRId64 ", but should be %" PRId64 ".\n", \ - #name, (int64_t)current->name, (int64_t)(value)); \ - return AVERROR_INVALIDDATA; \ - } \ - } while(0) - -#define byte_alignment(rw) (put_bits_count(rw) % 8) - -#include "cbs_av1_syntax_template.c" - -#undef WRITE -#undef READWRITE -#undef RWContext -#undef xf -#undef xsu -#undef uvlc -#undef ns -#undef increment -#undef subexp -#undef delta_q -#undef leb128 -#undef infer -#undef byte_alignment - - -static int cbs_av1_split_fragment(CodedBitstreamContext *ctx, - CodedBitstreamFragment *frag, - int header) { - GetBitContext gbc; - uint8_t *data; - size_t size; - uint64_t obu_length; - int pos, err, trace; - - // Don't include this parsing in trace output. - trace = ctx->trace_enable; - ctx->trace_enable = 0; - - data = frag->data; - size = frag->data_size; - - if(INT_MAX / 8 < size) { - av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid fragment: " - "too large (%zu bytes).\n", - size); - err = AVERROR_INVALIDDATA; - goto fail; - } - - if(header && size && data[0] & 0x80) { - // first bit is nonzero, the extradata does not consist purely of - // OBUs. Expect MP4/Matroska AV1CodecConfigurationRecord - int config_record_version = data[0] & 0x7f; - - if(config_record_version != 1) { - av_log(ctx->log_ctx, AV_LOG_ERROR, - "Unknown version %d of AV1CodecConfigurationRecord " - "found!\n", - config_record_version); - err = AVERROR_INVALIDDATA; - goto fail; - } - - if(size <= 4) { - if(size < 4) { - av_log(ctx->log_ctx, AV_LOG_WARNING, - "Undersized AV1CodecConfigurationRecord v%d found!\n", - config_record_version); - err = AVERROR_INVALIDDATA; - goto fail; - } - - goto success; - } - - // In AV1CodecConfigurationRecord v1, actual OBUs start after - // four bytes. Thus set the offset as required for properly - // parsing them. - data += 4; - size -= 4; - } - - while(size > 0) { - AV1RawOBUHeader header; - uint64_t obu_size; - - init_get_bits(&gbc, data, 8 * size); - - err = cbs_av1_read_obu_header(ctx, &gbc, &header); - if(err < 0) - goto fail; - - if(header.obu_has_size_field) { - if(get_bits_left(&gbc) < 8) { - av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid OBU: fragment " - "too short (%zu bytes).\n", - size); - err = AVERROR_INVALIDDATA; - goto fail; - } - err = cbs_av1_read_leb128(ctx, &gbc, "obu_size", &obu_size); - if(err < 0) - goto fail; - } - else - obu_size = size - 1 - header.obu_extension_flag; - - pos = get_bits_count(&gbc); - av_assert0(pos % 8 == 0 && pos / 8 <= size); - - obu_length = pos / 8 + obu_size; - - if(size < obu_length) { - av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid OBU length: " - "%" PRIu64 ", but only %zu bytes remaining in fragment.\n", - obu_length, size); - err = AVERROR_INVALIDDATA; - goto fail; - } - - err = ff_cbs_insert_unit_data(frag, -1, header.obu_type, - data, obu_length, frag->data_ref); - if(err < 0) - goto fail; - - data += obu_length; - size -= obu_length; - } - -success: - err = 0; -fail: - ctx->trace_enable = trace; - return err; -} - -static int cbs_av1_ref_tile_data(CodedBitstreamContext *ctx, - CodedBitstreamUnit *unit, - GetBitContext *gbc, - AV1RawTileData *td) { - int pos; - - pos = get_bits_count(gbc); - if(pos >= 8 * unit->data_size) { - av_log(ctx->log_ctx, AV_LOG_ERROR, "Bitstream ended before " - "any data in tile group (%d bits read).\n", - pos); - return AVERROR_INVALIDDATA; - } - // Must be byte-aligned at this point. - av_assert0(pos % 8 == 0); - - td->data_ref = av_buffer_ref(unit->data_ref); - if(!td->data_ref) - return AVERROR(ENOMEM); - - td->data = unit->data + pos / 8; - td->data_size = unit->data_size - pos / 8; - - return 0; -} - -static int cbs_av1_read_unit(CodedBitstreamContext *ctx, - CodedBitstreamUnit *unit) { - CodedBitstreamAV1Context *priv = ctx->priv_data; - AV1RawOBU *obu; - GetBitContext gbc; - int err, start_pos, end_pos; - - err = ff_cbs_alloc_unit_content2(ctx, unit); - if(err < 0) - return err; - obu = unit->content; - - err = init_get_bits(&gbc, unit->data, 8 * unit->data_size); - if(err < 0) - return err; - - err = cbs_av1_read_obu_header(ctx, &gbc, &obu->header); - if(err < 0) - return err; - av_assert0(obu->header.obu_type == unit->type); - - if(obu->header.obu_has_size_field) { - uint64_t obu_size; - err = cbs_av1_read_leb128(ctx, &gbc, "obu_size", &obu_size); - if(err < 0) - return err; - obu->obu_size = obu_size; - } - else { - if(unit->data_size < 1 + obu->header.obu_extension_flag) { - av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid OBU length: " - "unit too short (%zu).\n", - unit->data_size); - return AVERROR_INVALIDDATA; - } - obu->obu_size = unit->data_size - 1 - obu->header.obu_extension_flag; - } - - start_pos = get_bits_count(&gbc); - - if(obu->header.obu_extension_flag) { - if(obu->header.obu_type != AV1_OBU_SEQUENCE_HEADER && - obu->header.obu_type != AV1_OBU_TEMPORAL_DELIMITER && - priv->operating_point_idc) { - int in_temporal_layer = - (priv->operating_point_idc >> priv->temporal_id) & 1; - int in_spatial_layer = - (priv->operating_point_idc >> (priv->spatial_id + 8)) & 1; - if(!in_temporal_layer || !in_spatial_layer) { - return AVERROR(EAGAIN); // drop_obu() - } - } - } - - switch(obu->header.obu_type) { - case AV1_OBU_SEQUENCE_HEADER: { - err = cbs_av1_read_sequence_header_obu(ctx, &gbc, - &obu->obu.sequence_header); - if(err < 0) - return err; - - if(priv->operating_point >= 0) { - AV1RawSequenceHeader *sequence_header = &obu->obu.sequence_header; - - if(priv->operating_point > sequence_header->operating_points_cnt_minus_1) { - av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid Operating Point %d requested. " - "Must not be higher than %u.\n", - priv->operating_point, sequence_header->operating_points_cnt_minus_1); - return AVERROR(EINVAL); - } - priv->operating_point_idc = sequence_header->operating_point_idc[priv->operating_point]; - } - - av_buffer_unref(&priv->sequence_header_ref); - priv->sequence_header = NULL; - - priv->sequence_header_ref = av_buffer_ref(unit->content_ref); - if(!priv->sequence_header_ref) - return AVERROR(ENOMEM); - priv->sequence_header = &obu->obu.sequence_header; - } break; - case AV1_OBU_TEMPORAL_DELIMITER: { - err = cbs_av1_read_temporal_delimiter_obu(ctx, &gbc); - if(err < 0) - return err; - } break; - case AV1_OBU_FRAME_HEADER: - case AV1_OBU_REDUNDANT_FRAME_HEADER: { - err = cbs_av1_read_frame_header_obu(ctx, &gbc, - &obu->obu.frame_header, - obu->header.obu_type == - AV1_OBU_REDUNDANT_FRAME_HEADER, - unit->data_ref); - if(err < 0) - return err; - } break; - case AV1_OBU_TILE_GROUP: { - err = cbs_av1_read_tile_group_obu(ctx, &gbc, - &obu->obu.tile_group); - if(err < 0) - return err; - - err = cbs_av1_ref_tile_data(ctx, unit, &gbc, - &obu->obu.tile_group.tile_data); - if(err < 0) - return err; - } break; - case AV1_OBU_FRAME: { - err = cbs_av1_read_frame_obu(ctx, &gbc, &obu->obu.frame, - unit->data_ref); - if(err < 0) - return err; - - err = cbs_av1_ref_tile_data(ctx, unit, &gbc, - &obu->obu.frame.tile_group.tile_data); - if(err < 0) - return err; - } break; - case AV1_OBU_TILE_LIST: { - err = cbs_av1_read_tile_list_obu(ctx, &gbc, - &obu->obu.tile_list); - if(err < 0) - return err; - - err = cbs_av1_ref_tile_data(ctx, unit, &gbc, - &obu->obu.tile_list.tile_data); - if(err < 0) - return err; - } break; - case AV1_OBU_METADATA: { - err = cbs_av1_read_metadata_obu(ctx, &gbc, &obu->obu.metadata); - if(err < 0) - return err; - } break; - case AV1_OBU_PADDING: { - err = cbs_av1_read_padding_obu(ctx, &gbc, &obu->obu.padding); - if(err < 0) - return err; - } break; - default: - return AVERROR(ENOSYS); - } - - end_pos = get_bits_count(&gbc); - av_assert0(end_pos <= unit->data_size * 8); - - if(obu->obu_size > 0 && - obu->header.obu_type != AV1_OBU_TILE_GROUP && - obu->header.obu_type != AV1_OBU_TILE_LIST && - obu->header.obu_type != AV1_OBU_FRAME) { - int nb_bits = obu->obu_size * 8 + start_pos - end_pos; - - if(nb_bits <= 0) - return AVERROR_INVALIDDATA; - - err = cbs_av1_read_trailing_bits(ctx, &gbc, nb_bits); - if(err < 0) - return err; - } - - return 0; -} - -static int cbs_av1_write_obu(CodedBitstreamContext *ctx, - CodedBitstreamUnit *unit, - PutBitContext *pbc) { - CodedBitstreamAV1Context *priv = ctx->priv_data; - AV1RawOBU *obu = unit->content; - PutBitContext pbc_tmp; - AV1RawTileData *td; - size_t header_size; - int err, start_pos, end_pos, data_pos; - - // OBUs in the normal bitstream format must contain a size field - // in every OBU (in annex B it is optional, but we don't support - // writing that). - obu->header.obu_has_size_field = 1; - - err = cbs_av1_write_obu_header(ctx, pbc, &obu->header); - if(err < 0) - return err; - - if(obu->header.obu_has_size_field) { - pbc_tmp = *pbc; - // Add space for the size field to fill later. - put_bits32(pbc, 0); - put_bits32(pbc, 0); - } - - td = NULL; - start_pos = put_bits_count(pbc); - - switch(obu->header.obu_type) { - case AV1_OBU_SEQUENCE_HEADER: { - err = cbs_av1_write_sequence_header_obu(ctx, pbc, - &obu->obu.sequence_header); - if(err < 0) - return err; - - av_buffer_unref(&priv->sequence_header_ref); - priv->sequence_header = NULL; - - err = ff_cbs_make_unit_refcounted(ctx, unit); - if(err < 0) - return err; - - priv->sequence_header_ref = av_buffer_ref(unit->content_ref); - if(!priv->sequence_header_ref) - return AVERROR(ENOMEM); - priv->sequence_header = &obu->obu.sequence_header; - } break; - case AV1_OBU_TEMPORAL_DELIMITER: { - err = cbs_av1_write_temporal_delimiter_obu(ctx, pbc); - if(err < 0) - return err; - } break; - case AV1_OBU_FRAME_HEADER: - case AV1_OBU_REDUNDANT_FRAME_HEADER: { - err = cbs_av1_write_frame_header_obu(ctx, pbc, - &obu->obu.frame_header, - obu->header.obu_type == - AV1_OBU_REDUNDANT_FRAME_HEADER, - NULL); - if(err < 0) - return err; - } break; - case AV1_OBU_TILE_GROUP: { - err = cbs_av1_write_tile_group_obu(ctx, pbc, - &obu->obu.tile_group); - if(err < 0) - return err; - - td = &obu->obu.tile_group.tile_data; - } break; - case AV1_OBU_FRAME: { - err = cbs_av1_write_frame_obu(ctx, pbc, &obu->obu.frame, NULL); - if(err < 0) - return err; - - td = &obu->obu.frame.tile_group.tile_data; - } break; - case AV1_OBU_TILE_LIST: { - err = cbs_av1_write_tile_list_obu(ctx, pbc, &obu->obu.tile_list); - if(err < 0) - return err; - - td = &obu->obu.tile_list.tile_data; - } break; - case AV1_OBU_METADATA: { - err = cbs_av1_write_metadata_obu(ctx, pbc, &obu->obu.metadata); - if(err < 0) - return err; - } break; - case AV1_OBU_PADDING: { - err = cbs_av1_write_padding_obu(ctx, pbc, &obu->obu.padding); - if(err < 0) - return err; - } break; - default: - return AVERROR(ENOSYS); - } - - end_pos = put_bits_count(pbc); - header_size = (end_pos - start_pos + 7) / 8; - if(td) { - obu->obu_size = header_size + td->data_size; - } - else if(header_size > 0) { - // Add trailing bits and recalculate. - err = cbs_av1_write_trailing_bits(ctx, pbc, 8 - end_pos % 8); - if(err < 0) - return err; - end_pos = put_bits_count(pbc); - obu->obu_size = header_size = (end_pos - start_pos + 7) / 8; - } - else { - // Empty OBU. - obu->obu_size = 0; - } - - end_pos = put_bits_count(pbc); - // Must now be byte-aligned. - av_assert0(end_pos % 8 == 0); - flush_put_bits(pbc); - start_pos /= 8; - end_pos /= 8; - - *pbc = pbc_tmp; - err = cbs_av1_write_leb128(ctx, pbc, "obu_size", obu->obu_size); - if(err < 0) - return err; - - data_pos = put_bits_count(pbc) / 8; - flush_put_bits(pbc); - av_assert0(data_pos <= start_pos); - - if(8 * obu->obu_size > put_bits_left(pbc)) - return AVERROR(ENOSPC); - - if(obu->obu_size > 0) { - memmove(pbc->buf + data_pos, - pbc->buf + start_pos, header_size); - skip_put_bytes(pbc, header_size); - - if(td) { - memcpy(pbc->buf + data_pos + header_size, - td->data, td->data_size); - skip_put_bytes(pbc, td->data_size); - } - } - - // OBU data must be byte-aligned. - av_assert0(put_bits_count(pbc) % 8 == 0); - - return 0; -} - -static int cbs_av1_assemble_fragment(CodedBitstreamContext *ctx, - CodedBitstreamFragment *frag) { - size_t size, pos; - int i; - - size = 0; - for(i = 0; i < frag->nb_units; i++) - size += frag->units[i].data_size; - - frag->data_ref = av_buffer_alloc(size + AV_INPUT_BUFFER_PADDING_SIZE); - if(!frag->data_ref) - return AVERROR(ENOMEM); - frag->data = frag->data_ref->data; - memset(frag->data + size, 0, AV_INPUT_BUFFER_PADDING_SIZE); - - pos = 0; - for(i = 0; i < frag->nb_units; i++) { - memcpy(frag->data + pos, frag->units[i].data, - frag->units[i].data_size); - pos += frag->units[i].data_size; - } - av_assert0(pos == size); - frag->data_size = size; - - return 0; -} - -static void cbs_av1_flush(CodedBitstreamContext *ctx) { - CodedBitstreamAV1Context *priv = ctx->priv_data; - - av_buffer_unref(&priv->frame_header_ref); - priv->sequence_header = NULL; - priv->frame_header = NULL; - - memset(priv->ref, 0, sizeof(priv->ref)); - priv->operating_point_idc = 0; - priv->seen_frame_header = 0; - priv->tile_num = 0; -} - -static void cbs_av1_close(CodedBitstreamContext *ctx) { - CodedBitstreamAV1Context *priv = ctx->priv_data; - - av_buffer_unref(&priv->sequence_header_ref); - av_buffer_unref(&priv->frame_header_ref); -} - -static void cbs_av1_free_metadata(void *unit, uint8_t *content) { - AV1RawOBU *obu = (AV1RawOBU *)content; - AV1RawMetadata *md; - - av_assert0(obu->header.obu_type == AV1_OBU_METADATA); - md = &obu->obu.metadata; - - switch(md->metadata_type) { - case AV1_METADATA_TYPE_ITUT_T35: - av_buffer_unref(&md->metadata.itut_t35.payload_ref); - break; - } - av_free(content); -} - -static const CodedBitstreamUnitTypeDescriptor cbs_av1_unit_types[] = { - CBS_UNIT_TYPE_POD(AV1_OBU_SEQUENCE_HEADER, AV1RawOBU), - CBS_UNIT_TYPE_POD(AV1_OBU_TEMPORAL_DELIMITER, AV1RawOBU), - CBS_UNIT_TYPE_POD(AV1_OBU_FRAME_HEADER, AV1RawOBU), - CBS_UNIT_TYPE_POD(AV1_OBU_REDUNDANT_FRAME_HEADER, AV1RawOBU), - - CBS_UNIT_TYPE_INTERNAL_REF(AV1_OBU_TILE_GROUP, AV1RawOBU, - obu.tile_group.tile_data.data), - CBS_UNIT_TYPE_INTERNAL_REF(AV1_OBU_FRAME, AV1RawOBU, - obu.frame.tile_group.tile_data.data), - CBS_UNIT_TYPE_INTERNAL_REF(AV1_OBU_TILE_LIST, AV1RawOBU, - obu.tile_list.tile_data.data), - CBS_UNIT_TYPE_INTERNAL_REF(AV1_OBU_PADDING, AV1RawOBU, - obu.padding.payload), - - CBS_UNIT_TYPE_COMPLEX(AV1_OBU_METADATA, AV1RawOBU, - &cbs_av1_free_metadata), - - CBS_UNIT_TYPE_END_OF_LIST -}; - -#define OFFSET(x) offsetof(CodedBitstreamAV1Context, x) -static const AVOption cbs_av1_options[] = { - { "operating_point", "Set operating point to select layers to parse from a scalable bitstream", - OFFSET(operating_point), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, AV1_MAX_OPERATING_POINTS - 1, 0 }, - { NULL } -}; - -static const AVClass cbs_av1_class = { - .class_name = "cbs_av1", - .item_name = av_default_item_name, - .option = cbs_av1_options, - .version = LIBAVUTIL_VERSION_INT, -}; - -const CodedBitstreamType ff_cbs_type_av1 = { - .codec_id = AV_CODEC_ID_AV1, - - .priv_class = &cbs_av1_class, - .priv_data_size = sizeof(CodedBitstreamAV1Context), - - .unit_types = cbs_av1_unit_types, - - .split_fragment = &cbs_av1_split_fragment, - .read_unit = &cbs_av1_read_unit, - .write_unit = &cbs_av1_write_obu, - .assemble_fragment = &cbs_av1_assemble_fragment, - - .flush = &cbs_av1_flush, - .close = &cbs_av1_close, -}; diff --git a/third-party/cbs/cbs_av1_syntax_template.c b/third-party/cbs/cbs_av1_syntax_template.c deleted file mode 100644 index 1768a6d2f6a..00000000000 --- a/third-party/cbs/cbs_av1_syntax_template.c +++ /dev/null @@ -1,2063 +0,0 @@ -/* - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -static int FUNC(obu_header)(CodedBitstreamContext *ctx, RWContext *rw, - AV1RawOBUHeader *current) { - CodedBitstreamAV1Context *priv = ctx->priv_data; - int err; - - HEADER("OBU header"); - - fc(1, obu_forbidden_bit, 0, 0); - - fc(4, obu_type, 0, AV1_OBU_PADDING); - flag(obu_extension_flag); - flag(obu_has_size_field); - - fc(1, obu_reserved_1bit, 0, 0); - - if(current->obu_extension_flag) { - fb(3, temporal_id); - fb(2, spatial_id); - fc(3, extension_header_reserved_3bits, 0, 0); - } - else { - infer(temporal_id, 0); - infer(spatial_id, 0); - } - - priv->temporal_id = current->temporal_id; - priv->spatial_id = current->spatial_id; - - return 0; -} - -static int FUNC(trailing_bits)(CodedBitstreamContext *ctx, RWContext *rw, int nb_bits) { - int err; - - av_assert0(nb_bits > 0); - - fixed(1, trailing_one_bit, 1); - --nb_bits; - - while(nb_bits > 0) { - fixed(1, trailing_zero_bit, 0); - --nb_bits; - } - - return 0; -} - -static int FUNC(byte_alignment)(CodedBitstreamContext *ctx, RWContext *rw) { - int err; - - while(byte_alignment(rw) != 0) - fixed(1, zero_bit, 0); - - return 0; -} - -static int FUNC(color_config)(CodedBitstreamContext *ctx, RWContext *rw, - AV1RawColorConfig *current, int seq_profile) { - CodedBitstreamAV1Context *priv = ctx->priv_data; - int err; - - flag(high_bitdepth); - - if(seq_profile == FF_PROFILE_AV1_PROFESSIONAL && - current->high_bitdepth) { - flag(twelve_bit); - priv->bit_depth = current->twelve_bit ? 12 : 10; - } - else { - priv->bit_depth = current->high_bitdepth ? 10 : 8; - } - - if(seq_profile == FF_PROFILE_AV1_HIGH) - infer(mono_chrome, 0); - else - flag(mono_chrome); - priv->num_planes = current->mono_chrome ? 1 : 3; - - flag(color_description_present_flag); - if(current->color_description_present_flag) { - fb(8, color_primaries); - fb(8, transfer_characteristics); - fb(8, matrix_coefficients); - } - else { - infer(color_primaries, AVCOL_PRI_UNSPECIFIED); - infer(transfer_characteristics, AVCOL_TRC_UNSPECIFIED); - infer(matrix_coefficients, AVCOL_SPC_UNSPECIFIED); - } - - if(current->mono_chrome) { - flag(color_range); - - infer(subsampling_x, 1); - infer(subsampling_y, 1); - infer(chroma_sample_position, AV1_CSP_UNKNOWN); - infer(separate_uv_delta_q, 0); - } - else if(current->color_primaries == AVCOL_PRI_BT709 && - current->transfer_characteristics == AVCOL_TRC_IEC61966_2_1 && - current->matrix_coefficients == AVCOL_SPC_RGB) { - infer(color_range, 1); - infer(subsampling_x, 0); - infer(subsampling_y, 0); - flag(separate_uv_delta_q); - } - else { - flag(color_range); - - if(seq_profile == FF_PROFILE_AV1_MAIN) { - infer(subsampling_x, 1); - infer(subsampling_y, 1); - } - else if(seq_profile == FF_PROFILE_AV1_HIGH) { - infer(subsampling_x, 0); - infer(subsampling_y, 0); - } - else { - if(priv->bit_depth == 12) { - fb(1, subsampling_x); - if(current->subsampling_x) - fb(1, subsampling_y); - else - infer(subsampling_y, 0); - } - else { - infer(subsampling_x, 1); - infer(subsampling_y, 0); - } - } - if(current->subsampling_x && current->subsampling_y) { - fc(2, chroma_sample_position, AV1_CSP_UNKNOWN, - AV1_CSP_COLOCATED); - } - - flag(separate_uv_delta_q); - } - - return 0; -} - -static int FUNC(timing_info)(CodedBitstreamContext *ctx, RWContext *rw, - AV1RawTimingInfo *current) { - int err; - - fc(32, num_units_in_display_tick, 1, MAX_UINT_BITS(32)); - fc(32, time_scale, 1, MAX_UINT_BITS(32)); - - flag(equal_picture_interval); - if(current->equal_picture_interval) - uvlc(num_ticks_per_picture_minus_1, 0, MAX_UINT_BITS(32) - 1); - - return 0; -} - -static int FUNC(decoder_model_info)(CodedBitstreamContext *ctx, RWContext *rw, - AV1RawDecoderModelInfo *current) { - int err; - - fb(5, buffer_delay_length_minus_1); - fb(32, num_units_in_decoding_tick); - fb(5, buffer_removal_time_length_minus_1); - fb(5, frame_presentation_time_length_minus_1); - - return 0; -} - -static int FUNC(sequence_header_obu)(CodedBitstreamContext *ctx, RWContext *rw, - AV1RawSequenceHeader *current) { - int i, err; - - HEADER("Sequence Header"); - - fc(3, seq_profile, FF_PROFILE_AV1_MAIN, - FF_PROFILE_AV1_PROFESSIONAL); - flag(still_picture); - flag(reduced_still_picture_header); - - if(current->reduced_still_picture_header) { - infer(timing_info_present_flag, 0); - infer(decoder_model_info_present_flag, 0); - infer(initial_display_delay_present_flag, 0); - infer(operating_points_cnt_minus_1, 0); - infer(operating_point_idc[0], 0); - - fb(5, seq_level_idx[0]); - - infer(seq_tier[0], 0); - infer(decoder_model_present_for_this_op[0], 0); - infer(initial_display_delay_present_for_this_op[0], 0); - } - else { - flag(timing_info_present_flag); - if(current->timing_info_present_flag) { - CHECK(FUNC(timing_info)(ctx, rw, ¤t->timing_info)); - - flag(decoder_model_info_present_flag); - if(current->decoder_model_info_present_flag) { - CHECK(FUNC(decoder_model_info)(ctx, rw, ¤t->decoder_model_info)); - } - } - else { - infer(decoder_model_info_present_flag, 0); - } - - flag(initial_display_delay_present_flag); - - fb(5, operating_points_cnt_minus_1); - for(i = 0; i <= current->operating_points_cnt_minus_1; i++) { - fbs(12, operating_point_idc[i], 1, i); - fbs(5, seq_level_idx[i], 1, i); - - if(current->seq_level_idx[i] > 7) - flags(seq_tier[i], 1, i); - else - infer(seq_tier[i], 0); - - if(current->decoder_model_info_present_flag) { - flags(decoder_model_present_for_this_op[i], 1, i); - if(current->decoder_model_present_for_this_op[i]) { - int n = current->decoder_model_info.buffer_delay_length_minus_1 + 1; - fbs(n, decoder_buffer_delay[i], 1, i); - fbs(n, encoder_buffer_delay[i], 1, i); - flags(low_delay_mode_flag[i], 1, i); - } - } - else { - infer(decoder_model_present_for_this_op[i], 0); - } - - if(current->initial_display_delay_present_flag) { - flags(initial_display_delay_present_for_this_op[i], 1, i); - if(current->initial_display_delay_present_for_this_op[i]) - fbs(4, initial_display_delay_minus_1[i], 1, i); - } - } - } - - fb(4, frame_width_bits_minus_1); - fb(4, frame_height_bits_minus_1); - - fb(current->frame_width_bits_minus_1 + 1, max_frame_width_minus_1); - fb(current->frame_height_bits_minus_1 + 1, max_frame_height_minus_1); - - if(current->reduced_still_picture_header) - infer(frame_id_numbers_present_flag, 0); - else - flag(frame_id_numbers_present_flag); - if(current->frame_id_numbers_present_flag) { - fb(4, delta_frame_id_length_minus_2); - fb(3, additional_frame_id_length_minus_1); - } - - flag(use_128x128_superblock); - flag(enable_filter_intra); - flag(enable_intra_edge_filter); - - if(current->reduced_still_picture_header) { - infer(enable_interintra_compound, 0); - infer(enable_masked_compound, 0); - infer(enable_warped_motion, 0); - infer(enable_dual_filter, 0); - infer(enable_order_hint, 0); - infer(enable_jnt_comp, 0); - infer(enable_ref_frame_mvs, 0); - - infer(seq_force_screen_content_tools, - AV1_SELECT_SCREEN_CONTENT_TOOLS); - infer(seq_force_integer_mv, - AV1_SELECT_INTEGER_MV); - } - else { - flag(enable_interintra_compound); - flag(enable_masked_compound); - flag(enable_warped_motion); - flag(enable_dual_filter); - - flag(enable_order_hint); - if(current->enable_order_hint) { - flag(enable_jnt_comp); - flag(enable_ref_frame_mvs); - } - else { - infer(enable_jnt_comp, 0); - infer(enable_ref_frame_mvs, 0); - } - - flag(seq_choose_screen_content_tools); - if(current->seq_choose_screen_content_tools) - infer(seq_force_screen_content_tools, - AV1_SELECT_SCREEN_CONTENT_TOOLS); - else - fb(1, seq_force_screen_content_tools); - if(current->seq_force_screen_content_tools > 0) { - flag(seq_choose_integer_mv); - if(current->seq_choose_integer_mv) - infer(seq_force_integer_mv, - AV1_SELECT_INTEGER_MV); - else - fb(1, seq_force_integer_mv); - } - else { - infer(seq_force_integer_mv, AV1_SELECT_INTEGER_MV); - } - - if(current->enable_order_hint) - fb(3, order_hint_bits_minus_1); - } - - flag(enable_superres); - flag(enable_cdef); - flag(enable_restoration); - - CHECK(FUNC(color_config)(ctx, rw, ¤t->color_config, - current->seq_profile)); - - flag(film_grain_params_present); - - return 0; -} - -static int FUNC(temporal_delimiter_obu)(CodedBitstreamContext *ctx, RWContext *rw) { - CodedBitstreamAV1Context *priv = ctx->priv_data; - - HEADER("Temporal Delimiter"); - - priv->seen_frame_header = 0; - - return 0; -} - -static int FUNC(set_frame_refs)(CodedBitstreamContext *ctx, RWContext *rw, - AV1RawFrameHeader *current) { - CodedBitstreamAV1Context *priv = ctx->priv_data; - const AV1RawSequenceHeader *seq = priv->sequence_header; - static const uint8_t ref_frame_list[AV1_NUM_REF_FRAMES - 2] = { - AV1_REF_FRAME_LAST2, AV1_REF_FRAME_LAST3, AV1_REF_FRAME_BWDREF, - AV1_REF_FRAME_ALTREF2, AV1_REF_FRAME_ALTREF - }; - int8_t ref_frame_idx[AV1_REFS_PER_FRAME], used_frame[AV1_NUM_REF_FRAMES]; - int8_t shifted_order_hints[AV1_NUM_REF_FRAMES]; - int cur_frame_hint, latest_order_hint, earliest_order_hint, ref; - int i, j; - - for(i = 0; i < AV1_REFS_PER_FRAME; i++) - ref_frame_idx[i] = -1; - ref_frame_idx[AV1_REF_FRAME_LAST - AV1_REF_FRAME_LAST] = current->last_frame_idx; - ref_frame_idx[AV1_REF_FRAME_GOLDEN - AV1_REF_FRAME_LAST] = current->golden_frame_idx; - - for(i = 0; i < AV1_NUM_REF_FRAMES; i++) - used_frame[i] = 0; - used_frame[current->last_frame_idx] = 1; - used_frame[current->golden_frame_idx] = 1; - - cur_frame_hint = 1 << (seq->order_hint_bits_minus_1); - for(i = 0; i < AV1_NUM_REF_FRAMES; i++) - shifted_order_hints[i] = cur_frame_hint + - cbs_av1_get_relative_dist(seq, priv->ref[i].order_hint, - priv->order_hint); - - latest_order_hint = shifted_order_hints[current->last_frame_idx]; - earliest_order_hint = shifted_order_hints[current->golden_frame_idx]; - - ref = -1; - for(i = 0; i < AV1_NUM_REF_FRAMES; i++) { - int hint = shifted_order_hints[i]; - if(!used_frame[i] && hint >= cur_frame_hint && - (ref < 0 || hint >= latest_order_hint)) { - ref = i; - latest_order_hint = hint; - } - } - if(ref >= 0) { - ref_frame_idx[AV1_REF_FRAME_ALTREF - AV1_REF_FRAME_LAST] = ref; - used_frame[ref] = 1; - } - - ref = -1; - for(i = 0; i < AV1_NUM_REF_FRAMES; i++) { - int hint = shifted_order_hints[i]; - if(!used_frame[i] && hint >= cur_frame_hint && - (ref < 0 || hint < earliest_order_hint)) { - ref = i; - earliest_order_hint = hint; - } - } - if(ref >= 0) { - ref_frame_idx[AV1_REF_FRAME_BWDREF - AV1_REF_FRAME_LAST] = ref; - used_frame[ref] = 1; - } - - ref = -1; - for(i = 0; i < AV1_NUM_REF_FRAMES; i++) { - int hint = shifted_order_hints[i]; - if(!used_frame[i] && hint >= cur_frame_hint && - (ref < 0 || hint < earliest_order_hint)) { - ref = i; - earliest_order_hint = hint; - } - } - if(ref >= 0) { - ref_frame_idx[AV1_REF_FRAME_ALTREF2 - AV1_REF_FRAME_LAST] = ref; - used_frame[ref] = 1; - } - - for(i = 0; i < AV1_REFS_PER_FRAME - 2; i++) { - int ref_frame = ref_frame_list[i]; - if(ref_frame_idx[ref_frame - AV1_REF_FRAME_LAST] < 0) { - ref = -1; - for(j = 0; j < AV1_NUM_REF_FRAMES; j++) { - int hint = shifted_order_hints[j]; - if(!used_frame[j] && hint < cur_frame_hint && - (ref < 0 || hint >= latest_order_hint)) { - ref = j; - latest_order_hint = hint; - } - } - if(ref >= 0) { - ref_frame_idx[ref_frame - AV1_REF_FRAME_LAST] = ref; - used_frame[ref] = 1; - } - } - } - - ref = -1; - for(i = 0; i < AV1_NUM_REF_FRAMES; i++) { - int hint = shifted_order_hints[i]; - if(ref < 0 || hint < earliest_order_hint) { - ref = i; - earliest_order_hint = hint; - } - } - for(i = 0; i < AV1_REFS_PER_FRAME; i++) { - if(ref_frame_idx[i] < 0) - ref_frame_idx[i] = ref; - infer(ref_frame_idx[i], ref_frame_idx[i]); - } - - return 0; -} - -static int FUNC(superres_params)(CodedBitstreamContext *ctx, RWContext *rw, - AV1RawFrameHeader *current) { - CodedBitstreamAV1Context *priv = ctx->priv_data; - const AV1RawSequenceHeader *seq = priv->sequence_header; - int denom, err; - - if(seq->enable_superres) - flag(use_superres); - else - infer(use_superres, 0); - - if(current->use_superres) { - fb(3, coded_denom); - denom = current->coded_denom + AV1_SUPERRES_DENOM_MIN; - } - else { - denom = AV1_SUPERRES_NUM; - } - - priv->upscaled_width = priv->frame_width; - priv->frame_width = (priv->upscaled_width * AV1_SUPERRES_NUM + - denom / 2) / - denom; - - return 0; -} - -static int FUNC(frame_size)(CodedBitstreamContext *ctx, RWContext *rw, - AV1RawFrameHeader *current) { - CodedBitstreamAV1Context *priv = ctx->priv_data; - const AV1RawSequenceHeader *seq = priv->sequence_header; - int err; - - if(current->frame_size_override_flag) { - fb(seq->frame_width_bits_minus_1 + 1, frame_width_minus_1); - fb(seq->frame_height_bits_minus_1 + 1, frame_height_minus_1); - } - else { - infer(frame_width_minus_1, seq->max_frame_width_minus_1); - infer(frame_height_minus_1, seq->max_frame_height_minus_1); - } - - priv->frame_width = current->frame_width_minus_1 + 1; - priv->frame_height = current->frame_height_minus_1 + 1; - - CHECK(FUNC(superres_params)(ctx, rw, current)); - - return 0; -} - -static int FUNC(render_size)(CodedBitstreamContext *ctx, RWContext *rw, - AV1RawFrameHeader *current) { - CodedBitstreamAV1Context *priv = ctx->priv_data; - int err; - - flag(render_and_frame_size_different); - - if(current->render_and_frame_size_different) { - fb(16, render_width_minus_1); - fb(16, render_height_minus_1); - } - else { - infer(render_width_minus_1, current->frame_width_minus_1); - infer(render_height_minus_1, current->frame_height_minus_1); - } - - priv->render_width = current->render_width_minus_1 + 1; - priv->render_height = current->render_height_minus_1 + 1; - - return 0; -} - -static int FUNC(frame_size_with_refs)(CodedBitstreamContext *ctx, RWContext *rw, - AV1RawFrameHeader *current) { - CodedBitstreamAV1Context *priv = ctx->priv_data; - int i, err; - - for(i = 0; i < AV1_REFS_PER_FRAME; i++) { - flags(found_ref[i], 1, i); - if(current->found_ref[i]) { - AV1ReferenceFrameState *ref = - &priv->ref[current->ref_frame_idx[i]]; - - if(!ref->valid) { - av_log(ctx->log_ctx, AV_LOG_ERROR, - "Missing reference frame needed for frame size " - "(ref = %d, ref_frame_idx = %d).\n", - i, current->ref_frame_idx[i]); - return AVERROR_INVALIDDATA; - } - - infer(frame_width_minus_1, ref->upscaled_width - 1); - infer(frame_height_minus_1, ref->frame_height - 1); - infer(render_width_minus_1, ref->render_width - 1); - infer(render_height_minus_1, ref->render_height - 1); - - priv->upscaled_width = ref->upscaled_width; - priv->frame_width = priv->upscaled_width; - priv->frame_height = ref->frame_height; - priv->render_width = ref->render_width; - priv->render_height = ref->render_height; - break; - } - } - - if(i >= AV1_REFS_PER_FRAME) { - CHECK(FUNC(frame_size)(ctx, rw, current)); - CHECK(FUNC(render_size)(ctx, rw, current)); - } - else { - CHECK(FUNC(superres_params)(ctx, rw, current)); - } - - return 0; -} - -static int FUNC(interpolation_filter)(CodedBitstreamContext *ctx, RWContext *rw, - AV1RawFrameHeader *current) { - int err; - - flag(is_filter_switchable); - if(current->is_filter_switchable) - infer(interpolation_filter, - AV1_INTERPOLATION_FILTER_SWITCHABLE); - else - fb(2, interpolation_filter); - - return 0; -} - -static int FUNC(tile_info)(CodedBitstreamContext *ctx, RWContext *rw, - AV1RawFrameHeader *current) { - CodedBitstreamAV1Context *priv = ctx->priv_data; - const AV1RawSequenceHeader *seq = priv->sequence_header; - int mi_cols, mi_rows, sb_cols, sb_rows, sb_shift, sb_size; - int max_tile_width_sb, max_tile_height_sb, max_tile_area_sb; - int min_log2_tile_cols, max_log2_tile_cols, max_log2_tile_rows; - int min_log2_tiles, min_log2_tile_rows; - int i, err; - - mi_cols = 2 * ((priv->frame_width + 7) >> 3); - mi_rows = 2 * ((priv->frame_height + 7) >> 3); - - sb_cols = seq->use_128x128_superblock ? ((mi_cols + 31) >> 5) : ((mi_cols + 15) >> 4); - sb_rows = seq->use_128x128_superblock ? ((mi_rows + 31) >> 5) : ((mi_rows + 15) >> 4); - - sb_shift = seq->use_128x128_superblock ? 5 : 4; - sb_size = sb_shift + 2; - - max_tile_width_sb = AV1_MAX_TILE_WIDTH >> sb_size; - max_tile_area_sb = AV1_MAX_TILE_AREA >> (2 * sb_size); - - min_log2_tile_cols = cbs_av1_tile_log2(max_tile_width_sb, sb_cols); - max_log2_tile_cols = cbs_av1_tile_log2(1, FFMIN(sb_cols, AV1_MAX_TILE_COLS)); - max_log2_tile_rows = cbs_av1_tile_log2(1, FFMIN(sb_rows, AV1_MAX_TILE_ROWS)); - min_log2_tiles = FFMAX(min_log2_tile_cols, - cbs_av1_tile_log2(max_tile_area_sb, sb_rows * sb_cols)); - - flag(uniform_tile_spacing_flag); - - if(current->uniform_tile_spacing_flag) { - int tile_width_sb, tile_height_sb; - - increment(tile_cols_log2, min_log2_tile_cols, max_log2_tile_cols); - - tile_width_sb = (sb_cols + (1 << current->tile_cols_log2) - 1) >> - current->tile_cols_log2; - current->tile_cols = (sb_cols + tile_width_sb - 1) / tile_width_sb; - - min_log2_tile_rows = FFMAX(min_log2_tiles - current->tile_cols_log2, 0); - - increment(tile_rows_log2, min_log2_tile_rows, max_log2_tile_rows); - - tile_height_sb = (sb_rows + (1 << current->tile_rows_log2) - 1) >> - current->tile_rows_log2; - current->tile_rows = (sb_rows + tile_height_sb - 1) / tile_height_sb; - - for(i = 0; i < current->tile_cols - 1; i++) - infer(width_in_sbs_minus_1[i], tile_width_sb - 1); - infer(width_in_sbs_minus_1[i], - sb_cols - (current->tile_cols - 1) * tile_width_sb - 1); - for(i = 0; i < current->tile_rows - 1; i++) - infer(height_in_sbs_minus_1[i], tile_height_sb - 1); - infer(height_in_sbs_minus_1[i], - sb_rows - (current->tile_rows - 1) * tile_height_sb - 1); - } - else { - int widest_tile_sb, start_sb, size_sb, max_width, max_height; - - widest_tile_sb = 0; - - start_sb = 0; - for(i = 0; start_sb < sb_cols && i < AV1_MAX_TILE_COLS; i++) { - max_width = FFMIN(sb_cols - start_sb, max_tile_width_sb); - ns(max_width, width_in_sbs_minus_1[i], 1, i); - size_sb = current->width_in_sbs_minus_1[i] + 1; - widest_tile_sb = FFMAX(size_sb, widest_tile_sb); - start_sb += size_sb; - } - current->tile_cols_log2 = cbs_av1_tile_log2(1, i); - current->tile_cols = i; - - if(min_log2_tiles > 0) - max_tile_area_sb = (sb_rows * sb_cols) >> (min_log2_tiles + 1); - else - max_tile_area_sb = sb_rows * sb_cols; - max_tile_height_sb = FFMAX(max_tile_area_sb / widest_tile_sb, 1); - - start_sb = 0; - for(i = 0; start_sb < sb_rows && i < AV1_MAX_TILE_ROWS; i++) { - max_height = FFMIN(sb_rows - start_sb, max_tile_height_sb); - ns(max_height, height_in_sbs_minus_1[i], 1, i); - size_sb = current->height_in_sbs_minus_1[i] + 1; - start_sb += size_sb; - } - current->tile_rows_log2 = cbs_av1_tile_log2(1, i); - current->tile_rows = i; - } - - if(current->tile_cols_log2 > 0 || - current->tile_rows_log2 > 0) { - fb(current->tile_cols_log2 + current->tile_rows_log2, - context_update_tile_id); - fb(2, tile_size_bytes_minus1); - } - else { - infer(context_update_tile_id, 0); - } - - priv->tile_cols = current->tile_cols; - priv->tile_rows = current->tile_rows; - - return 0; -} - -static int FUNC(quantization_params)(CodedBitstreamContext *ctx, RWContext *rw, - AV1RawFrameHeader *current) { - CodedBitstreamAV1Context *priv = ctx->priv_data; - const AV1RawSequenceHeader *seq = priv->sequence_header; - int err; - - fb(8, base_q_idx); - - delta_q(delta_q_y_dc); - - if(priv->num_planes > 1) { - if(seq->color_config.separate_uv_delta_q) - flag(diff_uv_delta); - else - infer(diff_uv_delta, 0); - - delta_q(delta_q_u_dc); - delta_q(delta_q_u_ac); - - if(current->diff_uv_delta) { - delta_q(delta_q_v_dc); - delta_q(delta_q_v_ac); - } - else { - infer(delta_q_v_dc, current->delta_q_u_dc); - infer(delta_q_v_ac, current->delta_q_u_ac); - } - } - else { - infer(delta_q_u_dc, 0); - infer(delta_q_u_ac, 0); - infer(delta_q_v_dc, 0); - infer(delta_q_v_ac, 0); - } - - flag(using_qmatrix); - if(current->using_qmatrix) { - fb(4, qm_y); - fb(4, qm_u); - if(seq->color_config.separate_uv_delta_q) - fb(4, qm_v); - else - infer(qm_v, current->qm_u); - } - - return 0; -} - -static int FUNC(segmentation_params)(CodedBitstreamContext *ctx, RWContext *rw, - AV1RawFrameHeader *current) { - CodedBitstreamAV1Context *priv = ctx->priv_data; - static const uint8_t bits[AV1_SEG_LVL_MAX] = { 8, 6, 6, 6, 6, 3, 0, 0 }; - static const uint8_t sign[AV1_SEG_LVL_MAX] = { 1, 1, 1, 1, 1, 0, 0, 0 }; - static const uint8_t default_feature_enabled[AV1_SEG_LVL_MAX] = { 0 }; - static const int16_t default_feature_value[AV1_SEG_LVL_MAX] = { 0 }; - int i, j, err; - - flag(segmentation_enabled); - - if(current->segmentation_enabled) { - if(current->primary_ref_frame == AV1_PRIMARY_REF_NONE) { - infer(segmentation_update_map, 1); - infer(segmentation_temporal_update, 0); - infer(segmentation_update_data, 1); - } - else { - flag(segmentation_update_map); - if(current->segmentation_update_map) - flag(segmentation_temporal_update); - else - infer(segmentation_temporal_update, 0); - flag(segmentation_update_data); - } - - for(i = 0; i < AV1_MAX_SEGMENTS; i++) { - const uint8_t *ref_feature_enabled; - const int16_t *ref_feature_value; - - if(current->primary_ref_frame == AV1_PRIMARY_REF_NONE) { - ref_feature_enabled = default_feature_enabled; - ref_feature_value = default_feature_value; - } - else { - ref_feature_enabled = - priv->ref[current->ref_frame_idx[current->primary_ref_frame]].feature_enabled[i]; - ref_feature_value = - priv->ref[current->ref_frame_idx[current->primary_ref_frame]].feature_value[i]; - } - - for(j = 0; j < AV1_SEG_LVL_MAX; j++) { - if(current->segmentation_update_data) { - flags(feature_enabled[i][j], 2, i, j); - - if(current->feature_enabled[i][j] && bits[j] > 0) { - if(sign[j]) - sus(1 + bits[j], feature_value[i][j], 2, i, j); - else - fbs(bits[j], feature_value[i][j], 2, i, j); - } - else { - infer(feature_value[i][j], 0); - } - } - else { - infer(feature_enabled[i][j], ref_feature_enabled[j]); - infer(feature_value[i][j], ref_feature_value[j]); - } - } - } - } - else { - for(i = 0; i < AV1_MAX_SEGMENTS; i++) { - for(j = 0; j < AV1_SEG_LVL_MAX; j++) { - infer(feature_enabled[i][j], 0); - infer(feature_value[i][j], 0); - } - } - } - - return 0; -} - -static int FUNC(delta_q_params)(CodedBitstreamContext *ctx, RWContext *rw, - AV1RawFrameHeader *current) { - int err; - - if(current->base_q_idx > 0) - flag(delta_q_present); - else - infer(delta_q_present, 0); - - if(current->delta_q_present) - fb(2, delta_q_res); - - return 0; -} - -static int FUNC(delta_lf_params)(CodedBitstreamContext *ctx, RWContext *rw, - AV1RawFrameHeader *current) { - int err; - - if(current->delta_q_present) { - if(!current->allow_intrabc) - flag(delta_lf_present); - else - infer(delta_lf_present, 0); - if(current->delta_lf_present) { - fb(2, delta_lf_res); - flag(delta_lf_multi); - } - else { - infer(delta_lf_res, 0); - infer(delta_lf_multi, 0); - } - } - else { - infer(delta_lf_present, 0); - infer(delta_lf_res, 0); - infer(delta_lf_multi, 0); - } - - return 0; -} - -static int FUNC(loop_filter_params)(CodedBitstreamContext *ctx, RWContext *rw, - AV1RawFrameHeader *current) { - CodedBitstreamAV1Context *priv = ctx->priv_data; - static const int8_t default_loop_filter_ref_deltas[AV1_TOTAL_REFS_PER_FRAME] = { 1, 0, 0, 0, -1, 0, -1, -1 }; - static const int8_t default_loop_filter_mode_deltas[2] = { 0, 0 }; - int i, err; - - if(priv->coded_lossless || current->allow_intrabc) { - infer(loop_filter_level[0], 0); - infer(loop_filter_level[1], 0); - infer(loop_filter_ref_deltas[AV1_REF_FRAME_INTRA], 1); - infer(loop_filter_ref_deltas[AV1_REF_FRAME_LAST], 0); - infer(loop_filter_ref_deltas[AV1_REF_FRAME_LAST2], 0); - infer(loop_filter_ref_deltas[AV1_REF_FRAME_LAST3], 0); - infer(loop_filter_ref_deltas[AV1_REF_FRAME_BWDREF], 0); - infer(loop_filter_ref_deltas[AV1_REF_FRAME_GOLDEN], -1); - infer(loop_filter_ref_deltas[AV1_REF_FRAME_ALTREF], -1); - infer(loop_filter_ref_deltas[AV1_REF_FRAME_ALTREF2], -1); - for(i = 0; i < 2; i++) - infer(loop_filter_mode_deltas[i], 0); - return 0; - } - - fb(6, loop_filter_level[0]); - fb(6, loop_filter_level[1]); - - if(priv->num_planes > 1) { - if(current->loop_filter_level[0] || - current->loop_filter_level[1]) { - fb(6, loop_filter_level[2]); - fb(6, loop_filter_level[3]); - } - } - - fb(3, loop_filter_sharpness); - - flag(loop_filter_delta_enabled); - if(current->loop_filter_delta_enabled) { - const int8_t *ref_loop_filter_ref_deltas, *ref_loop_filter_mode_deltas; - - if(current->primary_ref_frame == AV1_PRIMARY_REF_NONE) { - ref_loop_filter_ref_deltas = default_loop_filter_ref_deltas; - ref_loop_filter_mode_deltas = default_loop_filter_mode_deltas; - } - else { - ref_loop_filter_ref_deltas = - priv->ref[current->ref_frame_idx[current->primary_ref_frame]].loop_filter_ref_deltas; - ref_loop_filter_mode_deltas = - priv->ref[current->ref_frame_idx[current->primary_ref_frame]].loop_filter_mode_deltas; - } - - flag(loop_filter_delta_update); - for(i = 0; i < AV1_TOTAL_REFS_PER_FRAME; i++) { - if(current->loop_filter_delta_update) - flags(update_ref_delta[i], 1, i); - else - infer(update_ref_delta[i], 0); - if(current->update_ref_delta[i]) - sus(1 + 6, loop_filter_ref_deltas[i], 1, i); - else - infer(loop_filter_ref_deltas[i], ref_loop_filter_ref_deltas[i]); - } - for(i = 0; i < 2; i++) { - if(current->loop_filter_delta_update) - flags(update_mode_delta[i], 1, i); - else - infer(update_mode_delta[i], 0); - if(current->update_mode_delta[i]) - sus(1 + 6, loop_filter_mode_deltas[i], 1, i); - else - infer(loop_filter_mode_deltas[i], ref_loop_filter_mode_deltas[i]); - } - } - else { - for(i = 0; i < AV1_TOTAL_REFS_PER_FRAME; i++) - infer(loop_filter_ref_deltas[i], default_loop_filter_ref_deltas[i]); - for(i = 0; i < 2; i++) - infer(loop_filter_mode_deltas[i], default_loop_filter_mode_deltas[i]); - } - - return 0; -} - -static int FUNC(cdef_params)(CodedBitstreamContext *ctx, RWContext *rw, - AV1RawFrameHeader *current) { - CodedBitstreamAV1Context *priv = ctx->priv_data; - const AV1RawSequenceHeader *seq = priv->sequence_header; - int i, err; - - if(priv->coded_lossless || current->allow_intrabc || - !seq->enable_cdef) { - infer(cdef_damping_minus_3, 0); - infer(cdef_bits, 0); - infer(cdef_y_pri_strength[0], 0); - infer(cdef_y_sec_strength[0], 0); - infer(cdef_uv_pri_strength[0], 0); - infer(cdef_uv_sec_strength[0], 0); - - return 0; - } - - fb(2, cdef_damping_minus_3); - fb(2, cdef_bits); - - for(i = 0; i < (1 << current->cdef_bits); i++) { - fbs(4, cdef_y_pri_strength[i], 1, i); - fbs(2, cdef_y_sec_strength[i], 1, i); - - if(priv->num_planes > 1) { - fbs(4, cdef_uv_pri_strength[i], 1, i); - fbs(2, cdef_uv_sec_strength[i], 1, i); - } - } - - return 0; -} - -static int FUNC(lr_params)(CodedBitstreamContext *ctx, RWContext *rw, - AV1RawFrameHeader *current) { - CodedBitstreamAV1Context *priv = ctx->priv_data; - const AV1RawSequenceHeader *seq = priv->sequence_header; - int uses_lr, uses_chroma_lr; - int i, err; - - if(priv->all_lossless || current->allow_intrabc || - !seq->enable_restoration) { - return 0; - } - - uses_lr = uses_chroma_lr = 0; - for(i = 0; i < priv->num_planes; i++) { - fbs(2, lr_type[i], 1, i); - - if(current->lr_type[i] != AV1_RESTORE_NONE) { - uses_lr = 1; - if(i > 0) - uses_chroma_lr = 1; - } - } - - if(uses_lr) { - if(seq->use_128x128_superblock) - increment(lr_unit_shift, 1, 2); - else - increment(lr_unit_shift, 0, 2); - - if(seq->color_config.subsampling_x && - seq->color_config.subsampling_y && uses_chroma_lr) { - fb(1, lr_uv_shift); - } - else { - infer(lr_uv_shift, 0); - } - } - - return 0; -} - -static int FUNC(read_tx_mode)(CodedBitstreamContext *ctx, RWContext *rw, - AV1RawFrameHeader *current) { - CodedBitstreamAV1Context *priv = ctx->priv_data; - int err; - - if(priv->coded_lossless) - infer(tx_mode, 0); - else - increment(tx_mode, 1, 2); - - return 0; -} - -static int FUNC(frame_reference_mode)(CodedBitstreamContext *ctx, RWContext *rw, - AV1RawFrameHeader *current) { - int err; - - if(current->frame_type == AV1_FRAME_INTRA_ONLY || - current->frame_type == AV1_FRAME_KEY) - infer(reference_select, 0); - else - flag(reference_select); - - return 0; -} - -static int FUNC(skip_mode_params)(CodedBitstreamContext *ctx, RWContext *rw, - AV1RawFrameHeader *current) { - CodedBitstreamAV1Context *priv = ctx->priv_data; - const AV1RawSequenceHeader *seq = priv->sequence_header; - int skip_mode_allowed; - int err; - - if(current->frame_type == AV1_FRAME_KEY || - current->frame_type == AV1_FRAME_INTRA_ONLY || - !current->reference_select || !seq->enable_order_hint) { - skip_mode_allowed = 0; - } - else { - int forward_idx, backward_idx; - int forward_hint, backward_hint; - int ref_hint, dist, i; - - forward_idx = -1; - backward_idx = -1; - for(i = 0; i < AV1_REFS_PER_FRAME; i++) { - ref_hint = priv->ref[current->ref_frame_idx[i]].order_hint; - dist = cbs_av1_get_relative_dist(seq, ref_hint, - priv->order_hint); - if(dist < 0) { - if(forward_idx < 0 || - cbs_av1_get_relative_dist(seq, ref_hint, - forward_hint) > 0) { - forward_idx = i; - forward_hint = ref_hint; - } - } - else if(dist > 0) { - if(backward_idx < 0 || - cbs_av1_get_relative_dist(seq, ref_hint, - backward_hint) < 0) { - backward_idx = i; - backward_hint = ref_hint; - } - } - } - - if(forward_idx < 0) { - skip_mode_allowed = 0; - } - else if(backward_idx >= 0) { - skip_mode_allowed = 1; - // Frames for skip mode are forward_idx and backward_idx. - } - else { - int second_forward_idx; - int second_forward_hint; - - second_forward_idx = -1; - for(i = 0; i < AV1_REFS_PER_FRAME; i++) { - ref_hint = priv->ref[current->ref_frame_idx[i]].order_hint; - if(cbs_av1_get_relative_dist(seq, ref_hint, - forward_hint) < 0) { - if(second_forward_idx < 0 || - cbs_av1_get_relative_dist(seq, ref_hint, - second_forward_hint) > 0) { - second_forward_idx = i; - second_forward_hint = ref_hint; - } - } - } - - if(second_forward_idx < 0) { - skip_mode_allowed = 0; - } - else { - skip_mode_allowed = 1; - // Frames for skip mode are forward_idx and second_forward_idx. - } - } - } - - if(skip_mode_allowed) - flag(skip_mode_present); - else - infer(skip_mode_present, 0); - - return 0; -} - -static int FUNC(global_motion_param)(CodedBitstreamContext *ctx, RWContext *rw, - AV1RawFrameHeader *current, - int type, int ref, int idx) { - uint32_t abs_bits, prec_bits, num_syms; - int err; - - if(idx < 2) { - if(type == AV1_WARP_MODEL_TRANSLATION) { - abs_bits = AV1_GM_ABS_TRANS_ONLY_BITS - !current->allow_high_precision_mv; - prec_bits = AV1_GM_TRANS_ONLY_PREC_BITS - !current->allow_high_precision_mv; - } - else { - abs_bits = AV1_GM_ABS_TRANS_BITS; - prec_bits = AV1_GM_TRANS_PREC_BITS; - } - } - else { - abs_bits = AV1_GM_ABS_ALPHA_BITS; - prec_bits = AV1_GM_ALPHA_PREC_BITS; - } - - num_syms = 2 * (1 << abs_bits) + 1; - subexp(gm_params[ref][idx], num_syms, 2, ref, idx); - - // Actual gm_params value is not reconstructed here. - (void)prec_bits; - - return 0; -} - -static int FUNC(global_motion_params)(CodedBitstreamContext *ctx, RWContext *rw, - AV1RawFrameHeader *current) { - int ref, type; - int err; - - if(current->frame_type == AV1_FRAME_KEY || - current->frame_type == AV1_FRAME_INTRA_ONLY) - return 0; - - for(ref = AV1_REF_FRAME_LAST; ref <= AV1_REF_FRAME_ALTREF; ref++) { - flags(is_global[ref], 1, ref); - if(current->is_global[ref]) { - flags(is_rot_zoom[ref], 1, ref); - if(current->is_rot_zoom[ref]) { - type = AV1_WARP_MODEL_ROTZOOM; - } - else { - flags(is_translation[ref], 1, ref); - type = current->is_translation[ref] ? AV1_WARP_MODEL_TRANSLATION : AV1_WARP_MODEL_AFFINE; - } - } - else { - type = AV1_WARP_MODEL_IDENTITY; - } - - if(type >= AV1_WARP_MODEL_ROTZOOM) { - CHECK(FUNC(global_motion_param)(ctx, rw, current, type, ref, 2)); - CHECK(FUNC(global_motion_param)(ctx, rw, current, type, ref, 3)); - if(type == AV1_WARP_MODEL_AFFINE) { - CHECK(FUNC(global_motion_param)(ctx, rw, current, type, ref, 4)); - CHECK(FUNC(global_motion_param)(ctx, rw, current, type, ref, 5)); - } - else { - // gm_params[ref][4] = -gm_params[ref][3] - // gm_params[ref][5] = gm_params[ref][2] - } - } - if(type >= AV1_WARP_MODEL_TRANSLATION) { - CHECK(FUNC(global_motion_param)(ctx, rw, current, type, ref, 0)); - CHECK(FUNC(global_motion_param)(ctx, rw, current, type, ref, 1)); - } - } - - return 0; -} - -static int FUNC(film_grain_params)(CodedBitstreamContext *ctx, RWContext *rw, - AV1RawFilmGrainParams *current, - AV1RawFrameHeader *frame_header) { - CodedBitstreamAV1Context *priv = ctx->priv_data; - const AV1RawSequenceHeader *seq = priv->sequence_header; - int num_pos_luma, num_pos_chroma; - int i, err; - - if(!seq->film_grain_params_present || - (!frame_header->show_frame && !frame_header->showable_frame)) - return 0; - - flag(apply_grain); - - if(!current->apply_grain) - return 0; - - fb(16, grain_seed); - - if(frame_header->frame_type == AV1_FRAME_INTER) - flag(update_grain); - else - infer(update_grain, 1); - - if(!current->update_grain) { - fb(3, film_grain_params_ref_idx); - return 0; - } - - fc(4, num_y_points, 0, 14); - for(i = 0; i < current->num_y_points; i++) { - fcs(8, point_y_value[i], - i ? current->point_y_value[i - 1] + 1 : 0, - MAX_UINT_BITS(8) - (current->num_y_points - i - 1), - 1, i); - fbs(8, point_y_scaling[i], 1, i); - } - - if(seq->color_config.mono_chrome) - infer(chroma_scaling_from_luma, 0); - else - flag(chroma_scaling_from_luma); - - if(seq->color_config.mono_chrome || - current->chroma_scaling_from_luma || - (seq->color_config.subsampling_x == 1 && - seq->color_config.subsampling_y == 1 && - current->num_y_points == 0)) { - infer(num_cb_points, 0); - infer(num_cr_points, 0); - } - else { - fc(4, num_cb_points, 0, 10); - for(i = 0; i < current->num_cb_points; i++) { - fcs(8, point_cb_value[i], - i ? current->point_cb_value[i - 1] + 1 : 0, - MAX_UINT_BITS(8) - (current->num_cb_points - i - 1), - 1, i); - fbs(8, point_cb_scaling[i], 1, i); - } - fc(4, num_cr_points, 0, 10); - for(i = 0; i < current->num_cr_points; i++) { - fcs(8, point_cr_value[i], - i ? current->point_cr_value[i - 1] + 1 : 0, - MAX_UINT_BITS(8) - (current->num_cr_points - i - 1), - 1, i); - fbs(8, point_cr_scaling[i], 1, i); - } - } - - fb(2, grain_scaling_minus_8); - fb(2, ar_coeff_lag); - num_pos_luma = 2 * current->ar_coeff_lag * (current->ar_coeff_lag + 1); - if(current->num_y_points) { - num_pos_chroma = num_pos_luma + 1; - for(i = 0; i < num_pos_luma; i++) - fbs(8, ar_coeffs_y_plus_128[i], 1, i); - } - else { - num_pos_chroma = num_pos_luma; - } - if(current->chroma_scaling_from_luma || current->num_cb_points) { - for(i = 0; i < num_pos_chroma; i++) - fbs(8, ar_coeffs_cb_plus_128[i], 1, i); - } - if(current->chroma_scaling_from_luma || current->num_cr_points) { - for(i = 0; i < num_pos_chroma; i++) - fbs(8, ar_coeffs_cr_plus_128[i], 1, i); - } - fb(2, ar_coeff_shift_minus_6); - fb(2, grain_scale_shift); - if(current->num_cb_points) { - fb(8, cb_mult); - fb(8, cb_luma_mult); - fb(9, cb_offset); - } - if(current->num_cr_points) { - fb(8, cr_mult); - fb(8, cr_luma_mult); - fb(9, cr_offset); - } - - flag(overlap_flag); - flag(clip_to_restricted_range); - - return 0; -} - -static int FUNC(uncompressed_header)(CodedBitstreamContext *ctx, RWContext *rw, - AV1RawFrameHeader *current) { - CodedBitstreamAV1Context *priv = ctx->priv_data; - const AV1RawSequenceHeader *seq; - int id_len, diff_len, all_frames, frame_is_intra, order_hint_bits; - int i, err; - - if(!priv->sequence_header) { - av_log(ctx->log_ctx, AV_LOG_ERROR, "No sequence header available: " - "unable to decode frame header.\n"); - return AVERROR_INVALIDDATA; - } - seq = priv->sequence_header; - - id_len = seq->additional_frame_id_length_minus_1 + - seq->delta_frame_id_length_minus_2 + 3; - all_frames = (1 << AV1_NUM_REF_FRAMES) - 1; - - if(seq->reduced_still_picture_header) { - infer(show_existing_frame, 0); - infer(frame_type, AV1_FRAME_KEY); - infer(show_frame, 1); - infer(showable_frame, 0); - frame_is_intra = 1; - } - else { - flag(show_existing_frame); - - if(current->show_existing_frame) { - AV1ReferenceFrameState *ref; - - fb(3, frame_to_show_map_idx); - ref = &priv->ref[current->frame_to_show_map_idx]; - - if(!ref->valid) { - av_log(ctx->log_ctx, AV_LOG_ERROR, "Missing reference frame needed for " - "show_existing_frame (frame_to_show_map_idx = %d).\n", - current->frame_to_show_map_idx); - return AVERROR_INVALIDDATA; - } - - if(seq->decoder_model_info_present_flag && - !seq->timing_info.equal_picture_interval) { - fb(seq->decoder_model_info.frame_presentation_time_length_minus_1 + 1, - frame_presentation_time); - } - - if(seq->frame_id_numbers_present_flag) - fb(id_len, display_frame_id); - - infer(frame_type, ref->frame_type); - if(current->frame_type == AV1_FRAME_KEY) { - infer(refresh_frame_flags, all_frames); - - // Section 7.21 - infer(current_frame_id, ref->frame_id); - priv->upscaled_width = ref->upscaled_width; - priv->frame_width = ref->frame_width; - priv->frame_height = ref->frame_height; - priv->render_width = ref->render_width; - priv->render_height = ref->render_height; - priv->bit_depth = ref->bit_depth; - priv->order_hint = ref->order_hint; - } - else - infer(refresh_frame_flags, 0); - - infer(frame_width_minus_1, ref->upscaled_width - 1); - infer(frame_height_minus_1, ref->frame_height - 1); - infer(render_width_minus_1, ref->render_width - 1); - infer(render_height_minus_1, ref->render_height - 1); - - // Section 7.20 - goto update_refs; - } - - fb(2, frame_type); - frame_is_intra = (current->frame_type == AV1_FRAME_INTRA_ONLY || - current->frame_type == AV1_FRAME_KEY); - - flag(show_frame); - if(current->show_frame && - seq->decoder_model_info_present_flag && - !seq->timing_info.equal_picture_interval) { - fb(seq->decoder_model_info.frame_presentation_time_length_minus_1 + 1, - frame_presentation_time); - } - if(current->show_frame) - infer(showable_frame, current->frame_type != AV1_FRAME_KEY); - else - flag(showable_frame); - - if(current->frame_type == AV1_FRAME_SWITCH || - (current->frame_type == AV1_FRAME_KEY && current->show_frame)) - infer(error_resilient_mode, 1); - else - flag(error_resilient_mode); - } - - if(current->frame_type == AV1_FRAME_KEY && current->show_frame) { - for(i = 0; i < AV1_NUM_REF_FRAMES; i++) { - priv->ref[i].valid = 0; - priv->ref[i].order_hint = 0; - } - } - - flag(disable_cdf_update); - - if(seq->seq_force_screen_content_tools == - AV1_SELECT_SCREEN_CONTENT_TOOLS) { - flag(allow_screen_content_tools); - } - else { - infer(allow_screen_content_tools, - seq->seq_force_screen_content_tools); - } - if(current->allow_screen_content_tools) { - if(seq->seq_force_integer_mv == AV1_SELECT_INTEGER_MV) - flag(force_integer_mv); - else - infer(force_integer_mv, seq->seq_force_integer_mv); - } - else { - infer(force_integer_mv, 0); - } - - if(seq->frame_id_numbers_present_flag) { - fb(id_len, current_frame_id); - - diff_len = seq->delta_frame_id_length_minus_2 + 2; - for(i = 0; i < AV1_NUM_REF_FRAMES; i++) { - if(current->current_frame_id > (1 << diff_len)) { - if(priv->ref[i].frame_id > current->current_frame_id || - priv->ref[i].frame_id < (current->current_frame_id - - (1 << diff_len))) - priv->ref[i].valid = 0; - } - else { - if(priv->ref[i].frame_id > current->current_frame_id && - priv->ref[i].frame_id < ((1 << id_len) + - current->current_frame_id - - (1 << diff_len))) - priv->ref[i].valid = 0; - } - } - } - else { - infer(current_frame_id, 0); - } - - if(current->frame_type == AV1_FRAME_SWITCH) - infer(frame_size_override_flag, 1); - else if(seq->reduced_still_picture_header) - infer(frame_size_override_flag, 0); - else - flag(frame_size_override_flag); - - order_hint_bits = - seq->enable_order_hint ? seq->order_hint_bits_minus_1 + 1 : 0; - if(order_hint_bits > 0) - fb(order_hint_bits, order_hint); - else - infer(order_hint, 0); - priv->order_hint = current->order_hint; - - if(frame_is_intra || current->error_resilient_mode) - infer(primary_ref_frame, AV1_PRIMARY_REF_NONE); - else - fb(3, primary_ref_frame); - - if(seq->decoder_model_info_present_flag) { - flag(buffer_removal_time_present_flag); - if(current->buffer_removal_time_present_flag) { - for(i = 0; i <= seq->operating_points_cnt_minus_1; i++) { - if(seq->decoder_model_present_for_this_op[i]) { - int op_pt_idc = seq->operating_point_idc[i]; - int in_temporal_layer = (op_pt_idc >> priv->temporal_id) & 1; - int in_spatial_layer = (op_pt_idc >> (priv->spatial_id + 8)) & 1; - if(seq->operating_point_idc[i] == 0 || - (in_temporal_layer && in_spatial_layer)) { - fbs(seq->decoder_model_info.buffer_removal_time_length_minus_1 + 1, - buffer_removal_time[i], 1, i); - } - } - } - } - } - - if(current->frame_type == AV1_FRAME_SWITCH || - (current->frame_type == AV1_FRAME_KEY && current->show_frame)) - infer(refresh_frame_flags, all_frames); - else - fb(8, refresh_frame_flags); - - if(!frame_is_intra || current->refresh_frame_flags != all_frames) { - if(seq->enable_order_hint) { - for(i = 0; i < AV1_NUM_REF_FRAMES; i++) { - if(current->error_resilient_mode) - fbs(order_hint_bits, ref_order_hint[i], 1, i); - else - infer(ref_order_hint[i], priv->ref[i].order_hint); - if(current->ref_order_hint[i] != priv->ref[i].order_hint) - priv->ref[i].valid = 0; - } - } - } - - if(current->frame_type == AV1_FRAME_KEY || - current->frame_type == AV1_FRAME_INTRA_ONLY) { - CHECK(FUNC(frame_size)(ctx, rw, current)); - CHECK(FUNC(render_size)(ctx, rw, current)); - - if(current->allow_screen_content_tools && - priv->upscaled_width == priv->frame_width) - flag(allow_intrabc); - else - infer(allow_intrabc, 0); - } - else { - if(!seq->enable_order_hint) { - infer(frame_refs_short_signaling, 0); - } - else { - flag(frame_refs_short_signaling); - if(current->frame_refs_short_signaling) { - fb(3, last_frame_idx); - fb(3, golden_frame_idx); - CHECK(FUNC(set_frame_refs)(ctx, rw, current)); - } - } - - for(i = 0; i < AV1_REFS_PER_FRAME; i++) { - if(!current->frame_refs_short_signaling) - fbs(3, ref_frame_idx[i], 1, i); - if(seq->frame_id_numbers_present_flag) { - fbs(seq->delta_frame_id_length_minus_2 + 2, - delta_frame_id_minus1[i], 1, i); - } - } - - if(current->frame_size_override_flag && - !current->error_resilient_mode) { - CHECK(FUNC(frame_size_with_refs)(ctx, rw, current)); - } - else { - CHECK(FUNC(frame_size)(ctx, rw, current)); - CHECK(FUNC(render_size)(ctx, rw, current)); - } - - if(current->force_integer_mv) - infer(allow_high_precision_mv, 0); - else - flag(allow_high_precision_mv); - - CHECK(FUNC(interpolation_filter)(ctx, rw, current)); - - flag(is_motion_mode_switchable); - - if(current->error_resilient_mode || - !seq->enable_ref_frame_mvs) - infer(use_ref_frame_mvs, 0); - else - flag(use_ref_frame_mvs); - - infer(allow_intrabc, 0); - } - - if(!frame_is_intra) { - // Derive reference frame sign biases. - } - - if(seq->reduced_still_picture_header || current->disable_cdf_update) - infer(disable_frame_end_update_cdf, 1); - else - flag(disable_frame_end_update_cdf); - - if(current->primary_ref_frame == AV1_PRIMARY_REF_NONE) { - // Init non-coeff CDFs. - // Setup past independence. - } - else { - // Load CDF tables from previous frame. - // Load params from previous frame. - } - - if(current->use_ref_frame_mvs) { - // Perform motion field estimation process. - } - - CHECK(FUNC(tile_info)(ctx, rw, current)); - - CHECK(FUNC(quantization_params)(ctx, rw, current)); - - CHECK(FUNC(segmentation_params)(ctx, rw, current)); - - CHECK(FUNC(delta_q_params)(ctx, rw, current)); - - CHECK(FUNC(delta_lf_params)(ctx, rw, current)); - - // Init coeff CDFs / load previous segments. - - priv->coded_lossless = 1; - for(i = 0; i < AV1_MAX_SEGMENTS; i++) { - int qindex; - if(current->feature_enabled[i][AV1_SEG_LVL_ALT_Q]) { - qindex = (current->base_q_idx + - current->feature_value[i][AV1_SEG_LVL_ALT_Q]); - } - else { - qindex = current->base_q_idx; - } - qindex = av_clip_uintp2(qindex, 8); - - if(qindex || current->delta_q_y_dc || - current->delta_q_u_ac || current->delta_q_u_dc || - current->delta_q_v_ac || current->delta_q_v_dc) { - priv->coded_lossless = 0; - } - } - priv->all_lossless = priv->coded_lossless && - priv->frame_width == priv->upscaled_width; - - CHECK(FUNC(loop_filter_params)(ctx, rw, current)); - - CHECK(FUNC(cdef_params)(ctx, rw, current)); - - CHECK(FUNC(lr_params)(ctx, rw, current)); - - CHECK(FUNC(read_tx_mode)(ctx, rw, current)); - - CHECK(FUNC(frame_reference_mode)(ctx, rw, current)); - - CHECK(FUNC(skip_mode_params)(ctx, rw, current)); - - if(frame_is_intra || current->error_resilient_mode || - !seq->enable_warped_motion) - infer(allow_warped_motion, 0); - else - flag(allow_warped_motion); - - flag(reduced_tx_set); - - CHECK(FUNC(global_motion_params)(ctx, rw, current)); - - CHECK(FUNC(film_grain_params)(ctx, rw, ¤t->film_grain, current)); - - av_log(ctx->log_ctx, AV_LOG_DEBUG, "Frame %d: size %dx%d " - "upscaled %d render %dx%d subsample %dx%d " - "bitdepth %d tiles %dx%d.\n", - priv->order_hint, - priv->frame_width, priv->frame_height, priv->upscaled_width, - priv->render_width, priv->render_height, - seq->color_config.subsampling_x + 1, - seq->color_config.subsampling_y + 1, priv->bit_depth, - priv->tile_rows, priv->tile_cols); - -update_refs: - for(i = 0; i < AV1_NUM_REF_FRAMES; i++) { - if(current->refresh_frame_flags & (1 << i)) { - priv->ref[i] = (AV1ReferenceFrameState) { - .valid = 1, - .frame_id = current->current_frame_id, - .upscaled_width = priv->upscaled_width, - .frame_width = priv->frame_width, - .frame_height = priv->frame_height, - .render_width = priv->render_width, - .render_height = priv->render_height, - .frame_type = current->frame_type, - .subsampling_x = seq->color_config.subsampling_x, - .subsampling_y = seq->color_config.subsampling_y, - .bit_depth = priv->bit_depth, - .order_hint = priv->order_hint, - }; - memcpy(priv->ref[i].loop_filter_ref_deltas, current->loop_filter_ref_deltas, - sizeof(current->loop_filter_ref_deltas)); - memcpy(priv->ref[i].loop_filter_mode_deltas, current->loop_filter_mode_deltas, - sizeof(current->loop_filter_mode_deltas)); - memcpy(priv->ref[i].feature_enabled, current->feature_enabled, - sizeof(current->feature_enabled)); - memcpy(priv->ref[i].feature_value, current->feature_value, - sizeof(current->feature_value)); - } - } - - return 0; -} - -static int FUNC(frame_header_obu)(CodedBitstreamContext *ctx, RWContext *rw, - AV1RawFrameHeader *current, int redundant, - AVBufferRef *rw_buffer_ref) { - CodedBitstreamAV1Context *priv = ctx->priv_data; - int start_pos, fh_bits, fh_bytes, err; - uint8_t *fh_start; - - if(priv->seen_frame_header) { - if(!redundant) { - av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid repeated " - "frame header OBU.\n"); - return AVERROR_INVALIDDATA; - } - else { - GetBitContext fh; - size_t i, b; - uint32_t val; - - HEADER("Redundant Frame Header"); - - av_assert0(priv->frame_header_ref && priv->frame_header); - - init_get_bits(&fh, priv->frame_header, - priv->frame_header_size); - for(i = 0; i < priv->frame_header_size; i += 8) { - b = FFMIN(priv->frame_header_size - i, 8); - val = get_bits(&fh, b); - xf(b, frame_header_copy[i], - val, val, val, 1, i / 8); - } - } - } - else { - if(redundant) - HEADER("Redundant Frame Header (used as Frame Header)"); - else - HEADER("Frame Header"); - -#ifdef READ - start_pos = get_bits_count(rw); -#else - start_pos = put_bits_count(rw); -#endif - - CHECK(FUNC(uncompressed_header)(ctx, rw, current)); - - priv->tile_num = 0; - - if(current->show_existing_frame) { - priv->seen_frame_header = 0; - } - else { - priv->seen_frame_header = 1; - - av_buffer_unref(&priv->frame_header_ref); - -#ifdef READ - fh_bits = get_bits_count(rw) - start_pos; - fh_start = (uint8_t *)rw->buffer + start_pos / 8; -#else - // Need to flush the bitwriter so that we can copy its output, - // but use a copy so we don't affect the caller's structure. - { - PutBitContext tmp = *rw; - flush_put_bits(&tmp); - } - - fh_bits = put_bits_count(rw) - start_pos; - fh_start = rw->buf + start_pos / 8; -#endif - fh_bytes = (fh_bits + 7) / 8; - - priv->frame_header_size = fh_bits; - - if(rw_buffer_ref) { - priv->frame_header_ref = av_buffer_ref(rw_buffer_ref); - if(!priv->frame_header_ref) - return AVERROR(ENOMEM); - priv->frame_header = fh_start; - } - else { - priv->frame_header_ref = - av_buffer_alloc(fh_bytes + AV_INPUT_BUFFER_PADDING_SIZE); - if(!priv->frame_header_ref) - return AVERROR(ENOMEM); - priv->frame_header = priv->frame_header_ref->data; - memcpy(priv->frame_header, fh_start, fh_bytes); - } - } - } - - return 0; -} - -static int FUNC(tile_group_obu)(CodedBitstreamContext *ctx, RWContext *rw, - AV1RawTileGroup *current) { - CodedBitstreamAV1Context *priv = ctx->priv_data; - int num_tiles, tile_bits; - int err; - - HEADER("Tile Group"); - - num_tiles = priv->tile_cols * priv->tile_rows; - if(num_tiles > 1) - flag(tile_start_and_end_present_flag); - else - infer(tile_start_and_end_present_flag, 0); - - if(num_tiles == 1 || !current->tile_start_and_end_present_flag) { - infer(tg_start, 0); - infer(tg_end, num_tiles - 1); - } - else { - tile_bits = cbs_av1_tile_log2(1, priv->tile_cols) + - cbs_av1_tile_log2(1, priv->tile_rows); - fc(tile_bits, tg_start, priv->tile_num, num_tiles - 1); - fc(tile_bits, tg_end, current->tg_start, num_tiles - 1); - } - - priv->tile_num = current->tg_end + 1; - - CHECK(FUNC(byte_alignment)(ctx, rw)); - - // Reset header for next frame. - if(current->tg_end == num_tiles - 1) - priv->seen_frame_header = 0; - - // Tile data follows. - - return 0; -} - -static int FUNC(frame_obu)(CodedBitstreamContext *ctx, RWContext *rw, - AV1RawFrame *current, - AVBufferRef *rw_buffer_ref) { - int err; - - CHECK(FUNC(frame_header_obu)(ctx, rw, ¤t->header, - 0, rw_buffer_ref)); - - CHECK(FUNC(byte_alignment)(ctx, rw)); - - CHECK(FUNC(tile_group_obu)(ctx, rw, ¤t->tile_group)); - - return 0; -} - -static int FUNC(tile_list_obu)(CodedBitstreamContext *ctx, RWContext *rw, - AV1RawTileList *current) { - int err; - - fb(8, output_frame_width_in_tiles_minus_1); - fb(8, output_frame_height_in_tiles_minus_1); - - fb(16, tile_count_minus_1); - - // Tile data follows. - - return 0; -} - -static int FUNC(metadata_hdr_cll)(CodedBitstreamContext *ctx, RWContext *rw, - AV1RawMetadataHDRCLL *current) { - int err; - - fb(16, max_cll); - fb(16, max_fall); - - return 0; -} - -static int FUNC(metadata_hdr_mdcv)(CodedBitstreamContext *ctx, RWContext *rw, - AV1RawMetadataHDRMDCV *current) { - int err, i; - - for(i = 0; i < 3; i++) { - fbs(16, primary_chromaticity_x[i], 1, i); - fbs(16, primary_chromaticity_y[i], 1, i); - } - - fb(16, white_point_chromaticity_x); - fb(16, white_point_chromaticity_y); - - fc(32, luminance_max, 1, MAX_UINT_BITS(32)); - // luminance_min must be lower than luminance_max. Convert luminance_max from - // 24.8 fixed point to 18.14 fixed point in order to compare them. - fc(32, luminance_min, 0, FFMIN(((uint64_t)current->luminance_max << 6) - 1, MAX_UINT_BITS(32))); - - return 0; -} - -static int FUNC(scalability_structure)(CodedBitstreamContext *ctx, RWContext *rw, - AV1RawMetadataScalability *current) { - CodedBitstreamAV1Context *priv = ctx->priv_data; - const AV1RawSequenceHeader *seq; - int err, i, j; - - if(!priv->sequence_header) { - av_log(ctx->log_ctx, AV_LOG_ERROR, "No sequence header available: " - "unable to parse scalability metadata.\n"); - return AVERROR_INVALIDDATA; - } - seq = priv->sequence_header; - - fb(2, spatial_layers_cnt_minus_1); - flag(spatial_layer_dimensions_present_flag); - flag(spatial_layer_description_present_flag); - flag(temporal_group_description_present_flag); - fc(3, scalability_structure_reserved_3bits, 0, 0); - if(current->spatial_layer_dimensions_present_flag) { - for(i = 0; i <= current->spatial_layers_cnt_minus_1; i++) { - fcs(16, spatial_layer_max_width[i], - 0, seq->max_frame_width_minus_1 + 1, 1, i); - fcs(16, spatial_layer_max_height[i], - 0, seq->max_frame_height_minus_1 + 1, 1, i); - } - } - if(current->spatial_layer_description_present_flag) { - for(i = 0; i <= current->spatial_layers_cnt_minus_1; i++) - fbs(8, spatial_layer_ref_id[i], 1, i); - } - if(current->temporal_group_description_present_flag) { - fb(8, temporal_group_size); - for(i = 0; i < current->temporal_group_size; i++) { - fbs(3, temporal_group_temporal_id[i], 1, i); - flags(temporal_group_temporal_switching_up_point_flag[i], 1, i); - flags(temporal_group_spatial_switching_up_point_flag[i], 1, i); - fbs(3, temporal_group_ref_cnt[i], 1, i); - for(j = 0; j < current->temporal_group_ref_cnt[i]; j++) { - fbs(8, temporal_group_ref_pic_diff[i][j], 2, i, j); - } - } - } - - return 0; -} - -static int FUNC(metadata_scalability)(CodedBitstreamContext *ctx, RWContext *rw, - AV1RawMetadataScalability *current) { - int err; - - fb(8, scalability_mode_idc); - - if(current->scalability_mode_idc == AV1_SCALABILITY_SS) - CHECK(FUNC(scalability_structure)(ctx, rw, current)); - - return 0; -} - -static int FUNC(metadata_itut_t35)(CodedBitstreamContext *ctx, RWContext *rw, - AV1RawMetadataITUTT35 *current) { - int err; - size_t i; - - fb(8, itu_t_t35_country_code); - if(current->itu_t_t35_country_code == 0xff) - fb(8, itu_t_t35_country_code_extension_byte); - -#ifdef READ - // The payload runs up to the start of the trailing bits, but there might - // be arbitrarily many trailing zeroes so we need to read through twice. - current->payload_size = cbs_av1_get_payload_bytes_left(rw); - - current->payload_ref = av_buffer_alloc(current->payload_size); - if(!current->payload_ref) - return AVERROR(ENOMEM); - current->payload = current->payload_ref->data; -#endif - - for(i = 0; i < current->payload_size; i++) - xf(8, itu_t_t35_payload_bytes[i], current->payload[i], - 0x00, 0xff, 1, i); - - return 0; -} - -static int FUNC(metadata_timecode)(CodedBitstreamContext *ctx, RWContext *rw, - AV1RawMetadataTimecode *current) { - int err; - - fb(5, counting_type); - flag(full_timestamp_flag); - flag(discontinuity_flag); - flag(cnt_dropped_flag); - fb(9, n_frames); - - if(current->full_timestamp_flag) { - fc(6, seconds_value, 0, 59); - fc(6, minutes_value, 0, 59); - fc(5, hours_value, 0, 23); - } - else { - flag(seconds_flag); - if(current->seconds_flag) { - fc(6, seconds_value, 0, 59); - flag(minutes_flag); - if(current->minutes_flag) { - fc(6, minutes_value, 0, 59); - flag(hours_flag); - if(current->hours_flag) - fc(5, hours_value, 0, 23); - } - } - } - - fb(5, time_offset_length); - if(current->time_offset_length > 0) - fb(current->time_offset_length, time_offset_value); - else - infer(time_offset_length, 0); - - return 0; -} - -static int FUNC(metadata_obu)(CodedBitstreamContext *ctx, RWContext *rw, - AV1RawMetadata *current) { - int err; - - leb128(metadata_type); - - switch(current->metadata_type) { - case AV1_METADATA_TYPE_HDR_CLL: - CHECK(FUNC(metadata_hdr_cll)(ctx, rw, ¤t->metadata.hdr_cll)); - break; - case AV1_METADATA_TYPE_HDR_MDCV: - CHECK(FUNC(metadata_hdr_mdcv)(ctx, rw, ¤t->metadata.hdr_mdcv)); - break; - case AV1_METADATA_TYPE_SCALABILITY: - CHECK(FUNC(metadata_scalability)(ctx, rw, ¤t->metadata.scalability)); - break; - case AV1_METADATA_TYPE_ITUT_T35: - CHECK(FUNC(metadata_itut_t35)(ctx, rw, ¤t->metadata.itut_t35)); - break; - case AV1_METADATA_TYPE_TIMECODE: - CHECK(FUNC(metadata_timecode)(ctx, rw, ¤t->metadata.timecode)); - break; - default: - // Unknown metadata type. - return AVERROR_PATCHWELCOME; - } - - return 0; -} - -static int FUNC(padding_obu)(CodedBitstreamContext *ctx, RWContext *rw, - AV1RawPadding *current) { - int i, err; - - HEADER("Padding"); - -#ifdef READ - // The payload runs up to the start of the trailing bits, but there might - // be arbitrarily many trailing zeroes so we need to read through twice. - current->payload_size = cbs_av1_get_payload_bytes_left(rw); - - current->payload_ref = av_buffer_alloc(current->payload_size); - if(!current->payload_ref) - return AVERROR(ENOMEM); - current->payload = current->payload_ref->data; -#endif - - for(i = 0; i < current->payload_size; i++) - xf(8, obu_padding_byte[i], current->payload[i], 0x00, 0xff, 1, i); - - return 0; -} diff --git a/third-party/cbs/cbs_h2645.c b/third-party/cbs/cbs_h2645.c deleted file mode 100644 index 4a60072d522..00000000000 --- a/third-party/cbs/cbs_h2645.c +++ /dev/null @@ -1,1632 +0,0 @@ -/* - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include - -#include "cbs/cbs.h" -#include "cbs/cbs_h264.h" -#include "cbs/cbs_h265.h" -#include "cbs/h264.h" -#include "cbs/h2645_parse.h" -#include "cbs/hevc.h" - -#include "bytestream.h" -#include "cbs_internal.h" -#include "h264_sei.h" -#include "hevc_sei.h" -#include "intmath.h" - - -static int cbs_read_ue_golomb(CodedBitstreamContext *ctx, GetBitContext *gbc, - const char *name, const int *subscripts, - uint32_t *write_to, - uint32_t range_min, uint32_t range_max) { - uint32_t value; - int position, i, j; - unsigned int k; - char bits[65]; - - position = get_bits_count(gbc); - - for(i = 0; i < 32; i++) { - if(get_bits_left(gbc) < i + 1) { - av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid ue-golomb code at " - "%s: bitstream ended.\n", - name); - return AVERROR_INVALIDDATA; - } - k = get_bits1(gbc); - bits[i] = k ? '1' : '0'; - if(k) - break; - } - if(i >= 32) { - av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid ue-golomb code at " - "%s: more than 31 zeroes.\n", - name); - return AVERROR_INVALIDDATA; - } - value = 1; - for(j = 0; j < i; j++) { - k = get_bits1(gbc); - bits[i + j + 1] = k ? '1' : '0'; - value = value << 1 | k; - } - bits[i + j + 1] = 0; - --value; - - if(ctx->trace_enable) - ff_cbs_trace_syntax_element(ctx, position, name, subscripts, - bits, value); - - if(value < range_min || value > range_max) { - av_log(ctx->log_ctx, AV_LOG_ERROR, "%s out of range: " - "%" PRIu32 ", but must be in [%" PRIu32 ",%" PRIu32 "].\n", - name, value, range_min, range_max); - return AVERROR_INVALIDDATA; - } - - *write_to = value; - return 0; -} - -static int cbs_read_se_golomb(CodedBitstreamContext *ctx, GetBitContext *gbc, - const char *name, const int *subscripts, - int32_t *write_to, - int32_t range_min, int32_t range_max) { - int32_t value; - int position, i, j; - unsigned int k; - uint32_t v; - char bits[65]; - - position = get_bits_count(gbc); - - for(i = 0; i < 32; i++) { - if(get_bits_left(gbc) < i + 1) { - av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid se-golomb code at " - "%s: bitstream ended.\n", - name); - return AVERROR_INVALIDDATA; - } - k = get_bits1(gbc); - bits[i] = k ? '1' : '0'; - if(k) - break; - } - if(i >= 32) { - av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid se-golomb code at " - "%s: more than 31 zeroes.\n", - name); - return AVERROR_INVALIDDATA; - } - v = 1; - for(j = 0; j < i; j++) { - k = get_bits1(gbc); - bits[i + j + 1] = k ? '1' : '0'; - v = v << 1 | k; - } - bits[i + j + 1] = 0; - if(v & 1) - value = -(int32_t)(v / 2); - else - value = v / 2; - - if(ctx->trace_enable) - ff_cbs_trace_syntax_element(ctx, position, name, subscripts, - bits, value); - - if(value < range_min || value > range_max) { - av_log(ctx->log_ctx, AV_LOG_ERROR, "%s out of range: " - "%" PRId32 ", but must be in [%" PRId32 ",%" PRId32 "].\n", - name, value, range_min, range_max); - return AVERROR_INVALIDDATA; - } - - *write_to = value; - return 0; -} - -static int cbs_write_ue_golomb(CodedBitstreamContext *ctx, PutBitContext *pbc, - const char *name, const int *subscripts, - uint32_t value, - uint32_t range_min, uint32_t range_max) { - int len; - - if(value < range_min || value > range_max) { - av_log(ctx->log_ctx, AV_LOG_ERROR, "%s out of range: " - "%" PRIu32 ", but must be in [%" PRIu32 ",%" PRIu32 "].\n", - name, value, range_min, range_max); - return AVERROR_INVALIDDATA; - } - av_assert0(value != UINT32_MAX); - - len = av_log2(value + 1); - if(put_bits_left(pbc) < 2 * len + 1) - return AVERROR(ENOSPC); - - if(ctx->trace_enable) { - char bits[65]; - int i; - - for(i = 0; i < len; i++) - bits[i] = '0'; - bits[len] = '1'; - for(i = 0; i < len; i++) - bits[len + i + 1] = (value + 1) >> (len - i - 1) & 1 ? '1' : '0'; - bits[len + len + 1] = 0; - - ff_cbs_trace_syntax_element(ctx, put_bits_count(pbc), - name, subscripts, bits, value); - } - - put_bits(pbc, len, 0); - if(len + 1 < 32) - put_bits(pbc, len + 1, value + 1); - else - put_bits32(pbc, value + 1); - - return 0; -} - -static int cbs_write_se_golomb(CodedBitstreamContext *ctx, PutBitContext *pbc, - const char *name, const int *subscripts, - int32_t value, - int32_t range_min, int32_t range_max) { - int len; - uint32_t uvalue; - - if(value < range_min || value > range_max) { - av_log(ctx->log_ctx, AV_LOG_ERROR, "%s out of range: " - "%" PRId32 ", but must be in [%" PRId32 ",%" PRId32 "].\n", - name, value, range_min, range_max); - return AVERROR_INVALIDDATA; - } - av_assert0(value != INT32_MIN); - - if(value == 0) - uvalue = 0; - else if(value > 0) - uvalue = 2 * (uint32_t)value - 1; - else - uvalue = 2 * (uint32_t)-value; - - len = av_log2(uvalue + 1); - if(put_bits_left(pbc) < 2 * len + 1) - return AVERROR(ENOSPC); - - if(ctx->trace_enable) { - char bits[65]; - int i; - - for(i = 0; i < len; i++) - bits[i] = '0'; - bits[len] = '1'; - for(i = 0; i < len; i++) - bits[len + i + 1] = (uvalue + 1) >> (len - i - 1) & 1 ? '1' : '0'; - bits[len + len + 1] = 0; - - ff_cbs_trace_syntax_element(ctx, put_bits_count(pbc), - name, subscripts, bits, value); - } - - put_bits(pbc, len, 0); - if(len + 1 < 32) - put_bits(pbc, len + 1, uvalue + 1); - else - put_bits32(pbc, uvalue + 1); - - return 0; -} - -// payload_extension_present() - true if we are before the last 1-bit -// in the payload structure, which must be in the last byte. -static int cbs_h265_payload_extension_present(GetBitContext *gbc, uint32_t payload_size, - int cur_pos) { - int bits_left = payload_size * 8 - cur_pos; - return (bits_left > 0 && - (bits_left > 7 || show_bits(gbc, bits_left) & MAX_UINT_BITS(bits_left - 1))); -} - -#define HEADER(name) \ - do { \ - ff_cbs_trace_header(ctx, name); \ - } while(0) - -#define CHECK(call) \ - do { \ - err = (call); \ - if(err < 0) \ - return err; \ - } while(0) - -#define FUNC_NAME2(rw, codec, name) cbs_##codec##_##rw##_##name -#define FUNC_NAME1(rw, codec, name) FUNC_NAME2(rw, codec, name) -#define FUNC_H264(name) FUNC_NAME1(READWRITE, h264, name) -#define FUNC_H265(name) FUNC_NAME1(READWRITE, h265, name) -#define FUNC_SEI(name) FUNC_NAME1(READWRITE, sei, name) - -#define SUBSCRIPTS(subs, ...) (subs > 0 ? ((int[subs + 1]) { subs, __VA_ARGS__ }) : NULL) - -#define u(width, name, range_min, range_max) \ - xu(width, name, current->name, range_min, range_max, 0, ) -#define ub(width, name) \ - xu(width, name, current->name, 0, MAX_UINT_BITS(width), 0, ) -#define flag(name) ub(1, name) -#define ue(name, range_min, range_max) \ - xue(name, current->name, range_min, range_max, 0, ) -#define i(width, name, range_min, range_max) \ - xi(width, name, current->name, range_min, range_max, 0, ) -#define ib(width, name) \ - xi(width, name, current->name, MIN_INT_BITS(width), MAX_INT_BITS(width), 0, ) -#define se(name, range_min, range_max) \ - xse(name, current->name, range_min, range_max, 0, ) - -#define us(width, name, range_min, range_max, subs, ...) \ - xu(width, name, current->name, range_min, range_max, subs, __VA_ARGS__) -#define ubs(width, name, subs, ...) \ - xu(width, name, current->name, 0, MAX_UINT_BITS(width), subs, __VA_ARGS__) -#define flags(name, subs, ...) \ - xu(1, name, current->name, 0, 1, subs, __VA_ARGS__) -#define ues(name, range_min, range_max, subs, ...) \ - xue(name, current->name, range_min, range_max, subs, __VA_ARGS__) -#define is(width, name, range_min, range_max, subs, ...) \ - xi(width, name, current->name, range_min, range_max, subs, __VA_ARGS__) -#define ibs(width, name, subs, ...) \ - xi(width, name, current->name, MIN_INT_BITS(width), MAX_INT_BITS(width), subs, __VA_ARGS__) -#define ses(name, range_min, range_max, subs, ...) \ - xse(name, current->name, range_min, range_max, subs, __VA_ARGS__) - -#define fixed(width, name, value) \ - do { \ - av_unused uint32_t fixed_value = value; \ - xu(width, name, fixed_value, value, value, 0, ); \ - } while(0) - - -#define READ -#define READWRITE read -#define RWContext GetBitContext - -#define xu(width, name, var, range_min, range_max, subs, ...) \ - do { \ - uint32_t value; \ - CHECK(ff_cbs_read_unsigned(ctx, rw, width, #name, \ - SUBSCRIPTS(subs, __VA_ARGS__), \ - &value, range_min, range_max)); \ - var = value; \ - } while(0) -#define xue(name, var, range_min, range_max, subs, ...) \ - do { \ - uint32_t value; \ - CHECK(cbs_read_ue_golomb(ctx, rw, #name, \ - SUBSCRIPTS(subs, __VA_ARGS__), \ - &value, range_min, range_max)); \ - var = value; \ - } while(0) -#define xi(width, name, var, range_min, range_max, subs, ...) \ - do { \ - int32_t value; \ - CHECK(ff_cbs_read_signed(ctx, rw, width, #name, \ - SUBSCRIPTS(subs, __VA_ARGS__), \ - &value, range_min, range_max)); \ - var = value; \ - } while(0) -#define xse(name, var, range_min, range_max, subs, ...) \ - do { \ - int32_t value; \ - CHECK(cbs_read_se_golomb(ctx, rw, #name, \ - SUBSCRIPTS(subs, __VA_ARGS__), \ - &value, range_min, range_max)); \ - var = value; \ - } while(0) - - -#define infer(name, value) \ - do { \ - current->name = value; \ - } while(0) - -static int cbs_h2645_read_more_rbsp_data(GetBitContext *gbc) { - int bits_left = get_bits_left(gbc); - if(bits_left > 8) - return 1; - if(bits_left == 0) - return 0; - if(show_bits(gbc, bits_left) & MAX_UINT_BITS(bits_left - 1)) - return 1; - return 0; -} - -#define more_rbsp_data(var) ((var) = cbs_h2645_read_more_rbsp_data(rw)) - -#define bit_position(rw) (get_bits_count(rw)) -#define byte_alignment(rw) (get_bits_count(rw) % 8) - -#define allocate(name, size) \ - do { \ - name##_ref = av_buffer_allocz(size + \ - AV_INPUT_BUFFER_PADDING_SIZE); \ - if(!name##_ref) \ - return AVERROR(ENOMEM); \ - name = name##_ref->data; \ - } while(0) - -#define FUNC(name) FUNC_SEI(name) -#include "cbs_sei_syntax_template.c" -#undef FUNC - -#define FUNC(name) FUNC_H264(name) -#include "cbs_h264_syntax_template.c" -#undef FUNC - -#define FUNC(name) FUNC_H265(name) -#include "cbs_h265_syntax_template.c" -#undef FUNC - -#undef READ -#undef READWRITE -#undef RWContext -#undef xu -#undef xi -#undef xue -#undef xse -#undef infer -#undef more_rbsp_data -#undef bit_position -#undef byte_alignment -#undef allocate - - -#define WRITE -#define READWRITE write -#define RWContext PutBitContext - -#define xu(width, name, var, range_min, range_max, subs, ...) \ - do { \ - uint32_t value = var; \ - CHECK(ff_cbs_write_unsigned(ctx, rw, width, #name, \ - SUBSCRIPTS(subs, __VA_ARGS__), \ - value, range_min, range_max)); \ - } while(0) -#define xue(name, var, range_min, range_max, subs, ...) \ - do { \ - uint32_t value = var; \ - CHECK(cbs_write_ue_golomb(ctx, rw, #name, \ - SUBSCRIPTS(subs, __VA_ARGS__), \ - value, range_min, range_max)); \ - } while(0) -#define xi(width, name, var, range_min, range_max, subs, ...) \ - do { \ - int32_t value = var; \ - CHECK(ff_cbs_write_signed(ctx, rw, width, #name, \ - SUBSCRIPTS(subs, __VA_ARGS__), \ - value, range_min, range_max)); \ - } while(0) -#define xse(name, var, range_min, range_max, subs, ...) \ - do { \ - int32_t value = var; \ - CHECK(cbs_write_se_golomb(ctx, rw, #name, \ - SUBSCRIPTS(subs, __VA_ARGS__), \ - value, range_min, range_max)); \ - } while(0) - -#define infer(name, value) \ - do { \ - if(current->name != (value)) { \ - av_log(ctx->log_ctx, AV_LOG_ERROR, \ - "%s does not match inferred value: " \ - "%" PRId64 ", but should be %" PRId64 ".\n", \ - #name, (int64_t)current->name, (int64_t)(value)); \ - return AVERROR_INVALIDDATA; \ - } \ - } while(0) - -#define more_rbsp_data(var) (var) - -#define bit_position(rw) (put_bits_count(rw)) -#define byte_alignment(rw) (put_bits_count(rw) % 8) - -#define allocate(name, size) \ - do { \ - if(!name) { \ - av_log(ctx->log_ctx, AV_LOG_ERROR, "%s must be set " \ - "for writing.\n", \ - #name); \ - return AVERROR_INVALIDDATA; \ - } \ - } while(0) - -#define FUNC(name) FUNC_SEI(name) -#include "cbs_sei_syntax_template.c" -#undef FUNC - -#define FUNC(name) FUNC_H264(name) -#include "cbs_h264_syntax_template.c" -#undef FUNC - -#define FUNC(name) FUNC_H265(name) -#include "cbs_h265_syntax_template.c" -#undef FUNC - -#undef WRITE -#undef READWRITE -#undef RWContext -#undef xu -#undef xi -#undef xue -#undef xse -#undef u -#undef i -#undef flag -#undef ue -#undef se -#undef infer -#undef more_rbsp_data -#undef bit_position -#undef byte_alignment -#undef allocate - - -static int cbs_h2645_fragment_add_nals(CodedBitstreamContext *ctx, - CodedBitstreamFragment *frag, - const H2645Packet *packet) { - int err, i; - - for(i = 0; i < packet->nb_nals; i++) { - const H2645NAL *nal = &packet->nals[i]; - AVBufferRef *ref; - size_t size = nal->size; - - if(nal->nuh_layer_id > 0) - continue; - - // Remove trailing zeroes. - while(size > 0 && nal->data[size - 1] == 0) - --size; - if(size == 0) { - av_log(ctx->log_ctx, AV_LOG_VERBOSE, "Discarding empty 0 NAL unit\n"); - continue; - } - - ref = (nal->data == nal->raw_data) ? frag->data_ref : packet->rbsp.rbsp_buffer_ref; - - err = ff_cbs_insert_unit_data(frag, -1, nal->type, - (uint8_t *)nal->data, size, ref); - if(err < 0) - return err; - } - - return 0; -} - -static int cbs_h2645_split_fragment(CodedBitstreamContext *ctx, - CodedBitstreamFragment *frag, - int header) { - enum AVCodecID codec_id = ctx->codec->codec_id; - CodedBitstreamH2645Context *priv = ctx->priv_data; - GetByteContext gbc; - int err; - - av_assert0(frag->data && frag->nb_units == 0); - if(frag->data_size == 0) - return 0; - - if(header && frag->data[0] && codec_id == AV_CODEC_ID_H264) { - // AVCC header. - size_t size, start, end; - int i, count, version; - - priv->mp4 = 1; - - bytestream2_init(&gbc, frag->data, frag->data_size); - - if(bytestream2_get_bytes_left(&gbc) < 6) - return AVERROR_INVALIDDATA; - - version = bytestream2_get_byte(&gbc); - if(version != 1) { - av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid AVCC header: " - "first byte %u.\n", - version); - return AVERROR_INVALIDDATA; - } - - bytestream2_skip(&gbc, 3); - priv->nal_length_size = (bytestream2_get_byte(&gbc) & 3) + 1; - - // SPS array. - count = bytestream2_get_byte(&gbc) & 0x1f; - start = bytestream2_tell(&gbc); - for(i = 0; i < count; i++) { - if(bytestream2_get_bytes_left(&gbc) < 2 * (count - i)) - return AVERROR_INVALIDDATA; - size = bytestream2_get_be16(&gbc); - if(bytestream2_get_bytes_left(&gbc) < size) - return AVERROR_INVALIDDATA; - bytestream2_skip(&gbc, size); - } - end = bytestream2_tell(&gbc); - - err = ff_h2645_packet_split(&priv->read_packet, - frag->data + start, end - start, - ctx->log_ctx, 1, 2, AV_CODEC_ID_H264, 1, 1); - if(err < 0) { - av_log(ctx->log_ctx, AV_LOG_ERROR, "Failed to split AVCC SPS array.\n"); - return err; - } - err = cbs_h2645_fragment_add_nals(ctx, frag, &priv->read_packet); - if(err < 0) - return err; - - // PPS array. - count = bytestream2_get_byte(&gbc); - start = bytestream2_tell(&gbc); - for(i = 0; i < count; i++) { - if(bytestream2_get_bytes_left(&gbc) < 2 * (count - i)) - return AVERROR_INVALIDDATA; - size = bytestream2_get_be16(&gbc); - if(bytestream2_get_bytes_left(&gbc) < size) - return AVERROR_INVALIDDATA; - bytestream2_skip(&gbc, size); - } - end = bytestream2_tell(&gbc); - - err = ff_h2645_packet_split(&priv->read_packet, - frag->data + start, end - start, - ctx->log_ctx, 1, 2, AV_CODEC_ID_H264, 1, 1); - if(err < 0) { - av_log(ctx->log_ctx, AV_LOG_ERROR, "Failed to split AVCC PPS array.\n"); - return err; - } - err = cbs_h2645_fragment_add_nals(ctx, frag, &priv->read_packet); - if(err < 0) - return err; - - if(bytestream2_get_bytes_left(&gbc) > 0) { - av_log(ctx->log_ctx, AV_LOG_WARNING, "%u bytes left at end of AVCC " - "header.\n", - bytestream2_get_bytes_left(&gbc)); - } - } - else if(header && frag->data[0] && codec_id == AV_CODEC_ID_HEVC) { - // HVCC header. - size_t size, start, end; - int i, j, nb_arrays, nal_unit_type, nb_nals, version; - - priv->mp4 = 1; - - bytestream2_init(&gbc, frag->data, frag->data_size); - - if(bytestream2_get_bytes_left(&gbc) < 23) - return AVERROR_INVALIDDATA; - - version = bytestream2_get_byte(&gbc); - if(version != 1) { - av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid HVCC header: " - "first byte %u.\n", - version); - return AVERROR_INVALIDDATA; - } - - bytestream2_skip(&gbc, 20); - priv->nal_length_size = (bytestream2_get_byte(&gbc) & 3) + 1; - - nb_arrays = bytestream2_get_byte(&gbc); - for(i = 0; i < nb_arrays; i++) { - nal_unit_type = bytestream2_get_byte(&gbc) & 0x3f; - nb_nals = bytestream2_get_be16(&gbc); - - start = bytestream2_tell(&gbc); - for(j = 0; j < nb_nals; j++) { - if(bytestream2_get_bytes_left(&gbc) < 2) - return AVERROR_INVALIDDATA; - size = bytestream2_get_be16(&gbc); - if(bytestream2_get_bytes_left(&gbc) < size) - return AVERROR_INVALIDDATA; - bytestream2_skip(&gbc, size); - } - end = bytestream2_tell(&gbc); - - err = ff_h2645_packet_split(&priv->read_packet, - frag->data + start, end - start, - ctx->log_ctx, 1, 2, AV_CODEC_ID_HEVC, 1, 1); - if(err < 0) { - av_log(ctx->log_ctx, AV_LOG_ERROR, "Failed to split " - "HVCC array %d (%d NAL units of type %d).\n", - i, nb_nals, nal_unit_type); - return err; - } - err = cbs_h2645_fragment_add_nals(ctx, frag, &priv->read_packet); - if(err < 0) - return err; - } - } - else { - // Annex B, or later MP4 with already-known parameters. - - err = ff_h2645_packet_split(&priv->read_packet, - frag->data, frag->data_size, - ctx->log_ctx, - priv->mp4, priv->nal_length_size, - codec_id, 1, 1); - if(err < 0) - return err; - - err = cbs_h2645_fragment_add_nals(ctx, frag, &priv->read_packet); - if(err < 0) - return err; - } - - return 0; -} - -#define cbs_h2645_replace_ps(h26n, ps_name, ps_var, id_element) \ - static int cbs_h26##h26n##_replace_##ps_var(CodedBitstreamContext *ctx, \ - CodedBitstreamUnit *unit) { \ - CodedBitstreamH26##h26n##Context *priv = ctx->priv_data; \ - H26##h26n##Raw##ps_name *ps_var = unit->content; \ - unsigned int id = ps_var->id_element; \ - int err; \ - if(id >= FF_ARRAY_ELEMS(priv->ps_var)) { \ - av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid " #ps_name " id : %d.\n", id); \ - return AVERROR_INVALIDDATA; \ - } \ - err = ff_cbs_make_unit_refcounted(ctx, unit); \ - if(err < 0) \ - return err; \ - if(priv->ps_var[id] == priv->active_##ps_var) \ - priv->active_##ps_var = NULL; \ - av_buffer_unref(&priv->ps_var##_ref[id]); \ - av_assert0(unit->content_ref); \ - priv->ps_var##_ref[id] = av_buffer_ref(unit->content_ref); \ - if(!priv->ps_var##_ref[id]) \ - return AVERROR(ENOMEM); \ - priv->ps_var[id] = (H26##h26n##Raw##ps_name *)priv->ps_var##_ref[id]->data; \ - return 0; \ - } - -cbs_h2645_replace_ps(4, SPS, sps, seq_parameter_set_id) - cbs_h2645_replace_ps(4, PPS, pps, pic_parameter_set_id) - cbs_h2645_replace_ps(5, VPS, vps, vps_video_parameter_set_id) - cbs_h2645_replace_ps(5, SPS, sps, sps_seq_parameter_set_id) - cbs_h2645_replace_ps(5, PPS, pps, pps_pic_parameter_set_id) - - static int cbs_h264_read_nal_unit(CodedBitstreamContext *ctx, - CodedBitstreamUnit *unit) { - GetBitContext gbc; - int err; - - err = init_get_bits(&gbc, unit->data, 8 * unit->data_size); - if(err < 0) - return err; - - err = ff_cbs_alloc_unit_content2(ctx, unit); - if(err < 0) - return err; - - switch(unit->type) { - case H264_NAL_SPS: { - H264RawSPS *sps = unit->content; - - err = cbs_h264_read_sps(ctx, &gbc, sps); - if(err < 0) - return err; - - err = cbs_h264_replace_sps(ctx, unit); - if(err < 0) - return err; - } break; - - case H264_NAL_SPS_EXT: { - err = cbs_h264_read_sps_extension(ctx, &gbc, unit->content); - if(err < 0) - return err; - } break; - - case H264_NAL_PPS: { - H264RawPPS *pps = unit->content; - - err = cbs_h264_read_pps(ctx, &gbc, pps); - if(err < 0) - return err; - - err = cbs_h264_replace_pps(ctx, unit); - if(err < 0) - return err; - } break; - - case H264_NAL_SLICE: - case H264_NAL_IDR_SLICE: - case H264_NAL_AUXILIARY_SLICE: { - H264RawSlice *slice = unit->content; - int pos, len; - - err = cbs_h264_read_slice_header(ctx, &gbc, &slice->header); - if(err < 0) - return err; - - if(!cbs_h2645_read_more_rbsp_data(&gbc)) - return AVERROR_INVALIDDATA; - - pos = get_bits_count(&gbc); - len = unit->data_size; - - slice->data_size = len - pos / 8; - slice->data_ref = av_buffer_ref(unit->data_ref); - if(!slice->data_ref) - return AVERROR(ENOMEM); - slice->data = unit->data + pos / 8; - slice->data_bit_start = pos % 8; - } break; - - case H264_NAL_AUD: { - err = cbs_h264_read_aud(ctx, &gbc, unit->content); - if(err < 0) - return err; - } break; - - case H264_NAL_SEI: { - err = cbs_h264_read_sei(ctx, &gbc, unit->content); - if(err < 0) - return err; - } break; - - case H264_NAL_FILLER_DATA: { - err = cbs_h264_read_filler(ctx, &gbc, unit->content); - if(err < 0) - return err; - } break; - - case H264_NAL_END_SEQUENCE: - case H264_NAL_END_STREAM: { - err = (unit->type == H264_NAL_END_SEQUENCE ? - cbs_h264_read_end_of_sequence : - cbs_h264_read_end_of_stream)(ctx, &gbc, unit->content); - if(err < 0) - return err; - } break; - - default: - return AVERROR(ENOSYS); - } - - return 0; -} - -static int cbs_h265_read_nal_unit(CodedBitstreamContext *ctx, - CodedBitstreamUnit *unit) { - GetBitContext gbc; - int err; - - err = init_get_bits(&gbc, unit->data, 8 * unit->data_size); - if(err < 0) - return err; - - err = ff_cbs_alloc_unit_content2(ctx, unit); - if(err < 0) - return err; - - switch(unit->type) { - case HEVC_NAL_VPS: { - H265RawVPS *vps = unit->content; - - err = cbs_h265_read_vps(ctx, &gbc, vps); - if(err < 0) - return err; - - err = cbs_h265_replace_vps(ctx, unit); - if(err < 0) - return err; - } break; - case HEVC_NAL_SPS: { - H265RawSPS *sps = unit->content; - - err = cbs_h265_read_sps(ctx, &gbc, sps); - if(err < 0) - return err; - - err = cbs_h265_replace_sps(ctx, unit); - if(err < 0) - return err; - } break; - - case HEVC_NAL_PPS: { - H265RawPPS *pps = unit->content; - - err = cbs_h265_read_pps(ctx, &gbc, pps); - if(err < 0) - return err; - - err = cbs_h265_replace_pps(ctx, unit); - if(err < 0) - return err; - } break; - - case HEVC_NAL_TRAIL_N: - case HEVC_NAL_TRAIL_R: - case HEVC_NAL_TSA_N: - case HEVC_NAL_TSA_R: - case HEVC_NAL_STSA_N: - case HEVC_NAL_STSA_R: - case HEVC_NAL_RADL_N: - case HEVC_NAL_RADL_R: - case HEVC_NAL_RASL_N: - case HEVC_NAL_RASL_R: - case HEVC_NAL_BLA_W_LP: - case HEVC_NAL_BLA_W_RADL: - case HEVC_NAL_BLA_N_LP: - case HEVC_NAL_IDR_W_RADL: - case HEVC_NAL_IDR_N_LP: - case HEVC_NAL_CRA_NUT: { - H265RawSlice *slice = unit->content; - int pos, len; - - err = cbs_h265_read_slice_segment_header(ctx, &gbc, &slice->header); - if(err < 0) - return err; - - if(!cbs_h2645_read_more_rbsp_data(&gbc)) - return AVERROR_INVALIDDATA; - - pos = get_bits_count(&gbc); - len = unit->data_size; - - slice->data_size = len - pos / 8; - slice->data_ref = av_buffer_ref(unit->data_ref); - if(!slice->data_ref) - return AVERROR(ENOMEM); - slice->data = unit->data + pos / 8; - slice->data_bit_start = pos % 8; - } break; - - case HEVC_NAL_AUD: { - err = cbs_h265_read_aud(ctx, &gbc, unit->content); - if(err < 0) - return err; - } break; - - case HEVC_NAL_SEI_PREFIX: - case HEVC_NAL_SEI_SUFFIX: { - err = cbs_h265_read_sei(ctx, &gbc, unit->content, - unit->type == HEVC_NAL_SEI_PREFIX); - - if(err < 0) - return err; - } break; - - default: - return AVERROR(ENOSYS); - } - - return 0; -} - -static int cbs_h2645_write_slice_data(CodedBitstreamContext *ctx, - PutBitContext *pbc, const uint8_t *data, - size_t data_size, int data_bit_start) { - size_t rest = data_size - (data_bit_start + 7) / 8; - const uint8_t *pos = data + data_bit_start / 8; - - av_assert0(data_bit_start >= 0 && - data_size > data_bit_start / 8); - - if(data_size * 8 + 8 > put_bits_left(pbc)) - return AVERROR(ENOSPC); - - if(!rest) - goto rbsp_stop_one_bit; - - // First copy the remaining bits of the first byte - // The above check ensures that we do not accidentally - // copy beyond the rbsp_stop_one_bit. - if(data_bit_start % 8) - put_bits(pbc, 8 - data_bit_start % 8, - *pos++ & MAX_UINT_BITS(8 - data_bit_start % 8)); - - if(put_bits_count(pbc) % 8 == 0) { - // If the writer is aligned at this point, - // memcpy can be used to improve performance. - // This happens normally for CABAC. - flush_put_bits(pbc); - memcpy(put_bits_ptr(pbc), pos, rest); - skip_put_bytes(pbc, rest); - } - else { - // If not, we have to copy manually. - // rbsp_stop_one_bit forces us to special-case - // the last byte. - uint8_t temp; - int i; - - for(; rest > 4; rest -= 4, pos += 4) - put_bits32(pbc, AV_RB32(pos)); - - for(; rest > 1; rest--, pos++) - put_bits(pbc, 8, *pos); - - rbsp_stop_one_bit: - temp = rest ? *pos : *pos & MAX_UINT_BITS(8 - data_bit_start % 8); - - av_assert0(temp); - i = ff_ctz(*pos); - temp = temp >> i; - i = rest ? (8 - i) : (8 - i - data_bit_start % 8); - put_bits(pbc, i, temp); - if(put_bits_count(pbc) % 8) - put_bits(pbc, 8 - put_bits_count(pbc) % 8, 0); - } - - return 0; -} - -static int cbs_h264_write_nal_unit(CodedBitstreamContext *ctx, - CodedBitstreamUnit *unit, - PutBitContext *pbc) { - int err; - - switch(unit->type) { - case H264_NAL_SPS: { - H264RawSPS *sps = unit->content; - - err = cbs_h264_write_sps(ctx, pbc, sps); - if(err < 0) - return err; - - err = cbs_h264_replace_sps(ctx, unit); - if(err < 0) - return err; - } break; - - case H264_NAL_SPS_EXT: { - H264RawSPSExtension *sps_ext = unit->content; - - err = cbs_h264_write_sps_extension(ctx, pbc, sps_ext); - if(err < 0) - return err; - } break; - - case H264_NAL_PPS: { - H264RawPPS *pps = unit->content; - - err = cbs_h264_write_pps(ctx, pbc, pps); - if(err < 0) - return err; - - err = cbs_h264_replace_pps(ctx, unit); - if(err < 0) - return err; - } break; - - case H264_NAL_SLICE: - case H264_NAL_IDR_SLICE: - case H264_NAL_AUXILIARY_SLICE: { - H264RawSlice *slice = unit->content; - - err = cbs_h264_write_slice_header(ctx, pbc, &slice->header); - if(err < 0) - return err; - - if(slice->data) { - err = cbs_h2645_write_slice_data(ctx, pbc, slice->data, - slice->data_size, - slice->data_bit_start); - if(err < 0) - return err; - } - else { - // No slice data - that was just the header. - // (Bitstream may be unaligned!) - } - } break; - - case H264_NAL_AUD: { - err = cbs_h264_write_aud(ctx, pbc, unit->content); - if(err < 0) - return err; - } break; - - case H264_NAL_SEI: { - err = cbs_h264_write_sei(ctx, pbc, unit->content); - if(err < 0) - return err; - } break; - - case H264_NAL_FILLER_DATA: { - err = cbs_h264_write_filler(ctx, pbc, unit->content); - if(err < 0) - return err; - } break; - - case H264_NAL_END_SEQUENCE: { - err = cbs_h264_write_end_of_sequence(ctx, pbc, unit->content); - if(err < 0) - return err; - } break; - - case H264_NAL_END_STREAM: { - err = cbs_h264_write_end_of_stream(ctx, pbc, unit->content); - if(err < 0) - return err; - } break; - - default: - av_log(ctx->log_ctx, AV_LOG_ERROR, "Write unimplemented for " - "NAL unit type %" PRIu32 ".\n", - unit->type); - return AVERROR_PATCHWELCOME; - } - - return 0; -} - -static int cbs_h265_write_nal_unit(CodedBitstreamContext *ctx, - CodedBitstreamUnit *unit, - PutBitContext *pbc) { - int err; - - switch(unit->type) { - case HEVC_NAL_VPS: { - H265RawVPS *vps = unit->content; - - err = cbs_h265_write_vps(ctx, pbc, vps); - if(err < 0) - return err; - - err = cbs_h265_replace_vps(ctx, unit); - if(err < 0) - return err; - } break; - - case HEVC_NAL_SPS: { - H265RawSPS *sps = unit->content; - - err = cbs_h265_write_sps(ctx, pbc, sps); - if(err < 0) - return err; - - err = cbs_h265_replace_sps(ctx, unit); - if(err < 0) - return err; - } break; - - case HEVC_NAL_PPS: { - H265RawPPS *pps = unit->content; - - err = cbs_h265_write_pps(ctx, pbc, pps); - if(err < 0) - return err; - - err = cbs_h265_replace_pps(ctx, unit); - if(err < 0) - return err; - } break; - - case HEVC_NAL_TRAIL_N: - case HEVC_NAL_TRAIL_R: - case HEVC_NAL_TSA_N: - case HEVC_NAL_TSA_R: - case HEVC_NAL_STSA_N: - case HEVC_NAL_STSA_R: - case HEVC_NAL_RADL_N: - case HEVC_NAL_RADL_R: - case HEVC_NAL_RASL_N: - case HEVC_NAL_RASL_R: - case HEVC_NAL_BLA_W_LP: - case HEVC_NAL_BLA_W_RADL: - case HEVC_NAL_BLA_N_LP: - case HEVC_NAL_IDR_W_RADL: - case HEVC_NAL_IDR_N_LP: - case HEVC_NAL_CRA_NUT: { - H265RawSlice *slice = unit->content; - - err = cbs_h265_write_slice_segment_header(ctx, pbc, &slice->header); - if(err < 0) - return err; - - if(slice->data) { - err = cbs_h2645_write_slice_data(ctx, pbc, slice->data, - slice->data_size, - slice->data_bit_start); - if(err < 0) - return err; - } - else { - // No slice data - that was just the header. - } - } break; - - case HEVC_NAL_AUD: { - err = cbs_h265_write_aud(ctx, pbc, unit->content); - if(err < 0) - return err; - } break; - - case HEVC_NAL_SEI_PREFIX: - case HEVC_NAL_SEI_SUFFIX: { - err = cbs_h265_write_sei(ctx, pbc, unit->content, - unit->type == HEVC_NAL_SEI_PREFIX); - - if(err < 0) - return err; - } break; - - default: - av_log(ctx->log_ctx, AV_LOG_ERROR, "Write unimplemented for " - "NAL unit type %" PRIu32 ".\n", - unit->type); - return AVERROR_PATCHWELCOME; - } - - return 0; -} - -static int cbs_h2645_unit_requires_zero_byte(enum AVCodecID codec_id, - CodedBitstreamUnitType type, - int nal_unit_index) { - // Section B.1.2 in H.264, section B.2.2 in H.265. - if(nal_unit_index == 0) { - // Assume that this is the first NAL unit in an access unit. - return 1; - } - if(codec_id == AV_CODEC_ID_H264) - return type == H264_NAL_SPS || type == H264_NAL_PPS; - if(codec_id == AV_CODEC_ID_HEVC) - return type == HEVC_NAL_VPS || type == HEVC_NAL_SPS || type == HEVC_NAL_PPS; - return 0; -} - -static int cbs_h2645_assemble_fragment(CodedBitstreamContext *ctx, - CodedBitstreamFragment *frag) { - uint8_t *data; - size_t max_size, dp, sp; - int err, i, zero_run; - - for(i = 0; i < frag->nb_units; i++) { - // Data should already all have been written when we get here. - av_assert0(frag->units[i].data); - } - - max_size = 0; - for(i = 0; i < frag->nb_units; i++) { - // Start code + content with worst-case emulation prevention. - max_size += 4 + frag->units[i].data_size * 3 / 2; - } - - data = av_realloc(NULL, max_size + AV_INPUT_BUFFER_PADDING_SIZE); - if(!data) - return AVERROR(ENOMEM); - - dp = 0; - for(i = 0; i < frag->nb_units; i++) { - CodedBitstreamUnit *unit = &frag->units[i]; - - if(unit->data_bit_padding > 0) { - if(i < frag->nb_units - 1) - av_log(ctx->log_ctx, AV_LOG_WARNING, "Probably invalid " - "unaligned padding on non-final NAL unit.\n"); - else - frag->data_bit_padding = unit->data_bit_padding; - } - - if(cbs_h2645_unit_requires_zero_byte(ctx->codec->codec_id, unit->type, i)) { - // zero_byte - data[dp++] = 0; - } - // start_code_prefix_one_3bytes - data[dp++] = 0; - data[dp++] = 0; - data[dp++] = 1; - - zero_run = 0; - for(sp = 0; sp < unit->data_size; sp++) { - if(zero_run < 2) { - if(unit->data[sp] == 0) - ++zero_run; - else - zero_run = 0; - } - else { - if((unit->data[sp] & ~3) == 0) { - // emulation_prevention_three_byte - data[dp++] = 3; - } - zero_run = unit->data[sp] == 0; - } - data[dp++] = unit->data[sp]; - } - } - - av_assert0(dp <= max_size); - err = av_reallocp(&data, dp + AV_INPUT_BUFFER_PADDING_SIZE); - if(err) - return err; - memset(data + dp, 0, AV_INPUT_BUFFER_PADDING_SIZE); - - frag->data_ref = av_buffer_create(data, dp + AV_INPUT_BUFFER_PADDING_SIZE, - NULL, NULL, 0); - if(!frag->data_ref) { - av_freep(&data); - return AVERROR(ENOMEM); - } - - frag->data = data; - frag->data_size = dp; - - return 0; -} - -static void cbs_h264_flush(CodedBitstreamContext *ctx) { - CodedBitstreamH264Context *h264 = ctx->priv_data; - - for(int i = 0; i < FF_ARRAY_ELEMS(h264->sps); i++) { - av_buffer_unref(&h264->sps_ref[i]); - h264->sps[i] = NULL; - } - for(int i = 0; i < FF_ARRAY_ELEMS(h264->pps); i++) { - av_buffer_unref(&h264->pps_ref[i]); - h264->pps[i] = NULL; - } - - h264->active_sps = NULL; - h264->active_pps = NULL; - h264->last_slice_nal_unit_type = 0; -} - -static void cbs_h264_close(CodedBitstreamContext *ctx) { - CodedBitstreamH264Context *h264 = ctx->priv_data; - int i; - - ff_h2645_packet_uninit(&h264->common.read_packet); - - for(i = 0; i < FF_ARRAY_ELEMS(h264->sps); i++) - av_buffer_unref(&h264->sps_ref[i]); - for(i = 0; i < FF_ARRAY_ELEMS(h264->pps); i++) - av_buffer_unref(&h264->pps_ref[i]); -} - -static void cbs_h265_flush(CodedBitstreamContext *ctx) { - CodedBitstreamH265Context *h265 = ctx->priv_data; - - for(int i = 0; i < FF_ARRAY_ELEMS(h265->vps); i++) { - av_buffer_unref(&h265->vps_ref[i]); - h265->vps[i] = NULL; - } - for(int i = 0; i < FF_ARRAY_ELEMS(h265->sps); i++) { - av_buffer_unref(&h265->sps_ref[i]); - h265->sps[i] = NULL; - } - for(int i = 0; i < FF_ARRAY_ELEMS(h265->pps); i++) { - av_buffer_unref(&h265->pps_ref[i]); - h265->pps[i] = NULL; - } - - h265->active_vps = NULL; - h265->active_sps = NULL; - h265->active_pps = NULL; -} - -static void cbs_h265_close(CodedBitstreamContext *ctx) { - CodedBitstreamH265Context *h265 = ctx->priv_data; - int i; - - ff_h2645_packet_uninit(&h265->common.read_packet); - - for(i = 0; i < FF_ARRAY_ELEMS(h265->vps); i++) - av_buffer_unref(&h265->vps_ref[i]); - for(i = 0; i < FF_ARRAY_ELEMS(h265->sps); i++) - av_buffer_unref(&h265->sps_ref[i]); - for(i = 0; i < FF_ARRAY_ELEMS(h265->pps); i++) - av_buffer_unref(&h265->pps_ref[i]); -} - -static void cbs_h264_free_sei(void *opaque, uint8_t *content) { - H264RawSEI *sei = (H264RawSEI *)content; - ff_cbs_sei_free_message_list(&sei->message_list); - av_free(content); -} - -static const CodedBitstreamUnitTypeDescriptor cbs_h264_unit_types[] = { - CBS_UNIT_TYPE_POD(H264_NAL_SPS, H264RawSPS), - CBS_UNIT_TYPE_POD(H264_NAL_SPS_EXT, H264RawSPSExtension), - - CBS_UNIT_TYPE_INTERNAL_REF(H264_NAL_PPS, H264RawPPS, slice_group_id), - - { - .nb_unit_types = 3, - .unit_types = { - H264_NAL_IDR_SLICE, - H264_NAL_SLICE, - H264_NAL_AUXILIARY_SLICE, - }, - .content_type = CBS_CONTENT_TYPE_INTERNAL_REFS, - .content_size = sizeof(H264RawSlice), - .nb_ref_offsets = 1, - .ref_offsets = { offsetof(H264RawSlice, data) }, - }, - - CBS_UNIT_TYPE_POD(H264_NAL_AUD, H264RawAUD), CBS_UNIT_TYPE_POD(H264_NAL_FILLER_DATA, H264RawFiller), CBS_UNIT_TYPE_POD(H264_NAL_END_SEQUENCE, H264RawNALUnitHeader), CBS_UNIT_TYPE_POD(H264_NAL_END_STREAM, H264RawNALUnitHeader), - - CBS_UNIT_TYPE_COMPLEX(H264_NAL_SEI, H264RawSEI, &cbs_h264_free_sei), - - CBS_UNIT_TYPE_END_OF_LIST -}; - -static void cbs_h265_free_sei(void *opaque, uint8_t *content) { - H265RawSEI *sei = (H265RawSEI *)content; - ff_cbs_sei_free_message_list(&sei->message_list); - av_free(content); -} - -static const CodedBitstreamUnitTypeDescriptor cbs_h265_unit_types[] = { - CBS_UNIT_TYPE_INTERNAL_REF(HEVC_NAL_VPS, H265RawVPS, extension_data.data), - CBS_UNIT_TYPE_INTERNAL_REF(HEVC_NAL_SPS, H265RawSPS, extension_data.data), - CBS_UNIT_TYPE_INTERNAL_REF(HEVC_NAL_PPS, H265RawPPS, extension_data.data), - - CBS_UNIT_TYPE_POD(HEVC_NAL_AUD, H265RawAUD), - - { - // Slices of non-IRAP pictures. - .nb_unit_types = CBS_UNIT_TYPE_RANGE, - .unit_type_range_start = HEVC_NAL_TRAIL_N, - .unit_type_range_end = HEVC_NAL_RASL_R, - - .content_type = CBS_CONTENT_TYPE_INTERNAL_REFS, - .content_size = sizeof(H265RawSlice), - .nb_ref_offsets = 1, - .ref_offsets = { offsetof(H265RawSlice, data) }, - }, - - { - // Slices of IRAP pictures. - .nb_unit_types = CBS_UNIT_TYPE_RANGE, - .unit_type_range_start = HEVC_NAL_BLA_W_LP, - .unit_type_range_end = HEVC_NAL_CRA_NUT, - - .content_type = CBS_CONTENT_TYPE_INTERNAL_REFS, - .content_size = sizeof(H265RawSlice), - .nb_ref_offsets = 1, - .ref_offsets = { offsetof(H265RawSlice, data) }, - }, - - { - .nb_unit_types = 2, - .unit_types = { - HEVC_NAL_SEI_PREFIX, - HEVC_NAL_SEI_SUFFIX }, - .content_type = CBS_CONTENT_TYPE_COMPLEX, - .content_size = sizeof(H265RawSEI), - .content_free = &cbs_h265_free_sei, - }, - - CBS_UNIT_TYPE_END_OF_LIST -}; - -const CodedBitstreamType ff_cbs_type_h264 = { - .codec_id = AV_CODEC_ID_H264, - - .priv_data_size = sizeof(CodedBitstreamH264Context), - - .unit_types = cbs_h264_unit_types, - - .split_fragment = &cbs_h2645_split_fragment, - .read_unit = &cbs_h264_read_nal_unit, - .write_unit = &cbs_h264_write_nal_unit, - .assemble_fragment = &cbs_h2645_assemble_fragment, - - .flush = &cbs_h264_flush, - .close = &cbs_h264_close, -}; - -const CodedBitstreamType ff_cbs_type_h265 = { - .codec_id = AV_CODEC_ID_HEVC, - - .priv_data_size = sizeof(CodedBitstreamH265Context), - - .unit_types = cbs_h265_unit_types, - - .split_fragment = &cbs_h2645_split_fragment, - .read_unit = &cbs_h265_read_nal_unit, - .write_unit = &cbs_h265_write_nal_unit, - .assemble_fragment = &cbs_h2645_assemble_fragment, - - .flush = &cbs_h265_flush, - .close = &cbs_h265_close, -}; - -static const SEIMessageTypeDescriptor cbs_sei_common_types[] = { - { - SEI_TYPE_FILLER_PAYLOAD, - 1, - 1, - sizeof(SEIRawFillerPayload), - SEI_MESSAGE_RW(sei, filler_payload), - }, - { - SEI_TYPE_USER_DATA_REGISTERED_ITU_T_T35, - 1, - 1, - sizeof(SEIRawUserDataRegistered), - SEI_MESSAGE_RW(sei, user_data_registered), - }, - { - SEI_TYPE_USER_DATA_UNREGISTERED, - 1, - 1, - sizeof(SEIRawUserDataUnregistered), - SEI_MESSAGE_RW(sei, user_data_unregistered), - }, - { - SEI_TYPE_MASTERING_DISPLAY_COLOUR_VOLUME, - 1, - 0, - sizeof(SEIRawMasteringDisplayColourVolume), - SEI_MESSAGE_RW(sei, mastering_display_colour_volume), - }, - { - SEI_TYPE_CONTENT_LIGHT_LEVEL_INFO, - 1, - 0, - sizeof(SEIRawContentLightLevelInfo), - SEI_MESSAGE_RW(sei, content_light_level_info), - }, - { - SEI_TYPE_ALTERNATIVE_TRANSFER_CHARACTERISTICS, - 1, - 0, - sizeof(SEIRawAlternativeTransferCharacteristics), - SEI_MESSAGE_RW(sei, alternative_transfer_characteristics), - }, - SEI_MESSAGE_TYPE_END, -}; - -static const SEIMessageTypeDescriptor cbs_sei_h264_types[] = { - { - SEI_TYPE_BUFFERING_PERIOD, - 1, - 0, - sizeof(H264RawSEIBufferingPeriod), - SEI_MESSAGE_RW(h264, sei_buffering_period), - }, - { - SEI_TYPE_PIC_TIMING, - 1, - 0, - sizeof(H264RawSEIPicTiming), - SEI_MESSAGE_RW(h264, sei_pic_timing), - }, - { - SEI_TYPE_PAN_SCAN_RECT, - 1, - 0, - sizeof(H264RawSEIPanScanRect), - SEI_MESSAGE_RW(h264, sei_pan_scan_rect), - }, - { - SEI_TYPE_RECOVERY_POINT, - 1, - 0, - sizeof(H264RawSEIRecoveryPoint), - SEI_MESSAGE_RW(h264, sei_recovery_point), - }, - { - SEI_TYPE_DISPLAY_ORIENTATION, - 1, - 0, - sizeof(H264RawSEIDisplayOrientation), - SEI_MESSAGE_RW(h264, sei_display_orientation), - }, - SEI_MESSAGE_TYPE_END -}; - -static const SEIMessageTypeDescriptor cbs_sei_h265_types[] = { - { - SEI_TYPE_BUFFERING_PERIOD, - 1, - 0, - sizeof(H265RawSEIBufferingPeriod), - SEI_MESSAGE_RW(h265, sei_buffering_period), - }, - { - SEI_TYPE_PIC_TIMING, - 1, - 0, - sizeof(H265RawSEIPicTiming), - SEI_MESSAGE_RW(h265, sei_pic_timing), - }, - { - SEI_TYPE_PAN_SCAN_RECT, - 1, - 0, - sizeof(H265RawSEIPanScanRect), - SEI_MESSAGE_RW(h265, sei_pan_scan_rect), - }, - { - SEI_TYPE_RECOVERY_POINT, - 1, - 0, - sizeof(H265RawSEIRecoveryPoint), - SEI_MESSAGE_RW(h265, sei_recovery_point), - }, - { - SEI_TYPE_DISPLAY_ORIENTATION, - 1, - 0, - sizeof(H265RawSEIDisplayOrientation), - SEI_MESSAGE_RW(h265, sei_display_orientation), - }, - { - SEI_TYPE_ACTIVE_PARAMETER_SETS, - 1, - 0, - sizeof(H265RawSEIActiveParameterSets), - SEI_MESSAGE_RW(h265, sei_active_parameter_sets), - }, - { - SEI_TYPE_DECODED_PICTURE_HASH, - 0, - 1, - sizeof(H265RawSEIDecodedPictureHash), - SEI_MESSAGE_RW(h265, sei_decoded_picture_hash), - }, - { - SEI_TYPE_TIME_CODE, - 1, - 0, - sizeof(H265RawSEITimeCode), - SEI_MESSAGE_RW(h265, sei_time_code), - }, - { - SEI_TYPE_ALPHA_CHANNEL_INFO, - 1, - 0, - sizeof(H265RawSEIAlphaChannelInfo), - SEI_MESSAGE_RW(h265, sei_alpha_channel_info), - }, - SEI_MESSAGE_TYPE_END -}; - -const SEIMessageTypeDescriptor *ff_cbs_sei_find_type(CodedBitstreamContext *ctx, - int payload_type) { - const SEIMessageTypeDescriptor *codec_list; - int i; - - for(i = 0; cbs_sei_common_types[i].type >= 0; i++) { - if(cbs_sei_common_types[i].type == payload_type) - return &cbs_sei_common_types[i]; - } - - switch(ctx->codec->codec_id) { - case AV_CODEC_ID_H264: - codec_list = cbs_sei_h264_types; - break; - case AV_CODEC_ID_H265: - codec_list = cbs_sei_h265_types; - break; - default: - return NULL; - } - - for(i = 0; codec_list[i].type >= 0; i++) { - if(codec_list[i].type == payload_type) - return &codec_list[i]; - } - - return NULL; -} diff --git a/third-party/cbs/cbs_h264_syntax_template.c b/third-party/cbs/cbs_h264_syntax_template.c deleted file mode 100644 index a2d3735b424..00000000000 --- a/third-party/cbs/cbs_h264_syntax_template.c +++ /dev/null @@ -1,1175 +0,0 @@ -/* - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -static int FUNC(rbsp_trailing_bits)(CodedBitstreamContext *ctx, RWContext *rw) { - int err; - - fixed(1, rbsp_stop_one_bit, 1); - while(byte_alignment(rw) != 0) - fixed(1, rbsp_alignment_zero_bit, 0); - - return 0; -} - -static int FUNC(nal_unit_header)(CodedBitstreamContext *ctx, RWContext *rw, - H264RawNALUnitHeader *current, - uint32_t valid_type_mask) { - int err; - - fixed(1, forbidden_zero_bit, 0); - ub(2, nal_ref_idc); - ub(5, nal_unit_type); - - if(!(1 << current->nal_unit_type & valid_type_mask)) { - av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid NAL unit type %d.\n", - current->nal_unit_type); - return AVERROR_INVALIDDATA; - } - - if(current->nal_unit_type == 14 || - current->nal_unit_type == 20 || - current->nal_unit_type == 21) { - if(current->nal_unit_type != 21) - flag(svc_extension_flag); - else - flag(avc_3d_extension_flag); - - if(current->svc_extension_flag) { - av_log(ctx->log_ctx, AV_LOG_ERROR, "SVC not supported.\n"); - return AVERROR_PATCHWELCOME; - } - else if(current->avc_3d_extension_flag) { - av_log(ctx->log_ctx, AV_LOG_ERROR, "3DAVC not supported.\n"); - return AVERROR_PATCHWELCOME; - } - else { - av_log(ctx->log_ctx, AV_LOG_ERROR, "MVC not supported.\n"); - return AVERROR_PATCHWELCOME; - } - } - - return 0; -} - -static int FUNC(scaling_list)(CodedBitstreamContext *ctx, RWContext *rw, - H264RawScalingList *current, - int size_of_scaling_list) { - int err, i, scale; - - scale = 8; - for(i = 0; i < size_of_scaling_list; i++) { - ses(delta_scale[i], -128, +127, 1, i); - scale = (scale + current->delta_scale[i] + 256) % 256; - if(scale == 0) - break; - } - - return 0; -} - -static int FUNC(hrd_parameters)(CodedBitstreamContext *ctx, RWContext *rw, - H264RawHRD *current) { - int err, i; - - ue(cpb_cnt_minus1, 0, 31); - ub(4, bit_rate_scale); - ub(4, cpb_size_scale); - - for(i = 0; i <= current->cpb_cnt_minus1; i++) { - ues(bit_rate_value_minus1[i], 0, UINT32_MAX - 1, 1, i); - ues(cpb_size_value_minus1[i], 0, UINT32_MAX - 1, 1, i); - flags(cbr_flag[i], 1, i); - } - - ub(5, initial_cpb_removal_delay_length_minus1); - ub(5, cpb_removal_delay_length_minus1); - ub(5, dpb_output_delay_length_minus1); - ub(5, time_offset_length); - - return 0; -} - -static int FUNC(vui_parameters)(CodedBitstreamContext *ctx, RWContext *rw, - H264RawVUI *current, H264RawSPS *sps) { - int err; - - flag(aspect_ratio_info_present_flag); - if(current->aspect_ratio_info_present_flag) { - ub(8, aspect_ratio_idc); - if(current->aspect_ratio_idc == 255) { - ub(16, sar_width); - ub(16, sar_height); - } - } - else { - infer(aspect_ratio_idc, 0); - } - - flag(overscan_info_present_flag); - if(current->overscan_info_present_flag) - flag(overscan_appropriate_flag); - - flag(video_signal_type_present_flag); - if(current->video_signal_type_present_flag) { - ub(3, video_format); - flag(video_full_range_flag); - flag(colour_description_present_flag); - if(current->colour_description_present_flag) { - ub(8, colour_primaries); - ub(8, transfer_characteristics); - ub(8, matrix_coefficients); - } - else { - infer(colour_primaries, 2); - infer(transfer_characteristics, 2); - infer(matrix_coefficients, 2); - } - } - else { - infer(video_format, 5); - infer(video_full_range_flag, 0); - infer(colour_primaries, 2); - infer(transfer_characteristics, 2); - infer(matrix_coefficients, 2); - } - - flag(chroma_loc_info_present_flag); - if(current->chroma_loc_info_present_flag) { - ue(chroma_sample_loc_type_top_field, 0, 5); - ue(chroma_sample_loc_type_bottom_field, 0, 5); - } - else { - infer(chroma_sample_loc_type_top_field, 0); - infer(chroma_sample_loc_type_bottom_field, 0); - } - - flag(timing_info_present_flag); - if(current->timing_info_present_flag) { - u(32, num_units_in_tick, 1, UINT32_MAX); - u(32, time_scale, 1, UINT32_MAX); - flag(fixed_frame_rate_flag); - } - else { - infer(fixed_frame_rate_flag, 0); - } - - flag(nal_hrd_parameters_present_flag); - if(current->nal_hrd_parameters_present_flag) - CHECK(FUNC(hrd_parameters)(ctx, rw, ¤t->nal_hrd_parameters)); - - flag(vcl_hrd_parameters_present_flag); - if(current->vcl_hrd_parameters_present_flag) - CHECK(FUNC(hrd_parameters)(ctx, rw, ¤t->vcl_hrd_parameters)); - - if(current->nal_hrd_parameters_present_flag || - current->vcl_hrd_parameters_present_flag) - flag(low_delay_hrd_flag); - else - infer(low_delay_hrd_flag, 1 - current->fixed_frame_rate_flag); - - flag(pic_struct_present_flag); - - flag(bitstream_restriction_flag); - if(current->bitstream_restriction_flag) { - flag(motion_vectors_over_pic_boundaries_flag); - ue(max_bytes_per_pic_denom, 0, 16); - ue(max_bits_per_mb_denom, 0, 16); - // The current version of the standard constrains this to be in - // [0,15], but older versions allow 16. - ue(log2_max_mv_length_horizontal, 0, 16); - ue(log2_max_mv_length_vertical, 0, 16); - ue(max_num_reorder_frames, 0, H264_MAX_DPB_FRAMES); - ue(max_dec_frame_buffering, 0, H264_MAX_DPB_FRAMES); - } - else { - infer(motion_vectors_over_pic_boundaries_flag, 1); - infer(max_bytes_per_pic_denom, 2); - infer(max_bits_per_mb_denom, 1); - infer(log2_max_mv_length_horizontal, 15); - infer(log2_max_mv_length_vertical, 15); - - if((sps->profile_idc == 44 || sps->profile_idc == 86 || - sps->profile_idc == 100 || sps->profile_idc == 110 || - sps->profile_idc == 122 || sps->profile_idc == 244) && - sps->constraint_set3_flag) { - infer(max_num_reorder_frames, 0); - infer(max_dec_frame_buffering, 0); - } - else { - infer(max_num_reorder_frames, H264_MAX_DPB_FRAMES); - infer(max_dec_frame_buffering, H264_MAX_DPB_FRAMES); - } - } - - return 0; -} - -static int FUNC(vui_parameters_default)(CodedBitstreamContext *ctx, - RWContext *rw, H264RawVUI *current, - H264RawSPS *sps) { - infer(aspect_ratio_idc, 0); - - infer(video_format, 5); - infer(video_full_range_flag, 0); - infer(colour_primaries, 2); - infer(transfer_characteristics, 2); - infer(matrix_coefficients, 2); - - infer(chroma_sample_loc_type_top_field, 0); - infer(chroma_sample_loc_type_bottom_field, 0); - - infer(fixed_frame_rate_flag, 0); - infer(low_delay_hrd_flag, 1); - - infer(pic_struct_present_flag, 0); - - infer(motion_vectors_over_pic_boundaries_flag, 1); - infer(max_bytes_per_pic_denom, 2); - infer(max_bits_per_mb_denom, 1); - infer(log2_max_mv_length_horizontal, 15); - infer(log2_max_mv_length_vertical, 15); - - if((sps->profile_idc == 44 || sps->profile_idc == 86 || - sps->profile_idc == 100 || sps->profile_idc == 110 || - sps->profile_idc == 122 || sps->profile_idc == 244) && - sps->constraint_set3_flag) { - infer(max_num_reorder_frames, 0); - infer(max_dec_frame_buffering, 0); - } - else { - infer(max_num_reorder_frames, H264_MAX_DPB_FRAMES); - infer(max_dec_frame_buffering, H264_MAX_DPB_FRAMES); - } - - return 0; -} - -static int FUNC(sps)(CodedBitstreamContext *ctx, RWContext *rw, - H264RawSPS *current) { - int err, i; - - HEADER("Sequence Parameter Set"); - - CHECK(FUNC(nal_unit_header)(ctx, rw, ¤t->nal_unit_header, - 1 << H264_NAL_SPS)); - - ub(8, profile_idc); - - flag(constraint_set0_flag); - flag(constraint_set1_flag); - flag(constraint_set2_flag); - flag(constraint_set3_flag); - flag(constraint_set4_flag); - flag(constraint_set5_flag); - - u(2, reserved_zero_2bits, 0, 0); - - ub(8, level_idc); - - ue(seq_parameter_set_id, 0, 31); - - if(current->profile_idc == 100 || current->profile_idc == 110 || - current->profile_idc == 122 || current->profile_idc == 244 || - current->profile_idc == 44 || current->profile_idc == 83 || - current->profile_idc == 86 || current->profile_idc == 118 || - current->profile_idc == 128 || current->profile_idc == 138) { - ue(chroma_format_idc, 0, 3); - - if(current->chroma_format_idc == 3) - flag(separate_colour_plane_flag); - else - infer(separate_colour_plane_flag, 0); - - ue(bit_depth_luma_minus8, 0, 6); - ue(bit_depth_chroma_minus8, 0, 6); - - flag(qpprime_y_zero_transform_bypass_flag); - - flag(seq_scaling_matrix_present_flag); - if(current->seq_scaling_matrix_present_flag) { - for(i = 0; i < ((current->chroma_format_idc != 3) ? 8 : 12); i++) { - flags(seq_scaling_list_present_flag[i], 1, i); - if(current->seq_scaling_list_present_flag[i]) { - if(i < 6) - CHECK(FUNC(scaling_list)(ctx, rw, - ¤t->scaling_list_4x4[i], - 16)); - else - CHECK(FUNC(scaling_list)(ctx, rw, - ¤t->scaling_list_8x8[i - 6], - 64)); - } - } - } - } - else { - infer(chroma_format_idc, current->profile_idc == 183 ? 0 : 1); - - infer(separate_colour_plane_flag, 0); - infer(bit_depth_luma_minus8, 0); - infer(bit_depth_chroma_minus8, 0); - } - - ue(log2_max_frame_num_minus4, 0, 12); - ue(pic_order_cnt_type, 0, 2); - - if(current->pic_order_cnt_type == 0) { - ue(log2_max_pic_order_cnt_lsb_minus4, 0, 12); - } - else if(current->pic_order_cnt_type == 1) { - flag(delta_pic_order_always_zero_flag); - se(offset_for_non_ref_pic, INT32_MIN + 1, INT32_MAX); - se(offset_for_top_to_bottom_field, INT32_MIN + 1, INT32_MAX); - ue(num_ref_frames_in_pic_order_cnt_cycle, 0, 255); - - for(i = 0; i < current->num_ref_frames_in_pic_order_cnt_cycle; i++) - ses(offset_for_ref_frame[i], INT32_MIN + 1, INT32_MAX, 1, i); - } - - ue(max_num_ref_frames, 0, H264_MAX_DPB_FRAMES); - flag(gaps_in_frame_num_allowed_flag); - - ue(pic_width_in_mbs_minus1, 0, H264_MAX_MB_WIDTH); - ue(pic_height_in_map_units_minus1, 0, H264_MAX_MB_HEIGHT); - - flag(frame_mbs_only_flag); - if(!current->frame_mbs_only_flag) - flag(mb_adaptive_frame_field_flag); - - flag(direct_8x8_inference_flag); - - flag(frame_cropping_flag); - if(current->frame_cropping_flag) { - ue(frame_crop_left_offset, 0, H264_MAX_WIDTH); - ue(frame_crop_right_offset, 0, H264_MAX_WIDTH); - ue(frame_crop_top_offset, 0, H264_MAX_HEIGHT); - ue(frame_crop_bottom_offset, 0, H264_MAX_HEIGHT); - } - - flag(vui_parameters_present_flag); - if(current->vui_parameters_present_flag) - CHECK(FUNC(vui_parameters)(ctx, rw, ¤t->vui, current)); - else - CHECK(FUNC(vui_parameters_default)(ctx, rw, ¤t->vui, current)); - - CHECK(FUNC(rbsp_trailing_bits)(ctx, rw)); - - return 0; -} - -static int FUNC(sps_extension)(CodedBitstreamContext *ctx, RWContext *rw, - H264RawSPSExtension *current) { - int err; - - HEADER("Sequence Parameter Set Extension"); - - CHECK(FUNC(nal_unit_header)(ctx, rw, ¤t->nal_unit_header, - 1 << H264_NAL_SPS_EXT)); - - ue(seq_parameter_set_id, 0, 31); - - ue(aux_format_idc, 0, 3); - - if(current->aux_format_idc != 0) { - int bits; - - ue(bit_depth_aux_minus8, 0, 4); - flag(alpha_incr_flag); - - bits = current->bit_depth_aux_minus8 + 9; - ub(bits, alpha_opaque_value); - ub(bits, alpha_transparent_value); - } - - flag(additional_extension_flag); - - CHECK(FUNC(rbsp_trailing_bits)(ctx, rw)); - - return 0; -} - -static int FUNC(pps)(CodedBitstreamContext *ctx, RWContext *rw, - H264RawPPS *current) { - CodedBitstreamH264Context *h264 = ctx->priv_data; - const H264RawSPS *sps; - int err, i; - - HEADER("Picture Parameter Set"); - - CHECK(FUNC(nal_unit_header)(ctx, rw, ¤t->nal_unit_header, - 1 << H264_NAL_PPS)); - - ue(pic_parameter_set_id, 0, 255); - ue(seq_parameter_set_id, 0, 31); - - sps = h264->sps[current->seq_parameter_set_id]; - if(!sps) { - av_log(ctx->log_ctx, AV_LOG_ERROR, "SPS id %d not available.\n", - current->seq_parameter_set_id); - return AVERROR_INVALIDDATA; - } - - flag(entropy_coding_mode_flag); - flag(bottom_field_pic_order_in_frame_present_flag); - - ue(num_slice_groups_minus1, 0, 7); - if(current->num_slice_groups_minus1 > 0) { - unsigned int pic_size; - int iGroup; - - pic_size = (sps->pic_width_in_mbs_minus1 + 1) * - (sps->pic_height_in_map_units_minus1 + 1); - - ue(slice_group_map_type, 0, 6); - - if(current->slice_group_map_type == 0) { - for(iGroup = 0; iGroup <= current->num_slice_groups_minus1; iGroup++) - ues(run_length_minus1[iGroup], 0, pic_size - 1, 1, iGroup); - } - else if(current->slice_group_map_type == 2) { - for(iGroup = 0; iGroup < current->num_slice_groups_minus1; iGroup++) { - ues(top_left[iGroup], 0, pic_size - 1, 1, iGroup); - ues(bottom_right[iGroup], - current->top_left[iGroup], pic_size - 1, 1, iGroup); - } - } - else if(current->slice_group_map_type == 3 || - current->slice_group_map_type == 4 || - current->slice_group_map_type == 5) { - flag(slice_group_change_direction_flag); - ue(slice_group_change_rate_minus1, 0, pic_size - 1); - } - else if(current->slice_group_map_type == 6) { - ue(pic_size_in_map_units_minus1, pic_size - 1, pic_size - 1); - - allocate(current->slice_group_id, - current->pic_size_in_map_units_minus1 + 1); - for(i = 0; i <= current->pic_size_in_map_units_minus1; i++) - us(av_log2(2 * current->num_slice_groups_minus1 + 1), - slice_group_id[i], 0, current->num_slice_groups_minus1, 1, i); - } - } - - ue(num_ref_idx_l0_default_active_minus1, 0, 31); - ue(num_ref_idx_l1_default_active_minus1, 0, 31); - - flag(weighted_pred_flag); - u(2, weighted_bipred_idc, 0, 2); - - se(pic_init_qp_minus26, -26 - 6 * sps->bit_depth_luma_minus8, +25); - se(pic_init_qs_minus26, -26, +25); - se(chroma_qp_index_offset, -12, +12); - - flag(deblocking_filter_control_present_flag); - flag(constrained_intra_pred_flag); - flag(redundant_pic_cnt_present_flag); - - if(more_rbsp_data(current->more_rbsp_data)) { - flag(transform_8x8_mode_flag); - - flag(pic_scaling_matrix_present_flag); - if(current->pic_scaling_matrix_present_flag) { - for(i = 0; i < 6 + (((sps->chroma_format_idc != 3) ? 2 : 6) * - current->transform_8x8_mode_flag); - i++) { - flags(pic_scaling_list_present_flag[i], 1, i); - if(current->pic_scaling_list_present_flag[i]) { - if(i < 6) - CHECK(FUNC(scaling_list)(ctx, rw, - ¤t->scaling_list_4x4[i], - 16)); - else - CHECK(FUNC(scaling_list)(ctx, rw, - ¤t->scaling_list_8x8[i - 6], - 64)); - } - } - } - - se(second_chroma_qp_index_offset, -12, +12); - } - else { - infer(transform_8x8_mode_flag, 0); - infer(pic_scaling_matrix_present_flag, 0); - infer(second_chroma_qp_index_offset, current->chroma_qp_index_offset); - } - - CHECK(FUNC(rbsp_trailing_bits)(ctx, rw)); - - return 0; -} - -static int FUNC(sei_buffering_period)(CodedBitstreamContext *ctx, RWContext *rw, - H264RawSEIBufferingPeriod *current, - SEIMessageState *sei) { - CodedBitstreamH264Context *h264 = ctx->priv_data; - const H264RawSPS *sps; - int err, i, length; - - HEADER("Buffering Period"); - - ue(seq_parameter_set_id, 0, 31); - - sps = h264->sps[current->seq_parameter_set_id]; - if(!sps) { - av_log(ctx->log_ctx, AV_LOG_ERROR, "SPS id %d not available.\n", - current->seq_parameter_set_id); - return AVERROR_INVALIDDATA; - } - h264->active_sps = sps; - - if(sps->vui.nal_hrd_parameters_present_flag) { - for(i = 0; i <= sps->vui.nal_hrd_parameters.cpb_cnt_minus1; i++) { - length = sps->vui.nal_hrd_parameters.initial_cpb_removal_delay_length_minus1 + 1; - xu(length, initial_cpb_removal_delay[SchedSelIdx], - current->nal.initial_cpb_removal_delay[i], - 1, MAX_UINT_BITS(length), 1, i); - xu(length, initial_cpb_removal_delay_offset[SchedSelIdx], - current->nal.initial_cpb_removal_delay_offset[i], - 0, MAX_UINT_BITS(length), 1, i); - } - } - - if(sps->vui.vcl_hrd_parameters_present_flag) { - for(i = 0; i <= sps->vui.vcl_hrd_parameters.cpb_cnt_minus1; i++) { - length = sps->vui.vcl_hrd_parameters.initial_cpb_removal_delay_length_minus1 + 1; - xu(length, initial_cpb_removal_delay[SchedSelIdx], - current->vcl.initial_cpb_removal_delay[i], - 1, MAX_UINT_BITS(length), 1, i); - xu(length, initial_cpb_removal_delay_offset[SchedSelIdx], - current->vcl.initial_cpb_removal_delay_offset[i], - 0, MAX_UINT_BITS(length), 1, i); - } - } - - return 0; -} - -static int FUNC(sei_pic_timestamp)(CodedBitstreamContext *ctx, RWContext *rw, - H264RawSEIPicTimestamp *current, - const H264RawSPS *sps) { - uint8_t time_offset_length; - int err; - - u(2, ct_type, 0, 2); - flag(nuit_field_based_flag); - u(5, counting_type, 0, 6); - flag(full_timestamp_flag); - flag(discontinuity_flag); - flag(cnt_dropped_flag); - ub(8, n_frames); - if(current->full_timestamp_flag) { - u(6, seconds_value, 0, 59); - u(6, minutes_value, 0, 59); - u(5, hours_value, 0, 23); - } - else { - flag(seconds_flag); - if(current->seconds_flag) { - u(6, seconds_value, 0, 59); - flag(minutes_flag); - if(current->minutes_flag) { - u(6, minutes_value, 0, 59); - flag(hours_flag); - if(current->hours_flag) - u(5, hours_value, 0, 23); - } - } - } - - if(sps->vui.nal_hrd_parameters_present_flag) - time_offset_length = sps->vui.nal_hrd_parameters.time_offset_length; - else if(sps->vui.vcl_hrd_parameters_present_flag) - time_offset_length = sps->vui.vcl_hrd_parameters.time_offset_length; - else - time_offset_length = 24; - - if(time_offset_length > 0) - ib(time_offset_length, time_offset); - else - infer(time_offset, 0); - - return 0; -} - -static int FUNC(sei_pic_timing)(CodedBitstreamContext *ctx, RWContext *rw, - H264RawSEIPicTiming *current, - SEIMessageState *sei) { - CodedBitstreamH264Context *h264 = ctx->priv_data; - const H264RawSPS *sps; - int err; - - HEADER("Picture Timing"); - - sps = h264->active_sps; - if(!sps) { - // If there is exactly one possible SPS but it is not yet active - // then just assume that it should be the active one. - int i, k = -1; - for(i = 0; i < H264_MAX_SPS_COUNT; i++) { - if(h264->sps[i]) { - if(k >= 0) { - k = -1; - break; - } - k = i; - } - } - if(k >= 0) - sps = h264->sps[k]; - } - if(!sps) { - av_log(ctx->log_ctx, AV_LOG_ERROR, - "No active SPS for pic_timing.\n"); - return AVERROR_INVALIDDATA; - } - - if(sps->vui.nal_hrd_parameters_present_flag || - sps->vui.vcl_hrd_parameters_present_flag) { - const H264RawHRD *hrd; - - if(sps->vui.nal_hrd_parameters_present_flag) - hrd = &sps->vui.nal_hrd_parameters; - else if(sps->vui.vcl_hrd_parameters_present_flag) - hrd = &sps->vui.vcl_hrd_parameters; - else { - av_log(ctx->log_ctx, AV_LOG_ERROR, - "No HRD parameters for pic_timing.\n"); - return AVERROR_INVALIDDATA; - } - - ub(hrd->cpb_removal_delay_length_minus1 + 1, cpb_removal_delay); - ub(hrd->dpb_output_delay_length_minus1 + 1, dpb_output_delay); - } - - if(sps->vui.pic_struct_present_flag) { - static const uint8_t num_clock_ts[9] = { - 1, 1, 1, 2, 2, 3, 3, 2, 3 - }; - int i; - - u(4, pic_struct, 0, 8); - if(current->pic_struct > 8) - return AVERROR_INVALIDDATA; - - for(i = 0; i < num_clock_ts[current->pic_struct]; i++) { - flags(clock_timestamp_flag[i], 1, i); - if(current->clock_timestamp_flag[i]) - CHECK(FUNC(sei_pic_timestamp)(ctx, rw, - ¤t->timestamp[i], sps)); - } - } - - return 0; -} - -static int FUNC(sei_pan_scan_rect)(CodedBitstreamContext *ctx, RWContext *rw, - H264RawSEIPanScanRect *current, - SEIMessageState *sei) { - int err, i; - - HEADER("Pan-Scan Rectangle"); - - ue(pan_scan_rect_id, 0, UINT32_MAX - 1); - flag(pan_scan_rect_cancel_flag); - - if(!current->pan_scan_rect_cancel_flag) { - ue(pan_scan_cnt_minus1, 0, 2); - - for(i = 0; i <= current->pan_scan_cnt_minus1; i++) { - ses(pan_scan_rect_left_offset[i], INT32_MIN + 1, INT32_MAX, 1, i); - ses(pan_scan_rect_right_offset[i], INT32_MIN + 1, INT32_MAX, 1, i); - ses(pan_scan_rect_top_offset[i], INT32_MIN + 1, INT32_MAX, 1, i); - ses(pan_scan_rect_bottom_offset[i], INT32_MIN + 1, INT32_MAX, 1, i); - } - - ue(pan_scan_rect_repetition_period, 0, 16384); - } - - return 0; -} - -static int FUNC(sei_recovery_point)(CodedBitstreamContext *ctx, RWContext *rw, - H264RawSEIRecoveryPoint *current, - SEIMessageState *sei) { - int err; - - HEADER("Recovery Point"); - - ue(recovery_frame_cnt, 0, 65535); - flag(exact_match_flag); - flag(broken_link_flag); - u(2, changing_slice_group_idc, 0, 2); - - return 0; -} - -static int FUNC(sei_display_orientation)(CodedBitstreamContext *ctx, RWContext *rw, - H264RawSEIDisplayOrientation *current, - SEIMessageState *sei) { - int err; - - HEADER("Display Orientation"); - - flag(display_orientation_cancel_flag); - if(!current->display_orientation_cancel_flag) { - flag(hor_flip); - flag(ver_flip); - ub(16, anticlockwise_rotation); - ue(display_orientation_repetition_period, 0, 16384); - flag(display_orientation_extension_flag); - } - - return 0; -} - -static int FUNC(sei)(CodedBitstreamContext *ctx, RWContext *rw, - H264RawSEI *current) { - int err; - - HEADER("Supplemental Enhancement Information"); - - CHECK(FUNC(nal_unit_header)(ctx, rw, ¤t->nal_unit_header, - 1 << H264_NAL_SEI)); - - CHECK(FUNC_SEI(message_list)(ctx, rw, ¤t->message_list, 1)); - - CHECK(FUNC(rbsp_trailing_bits)(ctx, rw)); - - return 0; -} - -static int FUNC(aud)(CodedBitstreamContext *ctx, RWContext *rw, - H264RawAUD *current) { - int err; - - HEADER("Access Unit Delimiter"); - - CHECK(FUNC(nal_unit_header)(ctx, rw, ¤t->nal_unit_header, - 1 << H264_NAL_AUD)); - - ub(3, primary_pic_type); - - CHECK(FUNC(rbsp_trailing_bits)(ctx, rw)); - - return 0; -} - -static int FUNC(ref_pic_list_modification)(CodedBitstreamContext *ctx, RWContext *rw, - H264RawSliceHeader *current) { - CodedBitstreamH264Context *h264 = ctx->priv_data; - const H264RawSPS *sps = h264->active_sps; - int err, i, mopn; - - if(current->slice_type % 5 != 2 && - current->slice_type % 5 != 4) { - flag(ref_pic_list_modification_flag_l0); - if(current->ref_pic_list_modification_flag_l0) { - for(i = 0; i < H264_MAX_RPLM_COUNT; i++) { - xue(modification_of_pic_nums_idc, - current->rplm_l0[i].modification_of_pic_nums_idc, 0, 3, 0); - - mopn = current->rplm_l0[i].modification_of_pic_nums_idc; - if(mopn == 3) - break; - - if(mopn == 0 || mopn == 1) - xue(abs_diff_pic_num_minus1, - current->rplm_l0[i].abs_diff_pic_num_minus1, - 0, (1 + current->field_pic_flag) * (1 << (sps->log2_max_frame_num_minus4 + 4)), 0); - else if(mopn == 2) - xue(long_term_pic_num, - current->rplm_l0[i].long_term_pic_num, - 0, sps->max_num_ref_frames - 1, 0); - } - } - } - - if(current->slice_type % 5 == 1) { - flag(ref_pic_list_modification_flag_l1); - if(current->ref_pic_list_modification_flag_l1) { - for(i = 0; i < H264_MAX_RPLM_COUNT; i++) { - xue(modification_of_pic_nums_idc, - current->rplm_l1[i].modification_of_pic_nums_idc, 0, 3, 0); - - mopn = current->rplm_l1[i].modification_of_pic_nums_idc; - if(mopn == 3) - break; - - if(mopn == 0 || mopn == 1) - xue(abs_diff_pic_num_minus1, - current->rplm_l1[i].abs_diff_pic_num_minus1, - 0, (1 + current->field_pic_flag) * (1 << (sps->log2_max_frame_num_minus4 + 4)), 0); - else if(mopn == 2) - xue(long_term_pic_num, - current->rplm_l1[i].long_term_pic_num, - 0, sps->max_num_ref_frames - 1, 0); - } - } - } - - return 0; -} - -static int FUNC(pred_weight_table)(CodedBitstreamContext *ctx, RWContext *rw, - H264RawSliceHeader *current) { - CodedBitstreamH264Context *h264 = ctx->priv_data; - const H264RawSPS *sps = h264->active_sps; - int chroma; - int err, i, j; - - ue(luma_log2_weight_denom, 0, 7); - - chroma = !sps->separate_colour_plane_flag && sps->chroma_format_idc != 0; - if(chroma) - ue(chroma_log2_weight_denom, 0, 7); - - for(i = 0; i <= current->num_ref_idx_l0_active_minus1; i++) { - flags(luma_weight_l0_flag[i], 1, i); - if(current->luma_weight_l0_flag[i]) { - ses(luma_weight_l0[i], -128, +127, 1, i); - ses(luma_offset_l0[i], -128, +127, 1, i); - } - if(chroma) { - flags(chroma_weight_l0_flag[i], 1, i); - if(current->chroma_weight_l0_flag[i]) { - for(j = 0; j < 2; j++) { - ses(chroma_weight_l0[i][j], -128, +127, 2, i, j); - ses(chroma_offset_l0[i][j], -128, +127, 2, i, j); - } - } - } - } - - if(current->slice_type % 5 == 1) { - for(i = 0; i <= current->num_ref_idx_l1_active_minus1; i++) { - flags(luma_weight_l1_flag[i], 1, i); - if(current->luma_weight_l1_flag[i]) { - ses(luma_weight_l1[i], -128, +127, 1, i); - ses(luma_offset_l1[i], -128, +127, 1, i); - } - if(chroma) { - flags(chroma_weight_l1_flag[i], 1, i); - if(current->chroma_weight_l1_flag[i]) { - for(j = 0; j < 2; j++) { - ses(chroma_weight_l1[i][j], -128, +127, 2, i, j); - ses(chroma_offset_l1[i][j], -128, +127, 2, i, j); - } - } - } - } - } - - return 0; -} - -static int FUNC(dec_ref_pic_marking)(CodedBitstreamContext *ctx, RWContext *rw, - H264RawSliceHeader *current, int idr_pic_flag) { - CodedBitstreamH264Context *h264 = ctx->priv_data; - const H264RawSPS *sps = h264->active_sps; - int err, i; - uint32_t mmco; - - if(idr_pic_flag) { - flag(no_output_of_prior_pics_flag); - flag(long_term_reference_flag); - } - else { - flag(adaptive_ref_pic_marking_mode_flag); - if(current->adaptive_ref_pic_marking_mode_flag) { - for(i = 0; i < H264_MAX_MMCO_COUNT; i++) { - xue(memory_management_control_operation, - current->mmco[i].memory_management_control_operation, - 0, 6, 0); - - mmco = current->mmco[i].memory_management_control_operation; - if(mmco == 0) - break; - - if(mmco == 1 || mmco == 3) - xue(difference_of_pic_nums_minus1, - current->mmco[i].difference_of_pic_nums_minus1, - 0, INT32_MAX, 0); - if(mmco == 2) - xue(long_term_pic_num, - current->mmco[i].long_term_pic_num, - 0, sps->max_num_ref_frames - 1, 0); - if(mmco == 3 || mmco == 6) - xue(long_term_frame_idx, - current->mmco[i].long_term_frame_idx, - 0, sps->max_num_ref_frames - 1, 0); - if(mmco == 4) - xue(max_long_term_frame_idx_plus1, - current->mmco[i].max_long_term_frame_idx_plus1, - 0, sps->max_num_ref_frames, 0); - } - if(i == H264_MAX_MMCO_COUNT) { - av_log(ctx->log_ctx, AV_LOG_ERROR, "Too many " - "memory management control operations.\n"); - return AVERROR_INVALIDDATA; - } - } - } - - return 0; -} - -static int FUNC(slice_header)(CodedBitstreamContext *ctx, RWContext *rw, - H264RawSliceHeader *current) { - CodedBitstreamH264Context *h264 = ctx->priv_data; - const H264RawSPS *sps; - const H264RawPPS *pps; - int err; - int idr_pic_flag; - int slice_type_i, slice_type_p, slice_type_b; - int slice_type_si, slice_type_sp; - - HEADER("Slice Header"); - - CHECK(FUNC(nal_unit_header)(ctx, rw, ¤t->nal_unit_header, - 1 << H264_NAL_SLICE | - 1 << H264_NAL_IDR_SLICE | - 1 << H264_NAL_AUXILIARY_SLICE)); - - if(current->nal_unit_header.nal_unit_type == H264_NAL_AUXILIARY_SLICE) { - if(!h264->last_slice_nal_unit_type) { - av_log(ctx->log_ctx, AV_LOG_ERROR, "Auxiliary slice " - "is not decodable without the main picture " - "in the same access unit.\n"); - return AVERROR_INVALIDDATA; - } - idr_pic_flag = h264->last_slice_nal_unit_type == H264_NAL_IDR_SLICE; - } - else { - idr_pic_flag = current->nal_unit_header.nal_unit_type == H264_NAL_IDR_SLICE; - } - - ue(first_mb_in_slice, 0, H264_MAX_MB_PIC_SIZE - 1); - ue(slice_type, 0, 9); - - slice_type_i = current->slice_type % 5 == 2; - slice_type_p = current->slice_type % 5 == 0; - slice_type_b = current->slice_type % 5 == 1; - slice_type_si = current->slice_type % 5 == 4; - slice_type_sp = current->slice_type % 5 == 3; - - if(idr_pic_flag && !(slice_type_i || slice_type_si)) { - av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid slice type %d " - "for IDR picture.\n", - current->slice_type); - return AVERROR_INVALIDDATA; - } - - ue(pic_parameter_set_id, 0, 255); - - pps = h264->pps[current->pic_parameter_set_id]; - if(!pps) { - av_log(ctx->log_ctx, AV_LOG_ERROR, "PPS id %d not available.\n", - current->pic_parameter_set_id); - return AVERROR_INVALIDDATA; - } - h264->active_pps = pps; - - sps = h264->sps[pps->seq_parameter_set_id]; - if(!sps) { - av_log(ctx->log_ctx, AV_LOG_ERROR, "SPS id %d not available.\n", - pps->seq_parameter_set_id); - return AVERROR_INVALIDDATA; - } - h264->active_sps = sps; - - if(sps->separate_colour_plane_flag) - u(2, colour_plane_id, 0, 2); - - ub(sps->log2_max_frame_num_minus4 + 4, frame_num); - - if(!sps->frame_mbs_only_flag) { - flag(field_pic_flag); - if(current->field_pic_flag) - flag(bottom_field_flag); - else - infer(bottom_field_flag, 0); - } - else { - infer(field_pic_flag, 0); - infer(bottom_field_flag, 0); - } - - if(idr_pic_flag) - ue(idr_pic_id, 0, 65535); - - if(sps->pic_order_cnt_type == 0) { - ub(sps->log2_max_pic_order_cnt_lsb_minus4 + 4, pic_order_cnt_lsb); - if(pps->bottom_field_pic_order_in_frame_present_flag && - !current->field_pic_flag) - se(delta_pic_order_cnt_bottom, INT32_MIN + 1, INT32_MAX); - } - else if(sps->pic_order_cnt_type == 1) { - if(!sps->delta_pic_order_always_zero_flag) { - se(delta_pic_order_cnt[0], INT32_MIN + 1, INT32_MAX); - if(pps->bottom_field_pic_order_in_frame_present_flag && - !current->field_pic_flag) - se(delta_pic_order_cnt[1], INT32_MIN + 1, INT32_MAX); - else - infer(delta_pic_order_cnt[1], 0); - } - else { - infer(delta_pic_order_cnt[0], 0); - infer(delta_pic_order_cnt[1], 0); - } - } - - if(pps->redundant_pic_cnt_present_flag) - ue(redundant_pic_cnt, 0, 127); - else - infer(redundant_pic_cnt, 0); - - if(current->nal_unit_header.nal_unit_type != H264_NAL_AUXILIARY_SLICE && !current->redundant_pic_cnt) - h264->last_slice_nal_unit_type = - current->nal_unit_header.nal_unit_type; - - if(slice_type_b) - flag(direct_spatial_mv_pred_flag); - - if(slice_type_p || slice_type_sp || slice_type_b) { - flag(num_ref_idx_active_override_flag); - if(current->num_ref_idx_active_override_flag) { - ue(num_ref_idx_l0_active_minus1, 0, 31); - if(slice_type_b) - ue(num_ref_idx_l1_active_minus1, 0, 31); - } - else { - infer(num_ref_idx_l0_active_minus1, - pps->num_ref_idx_l0_default_active_minus1); - infer(num_ref_idx_l1_active_minus1, - pps->num_ref_idx_l1_default_active_minus1); - } - } - - if(current->nal_unit_header.nal_unit_type == 20 || - current->nal_unit_header.nal_unit_type == 21) { - av_log(ctx->log_ctx, AV_LOG_ERROR, "MVC / 3DAVC not supported.\n"); - return AVERROR_PATCHWELCOME; - } - else { - CHECK(FUNC(ref_pic_list_modification)(ctx, rw, current)); - } - - if((pps->weighted_pred_flag && (slice_type_p || slice_type_sp)) || - (pps->weighted_bipred_idc == 1 && slice_type_b)) { - CHECK(FUNC(pred_weight_table)(ctx, rw, current)); - } - - if(current->nal_unit_header.nal_ref_idc != 0) { - CHECK(FUNC(dec_ref_pic_marking)(ctx, rw, current, idr_pic_flag)); - } - - if(pps->entropy_coding_mode_flag && - !slice_type_i && !slice_type_si) { - ue(cabac_init_idc, 0, 2); - } - - se(slice_qp_delta, -51 - 6 * sps->bit_depth_luma_minus8, - +51 + 6 * sps->bit_depth_luma_minus8); - if(slice_type_sp || slice_type_si) { - if(slice_type_sp) - flag(sp_for_switch_flag); - se(slice_qs_delta, -51, +51); - } - - if(pps->deblocking_filter_control_present_flag) { - ue(disable_deblocking_filter_idc, 0, 2); - if(current->disable_deblocking_filter_idc != 1) { - se(slice_alpha_c0_offset_div2, -6, +6); - se(slice_beta_offset_div2, -6, +6); - } - else { - infer(slice_alpha_c0_offset_div2, 0); - infer(slice_beta_offset_div2, 0); - } - } - else { - infer(disable_deblocking_filter_idc, 0); - infer(slice_alpha_c0_offset_div2, 0); - infer(slice_beta_offset_div2, 0); - } - - if(pps->num_slice_groups_minus1 > 0 && - pps->slice_group_map_type >= 3 && - pps->slice_group_map_type <= 5) { - unsigned int pic_size, max, bits; - - pic_size = (sps->pic_width_in_mbs_minus1 + 1) * - (sps->pic_height_in_map_units_minus1 + 1); - max = (pic_size + pps->slice_group_change_rate_minus1) / - (pps->slice_group_change_rate_minus1 + 1); - bits = av_ceil_log2(max + 1); - - u(bits, slice_group_change_cycle, 0, max); - } - - if(pps->entropy_coding_mode_flag) { - while(byte_alignment(rw)) - fixed(1, cabac_alignment_one_bit, 1); - } - - return 0; -} - -static int FUNC(filler)(CodedBitstreamContext *ctx, RWContext *rw, - H264RawFiller *current) { - int err; - - HEADER("Filler Data"); - - CHECK(FUNC(nal_unit_header)(ctx, rw, ¤t->nal_unit_header, - 1 << H264_NAL_FILLER_DATA)); - -#ifdef READ - while(show_bits(rw, 8) == 0xff) { - fixed(8, ff_byte, 0xff); - ++current->filler_size; - } -#else - { - uint32_t i; - for(i = 0; i < current->filler_size; i++) - fixed(8, ff_byte, 0xff); - } -#endif - - CHECK(FUNC(rbsp_trailing_bits)(ctx, rw)); - - return 0; -} - -static int FUNC(end_of_sequence)(CodedBitstreamContext *ctx, RWContext *rw, - H264RawNALUnitHeader *current) { - HEADER("End of Sequence"); - - return FUNC(nal_unit_header)(ctx, rw, current, - 1 << H264_NAL_END_SEQUENCE); -} - -static int FUNC(end_of_stream)(CodedBitstreamContext *ctx, RWContext *rw, - H264RawNALUnitHeader *current) { - HEADER("End of Stream"); - - return FUNC(nal_unit_header)(ctx, rw, current, - 1 << H264_NAL_END_STREAM); -} diff --git a/third-party/cbs/cbs_h265_syntax_template.c b/third-party/cbs/cbs_h265_syntax_template.c deleted file mode 100644 index 7ceefc6f314..00000000000 --- a/third-party/cbs/cbs_h265_syntax_template.c +++ /dev/null @@ -1,2038 +0,0 @@ -/* - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -static int FUNC(rbsp_trailing_bits)(CodedBitstreamContext *ctx, RWContext *rw) { - int err; - - fixed(1, rbsp_stop_one_bit, 1); - while(byte_alignment(rw) != 0) - fixed(1, rbsp_alignment_zero_bit, 0); - - return 0; -} - -static int FUNC(nal_unit_header)(CodedBitstreamContext *ctx, RWContext *rw, - H265RawNALUnitHeader *current, - int expected_nal_unit_type) { - int err; - - fixed(1, forbidden_zero_bit, 0); - - if(expected_nal_unit_type >= 0) - u(6, nal_unit_type, expected_nal_unit_type, - expected_nal_unit_type); - else - ub(6, nal_unit_type); - - u(6, nuh_layer_id, 0, 62); - u(3, nuh_temporal_id_plus1, 1, 7); - - return 0; -} - -static int FUNC(byte_alignment)(CodedBitstreamContext *ctx, RWContext *rw) { - int err; - - fixed(1, alignment_bit_equal_to_one, 1); - while(byte_alignment(rw) != 0) - fixed(1, alignment_bit_equal_to_zero, 0); - - return 0; -} - -static int FUNC(extension_data)(CodedBitstreamContext *ctx, RWContext *rw, - H265RawExtensionData *current) { - int err; - size_t k; -#ifdef READ - GetBitContext start; - uint8_t bit; - start = *rw; - for(k = 0; cbs_h2645_read_more_rbsp_data(rw); k++) - skip_bits(rw, 1); - current->bit_length = k; - if(k > 0) { - *rw = start; - allocate(current->data, (current->bit_length + 7) / 8); - for(k = 0; k < current->bit_length; k++) { - xu(1, extension_data, bit, 0, 1, 0); - current->data[k / 8] |= bit << (7 - k % 8); - } - } -#else - for(k = 0; k < current->bit_length; k++) - xu(1, extension_data, current->data[k / 8] >> (7 - k % 8) & 1, 0, 1, 0); -#endif - return 0; -} - -static int FUNC(profile_tier_level)(CodedBitstreamContext *ctx, RWContext *rw, - H265RawProfileTierLevel *current, - int profile_present_flag, - int max_num_sub_layers_minus1) { - int err, i, j; - - if(profile_present_flag) { - u(2, general_profile_space, 0, 0); - flag(general_tier_flag); - ub(5, general_profile_idc); - - for(j = 0; j < 32; j++) - flags(general_profile_compatibility_flag[j], 1, j); - - flag(general_progressive_source_flag); - flag(general_interlaced_source_flag); - flag(general_non_packed_constraint_flag); - flag(general_frame_only_constraint_flag); - -#define profile_compatible(x) (current->general_profile_idc == (x) || \ - current->general_profile_compatibility_flag[x]) - if(profile_compatible(4) || profile_compatible(5) || - profile_compatible(6) || profile_compatible(7) || - profile_compatible(8) || profile_compatible(9) || - profile_compatible(10)) { - flag(general_max_12bit_constraint_flag); - flag(general_max_10bit_constraint_flag); - flag(general_max_8bit_constraint_flag); - flag(general_max_422chroma_constraint_flag); - flag(general_max_420chroma_constraint_flag); - flag(general_max_monochrome_constraint_flag); - flag(general_intra_constraint_flag); - flag(general_one_picture_only_constraint_flag); - flag(general_lower_bit_rate_constraint_flag); - - if(profile_compatible(5) || profile_compatible(9) || - profile_compatible(10)) { - flag(general_max_14bit_constraint_flag); - fixed(24, general_reserved_zero_33bits, 0); - fixed(9, general_reserved_zero_33bits, 0); - } - else { - fixed(24, general_reserved_zero_34bits, 0); - fixed(10, general_reserved_zero_34bits, 0); - } - } - else if(profile_compatible(2)) { - fixed(7, general_reserved_zero_7bits, 0); - flag(general_one_picture_only_constraint_flag); - fixed(24, general_reserved_zero_35bits, 0); - fixed(11, general_reserved_zero_35bits, 0); - } - else { - fixed(24, general_reserved_zero_43bits, 0); - fixed(19, general_reserved_zero_43bits, 0); - } - - if(profile_compatible(1) || profile_compatible(2) || - profile_compatible(3) || profile_compatible(4) || - profile_compatible(5) || profile_compatible(9)) { - flag(general_inbld_flag); - } - else { - fixed(1, general_reserved_zero_bit, 0); - } -#undef profile_compatible - } - - ub(8, general_level_idc); - - for(i = 0; i < max_num_sub_layers_minus1; i++) { - flags(sub_layer_profile_present_flag[i], 1, i); - flags(sub_layer_level_present_flag[i], 1, i); - } - - if(max_num_sub_layers_minus1 > 0) { - for(i = max_num_sub_layers_minus1; i < 8; i++) - fixed(2, reserved_zero_2bits, 0); - } - - for(i = 0; i < max_num_sub_layers_minus1; i++) { - if(current->sub_layer_profile_present_flag[i]) { - us(2, sub_layer_profile_space[i], 0, 0, 1, i); - flags(sub_layer_tier_flag[i], 1, i); - ubs(5, sub_layer_profile_idc[i], 1, i); - - for(j = 0; j < 32; j++) - flags(sub_layer_profile_compatibility_flag[i][j], 2, i, j); - - flags(sub_layer_progressive_source_flag[i], 1, i); - flags(sub_layer_interlaced_source_flag[i], 1, i); - flags(sub_layer_non_packed_constraint_flag[i], 1, i); - flags(sub_layer_frame_only_constraint_flag[i], 1, i); - -#define profile_compatible(x) (current->sub_layer_profile_idc[i] == (x) || \ - current->sub_layer_profile_compatibility_flag[i][x]) - if(profile_compatible(4) || profile_compatible(5) || - profile_compatible(6) || profile_compatible(7) || - profile_compatible(8) || profile_compatible(9) || - profile_compatible(10)) { - flags(sub_layer_max_12bit_constraint_flag[i], 1, i); - flags(sub_layer_max_10bit_constraint_flag[i], 1, i); - flags(sub_layer_max_8bit_constraint_flag[i], 1, i); - flags(sub_layer_max_422chroma_constraint_flag[i], 1, i); - flags(sub_layer_max_420chroma_constraint_flag[i], 1, i); - flags(sub_layer_max_monochrome_constraint_flag[i], 1, i); - flags(sub_layer_intra_constraint_flag[i], 1, i); - flags(sub_layer_one_picture_only_constraint_flag[i], 1, i); - flags(sub_layer_lower_bit_rate_constraint_flag[i], 1, i); - - if(profile_compatible(5)) { - flags(sub_layer_max_14bit_constraint_flag[i], 1, i); - fixed(24, sub_layer_reserved_zero_33bits, 0); - fixed(9, sub_layer_reserved_zero_33bits, 0); - } - else { - fixed(24, sub_layer_reserved_zero_34bits, 0); - fixed(10, sub_layer_reserved_zero_34bits, 0); - } - } - else if(profile_compatible(2)) { - fixed(7, sub_layer_reserved_zero_7bits, 0); - flags(sub_layer_one_picture_only_constraint_flag[i], 1, i); - fixed(24, sub_layer_reserved_zero_43bits, 0); - fixed(11, sub_layer_reserved_zero_43bits, 0); - } - else { - fixed(24, sub_layer_reserved_zero_43bits, 0); - fixed(19, sub_layer_reserved_zero_43bits, 0); - } - - if(profile_compatible(1) || profile_compatible(2) || - profile_compatible(3) || profile_compatible(4) || - profile_compatible(5) || profile_compatible(9)) { - flags(sub_layer_inbld_flag[i], 1, i); - } - else { - fixed(1, sub_layer_reserved_zero_bit, 0); - } -#undef profile_compatible - } - if(current->sub_layer_level_present_flag[i]) - ubs(8, sub_layer_level_idc[i], 1, i); - } - - return 0; -} - -static int FUNC(sub_layer_hrd_parameters)(CodedBitstreamContext *ctx, RWContext *rw, - H265RawHRDParameters *hrd, - int nal, int sub_layer_id) { - H265RawSubLayerHRDParameters *current; - int err, i; - - if(nal) - current = &hrd->nal_sub_layer_hrd_parameters[sub_layer_id]; - else - current = &hrd->vcl_sub_layer_hrd_parameters[sub_layer_id]; - - for(i = 0; i <= hrd->cpb_cnt_minus1[sub_layer_id]; i++) { - ues(bit_rate_value_minus1[i], 0, UINT32_MAX - 1, 1, i); - ues(cpb_size_value_minus1[i], 0, UINT32_MAX - 1, 1, i); - if(hrd->sub_pic_hrd_params_present_flag) { - ues(cpb_size_du_value_minus1[i], 0, UINT32_MAX - 1, 1, i); - ues(bit_rate_du_value_minus1[i], 0, UINT32_MAX - 1, 1, i); - } - flags(cbr_flag[i], 1, i); - } - - return 0; -} - -static int FUNC(hrd_parameters)(CodedBitstreamContext *ctx, RWContext *rw, - H265RawHRDParameters *current, int common_inf_present_flag, - int max_num_sub_layers_minus1) { - int err, i; - - if(common_inf_present_flag) { - flag(nal_hrd_parameters_present_flag); - flag(vcl_hrd_parameters_present_flag); - - if(current->nal_hrd_parameters_present_flag || - current->vcl_hrd_parameters_present_flag) { - flag(sub_pic_hrd_params_present_flag); - if(current->sub_pic_hrd_params_present_flag) { - ub(8, tick_divisor_minus2); - ub(5, du_cpb_removal_delay_increment_length_minus1); - flag(sub_pic_cpb_params_in_pic_timing_sei_flag); - ub(5, dpb_output_delay_du_length_minus1); - } - - ub(4, bit_rate_scale); - ub(4, cpb_size_scale); - if(current->sub_pic_hrd_params_present_flag) - ub(4, cpb_size_du_scale); - - ub(5, initial_cpb_removal_delay_length_minus1); - ub(5, au_cpb_removal_delay_length_minus1); - ub(5, dpb_output_delay_length_minus1); - } - else { - infer(sub_pic_hrd_params_present_flag, 0); - - infer(initial_cpb_removal_delay_length_minus1, 23); - infer(au_cpb_removal_delay_length_minus1, 23); - infer(dpb_output_delay_length_minus1, 23); - } - } - - for(i = 0; i <= max_num_sub_layers_minus1; i++) { - flags(fixed_pic_rate_general_flag[i], 1, i); - - if(!current->fixed_pic_rate_general_flag[i]) - flags(fixed_pic_rate_within_cvs_flag[i], 1, i); - else - infer(fixed_pic_rate_within_cvs_flag[i], 1); - - if(current->fixed_pic_rate_within_cvs_flag[i]) { - ues(elemental_duration_in_tc_minus1[i], 0, 2047, 1, i); - infer(low_delay_hrd_flag[i], 0); - } - else - flags(low_delay_hrd_flag[i], 1, i); - - if(!current->low_delay_hrd_flag[i]) - ues(cpb_cnt_minus1[i], 0, 31, 1, i); - else - infer(cpb_cnt_minus1[i], 0); - - if(current->nal_hrd_parameters_present_flag) - CHECK(FUNC(sub_layer_hrd_parameters)(ctx, rw, current, 0, i)); - if(current->vcl_hrd_parameters_present_flag) - CHECK(FUNC(sub_layer_hrd_parameters)(ctx, rw, current, 1, i)); - } - - return 0; -} - -static int FUNC(vui_parameters)(CodedBitstreamContext *ctx, RWContext *rw, - H265RawVUI *current, const H265RawSPS *sps) { - int err; - - flag(aspect_ratio_info_present_flag); - if(current->aspect_ratio_info_present_flag) { - ub(8, aspect_ratio_idc); - if(current->aspect_ratio_idc == 255) { - ub(16, sar_width); - ub(16, sar_height); - } - } - else { - infer(aspect_ratio_idc, 0); - } - - flag(overscan_info_present_flag); - if(current->overscan_info_present_flag) - flag(overscan_appropriate_flag); - - flag(video_signal_type_present_flag); - if(current->video_signal_type_present_flag) { - ub(3, video_format); - flag(video_full_range_flag); - flag(colour_description_present_flag); - if(current->colour_description_present_flag) { - ub(8, colour_primaries); - ub(8, transfer_characteristics); - ub(8, matrix_coefficients); - } - else { - infer(colour_primaries, 2); - infer(transfer_characteristics, 2); - infer(matrix_coefficients, 2); - } - } - else { - infer(video_format, 5); - infer(video_full_range_flag, 0); - infer(colour_primaries, 2); - infer(transfer_characteristics, 2); - infer(matrix_coefficients, 2); - } - - flag(chroma_loc_info_present_flag); - if(current->chroma_loc_info_present_flag) { - ue(chroma_sample_loc_type_top_field, 0, 5); - ue(chroma_sample_loc_type_bottom_field, 0, 5); - } - else { - infer(chroma_sample_loc_type_top_field, 0); - infer(chroma_sample_loc_type_bottom_field, 0); - } - - flag(neutral_chroma_indication_flag); - flag(field_seq_flag); - flag(frame_field_info_present_flag); - - flag(default_display_window_flag); - if(current->default_display_window_flag) { - ue(def_disp_win_left_offset, 0, 16384); - ue(def_disp_win_right_offset, 0, 16384); - ue(def_disp_win_top_offset, 0, 16384); - ue(def_disp_win_bottom_offset, 0, 16384); - } - - flag(vui_timing_info_present_flag); - if(current->vui_timing_info_present_flag) { - u(32, vui_num_units_in_tick, 1, UINT32_MAX); - u(32, vui_time_scale, 1, UINT32_MAX); - flag(vui_poc_proportional_to_timing_flag); - if(current->vui_poc_proportional_to_timing_flag) - ue(vui_num_ticks_poc_diff_one_minus1, 0, UINT32_MAX - 1); - - flag(vui_hrd_parameters_present_flag); - if(current->vui_hrd_parameters_present_flag) { - CHECK(FUNC(hrd_parameters)(ctx, rw, ¤t->hrd_parameters, - 1, sps->sps_max_sub_layers_minus1)); - } - } - - flag(bitstream_restriction_flag); - if(current->bitstream_restriction_flag) { - flag(tiles_fixed_structure_flag); - flag(motion_vectors_over_pic_boundaries_flag); - flag(restricted_ref_pic_lists_flag); - ue(min_spatial_segmentation_idc, 0, 4095); - ue(max_bytes_per_pic_denom, 0, 16); - ue(max_bits_per_min_cu_denom, 0, 16); - ue(log2_max_mv_length_horizontal, 0, 16); - ue(log2_max_mv_length_vertical, 0, 16); - } - else { - infer(tiles_fixed_structure_flag, 0); - infer(motion_vectors_over_pic_boundaries_flag, 1); - infer(min_spatial_segmentation_idc, 0); - infer(max_bytes_per_pic_denom, 2); - infer(max_bits_per_min_cu_denom, 1); - infer(log2_max_mv_length_horizontal, 15); - infer(log2_max_mv_length_vertical, 15); - } - - return 0; -} - -static int FUNC(vps)(CodedBitstreamContext *ctx, RWContext *rw, - H265RawVPS *current) { - int err, i, j; - - HEADER("Video Parameter Set"); - - CHECK(FUNC(nal_unit_header)(ctx, rw, ¤t->nal_unit_header, HEVC_NAL_VPS)); - - ub(4, vps_video_parameter_set_id); - - flag(vps_base_layer_internal_flag); - flag(vps_base_layer_available_flag); - u(6, vps_max_layers_minus1, 0, HEVC_MAX_LAYERS - 1); - u(3, vps_max_sub_layers_minus1, 0, HEVC_MAX_SUB_LAYERS - 1); - flag(vps_temporal_id_nesting_flag); - - if(current->vps_max_sub_layers_minus1 == 0 && - current->vps_temporal_id_nesting_flag != 1) { - av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid stream: " - "vps_temporal_id_nesting_flag must be 1 if " - "vps_max_sub_layers_minus1 is 0.\n"); - return AVERROR_INVALIDDATA; - } - - fixed(16, vps_reserved_0xffff_16bits, 0xffff); - - CHECK(FUNC(profile_tier_level)(ctx, rw, ¤t->profile_tier_level, - 1, current->vps_max_sub_layers_minus1)); - - flag(vps_sub_layer_ordering_info_present_flag); - for(i = (current->vps_sub_layer_ordering_info_present_flag ? - 0 : - current->vps_max_sub_layers_minus1); - i <= current->vps_max_sub_layers_minus1; i++) { - ues(vps_max_dec_pic_buffering_minus1[i], - 0, HEVC_MAX_DPB_SIZE - 1, 1, i); - ues(vps_max_num_reorder_pics[i], - 0, current->vps_max_dec_pic_buffering_minus1[i], 1, i); - ues(vps_max_latency_increase_plus1[i], - 0, UINT32_MAX - 1, 1, i); - } - if(!current->vps_sub_layer_ordering_info_present_flag) { - for(i = 0; i < current->vps_max_sub_layers_minus1; i++) { - infer(vps_max_dec_pic_buffering_minus1[i], - current->vps_max_dec_pic_buffering_minus1[current->vps_max_sub_layers_minus1]); - infer(vps_max_num_reorder_pics[i], - current->vps_max_num_reorder_pics[current->vps_max_sub_layers_minus1]); - infer(vps_max_latency_increase_plus1[i], - current->vps_max_latency_increase_plus1[current->vps_max_sub_layers_minus1]); - } - } - - u(6, vps_max_layer_id, 0, HEVC_MAX_LAYERS - 1); - ue(vps_num_layer_sets_minus1, 0, HEVC_MAX_LAYER_SETS - 1); - for(i = 1; i <= current->vps_num_layer_sets_minus1; i++) { - for(j = 0; j <= current->vps_max_layer_id; j++) - flags(layer_id_included_flag[i][j], 2, i, j); - } - for(j = 0; j <= current->vps_max_layer_id; j++) - infer(layer_id_included_flag[0][j], j == 0); - - flag(vps_timing_info_present_flag); - if(current->vps_timing_info_present_flag) { - u(32, vps_num_units_in_tick, 1, UINT32_MAX); - u(32, vps_time_scale, 1, UINT32_MAX); - flag(vps_poc_proportional_to_timing_flag); - if(current->vps_poc_proportional_to_timing_flag) - ue(vps_num_ticks_poc_diff_one_minus1, 0, UINT32_MAX - 1); - ue(vps_num_hrd_parameters, 0, current->vps_num_layer_sets_minus1 + 1); - for(i = 0; i < current->vps_num_hrd_parameters; i++) { - ues(hrd_layer_set_idx[i], - current->vps_base_layer_internal_flag ? 0 : 1, - current->vps_num_layer_sets_minus1, 1, i); - if(i > 0) - flags(cprms_present_flag[i], 1, i); - else - infer(cprms_present_flag[0], 1); - - CHECK(FUNC(hrd_parameters)(ctx, rw, ¤t->hrd_parameters[i], - current->cprms_present_flag[i], - current->vps_max_sub_layers_minus1)); - } - } - - flag(vps_extension_flag); - if(current->vps_extension_flag) - CHECK(FUNC(extension_data)(ctx, rw, ¤t->extension_data)); - - CHECK(FUNC(rbsp_trailing_bits)(ctx, rw)); - - return 0; -} - -static int FUNC(st_ref_pic_set)(CodedBitstreamContext *ctx, RWContext *rw, - H265RawSTRefPicSet *current, int st_rps_idx, - const H265RawSPS *sps) { - int err, i, j; - - if(st_rps_idx != 0) - flag(inter_ref_pic_set_prediction_flag); - else - infer(inter_ref_pic_set_prediction_flag, 0); - - if(current->inter_ref_pic_set_prediction_flag) { - unsigned int ref_rps_idx, num_delta_pocs, num_ref_pics; - const H265RawSTRefPicSet *ref; - int delta_rps, d_poc; - int ref_delta_poc_s0[HEVC_MAX_REFS], ref_delta_poc_s1[HEVC_MAX_REFS]; - int delta_poc_s0[HEVC_MAX_REFS], delta_poc_s1[HEVC_MAX_REFS]; - uint8_t used_by_curr_pic_s0[HEVC_MAX_REFS], - used_by_curr_pic_s1[HEVC_MAX_REFS]; - - if(st_rps_idx == sps->num_short_term_ref_pic_sets) - ue(delta_idx_minus1, 0, st_rps_idx - 1); - else - infer(delta_idx_minus1, 0); - - ref_rps_idx = st_rps_idx - (current->delta_idx_minus1 + 1); - ref = &sps->st_ref_pic_set[ref_rps_idx]; - num_delta_pocs = ref->num_negative_pics + ref->num_positive_pics; - av_assert0(num_delta_pocs < HEVC_MAX_DPB_SIZE); - - flag(delta_rps_sign); - ue(abs_delta_rps_minus1, 0, INT16_MAX); - delta_rps = (1 - 2 * current->delta_rps_sign) * - (current->abs_delta_rps_minus1 + 1); - - num_ref_pics = 0; - for(j = 0; j <= num_delta_pocs; j++) { - flags(used_by_curr_pic_flag[j], 1, j); - if(!current->used_by_curr_pic_flag[j]) - flags(use_delta_flag[j], 1, j); - else - infer(use_delta_flag[j], 1); - if(current->use_delta_flag[j]) - ++num_ref_pics; - } - if(num_ref_pics >= HEVC_MAX_DPB_SIZE) { - av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid stream: " - "short-term ref pic set %d " - "contains too many pictures.\n", - st_rps_idx); - return AVERROR_INVALIDDATA; - } - - // Since the stored form of an RPS here is actually the delta-step - // form used when inter_ref_pic_set_prediction_flag is not set, we - // need to reconstruct that here in order to be able to refer to - // the RPS later (which is required for parsing, because we don't - // even know what syntax elements appear without it). Therefore, - // this code takes the delta-step form of the reference set, turns - // it into the delta-array form, applies the prediction process of - // 7.4.8, converts the result back to the delta-step form, and - // stores that as the current set for future use. Note that the - // inferences here mean that writers using prediction will need - // to fill in the delta-step values correctly as well - since the - // whole RPS prediction process is somewhat overly sophisticated, - // this hopefully forms a useful check for them to ensure their - // predicted form actually matches what was intended rather than - // an onerous additional requirement. - - d_poc = 0; - for(i = 0; i < ref->num_negative_pics; i++) { - d_poc -= ref->delta_poc_s0_minus1[i] + 1; - ref_delta_poc_s0[i] = d_poc; - } - d_poc = 0; - for(i = 0; i < ref->num_positive_pics; i++) { - d_poc += ref->delta_poc_s1_minus1[i] + 1; - ref_delta_poc_s1[i] = d_poc; - } - - i = 0; - for(j = ref->num_positive_pics - 1; j >= 0; j--) { - d_poc = ref_delta_poc_s1[j] + delta_rps; - if(d_poc < 0 && current->use_delta_flag[ref->num_negative_pics + j]) { - delta_poc_s0[i] = d_poc; - used_by_curr_pic_s0[i++] = - current->used_by_curr_pic_flag[ref->num_negative_pics + j]; - } - } - if(delta_rps < 0 && current->use_delta_flag[num_delta_pocs]) { - delta_poc_s0[i] = delta_rps; - used_by_curr_pic_s0[i++] = - current->used_by_curr_pic_flag[num_delta_pocs]; - } - for(j = 0; j < ref->num_negative_pics; j++) { - d_poc = ref_delta_poc_s0[j] + delta_rps; - if(d_poc < 0 && current->use_delta_flag[j]) { - delta_poc_s0[i] = d_poc; - used_by_curr_pic_s0[i++] = current->used_by_curr_pic_flag[j]; - } - } - - infer(num_negative_pics, i); - for(i = 0; i < current->num_negative_pics; i++) { - infer(delta_poc_s0_minus1[i], - -(delta_poc_s0[i] - (i == 0 ? 0 : delta_poc_s0[i - 1])) - 1); - infer(used_by_curr_pic_s0_flag[i], used_by_curr_pic_s0[i]); - } - - i = 0; - for(j = ref->num_negative_pics - 1; j >= 0; j--) { - d_poc = ref_delta_poc_s0[j] + delta_rps; - if(d_poc > 0 && current->use_delta_flag[j]) { - delta_poc_s1[i] = d_poc; - used_by_curr_pic_s1[i++] = current->used_by_curr_pic_flag[j]; - } - } - if(delta_rps > 0 && current->use_delta_flag[num_delta_pocs]) { - delta_poc_s1[i] = delta_rps; - used_by_curr_pic_s1[i++] = - current->used_by_curr_pic_flag[num_delta_pocs]; - } - for(j = 0; j < ref->num_positive_pics; j++) { - d_poc = ref_delta_poc_s1[j] + delta_rps; - if(d_poc > 0 && current->use_delta_flag[ref->num_negative_pics + j]) { - delta_poc_s1[i] = d_poc; - used_by_curr_pic_s1[i++] = - current->used_by_curr_pic_flag[ref->num_negative_pics + j]; - } - } - - infer(num_positive_pics, i); - for(i = 0; i < current->num_positive_pics; i++) { - infer(delta_poc_s1_minus1[i], - delta_poc_s1[i] - (i == 0 ? 0 : delta_poc_s1[i - 1]) - 1); - infer(used_by_curr_pic_s1_flag[i], used_by_curr_pic_s1[i]); - } - } - else { - ue(num_negative_pics, 0, 15); - ue(num_positive_pics, 0, 15 - current->num_negative_pics); - - for(i = 0; i < current->num_negative_pics; i++) { - ues(delta_poc_s0_minus1[i], 0, INT16_MAX, 1, i); - flags(used_by_curr_pic_s0_flag[i], 1, i); - } - - for(i = 0; i < current->num_positive_pics; i++) { - ues(delta_poc_s1_minus1[i], 0, INT16_MAX, 1, i); - flags(used_by_curr_pic_s1_flag[i], 1, i); - } - } - - return 0; -} - -static int FUNC(scaling_list_data)(CodedBitstreamContext *ctx, RWContext *rw, - H265RawScalingList *current) { - int sizeId, matrixId; - int err, n, i; - - for(sizeId = 0; sizeId < 4; sizeId++) { - for(matrixId = 0; matrixId < 6; matrixId += (sizeId == 3 ? 3 : 1)) { - flags(scaling_list_pred_mode_flag[sizeId][matrixId], - 2, sizeId, matrixId); - if(!current->scaling_list_pred_mode_flag[sizeId][matrixId]) { - ues(scaling_list_pred_matrix_id_delta[sizeId][matrixId], - 0, sizeId == 3 ? matrixId / 3 : matrixId, - 2, sizeId, matrixId); - } - else { - n = FFMIN(64, 1 << (4 + (sizeId << 1))); - if(sizeId > 1) { - ses(scaling_list_dc_coef_minus8[sizeId - 2][matrixId], -7, +247, - 2, sizeId - 2, matrixId); - } - for(i = 0; i < n; i++) { - ses(scaling_list_delta_coeff[sizeId][matrixId][i], - -128, +127, 3, sizeId, matrixId, i); - } - } - } - } - - return 0; -} - -static int FUNC(sps_range_extension)(CodedBitstreamContext *ctx, RWContext *rw, - H265RawSPS *current) { - int err; - - flag(transform_skip_rotation_enabled_flag); - flag(transform_skip_context_enabled_flag); - flag(implicit_rdpcm_enabled_flag); - flag(explicit_rdpcm_enabled_flag); - flag(extended_precision_processing_flag); - flag(intra_smoothing_disabled_flag); - flag(high_precision_offsets_enabled_flag); - flag(persistent_rice_adaptation_enabled_flag); - flag(cabac_bypass_alignment_enabled_flag); - - return 0; -} - -static int FUNC(sps_scc_extension)(CodedBitstreamContext *ctx, RWContext *rw, - H265RawSPS *current) { - int err, comp, i; - - flag(sps_curr_pic_ref_enabled_flag); - - flag(palette_mode_enabled_flag); - if(current->palette_mode_enabled_flag) { - ue(palette_max_size, 0, 64); - ue(delta_palette_max_predictor_size, 0, 128); - - flag(sps_palette_predictor_initializer_present_flag); - if(current->sps_palette_predictor_initializer_present_flag) { - ue(sps_num_palette_predictor_initializer_minus1, 0, 128); - for(comp = 0; comp < (current->chroma_format_idc ? 3 : 1); comp++) { - int bit_depth = comp == 0 ? current->bit_depth_luma_minus8 + 8 : current->bit_depth_chroma_minus8 + 8; - for(i = 0; i <= current->sps_num_palette_predictor_initializer_minus1; i++) - ubs(bit_depth, sps_palette_predictor_initializers[comp][i], 2, comp, i); - } - } - } - - u(2, motion_vector_resolution_control_idc, 0, 2); - flag(intra_boundary_filtering_disable_flag); - - return 0; -} - -static int FUNC(vui_parameters_default)(CodedBitstreamContext *ctx, - RWContext *rw, H265RawVUI *current, - H265RawSPS *sps) { - infer(aspect_ratio_idc, 0); - - infer(video_format, 5); - infer(video_full_range_flag, 0); - infer(colour_primaries, 2); - infer(transfer_characteristics, 2); - infer(matrix_coefficients, 2); - - infer(chroma_sample_loc_type_top_field, 0); - infer(chroma_sample_loc_type_bottom_field, 0); - - infer(tiles_fixed_structure_flag, 0); - infer(motion_vectors_over_pic_boundaries_flag, 1); - infer(min_spatial_segmentation_idc, 0); - infer(max_bytes_per_pic_denom, 2); - infer(max_bits_per_min_cu_denom, 1); - infer(log2_max_mv_length_horizontal, 15); - infer(log2_max_mv_length_vertical, 15); - - return 0; -} - -static int FUNC(sps)(CodedBitstreamContext *ctx, RWContext *rw, - H265RawSPS *current) { - CodedBitstreamH265Context *h265 = ctx->priv_data; - const H265RawVPS *vps; - int err, i; - unsigned int min_cb_log2_size_y, ctb_log2_size_y, - min_cb_size_y, min_tb_log2_size_y; - - HEADER("Sequence Parameter Set"); - - CHECK(FUNC(nal_unit_header)(ctx, rw, ¤t->nal_unit_header, HEVC_NAL_SPS)); - - ub(4, sps_video_parameter_set_id); - h265->active_vps = vps = h265->vps[current->sps_video_parameter_set_id]; - - u(3, sps_max_sub_layers_minus1, 0, HEVC_MAX_SUB_LAYERS - 1); - flag(sps_temporal_id_nesting_flag); - if(vps) { - if(vps->vps_max_sub_layers_minus1 > current->sps_max_sub_layers_minus1) { - av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid stream: " - "sps_max_sub_layers_minus1 (%d) must be less than or equal to " - "vps_max_sub_layers_minus1 (%d).\n", - vps->vps_max_sub_layers_minus1, - current->sps_max_sub_layers_minus1); - return AVERROR_INVALIDDATA; - } - if(vps->vps_temporal_id_nesting_flag && - !current->sps_temporal_id_nesting_flag) { - av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid stream: " - "sps_temporal_id_nesting_flag must be 1 if " - "vps_temporal_id_nesting_flag is 1.\n"); - return AVERROR_INVALIDDATA; - } - } - - CHECK(FUNC(profile_tier_level)(ctx, rw, ¤t->profile_tier_level, - 1, current->sps_max_sub_layers_minus1)); - - ue(sps_seq_parameter_set_id, 0, 15); - - ue(chroma_format_idc, 0, 3); - if(current->chroma_format_idc == 3) - flag(separate_colour_plane_flag); - else - infer(separate_colour_plane_flag, 0); - - ue(pic_width_in_luma_samples, 1, HEVC_MAX_WIDTH); - ue(pic_height_in_luma_samples, 1, HEVC_MAX_HEIGHT); - - flag(conformance_window_flag); - if(current->conformance_window_flag) { - ue(conf_win_left_offset, 0, current->pic_width_in_luma_samples); - ue(conf_win_right_offset, 0, current->pic_width_in_luma_samples); - ue(conf_win_top_offset, 0, current->pic_height_in_luma_samples); - ue(conf_win_bottom_offset, 0, current->pic_height_in_luma_samples); - } - else { - infer(conf_win_left_offset, 0); - infer(conf_win_right_offset, 0); - infer(conf_win_top_offset, 0); - infer(conf_win_bottom_offset, 0); - } - - ue(bit_depth_luma_minus8, 0, 8); - ue(bit_depth_chroma_minus8, 0, 8); - - ue(log2_max_pic_order_cnt_lsb_minus4, 0, 12); - - flag(sps_sub_layer_ordering_info_present_flag); - for(i = (current->sps_sub_layer_ordering_info_present_flag ? - 0 : - current->sps_max_sub_layers_minus1); - i <= current->sps_max_sub_layers_minus1; i++) { - ues(sps_max_dec_pic_buffering_minus1[i], - 0, HEVC_MAX_DPB_SIZE - 1, 1, i); - ues(sps_max_num_reorder_pics[i], - 0, current->sps_max_dec_pic_buffering_minus1[i], 1, i); - ues(sps_max_latency_increase_plus1[i], - 0, UINT32_MAX - 1, 1, i); - } - if(!current->sps_sub_layer_ordering_info_present_flag) { - for(i = 0; i < current->sps_max_sub_layers_minus1; i++) { - infer(sps_max_dec_pic_buffering_minus1[i], - current->sps_max_dec_pic_buffering_minus1[current->sps_max_sub_layers_minus1]); - infer(sps_max_num_reorder_pics[i], - current->sps_max_num_reorder_pics[current->sps_max_sub_layers_minus1]); - infer(sps_max_latency_increase_plus1[i], - current->sps_max_latency_increase_plus1[current->sps_max_sub_layers_minus1]); - } - } - - ue(log2_min_luma_coding_block_size_minus3, 0, 3); - min_cb_log2_size_y = current->log2_min_luma_coding_block_size_minus3 + 3; - - ue(log2_diff_max_min_luma_coding_block_size, 0, 3); - ctb_log2_size_y = min_cb_log2_size_y + - current->log2_diff_max_min_luma_coding_block_size; - - min_cb_size_y = 1 << min_cb_log2_size_y; - if(current->pic_width_in_luma_samples % min_cb_size_y || - current->pic_height_in_luma_samples % min_cb_size_y) { - av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid dimensions: %ux%u not divisible " - "by MinCbSizeY = %u.\n", - current->pic_width_in_luma_samples, - current->pic_height_in_luma_samples, min_cb_size_y); - return AVERROR_INVALIDDATA; - } - - ue(log2_min_luma_transform_block_size_minus2, 0, min_cb_log2_size_y - 3); - min_tb_log2_size_y = current->log2_min_luma_transform_block_size_minus2 + 2; - - ue(log2_diff_max_min_luma_transform_block_size, - 0, FFMIN(ctb_log2_size_y, 5) - min_tb_log2_size_y); - - ue(max_transform_hierarchy_depth_inter, - 0, ctb_log2_size_y - min_tb_log2_size_y); - ue(max_transform_hierarchy_depth_intra, - 0, ctb_log2_size_y - min_tb_log2_size_y); - - flag(scaling_list_enabled_flag); - if(current->scaling_list_enabled_flag) { - flag(sps_scaling_list_data_present_flag); - if(current->sps_scaling_list_data_present_flag) - CHECK(FUNC(scaling_list_data)(ctx, rw, ¤t->scaling_list)); - } - else { - infer(sps_scaling_list_data_present_flag, 0); - } - - flag(amp_enabled_flag); - flag(sample_adaptive_offset_enabled_flag); - - flag(pcm_enabled_flag); - if(current->pcm_enabled_flag) { - u(4, pcm_sample_bit_depth_luma_minus1, - 0, current->bit_depth_luma_minus8 + 8 - 1); - u(4, pcm_sample_bit_depth_chroma_minus1, - 0, current->bit_depth_chroma_minus8 + 8 - 1); - - ue(log2_min_pcm_luma_coding_block_size_minus3, - FFMIN(min_cb_log2_size_y, 5) - 3, FFMIN(ctb_log2_size_y, 5) - 3); - ue(log2_diff_max_min_pcm_luma_coding_block_size, - 0, FFMIN(ctb_log2_size_y, 5) - (current->log2_min_pcm_luma_coding_block_size_minus3 + 3)); - - flag(pcm_loop_filter_disabled_flag); - } - - ue(num_short_term_ref_pic_sets, 0, HEVC_MAX_SHORT_TERM_REF_PIC_SETS); - for(i = 0; i < current->num_short_term_ref_pic_sets; i++) - CHECK(FUNC(st_ref_pic_set)(ctx, rw, ¤t->st_ref_pic_set[i], i, current)); - - flag(long_term_ref_pics_present_flag); - if(current->long_term_ref_pics_present_flag) { - ue(num_long_term_ref_pics_sps, 0, HEVC_MAX_LONG_TERM_REF_PICS); - for(i = 0; i < current->num_long_term_ref_pics_sps; i++) { - ubs(current->log2_max_pic_order_cnt_lsb_minus4 + 4, - lt_ref_pic_poc_lsb_sps[i], 1, i); - flags(used_by_curr_pic_lt_sps_flag[i], 1, i); - } - } - - flag(sps_temporal_mvp_enabled_flag); - flag(strong_intra_smoothing_enabled_flag); - - flag(vui_parameters_present_flag); - if(current->vui_parameters_present_flag) - CHECK(FUNC(vui_parameters)(ctx, rw, ¤t->vui, current)); - else - CHECK(FUNC(vui_parameters_default)(ctx, rw, ¤t->vui, current)); - - flag(sps_extension_present_flag); - if(current->sps_extension_present_flag) { - flag(sps_range_extension_flag); - flag(sps_multilayer_extension_flag); - flag(sps_3d_extension_flag); - flag(sps_scc_extension_flag); - ub(4, sps_extension_4bits); - } - - if(current->sps_range_extension_flag) - CHECK(FUNC(sps_range_extension)(ctx, rw, current)); - if(current->sps_multilayer_extension_flag) - return AVERROR_PATCHWELCOME; - if(current->sps_3d_extension_flag) - return AVERROR_PATCHWELCOME; - if(current->sps_scc_extension_flag) - CHECK(FUNC(sps_scc_extension)(ctx, rw, current)); - if(current->sps_extension_4bits) - CHECK(FUNC(extension_data)(ctx, rw, ¤t->extension_data)); - - CHECK(FUNC(rbsp_trailing_bits)(ctx, rw)); - - return 0; -} - -static int FUNC(pps_range_extension)(CodedBitstreamContext *ctx, RWContext *rw, - H265RawPPS *current) { - CodedBitstreamH265Context *h265 = ctx->priv_data; - const H265RawSPS *sps = h265->active_sps; - int err, i; - - if(current->transform_skip_enabled_flag) - ue(log2_max_transform_skip_block_size_minus2, 0, 3); - flag(cross_component_prediction_enabled_flag); - - flag(chroma_qp_offset_list_enabled_flag); - if(current->chroma_qp_offset_list_enabled_flag) { - ue(diff_cu_chroma_qp_offset_depth, - 0, sps->log2_diff_max_min_luma_coding_block_size); - ue(chroma_qp_offset_list_len_minus1, 0, 5); - for(i = 0; i <= current->chroma_qp_offset_list_len_minus1; i++) { - ses(cb_qp_offset_list[i], -12, +12, 1, i); - ses(cr_qp_offset_list[i], -12, +12, 1, i); - } - } - - ue(log2_sao_offset_scale_luma, 0, FFMAX(0, sps->bit_depth_luma_minus8 - 2)); - ue(log2_sao_offset_scale_chroma, 0, FFMAX(0, sps->bit_depth_chroma_minus8 - 2)); - - return 0; -} - -static int FUNC(pps_scc_extension)(CodedBitstreamContext *ctx, RWContext *rw, - H265RawPPS *current) { - int err, comp, i; - - flag(pps_curr_pic_ref_enabled_flag); - - flag(residual_adaptive_colour_transform_enabled_flag); - if(current->residual_adaptive_colour_transform_enabled_flag) { - flag(pps_slice_act_qp_offsets_present_flag); - se(pps_act_y_qp_offset_plus5, -7, +17); - se(pps_act_cb_qp_offset_plus5, -7, +17); - se(pps_act_cr_qp_offset_plus3, -9, +15); - } - else { - infer(pps_slice_act_qp_offsets_present_flag, 0); - infer(pps_act_y_qp_offset_plus5, 0); - infer(pps_act_cb_qp_offset_plus5, 0); - infer(pps_act_cr_qp_offset_plus3, 0); - } - - flag(pps_palette_predictor_initializer_present_flag); - if(current->pps_palette_predictor_initializer_present_flag) { - ue(pps_num_palette_predictor_initializer, 0, 128); - if(current->pps_num_palette_predictor_initializer > 0) { - flag(monochrome_palette_flag); - ue(luma_bit_depth_entry_minus8, 0, 8); - if(!current->monochrome_palette_flag) - ue(chroma_bit_depth_entry_minus8, 0, 8); - for(comp = 0; comp < (current->monochrome_palette_flag ? 1 : 3); comp++) { - int bit_depth = comp == 0 ? current->luma_bit_depth_entry_minus8 + 8 : current->chroma_bit_depth_entry_minus8 + 8; - for(i = 0; i < current->pps_num_palette_predictor_initializer; i++) - ubs(bit_depth, pps_palette_predictor_initializers[comp][i], 2, comp, i); - } - } - } - - return 0; -} - -static int FUNC(pps)(CodedBitstreamContext *ctx, RWContext *rw, - H265RawPPS *current) { - CodedBitstreamH265Context *h265 = ctx->priv_data; - const H265RawSPS *sps; - int err, i; - - HEADER("Picture Parameter Set"); - - CHECK(FUNC(nal_unit_header)(ctx, rw, ¤t->nal_unit_header, HEVC_NAL_PPS)); - - ue(pps_pic_parameter_set_id, 0, 63); - ue(pps_seq_parameter_set_id, 0, 15); - sps = h265->sps[current->pps_seq_parameter_set_id]; - if(!sps) { - av_log(ctx->log_ctx, AV_LOG_ERROR, "SPS id %d not available.\n", - current->pps_seq_parameter_set_id); - return AVERROR_INVALIDDATA; - } - h265->active_sps = sps; - - flag(dependent_slice_segments_enabled_flag); - flag(output_flag_present_flag); - ub(3, num_extra_slice_header_bits); - flag(sign_data_hiding_enabled_flag); - flag(cabac_init_present_flag); - - ue(num_ref_idx_l0_default_active_minus1, 0, 14); - ue(num_ref_idx_l1_default_active_minus1, 0, 14); - - se(init_qp_minus26, -(26 + 6 * sps->bit_depth_luma_minus8), +25); - - flag(constrained_intra_pred_flag); - flag(transform_skip_enabled_flag); - flag(cu_qp_delta_enabled_flag); - if(current->cu_qp_delta_enabled_flag) - ue(diff_cu_qp_delta_depth, - 0, sps->log2_diff_max_min_luma_coding_block_size); - else - infer(diff_cu_qp_delta_depth, 0); - - se(pps_cb_qp_offset, -12, +12); - se(pps_cr_qp_offset, -12, +12); - flag(pps_slice_chroma_qp_offsets_present_flag); - - flag(weighted_pred_flag); - flag(weighted_bipred_flag); - - flag(transquant_bypass_enabled_flag); - flag(tiles_enabled_flag); - flag(entropy_coding_sync_enabled_flag); - - if(current->tiles_enabled_flag) { - ue(num_tile_columns_minus1, 0, HEVC_MAX_TILE_COLUMNS); - ue(num_tile_rows_minus1, 0, HEVC_MAX_TILE_ROWS); - flag(uniform_spacing_flag); - if(!current->uniform_spacing_flag) { - for(i = 0; i < current->num_tile_columns_minus1; i++) - ues(column_width_minus1[i], 0, sps->pic_width_in_luma_samples, 1, i); - for(i = 0; i < current->num_tile_rows_minus1; i++) - ues(row_height_minus1[i], 0, sps->pic_height_in_luma_samples, 1, i); - } - flag(loop_filter_across_tiles_enabled_flag); - } - else { - infer(num_tile_columns_minus1, 0); - infer(num_tile_rows_minus1, 0); - } - - flag(pps_loop_filter_across_slices_enabled_flag); - flag(deblocking_filter_control_present_flag); - if(current->deblocking_filter_control_present_flag) { - flag(deblocking_filter_override_enabled_flag); - flag(pps_deblocking_filter_disabled_flag); - if(!current->pps_deblocking_filter_disabled_flag) { - se(pps_beta_offset_div2, -6, +6); - se(pps_tc_offset_div2, -6, +6); - } - else { - infer(pps_beta_offset_div2, 0); - infer(pps_tc_offset_div2, 0); - } - } - else { - infer(deblocking_filter_override_enabled_flag, 0); - infer(pps_deblocking_filter_disabled_flag, 0); - infer(pps_beta_offset_div2, 0); - infer(pps_tc_offset_div2, 0); - } - - flag(pps_scaling_list_data_present_flag); - if(current->pps_scaling_list_data_present_flag) - CHECK(FUNC(scaling_list_data)(ctx, rw, ¤t->scaling_list)); - - flag(lists_modification_present_flag); - - ue(log2_parallel_merge_level_minus2, - 0, (sps->log2_min_luma_coding_block_size_minus3 + 3 + sps->log2_diff_max_min_luma_coding_block_size - 2)); - - flag(slice_segment_header_extension_present_flag); - - flag(pps_extension_present_flag); - if(current->pps_extension_present_flag) { - flag(pps_range_extension_flag); - flag(pps_multilayer_extension_flag); - flag(pps_3d_extension_flag); - flag(pps_scc_extension_flag); - ub(4, pps_extension_4bits); - } - if(current->pps_range_extension_flag) - CHECK(FUNC(pps_range_extension)(ctx, rw, current)); - if(current->pps_multilayer_extension_flag) - return AVERROR_PATCHWELCOME; - if(current->pps_3d_extension_flag) - return AVERROR_PATCHWELCOME; - if(current->pps_scc_extension_flag) - CHECK(FUNC(pps_scc_extension)(ctx, rw, current)); - if(current->pps_extension_4bits) - CHECK(FUNC(extension_data)(ctx, rw, ¤t->extension_data)); - - CHECK(FUNC(rbsp_trailing_bits)(ctx, rw)); - - return 0; -} - -static int FUNC(aud)(CodedBitstreamContext *ctx, RWContext *rw, - H265RawAUD *current) { - int err; - - HEADER("Access Unit Delimiter"); - - CHECK(FUNC(nal_unit_header)(ctx, rw, ¤t->nal_unit_header, HEVC_NAL_AUD)); - - u(3, pic_type, 0, 2); - - CHECK(FUNC(rbsp_trailing_bits)(ctx, rw)); - - return 0; -} - -static int FUNC(ref_pic_lists_modification)(CodedBitstreamContext *ctx, RWContext *rw, - H265RawSliceHeader *current, - unsigned int num_pic_total_curr) { - unsigned int entry_size; - int err, i; - - entry_size = av_log2(num_pic_total_curr - 1) + 1; - - flag(ref_pic_list_modification_flag_l0); - if(current->ref_pic_list_modification_flag_l0) { - for(i = 0; i <= current->num_ref_idx_l0_active_minus1; i++) - us(entry_size, list_entry_l0[i], 0, num_pic_total_curr - 1, 1, i); - } - - if(current->slice_type == HEVC_SLICE_B) { - flag(ref_pic_list_modification_flag_l1); - if(current->ref_pic_list_modification_flag_l1) { - for(i = 0; i <= current->num_ref_idx_l1_active_minus1; i++) - us(entry_size, list_entry_l1[i], 0, num_pic_total_curr - 1, 1, i); - } - } - - return 0; -} - -static int FUNC(pred_weight_table)(CodedBitstreamContext *ctx, RWContext *rw, - H265RawSliceHeader *current) { - CodedBitstreamH265Context *h265 = ctx->priv_data; - const H265RawSPS *sps = h265->active_sps; - int err, i, j; - int chroma = !sps->separate_colour_plane_flag && - sps->chroma_format_idc != 0; - - ue(luma_log2_weight_denom, 0, 7); - if(chroma) - se(delta_chroma_log2_weight_denom, -7, 7); - else - infer(delta_chroma_log2_weight_denom, 0); - - for(i = 0; i <= current->num_ref_idx_l0_active_minus1; i++) { - if(1 /* is not same POC and same layer_id */) - flags(luma_weight_l0_flag[i], 1, i); - else - infer(luma_weight_l0_flag[i], 0); - } - if(chroma) { - for(i = 0; i <= current->num_ref_idx_l0_active_minus1; i++) { - if(1 /* is not same POC and same layer_id */) - flags(chroma_weight_l0_flag[i], 1, i); - else - infer(chroma_weight_l0_flag[i], 0); - } - } - - for(i = 0; i <= current->num_ref_idx_l0_active_minus1; i++) { - if(current->luma_weight_l0_flag[i]) { - ses(delta_luma_weight_l0[i], -128, +127, 1, i); - ses(luma_offset_l0[i], - -(1 << (sps->bit_depth_luma_minus8 + 8 - 1)), - ((1 << (sps->bit_depth_luma_minus8 + 8 - 1)) - 1), 1, i); - } - else { - infer(delta_luma_weight_l0[i], 0); - infer(luma_offset_l0[i], 0); - } - if(current->chroma_weight_l0_flag[i]) { - for(j = 0; j < 2; j++) { - ses(delta_chroma_weight_l0[i][j], -128, +127, 2, i, j); - ses(chroma_offset_l0[i][j], - -(4 << (sps->bit_depth_chroma_minus8 + 8 - 1)), - ((4 << (sps->bit_depth_chroma_minus8 + 8 - 1)) - 1), 2, i, j); - } - } - else { - for(j = 0; j < 2; j++) { - infer(delta_chroma_weight_l0[i][j], 0); - infer(chroma_offset_l0[i][j], 0); - } - } - } - - if(current->slice_type == HEVC_SLICE_B) { - for(i = 0; i <= current->num_ref_idx_l1_active_minus1; i++) { - if(1 /* RefPicList1[i] is not CurrPic, nor is it in a different layer */) - flags(luma_weight_l1_flag[i], 1, i); - else - infer(luma_weight_l1_flag[i], 0); - } - if(chroma) { - for(i = 0; i <= current->num_ref_idx_l1_active_minus1; i++) { - if(1 /* RefPicList1[i] is not CurrPic, nor is it in a different layer */) - flags(chroma_weight_l1_flag[i], 1, i); - else - infer(chroma_weight_l1_flag[i], 0); - } - } - - for(i = 0; i <= current->num_ref_idx_l1_active_minus1; i++) { - if(current->luma_weight_l1_flag[i]) { - ses(delta_luma_weight_l1[i], -128, +127, 1, i); - ses(luma_offset_l1[i], - -(1 << (sps->bit_depth_luma_minus8 + 8 - 1)), - ((1 << (sps->bit_depth_luma_minus8 + 8 - 1)) - 1), 1, i); - } - else { - infer(delta_luma_weight_l1[i], 0); - infer(luma_offset_l1[i], 0); - } - if(current->chroma_weight_l1_flag[i]) { - for(j = 0; j < 2; j++) { - ses(delta_chroma_weight_l1[i][j], -128, +127, 2, i, j); - ses(chroma_offset_l1[i][j], - -(4 << (sps->bit_depth_chroma_minus8 + 8 - 1)), - ((4 << (sps->bit_depth_chroma_minus8 + 8 - 1)) - 1), 2, i, j); - } - } - else { - for(j = 0; j < 2; j++) { - infer(delta_chroma_weight_l1[i][j], 0); - infer(chroma_offset_l1[i][j], 0); - } - } - } - } - - return 0; -} - -static int FUNC(slice_segment_header)(CodedBitstreamContext *ctx, RWContext *rw, - H265RawSliceHeader *current) { - CodedBitstreamH265Context *h265 = ctx->priv_data; - const H265RawSPS *sps; - const H265RawPPS *pps; - unsigned int min_cb_log2_size_y, ctb_log2_size_y, ctb_size_y; - unsigned int pic_width_in_ctbs_y, pic_height_in_ctbs_y, pic_size_in_ctbs_y; - unsigned int num_pic_total_curr = 0; - int err, i; - - HEADER("Slice Segment Header"); - - CHECK(FUNC(nal_unit_header)(ctx, rw, ¤t->nal_unit_header, -1)); - - flag(first_slice_segment_in_pic_flag); - - if(current->nal_unit_header.nal_unit_type >= HEVC_NAL_BLA_W_LP && - current->nal_unit_header.nal_unit_type <= HEVC_NAL_RSV_IRAP_VCL23) - flag(no_output_of_prior_pics_flag); - - ue(slice_pic_parameter_set_id, 0, 63); - - pps = h265->pps[current->slice_pic_parameter_set_id]; - if(!pps) { - av_log(ctx->log_ctx, AV_LOG_ERROR, "PPS id %d not available.\n", - current->slice_pic_parameter_set_id); - return AVERROR_INVALIDDATA; - } - h265->active_pps = pps; - - sps = h265->sps[pps->pps_seq_parameter_set_id]; - if(!sps) { - av_log(ctx->log_ctx, AV_LOG_ERROR, "SPS id %d not available.\n", - pps->pps_seq_parameter_set_id); - return AVERROR_INVALIDDATA; - } - h265->active_sps = sps; - - min_cb_log2_size_y = sps->log2_min_luma_coding_block_size_minus3 + 3; - ctb_log2_size_y = min_cb_log2_size_y + sps->log2_diff_max_min_luma_coding_block_size; - ctb_size_y = 1 << ctb_log2_size_y; - pic_width_in_ctbs_y = - (sps->pic_width_in_luma_samples + ctb_size_y - 1) / ctb_size_y; - pic_height_in_ctbs_y = - (sps->pic_height_in_luma_samples + ctb_size_y - 1) / ctb_size_y; - pic_size_in_ctbs_y = pic_width_in_ctbs_y * pic_height_in_ctbs_y; - - if(!current->first_slice_segment_in_pic_flag) { - unsigned int address_size = av_log2(pic_size_in_ctbs_y - 1) + 1; - if(pps->dependent_slice_segments_enabled_flag) - flag(dependent_slice_segment_flag); - else - infer(dependent_slice_segment_flag, 0); - u(address_size, slice_segment_address, 0, pic_size_in_ctbs_y - 1); - } - else { - infer(dependent_slice_segment_flag, 0); - } - - if(!current->dependent_slice_segment_flag) { - for(i = 0; i < pps->num_extra_slice_header_bits; i++) - flags(slice_reserved_flag[i], 1, i); - - ue(slice_type, 0, 2); - - if(pps->output_flag_present_flag) - flag(pic_output_flag); - - if(sps->separate_colour_plane_flag) - u(2, colour_plane_id, 0, 2); - - if(current->nal_unit_header.nal_unit_type != HEVC_NAL_IDR_W_RADL && - current->nal_unit_header.nal_unit_type != HEVC_NAL_IDR_N_LP) { - const H265RawSTRefPicSet *rps; - int dpb_slots_remaining; - - ub(sps->log2_max_pic_order_cnt_lsb_minus4 + 4, slice_pic_order_cnt_lsb); - - flag(short_term_ref_pic_set_sps_flag); - if(!current->short_term_ref_pic_set_sps_flag) { - CHECK(FUNC(st_ref_pic_set)(ctx, rw, ¤t->short_term_ref_pic_set, - sps->num_short_term_ref_pic_sets, sps)); - rps = ¤t->short_term_ref_pic_set; - } - else if(sps->num_short_term_ref_pic_sets > 1) { - unsigned int idx_size = av_log2(sps->num_short_term_ref_pic_sets - 1) + 1; - u(idx_size, short_term_ref_pic_set_idx, - 0, sps->num_short_term_ref_pic_sets - 1); - rps = &sps->st_ref_pic_set[current->short_term_ref_pic_set_idx]; - } - else { - infer(short_term_ref_pic_set_idx, 0); - rps = &sps->st_ref_pic_set[0]; - } - - dpb_slots_remaining = HEVC_MAX_DPB_SIZE - 1 - - rps->num_negative_pics - rps->num_positive_pics; - if(pps->pps_curr_pic_ref_enabled_flag && - (sps->sample_adaptive_offset_enabled_flag || - !pps->pps_deblocking_filter_disabled_flag || - pps->deblocking_filter_override_enabled_flag)) { - // This picture will occupy two DPB slots. - if(dpb_slots_remaining == 0) { - av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid stream: " - "short-term ref pic set contains too many pictures " - "to use with current picture reference enabled.\n"); - return AVERROR_INVALIDDATA; - } - --dpb_slots_remaining; - } - - num_pic_total_curr = 0; - for(i = 0; i < rps->num_negative_pics; i++) - if(rps->used_by_curr_pic_s0_flag[i]) - ++num_pic_total_curr; - for(i = 0; i < rps->num_positive_pics; i++) - if(rps->used_by_curr_pic_s1_flag[i]) - ++num_pic_total_curr; - - if(sps->long_term_ref_pics_present_flag) { - unsigned int idx_size; - - if(sps->num_long_term_ref_pics_sps > 0) { - ue(num_long_term_sps, 0, FFMIN(sps->num_long_term_ref_pics_sps, dpb_slots_remaining)); - idx_size = av_log2(sps->num_long_term_ref_pics_sps - 1) + 1; - dpb_slots_remaining -= current->num_long_term_sps; - } - else { - infer(num_long_term_sps, 0); - idx_size = 0; - } - ue(num_long_term_pics, 0, dpb_slots_remaining); - - for(i = 0; i < current->num_long_term_sps + - current->num_long_term_pics; - i++) { - if(i < current->num_long_term_sps) { - if(sps->num_long_term_ref_pics_sps > 1) - us(idx_size, lt_idx_sps[i], - 0, sps->num_long_term_ref_pics_sps - 1, 1, i); - if(sps->used_by_curr_pic_lt_sps_flag[current->lt_idx_sps[i]]) - ++num_pic_total_curr; - } - else { - ubs(sps->log2_max_pic_order_cnt_lsb_minus4 + 4, poc_lsb_lt[i], 1, i); - flags(used_by_curr_pic_lt_flag[i], 1, i); - if(current->used_by_curr_pic_lt_flag[i]) - ++num_pic_total_curr; - } - flags(delta_poc_msb_present_flag[i], 1, i); - if(current->delta_poc_msb_present_flag[i]) - ues(delta_poc_msb_cycle_lt[i], 0, UINT32_MAX - 1, 1, i); - else - infer(delta_poc_msb_cycle_lt[i], 0); - } - } - - if(sps->sps_temporal_mvp_enabled_flag) - flag(slice_temporal_mvp_enabled_flag); - else - infer(slice_temporal_mvp_enabled_flag, 0); - - if(pps->pps_curr_pic_ref_enabled_flag) - ++num_pic_total_curr; - } - - if(sps->sample_adaptive_offset_enabled_flag) { - flag(slice_sao_luma_flag); - if(!sps->separate_colour_plane_flag && sps->chroma_format_idc != 0) - flag(slice_sao_chroma_flag); - else - infer(slice_sao_chroma_flag, 0); - } - else { - infer(slice_sao_luma_flag, 0); - infer(slice_sao_chroma_flag, 0); - } - - if(current->slice_type == HEVC_SLICE_P || - current->slice_type == HEVC_SLICE_B) { - flag(num_ref_idx_active_override_flag); - if(current->num_ref_idx_active_override_flag) { - ue(num_ref_idx_l0_active_minus1, 0, 14); - if(current->slice_type == HEVC_SLICE_B) - ue(num_ref_idx_l1_active_minus1, 0, 14); - else - infer(num_ref_idx_l1_active_minus1, pps->num_ref_idx_l1_default_active_minus1); - } - else { - infer(num_ref_idx_l0_active_minus1, pps->num_ref_idx_l0_default_active_minus1); - infer(num_ref_idx_l1_active_minus1, pps->num_ref_idx_l1_default_active_minus1); - } - - if(pps->lists_modification_present_flag && num_pic_total_curr > 1) - CHECK(FUNC(ref_pic_lists_modification)(ctx, rw, current, - num_pic_total_curr)); - - if(current->slice_type == HEVC_SLICE_B) - flag(mvd_l1_zero_flag); - if(pps->cabac_init_present_flag) - flag(cabac_init_flag); - else - infer(cabac_init_flag, 0); - if(current->slice_temporal_mvp_enabled_flag) { - if(current->slice_type == HEVC_SLICE_B) - flag(collocated_from_l0_flag); - else - infer(collocated_from_l0_flag, 1); - if(current->collocated_from_l0_flag) { - if(current->num_ref_idx_l0_active_minus1 > 0) - ue(collocated_ref_idx, 0, current->num_ref_idx_l0_active_minus1); - else - infer(collocated_ref_idx, 0); - } - else { - if(current->num_ref_idx_l1_active_minus1 > 0) - ue(collocated_ref_idx, 0, current->num_ref_idx_l1_active_minus1); - else - infer(collocated_ref_idx, 0); - } - } - - if((pps->weighted_pred_flag && current->slice_type == HEVC_SLICE_P) || - (pps->weighted_bipred_flag && current->slice_type == HEVC_SLICE_B)) - CHECK(FUNC(pred_weight_table)(ctx, rw, current)); - - ue(five_minus_max_num_merge_cand, 0, 4); - if(sps->motion_vector_resolution_control_idc == 2) - flag(use_integer_mv_flag); - else - infer(use_integer_mv_flag, sps->motion_vector_resolution_control_idc); - } - - se(slice_qp_delta, - -6 * sps->bit_depth_luma_minus8 - (pps->init_qp_minus26 + 26), - +51 - (pps->init_qp_minus26 + 26)); - if(pps->pps_slice_chroma_qp_offsets_present_flag) { - se(slice_cb_qp_offset, -12, +12); - se(slice_cr_qp_offset, -12, +12); - } - else { - infer(slice_cb_qp_offset, 0); - infer(slice_cr_qp_offset, 0); - } - if(pps->pps_slice_act_qp_offsets_present_flag) { - se(slice_act_y_qp_offset, - -12 - (pps->pps_act_y_qp_offset_plus5 - 5), - +12 - (pps->pps_act_y_qp_offset_plus5 - 5)); - se(slice_act_cb_qp_offset, - -12 - (pps->pps_act_cb_qp_offset_plus5 - 5), - +12 - (pps->pps_act_cb_qp_offset_plus5 - 5)); - se(slice_act_cr_qp_offset, - -12 - (pps->pps_act_cr_qp_offset_plus3 - 3), - +12 - (pps->pps_act_cr_qp_offset_plus3 - 3)); - } - else { - infer(slice_act_y_qp_offset, 0); - infer(slice_act_cb_qp_offset, 0); - infer(slice_act_cr_qp_offset, 0); - } - if(pps->chroma_qp_offset_list_enabled_flag) - flag(cu_chroma_qp_offset_enabled_flag); - else - infer(cu_chroma_qp_offset_enabled_flag, 0); - - if(pps->deblocking_filter_override_enabled_flag) - flag(deblocking_filter_override_flag); - else - infer(deblocking_filter_override_flag, 0); - if(current->deblocking_filter_override_flag) { - flag(slice_deblocking_filter_disabled_flag); - if(!current->slice_deblocking_filter_disabled_flag) { - se(slice_beta_offset_div2, -6, +6); - se(slice_tc_offset_div2, -6, +6); - } - else { - infer(slice_beta_offset_div2, pps->pps_beta_offset_div2); - infer(slice_tc_offset_div2, pps->pps_tc_offset_div2); - } - } - else { - infer(slice_deblocking_filter_disabled_flag, - pps->pps_deblocking_filter_disabled_flag); - infer(slice_beta_offset_div2, pps->pps_beta_offset_div2); - infer(slice_tc_offset_div2, pps->pps_tc_offset_div2); - } - if(pps->pps_loop_filter_across_slices_enabled_flag && - (current->slice_sao_luma_flag || current->slice_sao_chroma_flag || - !current->slice_deblocking_filter_disabled_flag)) - flag(slice_loop_filter_across_slices_enabled_flag); - else - infer(slice_loop_filter_across_slices_enabled_flag, - pps->pps_loop_filter_across_slices_enabled_flag); - } - - if(pps->tiles_enabled_flag || pps->entropy_coding_sync_enabled_flag) { - unsigned int num_entry_point_offsets_limit; - if(!pps->tiles_enabled_flag && pps->entropy_coding_sync_enabled_flag) - num_entry_point_offsets_limit = pic_height_in_ctbs_y - 1; - else if(pps->tiles_enabled_flag && !pps->entropy_coding_sync_enabled_flag) - num_entry_point_offsets_limit = - (pps->num_tile_columns_minus1 + 1) * (pps->num_tile_rows_minus1 + 1); - else - num_entry_point_offsets_limit = - (pps->num_tile_columns_minus1 + 1) * pic_height_in_ctbs_y - 1; - ue(num_entry_point_offsets, 0, num_entry_point_offsets_limit); - - if(current->num_entry_point_offsets > HEVC_MAX_ENTRY_POINT_OFFSETS) { - av_log(ctx->log_ctx, AV_LOG_ERROR, "Too many entry points: " - "%" PRIu16 ".\n", - current->num_entry_point_offsets); - return AVERROR_PATCHWELCOME; - } - - if(current->num_entry_point_offsets > 0) { - ue(offset_len_minus1, 0, 31); - for(i = 0; i < current->num_entry_point_offsets; i++) - ubs(current->offset_len_minus1 + 1, entry_point_offset_minus1[i], 1, i); - } - } - - if(pps->slice_segment_header_extension_present_flag) { - ue(slice_segment_header_extension_length, 0, 256); - for(i = 0; i < current->slice_segment_header_extension_length; i++) - us(8, slice_segment_header_extension_data_byte[i], 0x00, 0xff, 1, i); - } - - CHECK(FUNC(byte_alignment)(ctx, rw)); - - return 0; -} - -static int FUNC(sei_buffering_period)(CodedBitstreamContext *ctx, RWContext *rw, - H265RawSEIBufferingPeriod *current, SEIMessageState *sei) { - CodedBitstreamH265Context *h265 = ctx->priv_data; - const H265RawSPS *sps; - const H265RawHRDParameters *hrd; - int err, i, length; - -#ifdef READ - int start_pos, end_pos; - start_pos = get_bits_count(rw); -#endif - - HEADER("Buffering Period"); - - ue(bp_seq_parameter_set_id, 0, HEVC_MAX_SPS_COUNT - 1); - - sps = h265->sps[current->bp_seq_parameter_set_id]; - if(!sps) { - av_log(ctx->log_ctx, AV_LOG_ERROR, "SPS id %d not available.\n", - current->bp_seq_parameter_set_id); - return AVERROR_INVALIDDATA; - } - h265->active_sps = sps; - - if(!sps->vui_parameters_present_flag || - !sps->vui.vui_hrd_parameters_present_flag) { - av_log(ctx->log_ctx, AV_LOG_ERROR, "Buffering period SEI requires " - "HRD parameters to be present in SPS.\n"); - return AVERROR_INVALIDDATA; - } - hrd = &sps->vui.hrd_parameters; - if(!hrd->nal_hrd_parameters_present_flag && - !hrd->vcl_hrd_parameters_present_flag) { - av_log(ctx->log_ctx, AV_LOG_ERROR, "Buffering period SEI requires " - "NAL or VCL HRD parameters to be present.\n"); - return AVERROR_INVALIDDATA; - } - - if(!hrd->sub_pic_hrd_params_present_flag) - flag(irap_cpb_params_present_flag); - else - infer(irap_cpb_params_present_flag, 0); - if(current->irap_cpb_params_present_flag) { - length = hrd->au_cpb_removal_delay_length_minus1 + 1; - ub(length, cpb_delay_offset); - length = hrd->dpb_output_delay_length_minus1 + 1; - ub(length, dpb_delay_offset); - } - else { - infer(cpb_delay_offset, 0); - infer(dpb_delay_offset, 0); - } - - flag(concatenation_flag); - - length = hrd->au_cpb_removal_delay_length_minus1 + 1; - ub(length, au_cpb_removal_delay_delta_minus1); - - if(hrd->nal_hrd_parameters_present_flag) { - for(i = 0; i <= hrd->cpb_cnt_minus1[0]; i++) { - length = hrd->initial_cpb_removal_delay_length_minus1 + 1; - - ubs(length, nal_initial_cpb_removal_delay[i], 1, i); - ubs(length, nal_initial_cpb_removal_offset[i], 1, i); - - if(hrd->sub_pic_hrd_params_present_flag || - current->irap_cpb_params_present_flag) { - ubs(length, nal_initial_alt_cpb_removal_delay[i], 1, i); - ubs(length, nal_initial_alt_cpb_removal_offset[i], 1, i); - } - } - } - if(hrd->vcl_hrd_parameters_present_flag) { - for(i = 0; i <= hrd->cpb_cnt_minus1[0]; i++) { - length = hrd->initial_cpb_removal_delay_length_minus1 + 1; - - ubs(length, vcl_initial_cpb_removal_delay[i], 1, i); - ubs(length, vcl_initial_cpb_removal_offset[i], 1, i); - - if(hrd->sub_pic_hrd_params_present_flag || - current->irap_cpb_params_present_flag) { - ubs(length, vcl_initial_alt_cpb_removal_delay[i], 1, i); - ubs(length, vcl_initial_alt_cpb_removal_offset[i], 1, i); - } - } - } - -#ifdef READ - end_pos = get_bits_count(rw); - if(cbs_h265_payload_extension_present(rw, sei->payload_size, - end_pos - start_pos)) - flag(use_alt_cpb_params_flag); - else - infer(use_alt_cpb_params_flag, 0); -#else - // If unknown extension data exists, then use_alt_cpb_params_flag is - // coded in the bitstream and must be written even if it's 0. - if(current->use_alt_cpb_params_flag || sei->extension_present) { - flag(use_alt_cpb_params_flag); - // Ensure this bit is not the last in the payload by making the - // more_data_in_payload() check evaluate to true, so it may not - // be mistaken as something else by decoders. - sei->extension_present = 1; - } -#endif - - return 0; -} - -static int FUNC(sei_pic_timing)(CodedBitstreamContext *ctx, RWContext *rw, - H265RawSEIPicTiming *current, SEIMessageState *sei) { - CodedBitstreamH265Context *h265 = ctx->priv_data; - const H265RawSPS *sps; - const H265RawHRDParameters *hrd; - int err, expected_source_scan_type, i, length; - - HEADER("Picture Timing"); - - sps = h265->active_sps; - if(!sps) { - av_log(ctx->log_ctx, AV_LOG_ERROR, - "No active SPS for pic_timing.\n"); - return AVERROR_INVALIDDATA; - } - - expected_source_scan_type = 2 - - 2 * sps->profile_tier_level.general_interlaced_source_flag - - sps->profile_tier_level.general_progressive_source_flag; - - if(sps->vui.frame_field_info_present_flag) { - u(4, pic_struct, 0, 12); - u(2, source_scan_type, - expected_source_scan_type >= 0 ? expected_source_scan_type : 0, - expected_source_scan_type >= 0 ? expected_source_scan_type : 2); - flag(duplicate_flag); - } - else { - infer(pic_struct, 0); - infer(source_scan_type, - expected_source_scan_type >= 0 ? expected_source_scan_type : 2); - infer(duplicate_flag, 0); - } - - if(sps->vui_parameters_present_flag && - sps->vui.vui_hrd_parameters_present_flag) - hrd = &sps->vui.hrd_parameters; - else - hrd = NULL; - if(hrd && (hrd->nal_hrd_parameters_present_flag || - hrd->vcl_hrd_parameters_present_flag)) { - length = hrd->au_cpb_removal_delay_length_minus1 + 1; - ub(length, au_cpb_removal_delay_minus1); - - length = hrd->dpb_output_delay_length_minus1 + 1; - ub(length, pic_dpb_output_delay); - - if(hrd->sub_pic_hrd_params_present_flag) { - length = hrd->dpb_output_delay_du_length_minus1 + 1; - ub(length, pic_dpb_output_du_delay); - } - - if(hrd->sub_pic_hrd_params_present_flag && - hrd->sub_pic_cpb_params_in_pic_timing_sei_flag) { - // Each decoding unit must contain at least one slice segment. - ue(num_decoding_units_minus1, 0, HEVC_MAX_SLICE_SEGMENTS); - flag(du_common_cpb_removal_delay_flag); - - length = hrd->du_cpb_removal_delay_increment_length_minus1 + 1; - if(current->du_common_cpb_removal_delay_flag) - ub(length, du_common_cpb_removal_delay_increment_minus1); - - for(i = 0; i <= current->num_decoding_units_minus1; i++) { - ues(num_nalus_in_du_minus1[i], - 0, HEVC_MAX_SLICE_SEGMENTS, 1, i); - if(!current->du_common_cpb_removal_delay_flag && - i < current->num_decoding_units_minus1) - ubs(length, du_cpb_removal_delay_increment_minus1[i], 1, i); - } - } - } - - return 0; -} - -static int FUNC(sei_pan_scan_rect)(CodedBitstreamContext *ctx, RWContext *rw, - H265RawSEIPanScanRect *current, SEIMessageState *sei) { - int err, i; - - HEADER("Pan-Scan Rectangle"); - - ue(pan_scan_rect_id, 0, UINT32_MAX - 1); - flag(pan_scan_rect_cancel_flag); - - if(!current->pan_scan_rect_cancel_flag) { - ue(pan_scan_cnt_minus1, 0, 2); - - for(i = 0; i <= current->pan_scan_cnt_minus1; i++) { - ses(pan_scan_rect_left_offset[i], INT32_MIN + 1, INT32_MAX, 1, i); - ses(pan_scan_rect_right_offset[i], INT32_MIN + 1, INT32_MAX, 1, i); - ses(pan_scan_rect_top_offset[i], INT32_MIN + 1, INT32_MAX, 1, i); - ses(pan_scan_rect_bottom_offset[i], INT32_MIN + 1, INT32_MAX, 1, i); - } - - flag(pan_scan_rect_persistence_flag); - } - - return 0; -} - -static int FUNC(sei_recovery_point)(CodedBitstreamContext *ctx, RWContext *rw, - H265RawSEIRecoveryPoint *current, SEIMessageState *sei) { - int err; - - HEADER("Recovery Point"); - - se(recovery_poc_cnt, -32768, 32767); - - flag(exact_match_flag); - flag(broken_link_flag); - - return 0; -} - -static int FUNC(sei_display_orientation)(CodedBitstreamContext *ctx, RWContext *rw, - H265RawSEIDisplayOrientation *current, SEIMessageState *sei) { - int err; - - HEADER("Display Orientation"); - - flag(display_orientation_cancel_flag); - if(!current->display_orientation_cancel_flag) { - flag(hor_flip); - flag(ver_flip); - ub(16, anticlockwise_rotation); - flag(display_orientation_persistence_flag); - } - - return 0; -} - -static int FUNC(sei_active_parameter_sets)(CodedBitstreamContext *ctx, RWContext *rw, - H265RawSEIActiveParameterSets *current, SEIMessageState *sei) { - CodedBitstreamH265Context *h265 = ctx->priv_data; - const H265RawVPS *vps; - int err, i; - - HEADER("Active Parameter Sets"); - - u(4, active_video_parameter_set_id, 0, HEVC_MAX_VPS_COUNT); - vps = h265->vps[current->active_video_parameter_set_id]; - if(!vps) { - av_log(ctx->log_ctx, AV_LOG_ERROR, "VPS id %d not available for active " - "parameter sets.\n", - current->active_video_parameter_set_id); - return AVERROR_INVALIDDATA; - } - h265->active_vps = vps; - - flag(self_contained_cvs_flag); - flag(no_parameter_set_update_flag); - - ue(num_sps_ids_minus1, 0, HEVC_MAX_SPS_COUNT - 1); - for(i = 0; i <= current->num_sps_ids_minus1; i++) - ues(active_seq_parameter_set_id[i], 0, HEVC_MAX_SPS_COUNT - 1, 1, i); - - for(i = vps->vps_base_layer_internal_flag; - i <= FFMIN(62, vps->vps_max_layers_minus1); i++) { - ues(layer_sps_idx[i], 0, current->num_sps_ids_minus1, 1, i); - - if(i == 0) - h265->active_sps = h265->sps[current->active_seq_parameter_set_id[current->layer_sps_idx[0]]]; - } - - return 0; -} - -static int FUNC(sei_decoded_picture_hash)(CodedBitstreamContext *ctx, RWContext *rw, - H265RawSEIDecodedPictureHash *current, SEIMessageState *sei) { - CodedBitstreamH265Context *h265 = ctx->priv_data; - const H265RawSPS *sps = h265->active_sps; - int err, c, i; - - HEADER("Decoded Picture Hash"); - - if(!sps) { - av_log(ctx->log_ctx, AV_LOG_ERROR, - "No active SPS for decoded picture hash.\n"); - return AVERROR_INVALIDDATA; - } - - u(8, hash_type, 0, 2); - - for(c = 0; c < (sps->chroma_format_idc == 0 ? 1 : 3); c++) { - if(current->hash_type == 0) { - for(i = 0; i < 16; i++) - us(8, picture_md5[c][i], 0x00, 0xff, 2, c, i); - } - else if(current->hash_type == 1) { - us(16, picture_crc[c], 0x0000, 0xffff, 1, c); - } - else if(current->hash_type == 2) { - us(32, picture_checksum[c], 0x00000000, 0xffffffff, 1, c); - } - } - - return 0; -} - -static int FUNC(sei_time_code)(CodedBitstreamContext *ctx, RWContext *rw, - H265RawSEITimeCode *current, SEIMessageState *sei) { - int err, i; - - HEADER("Time Code"); - - u(2, num_clock_ts, 1, 3); - - for(i = 0; i < current->num_clock_ts; i++) { - flags(clock_timestamp_flag[i], 1, i); - - if(current->clock_timestamp_flag[i]) { - flags(units_field_based_flag[i], 1, i); - us(5, counting_type[i], 0, 6, 1, i); - flags(full_timestamp_flag[i], 1, i); - flags(discontinuity_flag[i], 1, i); - flags(cnt_dropped_flag[i], 1, i); - - ubs(9, n_frames[i], 1, i); - - if(current->full_timestamp_flag[i]) { - us(6, seconds_value[i], 0, 59, 1, i); - us(6, minutes_value[i], 0, 59, 1, i); - us(5, hours_value[i], 0, 23, 1, i); - } - else { - flags(seconds_flag[i], 1, i); - if(current->seconds_flag[i]) { - us(6, seconds_value[i], 0, 59, 1, i); - flags(minutes_flag[i], 1, i); - if(current->minutes_flag[i]) { - us(6, minutes_value[i], 0, 59, 1, i); - flags(hours_flag[i], 1, i); - if(current->hours_flag[i]) - us(5, hours_value[i], 0, 23, 1, i); - } - } - } - - ubs(5, time_offset_length[i], 1, i); - if(current->time_offset_length[i] > 0) - ibs(current->time_offset_length[i], time_offset_value[i], 1, i); - else - infer(time_offset_value[i], 0); - } - } - - return 0; -} - -static int FUNC(sei_alpha_channel_info)(CodedBitstreamContext *ctx, RWContext *rw, - H265RawSEIAlphaChannelInfo *current, SEIMessageState *sei) { - int err, length; - - HEADER("Alpha Channel Information"); - - flag(alpha_channel_cancel_flag); - if(!current->alpha_channel_cancel_flag) { - ub(3, alpha_channel_use_idc); - ub(3, alpha_channel_bit_depth_minus8); - length = current->alpha_channel_bit_depth_minus8 + 9; - ub(length, alpha_transparent_value); - ub(length, alpha_opaque_value); - flag(alpha_channel_incr_flag); - flag(alpha_channel_clip_flag); - if(current->alpha_channel_clip_flag) - flag(alpha_channel_clip_type_flag); - } - else { - infer(alpha_channel_use_idc, 2); - infer(alpha_channel_incr_flag, 0); - infer(alpha_channel_clip_flag, 0); - } - - return 0; -} - -static int FUNC(sei)(CodedBitstreamContext *ctx, RWContext *rw, - H265RawSEI *current, int prefix) { - int err; - - if(prefix) - HEADER("Prefix Supplemental Enhancement Information"); - else - HEADER("Suffix Supplemental Enhancement Information"); - - CHECK(FUNC(nal_unit_header)(ctx, rw, ¤t->nal_unit_header, - prefix ? HEVC_NAL_SEI_PREFIX : HEVC_NAL_SEI_SUFFIX)); - - CHECK(FUNC_SEI(message_list)(ctx, rw, ¤t->message_list, prefix)); - - CHECK(FUNC(rbsp_trailing_bits)(ctx, rw)); - - return 0; -} diff --git a/third-party/cbs/cbs_internal.h b/third-party/cbs/cbs_internal.h deleted file mode 100644 index 4fb6e7c4d40..00000000000 --- a/third-party/cbs/cbs_internal.h +++ /dev/null @@ -1,220 +0,0 @@ -/* - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_CBS_INTERNAL_H -#define AVCODEC_CBS_INTERNAL_H - -#include - -#include -#include - -#include "cbs/cbs.h" -#include "get_bits.h" -#include "put_bits.h" - - -enum CBSContentType { - // Unit content is a simple structure. - CBS_CONTENT_TYPE_POD, - // Unit content contains some references to other structures, but all - // managed via buffer reference counting. The descriptor defines the - // structure offsets of every buffer reference. - CBS_CONTENT_TYPE_INTERNAL_REFS, - // Unit content is something more complex. The descriptor defines - // special functions to manage the content. - CBS_CONTENT_TYPE_COMPLEX, -}; - -enum { - // Maximum number of unit types described by the same unit type - // descriptor. - CBS_MAX_UNIT_TYPES = 3, - // Maximum number of reference buffer offsets in any one unit. - CBS_MAX_REF_OFFSETS = 2, - // Special value used in a unit type descriptor to indicate that it - // applies to a large range of types rather than a set of discrete - // values. - CBS_UNIT_TYPE_RANGE = -1, -}; - -typedef const struct CodedBitstreamUnitTypeDescriptor { - // Number of entries in the unit_types array, or the special value - // CBS_UNIT_TYPE_RANGE to indicate that the range fields should be - // used instead. - int nb_unit_types; - - // Array of unit types that this entry describes. - const CodedBitstreamUnitType unit_types[CBS_MAX_UNIT_TYPES]; - - // Start and end of unit type range, used if nb_unit_types is - // CBS_UNIT_TYPE_RANGE. - const CodedBitstreamUnitType unit_type_range_start; - const CodedBitstreamUnitType unit_type_range_end; - - // The type of content described. - enum CBSContentType content_type; - // The size of the structure which should be allocated to contain - // the decomposed content of this type of unit. - size_t content_size; - - // Number of entries in the ref_offsets array. Only used if the - // content_type is CBS_CONTENT_TYPE_INTERNAL_REFS. - int nb_ref_offsets; - // The structure must contain two adjacent elements: - // type *field; - // AVBufferRef *field_ref; - // where field points to something in the buffer referred to by - // field_ref. This offset is then set to offsetof(struct, field). - size_t ref_offsets[CBS_MAX_REF_OFFSETS]; - - void (*content_free)(void *opaque, uint8_t *data); - int (*content_clone)(AVBufferRef **ref, CodedBitstreamUnit *unit); -} CodedBitstreamUnitTypeDescriptor; - -typedef struct CodedBitstreamType { - enum AVCodecID codec_id; - - // A class for the private data, used to declare private AVOptions. - // This field is NULL for types that do not declare any options. - // If this field is non-NULL, the first member of the filter private data - // must be a pointer to AVClass. - const AVClass *priv_class; - - size_t priv_data_size; - - // List of unit type descriptors for this codec. - // Terminated by a descriptor with nb_unit_types equal to zero. - const CodedBitstreamUnitTypeDescriptor *unit_types; - - // Split frag->data into coded bitstream units, creating the - // frag->units array. Fill data but not content on each unit. - // The header argument should be set if the fragment came from - // a header block, which may require different parsing for some - // codecs (e.g. the AVCC header in H.264). - int (*split_fragment)(CodedBitstreamContext *ctx, - CodedBitstreamFragment *frag, - int header); - - // Read the unit->data bitstream and decompose it, creating - // unit->content. - int (*read_unit)(CodedBitstreamContext *ctx, - CodedBitstreamUnit *unit); - - // Write the data bitstream from unit->content into pbc. - // Return value AVERROR(ENOSPC) indicates that pbc was too small. - int (*write_unit)(CodedBitstreamContext *ctx, - CodedBitstreamUnit *unit, - PutBitContext *pbc); - - // Read the data from all of frag->units and assemble it into - // a bitstream for the whole fragment. - int (*assemble_fragment)(CodedBitstreamContext *ctx, - CodedBitstreamFragment *frag); - - // Reset the codec internal state. - void (*flush)(CodedBitstreamContext *ctx); - - // Free the codec internal state. - void (*close)(CodedBitstreamContext *ctx); -} CodedBitstreamType; - - -// Helper functions for trace output. - -void ff_cbs_trace_header(CodedBitstreamContext *ctx, - const char *name); - -void ff_cbs_trace_syntax_element(CodedBitstreamContext *ctx, int position, - const char *name, const int *subscripts, - const char *bitstring, int64_t value); - - -// Helper functions for read/write of common bitstream elements, including -// generation of trace output. - -int ff_cbs_read_unsigned(CodedBitstreamContext *ctx, GetBitContext *gbc, - int width, const char *name, - const int *subscripts, uint32_t *write_to, - uint32_t range_min, uint32_t range_max); - -int ff_cbs_write_unsigned(CodedBitstreamContext *ctx, PutBitContext *pbc, - int width, const char *name, - const int *subscripts, uint32_t value, - uint32_t range_min, uint32_t range_max); - -int ff_cbs_read_signed(CodedBitstreamContext *ctx, GetBitContext *gbc, - int width, const char *name, - const int *subscripts, int32_t *write_to, - int32_t range_min, int32_t range_max); - -int ff_cbs_write_signed(CodedBitstreamContext *ctx, PutBitContext *pbc, - int width, const char *name, - const int *subscripts, int32_t value, - int32_t range_min, int32_t range_max); - -// The largest unsigned value representable in N bits, suitable for use as -// range_max in the above functions. -#define MAX_UINT_BITS(length) ((UINT64_C(1) << (length)) - 1) - -// The largest signed value representable in N bits, suitable for use as -// range_max in the above functions. -#define MAX_INT_BITS(length) ((INT64_C(1) << ((length)-1)) - 1) - -// The smallest signed value representable in N bits, suitable for use as -// range_min in the above functions. -#define MIN_INT_BITS(length) (-(INT64_C(1) << ((length)-1))) - - -#define CBS_UNIT_TYPE_POD(type, structure) \ - { \ - .nb_unit_types = 1, \ - .unit_types = { type }, \ - .content_type = CBS_CONTENT_TYPE_POD, \ - .content_size = sizeof(structure), \ - } -#define CBS_UNIT_TYPE_INTERNAL_REF(type, structure, ref_field) \ - { \ - .nb_unit_types = 1, \ - .unit_types = { type }, \ - .content_type = CBS_CONTENT_TYPE_INTERNAL_REFS, \ - .content_size = sizeof(structure), \ - .nb_ref_offsets = 1, \ - .ref_offsets = { offsetof(structure, ref_field) }, \ - } -#define CBS_UNIT_TYPE_COMPLEX(type, structure, free_func) \ - { \ - .nb_unit_types = 1, \ - .unit_types = { type }, \ - .content_type = CBS_CONTENT_TYPE_COMPLEX, \ - .content_size = sizeof(structure), \ - .content_free = free_func, \ - } -#define CBS_UNIT_TYPE_END_OF_LIST \ - { .nb_unit_types = 0 } - - -extern const CodedBitstreamType ff_cbs_type_av1; -extern const CodedBitstreamType ff_cbs_type_h264; -extern const CodedBitstreamType ff_cbs_type_h265; -extern const CodedBitstreamType ff_cbs_type_jpeg; -extern const CodedBitstreamType ff_cbs_type_mpeg2; -extern const CodedBitstreamType ff_cbs_type_vp9; - - -#endif /* AVCODEC_CBS_INTERNAL_H */ diff --git a/third-party/cbs/cbs_jpeg.c b/third-party/cbs/cbs_jpeg.c deleted file mode 100644 index bb4f08a14d9..00000000000 --- a/third-party/cbs/cbs_jpeg.c +++ /dev/null @@ -1,482 +0,0 @@ -/* - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "cbs/cbs_jpeg.h" -#include "cbs/cbs.h" - -#include "cbs_internal.h" - - -#define HEADER(name) \ - do { \ - ff_cbs_trace_header(ctx, name); \ - } while(0) - -#define CHECK(call) \ - do { \ - err = (call); \ - if(err < 0) \ - return err; \ - } while(0) - -#define SUBSCRIPTS(subs, ...) (subs > 0 ? ((int[subs + 1]) { subs, __VA_ARGS__ }) : NULL) - -#define u(width, name, range_min, range_max) \ - xu(width, name, range_min, range_max, 0, ) -#define us(width, name, sub, range_min, range_max) \ - xu(width, name, range_min, range_max, 1, sub) - - -#define READ -#define READWRITE read -#define RWContext GetBitContext -#define FUNC(name) cbs_jpeg_read_##name - -#define xu(width, name, range_min, range_max, subs, ...) \ - do { \ - uint32_t value; \ - CHECK(ff_cbs_read_unsigned(ctx, rw, width, #name, \ - SUBSCRIPTS(subs, __VA_ARGS__), \ - &value, range_min, range_max)); \ - current->name = value; \ - } while(0) - -#include "cbs_jpeg_syntax_template.c" - -#undef READ -#undef READWRITE -#undef RWContext -#undef FUNC -#undef xu - -#define WRITE -#define READWRITE write -#define RWContext PutBitContext -#define FUNC(name) cbs_jpeg_write_##name - -#define xu(width, name, range_min, range_max, subs, ...) \ - do { \ - uint32_t value = current->name; \ - CHECK(ff_cbs_write_unsigned(ctx, rw, width, #name, \ - SUBSCRIPTS(subs, __VA_ARGS__), \ - value, range_min, range_max)); \ - } while(0) - - -#include "cbs_jpeg_syntax_template.c" - -#undef WRITE -#undef READWRITE -#undef RWContext -#undef FUNC -#undef xu - - -static void cbs_jpeg_free_application_data(void *opaque, uint8_t *content) { - JPEGRawApplicationData *ad = (JPEGRawApplicationData *)content; - av_buffer_unref(&ad->Ap_ref); - av_freep(&content); -} - -static void cbs_jpeg_free_comment(void *opaque, uint8_t *content) { - JPEGRawComment *comment = (JPEGRawComment *)content; - av_buffer_unref(&comment->Cm_ref); - av_freep(&content); -} - -static void cbs_jpeg_free_scan(void *opaque, uint8_t *content) { - JPEGRawScan *scan = (JPEGRawScan *)content; - av_buffer_unref(&scan->data_ref); - av_freep(&content); -} - -static int cbs_jpeg_split_fragment(CodedBitstreamContext *ctx, - CodedBitstreamFragment *frag, - int header) { - AVBufferRef *data_ref; - uint8_t *data; - size_t data_size; - int unit, start, end, marker, next_start, next_marker; - int err, i, j, length; - - if(frag->data_size < 4) { - // Definitely too short to be meaningful. - return AVERROR_INVALIDDATA; - } - - for(i = 0; i + 1 < frag->data_size && frag->data[i] != 0xff; i++) - ; - if(i > 0) { - av_log(ctx->log_ctx, AV_LOG_WARNING, "Discarding %d bytes at " - "beginning of image.\n", - i); - } - for(++i; i + 1 < frag->data_size && frag->data[i] == 0xff; i++) - ; - if(i + 1 >= frag->data_size && frag->data[i]) { - av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid JPEG image: " - "no SOI marker found.\n"); - return AVERROR_INVALIDDATA; - } - marker = frag->data[i]; - if(marker != JPEG_MARKER_SOI) { - av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid JPEG image: first " - "marker is %02x, should be SOI.\n", - marker); - return AVERROR_INVALIDDATA; - } - for(++i; i + 1 < frag->data_size && frag->data[i] == 0xff; i++) - ; - if(i + 1 >= frag->data_size) { - av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid JPEG image: " - "no image content found.\n"); - return AVERROR_INVALIDDATA; - } - marker = frag->data[i]; - start = i + 1; - - for(unit = 0;; unit++) { - if(marker == JPEG_MARKER_EOI) { - break; - } - else if(marker == JPEG_MARKER_SOS) { - next_marker = -1; - end = start; - for(i = start; i + 1 < frag->data_size; i++) { - if(frag->data[i] != 0xff) - continue; - end = i; - for(++i; i + 1 < frag->data_size && - frag->data[i] == 0xff; - i++) - ; - if(i + 1 < frag->data_size) { - if(frag->data[i] == 0x00) - continue; - next_marker = frag->data[i]; - next_start = i + 1; - } - break; - } - } - else { - i = start; - if(i + 2 > frag->data_size) { - av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid JPEG image: " - "truncated at %02x marker.\n", - marker); - return AVERROR_INVALIDDATA; - } - length = AV_RB16(frag->data + i); - if(i + length > frag->data_size) { - av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid JPEG image: " - "truncated at %02x marker segment.\n", - marker); - return AVERROR_INVALIDDATA; - } - end = start + length; - - i = end; - if(frag->data[i] != 0xff) { - next_marker = -1; - } - else { - for(++i; i + 1 < frag->data_size && - frag->data[i] == 0xff; - i++) - ; - if(i + 1 >= frag->data_size) { - next_marker = -1; - } - else { - next_marker = frag->data[i]; - next_start = i + 1; - } - } - } - - if(marker == JPEG_MARKER_SOS) { - length = AV_RB16(frag->data + start); - - if(length > end - start) - return AVERROR_INVALIDDATA; - - data_ref = NULL; - data = av_malloc(end - start + - AV_INPUT_BUFFER_PADDING_SIZE); - if(!data) - return AVERROR(ENOMEM); - - memcpy(data, frag->data + start, length); - for(i = start + length, j = length; i < end; i++, j++) { - if(frag->data[i] == 0xff) { - while(frag->data[i] == 0xff) - ++i; - data[j] = 0xff; - } - else { - data[j] = frag->data[i]; - } - } - data_size = j; - - memset(data + data_size, 0, AV_INPUT_BUFFER_PADDING_SIZE); - } - else { - data = frag->data + start; - data_size = end - start; - data_ref = frag->data_ref; - } - - err = ff_cbs_insert_unit_data(frag, unit, marker, - data, data_size, data_ref); - if(err < 0) - return err; - - if(next_marker == -1) - break; - marker = next_marker; - start = next_start; - } - - return 0; -} - -static int cbs_jpeg_read_unit(CodedBitstreamContext *ctx, - CodedBitstreamUnit *unit) { - GetBitContext gbc; - int err; - - err = init_get_bits(&gbc, unit->data, 8 * unit->data_size); - if(err < 0) - return err; - - if(unit->type >= JPEG_MARKER_SOF0 && - unit->type <= JPEG_MARKER_SOF3) { - err = ff_cbs_alloc_unit_content(unit, - sizeof(JPEGRawFrameHeader), - NULL); - if(err < 0) - return err; - - err = cbs_jpeg_read_frame_header(ctx, &gbc, unit->content); - if(err < 0) - return err; - } - else if(unit->type >= JPEG_MARKER_APPN && - unit->type <= JPEG_MARKER_APPN + 15) { - err = ff_cbs_alloc_unit_content(unit, - sizeof(JPEGRawApplicationData), - &cbs_jpeg_free_application_data); - if(err < 0) - return err; - - err = cbs_jpeg_read_application_data(ctx, &gbc, unit->content); - if(err < 0) - return err; - } - else if(unit->type == JPEG_MARKER_SOS) { - JPEGRawScan *scan; - int pos; - - err = ff_cbs_alloc_unit_content(unit, - sizeof(JPEGRawScan), - &cbs_jpeg_free_scan); - if(err < 0) - return err; - scan = unit->content; - - err = cbs_jpeg_read_scan_header(ctx, &gbc, &scan->header); - if(err < 0) - return err; - - pos = get_bits_count(&gbc); - av_assert0(pos % 8 == 0); - if(pos > 0) { - scan->data_size = unit->data_size - pos / 8; - scan->data_ref = av_buffer_ref(unit->data_ref); - if(!scan->data_ref) - return AVERROR(ENOMEM); - scan->data = unit->data + pos / 8; - } - } - else { - switch(unit->type) { -#define SEGMENT(marker, type, func, free) \ - case JPEG_MARKER_##marker: { \ - err = ff_cbs_alloc_unit_content(unit, \ - sizeof(type), free); \ - if(err < 0) \ - return err; \ - err = cbs_jpeg_read_##func(ctx, &gbc, unit->content); \ - if(err < 0) \ - return err; \ - } break - SEGMENT(DQT, JPEGRawQuantisationTableSpecification, dqt, NULL); - SEGMENT(DHT, JPEGRawHuffmanTableSpecification, dht, NULL); - SEGMENT(COM, JPEGRawComment, comment, &cbs_jpeg_free_comment); -#undef SEGMENT - default: - return AVERROR(ENOSYS); - } - } - - return 0; -} - -static int cbs_jpeg_write_scan(CodedBitstreamContext *ctx, - CodedBitstreamUnit *unit, - PutBitContext *pbc) { - JPEGRawScan *scan = unit->content; - int err; - - err = cbs_jpeg_write_scan_header(ctx, pbc, &scan->header); - if(err < 0) - return err; - - if(scan->data) { - if(scan->data_size * 8 > put_bits_left(pbc)) - return AVERROR(ENOSPC); - - av_assert0(put_bits_count(pbc) % 8 == 0); - - flush_put_bits(pbc); - - memcpy(put_bits_ptr(pbc), scan->data, scan->data_size); - skip_put_bytes(pbc, scan->data_size); - } - - return 0; -} - -static int cbs_jpeg_write_segment(CodedBitstreamContext *ctx, - CodedBitstreamUnit *unit, - PutBitContext *pbc) { - int err; - - if(unit->type >= JPEG_MARKER_SOF0 && - unit->type <= JPEG_MARKER_SOF3) { - err = cbs_jpeg_write_frame_header(ctx, pbc, unit->content); - } - else if(unit->type >= JPEG_MARKER_APPN && - unit->type <= JPEG_MARKER_APPN + 15) { - err = cbs_jpeg_write_application_data(ctx, pbc, unit->content); - } - else { - switch(unit->type) { -#define SEGMENT(marker, func) \ - case JPEG_MARKER_##marker: \ - err = cbs_jpeg_write_##func(ctx, pbc, unit->content); \ - break; - SEGMENT(DQT, dqt); - SEGMENT(DHT, dht); - SEGMENT(COM, comment); - default: - return AVERROR_PATCHWELCOME; - } - } - - return err; -} - -static int cbs_jpeg_write_unit(CodedBitstreamContext *ctx, - CodedBitstreamUnit *unit, - PutBitContext *pbc) { - if(unit->type == JPEG_MARKER_SOS) - return cbs_jpeg_write_scan(ctx, unit, pbc); - else - return cbs_jpeg_write_segment(ctx, unit, pbc); -} - -static int cbs_jpeg_assemble_fragment(CodedBitstreamContext *ctx, - CodedBitstreamFragment *frag) { - const CodedBitstreamUnit *unit; - uint8_t *data; - size_t size, dp, sp; - int i; - - size = 4; // SOI + EOI. - for(i = 0; i < frag->nb_units; i++) { - unit = &frag->units[i]; - size += 2 + unit->data_size; - if(unit->type == JPEG_MARKER_SOS) { - for(sp = 0; sp < unit->data_size; sp++) { - if(unit->data[sp] == 0xff) - ++size; - } - } - } - - frag->data_ref = av_buffer_alloc(size + AV_INPUT_BUFFER_PADDING_SIZE); - if(!frag->data_ref) - return AVERROR(ENOMEM); - data = frag->data_ref->data; - - dp = 0; - - data[dp++] = 0xff; - data[dp++] = JPEG_MARKER_SOI; - - for(i = 0; i < frag->nb_units; i++) { - unit = &frag->units[i]; - - data[dp++] = 0xff; - data[dp++] = unit->type; - - if(unit->type != JPEG_MARKER_SOS) { - memcpy(data + dp, unit->data, unit->data_size); - dp += unit->data_size; - } - else { - sp = AV_RB16(unit->data); - av_assert0(sp <= unit->data_size); - memcpy(data + dp, unit->data, sp); - dp += sp; - - for(; sp < unit->data_size; sp++) { - if(unit->data[sp] == 0xff) { - data[dp++] = 0xff; - data[dp++] = 0x00; - } - else { - data[dp++] = unit->data[sp]; - } - } - } - } - - data[dp++] = 0xff; - data[dp++] = JPEG_MARKER_EOI; - - av_assert0(dp == size); - - memset(data + size, 0, AV_INPUT_BUFFER_PADDING_SIZE); - frag->data = data; - frag->data_size = size; - - return 0; -} - -const CodedBitstreamType ff_cbs_type_jpeg = { - .codec_id = AV_CODEC_ID_MJPEG, - - .split_fragment = &cbs_jpeg_split_fragment, - .read_unit = &cbs_jpeg_read_unit, - .write_unit = &cbs_jpeg_write_unit, - .assemble_fragment = &cbs_jpeg_assemble_fragment, -}; diff --git a/third-party/cbs/cbs_jpeg_syntax_template.c b/third-party/cbs/cbs_jpeg_syntax_template.c deleted file mode 100644 index 613a68359c6..00000000000 --- a/third-party/cbs/cbs_jpeg_syntax_template.c +++ /dev/null @@ -1,189 +0,0 @@ -/* - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -static int FUNC(frame_header)(CodedBitstreamContext *ctx, RWContext *rw, - JPEGRawFrameHeader *current) { - int err, i; - - HEADER("Frame Header"); - - u(16, Lf, 8, 8 + 3 * JPEG_MAX_COMPONENTS); - - u(8, P, 2, 16); - u(16, Y, 0, JPEG_MAX_HEIGHT); - u(16, X, 1, JPEG_MAX_WIDTH); - u(8, Nf, 1, JPEG_MAX_COMPONENTS); - - for(i = 0; i < current->Nf; i++) { - us(8, C[i], i, 0, JPEG_MAX_COMPONENTS); - us(4, H[i], i, 1, 4); - us(4, V[i], i, 1, 4); - us(8, Tq[i], i, 0, 3); - } - - return 0; -} - -static int FUNC(quantisation_table)(CodedBitstreamContext *ctx, RWContext *rw, - JPEGRawQuantisationTable *current) { - int err, i; - - u(4, Pq, 0, 1); - u(4, Tq, 0, 3); - - if(current->Pq) { - for(i = 0; i < 64; i++) - us(16, Q[i], i, 1, 255); - } - else { - for(i = 0; i < 64; i++) - us(8, Q[i], i, 1, 255); - } - - return 0; -} - -static int FUNC(dqt)(CodedBitstreamContext *ctx, RWContext *rw, - JPEGRawQuantisationTableSpecification *current) { - int err, i, n; - - HEADER("Quantisation Tables"); - - u(16, Lq, 2, 2 + 4 * 65); - n = current->Lq / 65; - - for(i = 0; i < n; i++) - CHECK(FUNC(quantisation_table)(ctx, rw, ¤t->table[i])); - - return 0; -} - -static int FUNC(huffman_table)(CodedBitstreamContext *ctx, RWContext *rw, - JPEGRawHuffmanTable *current) { - int err, i, j, ij; - - u(4, Tc, 0, 1); - u(4, Th, 0, 3); - - for(i = 0; i < 16; i++) - us(8, L[i], i, 0, 224); - - ij = 0; - for(i = 0; i < 16; i++) { - for(j = 0; j < current->L[i]; j++) { - if(ij >= 224) - return AVERROR_INVALIDDATA; - us(8, V[ij], ij, 0, 255); - ++ij; - } - } - - return 0; -} - -static int FUNC(dht)(CodedBitstreamContext *ctx, RWContext *rw, - JPEGRawHuffmanTableSpecification *current) { - int err, i, j, n; - - HEADER("Huffman Tables"); - - u(16, Lh, 2, 2 + 8 * (1 + 16 + 256)); - - n = 2; - for(i = 0; n < current->Lh; i++) { - if(i >= 8) - return AVERROR_INVALIDDATA; - - CHECK(FUNC(huffman_table)(ctx, rw, ¤t->table[i])); - - ++n; - for(j = 0; j < 16; j++) - n += 1 + current->table[i].L[j]; - } - - return 0; -} - -static int FUNC(scan_header)(CodedBitstreamContext *ctx, RWContext *rw, - JPEGRawScanHeader *current) { - int err, j; - - HEADER("Scan"); - - u(16, Ls, 6, 6 + 2 * JPEG_MAX_COMPONENTS); - - u(8, Ns, 1, 4); - for(j = 0; j < current->Ns; j++) { - us(8, Cs[j], j, 0, JPEG_MAX_COMPONENTS); - us(4, Td[j], j, 0, 3); - us(4, Ta[j], j, 0, 3); - } - - u(8, Ss, 0, 63); - u(8, Se, 0, 63); - u(4, Ah, 0, 13); - u(4, Al, 0, 15); - - return 0; -} - -static int FUNC(application_data)(CodedBitstreamContext *ctx, RWContext *rw, - JPEGRawApplicationData *current) { - int err, i; - - HEADER("Application Data"); - - u(16, Lp, 2, 65535); - - if(current->Lp > 2) { -#ifdef READ - current->Ap_ref = av_buffer_alloc(current->Lp - 2); - if(!current->Ap_ref) - return AVERROR(ENOMEM); - current->Ap = current->Ap_ref->data; -#endif - - for(i = 0; i < current->Lp - 2; i++) - us(8, Ap[i], i, 0, 255); - } - - return 0; -} - -static int FUNC(comment)(CodedBitstreamContext *ctx, RWContext *rw, - JPEGRawComment *current) { - int err, i; - - HEADER("Comment"); - - u(16, Lc, 2, 65535); - - if(current->Lc > 2) { -#ifdef READ - current->Cm_ref = av_buffer_alloc(current->Lc - 2); - if(!current->Cm_ref) - return AVERROR(ENOMEM); - current->Cm = current->Cm_ref->data; -#endif - - for(i = 0; i < current->Lc - 2; i++) - us(8, Cm[i], i, 0, 255); - } - - return 0; -} diff --git a/third-party/cbs/cbs_mpeg2.c b/third-party/cbs/cbs_mpeg2.c deleted file mode 100644 index 98a975f8f08..00000000000 --- a/third-party/cbs/cbs_mpeg2.c +++ /dev/null @@ -1,469 +0,0 @@ -/* - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include - -#include "cbs/cbs.h" -#include "cbs/cbs_mpeg2.h" - -#include "cbs_internal.h" - - -#define HEADER(name) \ - do { \ - ff_cbs_trace_header(ctx, name); \ - } while(0) - -#define CHECK(call) \ - do { \ - err = (call); \ - if(err < 0) \ - return err; \ - } while(0) - -#define FUNC_NAME(rw, codec, name) cbs_##codec##_##rw##_##name -#define FUNC_MPEG2(rw, name) FUNC_NAME(rw, mpeg2, name) -#define FUNC(name) FUNC_MPEG2(READWRITE, name) - -#define SUBSCRIPTS(subs, ...) (subs > 0 ? ((int[subs + 1]) { subs, __VA_ARGS__ }) : NULL) - -#define ui(width, name) \ - xui(width, name, current->name, 0, MAX_UINT_BITS(width), 0, ) -#define uir(width, name) \ - xui(width, name, current->name, 1, MAX_UINT_BITS(width), 0, ) -#define uis(width, name, subs, ...) \ - xui(width, name, current->name, 0, MAX_UINT_BITS(width), subs, __VA_ARGS__) -#define uirs(width, name, subs, ...) \ - xui(width, name, current->name, 1, MAX_UINT_BITS(width), subs, __VA_ARGS__) -#define xui(width, name, var, range_min, range_max, subs, ...) \ - xuia(width, #name, var, range_min, range_max, subs, __VA_ARGS__) -#define sis(width, name, subs, ...) \ - xsi(width, name, current->name, subs, __VA_ARGS__) - -#define marker_bit() \ - bit("marker_bit", 1) -#define bit(string, value) \ - do { \ - av_unused uint32_t bit = value; \ - xuia(1, string, bit, value, value, 0, ); \ - } while(0) - - -#define READ -#define READWRITE read -#define RWContext GetBitContext - -#define xuia(width, string, var, range_min, range_max, subs, ...) \ - do { \ - uint32_t value; \ - CHECK(ff_cbs_read_unsigned(ctx, rw, width, string, \ - SUBSCRIPTS(subs, __VA_ARGS__), \ - &value, range_min, range_max)); \ - var = value; \ - } while(0) - -#define xsi(width, name, var, subs, ...) \ - do { \ - int32_t value; \ - CHECK(ff_cbs_read_signed(ctx, rw, width, #name, \ - SUBSCRIPTS(subs, __VA_ARGS__), &value, \ - MIN_INT_BITS(width), \ - MAX_INT_BITS(width))); \ - var = value; \ - } while(0) - -#define nextbits(width, compare, var) \ - (get_bits_left(rw) >= width && \ - (var = show_bits(rw, width)) == (compare)) - -#define infer(name, value) \ - do { \ - current->name = value; \ - } while(0) - -#include "cbs_mpeg2_syntax_template.c" - -#undef READ -#undef READWRITE -#undef RWContext -#undef xuia -#undef xsi -#undef nextbits -#undef infer - - -#define WRITE -#define READWRITE write -#define RWContext PutBitContext - -#define xuia(width, string, var, range_min, range_max, subs, ...) \ - do { \ - CHECK(ff_cbs_write_unsigned(ctx, rw, width, string, \ - SUBSCRIPTS(subs, __VA_ARGS__), \ - var, range_min, range_max)); \ - } while(0) - -#define xsi(width, name, var, subs, ...) \ - do { \ - CHECK(ff_cbs_write_signed(ctx, rw, width, #name, \ - SUBSCRIPTS(subs, __VA_ARGS__), var, \ - MIN_INT_BITS(width), \ - MAX_INT_BITS(width))); \ - } while(0) - -#define nextbits(width, compare, var) (var) - -#define infer(name, value) \ - do { \ - if(current->name != (value)) { \ - av_log(ctx->log_ctx, AV_LOG_WARNING, "Warning: " \ - "%s does not match inferred value: " \ - "%" PRId64 ", but should be %" PRId64 ".\n", \ - #name, (int64_t)current->name, (int64_t)(value)); \ - } \ - } while(0) - -#include "cbs_mpeg2_syntax_template.c" - -#undef WRITE -#undef READWRITE -#undef RWContext -#undef xuia -#undef xsi -#undef nextbits -#undef infer - -static const uint8_t *avpriv_find_start_code(const uint8_t *restrict p, - const uint8_t *end, - uint32_t *restrict state) { - int i; - - av_assert0(p <= end); - if(p >= end) - return end; - - for(i = 0; i < 3; i++) { - uint32_t tmp = *state << 8; - *state = tmp + *(p++); - if(tmp == 0x100 || p == end) - return p; - } - - while(p < end) { - if(p[-1] > 1) p += 3; - else if(p[-2]) - p += 2; - else if(p[-3] | (p[-1] - 1)) - p++; - else { - p++; - break; - } - } - - p = FFMIN(p, end) - 4; - *state = AV_RB32(p); - - return p + 4; -} - -static int cbs_mpeg2_split_fragment(CodedBitstreamContext *ctx, - CodedBitstreamFragment *frag, - int header) { - const uint8_t *start, *end; - CodedBitstreamUnitType unit_type; - uint32_t start_code = -1; - size_t unit_size; - int err, i, final = 0; - - start = avpriv_find_start_code(frag->data, frag->data + frag->data_size, - &start_code); - if(start_code >> 8 != 0x000001) { - // No start code found. - return AVERROR_INVALIDDATA; - } - - for(i = 0;; i++) { - unit_type = start_code & 0xff; - - if(start == frag->data + frag->data_size) { - // The last four bytes form a start code which constitutes - // a unit of its own. In this situation avpriv_find_start_code - // won't modify start_code at all so modify start_code so that - // the next unit will be treated as the last unit. - start_code = 0; - } - - end = avpriv_find_start_code(start--, frag->data + frag->data_size, - &start_code); - - // start points to the byte containing the start_code_identifier - // (may be the last byte of fragment->data); end points to the byte - // following the byte containing the start code identifier (or to - // the end of fragment->data). - if(start_code >> 8 == 0x000001) { - // Unit runs from start to the beginning of the start code - // pointed to by end (including any padding zeroes). - unit_size = (end - 4) - start; - } - else { - // We didn't find a start code, so this is the final unit. - unit_size = end - start; - final = 1; - } - - err = ff_cbs_insert_unit_data(frag, i, unit_type, (uint8_t *)start, - unit_size, frag->data_ref); - if(err < 0) - return err; - - if(final) - break; - - start = end; - } - - return 0; -} - -static int cbs_mpeg2_read_unit(CodedBitstreamContext *ctx, - CodedBitstreamUnit *unit) { - GetBitContext gbc; - int err; - - err = init_get_bits(&gbc, unit->data, 8 * unit->data_size); - if(err < 0) - return err; - - err = ff_cbs_alloc_unit_content2(ctx, unit); - if(err < 0) - return err; - - if(MPEG2_START_IS_SLICE(unit->type)) { - MPEG2RawSlice *slice = unit->content; - int pos, len; - - err = cbs_mpeg2_read_slice_header(ctx, &gbc, &slice->header); - if(err < 0) - return err; - - if(!get_bits_left(&gbc)) - return AVERROR_INVALIDDATA; - - pos = get_bits_count(&gbc); - len = unit->data_size; - - slice->data_size = len - pos / 8; - slice->data_ref = av_buffer_ref(unit->data_ref); - if(!slice->data_ref) - return AVERROR(ENOMEM); - slice->data = unit->data + pos / 8; - - slice->data_bit_start = pos % 8; - } - else { - switch(unit->type) { -#define START(start_code, type, read_func, free_func) \ - case start_code: { \ - type *header = unit->content; \ - err = cbs_mpeg2_read_##read_func(ctx, &gbc, header); \ - if(err < 0) \ - return err; \ - } break; - START(MPEG2_START_PICTURE, MPEG2RawPictureHeader, - picture_header, &cbs_mpeg2_free_picture_header); - START(MPEG2_START_USER_DATA, MPEG2RawUserData, - user_data, &cbs_mpeg2_free_user_data); - START(MPEG2_START_SEQUENCE_HEADER, MPEG2RawSequenceHeader, - sequence_header, NULL); - START(MPEG2_START_EXTENSION, MPEG2RawExtensionData, - extension_data, NULL); - START(MPEG2_START_GROUP, MPEG2RawGroupOfPicturesHeader, - group_of_pictures_header, NULL); - START(MPEG2_START_SEQUENCE_END, MPEG2RawSequenceEnd, - sequence_end, NULL); -#undef START - default: - return AVERROR(ENOSYS); - } - } - - return 0; -} - -static int cbs_mpeg2_write_header(CodedBitstreamContext *ctx, - CodedBitstreamUnit *unit, - PutBitContext *pbc) { - int err; - - switch(unit->type) { -#define START(start_code, type, func) \ - case start_code: \ - err = cbs_mpeg2_write_##func(ctx, pbc, unit->content); \ - break; - START(MPEG2_START_PICTURE, MPEG2RawPictureHeader, picture_header); - START(MPEG2_START_USER_DATA, MPEG2RawUserData, user_data); - START(MPEG2_START_SEQUENCE_HEADER, MPEG2RawSequenceHeader, sequence_header); - START(MPEG2_START_EXTENSION, MPEG2RawExtensionData, extension_data); - START(MPEG2_START_GROUP, MPEG2RawGroupOfPicturesHeader, - group_of_pictures_header); - START(MPEG2_START_SEQUENCE_END, MPEG2RawSequenceEnd, sequence_end); -#undef START - default: - av_log(ctx->log_ctx, AV_LOG_ERROR, "Write unimplemented for start " - "code %02" PRIx32 ".\n", - unit->type); - return AVERROR_PATCHWELCOME; - } - - return err; -} - -static int cbs_mpeg2_write_slice(CodedBitstreamContext *ctx, - CodedBitstreamUnit *unit, - PutBitContext *pbc) { - MPEG2RawSlice *slice = unit->content; - int err; - - err = cbs_mpeg2_write_slice_header(ctx, pbc, &slice->header); - if(err < 0) - return err; - - if(slice->data) { - size_t rest = slice->data_size - (slice->data_bit_start + 7) / 8; - uint8_t *pos = slice->data + slice->data_bit_start / 8; - - av_assert0(slice->data_bit_start >= 0 && - slice->data_size > slice->data_bit_start / 8); - - if(slice->data_size * 8 + 8 > put_bits_left(pbc)) - return AVERROR(ENOSPC); - - // First copy the remaining bits of the first byte - if(slice->data_bit_start % 8) - put_bits(pbc, 8 - slice->data_bit_start % 8, - *pos++ & MAX_UINT_BITS(8 - slice->data_bit_start % 8)); - - if(put_bits_count(pbc) % 8 == 0) { - // If the writer is aligned at this point, - // memcpy can be used to improve performance. - // This is the normal case. - flush_put_bits(pbc); - memcpy(put_bits_ptr(pbc), pos, rest); - skip_put_bytes(pbc, rest); - } - else { - // If not, we have to copy manually: - for(; rest > 3; rest -= 4, pos += 4) - put_bits32(pbc, AV_RB32(pos)); - - for(; rest; rest--, pos++) - put_bits(pbc, 8, *pos); - - // Align with zeros - put_bits(pbc, 8 - put_bits_count(pbc) % 8, 0); - } - } - - return 0; -} - -static int cbs_mpeg2_write_unit(CodedBitstreamContext *ctx, - CodedBitstreamUnit *unit, - PutBitContext *pbc) { - if(MPEG2_START_IS_SLICE(unit->type)) - return cbs_mpeg2_write_slice(ctx, unit, pbc); - else - return cbs_mpeg2_write_header(ctx, unit, pbc); -} - -static int cbs_mpeg2_assemble_fragment(CodedBitstreamContext *ctx, - CodedBitstreamFragment *frag) { - uint8_t *data; - size_t size, dp; - int i; - - size = 0; - for(i = 0; i < frag->nb_units; i++) - size += 3 + frag->units[i].data_size; - - frag->data_ref = av_buffer_alloc(size + AV_INPUT_BUFFER_PADDING_SIZE); - if(!frag->data_ref) - return AVERROR(ENOMEM); - data = frag->data_ref->data; - - dp = 0; - for(i = 0; i < frag->nb_units; i++) { - CodedBitstreamUnit *unit = &frag->units[i]; - - data[dp++] = 0; - data[dp++] = 0; - data[dp++] = 1; - - memcpy(data + dp, unit->data, unit->data_size); - dp += unit->data_size; - } - - av_assert0(dp == size); - - memset(data + size, 0, AV_INPUT_BUFFER_PADDING_SIZE); - frag->data = data; - frag->data_size = size; - - return 0; -} - -static const CodedBitstreamUnitTypeDescriptor cbs_mpeg2_unit_types[] = { - CBS_UNIT_TYPE_INTERNAL_REF(MPEG2_START_PICTURE, MPEG2RawPictureHeader, - extra_information_picture.extra_information), - - { - .nb_unit_types = CBS_UNIT_TYPE_RANGE, - .unit_type_range_start = 0x01, - .unit_type_range_end = 0xaf, - - .content_type = CBS_CONTENT_TYPE_INTERNAL_REFS, - .content_size = sizeof(MPEG2RawSlice), - .nb_ref_offsets = 2, - .ref_offsets = { offsetof(MPEG2RawSlice, header.extra_information_slice.extra_information), - offsetof(MPEG2RawSlice, data) }, - }, - - CBS_UNIT_TYPE_INTERNAL_REF(MPEG2_START_USER_DATA, MPEG2RawUserData, - user_data), - - CBS_UNIT_TYPE_POD(MPEG2_START_SEQUENCE_HEADER, MPEG2RawSequenceHeader), - CBS_UNIT_TYPE_POD(MPEG2_START_EXTENSION, MPEG2RawExtensionData), - CBS_UNIT_TYPE_POD(MPEG2_START_SEQUENCE_END, MPEG2RawSequenceEnd), - CBS_UNIT_TYPE_POD(MPEG2_START_GROUP, MPEG2RawGroupOfPicturesHeader), - - CBS_UNIT_TYPE_END_OF_LIST -}; - -const CodedBitstreamType ff_cbs_type_mpeg2 = { - .codec_id = AV_CODEC_ID_MPEG2VIDEO, - - .priv_data_size = sizeof(CodedBitstreamMPEG2Context), - - .unit_types = cbs_mpeg2_unit_types, - - .split_fragment = &cbs_mpeg2_split_fragment, - .read_unit = &cbs_mpeg2_read_unit, - .write_unit = &cbs_mpeg2_write_unit, - .assemble_fragment = &cbs_mpeg2_assemble_fragment, -}; diff --git a/third-party/cbs/cbs_mpeg2_syntax_template.c b/third-party/cbs/cbs_mpeg2_syntax_template.c deleted file mode 100644 index 7fc1e80aa6f..00000000000 --- a/third-party/cbs/cbs_mpeg2_syntax_template.c +++ /dev/null @@ -1,413 +0,0 @@ -/* - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -static int FUNC(sequence_header)(CodedBitstreamContext *ctx, RWContext *rw, - MPEG2RawSequenceHeader *current) { - CodedBitstreamMPEG2Context *mpeg2 = ctx->priv_data; - int err, i; - - HEADER("Sequence Header"); - - ui(8, sequence_header_code); - - uir(12, horizontal_size_value); - uir(12, vertical_size_value); - - mpeg2->horizontal_size = current->horizontal_size_value; - mpeg2->vertical_size = current->vertical_size_value; - - uir(4, aspect_ratio_information); - uir(4, frame_rate_code); - ui(18, bit_rate_value); - - marker_bit(); - - ui(10, vbv_buffer_size_value); - ui(1, constrained_parameters_flag); - - ui(1, load_intra_quantiser_matrix); - if(current->load_intra_quantiser_matrix) { - for(i = 0; i < 64; i++) - uirs(8, intra_quantiser_matrix[i], 1, i); - } - - ui(1, load_non_intra_quantiser_matrix); - if(current->load_non_intra_quantiser_matrix) { - for(i = 0; i < 64; i++) - uirs(8, non_intra_quantiser_matrix[i], 1, i); - } - - return 0; -} - -static int FUNC(user_data)(CodedBitstreamContext *ctx, RWContext *rw, - MPEG2RawUserData *current) { - size_t k; - int err; - - HEADER("User Data"); - - ui(8, user_data_start_code); - -#ifdef READ - k = get_bits_left(rw); - av_assert0(k % 8 == 0); - current->user_data_length = k /= 8; - if(k > 0) { - current->user_data_ref = av_buffer_allocz(k + AV_INPUT_BUFFER_PADDING_SIZE); - if(!current->user_data_ref) - return AVERROR(ENOMEM); - current->user_data = current->user_data_ref->data; - } -#endif - - for(k = 0; k < current->user_data_length; k++) - uis(8, user_data[k], 1, k); - - return 0; -} - -static int FUNC(sequence_extension)(CodedBitstreamContext *ctx, RWContext *rw, - MPEG2RawSequenceExtension *current) { - CodedBitstreamMPEG2Context *mpeg2 = ctx->priv_data; - int err; - - HEADER("Sequence Extension"); - - ui(8, profile_and_level_indication); - ui(1, progressive_sequence); - ui(2, chroma_format); - ui(2, horizontal_size_extension); - ui(2, vertical_size_extension); - - mpeg2->horizontal_size = (mpeg2->horizontal_size & 0xfff) | - current->horizontal_size_extension << 12; - mpeg2->vertical_size = (mpeg2->vertical_size & 0xfff) | - current->vertical_size_extension << 12; - mpeg2->progressive_sequence = current->progressive_sequence; - - ui(12, bit_rate_extension); - marker_bit(); - ui(8, vbv_buffer_size_extension); - ui(1, low_delay); - ui(2, frame_rate_extension_n); - ui(5, frame_rate_extension_d); - - return 0; -} - -static int FUNC(sequence_display_extension)(CodedBitstreamContext *ctx, RWContext *rw, - MPEG2RawSequenceDisplayExtension *current) { - int err; - - HEADER("Sequence Display Extension"); - - ui(3, video_format); - - ui(1, colour_description); - if(current->colour_description) { -#ifdef READ -#define READ_AND_PATCH(name) \ - do { \ - ui(8, name); \ - if(current->name == 0) { \ - current->name = 2; \ - av_log(ctx->log_ctx, AV_LOG_WARNING, "%s in a sequence display " \ - "extension had the invalid value 0. Setting it to 2 " \ - "(meaning unknown) instead.\n", \ - #name); \ - } \ - } while(0) - READ_AND_PATCH(colour_primaries); - READ_AND_PATCH(transfer_characteristics); - READ_AND_PATCH(matrix_coefficients); -#undef READ_AND_PATCH -#else - uir(8, colour_primaries); - uir(8, transfer_characteristics); - uir(8, matrix_coefficients); -#endif - } - else { - infer(colour_primaries, 2); - infer(transfer_characteristics, 2); - infer(matrix_coefficients, 2); - } - - ui(14, display_horizontal_size); - marker_bit(); - ui(14, display_vertical_size); - - return 0; -} - -static int FUNC(group_of_pictures_header)(CodedBitstreamContext *ctx, RWContext *rw, - MPEG2RawGroupOfPicturesHeader *current) { - int err; - - HEADER("Group of Pictures Header"); - - ui(8, group_start_code); - - ui(25, time_code); - ui(1, closed_gop); - ui(1, broken_link); - - return 0; -} - -static int FUNC(extra_information)(CodedBitstreamContext *ctx, RWContext *rw, - MPEG2RawExtraInformation *current, - const char *element_name, const char *marker_name) { - int err; - size_t k; -#ifdef READ - GetBitContext start = *rw; - uint8_t bit; - - for(k = 0; nextbits(1, 1, bit); k++) - skip_bits(rw, 1 + 8); - current->extra_information_length = k; - if(k > 0) { - *rw = start; - current->extra_information_ref = - av_buffer_allocz(k + AV_INPUT_BUFFER_PADDING_SIZE); - if(!current->extra_information_ref) - return AVERROR(ENOMEM); - current->extra_information = current->extra_information_ref->data; - } -#endif - - for(k = 0; k < current->extra_information_length; k++) { - bit(marker_name, 1); - xuia(8, element_name, - current->extra_information[k], 0, 255, 1, k); - } - - bit(marker_name, 0); - - return 0; -} - -static int FUNC(picture_header)(CodedBitstreamContext *ctx, RWContext *rw, - MPEG2RawPictureHeader *current) { - int err; - - HEADER("Picture Header"); - - ui(8, picture_start_code); - - ui(10, temporal_reference); - uir(3, picture_coding_type); - ui(16, vbv_delay); - - if(current->picture_coding_type == 2 || - current->picture_coding_type == 3) { - ui(1, full_pel_forward_vector); - ui(3, forward_f_code); - } - - if(current->picture_coding_type == 3) { - ui(1, full_pel_backward_vector); - ui(3, backward_f_code); - } - - CHECK(FUNC(extra_information)(ctx, rw, ¤t->extra_information_picture, - "extra_information_picture[k]", "extra_bit_picture")); - - return 0; -} - -static int FUNC(picture_coding_extension)(CodedBitstreamContext *ctx, RWContext *rw, - MPEG2RawPictureCodingExtension *current) { - CodedBitstreamMPEG2Context *mpeg2 = ctx->priv_data; - int err; - - HEADER("Picture Coding Extension"); - - uir(4, f_code[0][0]); - uir(4, f_code[0][1]); - uir(4, f_code[1][0]); - uir(4, f_code[1][1]); - - ui(2, intra_dc_precision); - ui(2, picture_structure); - ui(1, top_field_first); - ui(1, frame_pred_frame_dct); - ui(1, concealment_motion_vectors); - ui(1, q_scale_type); - ui(1, intra_vlc_format); - ui(1, alternate_scan); - ui(1, repeat_first_field); - ui(1, chroma_420_type); - ui(1, progressive_frame); - - if(mpeg2->progressive_sequence) { - if(current->repeat_first_field) { - if(current->top_field_first) - mpeg2->number_of_frame_centre_offsets = 3; - else - mpeg2->number_of_frame_centre_offsets = 2; - } - else { - mpeg2->number_of_frame_centre_offsets = 1; - } - } - else { - if(current->picture_structure == 1 || // Top field. - current->picture_structure == 2) { // Bottom field. - mpeg2->number_of_frame_centre_offsets = 1; - } - else { - if(current->repeat_first_field) - mpeg2->number_of_frame_centre_offsets = 3; - else - mpeg2->number_of_frame_centre_offsets = 2; - } - } - - ui(1, composite_display_flag); - if(current->composite_display_flag) { - ui(1, v_axis); - ui(3, field_sequence); - ui(1, sub_carrier); - ui(7, burst_amplitude); - ui(8, sub_carrier_phase); - } - - return 0; -} - -static int FUNC(quant_matrix_extension)(CodedBitstreamContext *ctx, RWContext *rw, - MPEG2RawQuantMatrixExtension *current) { - int err, i; - - HEADER("Quant Matrix Extension"); - - ui(1, load_intra_quantiser_matrix); - if(current->load_intra_quantiser_matrix) { - for(i = 0; i < 64; i++) - uirs(8, intra_quantiser_matrix[i], 1, i); - } - - ui(1, load_non_intra_quantiser_matrix); - if(current->load_non_intra_quantiser_matrix) { - for(i = 0; i < 64; i++) - uirs(8, non_intra_quantiser_matrix[i], 1, i); - } - - ui(1, load_chroma_intra_quantiser_matrix); - if(current->load_chroma_intra_quantiser_matrix) { - for(i = 0; i < 64; i++) - uirs(8, intra_quantiser_matrix[i], 1, i); - } - - ui(1, load_chroma_non_intra_quantiser_matrix); - if(current->load_chroma_non_intra_quantiser_matrix) { - for(i = 0; i < 64; i++) - uirs(8, chroma_non_intra_quantiser_matrix[i], 1, i); - } - - return 0; -} - -static int FUNC(picture_display_extension)(CodedBitstreamContext *ctx, RWContext *rw, - MPEG2RawPictureDisplayExtension *current) { - CodedBitstreamMPEG2Context *mpeg2 = ctx->priv_data; - int err, i; - - HEADER("Picture Display Extension"); - - for(i = 0; i < mpeg2->number_of_frame_centre_offsets; i++) { - sis(16, frame_centre_horizontal_offset[i], 1, i); - marker_bit(); - sis(16, frame_centre_vertical_offset[i], 1, i); - marker_bit(); - } - - return 0; -} - -static int FUNC(extension_data)(CodedBitstreamContext *ctx, RWContext *rw, - MPEG2RawExtensionData *current) { - int err; - - HEADER("Extension Data"); - - ui(8, extension_start_code); - ui(4, extension_start_code_identifier); - - switch(current->extension_start_code_identifier) { - case MPEG2_EXTENSION_SEQUENCE: - return FUNC(sequence_extension)(ctx, rw, ¤t->data.sequence); - case MPEG2_EXTENSION_SEQUENCE_DISPLAY: - return FUNC(sequence_display_extension)(ctx, rw, ¤t->data.sequence_display); - case MPEG2_EXTENSION_QUANT_MATRIX: - return FUNC(quant_matrix_extension)(ctx, rw, ¤t->data.quant_matrix); - case MPEG2_EXTENSION_PICTURE_DISPLAY: - return FUNC(picture_display_extension)(ctx, rw, ¤t->data.picture_display); - case MPEG2_EXTENSION_PICTURE_CODING: - return FUNC(picture_coding_extension)(ctx, rw, ¤t->data.picture_coding); - default: - av_log(ctx->log_ctx, AV_LOG_ERROR, "Extension ID %d not supported.\n", - current->extension_start_code_identifier); - return AVERROR_PATCHWELCOME; - } -} - -static int FUNC(slice_header)(CodedBitstreamContext *ctx, RWContext *rw, - MPEG2RawSliceHeader *current) { - CodedBitstreamMPEG2Context *mpeg2 = ctx->priv_data; - int err; - - HEADER("Slice Header"); - - ui(8, slice_vertical_position); - - if(mpeg2->vertical_size > 2800) - ui(3, slice_vertical_position_extension); - if(mpeg2->scalable) { - if(mpeg2->scalable_mode == 0) - ui(7, priority_breakpoint); - } - - uir(5, quantiser_scale_code); - - if(nextbits(1, 1, current->slice_extension_flag)) { - ui(1, slice_extension_flag); - ui(1, intra_slice); - ui(1, slice_picture_id_enable); - ui(6, slice_picture_id); - } - - CHECK(FUNC(extra_information)(ctx, rw, ¤t->extra_information_slice, - "extra_information_slice[k]", "extra_bit_slice")); - - return 0; -} - -static int FUNC(sequence_end)(CodedBitstreamContext *ctx, RWContext *rw, - MPEG2RawSequenceEnd *current) { - int err; - - HEADER("Sequence End"); - - ui(8, sequence_end_code); - - return 0; -} diff --git a/third-party/cbs/cbs_sei.c b/third-party/cbs/cbs_sei.c deleted file mode 100644 index c184d67d41d..00000000000 --- a/third-party/cbs/cbs_sei.c +++ /dev/null @@ -1,355 +0,0 @@ -/* - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "cbs/cbs_sei.h" -#include "cbs/cbs.h" -#include "cbs/cbs_h264.h" -#include "cbs/cbs_h265.h" - -#include "cbs_internal.h" - -static void cbs_free_user_data_registered(void *opaque, uint8_t *data) { - SEIRawUserDataRegistered *udr = (SEIRawUserDataRegistered *)data; - av_buffer_unref(&udr->data_ref); - av_free(udr); -} - -static void cbs_free_user_data_unregistered(void *opaque, uint8_t *data) { - SEIRawUserDataUnregistered *udu = (SEIRawUserDataUnregistered *)data; - av_buffer_unref(&udu->data_ref); - av_free(udu); -} - -int ff_cbs_sei_alloc_message_payload(SEIRawMessage *message, - const SEIMessageTypeDescriptor *desc) { - void (*free_func)(void *, uint8_t *); - - av_assert0(message->payload == NULL && - message->payload_ref == NULL); - message->payload_type = desc->type; - - if(desc->type == SEI_TYPE_USER_DATA_REGISTERED_ITU_T_T35) - free_func = &cbs_free_user_data_registered; - else if(desc->type == SEI_TYPE_USER_DATA_UNREGISTERED) - free_func = &cbs_free_user_data_unregistered; - else - free_func = NULL; - - if(free_func) { - message->payload = av_mallocz(desc->size); - if(!message->payload) - return AVERROR(ENOMEM); - message->payload_ref = - av_buffer_create(message->payload, desc->size, - free_func, NULL, 0); - } - else { - message->payload_ref = av_buffer_alloc(desc->size); - } - if(!message->payload_ref) { - av_freep(&message->payload); - return AVERROR(ENOMEM); - } - message->payload = message->payload_ref->data; - - return 0; -} - -int ff_cbs_sei_list_add(SEIRawMessageList *list) { - void *ptr; - int old_count = list->nb_messages_allocated; - - av_assert0(list->nb_messages <= old_count); - if(list->nb_messages + 1 > old_count) { - int new_count = 2 * old_count + 1; - - ptr = av_realloc_array(list->messages, - new_count, sizeof(*list->messages)); - if(!ptr) - return AVERROR(ENOMEM); - - list->messages = ptr; - list->nb_messages_allocated = new_count; - - // Zero the newly-added entries. - memset(list->messages + old_count, 0, - (new_count - old_count) * sizeof(*list->messages)); - } - ++list->nb_messages; - return 0; -} - -void ff_cbs_sei_free_message_list(SEIRawMessageList *list) { - for(int i = 0; i < list->nb_messages; i++) { - SEIRawMessage *message = &list->messages[i]; - av_buffer_unref(&message->payload_ref); - av_buffer_unref(&message->extension_data_ref); - } - av_free(list->messages); -} - -static int cbs_sei_get_unit(CodedBitstreamContext *ctx, - CodedBitstreamFragment *au, - int prefix, - CodedBitstreamUnit **sei_unit) { - CodedBitstreamUnit *unit; - int sei_type, highest_vcl_type, err, i, position; - - switch(ctx->codec->codec_id) { - case AV_CODEC_ID_H264: - // (We can ignore auxiliary slices because we only have prefix - // SEI in H.264 and an auxiliary picture must always follow a - // primary picture.) - highest_vcl_type = H264_NAL_IDR_SLICE; - if(prefix) - sei_type = H264_NAL_SEI; - else - return AVERROR(EINVAL); - break; - case AV_CODEC_ID_H265: - highest_vcl_type = HEVC_NAL_RSV_VCL31; - if(prefix) - sei_type = HEVC_NAL_SEI_PREFIX; - else - sei_type = HEVC_NAL_SEI_SUFFIX; - break; - default: - return AVERROR(EINVAL); - } - - // Find an existing SEI NAL unit of the right type. - unit = NULL; - for(i = 0; i < au->nb_units; i++) { - if(au->units[i].type == sei_type) { - unit = &au->units[i]; - break; - } - } - - if(unit) { - *sei_unit = unit; - return 0; - } - - // Need to add a new SEI NAL unit ... - if(prefix) { - // ... before the first VCL NAL unit. - for(i = 0; i < au->nb_units; i++) { - if(au->units[i].type < highest_vcl_type) - break; - } - position = i; - } - else { - // ... after the last VCL NAL unit. - for(i = au->nb_units - 1; i >= 0; i--) { - if(au->units[i].type < highest_vcl_type) - break; - } - if(i < 0) { - // No VCL units; just put it at the end. - position = au->nb_units; - } - else { - position = i + 1; - } - } - - err = ff_cbs_insert_unit_content(au, position, sei_type, - NULL, NULL); - if(err < 0) - return err; - unit = &au->units[position]; - unit->type = sei_type; - - err = ff_cbs_alloc_unit_content2(ctx, unit); - if(err < 0) - return err; - - switch(ctx->codec->codec_id) { - case AV_CODEC_ID_H264: { - H264RawSEI sei = { - .nal_unit_header = { - .nal_ref_idc = 0, - .nal_unit_type = sei_type, - }, - }; - memcpy(unit->content, &sei, sizeof(sei)); - } break; - case AV_CODEC_ID_H265: { - H265RawSEI sei = { - .nal_unit_header = { - .nal_unit_type = sei_type, - .nuh_layer_id = 0, - .nuh_temporal_id_plus1 = 1, - }, - }; - memcpy(unit->content, &sei, sizeof(sei)); - } break; - default: - av_assert0(0); - } - - *sei_unit = unit; - return 0; -} - -static int cbs_sei_get_message_list(CodedBitstreamContext *ctx, - CodedBitstreamUnit *unit, - SEIRawMessageList **list) { - switch(ctx->codec->codec_id) { - case AV_CODEC_ID_H264: { - H264RawSEI *sei = unit->content; - if(unit->type != H264_NAL_SEI) - return AVERROR(EINVAL); - *list = &sei->message_list; - } break; - case AV_CODEC_ID_H265: { - H265RawSEI *sei = unit->content; - if(unit->type != HEVC_NAL_SEI_PREFIX && - unit->type != HEVC_NAL_SEI_SUFFIX) - return AVERROR(EINVAL); - *list = &sei->message_list; - } break; - default: - return AVERROR(EINVAL); - } - - return 0; -} - -int ff_cbs_sei_add_message(CodedBitstreamContext *ctx, - CodedBitstreamFragment *au, - int prefix, - uint32_t payload_type, - void *payload_data, - AVBufferRef *payload_buf) { - const SEIMessageTypeDescriptor *desc; - CodedBitstreamUnit *unit; - SEIRawMessageList *list; - SEIRawMessage *message; - AVBufferRef *payload_ref; - int err; - - desc = ff_cbs_sei_find_type(ctx, payload_type); - if(!desc) - return AVERROR(EINVAL); - - // Find an existing SEI unit or make a new one to add to. - err = cbs_sei_get_unit(ctx, au, prefix, &unit); - if(err < 0) - return err; - - // Find the message list inside the codec-dependent unit. - err = cbs_sei_get_message_list(ctx, unit, &list); - if(err < 0) - return err; - - // Add a new message to the message list. - err = ff_cbs_sei_list_add(list); - if(err < 0) - return err; - - if(payload_buf) { - payload_ref = av_buffer_ref(payload_buf); - if(!payload_ref) - return AVERROR(ENOMEM); - } - else { - payload_ref = NULL; - } - - message = &list->messages[list->nb_messages - 1]; - - message->payload_type = payload_type; - message->payload = payload_data; - message->payload_ref = payload_ref; - - return 0; -} - -int ff_cbs_sei_find_message(CodedBitstreamContext *ctx, - CodedBitstreamFragment *au, - uint32_t payload_type, - SEIRawMessage **iter) { - int err, i, j, found; - - found = 0; - for(i = 0; i < au->nb_units; i++) { - CodedBitstreamUnit *unit = &au->units[i]; - SEIRawMessageList *list; - - err = cbs_sei_get_message_list(ctx, unit, &list); - if(err < 0) - continue; - - for(j = 0; j < list->nb_messages; j++) { - SEIRawMessage *message = &list->messages[j]; - - if(message->payload_type == payload_type) { - if(!*iter || found) { - *iter = message; - return 0; - } - if(message == *iter) - found = 1; - } - } - } - - return AVERROR(ENOENT); -} - -static void cbs_sei_delete_message(SEIRawMessageList *list, - int position) { - SEIRawMessage *message; - - av_assert0(0 <= position && position < list->nb_messages); - - message = &list->messages[position]; - av_buffer_unref(&message->payload_ref); - av_buffer_unref(&message->extension_data_ref); - - --list->nb_messages; - - if(list->nb_messages > 0) { - memmove(list->messages + position, - list->messages + position + 1, - (list->nb_messages - position) * sizeof(*list->messages)); - } -} - -void ff_cbs_sei_delete_message_type(CodedBitstreamContext *ctx, - CodedBitstreamFragment *au, - uint32_t payload_type) { - int err, i, j; - - for(i = 0; i < au->nb_units; i++) { - CodedBitstreamUnit *unit = &au->units[i]; - SEIRawMessageList *list; - - err = cbs_sei_get_message_list(ctx, unit, &list); - if(err < 0) - continue; - - for(j = list->nb_messages - 1; j >= 0; j--) { - if(list->messages[j].payload_type == payload_type) - cbs_sei_delete_message(list, j); - } - } -} diff --git a/third-party/cbs/cbs_sei_syntax_template.c b/third-party/cbs/cbs_sei_syntax_template.c deleted file mode 100644 index e9688013adf..00000000000 --- a/third-party/cbs/cbs_sei_syntax_template.c +++ /dev/null @@ -1,310 +0,0 @@ -/* - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -static int FUNC(filler_payload)(CodedBitstreamContext *ctx, RWContext *rw, - SEIRawFillerPayload *current, SEIMessageState *state) { - int err, i; - - HEADER("Filler Payload"); - -#ifdef READ - current->payload_size = state->payload_size; -#endif - - for(i = 0; i < current->payload_size; i++) - fixed(8, ff_byte, 0xff); - - return 0; -} - -static int FUNC(user_data_registered)(CodedBitstreamContext *ctx, RWContext *rw, - SEIRawUserDataRegistered *current, SEIMessageState *state) { - int err, i, j; - - HEADER("User Data Registered ITU-T T.35"); - - u(8, itu_t_t35_country_code, 0x00, 0xff); - if(current->itu_t_t35_country_code != 0xff) - i = 1; - else { - u(8, itu_t_t35_country_code_extension_byte, 0x00, 0xff); - i = 2; - } - -#ifdef READ - if(state->payload_size < i) { - av_log(ctx->log_ctx, AV_LOG_ERROR, - "Invalid SEI user data registered payload.\n"); - return AVERROR_INVALIDDATA; - } - current->data_length = state->payload_size - i; -#endif - - allocate(current->data, current->data_length); - for(j = 0; j < current->data_length; j++) - xu(8, itu_t_t35_payload_byte[], current->data[j], 0x00, 0xff, 1, i + j); - - return 0; -} - -static int FUNC(user_data_unregistered)(CodedBitstreamContext *ctx, RWContext *rw, - SEIRawUserDataUnregistered *current, SEIMessageState *state) { - int err, i; - - HEADER("User Data Unregistered"); - -#ifdef READ - if(state->payload_size < 16) { - av_log(ctx->log_ctx, AV_LOG_ERROR, - "Invalid SEI user data unregistered payload.\n"); - return AVERROR_INVALIDDATA; - } - current->data_length = state->payload_size - 16; -#endif - - for(i = 0; i < 16; i++) - us(8, uuid_iso_iec_11578[i], 0x00, 0xff, 1, i); - - allocate(current->data, current->data_length); - - for(i = 0; i < current->data_length; i++) - xu(8, user_data_payload_byte[i], current->data[i], 0x00, 0xff, 1, i); - - return 0; -} - -static int FUNC(mastering_display_colour_volume)(CodedBitstreamContext *ctx, RWContext *rw, - SEIRawMasteringDisplayColourVolume *current, SEIMessageState *state) { - int err, c; - - HEADER("Mastering Display Colour Volume"); - - for(c = 0; c < 3; c++) { - ubs(16, display_primaries_x[c], 1, c); - ubs(16, display_primaries_y[c], 1, c); - } - - ub(16, white_point_x); - ub(16, white_point_y); - - ub(32, max_display_mastering_luminance); - ub(32, min_display_mastering_luminance); - - return 0; -} - -static int FUNC(content_light_level_info)(CodedBitstreamContext *ctx, RWContext *rw, - SEIRawContentLightLevelInfo *current, SEIMessageState *state) { - int err; - - HEADER("Content Light Level Information"); - - ub(16, max_content_light_level); - ub(16, max_pic_average_light_level); - - return 0; -} - -static int FUNC(alternative_transfer_characteristics)(CodedBitstreamContext *ctx, RWContext *rw, - SEIRawAlternativeTransferCharacteristics *current, - SEIMessageState *state) { - int err; - - HEADER("Alternative Transfer Characteristics"); - - ub(8, preferred_transfer_characteristics); - - return 0; -} - -static int FUNC(message)(CodedBitstreamContext *ctx, RWContext *rw, - SEIRawMessage *current) { - const SEIMessageTypeDescriptor *desc; - int err, i; - - desc = ff_cbs_sei_find_type(ctx, current->payload_type); - if(desc) { - SEIMessageState state = { - .payload_type = current->payload_type, - .payload_size = current->payload_size, - .extension_present = current->extension_bit_length > 0, - }; - int start_position, current_position, bits_written; - -#ifdef READ - CHECK(ff_cbs_sei_alloc_message_payload(current, desc)); -#endif - - start_position = bit_position(rw); - - CHECK(desc->READWRITE(ctx, rw, current->payload, &state)); - - current_position = bit_position(rw); - bits_written = current_position - start_position; - - if(byte_alignment(rw) || state.extension_present || - bits_written < 8 * current->payload_size) { - size_t bits_left; - -#ifdef READ - GetBitContext tmp = *rw; - int trailing_bits, trailing_zero_bits; - - bits_left = 8 * current->payload_size - bits_written; - if(bits_left > 8) - skip_bits_long(&tmp, bits_left - 8); - trailing_bits = get_bits(&tmp, FFMIN(bits_left, 8)); - if(trailing_bits == 0) { - // The trailing bits must contain a bit_equal_to_one, so - // they can't all be zero. - return AVERROR_INVALIDDATA; - } - trailing_zero_bits = ff_ctz(trailing_bits); - current->extension_bit_length = - bits_left - 1 - trailing_zero_bits; -#endif - - if(current->extension_bit_length > 0) { - allocate(current->extension_data, - (current->extension_bit_length + 7) / 8); - - bits_left = current->extension_bit_length; - for(i = 0; bits_left > 0; i++) { - int length = FFMIN(bits_left, 8); - xu(length, reserved_payload_extension_data, - current->extension_data[i], - 0, MAX_UINT_BITS(length), 0); - bits_left -= length; - } - } - - fixed(1, bit_equal_to_one, 1); - while(byte_alignment(rw)) - fixed(1, bit_equal_to_zero, 0); - } - -#ifdef WRITE - current->payload_size = (put_bits_count(rw) - start_position) / 8; -#endif - } - else { - uint8_t *data; - - allocate(current->payload, current->payload_size); - data = current->payload; - - for(i = 0; i < current->payload_size; i++) - xu(8, payload_byte[i], data[i], 0, 255, 1, i); - } - - return 0; -} - -static int FUNC(message_list)(CodedBitstreamContext *ctx, RWContext *rw, - SEIRawMessageList *current, int prefix) { - SEIRawMessage *message; - int err, k; - -#ifdef READ - for(k = 0;; k++) { - uint32_t payload_type = 0; - uint32_t payload_size = 0; - uint32_t tmp; - GetBitContext payload_gbc; - - while(show_bits(rw, 8) == 0xff) { - fixed(8, ff_byte, 0xff); - payload_type += 255; - } - xu(8, last_payload_type_byte, tmp, 0, 254, 0); - payload_type += tmp; - - while(show_bits(rw, 8) == 0xff) { - fixed(8, ff_byte, 0xff); - payload_size += 255; - } - xu(8, last_payload_size_byte, tmp, 0, 254, 0); - payload_size += tmp; - - // There must be space remaining for both the payload and - // the trailing bits on the SEI NAL unit. - if(payload_size + 1 > get_bits_left(rw) / 8) { - av_log(ctx->log_ctx, AV_LOG_ERROR, - "Invalid SEI message: payload_size too large " - "(%" PRIu32 " bytes).\n", - payload_size); - return AVERROR_INVALIDDATA; - } - CHECK(init_get_bits(&payload_gbc, rw->buffer, - get_bits_count(rw) + 8 * payload_size)); - skip_bits_long(&payload_gbc, get_bits_count(rw)); - - CHECK(ff_cbs_sei_list_add(current)); - message = ¤t->messages[k]; - - message->payload_type = payload_type; - message->payload_size = payload_size; - - CHECK(FUNC(message)(ctx, &payload_gbc, message)); - - skip_bits_long(rw, 8 * payload_size); - - if(!cbs_h2645_read_more_rbsp_data(rw)) - break; - } -#else - for(k = 0; k < current->nb_messages; k++) { - PutBitContext start_state; - uint32_t tmp; - int trace, i; - - message = ¤t->messages[k]; - - // We write the payload twice in order to find the size. Trace - // output is switched off for the first write. - trace = ctx->trace_enable; - ctx->trace_enable = 0; - - start_state = *rw; - for(i = 0; i < 2; i++) { - *rw = start_state; - - tmp = message->payload_type; - while(tmp >= 255) { - fixed(8, ff_byte, 0xff); - tmp -= 255; - } - xu(8, last_payload_type_byte, tmp, 0, 254, 0); - - tmp = message->payload_size; - while(tmp >= 255) { - fixed(8, ff_byte, 0xff); - tmp -= 255; - } - xu(8, last_payload_size_byte, tmp, 0, 254, 0); - - err = FUNC(message)(ctx, rw, message); - ctx->trace_enable = trace; - if(err < 0) - return err; - } - } -#endif - - return 0; -} diff --git a/third-party/cbs/cbs_vp9.c b/third-party/cbs/cbs_vp9.c deleted file mode 100644 index 74da5b03875..00000000000 --- a/third-party/cbs/cbs_vp9.c +++ /dev/null @@ -1,675 +0,0 @@ -/* - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include - -#include "cbs/cbs.h" -#include "cbs/cbs_vp9.h" -#include "cbs_internal.h" - - -static int cbs_vp9_read_s(CodedBitstreamContext *ctx, GetBitContext *gbc, - int width, const char *name, - const int *subscripts, int32_t *write_to) { - uint32_t magnitude; - int position, sign; - int32_t value; - - if(ctx->trace_enable) - position = get_bits_count(gbc); - - if(get_bits_left(gbc) < width + 1) { - av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid signed value at " - "%s: bitstream ended.\n", - name); - return AVERROR_INVALIDDATA; - } - - magnitude = get_bits(gbc, width); - sign = get_bits1(gbc); - value = sign ? -(int32_t)magnitude : magnitude; - - if(ctx->trace_enable) { - char bits[33]; - int i; - for(i = 0; i < width; i++) - bits[i] = magnitude >> (width - i - 1) & 1 ? '1' : '0'; - bits[i] = sign ? '1' : '0'; - bits[i + 1] = 0; - - ff_cbs_trace_syntax_element(ctx, position, name, subscripts, - bits, value); - } - - *write_to = value; - return 0; -} - -static int cbs_vp9_write_s(CodedBitstreamContext *ctx, PutBitContext *pbc, - int width, const char *name, - const int *subscripts, int32_t value) { - uint32_t magnitude; - int sign; - - if(put_bits_left(pbc) < width + 1) - return AVERROR(ENOSPC); - - sign = value < 0; - magnitude = sign ? -value : value; - - if(ctx->trace_enable) { - char bits[33]; - int i; - for(i = 0; i < width; i++) - bits[i] = magnitude >> (width - i - 1) & 1 ? '1' : '0'; - bits[i] = sign ? '1' : '0'; - bits[i + 1] = 0; - - ff_cbs_trace_syntax_element(ctx, put_bits_count(pbc), - name, subscripts, bits, value); - } - - put_bits(pbc, width, magnitude); - put_bits(pbc, 1, sign); - - return 0; -} - -static int cbs_vp9_read_increment(CodedBitstreamContext *ctx, GetBitContext *gbc, - uint32_t range_min, uint32_t range_max, - const char *name, uint32_t *write_to) { - uint32_t value; - int position, i; - char bits[8]; - - av_assert0(range_min <= range_max && range_max - range_min < sizeof(bits) - 1); - if(ctx->trace_enable) - position = get_bits_count(gbc); - - for(i = 0, value = range_min; value < range_max;) { - if(get_bits_left(gbc) < 1) { - av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid increment value at " - "%s: bitstream ended.\n", - name); - return AVERROR_INVALIDDATA; - } - if(get_bits1(gbc)) { - bits[i++] = '1'; - ++value; - } - else { - bits[i++] = '0'; - break; - } - } - - if(ctx->trace_enable) { - bits[i] = 0; - ff_cbs_trace_syntax_element(ctx, position, name, NULL, bits, value); - } - - *write_to = value; - return 0; -} - -static int cbs_vp9_write_increment(CodedBitstreamContext *ctx, PutBitContext *pbc, - uint32_t range_min, uint32_t range_max, - const char *name, uint32_t value) { - int len; - - av_assert0(range_min <= range_max && range_max - range_min < 8); - if(value < range_min || value > range_max) { - av_log(ctx->log_ctx, AV_LOG_ERROR, "%s out of range: " - "%" PRIu32 ", but must be in [%" PRIu32 ",%" PRIu32 "].\n", - name, value, range_min, range_max); - return AVERROR_INVALIDDATA; - } - - if(value == range_max) - len = range_max - range_min; - else - len = value - range_min + 1; - if(put_bits_left(pbc) < len) - return AVERROR(ENOSPC); - - if(ctx->trace_enable) { - char bits[8]; - int i; - for(i = 0; i < len; i++) { - if(range_min + i == value) - bits[i] = '0'; - else - bits[i] = '1'; - } - bits[i] = 0; - ff_cbs_trace_syntax_element(ctx, put_bits_count(pbc), - name, NULL, bits, value); - } - - if(len > 0) - put_bits(pbc, len, (1 << len) - 1 - (value != range_max)); - - return 0; -} - -static int cbs_vp9_read_le(CodedBitstreamContext *ctx, GetBitContext *gbc, - int width, const char *name, - const int *subscripts, uint32_t *write_to) { - uint32_t value; - int position, b; - - av_assert0(width % 8 == 0); - - if(ctx->trace_enable) - position = get_bits_count(gbc); - - if(get_bits_left(gbc) < width) { - av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid le value at " - "%s: bitstream ended.\n", - name); - return AVERROR_INVALIDDATA; - } - - value = 0; - for(b = 0; b < width; b += 8) - value |= get_bits(gbc, 8) << b; - - if(ctx->trace_enable) { - char bits[33]; - int i; - for(b = 0; b < width; b += 8) - for(i = 0; i < 8; i++) - bits[b + i] = value >> (b + i) & 1 ? '1' : '0'; - bits[b] = 0; - - ff_cbs_trace_syntax_element(ctx, position, name, subscripts, - bits, value); - } - - *write_to = value; - return 0; -} - -static int cbs_vp9_write_le(CodedBitstreamContext *ctx, PutBitContext *pbc, - int width, const char *name, - const int *subscripts, uint32_t value) { - int b; - - av_assert0(width % 8 == 0); - - if(put_bits_left(pbc) < width) - return AVERROR(ENOSPC); - - if(ctx->trace_enable) { - char bits[33]; - int i; - for(b = 0; b < width; b += 8) - for(i = 0; i < 8; i++) - bits[b + i] = value >> (b + i) & 1 ? '1' : '0'; - bits[b] = 0; - - ff_cbs_trace_syntax_element(ctx, put_bits_count(pbc), - name, subscripts, bits, value); - } - - for(b = 0; b < width; b += 8) - put_bits(pbc, 8, value >> b & 0xff); - - return 0; -} - -#define HEADER(name) \ - do { \ - ff_cbs_trace_header(ctx, name); \ - } while(0) - -#define CHECK(call) \ - do { \ - err = (call); \ - if(err < 0) \ - return err; \ - } while(0) - -#define FUNC_NAME(rw, codec, name) cbs_##codec##_##rw##_##name -#define FUNC_VP9(rw, name) FUNC_NAME(rw, vp9, name) -#define FUNC(name) FUNC_VP9(READWRITE, name) - -#define SUBSCRIPTS(subs, ...) (subs > 0 ? ((int[subs + 1]) { subs, __VA_ARGS__ }) : NULL) - -#define f(width, name) \ - xf(width, name, current->name, 0, ) -#define s(width, name) \ - xs(width, name, current->name, 0, ) -#define fs(width, name, subs, ...) \ - xf(width, name, current->name, subs, __VA_ARGS__) -#define ss(width, name, subs, ...) \ - xs(width, name, current->name, subs, __VA_ARGS__) - -#define READ -#define READWRITE read -#define RWContext GetBitContext - -#define xf(width, name, var, subs, ...) \ - do { \ - uint32_t value; \ - CHECK(ff_cbs_read_unsigned(ctx, rw, width, #name, \ - SUBSCRIPTS(subs, __VA_ARGS__), \ - &value, 0, (1 << width) - 1)); \ - var = value; \ - } while(0) -#define xs(width, name, var, subs, ...) \ - do { \ - int32_t value; \ - CHECK(cbs_vp9_read_s(ctx, rw, width, #name, \ - SUBSCRIPTS(subs, __VA_ARGS__), &value)); \ - var = value; \ - } while(0) - - -#define increment(name, min, max) \ - do { \ - uint32_t value; \ - CHECK(cbs_vp9_read_increment(ctx, rw, min, max, #name, &value)); \ - current->name = value; \ - } while(0) - -#define fle(width, name, subs, ...) \ - do { \ - CHECK(cbs_vp9_read_le(ctx, rw, width, #name, \ - SUBSCRIPTS(subs, __VA_ARGS__), ¤t->name)); \ - } while(0) - -#define delta_q(name) \ - do { \ - uint8_t delta_coded; \ - int8_t delta_q; \ - xf(1, name.delta_coded, delta_coded, 0, ); \ - if(delta_coded) \ - xs(4, name.delta_q, delta_q, 0, ); \ - else \ - delta_q = 0; \ - current->name = delta_q; \ - } while(0) - -#define prob(name, subs, ...) \ - do { \ - uint8_t prob_coded; \ - uint8_t prob; \ - xf(1, name.prob_coded, prob_coded, subs, __VA_ARGS__); \ - if(prob_coded) \ - xf(8, name.prob, prob, subs, __VA_ARGS__); \ - else \ - prob = 255; \ - current->name = prob; \ - } while(0) - -#define fixed(width, name, value) \ - do { \ - av_unused uint32_t fixed_value; \ - CHECK(ff_cbs_read_unsigned(ctx, rw, width, #name, \ - 0, &fixed_value, value, value)); \ - } while(0) - -#define infer(name, value) \ - do { \ - current->name = value; \ - } while(0) - -#define byte_alignment(rw) (get_bits_count(rw) % 8) - -#include "cbs_vp9_syntax_template.c" - -#undef READ -#undef READWRITE -#undef RWContext -#undef xf -#undef xs -#undef increment -#undef fle -#undef delta_q -#undef prob -#undef fixed -#undef infer -#undef byte_alignment - - -#define WRITE -#define READWRITE write -#define RWContext PutBitContext - -#define xf(width, name, var, subs, ...) \ - do { \ - CHECK(ff_cbs_write_unsigned(ctx, rw, width, #name, \ - SUBSCRIPTS(subs, __VA_ARGS__), \ - var, 0, (1 << width) - 1)); \ - } while(0) -#define xs(width, name, var, subs, ...) \ - do { \ - CHECK(cbs_vp9_write_s(ctx, rw, width, #name, \ - SUBSCRIPTS(subs, __VA_ARGS__), var)); \ - } while(0) - -#define increment(name, min, max) \ - do { \ - CHECK(cbs_vp9_write_increment(ctx, rw, min, max, #name, current->name)); \ - } while(0) - -#define fle(width, name, subs, ...) \ - do { \ - CHECK(cbs_vp9_write_le(ctx, rw, width, #name, \ - SUBSCRIPTS(subs, __VA_ARGS__), current->name)); \ - } while(0) - -#define delta_q(name) \ - do { \ - xf(1, name.delta_coded, !!current->name, 0, ); \ - if(current->name) \ - xs(4, name.delta_q, current->name, 0, ); \ - } while(0) - -#define prob(name, subs, ...) \ - do { \ - xf(1, name.prob_coded, current->name != 255, subs, __VA_ARGS__); \ - if(current->name != 255) \ - xf(8, name.prob, current->name, subs, __VA_ARGS__); \ - } while(0) - -#define fixed(width, name, value) \ - do { \ - CHECK(ff_cbs_write_unsigned(ctx, rw, width, #name, \ - 0, value, value, value)); \ - } while(0) - -#define infer(name, value) \ - do { \ - if(current->name != (value)) { \ - av_log(ctx->log_ctx, AV_LOG_WARNING, "Warning: " \ - "%s does not match inferred value: " \ - "%" PRId64 ", but should be %" PRId64 ".\n", \ - #name, (int64_t)current->name, (int64_t)(value)); \ - } \ - } while(0) - -#define byte_alignment(rw) (put_bits_count(rw) % 8) - -#include "cbs_vp9_syntax_template.c" - -#undef WRITE -#undef READWRITE -#undef RWContext -#undef xf -#undef xs -#undef increment -#undef fle -#undef delta_q -#undef prob -#undef fixed -#undef infer -#undef byte_alignment - - -static int cbs_vp9_split_fragment(CodedBitstreamContext *ctx, - CodedBitstreamFragment *frag, - int header) { - uint8_t superframe_header; - int err; - - if(frag->data_size == 0) - return AVERROR_INVALIDDATA; - - // Last byte in the packet. - superframe_header = frag->data[frag->data_size - 1]; - - if((superframe_header & 0xe0) == 0xc0) { - VP9RawSuperframeIndex sfi; - GetBitContext gbc; - size_t index_size, pos; - int i; - - index_size = 2 + (((superframe_header & 0x18) >> 3) + 1) * - ((superframe_header & 0x07) + 1); - - if(index_size > frag->data_size) - return AVERROR_INVALIDDATA; - - err = init_get_bits(&gbc, frag->data + frag->data_size - index_size, - 8 * index_size); - if(err < 0) - return err; - - err = cbs_vp9_read_superframe_index(ctx, &gbc, &sfi); - if(err < 0) - return err; - - pos = 0; - for(i = 0; i <= sfi.frames_in_superframe_minus_1; i++) { - if(pos + sfi.frame_sizes[i] + index_size > frag->data_size) { - av_log(ctx->log_ctx, AV_LOG_ERROR, "Frame %d too large " - "in superframe: %" PRIu32 " bytes.\n", - i, sfi.frame_sizes[i]); - return AVERROR_INVALIDDATA; - } - - err = ff_cbs_insert_unit_data(frag, -1, 0, - frag->data + pos, - sfi.frame_sizes[i], - frag->data_ref); - if(err < 0) - return err; - - pos += sfi.frame_sizes[i]; - } - if(pos + index_size != frag->data_size) { - av_log(ctx->log_ctx, AV_LOG_WARNING, "Extra padding at " - "end of superframe: %zu bytes.\n", - frag->data_size - (pos + index_size)); - } - - return 0; - } - else { - err = ff_cbs_insert_unit_data(frag, -1, 0, - frag->data, frag->data_size, - frag->data_ref); - if(err < 0) - return err; - } - - return 0; -} - -static int cbs_vp9_read_unit(CodedBitstreamContext *ctx, - CodedBitstreamUnit *unit) { - VP9RawFrame *frame; - GetBitContext gbc; - int err, pos; - - err = init_get_bits(&gbc, unit->data, 8 * unit->data_size); - if(err < 0) - return err; - - err = ff_cbs_alloc_unit_content2(ctx, unit); - if(err < 0) - return err; - frame = unit->content; - - err = cbs_vp9_read_frame(ctx, &gbc, frame); - if(err < 0) - return err; - - pos = get_bits_count(&gbc); - av_assert0(pos % 8 == 0); - pos /= 8; - av_assert0(pos <= unit->data_size); - - if(pos == unit->data_size) { - // No data (e.g. a show-existing-frame frame). - } - else { - frame->data_ref = av_buffer_ref(unit->data_ref); - if(!frame->data_ref) - return AVERROR(ENOMEM); - - frame->data = unit->data + pos; - frame->data_size = unit->data_size - pos; - } - - return 0; -} - -static int cbs_vp9_write_unit(CodedBitstreamContext *ctx, - CodedBitstreamUnit *unit, - PutBitContext *pbc) { - VP9RawFrame *frame = unit->content; - int err; - - err = cbs_vp9_write_frame(ctx, pbc, frame); - if(err < 0) - return err; - - // Frame must be byte-aligned. - av_assert0(put_bits_count(pbc) % 8 == 0); - - if(frame->data) { - if(frame->data_size > put_bits_left(pbc) / 8) - return AVERROR(ENOSPC); - - flush_put_bits(pbc); - memcpy(put_bits_ptr(pbc), frame->data, frame->data_size); - skip_put_bytes(pbc, frame->data_size); - } - - return 0; -} - -static int cbs_vp9_assemble_fragment(CodedBitstreamContext *ctx, - CodedBitstreamFragment *frag) { - int err; - - if(frag->nb_units == 1) { - // Output is just the content of the single frame. - - CodedBitstreamUnit *frame = &frag->units[0]; - - frag->data_ref = av_buffer_ref(frame->data_ref); - if(!frag->data_ref) - return AVERROR(ENOMEM); - - frag->data = frame->data; - frag->data_size = frame->data_size; - } - else { - // Build superframe out of frames. - - VP9RawSuperframeIndex sfi; - PutBitContext pbc; - AVBufferRef *ref; - uint8_t *data; - size_t size, max, pos; - int i, size_len; - - if(frag->nb_units > 8) { - av_log(ctx->log_ctx, AV_LOG_ERROR, "Too many frames to " - "make superframe: %d.\n", - frag->nb_units); - return AVERROR(EINVAL); - } - - max = 0; - for(i = 0; i < frag->nb_units; i++) - if(max < frag->units[i].data_size) - max = frag->units[i].data_size; - - if(max < 2) - size_len = 1; - else - size_len = av_log2(max) / 8 + 1; - av_assert0(size_len <= 4); - - sfi.superframe_marker = VP9_SUPERFRAME_MARKER; - sfi.bytes_per_framesize_minus_1 = size_len - 1; - sfi.frames_in_superframe_minus_1 = frag->nb_units - 1; - - size = 2; - for(i = 0; i < frag->nb_units; i++) { - size += size_len + frag->units[i].data_size; - sfi.frame_sizes[i] = frag->units[i].data_size; - } - - ref = av_buffer_alloc(size + AV_INPUT_BUFFER_PADDING_SIZE); - if(!ref) - return AVERROR(ENOMEM); - data = ref->data; - memset(data + size, 0, AV_INPUT_BUFFER_PADDING_SIZE); - - pos = 0; - for(i = 0; i < frag->nb_units; i++) { - av_assert0(size - pos > frag->units[i].data_size); - memcpy(data + pos, frag->units[i].data, - frag->units[i].data_size); - pos += frag->units[i].data_size; - } - av_assert0(size - pos == 2 + frag->nb_units * size_len); - - init_put_bits(&pbc, data + pos, size - pos); - - err = cbs_vp9_write_superframe_index(ctx, &pbc, &sfi); - if(err < 0) { - av_log(ctx->log_ctx, AV_LOG_ERROR, "Failed to write " - "superframe index.\n"); - av_buffer_unref(&ref); - return err; - } - - av_assert0(put_bits_left(&pbc) == 0); - flush_put_bits(&pbc); - - frag->data_ref = ref; - frag->data = data; - frag->data_size = size; - } - - return 0; -} - -static void cbs_vp9_flush(CodedBitstreamContext *ctx) { - CodedBitstreamVP9Context *vp9 = ctx->priv_data; - - memset(vp9->ref, 0, sizeof(vp9->ref)); -} - -static const CodedBitstreamUnitTypeDescriptor cbs_vp9_unit_types[] = { - CBS_UNIT_TYPE_INTERNAL_REF(0, VP9RawFrame, data), - CBS_UNIT_TYPE_END_OF_LIST -}; - -const CodedBitstreamType ff_cbs_type_vp9 = { - .codec_id = AV_CODEC_ID_VP9, - - .priv_data_size = sizeof(CodedBitstreamVP9Context), - - .unit_types = cbs_vp9_unit_types, - - .split_fragment = &cbs_vp9_split_fragment, - .read_unit = &cbs_vp9_read_unit, - .write_unit = &cbs_vp9_write_unit, - - .flush = &cbs_vp9_flush, - - .assemble_fragment = &cbs_vp9_assemble_fragment, -}; diff --git a/third-party/cbs/cbs_vp9_syntax_template.c b/third-party/cbs/cbs_vp9_syntax_template.c deleted file mode 100644 index a0e15c538de..00000000000 --- a/third-party/cbs/cbs_vp9_syntax_template.c +++ /dev/null @@ -1,422 +0,0 @@ -/* - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -static int FUNC(frame_sync_code)(CodedBitstreamContext *ctx, RWContext *rw, - VP9RawFrameHeader *current) { - int err; - - fixed(8, frame_sync_byte_0, VP9_FRAME_SYNC_0); - fixed(8, frame_sync_byte_1, VP9_FRAME_SYNC_1); - fixed(8, frame_sync_byte_2, VP9_FRAME_SYNC_2); - - return 0; -} - -static int FUNC(color_config)(CodedBitstreamContext *ctx, RWContext *rw, - VP9RawFrameHeader *current, int profile) { - CodedBitstreamVP9Context *vp9 = ctx->priv_data; - int err; - - if(profile >= 2) { - f(1, ten_or_twelve_bit); - vp9->bit_depth = current->ten_or_twelve_bit ? 12 : 10; - } - else - vp9->bit_depth = 8; - - f(3, color_space); - - if(current->color_space != VP9_CS_RGB) { - f(1, color_range); - if(profile == 1 || profile == 3) { - f(1, subsampling_x); - f(1, subsampling_y); - fixed(1, reserved_zero, 0); - } - else { - infer(subsampling_x, 1); - infer(subsampling_y, 1); - } - } - else { - infer(color_range, 1); - if(profile == 1 || profile == 3) { - infer(subsampling_x, 0); - infer(subsampling_y, 0); - fixed(1, reserved_zero, 0); - } - } - - vp9->subsampling_x = current->subsampling_x; - vp9->subsampling_y = current->subsampling_y; - - return 0; -} - -static int FUNC(frame_size)(CodedBitstreamContext *ctx, RWContext *rw, - VP9RawFrameHeader *current) { - CodedBitstreamVP9Context *vp9 = ctx->priv_data; - int err; - - f(16, frame_width_minus_1); - f(16, frame_height_minus_1); - - vp9->frame_width = current->frame_width_minus_1 + 1; - vp9->frame_height = current->frame_height_minus_1 + 1; - - vp9->mi_cols = (vp9->frame_width + 7) >> 3; - vp9->mi_rows = (vp9->frame_height + 7) >> 3; - vp9->sb64_cols = (vp9->mi_cols + 7) >> 3; - vp9->sb64_rows = (vp9->mi_rows + 7) >> 3; - - return 0; -} - -static int FUNC(render_size)(CodedBitstreamContext *ctx, RWContext *rw, - VP9RawFrameHeader *current) { - int err; - - f(1, render_and_frame_size_different); - - if(current->render_and_frame_size_different) { - f(16, render_width_minus_1); - f(16, render_height_minus_1); - } - - return 0; -} - -static int FUNC(frame_size_with_refs)(CodedBitstreamContext *ctx, RWContext *rw, - VP9RawFrameHeader *current) { - CodedBitstreamVP9Context *vp9 = ctx->priv_data; - int err, i; - - for(i = 0; i < VP9_REFS_PER_FRAME; i++) { - fs(1, found_ref[i], 1, i); - if(current->found_ref[i]) { - VP9ReferenceFrameState *ref = - &vp9->ref[current->ref_frame_idx[i]]; - - vp9->frame_width = ref->frame_width; - vp9->frame_height = ref->frame_height; - - vp9->subsampling_x = ref->subsampling_x; - vp9->subsampling_y = ref->subsampling_y; - vp9->bit_depth = ref->bit_depth; - - break; - } - } - if(i >= VP9_REFS_PER_FRAME) - CHECK(FUNC(frame_size)(ctx, rw, current)); - else { - vp9->mi_cols = (vp9->frame_width + 7) >> 3; - vp9->mi_rows = (vp9->frame_height + 7) >> 3; - vp9->sb64_cols = (vp9->mi_cols + 7) >> 3; - vp9->sb64_rows = (vp9->mi_rows + 7) >> 3; - } - CHECK(FUNC(render_size)(ctx, rw, current)); - - return 0; -} - -static int FUNC(interpolation_filter)(CodedBitstreamContext *ctx, RWContext *rw, - VP9RawFrameHeader *current) { - int err; - - f(1, is_filter_switchable); - if(!current->is_filter_switchable) - f(2, raw_interpolation_filter_type); - - return 0; -} - -static int FUNC(loop_filter_params)(CodedBitstreamContext *ctx, RWContext *rw, - VP9RawFrameHeader *current) { - int err, i; - - f(6, loop_filter_level); - f(3, loop_filter_sharpness); - - f(1, loop_filter_delta_enabled); - if(current->loop_filter_delta_enabled) { - f(1, loop_filter_delta_update); - if(current->loop_filter_delta_update) { - for(i = 0; i < VP9_MAX_REF_FRAMES; i++) { - fs(1, update_ref_delta[i], 1, i); - if(current->update_ref_delta[i]) - ss(6, loop_filter_ref_deltas[i], 1, i); - } - for(i = 0; i < 2; i++) { - fs(1, update_mode_delta[i], 1, i); - if(current->update_mode_delta[i]) - ss(6, loop_filter_mode_deltas[i], 1, i); - } - } - } - - return 0; -} - -static int FUNC(quantization_params)(CodedBitstreamContext *ctx, RWContext *rw, - VP9RawFrameHeader *current) { - int err; - - f(8, base_q_idx); - - delta_q(delta_q_y_dc); - delta_q(delta_q_uv_dc); - delta_q(delta_q_uv_ac); - - return 0; -} - -static int FUNC(segmentation_params)(CodedBitstreamContext *ctx, RWContext *rw, - VP9RawFrameHeader *current) { - static const uint8_t segmentation_feature_bits[VP9_SEG_LVL_MAX] = { 8, 6, 2, 0 }; - static const uint8_t segmentation_feature_signed[VP9_SEG_LVL_MAX] = { 1, 1, 0, 0 }; - - int err, i, j; - - f(1, segmentation_enabled); - - if(current->segmentation_enabled) { - f(1, segmentation_update_map); - if(current->segmentation_update_map) { - for(i = 0; i < 7; i++) - prob(segmentation_tree_probs[i], 1, i); - f(1, segmentation_temporal_update); - for(i = 0; i < 3; i++) { - if(current->segmentation_temporal_update) - prob(segmentation_pred_prob[i], 1, i); - else - infer(segmentation_pred_prob[i], 255); - } - } - - f(1, segmentation_update_data); - if(current->segmentation_update_data) { - f(1, segmentation_abs_or_delta_update); - for(i = 0; i < VP9_MAX_SEGMENTS; i++) { - for(j = 0; j < VP9_SEG_LVL_MAX; j++) { - fs(1, feature_enabled[i][j], 2, i, j); - if(current->feature_enabled[i][j] && - segmentation_feature_bits[j]) { - fs(segmentation_feature_bits[j], - feature_value[i][j], 2, i, j); - if(segmentation_feature_signed[j]) - fs(1, feature_sign[i][j], 2, i, j); - else - infer(feature_sign[i][j], 0); - } - else { - infer(feature_value[i][j], 0); - infer(feature_sign[i][j], 0); - } - } - } - } - } - - return 0; -} - -static int FUNC(tile_info)(CodedBitstreamContext *ctx, RWContext *rw, - VP9RawFrameHeader *current) { - CodedBitstreamVP9Context *vp9 = ctx->priv_data; - int min_log2_tile_cols, max_log2_tile_cols; - int err; - - min_log2_tile_cols = 0; - while((VP9_MAX_TILE_WIDTH_B64 << min_log2_tile_cols) < vp9->sb64_cols) - ++min_log2_tile_cols; - max_log2_tile_cols = 0; - while((vp9->sb64_cols >> (max_log2_tile_cols + 1)) >= VP9_MIN_TILE_WIDTH_B64) - ++max_log2_tile_cols; - - increment(tile_cols_log2, min_log2_tile_cols, max_log2_tile_cols); - - increment(tile_rows_log2, 0, 2); - - return 0; -} - -static int FUNC(uncompressed_header)(CodedBitstreamContext *ctx, RWContext *rw, - VP9RawFrameHeader *current) { - CodedBitstreamVP9Context *vp9 = ctx->priv_data; - int err, i; - - f(2, frame_marker); - - f(1, profile_low_bit); - f(1, profile_high_bit); - vp9->profile = (current->profile_high_bit << 1) + current->profile_low_bit; - if(vp9->profile == 3) - fixed(1, reserved_zero, 0); - - f(1, show_existing_frame); - if(current->show_existing_frame) { - f(3, frame_to_show_map_idx); - infer(header_size_in_bytes, 0); - infer(refresh_frame_flags, 0x00); - infer(loop_filter_level, 0); - return 0; - } - - f(1, frame_type); - f(1, show_frame); - f(1, error_resilient_mode); - - if(current->frame_type == VP9_KEY_FRAME) { - CHECK(FUNC(frame_sync_code)(ctx, rw, current)); - CHECK(FUNC(color_config)(ctx, rw, current, vp9->profile)); - CHECK(FUNC(frame_size)(ctx, rw, current)); - CHECK(FUNC(render_size)(ctx, rw, current)); - - infer(refresh_frame_flags, 0xff); - } - else { - if(current->show_frame == 0) - f(1, intra_only); - else - infer(intra_only, 0); - - if(current->error_resilient_mode == 0) - f(2, reset_frame_context); - else - infer(reset_frame_context, 0); - - if(current->intra_only == 1) { - CHECK(FUNC(frame_sync_code)(ctx, rw, current)); - - if(vp9->profile > 0) { - CHECK(FUNC(color_config)(ctx, rw, current, vp9->profile)); - } - else { - infer(color_space, 1); - infer(subsampling_x, 1); - infer(subsampling_y, 1); - vp9->bit_depth = 8; - - vp9->subsampling_x = current->subsampling_x; - vp9->subsampling_y = current->subsampling_y; - } - - f(8, refresh_frame_flags); - - CHECK(FUNC(frame_size)(ctx, rw, current)); - CHECK(FUNC(render_size)(ctx, rw, current)); - } - else { - f(8, refresh_frame_flags); - - for(i = 0; i < VP9_REFS_PER_FRAME; i++) { - fs(3, ref_frame_idx[i], 1, i); - fs(1, ref_frame_sign_bias[VP9_LAST_FRAME + i], - 1, VP9_LAST_FRAME + i); - } - - CHECK(FUNC(frame_size_with_refs)(ctx, rw, current)); - f(1, allow_high_precision_mv); - CHECK(FUNC(interpolation_filter)(ctx, rw, current)); - } - } - - if(current->error_resilient_mode == 0) { - f(1, refresh_frame_context); - f(1, frame_parallel_decoding_mode); - } - else { - infer(refresh_frame_context, 0); - infer(frame_parallel_decoding_mode, 1); - } - - f(2, frame_context_idx); - - CHECK(FUNC(loop_filter_params)(ctx, rw, current)); - CHECK(FUNC(quantization_params)(ctx, rw, current)); - CHECK(FUNC(segmentation_params)(ctx, rw, current)); - CHECK(FUNC(tile_info)(ctx, rw, current)); - - f(16, header_size_in_bytes); - - for(i = 0; i < VP9_NUM_REF_FRAMES; i++) { - if(current->refresh_frame_flags & (1 << i)) { - vp9->ref[i] = (VP9ReferenceFrameState) { - .frame_width = vp9->frame_width, - .frame_height = vp9->frame_height, - .subsampling_x = vp9->subsampling_x, - .subsampling_y = vp9->subsampling_y, - .bit_depth = vp9->bit_depth, - }; - } - } - - av_log(ctx->log_ctx, AV_LOG_DEBUG, "Frame: size %dx%d " - "subsample %dx%d bit_depth %d tiles %dx%d.\n", - vp9->frame_width, vp9->frame_height, - vp9->subsampling_x, vp9->subsampling_y, - vp9->bit_depth, 1 << current->tile_cols_log2, - 1 << current->tile_rows_log2); - - return 0; -} - -static int FUNC(trailing_bits)(CodedBitstreamContext *ctx, RWContext *rw) { - int err; - while(byte_alignment(rw) != 0) - fixed(1, zero_bit, 0); - - return 0; -} - -static int FUNC(frame)(CodedBitstreamContext *ctx, RWContext *rw, - VP9RawFrame *current) { - int err; - - HEADER("Frame"); - - CHECK(FUNC(uncompressed_header)(ctx, rw, ¤t->header)); - - CHECK(FUNC(trailing_bits)(ctx, rw)); - - return 0; -} - -static int FUNC(superframe_index)(CodedBitstreamContext *ctx, RWContext *rw, - VP9RawSuperframeIndex *current) { - int err, i; - - HEADER("Superframe Index"); - - f(3, superframe_marker); - f(2, bytes_per_framesize_minus_1); - f(3, frames_in_superframe_minus_1); - - for(i = 0; i <= current->frames_in_superframe_minus_1; i++) { - // Surprise little-endian! - fle(8 * (current->bytes_per_framesize_minus_1 + 1), - frame_sizes[i], 1, i); - } - - f(3, superframe_marker); - f(2, bytes_per_framesize_minus_1); - f(3, frames_in_superframe_minus_1); - - return 0; -} diff --git a/third-party/cbs/config.h b/third-party/cbs/config.h deleted file mode 100644 index b33923f3ff2..00000000000 --- a/third-party/cbs/config.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef CBS_CONFIG_H -#define CBS_CONFIG_H - -#if defined(__BYTE_ORDER) && __BYTE_ORDER == __BIG_ENDIAN || \ - defined(__BIG_ENDIAN__) || \ - defined(__ARMEB__) || \ - defined(__THUMBEB__) || \ - defined(__AARCH64EB__) || \ - defined(_MIBSEB) || defined(__MIBSEB) || defined(__MIBSEB__) -// It's a big-endian target architecture -#define AV_HAVE_BIGENDIAN 1 - -#elif defined(__BYTE_ORDER) && __BYTE_ORDER == __LITTLE_ENDIAN || \ - defined(__LITTLE_ENDIAN__) || \ - defined(__ARMEL__) || \ - defined(__THUMBEL__) || \ - defined(__AARCH64EL__) || \ - defined(_MIPSEL) || defined(__MIPSEL) || defined(__MIPSEL__) || \ - defined(_WIN32) -// It's a little-endian target architecture -#define AV_HAVE_BIGENDIAN 0 - -#else -#error "Unknown Endianness" -#endif - -#endif \ No newline at end of file diff --git a/third-party/cbs/defs.h b/third-party/cbs/defs.h deleted file mode 100644 index 1c5f0ce82c1..00000000000 --- a/third-party/cbs/defs.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_DEFS_H -#define AVCODEC_DEFS_H - -/** - * @file - * @ingroup libavc - * Misc types and constants that do not belong anywhere else. - */ - -#include -#include - -/** - * @ingroup lavc_decoding - * Required number of additionally allocated bytes at the end of the input bitstream for decoding. - * This is mainly needed because some optimized bitstream readers read - * 32 or 64 bit at once and could read over the end.
- * Note: If the first 23 bits of the additional bytes are not 0, then damaged - * MPEG bitstreams could cause overread and segfault. - */ -#define AV_INPUT_BUFFER_PADDING_SIZE 64 - -/** - * Encode extradata length to a buffer. Used by xiph codecs. - * - * @param s buffer to write to; must be at least (v/255+1) bytes long - * @param v size of extradata in bytes - * @return number of bytes written to the buffer. - */ -unsigned int av_xiphlacing(unsigned char *s, unsigned int v); - -#endif // AVCODEC_DEFS_H diff --git a/third-party/cbs/get_bits.h b/third-party/cbs/get_bits.h deleted file mode 100644 index 3c34b0408d5..00000000000 --- a/third-party/cbs/get_bits.h +++ /dev/null @@ -1,831 +0,0 @@ -/* - * Copyright (c) 2004 Michael Niedermayer - * Copyright (c) 2016 Alexandra Hájková - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * bitstream reader API header. - */ - -#ifndef AVCODEC_GET_BITS_H -#define AVCODEC_GET_BITS_H - -#include - -#include -#include -#include -#include - -#include "defs.h" -#include "mathops.h" -#include "vlc.h" - -/* - * Safe bitstream reading: - * optionally, the get_bits API can check to ensure that we - * don't read past input buffer boundaries. This is protected - * with CONFIG_SAFE_BITSTREAM_READER at the global level, and - * then below that with UNCHECKED_BITSTREAM_READER at the per- - * decoder level. This means that decoders that check internally - * can "#define UNCHECKED_BITSTREAM_READER 1" to disable - * overread checks. - * Boundary checking causes a minor performance penalty so for - * applications that won't want/need this, it can be disabled - * globally using "#define CONFIG_SAFE_BITSTREAM_READER 0". - */ -#ifndef UNCHECKED_BITSTREAM_READER -#define UNCHECKED_BITSTREAM_READER 0 -#endif - -#ifndef CACHED_BITSTREAM_READER -#define CACHED_BITSTREAM_READER 0 -#endif - -#include "cbs/h2645_parse.h" - -static inline unsigned int get_bits(GetBitContext *s, int n); -static inline void skip_bits(GetBitContext *s, int n); -static inline unsigned int show_bits(GetBitContext *s, int n); - -/* Bitstream reader API docs: - * name - * arbitrary name which is used as prefix for the internal variables - * - * gb - * getbitcontext - * - * OPEN_READER(name, gb) - * load gb into local variables - * - * CLOSE_READER(name, gb) - * store local vars in gb - * - * UPDATE_CACHE(name, gb) - * Refill the internal cache from the bitstream. - * After this call at least MIN_CACHE_BITS will be available. - * - * GET_CACHE(name, gb) - * Will output the contents of the internal cache, - * next bit is MSB of 32 or 64 bits (FIXME 64 bits). - * - * SHOW_UBITS(name, gb, num) - * Will return the next num bits. - * - * SHOW_SBITS(name, gb, num) - * Will return the next num bits and do sign extension. - * - * SKIP_BITS(name, gb, num) - * Will skip over the next num bits. - * Note, this is equivalent to SKIP_CACHE; SKIP_COUNTER. - * - * SKIP_CACHE(name, gb, num) - * Will remove the next num bits from the cache (note SKIP_COUNTER - * MUST be called before UPDATE_CACHE / CLOSE_READER). - * - * SKIP_COUNTER(name, gb, num) - * Will increment the internal bit counter (see SKIP_CACHE & SKIP_BITS). - * - * LAST_SKIP_BITS(name, gb, num) - * Like SKIP_BITS, to be used if next call is UPDATE_CACHE or CLOSE_READER. - * - * BITS_LEFT(name, gb) - * Return the number of bits left - * - * For examples see get_bits, show_bits, skip_bits, get_vlc. - */ - -#if CACHED_BITSTREAM_READER -#define MIN_CACHE_BITS 64 -#elif defined LONG_BITSTREAM_READER -#define MIN_CACHE_BITS 32 -#else -#define MIN_CACHE_BITS 25 -#endif - -#if !CACHED_BITSTREAM_READER - -#define OPEN_READER_NOSIZE(name, gb) \ - unsigned int name##_index = (gb)->index; \ - unsigned int av_unused name##_cache - -#if UNCHECKED_BITSTREAM_READER -#define OPEN_READER(name, gb) OPEN_READER_NOSIZE(name, gb) - -#define BITS_AVAILABLE(name, gb) 1 -#else -#define OPEN_READER(name, gb) \ - OPEN_READER_NOSIZE(name, gb); \ - unsigned int name##_size_plus8 = (gb)->size_in_bits_plus8 - -#define BITS_AVAILABLE(name, gb) name##_index < name##_size_plus8 -#endif - -#define CLOSE_READER(name, gb) (gb)->index = name##_index - -#ifdef LONG_BITSTREAM_READER - -#define UPDATE_CACHE_LE(name, gb) name##_cache = \ - AV_RL64((gb)->buffer + (name##_index >> 3)) >> (name##_index & 7) - -#define UPDATE_CACHE_BE(name, gb) name##_cache = \ - AV_RB64((gb)->buffer + (name##_index >> 3)) >> (32 - (name##_index & 7)) - -#else - -#define UPDATE_CACHE_LE(name, gb) name##_cache = \ - AV_RL32((gb)->buffer + (name##_index >> 3)) >> (name##_index & 7) - -#define UPDATE_CACHE_BE(name, gb) name##_cache = \ - AV_RB32((gb)->buffer + (name##_index >> 3)) << (name##_index & 7) - -#endif - - -#ifdef BITSTREAM_READER_LE - -#define UPDATE_CACHE(name, gb) UPDATE_CACHE_LE(name, gb) - -#define SKIP_CACHE(name, gb, num) name##_cache >>= (num) - -#else - -#define UPDATE_CACHE(name, gb) UPDATE_CACHE_BE(name, gb) - -#define SKIP_CACHE(name, gb, num) name##_cache <<= (num) - -#endif - -#if UNCHECKED_BITSTREAM_READER -#define SKIP_COUNTER(name, gb, num) name##_index += (num) -#else -#define SKIP_COUNTER(name, gb, num) \ - name##_index = FFMIN(name##_size_plus8, name##_index + (num)) -#endif - -#define BITS_LEFT(name, gb) ((int)((gb)->size_in_bits - name##_index)) - -#define SKIP_BITS(name, gb, num) \ - do { \ - SKIP_CACHE(name, gb, num); \ - SKIP_COUNTER(name, gb, num); \ - } while(0) - -#define LAST_SKIP_BITS(name, gb, num) SKIP_COUNTER(name, gb, num) - -#define SHOW_UBITS_LE(name, gb, num) zero_extend(name##_cache, num) -#define SHOW_SBITS_LE(name, gb, num) sign_extend(name##_cache, num) - -#define SHOW_UBITS_BE(name, gb, num) NEG_USR32(name##_cache, num) -#define SHOW_SBITS_BE(name, gb, num) NEG_SSR32(name##_cache, num) - -#ifdef BITSTREAM_READER_LE -#define SHOW_UBITS(name, gb, num) SHOW_UBITS_LE(name, gb, num) -#define SHOW_SBITS(name, gb, num) SHOW_SBITS_LE(name, gb, num) -#else -#define SHOW_UBITS(name, gb, num) SHOW_UBITS_BE(name, gb, num) -#define SHOW_SBITS(name, gb, num) SHOW_SBITS_BE(name, gb, num) -#endif - -#define GET_CACHE(name, gb) ((uint32_t)name##_cache) - -#endif - -static inline int get_bits_count(const GetBitContext *s) { -#if CACHED_BITSTREAM_READER - return s->index - s->bits_left; -#else - return s->index; -#endif -} - -#if CACHED_BITSTREAM_READER -static inline void refill_32(GetBitContext *s, int is_le) { -#if !UNCHECKED_BITSTREAM_READER - if(s->index >> 3 >= s->buffer_end - s->buffer) - return; -#endif - - if(is_le) - s->cache = (uint64_t)AV_RL32(s->buffer + (s->index >> 3)) << s->bits_left | s->cache; - else - s->cache = s->cache | (uint64_t)AV_RB32(s->buffer + (s->index >> 3)) << (32 - s->bits_left); - s->index += 32; - s->bits_left += 32; -} - -static inline void refill_64(GetBitContext *s, int is_le) { -#if !UNCHECKED_BITSTREAM_READER - if(s->index >> 3 >= s->buffer_end - s->buffer) - return; -#endif - - if(is_le) - s->cache = AV_RL64(s->buffer + (s->index >> 3)); - else - s->cache = AV_RB64(s->buffer + (s->index >> 3)); - s->index += 64; - s->bits_left = 64; -} - -static inline uint64_t get_val(GetBitContext *s, unsigned n, int is_le) { - uint64_t ret; - av_assert2(n > 0 && n <= 63); - if(is_le) { - ret = s->cache & ((UINT64_C(1) << n) - 1); - s->cache >>= n; - } - else { - ret = s->cache >> (64 - n); - s->cache <<= n; - } - s->bits_left -= n; - return ret; -} - -static inline unsigned show_val(const GetBitContext *s, unsigned n) { -#ifdef BITSTREAM_READER_LE - return s->cache & ((UINT64_C(1) << n) - 1); -#else - return s->cache >> (64 - n); -#endif -} -#endif - -/** - * Skips the specified number of bits. - * @param n the number of bits to skip, - * For the UNCHECKED_BITSTREAM_READER this must not cause the distance - * from the start to overflow int32_t. Staying within the bitstream + padding - * is sufficient, too. - */ -static inline void skip_bits_long(GetBitContext *s, int n) { -#if CACHED_BITSTREAM_READER - skip_bits(s, n); -#else -#if UNCHECKED_BITSTREAM_READER - s->index += n; -#else - s->index += av_clip(n, -s->index, s->size_in_bits_plus8 - s->index); -#endif -#endif -} - -#if CACHED_BITSTREAM_READER -static inline void skip_remaining(GetBitContext *s, unsigned n) { -#ifdef BITSTREAM_READER_LE - s->cache >>= n; -#else - s->cache <<= n; -#endif - s->bits_left -= n; -} -#endif - -/** - * Read MPEG-1 dc-style VLC (sign bit + mantissa with no MSB). - * if MSB not set it is negative - * @param n length in bits - */ -static inline int get_xbits(GetBitContext *s, int n) { -#if CACHED_BITSTREAM_READER - int32_t cache = show_bits(s, 32); - int sign = ~cache >> 31; - skip_remaining(s, n); - - return ((((uint32_t)(sign ^ cache)) >> (32 - n)) ^ sign) - sign; -#else - register int sign; - register int32_t cache; - OPEN_READER(re, s); - av_assert2(n > 0 && n <= 25); - UPDATE_CACHE(re, s); - cache = GET_CACHE(re, s); - sign = ~cache >> 31; - LAST_SKIP_BITS(re, s, n); - CLOSE_READER(re, s); - return (NEG_USR32(sign ^ cache, n) ^ sign) - sign; -#endif -} - -#if !CACHED_BITSTREAM_READER -static inline int get_xbits_le(GetBitContext *s, int n) { - register int sign; - register int32_t cache; - OPEN_READER(re, s); - av_assert2(n > 0 && n <= 25); - UPDATE_CACHE_LE(re, s); - cache = GET_CACHE(re, s); - sign = sign_extend(~cache, n) >> 31; - LAST_SKIP_BITS(re, s, n); - CLOSE_READER(re, s); - return (zero_extend(sign ^ cache, n) ^ sign) - sign; -} -#endif - -static inline int get_sbits(GetBitContext *s, int n) { - register int tmp; -#if CACHED_BITSTREAM_READER - av_assert2(n > 0 && n <= 25); - tmp = sign_extend(get_bits(s, n), n); -#else - OPEN_READER(re, s); - av_assert2(n > 0 && n <= 25); - UPDATE_CACHE(re, s); - tmp = SHOW_SBITS(re, s, n); - LAST_SKIP_BITS(re, s, n); - CLOSE_READER(re, s); -#endif - return tmp; -} - -/** - * Read 1-25 bits. - */ -static inline unsigned int get_bits(GetBitContext *s, int n) { - register unsigned int tmp; -#if CACHED_BITSTREAM_READER - - av_assert2(n > 0 && n <= 32); - if(n > s->bits_left) { -#ifdef BITSTREAM_READER_LE - refill_32(s, 1); -#else - refill_32(s, 0); -#endif - if(s->bits_left < 32) - s->bits_left = n; - } - -#ifdef BITSTREAM_READER_LE - tmp = get_val(s, n, 1); -#else - tmp = get_val(s, n, 0); -#endif -#else - OPEN_READER(re, s); - av_assert2(n > 0 && n <= 25); - UPDATE_CACHE(re, s); - tmp = SHOW_UBITS(re, s, n); - LAST_SKIP_BITS(re, s, n); - CLOSE_READER(re, s); -#endif - av_assert2(tmp < UINT64_C(1) << n); - return tmp; -} - -/** - * Read 0-25 bits. - */ -static av_always_inline int get_bitsz(GetBitContext *s, int n) { - return n ? get_bits(s, n) : 0; -} - -static inline unsigned int get_bits_le(GetBitContext *s, int n) { -#if CACHED_BITSTREAM_READER - av_assert2(n > 0 && n <= 32); - if(n > s->bits_left) { - refill_32(s, 1); - if(s->bits_left < 32) - s->bits_left = n; - } - - return get_val(s, n, 1); -#else - register int tmp; - OPEN_READER(re, s); - av_assert2(n > 0 && n <= 25); - UPDATE_CACHE_LE(re, s); - tmp = SHOW_UBITS_LE(re, s, n); - LAST_SKIP_BITS(re, s, n); - CLOSE_READER(re, s); - return tmp; -#endif -} - -/** - * Show 1-25 bits. - */ -static inline unsigned int show_bits(GetBitContext *s, int n) { - register unsigned int tmp; -#if CACHED_BITSTREAM_READER - if(n > s->bits_left) -#ifdef BITSTREAM_READER_LE - refill_32(s, 1); -#else - refill_32(s, 0); -#endif - - tmp = show_val(s, n); -#else - OPEN_READER_NOSIZE(re, s); - av_assert2(n > 0 && n <= 25); - UPDATE_CACHE(re, s); - tmp = SHOW_UBITS(re, s, n); -#endif - return tmp; -} - -static inline void skip_bits(GetBitContext *s, int n) { -#if CACHED_BITSTREAM_READER - if(n < s->bits_left) - skip_remaining(s, n); - else { - n -= s->bits_left; - s->cache = 0; - s->bits_left = 0; - - if(n >= 64) { - unsigned skip = (n / 8) * 8; - - n -= skip; - s->index += skip; - } -#ifdef BITSTREAM_READER_LE - refill_64(s, 1); -#else - refill_64(s, 0); -#endif - if(n) - skip_remaining(s, n); - } -#else - OPEN_READER(re, s); - LAST_SKIP_BITS(re, s, n); - CLOSE_READER(re, s); -#endif -} - -static inline unsigned int get_bits1(GetBitContext *s) { -#if CACHED_BITSTREAM_READER - if(!s->bits_left) -#ifdef BITSTREAM_READER_LE - refill_64(s, 1); -#else - refill_64(s, 0); -#endif - -#ifdef BITSTREAM_READER_LE - return get_val(s, 1, 1); -#else - return get_val(s, 1, 0); -#endif -#else - unsigned int index = s->index; - uint8_t result = s->buffer[index >> 3]; -#ifdef BITSTREAM_READER_LE - result >>= index & 7; - result &= 1; -#else - result <<= index & 7; - result >>= 8 - 1; -#endif -#if !UNCHECKED_BITSTREAM_READER - if(s->index < s->size_in_bits_plus8) -#endif - index++; - s->index = index; - - return result; -#endif -} - -static inline unsigned int show_bits1(GetBitContext *s) { - return show_bits(s, 1); -} - -static inline void skip_bits1(GetBitContext *s) { - skip_bits(s, 1); -} - -/** - * Read 0-32 bits. - */ -static inline unsigned int get_bits_long(GetBitContext *s, int n) { - av_assert2(n >= 0 && n <= 32); - if(!n) { - return 0; -#if CACHED_BITSTREAM_READER - } - return get_bits(s, n); -#else - } - else if(n <= MIN_CACHE_BITS) { - return get_bits(s, n); - } - else { -#ifdef BITSTREAM_READER_LE - unsigned ret = get_bits(s, 16); - return ret | (get_bits(s, n - 16) << 16); -#else - unsigned ret = get_bits(s, 16) << (n - 16); - return ret | get_bits(s, n - 16); -#endif - } -#endif -} - -/** - * Read 0-64 bits. - */ -static inline uint64_t get_bits64(GetBitContext *s, int n) { - if(n <= 32) { - return get_bits_long(s, n); - } - else { -#ifdef BITSTREAM_READER_LE - uint64_t ret = get_bits_long(s, 32); - return ret | (uint64_t)get_bits_long(s, n - 32) << 32; -#else - uint64_t ret = (uint64_t)get_bits_long(s, n - 32) << 32; - return ret | get_bits_long(s, 32); -#endif - } -} - -/** - * Read 0-32 bits as a signed integer. - */ -static inline int get_sbits_long(GetBitContext *s, int n) { - // sign_extend(x, 0) is undefined - if(!n) - return 0; - - return sign_extend(get_bits_long(s, n), n); -} - -/** - * Show 0-32 bits. - */ -static inline unsigned int show_bits_long(GetBitContext *s, int n) { - if(n <= MIN_CACHE_BITS) { - return show_bits(s, n); - } - else { - GetBitContext gb = *s; - return get_bits_long(&gb, n); - } -} - -static inline int check_marker(void *logctx, GetBitContext *s, const char *msg) { - int bit = get_bits1(s); - if(!bit) - av_log(logctx, AV_LOG_INFO, "Marker bit missing at %d of %d %s\n", - get_bits_count(s) - 1, s->size_in_bits, msg); - - return bit; -} - -static inline int init_get_bits_xe(GetBitContext *s, const uint8_t *buffer, - int bit_size, int is_le) { - int buffer_size; - int ret = 0; - - if(bit_size >= INT_MAX - FFMAX(7, AV_INPUT_BUFFER_PADDING_SIZE * 8) || bit_size < 0 || !buffer) { - bit_size = 0; - buffer = NULL; - ret = AVERROR_INVALIDDATA; - } - - buffer_size = (bit_size + 7) >> 3; - - s->buffer = buffer; - s->size_in_bits = bit_size; - s->size_in_bits_plus8 = bit_size + 8; - s->buffer_end = buffer + buffer_size; - s->index = 0; - -#if CACHED_BITSTREAM_READER - s->cache = 0; - s->bits_left = 0; - refill_64(s, is_le); -#endif - - return ret; -} - -/** - * Initialize GetBitContext. - * @param buffer bitstream buffer, must be AV_INPUT_BUFFER_PADDING_SIZE bytes - * larger than the actual read bits because some optimized bitstream - * readers read 32 or 64 bit at once and could read over the end - * @param bit_size the size of the buffer in bits - * @return 0 on success, AVERROR_INVALIDDATA if the buffer_size would overflow. - */ -static inline int init_get_bits(GetBitContext *s, const uint8_t *buffer, - int bit_size) { -#ifdef BITSTREAM_READER_LE - return init_get_bits_xe(s, buffer, bit_size, 1); -#else - return init_get_bits_xe(s, buffer, bit_size, 0); -#endif -} - -/** - * Initialize GetBitContext. - * @param buffer bitstream buffer, must be AV_INPUT_BUFFER_PADDING_SIZE bytes - * larger than the actual read bits because some optimized bitstream - * readers read 32 or 64 bit at once and could read over the end - * @param byte_size the size of the buffer in bytes - * @return 0 on success, AVERROR_INVALIDDATA if the buffer_size would overflow. - */ -static inline int init_get_bits8(GetBitContext *s, const uint8_t *buffer, - int byte_size) { - if(byte_size > INT_MAX / 8 || byte_size < 0) - byte_size = -1; - return init_get_bits(s, buffer, byte_size * 8); -} - -static inline int init_get_bits8_le(GetBitContext *s, const uint8_t *buffer, - int byte_size) { - if(byte_size > INT_MAX / 8 || byte_size < 0) - byte_size = -1; - return init_get_bits_xe(s, buffer, byte_size * 8, 1); -} - -static inline const uint8_t *align_get_bits(GetBitContext *s) { - int n = -get_bits_count(s) & 7; - if(n) - skip_bits(s, n); - return s->buffer + (s->index >> 3); -} - -/** - * If the vlc code is invalid and max_depth=1, then no bits will be removed. - * If the vlc code is invalid and max_depth>1, then the number of bits removed - * is undefined. - */ -#define GET_VLC(code, name, gb, table, bits, max_depth) \ - do { \ - int n, nb_bits; \ - unsigned int index; \ - \ - index = SHOW_UBITS(name, gb, bits); \ - code = table[index][0]; \ - n = table[index][1]; \ - \ - if(max_depth > 1 && n < 0) { \ - LAST_SKIP_BITS(name, gb, bits); \ - UPDATE_CACHE(name, gb); \ - \ - nb_bits = -n; \ - \ - index = SHOW_UBITS(name, gb, nb_bits) + code; \ - code = table[index][0]; \ - n = table[index][1]; \ - if(max_depth > 2 && n < 0) { \ - LAST_SKIP_BITS(name, gb, nb_bits); \ - UPDATE_CACHE(name, gb); \ - \ - nb_bits = -n; \ - \ - index = SHOW_UBITS(name, gb, nb_bits) + code; \ - code = table[index][0]; \ - n = table[index][1]; \ - } \ - } \ - SKIP_BITS(name, gb, n); \ - } while(0) - -#define GET_RL_VLC(level, run, name, gb, table, bits, \ - max_depth, need_update) \ - do { \ - int n, nb_bits; \ - unsigned int index; \ - \ - index = SHOW_UBITS(name, gb, bits); \ - level = table[index].level; \ - n = table[index].len; \ - \ - if(max_depth > 1 && n < 0) { \ - SKIP_BITS(name, gb, bits); \ - if(need_update) { \ - UPDATE_CACHE(name, gb); \ - } \ - \ - nb_bits = -n; \ - \ - index = SHOW_UBITS(name, gb, nb_bits) + level; \ - level = table[index].level; \ - n = table[index].len; \ - if(max_depth > 2 && n < 0) { \ - LAST_SKIP_BITS(name, gb, nb_bits); \ - if(need_update) { \ - UPDATE_CACHE(name, gb); \ - } \ - nb_bits = -n; \ - \ - index = SHOW_UBITS(name, gb, nb_bits) + level; \ - level = table[index].level; \ - n = table[index].len; \ - } \ - } \ - run = table[index].run; \ - SKIP_BITS(name, gb, n); \ - } while(0) - -/* Return the LUT element for the given bitstream configuration. */ -static inline int set_idx(GetBitContext *s, int code, int *n, int *nb_bits, - VLC_TYPE (*table)[2]) { - unsigned idx; - - *nb_bits = -*n; - idx = show_bits(s, *nb_bits) + code; - *n = table[idx][1]; - - return table[idx][0]; -} - -/** - * Parse a vlc code. - * @param bits is the number of bits which will be read at once, must be - * identical to nb_bits in init_vlc() - * @param max_depth is the number of times bits bits must be read to completely - * read the longest vlc code - * = (max_vlc_length + bits - 1) / bits - * @returns the code parsed or -1 if no vlc matches - */ -static av_always_inline int get_vlc2(GetBitContext *s, VLC_TYPE (*table)[2], - int bits, int max_depth) { -#if CACHED_BITSTREAM_READER - int nb_bits; - unsigned idx = show_bits(s, bits); - int code = table[idx][0]; - int n = table[idx][1]; - - if(max_depth > 1 && n < 0) { - skip_remaining(s, bits); - code = set_idx(s, code, &n, &nb_bits, table); - if(max_depth > 2 && n < 0) { - skip_remaining(s, nb_bits); - code = set_idx(s, code, &n, &nb_bits, table); - } - } - skip_remaining(s, n); - - return code; -#else - int code; - - OPEN_READER(re, s); - UPDATE_CACHE(re, s); - - GET_VLC(code, re, s, table, bits, max_depth); - - CLOSE_READER(re, s); - - return code; -#endif -} - -static inline int decode012(GetBitContext *gb) { - int n; - n = get_bits1(gb); - if(n == 0) - return 0; - else - return get_bits1(gb) + 1; -} - -static inline int decode210(GetBitContext *gb) { - if(get_bits1(gb)) - return 0; - else - return 2 - get_bits1(gb); -} - -static inline int get_bits_left(GetBitContext *gb) { - return gb->size_in_bits - get_bits_count(gb); -} - -static inline int skip_1stop_8data_bits(GetBitContext *gb) { - if(get_bits_left(gb) <= 0) - return AVERROR_INVALIDDATA; - - while(get_bits1(gb)) { - skip_bits(gb, 8); - if(get_bits_left(gb) <= 0) - return AVERROR_INVALIDDATA; - } - - return 0; -} - -#endif /* AVCODEC_GET_BITS_H */ diff --git a/third-party/cbs/h2645_parse.c b/third-party/cbs/h2645_parse.c deleted file mode 100644 index a401ca577e6..00000000000 --- a/third-party/cbs/h2645_parse.c +++ /dev/null @@ -1,535 +0,0 @@ -/* - * H.264/HEVC common parsing code - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include - -#include -#include - -#include "cbs/h264.h" -#include "cbs/h2645_parse.h" -#include "cbs/hevc.h" - -#include "bytestream.h" -#include "config.h" -#include "get_bits.h" -#include "intmath.h" - -int ff_h2645_extract_rbsp(const uint8_t *src, int length, - H2645RBSP *rbsp, H2645NAL *nal, int small_padding) { - int i, si, di; - uint8_t *dst; - - nal->skipped_bytes = 0; -#define STARTCODE_TEST \ - if(i + 2 < length && src[i + 1] == 0 && src[i + 2] <= 3) { \ - if(src[i + 2] != 3 && src[i + 2] != 0) { \ - /* startcode, so we must be past the end */ \ - length = i; \ - } \ - break; \ - } -#if HAVE_FAST_UNALIGNED -#define FIND_FIRST_ZERO \ - if(i > 0 && !src[i]) \ - i--; \ - while(src[i]) \ - i++ -#if HAVE_FAST_64BIT - for(i = 0; i + 1 < length; i += 9) { - if(!((~AV_RN64(src + i) & - (AV_RN64(src + i) - 0x0100010001000101ULL)) & - 0x8000800080008080ULL)) - continue; - FIND_FIRST_ZERO; - STARTCODE_TEST; - i -= 7; - } -#else - for(i = 0; i + 1 < length; i += 5) { - if(!((~AV_RN32(src + i) & - (AV_RN32(src + i) - 0x01000101U)) & - 0x80008080U)) - continue; - FIND_FIRST_ZERO; - STARTCODE_TEST; - i -= 3; - } -#endif /* HAVE_FAST_64BIT */ -#else - for(i = 0; i + 1 < length; i += 2) { - if(src[i]) - continue; - if(i > 0 && src[i - 1] == 0) - i--; - STARTCODE_TEST; - } -#endif /* HAVE_FAST_UNALIGNED */ - - if(i >= length - 1 && small_padding) { // no escaped 0 - nal->data = - nal->raw_data = src; - nal->size = - nal->raw_size = length; - return length; - } - else if(i > length) - i = length; - - nal->rbsp_buffer = &rbsp->rbsp_buffer[rbsp->rbsp_buffer_size]; - dst = nal->rbsp_buffer; - - memcpy(dst, src, i); - si = di = i; - while(si + 2 < length) { - // remove escapes (very rare 1:2^22) - if(src[si + 2] > 3) { - dst[di++] = src[si++]; - dst[di++] = src[si++]; - } - else if(src[si] == 0 && src[si + 1] == 0 && src[si + 2] != 0) { - if(src[si + 2] == 3) { // escape - dst[di++] = 0; - dst[di++] = 0; - si += 3; - - if(nal->skipped_bytes_pos) { - nal->skipped_bytes++; - if(nal->skipped_bytes_pos_size < nal->skipped_bytes) { - nal->skipped_bytes_pos_size *= 2; - av_assert0(nal->skipped_bytes_pos_size >= nal->skipped_bytes); - av_reallocp_array(&nal->skipped_bytes_pos, - nal->skipped_bytes_pos_size, - sizeof(*nal->skipped_bytes_pos)); - if(!nal->skipped_bytes_pos) { - nal->skipped_bytes_pos_size = 0; - return AVERROR(ENOMEM); - } - } - if(nal->skipped_bytes_pos) - nal->skipped_bytes_pos[nal->skipped_bytes - 1] = di - 1; - } - continue; - } - else // next start code - goto nsc; - } - - dst[di++] = src[si++]; - } - while(si < length) - dst[di++] = src[si++]; - -nsc: - memset(dst + di, 0, AV_INPUT_BUFFER_PADDING_SIZE); - - nal->data = dst; - nal->size = di; - nal->raw_data = src; - nal->raw_size = si; - rbsp->rbsp_buffer_size += si; - - return si; -} - -static const char *const hevc_nal_type_name[64] = { - "TRAIL_N", // HEVC_NAL_TRAIL_N - "TRAIL_R", // HEVC_NAL_TRAIL_R - "TSA_N", // HEVC_NAL_TSA_N - "TSA_R", // HEVC_NAL_TSA_R - "STSA_N", // HEVC_NAL_STSA_N - "STSA_R", // HEVC_NAL_STSA_R - "RADL_N", // HEVC_NAL_RADL_N - "RADL_R", // HEVC_NAL_RADL_R - "RASL_N", // HEVC_NAL_RASL_N - "RASL_R", // HEVC_NAL_RASL_R - "RSV_VCL_N10", // HEVC_NAL_VCL_N10 - "RSV_VCL_R11", // HEVC_NAL_VCL_R11 - "RSV_VCL_N12", // HEVC_NAL_VCL_N12 - "RSV_VLC_R13", // HEVC_NAL_VCL_R13 - "RSV_VCL_N14", // HEVC_NAL_VCL_N14 - "RSV_VCL_R15", // HEVC_NAL_VCL_R15 - "BLA_W_LP", // HEVC_NAL_BLA_W_LP - "BLA_W_RADL", // HEVC_NAL_BLA_W_RADL - "BLA_N_LP", // HEVC_NAL_BLA_N_LP - "IDR_W_RADL", // HEVC_NAL_IDR_W_RADL - "IDR_N_LP", // HEVC_NAL_IDR_N_LP - "CRA_NUT", // HEVC_NAL_CRA_NUT - "RSV_IRAP_VCL22", // HEVC_NAL_RSV_IRAP_VCL22 - "RSV_IRAP_VCL23", // HEVC_NAL_RSV_IRAP_VCL23 - "RSV_VCL24", // HEVC_NAL_RSV_VCL24 - "RSV_VCL25", // HEVC_NAL_RSV_VCL25 - "RSV_VCL26", // HEVC_NAL_RSV_VCL26 - "RSV_VCL27", // HEVC_NAL_RSV_VCL27 - "RSV_VCL28", // HEVC_NAL_RSV_VCL28 - "RSV_VCL29", // HEVC_NAL_RSV_VCL29 - "RSV_VCL30", // HEVC_NAL_RSV_VCL30 - "RSV_VCL31", // HEVC_NAL_RSV_VCL31 - "VPS", // HEVC_NAL_VPS - "SPS", // HEVC_NAL_SPS - "PPS", // HEVC_NAL_PPS - "AUD", // HEVC_NAL_AUD - "EOS_NUT", // HEVC_NAL_EOS_NUT - "EOB_NUT", // HEVC_NAL_EOB_NUT - "FD_NUT", // HEVC_NAL_FD_NUT - "SEI_PREFIX", // HEVC_NAL_SEI_PREFIX - "SEI_SUFFIX", // HEVC_NAL_SEI_SUFFIX - "RSV_NVCL41", // HEVC_NAL_RSV_NVCL41 - "RSV_NVCL42", // HEVC_NAL_RSV_NVCL42 - "RSV_NVCL43", // HEVC_NAL_RSV_NVCL43 - "RSV_NVCL44", // HEVC_NAL_RSV_NVCL44 - "RSV_NVCL45", // HEVC_NAL_RSV_NVCL45 - "RSV_NVCL46", // HEVC_NAL_RSV_NVCL46 - "RSV_NVCL47", // HEVC_NAL_RSV_NVCL47 - "UNSPEC48", // HEVC_NAL_UNSPEC48 - "UNSPEC49", // HEVC_NAL_UNSPEC49 - "UNSPEC50", // HEVC_NAL_UNSPEC50 - "UNSPEC51", // HEVC_NAL_UNSPEC51 - "UNSPEC52", // HEVC_NAL_UNSPEC52 - "UNSPEC53", // HEVC_NAL_UNSPEC53 - "UNSPEC54", // HEVC_NAL_UNSPEC54 - "UNSPEC55", // HEVC_NAL_UNSPEC55 - "UNSPEC56", // HEVC_NAL_UNSPEC56 - "UNSPEC57", // HEVC_NAL_UNSPEC57 - "UNSPEC58", // HEVC_NAL_UNSPEC58 - "UNSPEC59", // HEVC_NAL_UNSPEC59 - "UNSPEC60", // HEVC_NAL_UNSPEC60 - "UNSPEC61", // HEVC_NAL_UNSPEC61 - "UNSPEC62", // HEVC_NAL_UNSPEC62 - "UNSPEC63", // HEVC_NAL_UNSPEC63 -}; - -static const char *hevc_nal_unit_name(int nal_type) { - av_assert0(nal_type >= 0 && nal_type < 64); - return hevc_nal_type_name[nal_type]; -} - -static const char *const h264_nal_type_name[32] = { - "Unspecified 0", //H264_NAL_UNSPECIFIED - "Coded slice of a non-IDR picture", // H264_NAL_SLICE - "Coded slice data partition A", // H264_NAL_DPA - "Coded slice data partition B", // H264_NAL_DPB - "Coded slice data partition C", // H264_NAL_DPC - "IDR", // H264_NAL_IDR_SLICE - "SEI", // H264_NAL_SEI - "SPS", // H264_NAL_SPS - "PPS", // H264_NAL_PPS - "AUD", // H264_NAL_AUD - "End of sequence", // H264_NAL_END_SEQUENCE - "End of stream", // H264_NAL_END_STREAM - "Filler data", // H264_NAL_FILLER_DATA - "SPS extension", // H264_NAL_SPS_EXT - "Prefix", // H264_NAL_PREFIX - "Subset SPS", // H264_NAL_SUB_SPS - "Depth parameter set", // H264_NAL_DPS - "Reserved 17", // H264_NAL_RESERVED17 - "Reserved 18", // H264_NAL_RESERVED18 - "Auxiliary coded picture without partitioning", // H264_NAL_AUXILIARY_SLICE - "Slice extension", // H264_NAL_EXTEN_SLICE - "Slice extension for a depth view or a 3D-AVC texture view", // H264_NAL_DEPTH_EXTEN_SLICE - "Reserved 22", // H264_NAL_RESERVED22 - "Reserved 23", // H264_NAL_RESERVED23 - "Unspecified 24", // H264_NAL_UNSPECIFIED24 - "Unspecified 25", // H264_NAL_UNSPECIFIED25 - "Unspecified 26", // H264_NAL_UNSPECIFIED26 - "Unspecified 27", // H264_NAL_UNSPECIFIED27 - "Unspecified 28", // H264_NAL_UNSPECIFIED28 - "Unspecified 29", // H264_NAL_UNSPECIFIED29 - "Unspecified 30", // H264_NAL_UNSPECIFIED30 - "Unspecified 31", // H264_NAL_UNSPECIFIED31 -}; - -static const char *h264_nal_unit_name(int nal_type) { - av_assert0(nal_type >= 0 && nal_type < 32); - return h264_nal_type_name[nal_type]; -} - -static int get_bit_length(H2645NAL *nal, int skip_trailing_zeros) { - int size = nal->size; - int v; - - while(skip_trailing_zeros && size > 0 && nal->data[size - 1] == 0) - size--; - - if(!size) - return 0; - - v = nal->data[size - 1]; - - if(size > INT_MAX / 8) - return AVERROR(ERANGE); - size *= 8; - - /* remove the stop bit and following trailing zeros, - * or nothing for damaged bitstreams */ - if(v) - size -= ff_ctz(v) + 1; - - return size; -} - -/** - * @return AVERROR_INVALIDDATA if the packet is not a valid NAL unit, - * 0 otherwise - */ -static int hevc_parse_nal_header(H2645NAL *nal, void *logctx) { - GetBitContext *gb = &nal->gb; - - if(get_bits1(gb) != 0) - return AVERROR_INVALIDDATA; - - nal->type = get_bits(gb, 6); - - nal->nuh_layer_id = get_bits(gb, 6); - nal->temporal_id = get_bits(gb, 3) - 1; - if(nal->temporal_id < 0) - return AVERROR_INVALIDDATA; - - av_log(logctx, AV_LOG_DEBUG, - "nal_unit_type: %d(%s), nuh_layer_id: %d, temporal_id: %d\n", - nal->type, hevc_nal_unit_name(nal->type), nal->nuh_layer_id, nal->temporal_id); - - return 0; -} - -static int h264_parse_nal_header(H2645NAL *nal, void *logctx) { - GetBitContext *gb = &nal->gb; - - if(get_bits1(gb) != 0) - return AVERROR_INVALIDDATA; - - nal->ref_idc = get_bits(gb, 2); - nal->type = get_bits(gb, 5); - - av_log(logctx, AV_LOG_DEBUG, - "nal_unit_type: %d(%s), nal_ref_idc: %d\n", - nal->type, h264_nal_unit_name(nal->type), nal->ref_idc); - - return 0; -} - -static int find_next_start_code(const uint8_t *buf, const uint8_t *next_avc) { - int i = 0; - - if(buf + 3 >= next_avc) - return next_avc - buf; - - while(buf + i + 3 < next_avc) { - if(buf[i] == 0 && buf[i + 1] == 0 && buf[i + 2] == 1) - break; - i++; - } - return i + 3; -} - -static void alloc_rbsp_buffer(H2645RBSP *rbsp, unsigned int size, int use_ref) { - int min_size = size; - - if(size > INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE) - goto fail; - size += AV_INPUT_BUFFER_PADDING_SIZE; - - if(rbsp->rbsp_buffer_alloc_size >= size && - (!rbsp->rbsp_buffer_ref || av_buffer_is_writable(rbsp->rbsp_buffer_ref))) { - av_assert0(rbsp->rbsp_buffer); - memset(rbsp->rbsp_buffer + min_size, 0, AV_INPUT_BUFFER_PADDING_SIZE); - return; - } - - size = FFMIN(size + size / 16 + 32, INT_MAX); - - if(rbsp->rbsp_buffer_ref) - av_buffer_unref(&rbsp->rbsp_buffer_ref); - else - av_free(rbsp->rbsp_buffer); - - rbsp->rbsp_buffer = av_mallocz(size); - if(!rbsp->rbsp_buffer) - goto fail; - rbsp->rbsp_buffer_alloc_size = size; - - if(use_ref) { - rbsp->rbsp_buffer_ref = av_buffer_create(rbsp->rbsp_buffer, size, - NULL, NULL, 0); - if(!rbsp->rbsp_buffer_ref) - goto fail; - } - - return; - -fail: - rbsp->rbsp_buffer_alloc_size = 0; - if(rbsp->rbsp_buffer_ref) { - av_buffer_unref(&rbsp->rbsp_buffer_ref); - rbsp->rbsp_buffer = NULL; - } - else - av_freep(&rbsp->rbsp_buffer); - - return; -} - -int ff_h2645_packet_split(H2645Packet *pkt, const uint8_t *buf, int length, - void *logctx, int is_nalff, int nal_length_size, - enum AVCodecID codec_id, int small_padding, int use_ref) { - GetByteContext bc; - int consumed, ret = 0; - int next_avc = is_nalff ? 0 : length; - int64_t padding = small_padding ? 0 : MAX_MBPAIR_SIZE; - - bytestream2_init(&bc, buf, length); - alloc_rbsp_buffer(&pkt->rbsp, length + padding, use_ref); - - if(!pkt->rbsp.rbsp_buffer) - return AVERROR(ENOMEM); - - pkt->rbsp.rbsp_buffer_size = 0; - pkt->nb_nals = 0; - while(bytestream2_get_bytes_left(&bc) >= 4) { - H2645NAL *nal; - int extract_length = 0; - int skip_trailing_zeros = 1; - - if(bytestream2_tell(&bc) == next_avc) { - int i = 0; - extract_length = get_nalsize(nal_length_size, - bc.buffer, bytestream2_get_bytes_left(&bc), &i, logctx); - if(extract_length < 0) - return extract_length; - - bytestream2_skip(&bc, nal_length_size); - - next_avc = bytestream2_tell(&bc) + extract_length; - } - else { - int buf_index; - - if(bytestream2_tell(&bc) > next_avc) - av_log(logctx, AV_LOG_WARNING, "Exceeded next NALFF position, re-syncing.\n"); - - /* search start code */ - buf_index = find_next_start_code(bc.buffer, buf + next_avc); - - bytestream2_skip(&bc, buf_index); - - if(!bytestream2_get_bytes_left(&bc)) { - if(pkt->nb_nals > 0) { - // No more start codes: we discarded some irrelevant - // bytes at the end of the packet. - return 0; - } - else { - av_log(logctx, AV_LOG_ERROR, "No start code is found.\n"); - return AVERROR_INVALIDDATA; - } - } - - extract_length = FFMIN(bytestream2_get_bytes_left(&bc), next_avc - bytestream2_tell(&bc)); - - if(bytestream2_tell(&bc) >= next_avc) { - /* skip to the start of the next NAL */ - bytestream2_skip(&bc, next_avc - bytestream2_tell(&bc)); - continue; - } - } - - if(pkt->nals_allocated < pkt->nb_nals + 1) { - int new_size = pkt->nals_allocated + 1; - void *tmp; - - if(new_size >= INT_MAX / sizeof(*pkt->nals)) - return AVERROR(ENOMEM); - - tmp = av_fast_realloc(pkt->nals, &pkt->nal_buffer_size, new_size * sizeof(*pkt->nals)); - if(!tmp) - return AVERROR(ENOMEM); - - pkt->nals = tmp; - memset(pkt->nals + pkt->nals_allocated, 0, sizeof(*pkt->nals)); - - nal = &pkt->nals[pkt->nb_nals]; - nal->skipped_bytes_pos_size = FFMIN(1024, extract_length / 3 + 1); // initial buffer size - nal->skipped_bytes_pos = av_malloc_array(nal->skipped_bytes_pos_size, sizeof(*nal->skipped_bytes_pos)); - if(!nal->skipped_bytes_pos) - return AVERROR(ENOMEM); - - pkt->nals_allocated = new_size; - } - nal = &pkt->nals[pkt->nb_nals]; - - consumed = ff_h2645_extract_rbsp(bc.buffer, extract_length, &pkt->rbsp, nal, small_padding); - if(consumed < 0) - return consumed; - - if(is_nalff && (extract_length != consumed) && extract_length) - av_log(logctx, AV_LOG_DEBUG, - "NALFF: Consumed only %d bytes instead of %d\n", - consumed, extract_length); - - bytestream2_skip(&bc, consumed); - - /* see commit 3566042a0 */ - if(bytestream2_get_bytes_left(&bc) >= 4 && - bytestream2_peek_be32(&bc) == 0x000001E0) - skip_trailing_zeros = 0; - - nal->size_bits = get_bit_length(nal, skip_trailing_zeros); - - if(nal->size <= 0 || nal->size_bits <= 0) - continue; - - ret = init_get_bits(&nal->gb, nal->data, nal->size_bits); - if(ret < 0) - return ret; - - /* Reset type in case it contains a stale value from a previously parsed NAL */ - nal->type = 0; - - if(codec_id == AV_CODEC_ID_HEVC) - ret = hevc_parse_nal_header(nal, logctx); - else - ret = h264_parse_nal_header(nal, logctx); - if(ret < 0) { - av_log(logctx, AV_LOG_WARNING, "Invalid NAL unit %d, skipping.\n", - nal->type); - continue; - } - - pkt->nb_nals++; - } - - return 0; -} - -void ff_h2645_packet_uninit(H2645Packet *pkt) { - int i; - for(i = 0; i < pkt->nals_allocated; i++) { - av_freep(&pkt->nals[i].skipped_bytes_pos); - } - av_freep(&pkt->nals); - pkt->nals_allocated = pkt->nal_buffer_size = 0; - if(pkt->rbsp.rbsp_buffer_ref) { - av_buffer_unref(&pkt->rbsp.rbsp_buffer_ref); - pkt->rbsp.rbsp_buffer = NULL; - } - else - av_freep(&pkt->rbsp.rbsp_buffer); - pkt->rbsp.rbsp_buffer_alloc_size = pkt->rbsp.rbsp_buffer_size = 0; -} diff --git a/third-party/cbs/h264_ps.h b/third-party/cbs/h264_ps.h deleted file mode 100644 index fbd0cb7a423..00000000000 --- a/third-party/cbs/h264_ps.h +++ /dev/null @@ -1,173 +0,0 @@ -/* - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * H.264 parameter set handling - */ - -#ifndef AVCODEC_H264_PS_H -#define AVCODEC_H264_PS_H - -#include - -#include -#include -#include -#include - -#include "cbs/h264.h" - -#include "get_bits.h" - -#define MAX_SPS_COUNT 32 -#define MAX_PPS_COUNT 256 -#define MAX_LOG2_MAX_FRAME_NUM (12 + 4) - -/** - * Sequence parameter set - */ -typedef struct SPS { - unsigned int sps_id; - int profile_idc; - int level_idc; - int chroma_format_idc; - int transform_bypass; ///< qpprime_y_zero_transform_bypass_flag - int log2_max_frame_num; ///< log2_max_frame_num_minus4 + 4 - int poc_type; ///< pic_order_cnt_type - int log2_max_poc_lsb; ///< log2_max_pic_order_cnt_lsb_minus4 - int delta_pic_order_always_zero_flag; - int offset_for_non_ref_pic; - int offset_for_top_to_bottom_field; - int poc_cycle_length; ///< num_ref_frames_in_pic_order_cnt_cycle - int ref_frame_count; ///< num_ref_frames - int gaps_in_frame_num_allowed_flag; - int mb_width; ///< pic_width_in_mbs_minus1 + 1 - ///< (pic_height_in_map_units_minus1 + 1) * (2 - frame_mbs_only_flag) - int mb_height; - int frame_mbs_only_flag; - int mb_aff; ///< mb_adaptive_frame_field_flag - int direct_8x8_inference_flag; - int crop; ///< frame_cropping_flag - - /* those 4 are already in luma samples */ - unsigned int crop_left; ///< frame_cropping_rect_left_offset - unsigned int crop_right; ///< frame_cropping_rect_right_offset - unsigned int crop_top; ///< frame_cropping_rect_top_offset - unsigned int crop_bottom; ///< frame_cropping_rect_bottom_offset - int vui_parameters_present_flag; - AVRational sar; - int video_signal_type_present_flag; - int full_range; - int colour_description_present_flag; - enum AVColorPrimaries color_primaries; - enum AVColorTransferCharacteristic color_trc; - enum AVColorSpace colorspace; - enum AVChromaLocation chroma_location; - - int timing_info_present_flag; - uint32_t num_units_in_tick; - uint32_t time_scale; - int fixed_frame_rate_flag; - int32_t offset_for_ref_frame[256]; - int bitstream_restriction_flag; - int num_reorder_frames; - int scaling_matrix_present; - uint8_t scaling_matrix4[6][16]; - uint8_t scaling_matrix8[6][64]; - int nal_hrd_parameters_present_flag; - int vcl_hrd_parameters_present_flag; - int pic_struct_present_flag; - int time_offset_length; - int cpb_cnt; ///< See H.264 E.1.2 - int initial_cpb_removal_delay_length; ///< initial_cpb_removal_delay_length_minus1 + 1 - int cpb_removal_delay_length; ///< cpb_removal_delay_length_minus1 + 1 - int dpb_output_delay_length; ///< dpb_output_delay_length_minus1 + 1 - int bit_depth_luma; ///< bit_depth_luma_minus8 + 8 - int bit_depth_chroma; ///< bit_depth_chroma_minus8 + 8 - int residual_color_transform_flag; ///< residual_colour_transform_flag - int constraint_set_flags; ///< constraint_set[0-3]_flag - uint8_t data[4096]; - size_t data_size; -} SPS; - -/** - * Picture parameter set - */ -typedef struct PPS { - unsigned int sps_id; - int cabac; ///< entropy_coding_mode_flag - int pic_order_present; ///< pic_order_present_flag - int slice_group_count; ///< num_slice_groups_minus1 + 1 - int mb_slice_group_map_type; - unsigned int ref_count[2]; ///< num_ref_idx_l0/1_active_minus1 + 1 - int weighted_pred; ///< weighted_pred_flag - int weighted_bipred_idc; - int init_qp; ///< pic_init_qp_minus26 + 26 - int init_qs; ///< pic_init_qs_minus26 + 26 - int chroma_qp_index_offset[2]; - int deblocking_filter_parameters_present; ///< deblocking_filter_parameters_present_flag - int constrained_intra_pred; ///< constrained_intra_pred_flag - int redundant_pic_cnt_present; ///< redundant_pic_cnt_present_flag - int transform_8x8_mode; ///< transform_8x8_mode_flag - uint8_t scaling_matrix4[6][16]; - uint8_t scaling_matrix8[6][64]; - uint8_t chroma_qp_table[2][QP_MAX_NUM + 1]; ///< pre-scaled (with chroma_qp_index_offset) version of qp_table - int chroma_qp_diff; - uint8_t data[4096]; - size_t data_size; - - uint32_t dequant4_buffer[6][QP_MAX_NUM + 1][16]; - uint32_t dequant8_buffer[6][QP_MAX_NUM + 1][64]; - uint32_t (*dequant4_coeff[6])[16]; - uint32_t (*dequant8_coeff[6])[64]; - - AVBufferRef *sps_ref; - const SPS *sps; -} PPS; - -typedef struct H264ParamSets { - AVBufferRef *sps_list[MAX_SPS_COUNT]; - AVBufferRef *pps_list[MAX_PPS_COUNT]; - - AVBufferRef *pps_ref; - /* currently active parameters sets */ - const PPS *pps; - const SPS *sps; - - int overread_warning_printed[2]; -} H264ParamSets; - -/** - * Decode SPS - */ -int ff_h264_decode_seq_parameter_set(GetBitContext *gb, AVCodecContext *avctx, - H264ParamSets *ps, int ignore_truncation); - -/** - * Decode PPS - */ -int ff_h264_decode_picture_parameter_set(GetBitContext *gb, AVCodecContext *avctx, - H264ParamSets *ps, int bit_length); - -/** - * Uninit H264 param sets structure. - */ -void ff_h264_ps_uninit(H264ParamSets *ps); - -#endif /* AVCODEC_H264_PS_H */ diff --git a/third-party/cbs/h264_sei.h b/third-party/cbs/h264_sei.h deleted file mode 100644 index 64dbb86e777..00000000000 --- a/third-party/cbs/h264_sei.h +++ /dev/null @@ -1,202 +0,0 @@ -/* - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_H264_SEI_H -#define AVCODEC_H264_SEI_H - -#include "cbs/sei.h" -#include "get_bits.h" -#include "h264_ps.h" - - -/** - * pic_struct in picture timing SEI message - */ -typedef enum { - H264_SEI_PIC_STRUCT_FRAME = 0, ///< 0: %frame - H264_SEI_PIC_STRUCT_TOP_FIELD = 1, ///< 1: top field - H264_SEI_PIC_STRUCT_BOTTOM_FIELD = 2, ///< 2: bottom field - H264_SEI_PIC_STRUCT_TOP_BOTTOM = 3, ///< 3: top field, bottom field, in that order - H264_SEI_PIC_STRUCT_BOTTOM_TOP = 4, ///< 4: bottom field, top field, in that order - H264_SEI_PIC_STRUCT_TOP_BOTTOM_TOP = 5, ///< 5: top field, bottom field, top field repeated, in that order - H264_SEI_PIC_STRUCT_BOTTOM_TOP_BOTTOM = 6, ///< 6: bottom field, top field, bottom field repeated, in that order - H264_SEI_PIC_STRUCT_FRAME_DOUBLING = 7, ///< 7: %frame doubling - H264_SEI_PIC_STRUCT_FRAME_TRIPLING = 8 ///< 8: %frame tripling -} H264_SEI_PicStructType; - -/** - * frame_packing_arrangement types - */ -typedef enum { - H264_SEI_FPA_TYPE_CHECKERBOARD = 0, - H264_SEI_FPA_TYPE_INTERLEAVE_COLUMN = 1, - H264_SEI_FPA_TYPE_INTERLEAVE_ROW = 2, - H264_SEI_FPA_TYPE_SIDE_BY_SIDE = 3, - H264_SEI_FPA_TYPE_TOP_BOTTOM = 4, - H264_SEI_FPA_TYPE_INTERLEAVE_TEMPORAL = 5, - H264_SEI_FPA_TYPE_2D = 6, -} H264_SEI_FpaType; - -typedef struct H264SEITimeCode { - /* When not continuously receiving full timecodes, we have to reference - the previous timecode received */ - int full; - int frame; - int seconds; - int minutes; - int hours; - int dropframe; -} H264SEITimeCode; - -typedef struct H264SEIPictureTiming { - // maximum size of pic_timing according to the spec should be 274 bits - uint8_t payload[40]; - int payload_size_bits; - - int present; - H264_SEI_PicStructType pic_struct; - - /** - * Bit set of clock types for fields/frames in picture timing SEI message. - * For each found ct_type, appropriate bit is set (e.g., bit 1 for - * interlaced). - */ - int ct_type; - - /** - * dpb_output_delay in picture timing SEI message, see H.264 C.2.2 - */ - int dpb_output_delay; - - /** - * cpb_removal_delay in picture timing SEI message, see H.264 C.1.2 - */ - int cpb_removal_delay; - - /** - * Maximum three timecodes in a pic_timing SEI. - */ - H264SEITimeCode timecode[3]; - - /** - * Number of timecode in use - */ - int timecode_cnt; -} H264SEIPictureTiming; - -typedef struct H264SEIAFD { - int present; - uint8_t active_format_description; -} H264SEIAFD; - -typedef struct H264SEIA53Caption { - AVBufferRef *buf_ref; -} H264SEIA53Caption; - -typedef struct H264SEIUnregistered { - int x264_build; - AVBufferRef **buf_ref; - int nb_buf_ref; -} H264SEIUnregistered; - -typedef struct H264SEIRecoveryPoint { - /** - * recovery_frame_cnt - * - * Set to -1 if no recovery point SEI message found or to number of frames - * before playback synchronizes. Frames having recovery point are key - * frames. - */ - int recovery_frame_cnt; -} H264SEIRecoveryPoint; - -typedef struct H264SEIBufferingPeriod { - int present; ///< Buffering period SEI flag - int initial_cpb_removal_delay[32]; ///< Initial timestamps for CPBs -} H264SEIBufferingPeriod; - -typedef struct H264SEIFramePacking { - int present; - int arrangement_id; - int arrangement_cancel_flag; ///< is previous arrangement canceled, -1 if never received - H264_SEI_FpaType arrangement_type; - int arrangement_repetition_period; - int content_interpretation_type; - int quincunx_sampling_flag; - int current_frame_is_frame0_flag; -} H264SEIFramePacking; - -typedef struct H264SEIDisplayOrientation { - int present; - int anticlockwise_rotation; - int hflip, vflip; -} H264SEIDisplayOrientation; - -typedef struct H264SEIGreenMetaData { - uint8_t green_metadata_type; - uint8_t period_type; - uint16_t num_seconds; - uint16_t num_pictures; - uint8_t percent_non_zero_macroblocks; - uint8_t percent_intra_coded_macroblocks; - uint8_t percent_six_tap_filtering; - uint8_t percent_alpha_point_deblocking_instance; - uint8_t xsd_metric_type; - uint16_t xsd_metric_value; -} H264SEIGreenMetaData; - -typedef struct H264SEIAlternativeTransfer { - int present; - int preferred_transfer_characteristics; -} H264SEIAlternativeTransfer; - -typedef struct H264SEIContext { - H264SEIPictureTiming picture_timing; - H264SEIAFD afd; - H264SEIA53Caption a53_caption; - H264SEIUnregistered unregistered; - H264SEIRecoveryPoint recovery_point; - H264SEIBufferingPeriod buffering_period; - H264SEIFramePacking frame_packing; - H264SEIDisplayOrientation display_orientation; - H264SEIGreenMetaData green_metadata; - H264SEIAlternativeTransfer alternative_transfer; -} H264SEIContext; - -struct H264ParamSets; - -int ff_h264_sei_decode(H264SEIContext *h, GetBitContext *gb, - const struct H264ParamSets *ps, void *logctx); - -/** - * Reset SEI values at the beginning of the frame. - */ -void ff_h264_sei_uninit(H264SEIContext *h); - -/** - * Get stereo_mode string from the h264 frame_packing_arrangement - */ -const char *ff_h264_sei_stereo_mode(const H264SEIFramePacking *h); - -/** - * Parse the contents of a picture timing message given an active SPS. - */ -int ff_h264_sei_process_picture_timing(H264SEIPictureTiming *h, const SPS *sps, - void *logctx); - -#endif /* AVCODEC_H264_SEI_H */ diff --git a/third-party/cbs/hevc_sei.h b/third-party/cbs/hevc_sei.h deleted file mode 100644 index 8dfffcc45d9..00000000000 --- a/third-party/cbs/hevc_sei.h +++ /dev/null @@ -1,142 +0,0 @@ -/* - * HEVC Supplementary Enhancement Information messages - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_HEVC_SEI_H -#define AVCODEC_HEVC_SEI_H - -#include - -#include - -#include "cbs/sei.h" - -#include "get_bits.h" - - -typedef enum { - HEVC_SEI_PIC_STRUCT_FRAME_DOUBLING = 7, - HEVC_SEI_PIC_STRUCT_FRAME_TRIPLING = 8 -} HEVC_SEI_PicStructType; - -typedef struct HEVCSEIPictureHash { - uint8_t md5[3][16]; - uint8_t is_md5; -} HEVCSEIPictureHash; - -typedef struct HEVCSEIFramePacking { - int present; - int arrangement_type; - int content_interpretation_type; - int quincunx_subsampling; - int current_frame_is_frame0_flag; -} HEVCSEIFramePacking; - -typedef struct HEVCSEIDisplayOrientation { - int present; - int anticlockwise_rotation; - int hflip, vflip; -} HEVCSEIDisplayOrientation; - -typedef struct HEVCSEIPictureTiming { - int picture_struct; -} HEVCSEIPictureTiming; - -typedef struct HEVCSEIA53Caption { - AVBufferRef *buf_ref; -} HEVCSEIA53Caption; - -typedef struct HEVCSEIUnregistered { - AVBufferRef **buf_ref; - int nb_buf_ref; -} HEVCSEIUnregistered; - -typedef struct HEVCSEIMasteringDisplay { - int present; - uint16_t display_primaries[3][2]; - uint16_t white_point[2]; - uint32_t max_luminance; - uint32_t min_luminance; -} HEVCSEIMasteringDisplay; - -typedef struct HEVCSEIDynamicHDRPlus { - AVBufferRef *info; -} HEVCSEIDynamicHDRPlus; - -typedef struct HEVCSEIContentLight { - int present; - uint16_t max_content_light_level; - uint16_t max_pic_average_light_level; -} HEVCSEIContentLight; - -typedef struct HEVCSEIAlternativeTransfer { - int present; - int preferred_transfer_characteristics; -} HEVCSEIAlternativeTransfer; - -typedef struct HEVCSEITimeCode { - int present; - uint8_t num_clock_ts; - uint8_t clock_timestamp_flag[3]; - uint8_t units_field_based_flag[3]; - uint8_t counting_type[3]; - uint8_t full_timestamp_flag[3]; - uint8_t discontinuity_flag[3]; - uint8_t cnt_dropped_flag[3]; - uint16_t n_frames[3]; - uint8_t seconds_value[3]; - uint8_t minutes_value[3]; - uint8_t hours_value[3]; - uint8_t seconds_flag[3]; - uint8_t minutes_flag[3]; - uint8_t hours_flag[3]; - uint8_t time_offset_length[3]; - int32_t time_offset_value[3]; -} HEVCSEITimeCode; - -typedef struct HEVCSEI { - HEVCSEIPictureHash picture_hash; - HEVCSEIFramePacking frame_packing; - HEVCSEIDisplayOrientation display_orientation; - HEVCSEIPictureTiming picture_timing; - HEVCSEIA53Caption a53_caption; - HEVCSEIUnregistered unregistered; - HEVCSEIMasteringDisplay mastering_display; - HEVCSEIDynamicHDRPlus dynamic_hdr_plus; - HEVCSEIContentLight content_light; - int active_seq_parameter_set_id; - HEVCSEIAlternativeTransfer alternative_transfer; - HEVCSEITimeCode timecode; -} HEVCSEI; - -struct HEVCParamSets; - -int ff_hevc_decode_nal_sei(GetBitContext *gb, void *logctx, HEVCSEI *s, - const struct HEVCParamSets *ps, int type); - -/** - * Reset SEI values that are stored on the Context. - * e.g. Caption data that was extracted during NAL - * parsing. - * - * @param s HEVCContext. - */ -void ff_hevc_reset_sei(HEVCSEI *s); - -#endif /* AVCODEC_HEVC_SEI_H */ diff --git a/third-party/cbs/intmath.h b/third-party/cbs/intmath.h deleted file mode 100644 index 377b74127f2..00000000000 --- a/third-party/cbs/intmath.h +++ /dev/null @@ -1,152 +0,0 @@ -/* - * Copyright (c) 2010 Mans Rullgard - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVUTIL_INTMATH_H -#define AVUTIL_INTMATH_H - -#include - -#include - -#if HAVE_FAST_CLZ -#if AV_GCC_VERSION_AT_LEAST(3, 4) -#ifndef ff_log2 -#define ff_log2(x) (31 - __builtin_clz((x) | 1)) -#ifndef ff_log2_16bit -#define ff_log2_16bit av_log2 -#endif -#endif /* ff_log2 */ -#endif /* AV_GCC_VERSION_AT_LEAST(3,4) */ -#endif - -extern const uint8_t ff_log2_tab[256]; - -#ifndef ff_log2 -#define ff_log2 ff_log2_c -static av_always_inline av_const int ff_log2_c(unsigned int v) { - int n = 0; - if(v & 0xffff0000) { - v >>= 16; - n += 16; - } - if(v & 0xff00) { - v >>= 8; - n += 8; - } - n += ff_log2_tab[v]; - - return n; -} -#endif - -#ifndef ff_log2_16bit -#define ff_log2_16bit ff_log2_16bit_c -static av_always_inline av_const int ff_log2_16bit_c(unsigned int v) { - int n = 0; - if(v & 0xff00) { - v >>= 8; - n += 8; - } - n += ff_log2_tab[v]; - - return n; -} -#endif - -#define av_log2 ff_log2 -#define av_log2_16bit ff_log2_16bit - -/** - * @addtogroup lavu_math - * @{ - */ - -#if HAVE_FAST_CLZ -#if AV_GCC_VERSION_AT_LEAST(3, 4) -#ifndef ff_ctz -#define ff_ctz(v) __builtin_ctz(v) -#endif -#ifndef ff_ctzll -#define ff_ctzll(v) __builtin_ctzll(v) -#endif -#ifndef ff_clz -#define ff_clz(v) __builtin_clz(v) -#endif -#endif -#endif - -#ifndef ff_ctz -#define ff_ctz ff_ctz_c -/** - * Trailing zero bit count. - * - * @param v input value. If v is 0, the result is undefined. - * @return the number of trailing 0-bits - */ -/* We use the De-Bruijn method outlined in: - * http://supertech.csail.mit.edu/papers/debruijn.pdf. */ -static av_always_inline av_const int ff_ctz_c(int v) { - static const uint8_t debruijn_ctz32[32] = { - 0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8, - 31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9 - }; - return debruijn_ctz32[(uint32_t)((v & -v) * 0x077CB531U) >> 27]; -} -#endif - -#ifndef ff_ctzll -#define ff_ctzll ff_ctzll_c -/* We use the De-Bruijn method outlined in: - * http://supertech.csail.mit.edu/papers/debruijn.pdf. */ -static av_always_inline av_const int ff_ctzll_c(long long v) { - static const uint8_t debruijn_ctz64[64] = { - 0, 1, 2, 53, 3, 7, 54, 27, 4, 38, 41, 8, 34, 55, 48, 28, - 62, 5, 39, 46, 44, 42, 22, 9, 24, 35, 59, 56, 49, 18, 29, 11, - 63, 52, 6, 26, 37, 40, 33, 47, 61, 45, 43, 21, 23, 58, 17, 10, - 51, 25, 36, 32, 60, 20, 57, 16, 50, 31, 19, 15, 30, 14, 13, 12 - }; - return debruijn_ctz64[(uint64_t)((v & -v) * 0x022FDD63CC95386DU) >> 58]; -} -#endif - -#ifndef ff_clz -#define ff_clz ff_clz_c -static av_always_inline av_const unsigned ff_clz_c(unsigned x) { - unsigned i = sizeof(x) * 8; - - while(x) { - x >>= 1; - i--; - } - - return i; -} -#endif - -#if AV_GCC_VERSION_AT_LEAST(3, 4) -#ifndef av_parity -#define av_parity __builtin_parity -#endif -#endif - -/** - * @} - */ -#endif /* AVUTIL_INTMATH_H */ diff --git a/third-party/cbs/mathops.h b/third-party/cbs/mathops.h deleted file mode 100644 index c0b8f3db2c1..00000000000 --- a/third-party/cbs/mathops.h +++ /dev/null @@ -1,243 +0,0 @@ -/* - * simple math operations - * Copyright (c) 2001, 2002 Fabrice Bellard - * Copyright (c) 2006 Michael Niedermayer et al - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ -#ifndef AVCODEC_MATHOPS_H -#define AVCODEC_MATHOPS_H - -#include "config.h" - -#include - -#include - -#define MAX_NEG_CROP 1024 - -extern const uint8_t ff_reverse[256]; -extern const uint32_t ff_inverse[257]; -extern const uint8_t ff_sqrt_tab[256]; -extern const uint8_t ff_crop_tab[256 + 2 * MAX_NEG_CROP]; -extern const uint8_t ff_zigzag_direct[64]; -extern const uint8_t ff_zigzag_scan[16 + 1]; - -#ifndef MUL64 -#define MUL64(a, b) ((int64_t)(a) * (int64_t)(b)) -#endif - -#ifndef MULL -#define MULL(a, b, s) (MUL64(a, b) >> (s)) -#endif - -#ifndef MULH -static av_always_inline int MULH(int a, int b) { - return MUL64(a, b) >> 32; -} -#endif - -#ifndef UMULH -static av_always_inline unsigned UMULH(unsigned a, unsigned b) { - return ((uint64_t)(a) * (uint64_t)(b)) >> 32; -} -#endif - -#ifndef MAC64 -#define MAC64(d, a, b) ((d) += MUL64(a, b)) -#endif - -#ifndef MLS64 -#define MLS64(d, a, b) ((d) -= MUL64(a, b)) -#endif - -/* signed 16x16 -> 32 multiply add accumulate */ -#ifndef MAC16 -#define MAC16(rt, ra, rb) rt += (ra) * (rb) -#endif - -/* signed 16x16 -> 32 multiply */ -#ifndef MUL16 -#define MUL16(ra, rb) ((ra) * (rb)) -#endif - -#ifndef MLS16 -#define MLS16(rt, ra, rb) ((rt) -= (ra) * (rb)) -#endif - -/* median of 3 */ -#ifndef mid_pred -#define mid_pred mid_pred -static inline av_const int mid_pred(int a, int b, int c) { - if(a > b) { - if(c > b) { - if(c > a) b = a; - else - b = c; - } - } - else { - if(b > c) { - if(c > a) b = c; - else - b = a; - } - } - return b; -} -#endif - -#ifndef median4 -#define median4 median4 -static inline av_const int median4(int a, int b, int c, int d) { - if(a < b) { - if(c < d) return (FFMIN(b, d) + FFMAX(a, c)) / 2; - else - return (FFMIN(b, c) + FFMAX(a, d)) / 2; - } - else { - if(c < d) return (FFMIN(a, d) + FFMAX(b, c)) / 2; - else - return (FFMIN(a, c) + FFMAX(b, d)) / 2; - } -} -#endif - -#ifndef sign_extend -static inline av_const int sign_extend(int val, unsigned bits) { - unsigned shift = 8 * sizeof(int) - bits; - union { - unsigned u; - int s; - } v = { (unsigned)val << shift }; - return v.s >> shift; -} -#endif - -#ifndef zero_extend -static inline av_const unsigned zero_extend(unsigned val, unsigned bits) { - return (val << ((8 * sizeof(int)) - bits)) >> ((8 * sizeof(int)) - bits); -} -#endif - -#ifndef COPY3_IF_LT -#define COPY3_IF_LT(x, y, a, b, c, d) \ - if((y) < (x)) { \ - (x) = (y); \ - (a) = (b); \ - (c) = (d); \ - } -#endif - -#ifndef MASK_ABS -#define MASK_ABS(mask, level) \ - do { \ - mask = level >> 31; \ - level = (level ^ mask) - mask; \ - } while(0) -#endif - -#ifndef NEG_SSR32 -#define NEG_SSR32(a, s) (((int32_t)(a)) >> (32 - (s))) -#endif - -#ifndef NEG_USR32 -#define NEG_USR32(a, s) (((uint32_t)(a)) >> (32 - (s))) -#endif - -#if HAVE_BIGENDIAN -#ifndef PACK_2U8 -#define PACK_2U8(a, b) (((a) << 8) | (b)) -#endif -#ifndef PACK_4U8 -#define PACK_4U8(a, b, c, d) (((a) << 24) | ((b) << 16) | ((c) << 8) | (d)) -#endif -#ifndef PACK_2U16 -#define PACK_2U16(a, b) (((a) << 16) | (b)) -#endif -#else -#ifndef PACK_2U8 -#define PACK_2U8(a, b) (((b) << 8) | (a)) -#endif -#ifndef PACK_4U2 -#define PACK_4U8(a, b, c, d) (((d) << 24) | ((c) << 16) | ((b) << 8) | (a)) -#endif -#ifndef PACK_2U16 -#define PACK_2U16(a, b) (((b) << 16) | (a)) -#endif -#endif - -#ifndef PACK_2S8 -#define PACK_2S8(a, b) PACK_2U8((a)&255, (b)&255) -#endif -#ifndef PACK_4S8 -#define PACK_4S8(a, b, c, d) PACK_4U8((a)&255, (b)&255, (c)&255, (d)&255) -#endif -#ifndef PACK_2S16 -#define PACK_2S16(a, b) PACK_2U16((a)&0xffff, (b)&0xffff) -#endif - -#ifndef FASTDIV -#define FASTDIV(a, b) ((uint32_t)((((uint64_t)a) * ff_inverse[b]) >> 32)) -#endif /* FASTDIV */ - -#ifndef ff_sqrt -#define ff_sqrt ff_sqrt -static inline av_const unsigned int ff_sqrt(unsigned int a) { - unsigned int b; - - if(a < 255) return (ff_sqrt_tab[a + 1] - 1) >> 4; - else if(a < (1 << 12)) - b = ff_sqrt_tab[a >> 4] >> 2; -#if !CONFIG_SMALL - else if(a < (1 << 14)) - b = ff_sqrt_tab[a >> 6] >> 1; - else if(a < (1 << 16)) - b = ff_sqrt_tab[a >> 8]; -#endif - else { - int s = av_log2_16bit(a >> 16) >> 1; - unsigned int c = a >> (s + 2); - b = ff_sqrt_tab[c >> (s + 8)]; - b = FASTDIV(c, b) + (b << s); - } - - return b - (a < b * b); -} -#endif - -static inline av_const float ff_sqrf(float a) { - return a * a; -} - -static inline int8_t ff_u8_to_s8(uint8_t a) { - union { - uint8_t u8; - int8_t s8; - } b; - b.u8 = a; - return b.s8; -} - -static av_always_inline uint32_t bitswap_32(uint32_t x) { - return (uint32_t)ff_reverse[x & 0xFF] << 24 | - (uint32_t)ff_reverse[(x >> 8) & 0xFF] << 16 | - (uint32_t)ff_reverse[(x >> 16) & 0xFF] << 8 | - (uint32_t)ff_reverse[x >> 24]; -} - -#endif /* AVCODEC_MATHOPS_H */ diff --git a/third-party/cbs/put_bits.h b/third-party/cbs/put_bits.h deleted file mode 100644 index 5d3f96c4bd1..00000000000 --- a/third-party/cbs/put_bits.h +++ /dev/null @@ -1,406 +0,0 @@ -/* - * copyright (c) 2004 Michael Niedermayer - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * bitstream writer API - */ - -#ifndef AVCODEC_PUT_BITS_H -#define AVCODEC_PUT_BITS_H - -#include "config.h" - -#include -#include - -#include -#include - -#if HAVE_FAST_64BIT -typedef uint64_t BitBuf; -#define AV_WBBUF AV_WB64 -#define AV_WLBUF AV_WL64 -#else -typedef uint32_t BitBuf; -#define AV_WBBUF AV_WB32 -#define AV_WLBUF AV_WL32 -#endif - -static const int BUF_BITS = 8 * sizeof(BitBuf); - -typedef struct PutBitContext { - BitBuf bit_buf; - int bit_left; - uint8_t *buf, *buf_ptr, *buf_end; -} PutBitContext; - -/** - * Initialize the PutBitContext s. - * - * @param buffer the buffer where to put bits - * @param buffer_size the size in bytes of buffer - */ -static inline void init_put_bits(PutBitContext *s, uint8_t *buffer, - int buffer_size) { - if(buffer_size < 0) { - buffer_size = 0; - buffer = NULL; - } - - s->buf = buffer; - s->buf_end = s->buf + buffer_size; - s->buf_ptr = s->buf; - s->bit_left = BUF_BITS; - s->bit_buf = 0; -} - -/** - * @return the total number of bits written to the bitstream. - */ -static inline int put_bits_count(PutBitContext *s) { - return (s->buf_ptr - s->buf) * 8 + BUF_BITS - s->bit_left; -} - -/** - * @return the number of bytes output so far; may only be called - * when the PutBitContext is freshly initialized or flushed. - */ -static inline int put_bytes_output(const PutBitContext *s) { - av_assert2(s->bit_left == BUF_BITS); - return s->buf_ptr - s->buf; -} - -/** - * @param round_up When set, the number of bits written so far will be - * rounded up to the next byte. - * @return the number of bytes output so far. - */ -static inline int put_bytes_count(const PutBitContext *s, int round_up) { - return s->buf_ptr - s->buf + ((BUF_BITS - s->bit_left + (round_up ? 7 : 0)) >> 3); -} - -/** - * Rebase the bit writer onto a reallocated buffer. - * - * @param buffer the buffer where to put bits - * @param buffer_size the size in bytes of buffer, - * must be large enough to hold everything written so far - */ -static inline void rebase_put_bits(PutBitContext *s, uint8_t *buffer, - int buffer_size) { - av_assert0(8 * buffer_size >= put_bits_count(s)); - - s->buf_end = buffer + buffer_size; - s->buf_ptr = buffer + (s->buf_ptr - s->buf); - s->buf = buffer; -} - -/** - * @return the number of bits available in the bitstream. - */ -static inline int put_bits_left(PutBitContext *s) { - return (s->buf_end - s->buf_ptr) * 8 - BUF_BITS + s->bit_left; -} - -/** - * @param round_up When set, the number of bits written will be - * rounded up to the next byte. - * @return the number of bytes left. - */ -static inline int put_bytes_left(const PutBitContext *s, int round_up) { - return s->buf_end - s->buf_ptr - ((BUF_BITS - s->bit_left + (round_up ? 7 : 0)) >> 3); -} - -/** - * Pad the end of the output stream with zeros. - */ -static inline void flush_put_bits(PutBitContext *s) { -#ifndef BITSTREAM_WRITER_LE - if(s->bit_left < BUF_BITS) - s->bit_buf <<= s->bit_left; -#endif - while(s->bit_left < BUF_BITS) { - av_assert0(s->buf_ptr < s->buf_end); -#ifdef BITSTREAM_WRITER_LE - *s->buf_ptr++ = s->bit_buf; - s->bit_buf >>= 8; -#else - *s->buf_ptr++ = s->bit_buf >> (BUF_BITS - 8); - s->bit_buf <<= 8; -#endif - s->bit_left += 8; - } - s->bit_left = BUF_BITS; - s->bit_buf = 0; -} - -static inline void flush_put_bits_le(PutBitContext *s) { - while(s->bit_left < BUF_BITS) { - av_assert0(s->buf_ptr < s->buf_end); - *s->buf_ptr++ = s->bit_buf; - s->bit_buf >>= 8; - s->bit_left += 8; - } - s->bit_left = BUF_BITS; - s->bit_buf = 0; -} - -#ifdef BITSTREAM_WRITER_LE -#define ff_put_string ff_put_string_unsupported_here -#define ff_copy_bits ff_copy_bits_unsupported_here -#else - -/** - * Put the string string in the bitstream. - * - * @param terminate_string 0-terminates the written string if value is 1 - */ -void ff_put_string(PutBitContext *pb, const char *string, - int terminate_string); - -/** - * Copy the content of src to the bitstream. - * - * @param length the number of bits of src to copy - */ -void ff_copy_bits(PutBitContext *pb, const uint8_t *src, int length); -#endif - -static inline void put_bits_no_assert(PutBitContext *s, int n, BitBuf value) { - BitBuf bit_buf; - int bit_left; - - bit_buf = s->bit_buf; - bit_left = s->bit_left; - - /* XXX: optimize */ -#ifdef BITSTREAM_WRITER_LE - bit_buf |= value << (BUF_BITS - bit_left); - if(n >= bit_left) { - if(s->buf_end - s->buf_ptr >= sizeof(BitBuf)) { - AV_WLBUF(s->buf_ptr, bit_buf); - s->buf_ptr += sizeof(BitBuf); - } - else { - av_log(NULL, AV_LOG_ERROR, "Internal error, put_bits buffer too small\n"); - av_assert2(0); - } - bit_buf = value >> bit_left; - bit_left += BUF_BITS; - } - bit_left -= n; -#else - if(n < bit_left) { - bit_buf = (bit_buf << n) | value; - bit_left -= n; - } - else { - bit_buf <<= bit_left; - bit_buf |= value >> (n - bit_left); - if(s->buf_end - s->buf_ptr >= sizeof(BitBuf)) { - AV_WBBUF(s->buf_ptr, bit_buf); - s->buf_ptr += sizeof(BitBuf); - } - else { - av_log(NULL, AV_LOG_ERROR, "Internal error, put_bits buffer too small\n"); - av_assert2(0); - } - bit_left += BUF_BITS - n; - bit_buf = value; - } -#endif - - s->bit_buf = bit_buf; - s->bit_left = bit_left; -} - -/** - * Write up to 31 bits into a bitstream. - * Use put_bits32 to write 32 bits. - */ -static inline void put_bits(PutBitContext *s, int n, BitBuf value) { - av_assert2(n <= 31 && value < (1UL << n)); - put_bits_no_assert(s, n, value); -} - -static inline void put_bits_le(PutBitContext *s, int n, BitBuf value) { - BitBuf bit_buf; - int bit_left; - - av_assert2(n <= 31 && value < (1UL << n)); - - bit_buf = s->bit_buf; - bit_left = s->bit_left; - - bit_buf |= value << (BUF_BITS - bit_left); - if(n >= bit_left) { - if(s->buf_end - s->buf_ptr >= sizeof(BitBuf)) { - AV_WLBUF(s->buf_ptr, bit_buf); - s->buf_ptr += sizeof(BitBuf); - } - else { - av_log(NULL, AV_LOG_ERROR, "Internal error, put_bits buffer too small\n"); - av_assert2(0); - } - bit_buf = value >> bit_left; - bit_left += BUF_BITS; - } - bit_left -= n; - - s->bit_buf = bit_buf; - s->bit_left = bit_left; -} - -static inline void put_sbits(PutBitContext *pb, int n, int32_t value) { - av_assert2(n >= 0 && n <= 31); - - put_bits(pb, n, av_mod_uintp2(value, n)); -} - -/** - * Write exactly 32 bits into a bitstream. - */ -static void av_unused put_bits32(PutBitContext *s, uint32_t value) { - BitBuf bit_buf; - int bit_left; - - if(BUF_BITS > 32) { - put_bits_no_assert(s, 32, value); - return; - } - - bit_buf = s->bit_buf; - bit_left = s->bit_left; - -#ifdef BITSTREAM_WRITER_LE - bit_buf |= (BitBuf)value << (BUF_BITS - bit_left); - if(s->buf_end - s->buf_ptr >= sizeof(BitBuf)) { - AV_WLBUF(s->buf_ptr, bit_buf); - s->buf_ptr += sizeof(BitBuf); - } - else { - av_log(NULL, AV_LOG_ERROR, "Internal error, put_bits buffer too small\n"); - av_assert2(0); - } - bit_buf = (uint64_t)value >> bit_left; -#else - bit_buf = (uint64_t)bit_buf << bit_left; - bit_buf |= (BitBuf)value >> (BUF_BITS - bit_left); - if(s->buf_end - s->buf_ptr >= sizeof(BitBuf)) { - AV_WBBUF(s->buf_ptr, bit_buf); - s->buf_ptr += sizeof(BitBuf); - } - else { - av_log(NULL, AV_LOG_ERROR, "Internal error, put_bits buffer too small\n"); - av_assert2(0); - } - bit_buf = value; -#endif - - s->bit_buf = bit_buf; - s->bit_left = bit_left; -} - -/** - * Write up to 64 bits into a bitstream. - */ -static inline void put_bits64(PutBitContext *s, int n, uint64_t value) { - av_assert2((n == 64) || (n < 64 && value < (UINT64_C(1) << n))); - - if(n < 32) - put_bits(s, n, value); - else if(n == 32) - put_bits32(s, value); - else if(n < 64) { - uint32_t lo = value & 0xffffffff; - uint32_t hi = value >> 32; -#ifdef BITSTREAM_WRITER_LE - put_bits32(s, lo); - put_bits(s, n - 32, hi); -#else - put_bits(s, n - 32, hi); - put_bits32(s, lo); -#endif - } - else { - uint32_t lo = value & 0xffffffff; - uint32_t hi = value >> 32; -#ifdef BITSTREAM_WRITER_LE - put_bits32(s, lo); - put_bits32(s, hi); -#else - put_bits32(s, hi); - put_bits32(s, lo); -#endif - } -} - -/** - * Return the pointer to the byte where the bitstream writer will put - * the next bit. - */ -static inline uint8_t *put_bits_ptr(PutBitContext *s) { - return s->buf_ptr; -} - -/** - * Skip the given number of bytes. - * PutBitContext must be flushed & aligned to a byte boundary before calling this. - */ -static inline void skip_put_bytes(PutBitContext *s, int n) { - av_assert2((put_bits_count(s) & 7) == 0); - av_assert2(s->bit_left == BUF_BITS); - av_assert0(n <= s->buf_end - s->buf_ptr); - s->buf_ptr += n; -} - -/** - * Skip the given number of bits. - * Must only be used if the actual values in the bitstream do not matter. - * If n is < 0 the behavior is undefined. - */ -static inline void skip_put_bits(PutBitContext *s, int n) { - unsigned bits = BUF_BITS - s->bit_left + n; - s->buf_ptr += sizeof(BitBuf) * (bits / BUF_BITS); - s->bit_left = BUF_BITS - (bits & (BUF_BITS - 1)); -} - -/** - * Change the end of the buffer. - * - * @param size the new size in bytes of the buffer where to put bits - */ -static inline void set_put_bits_buffer_size(PutBitContext *s, int size) { - av_assert0(size <= INT_MAX / 8 - BUF_BITS); - s->buf_end = s->buf + size; -} - -/** - * Pad the bitstream with zeros up to the next byte boundary. - */ -static inline void align_put_bits(PutBitContext *s) { - put_bits(s, s->bit_left & 7, 0); -} - -#undef AV_WBBUF -#undef AV_WLBUF - -#endif /* AVCODEC_PUT_BITS_H */ diff --git a/third-party/cbs/video_levels.c b/third-party/cbs/video_levels.c deleted file mode 100644 index 24143dfcfca..00000000000 --- a/third-party/cbs/video_levels.c +++ /dev/null @@ -1,349 +0,0 @@ -/* - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include - -#include "include/cbs/video_levels.h" - -// H.264 table A-1. -static const H264LevelDescriptor h264_levels[] = { - // Name MaxMBPS MaxBR MinCR - // | level_idc | MaxFS | MaxCPB | MaxMvsPer2Mb - // | | cs3f | | MaxDpbMbs | | MaxVmvR | | - { "1", 10, 0, 1485, 99, 396, 64, 175, 64, 2, 0 }, - { "1b", 11, 1, 1485, 99, 396, 128, 350, 64, 2, 0 }, - { "1b", 9, 0, 1485, 99, 396, 128, 350, 64, 2, 0 }, - { "1.1", 11, 0, 3000, 396, 900, 192, 500, 128, 2, 0 }, - { "1.2", 12, 0, 6000, 396, 2376, 384, 1000, 128, 2, 0 }, - { "1.3", 13, 0, 11880, 396, 2376, 768, 2000, 128, 2, 0 }, - { "2", 20, 0, 11880, 396, 2376, 2000, 2000, 128, 2, 0 }, - { "2.1", 21, 0, 19800, 792, 4752, 4000, 4000, 256, 2, 0 }, - { "2.2", 22, 0, 20250, 1620, 8100, 4000, 4000, 256, 2, 0 }, - { "3", 30, 0, 40500, 1620, 8100, 10000, 10000, 256, 2, 32 }, - { "3.1", 31, 0, 108000, 3600, 18000, 14000, 14000, 512, 4, 16 }, - { "3.2", 32, 0, 216000, 5120, 20480, 20000, 20000, 512, 4, 16 }, - { "4", 40, 0, 245760, 8192, 32768, 20000, 25000, 512, 4, 16 }, - { "4.1", 41, 0, 245760, 8192, 32768, 50000, 62500, 512, 2, 16 }, - { "4.2", 42, 0, 522240, 8704, 34816, 50000, 62500, 512, 2, 16 }, - { "5", 50, 0, 589824, 22080, 110400, 135000, 135000, 512, 2, 16 }, - { "5.1", 51, 0, 983040, 36864, 184320, 240000, 240000, 512, 2, 16 }, - { "5.2", 52, 0, 2073600, 36864, 184320, 240000, 240000, 512, 2, 16 }, - { "6", 60, 0, 4177920, 139264, 696320, 240000, 240000, 8192, 2, 16 }, - { "6.1", 61, 0, 8355840, 139264, 696320, 480000, 480000, 8192, 2, 16 }, - { "6.2", 62, 0, 16711680, 139264, 696320, 800000, 800000, 8192, 2, 16 }, -}; - -// H.264 table A-2 plus values from A-1. -static const struct { - int profile_idc; - int cpb_br_vcl_factor; - int cpb_br_nal_factor; -} h264_br_factors[] = { - { 66, 1000, 1200 }, - { 77, 1000, 1200 }, - { 88, 1000, 1200 }, - { 100, 1250, 1500 }, - { 110, 3000, 3600 }, - { 122, 4000, 4800 }, - { 244, 4000, 4800 }, - { 44, 4000, 4800 }, -}; - -// We are only ever interested in the NAL bitrate factor. -static int h264_get_br_factor(int profile_idc) { - int i; - for(i = 0; i < FF_ARRAY_ELEMS(h264_br_factors); i++) { - if(h264_br_factors[i].profile_idc == profile_idc) - return h264_br_factors[i].cpb_br_nal_factor; - } - // Default to the non-high profile value if not specified. - return 1200; -} - -const H264LevelDescriptor *ff_h264_guess_level(int profile_idc, - int64_t bitrate, - int framerate, - int width, int height, - int max_dec_frame_buffering) { - int width_mbs = (width + 15) / 16; - int height_mbs = (height + 15) / 16; - int no_cs3f = !(profile_idc == 66 || - profile_idc == 77 || - profile_idc == 88); - int i; - - for(i = 0; i < FF_ARRAY_ELEMS(h264_levels); i++) { - const H264LevelDescriptor *level = &h264_levels[i]; - - if(level->constraint_set3_flag && no_cs3f) - continue; - - if(bitrate > (int64_t)level->max_br * h264_get_br_factor(profile_idc)) - continue; - - if(width_mbs * height_mbs > level->max_fs) - continue; - if(width_mbs * width_mbs > 8 * level->max_fs) - continue; - if(height_mbs * height_mbs > 8 * level->max_fs) - continue; - - if(width_mbs && height_mbs) { - int max_dpb_frames = - FFMIN(level->max_dpb_mbs / (width_mbs * height_mbs), 16); - if(max_dec_frame_buffering > max_dpb_frames) - continue; - - if(framerate > (level->max_mbps / (width_mbs * height_mbs))) - continue; - } - - return level; - } - - // No usable levels found - frame is too big or bitrate is too high. - return NULL; -} - -static const H265LevelDescriptor h265_levels[] = { - // Name CpbFactor-Main MaxSliceSegmentsPerPicture - // | level_idc | CpbFactor-High MaxLumaSr BrFactor-High - // | | MaxLumaPs | | | MaxTileRows | BrFactor-Main | MinCr-Main - // | | | | | | | MaxTileCols | | | MinCr-High - { "1", 30, 36864, 350, 0, 16, 1, 1, 552960, 128, 0, 2, 2 }, - { "2", 60, 122880, 1500, 0, 16, 1, 1, 3686400, 1500, 0, 2, 2 }, - { "2.1", 63, 245760, 3000, 0, 20, 1, 1, 7372800, 3000, 0, 2, 2 }, - { "3", 90, 552960, 6000, 0, 30, 2, 2, 16588800, 6000, 0, 2, 2 }, - { "3.1", 93, 983040, 10000, 0, 40, 3, 3, 33177600, 10000, 0, 2, 2 }, - { "4", 120, 2228224, 12000, 30000, 75, 5, 5, 66846720, 12000, 30000, 4, 4 }, - { "4.1", 123, 2228224, 20000, 50000, 75, 5, 5, 133693440, 20000, 50000, 4, 4 }, - { "5", 150, 8912896, 25000, 100000, 200, 11, 10, 267386880, 25000, 100000, 6, 4 }, - { "5.1", 153, 8912896, 40000, 160000, 200, 11, 10, 534773760, 40000, 160000, 8, 4 }, - { "5.2", 156, 8912896, 60000, 240000, 200, 11, 10, 1069547520, 60000, 240000, 8, 4 }, - { "6", 180, 35651584, 60000, 240000, 600, 22, 20, 1069547520, 60000, 240000, 8, 4 }, - { "6.1", 183, 35651584, 120000, 480000, 600, 22, 20, 2139095040, 120000, 480000, 8, 4 }, - { "6.2", 186, 35651584, 240000, 800000, 600, 22, 20, 4278190080, 240000, 800000, 6, 4 }, -}; - -static const H265ProfileDescriptor h265_profiles[] = { - // profile_idc 8bit one-picture - // HT-profile | 422chroma | lower-bit-rate - // | 14bit | | 420chroma | | CpbVclFactor MinCrScaleFactor - // | | 12bit | | | monochrome| | CpbNalFactor | maxDpbPicBuf - // | | | 10bit | | | intra | | | FormatCapabilityFactor - { "Monochrome", // | | | | | | | | | | | - 4, 0, 2, 1, 1, 1, 1, 1, 1, 0, 0, 1, 667, 733, 1.000, 1.0, 6 }, - { "Monochrome 10", - 4, 0, 2, 1, 1, 0, 1, 1, 1, 0, 0, 1, 833, 917, 1.250, 1.0, 6 }, - { "Monochrome 12", - 4, 0, 2, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1000, 1100, 1.500, 1.0, 6 }, - { "Monochrome 16", - 4, 0, 2, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1333, 1467, 2.000, 1.0, 6 }, - { "Main", - 1, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1000, 1100, 1.500, 1.0, 6 }, - { "Screen-Extended Main", - 9, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1000, 1100, 1.500, 1.0, 7 }, - { "Main 10", - 2, 0, 2, 2, 2, 2, 2, 2, 2, 2, 0, 2, 1000, 1100, 1.875, 1.0, 6 }, - { "Screen-Extended Main 10", - 9, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1000, 1100, 1.875, 1.0, 7 }, - { "Main 12", - 4, 0, 2, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1500, 1650, 2.250, 1.0, 6 }, - { "Main Still Picture", - 3, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1000, 1100, 1.500, 1.0, 6 }, - { "Main 10 Still Picture", - 2, 0, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 1000, 1100, 1.875, 1.0, 6 }, - { "Main 4:2:2 10", - 4, 0, 2, 1, 1, 0, 1, 0, 0, 0, 0, 1, 1667, 1833, 2.500, 0.5, 6 }, - { "Main 4:2:2 12", - 4, 0, 2, 1, 0, 0, 1, 0, 0, 0, 0, 1, 2000, 2200, 3.000, 0.5, 6 }, - { "Main 4:4:4", - 4, 0, 2, 1, 1, 1, 0, 0, 0, 0, 0, 1, 2000, 2200, 3.000, 0.5, 6 }, - { "High Throughput 4:4:4", - 5, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 2000, 2200, 3.000, 0.5, 6 }, - { "Screen-Extended Main 4:4:4", - 9, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 2000, 2200, 3.000, 0.5, 7 }, - { "Screen-Extended High Throughput 4:4:4", - 9, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 2000, 2200, 3.000, 0.5, 7 }, - { "Main 4:4:4 10", - 4, 0, 2, 1, 1, 0, 0, 0, 0, 0, 0, 1, 2500, 2750, 3.750, 0.5, 6 }, - { "High Throughput 4:4:4 10", - 5, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 2500, 2750, 3.750, 0.5, 6 }, - { "Screen-Extended Main 4:4:4 10", - 9, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 2500, 2750, 3.750, 0.5, 7 }, - { "Screen-Extended High Throughput 4:4:4 10", - 9, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 2500, 2750, 3.750, 0.5, 7 }, - { "Main 4:4:4 12", - 4, 0, 2, 1, 0, 0, 0, 0, 0, 0, 0, 1, 3000, 3300, 4.500, 0.5, 6 }, - { "High Throughput 4:4:4 14", - 5, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3500, 3850, 5.250, 0.5, 6 }, - { "Screen-Extended High Throughput 4:4:4 14", - 9, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3500, 3850, 5.250, 0.5, 7 }, - { "Main Intra", - 4, 0, 2, 1, 1, 1, 1, 1, 0, 1, 0, 2, 1000, 1100, 1.500, 1.0, 6 }, - { "Main 10 Intra", - 4, 0, 2, 1, 1, 0, 1, 1, 0, 1, 0, 2, 1000, 1100, 1.875, 1.0, 6 }, - { "Main 12 Intra", - 4, 0, 2, 1, 0, 0, 1, 1, 0, 1, 0, 2, 1500, 1650, 2.250, 1.0, 6 }, - { "Main 4:2:2 10 Intra", - 4, 0, 2, 1, 1, 0, 1, 0, 0, 1, 0, 2, 1667, 1833, 2.500, 0.5, 6 }, - { "Main 4:2:2 12 Intra", - 4, 0, 2, 1, 0, 0, 1, 0, 0, 1, 0, 2, 2000, 2200, 3.000, 0.5, 6 }, - { "Main 4:4:4 Intra", - 4, 0, 2, 1, 1, 1, 0, 0, 0, 1, 0, 2, 2000, 2200, 3.000, 0.5, 6 }, - { "Main 4:4:4 10 Intra", - 4, 0, 2, 1, 1, 0, 0, 0, 0, 1, 0, 2, 2500, 2750, 3.750, 0.5, 6 }, - { "Main 4:4:4 12 Intra", - 4, 0, 2, 1, 0, 0, 0, 0, 0, 1, 0, 2, 3000, 3300, 4.500, 0.5, 6 }, - { "Main 4:4:4 16 Intra", - 4, 0, 2, 0, 0, 0, 0, 0, 0, 1, 0, 2, 4000, 4400, 6.000, 0.5, 6 }, - { "Main 4:4:4 Still Picture", - 4, 0, 2, 1, 1, 1, 0, 0, 0, 1, 1, 2, 2000, 2200, 3.000, 0.5, 6 }, - { "Main 4:4:4 16 Still Picture", - 4, 0, 2, 0, 0, 0, 0, 0, 0, 1, 1, 2, 4000, 4400, 6.000, 0.5, 6 }, - { "High Throughput 4:4:4 16 Intra", - 5, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 2, 4000, 4400, 6.000, 0.5, 6 }, -}; - - -const H265ProfileDescriptor *ff_h265_get_profile(const H265RawProfileTierLevel *ptl) { - int i; - - if(ptl->general_profile_space) - return NULL; - - for(i = 0; i < FF_ARRAY_ELEMS(h265_profiles); i++) { - const H265ProfileDescriptor *profile = &h265_profiles[i]; - - if(ptl->general_profile_idc && - ptl->general_profile_idc != profile->profile_idc) - continue; - if(!ptl->general_profile_compatibility_flag[profile->profile_idc]) - continue; - -#define check_flag(name) \ - if(profile->name < 2) { \ - if(profile->name != ptl->general_##name##_constraint_flag) \ - continue; \ - } - check_flag(max_14bit); - check_flag(max_12bit); - check_flag(max_10bit); - check_flag(max_8bit); - check_flag(max_422chroma); - check_flag(max_420chroma); - check_flag(max_monochrome); - check_flag(intra); - check_flag(one_picture_only); - check_flag(lower_bit_rate); -#undef check_flag - - return profile; - } - - return NULL; -} - -const H265LevelDescriptor *ff_h265_guess_level(const H265RawProfileTierLevel *ptl, - int64_t bitrate, - int width, int height, - int slice_segments, - int tile_rows, int tile_cols, - int max_dec_pic_buffering) { - const H265ProfileDescriptor *profile; - int pic_size, tier_flag, lbr_flag, hbr_factor; - int i; - - if(ptl) - profile = ff_h265_get_profile(ptl); - else - profile = NULL; - if(!profile) { - // Default to using multiplication factors for Main profile. - profile = &h265_profiles[4]; - } - - pic_size = width * height; - - if(ptl) { - tier_flag = ptl->general_tier_flag; - lbr_flag = ptl->general_lower_bit_rate_constraint_flag; - } - else { - tier_flag = 0; - lbr_flag = profile->lower_bit_rate > 0; - } - if(profile->profile_idc == 1 || profile->profile_idc == 2) { - hbr_factor = 1; - } - else if(profile->high_throughput) { - if(profile->intra) - hbr_factor = 24 - 12 * lbr_flag; - else - hbr_factor = 6; - } - else { - hbr_factor = 2 - lbr_flag; - } - - for(i = 0; i < FF_ARRAY_ELEMS(h265_levels); i++) { - const H265LevelDescriptor *level = &h265_levels[i]; - int max_br, max_dpb_size; - - if(tier_flag && !level->max_br_high) - continue; - - if(pic_size > level->max_luma_ps) - continue; - if(width * width > 8 * level->max_luma_ps) - continue; - if(height * height > 8 * level->max_luma_ps) - continue; - - if(slice_segments > level->max_slice_segments_per_picture) - continue; - if(tile_rows > level->max_tile_rows) - continue; - if(tile_cols > level->max_tile_cols) - continue; - - if(tier_flag) - max_br = level->max_br_high; - else - max_br = level->max_br_main; - if(!max_br) - continue; - if(bitrate > (int64_t)profile->cpb_nal_factor * hbr_factor * max_br) - continue; - - if(pic_size <= (level->max_luma_ps >> 2)) - max_dpb_size = FFMIN(4 * profile->max_dpb_pic_buf, 16); - else if(pic_size <= (level->max_luma_ps >> 1)) - max_dpb_size = FFMIN(2 * profile->max_dpb_pic_buf, 16); - else if(pic_size <= (3 * level->max_luma_ps >> 2)) - max_dpb_size = FFMIN(4 * profile->max_dpb_pic_buf / 3, 16); - else - max_dpb_size = profile->max_dpb_pic_buf; - if(max_dec_pic_buffering > max_dpb_size) - continue; - - return level; - } - - return NULL; -} \ No newline at end of file diff --git a/third-party/cbs/vlc.h b/third-party/cbs/vlc.h deleted file mode 100644 index aaa21a9cb6f..00000000000 --- a/third-party/cbs/vlc.h +++ /dev/null @@ -1,140 +0,0 @@ -/* - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVCODEC_VLC_H -#define AVCODEC_VLC_H - -#include - -#define VLC_TYPE int16_t - -typedef struct VLC { - int bits; - VLC_TYPE (*table) - [2]; ///< code, bits - int table_size, table_allocated; -} VLC; - -typedef struct RL_VLC_ELEM { - int16_t level; - int8_t len; - uint8_t run; -} RL_VLC_ELEM; - -#define init_vlc(vlc, nb_bits, nb_codes, \ - bits, bits_wrap, bits_size, \ - codes, codes_wrap, codes_size, \ - flags) \ - ff_init_vlc_sparse(vlc, nb_bits, nb_codes, \ - bits, bits_wrap, bits_size, \ - codes, codes_wrap, codes_size, \ - NULL, 0, 0, flags) - -int ff_init_vlc_sparse(VLC *vlc, int nb_bits, int nb_codes, - const void *bits, int bits_wrap, int bits_size, - const void *codes, int codes_wrap, int codes_size, - const void *symbols, int symbols_wrap, int symbols_size, - int flags); - -/** - * Build VLC decoding tables suitable for use with get_vlc2() - * - * This function takes lengths and symbols and calculates the codes from them. - * For this the input lengths and symbols have to be sorted according to "left - * nodes in the corresponding tree first". - * - * @param[in,out] vlc The VLC to be initialized; table and table_allocated - * must have been set when initializing a static VLC, - * otherwise this will be treated as uninitialized. - * @param[in] nb_bits The number of bits to use for the VLC table; - * higher values take up more memory and cache, but - * allow to read codes with fewer reads. - * @param[in] nb_codes The number of provided length and (if supplied) symbol - * entries. - * @param[in] lens The lengths of the codes. Entries > 0 correspond to - * valid codes; entries == 0 will be skipped and entries - * with len < 0 indicate that the tree is incomplete and - * has an open end of length -len at this position. - * @param[in] lens_wrap Stride (in bytes) of the lengths. - * @param[in] symbols The symbols, i.e. what is returned from get_vlc2() - * when the corresponding code is encountered. - * May be NULL, then 0, 1, 2, 3, 4,... will be used. - * @param[in] symbols_wrap Stride (in bytes) of the symbols. - * @param[in] symbols_size Size of the symbols. 1 and 2 are supported. - * @param[in] offset An offset to apply to all the valid symbols. - * @param[in] flags A combination of the INIT_VLC_* flags; notice that - * INIT_VLC_INPUT_LE is pointless and ignored. - */ -int ff_init_vlc_from_lengths(VLC *vlc, int nb_bits, int nb_codes, - const int8_t *lens, int lens_wrap, - const void *symbols, int symbols_wrap, int symbols_size, - int offset, int flags, void *logctx); - -void ff_free_vlc(VLC *vlc); - -/* If INIT_VLC_INPUT_LE is set, the LSB bit of the codes used to - * initialize the VLC table is the first bit to be read. */ -#define INIT_VLC_INPUT_LE 2 -/* If set the VLC is intended for a little endian bitstream reader. */ -#define INIT_VLC_OUTPUT_LE 8 -#define INIT_VLC_LE (INIT_VLC_INPUT_LE | INIT_VLC_OUTPUT_LE) -#define INIT_VLC_USE_NEW_STATIC 4 -#define INIT_VLC_STATIC_OVERLONG (1 | INIT_VLC_USE_NEW_STATIC) - -#define INIT_CUSTOM_VLC_SPARSE_STATIC(vlc, bits, a, b, c, d, e, f, g, \ - h, i, j, flags, static_size) \ - do { \ - static VLC_TYPE table[static_size][2]; \ - (vlc)->table = table; \ - (vlc)->table_allocated = static_size; \ - ff_init_vlc_sparse(vlc, bits, a, b, c, d, e, f, g, h, i, j, \ - flags | INIT_VLC_USE_NEW_STATIC); \ - } while(0) - -#define INIT_VLC_SPARSE_STATIC(vlc, bits, a, b, c, d, e, f, g, h, i, j, static_size) \ - INIT_CUSTOM_VLC_SPARSE_STATIC(vlc, bits, a, b, c, d, e, f, g, \ - h, i, j, 0, static_size) - -#define INIT_LE_VLC_SPARSE_STATIC(vlc, bits, a, b, c, d, e, f, g, h, i, j, static_size) \ - INIT_CUSTOM_VLC_SPARSE_STATIC(vlc, bits, a, b, c, d, e, f, g, \ - h, i, j, INIT_VLC_LE, static_size) - -#define INIT_CUSTOM_VLC_STATIC(vlc, bits, a, b, c, d, e, f, g, flags, static_size) \ - INIT_CUSTOM_VLC_SPARSE_STATIC(vlc, bits, a, b, c, d, e, f, g, \ - NULL, 0, 0, flags, static_size) - -#define INIT_VLC_STATIC(vlc, bits, a, b, c, d, e, f, g, static_size) \ - INIT_VLC_SPARSE_STATIC(vlc, bits, a, b, c, d, e, f, g, NULL, 0, 0, static_size) - -#define INIT_LE_VLC_STATIC(vlc, bits, a, b, c, d, e, f, g, static_size) \ - INIT_LE_VLC_SPARSE_STATIC(vlc, bits, a, b, c, d, e, f, g, NULL, 0, 0, static_size) - -#define INIT_VLC_STATIC_FROM_LENGTHS(vlc, bits, nb_codes, lens, len_wrap, \ - symbols, symbols_wrap, symbols_size, \ - offset, flags, static_size) \ - do { \ - static VLC_TYPE table[static_size][2]; \ - (vlc)->table = table; \ - (vlc)->table_allocated = static_size; \ - ff_init_vlc_from_lengths(vlc, bits, nb_codes, lens, len_wrap, \ - symbols, symbols_wrap, symbols_size, \ - offset, flags | INIT_VLC_USE_NEW_STATIC, \ - NULL); \ - } while(0) - -#endif /* AVCODEC_VLC_H */ From c5351e59714c74e509694a5bf8eab5e83afc1983 Mon Sep 17 00:00:00 2001 From: cfajardo Date: Thu, 10 Feb 2022 21:53:46 +0100 Subject: [PATCH 2/7] restore prebuilt into CMakeList.txt --- CMakeLists.txt | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 01a4178009d..d52c4a918b9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -31,14 +31,14 @@ list(APPEND SUNSHINE_COMPILE_OPTIONS -Wall -Wno-missing-braces -Wno-maybe-uninit if(WIN32) enable_language(RC) set(CMAKE_RC_COMPILER windres) - # file( - # DOWNLOAD "https://github.com/TheElixZammuto/sunshine-prebuilt/releases/download/1.0.0/pre-compiled.zip" "${CMAKE_CURRENT_BINARY_DIR}/pre-compiled.zip" - # TIMEOUT 60 - # EXPECTED_HASH SHA256=5d59986bd7f619eaaf82b2dd56b5127b747c9cbe8db61e3b898ff6b485298ed6) - - # file(ARCHIVE_EXTRACT - # INPUT "${CMAKE_CURRENT_BINARY_DIR}/pre-compiled.zip" - # DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/pre-compiled) + file( + DOWNLOAD "https://github.com/TheElixZammuto/sunshine-prebuilt/releases/download/1.0.0/pre-compiled.zip" "${CMAKE_CURRENT_BINARY_DIR}/pre-compiled.zip" + TIMEOUT 60 + EXPECTED_HASH SHA256=5d59986bd7f619eaaf82b2dd56b5127b747c9cbe8db61e3b898ff6b485298ed6) + + file(ARCHIVE_EXTRACT + INPUT "${CMAKE_CURRENT_BINARY_DIR}/pre-compiled.zip" + DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/pre-compiled) set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static") if(NOT DEFINED SUNSHINE_PREPARED_BINARIES) @@ -345,12 +345,9 @@ if(NOT SUNSHINE_DEFAULT_DIR) set(SUNSHINE_DEFAULT_DIR "${SUNSHINE_ASSETS_DIR}") endif() -# list(APPEND CBS_EXTERNAL_LIBRARIES -# cbs) list(APPEND SUNSHINE_EXTERNAL_LIBRARIES libminiupnpc-static - # ${CBS_EXTERNAL_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} stdc++fs enet From 582716c43e2d62f8a7671488da3a0dadd9172b28 Mon Sep 17 00:00:00 2001 From: cfajardo Date: Thu, 10 Feb 2022 21:54:54 +0100 Subject: [PATCH 3/7] remove cbs external library from CMakeList.txt --- CMakeLists.txt | 2 -- 1 file changed, 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d52c4a918b9..9e8f086be20 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -320,8 +320,6 @@ include_directories( ${PLATFORM_INCLUDE_DIRS} ) -# add_subdirectory(third-party/cbs) - string(TOUPPER "x${CMAKE_BUILD_TYPE}" BUILD_TYPE) if("${BUILD_TYPE}" STREQUAL "XDEBUG") list(APPEND SUNSHINE_COMPILE_OPTIONS -O0 -ggdb3) From 3a2db3ae0a7774f6dd3443a4dbe47182678f94bc Mon Sep 17 00:00:00 2001 From: cfajardo Date: Fri, 11 Feb 2022 23:18:43 +0100 Subject: [PATCH 4/7] fix amdvce cqp parameter --- assets/sunshine.conf | 2 +- sunshine/config.cpp | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/assets/sunshine.conf b/assets/sunshine.conf index d8a1f4b461b..fba1bee388a 100644 --- a/assets/sunshine.conf +++ b/assets/sunshine.conf @@ -248,7 +248,7 @@ # ####### rate control ##### # auto -- let ffmpeg decide rate control -# constqp -- constant QP mode +# cqp -- constant QP mode # vbr_latency -- Latency Constrained Variable Bitrate # vbr_peak -- Peak Contrained Variable Bitrate # cbr -- constant bitrate diff --git a/sunshine/config.cpp b/sunshine/config.cpp index a35d59551d2..ddd39d21baa 100644 --- a/sunshine/config.cpp +++ b/sunshine/config.cpp @@ -102,14 +102,14 @@ enum quality_e : int { }; enum class rc_hevc_e : int { - constqp, /**< Constant QP mode */ + cqp, /**< Constant QP mode */ vbr_latency, /**< Latency Constrained Variable Bitrate */ vbr_peak, /**< Peak Contrained Variable Bitrate */ cbr, /**< Constant bitrate mode */ }; enum class rc_h264_e : int { - constqp, /**< Constant QP mode */ + cqp, /**< Constant QP mode */ cbr, /**< Constant bitrate mode */ vbr_peak, /**< Peak Contrained Variable Bitrate */ vbr_latency, /**< Latency Constrained Variable Bitrate */ @@ -134,7 +134,7 @@ std::optional quality_from_view(const std::string_view &quality) { std::optional rc_h264_from_view(const std::string_view &rc) { #define _CONVERT_(x) \ if(rc == #x##sv) return (int)rc_h264_e::x - _CONVERT_(constqp); + _CONVERT_(cqp); _CONVERT_(vbr_latency); _CONVERT_(vbr_peak); _CONVERT_(cbr); @@ -145,7 +145,7 @@ std::optional rc_h264_from_view(const std::string_view &rc) { std::optional rc_hevc_from_view(const std::string_view &rc) { #define _CONVERT_(x) \ if(rc == #x##sv) return (int)rc_hevc_e::x - _CONVERT_(constqp); + _CONVERT_(cqp); _CONVERT_(vbr_latency); _CONVERT_(vbr_peak); _CONVERT_(cbr); From bd667e4581ada96bc6d7c11ba133e85e25121830 Mon Sep 17 00:00:00 2001 From: cfajardo Date: Fri, 11 Feb 2022 23:21:52 +0100 Subject: [PATCH 5/7] fix format --- sunshine/config.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sunshine/config.cpp b/sunshine/config.cpp index ddd39d21baa..2dc8176a18d 100644 --- a/sunshine/config.cpp +++ b/sunshine/config.cpp @@ -109,7 +109,7 @@ enum class rc_hevc_e : int { }; enum class rc_h264_e : int { - cqp, /**< Constant QP mode */ + cqp, /**< Constant QP mode */ cbr, /**< Constant bitrate mode */ vbr_peak, /**< Peak Contrained Variable Bitrate */ vbr_latency, /**< Latency Constrained Variable Bitrate */ From c18e5a1078ae4ac0cc1853341ec1d55ce751d5d8 Mon Sep 17 00:00:00 2001 From: cfajardo Date: Fri, 11 Feb 2022 23:22:59 +0100 Subject: [PATCH 6/7] fix format --- sunshine/config.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sunshine/config.cpp b/sunshine/config.cpp index 2dc8176a18d..a0e6a553f0d 100644 --- a/sunshine/config.cpp +++ b/sunshine/config.cpp @@ -102,7 +102,7 @@ enum quality_e : int { }; enum class rc_hevc_e : int { - cqp, /**< Constant QP mode */ + cqp, /**< Constant QP mode */ vbr_latency, /**< Latency Constrained Variable Bitrate */ vbr_peak, /**< Peak Contrained Variable Bitrate */ cbr, /**< Constant bitrate mode */ From b895936dc4a7d0c4821a14746d9fe594236245f2 Mon Sep 17 00:00:00 2001 From: PapyKahan Date: Sun, 13 Feb 2022 10:10:31 +0100 Subject: [PATCH 7/7] update prebuild --- CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9e8f086be20..8ae81b91f71 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -32,9 +32,9 @@ if(WIN32) enable_language(RC) set(CMAKE_RC_COMPILER windres) file( - DOWNLOAD "https://github.com/TheElixZammuto/sunshine-prebuilt/releases/download/1.0.0/pre-compiled.zip" "${CMAKE_CURRENT_BINARY_DIR}/pre-compiled.zip" + DOWNLOAD "https://github.com/SunshineStream/Sunshine-Windows-Prebuilt/releases/download/v1/pre-compiled.zip" "${CMAKE_CURRENT_BINARY_DIR}/pre-compiled.zip" TIMEOUT 60 - EXPECTED_HASH SHA256=5d59986bd7f619eaaf82b2dd56b5127b747c9cbe8db61e3b898ff6b485298ed6) + EXPECTED_HASH SHA256=e0bd75cc9cd98e1c22b8c6805afd9126ce141d46837405bdc10c4458437590a2) file(ARCHIVE_EXTRACT INPUT "${CMAKE_CURRENT_BINARY_DIR}/pre-compiled.zip"