X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Fcbs_h2645.c;h=ab33cdb69bfb6b9fbbb2c05a67f22f5f8a83ef81;hb=755e618399264d57a64a21115e2bf067b73492e7;hp=ebc02361d02d63a976a1c35e91de2b8e8cacdd63;hpb=7157d959264f3729da463725c6faa580d9394d19;p=ffmpeg diff --git a/libavcodec/cbs_h2645.c b/libavcodec/cbs_h2645.c index ebc02361d02..ab33cdb69bf 100644 --- a/libavcodec/cbs_h2645.c +++ b/libavcodec/cbs_h2645.c @@ -1,18 +1,18 @@ /* - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -29,10 +29,12 @@ #include "h264_sei.h" #include "h2645_parse.h" #include "hevc.h" +#include "hevc_sei.h" -static int cbs_read_ue_golomb(CodedBitstreamContext *ctx, BitstreamContext *bc, - const char *name, uint32_t *write_to, +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; @@ -40,15 +42,15 @@ static int cbs_read_ue_golomb(CodedBitstreamContext *ctx, BitstreamContext *bc, unsigned int k; char bits[65]; - position = bitstream_tell(bc); + position = get_bits_count(gbc); for (i = 0; i < 32; i++) { - if (bitstream_bits_left(bc) < i + 1) { + 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 = bitstream_read_bit(bc); + k = get_bits1(gbc); bits[i] = k ? '1' : '0'; if (k) break; @@ -60,7 +62,7 @@ static int cbs_read_ue_golomb(CodedBitstreamContext *ctx, BitstreamContext *bc, } value = 1; for (j = 0; j < i; j++) { - k = bitstream_read_bit(bc); + k = get_bits1(gbc); bits[i + j + 1] = k ? '1' : '0'; value = value << 1 | k; } @@ -68,7 +70,8 @@ static int cbs_read_ue_golomb(CodedBitstreamContext *ctx, BitstreamContext *bc, --value; if (ctx->trace_enable) - ff_cbs_trace_syntax_element(ctx, position, name, bits, value); + 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: " @@ -81,8 +84,9 @@ static int cbs_read_ue_golomb(CodedBitstreamContext *ctx, BitstreamContext *bc, return 0; } -static int cbs_read_se_golomb(CodedBitstreamContext *ctx, BitstreamContext *bc, - const char *name, int32_t *write_to, +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; @@ -91,15 +95,15 @@ static int cbs_read_se_golomb(CodedBitstreamContext *ctx, BitstreamContext *bc, uint32_t v; char bits[65]; - position = bitstream_tell(bc); + position = get_bits_count(gbc); for (i = 0; i < 32; i++) { - if (bitstream_bits_left(bc) < i + 1) { + 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 = bitstream_read_bit(bc); + k = get_bits1(gbc); bits[i] = k ? '1' : '0'; if (k) break; @@ -111,7 +115,7 @@ static int cbs_read_se_golomb(CodedBitstreamContext *ctx, BitstreamContext *bc, } v = 1; for (j = 0; j < i; j++) { - k = bitstream_read_bit(bc); + k = get_bits1(gbc); bits[i + j + 1] = k ? '1' : '0'; v = v << 1 | k; } @@ -122,7 +126,8 @@ static int cbs_read_se_golomb(CodedBitstreamContext *ctx, BitstreamContext *bc, value = v / 2; if (ctx->trace_enable) - ff_cbs_trace_syntax_element(ctx, position, name, bits, value); + 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: " @@ -136,7 +141,8 @@ static int cbs_read_se_golomb(CodedBitstreamContext *ctx, BitstreamContext *bc, } static int cbs_write_ue_golomb(CodedBitstreamContext *ctx, PutBitContext *pbc, - const char *name, uint32_t value, + const char *name, const int *subscripts, + uint32_t value, uint32_t range_min, uint32_t range_max) { int len; @@ -164,7 +170,8 @@ static int cbs_write_ue_golomb(CodedBitstreamContext *ctx, PutBitContext *pbc, 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, bits, value); + ff_cbs_trace_syntax_element(ctx, put_bits_count(pbc), + name, subscripts, bits, value); } put_bits(pbc, len, 0); @@ -177,7 +184,8 @@ static int cbs_write_ue_golomb(CodedBitstreamContext *ctx, PutBitContext *pbc, } static int cbs_write_se_golomb(CodedBitstreamContext *ctx, PutBitContext *pbc, - const char *name, int32_t value, + const char *name, const int *subscripts, + int32_t value, int32_t range_min, int32_t range_max) { int len; @@ -213,7 +221,8 @@ static int cbs_write_se_golomb(CodedBitstreamContext *ctx, PutBitContext *pbc, 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, bits, value); + ff_cbs_trace_syntax_element(ctx, put_bits_count(pbc), + name, subscripts, bits, value); } put_bits(pbc, len, 0); @@ -239,56 +248,75 @@ static int cbs_write_se_golomb(CodedBitstreamContext *ctx, PutBitContext *pbc, #define FUNC_H264(rw, name) FUNC_NAME(rw, h264, name) #define FUNC_H265(rw, name) FUNC_NAME(rw, h265, 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 flag(name) u(1, name, 0, 1) +#define ue(name, range_min, range_max) \ + xue(name, current->name, range_min, range_max, 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 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 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 BitstreamContext +#define RWContext GetBitContext -#define xu(width, name, var, range_min, range_max) do { \ +#define xu(width, name, var, range_min, range_max, subs, ...) do { \ uint32_t value = range_min; \ 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) do { \ +#define xue(name, var, range_min, range_max, subs, ...) do { \ uint32_t value = range_min; \ CHECK(cbs_read_ue_golomb(ctx, rw, #name, \ + SUBSCRIPTS(subs, __VA_ARGS__), \ &value, range_min, range_max)); \ var = value; \ } while (0) -#define xse(name, var, range_min, range_max) do { \ +#define xse(name, var, range_min, range_max, subs, ...) do { \ int32_t value = range_min; \ CHECK(cbs_read_se_golomb(ctx, rw, #name, \ + SUBSCRIPTS(subs, __VA_ARGS__), \ &value, range_min, range_max)); \ var = value; \ } while (0) -#define u(width, name, range_min, range_max) \ - xu(width, name, current->name, range_min, range_max) -#define flag(name) u(1, name, 0, 1) -#define ue(name, range_min, range_max) \ - xue(name, current->name, range_min, range_max) -#define se(name, range_min, range_max) \ - xse(name, current->name, range_min, range_max) - #define infer(name, value) do { \ current->name = value; \ } while (0) -static int cbs_h2645_read_more_rbsp_data(BitstreamContext *bc) +static int cbs_h2645_read_more_rbsp_data(GetBitContext *gbc) { - int bits_left = bitstream_bits_left(bc); + int bits_left = get_bits_left(gbc); if (bits_left > 8) return 1; - if (bitstream_peek(bc, bits_left) == 1 << (bits_left - 1)) + if (show_bits(gbc, bits_left) == 1 << (bits_left - 1)) return 0; return 1; } #define more_rbsp_data(var) ((var) = cbs_h2645_read_more_rbsp_data(rw)) -#define byte_alignment(rw) (bitstream_tell(rw) % 8) +#define byte_alignment(rw) (get_bits_count(rw) % 8) #define allocate(name, size) do { \ name ## _ref = av_buffer_allocz(size); \ @@ -311,10 +339,6 @@ static int cbs_h2645_read_more_rbsp_data(BitstreamContext *bc) #undef xu #undef xue #undef xse -#undef u -#undef flag -#undef ue -#undef se #undef infer #undef more_rbsp_data #undef byte_alignment @@ -325,30 +349,25 @@ static int cbs_h2645_read_more_rbsp_data(BitstreamContext *bc) #define READWRITE write #define RWContext PutBitContext -#define xu(width, name, var, range_min, range_max) do { \ +#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) do { \ +#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 xse(name, var, range_min, range_max) do { \ +#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 u(width, name, range_min, range_max) \ - xu(width, name, current->name, range_min, range_max) -#define flag(name) u(1, name, 0, 1) -#define ue(name, range_min, range_max) \ - xue(name, current->name, range_min, range_max) -#define se(name, range_min, range_max) \ - xse(name, current->name, range_min, range_max) - #define infer(name, value) do { \ if (current->name != (value)) { \ av_log(ctx->log_ctx, AV_LOG_WARNING, "Warning: " \ @@ -406,8 +425,10 @@ static void cbs_h264_free_sei_payload(H264RawSEIPayload *payload) switch (payload->payload_type) { case H264_SEI_TYPE_BUFFERING_PERIOD: case H264_SEI_TYPE_PIC_TIMING: + case H264_SEI_TYPE_PAN_SCAN_RECT: case H264_SEI_TYPE_RECOVERY_POINT: case H264_SEI_TYPE_DISPLAY_ORIENTATION: + case H264_SEI_TYPE_MASTERING_DISPLAY_COLOUR_VOLUME: break; case H264_SEI_TYPE_USER_DATA_REGISTERED: av_buffer_unref(&payload->payload.user_data_registered.data_ref); @@ -465,6 +486,27 @@ static void cbs_h265_free_slice(void *unit, uint8_t *content) av_freep(&content); } +static void cbs_h265_free_sei_payload(H265RawSEIPayload *payload) +{ + switch (payload->payload_type) { + case HEVC_SEI_TYPE_MASTERING_DISPLAY_INFO: + case HEVC_SEI_TYPE_CONTENT_LIGHT_LEVEL_INFO: + break; + default: + av_buffer_unref(&payload->payload.other.data_ref); + break; + } +} + +static void cbs_h265_free_sei(void *unit, uint8_t *content) +{ + H265RawSEI *sei = (H265RawSEI*)content; + int i; + for (i = 0; i < sei->payload_count; i++) + cbs_h265_free_sei_payload(&sei->payload[i]); + av_freep(&content); +} + static int cbs_h2645_fragment_add_nals(CodedBitstreamContext *ctx, CodedBitstreamFragment *frag, const H2645Packet *packet) @@ -488,7 +530,7 @@ static int cbs_h2645_fragment_add_nals(CodedBitstreamContext *ctx, memset(data + size, 0, AV_INPUT_BUFFER_PADDING_SIZE); err = ff_cbs_insert_unit_data(ctx, frag, -1, nal->type, - data, nal->size, NULL); + data, size, NULL); if (err < 0) { av_freep(&data); return err; @@ -548,7 +590,7 @@ static int cbs_h2645_split_fragment(CodedBitstreamContext *ctx, err = ff_h2645_packet_split(&priv->read_packet, frag->data + start, end - start, - ctx->log_ctx, 1, 2, AV_CODEC_ID_H264); + ctx->log_ctx, 1, 2, AV_CODEC_ID_H264, 1); if (err < 0) { av_log(ctx->log_ctx, AV_LOG_ERROR, "Failed to split AVCC SPS array.\n"); return err; @@ -572,7 +614,7 @@ static int cbs_h2645_split_fragment(CodedBitstreamContext *ctx, err = ff_h2645_packet_split(&priv->read_packet, frag->data + start, end - start, - ctx->log_ctx, 1, 2, AV_CODEC_ID_H264); + ctx->log_ctx, 1, 2, AV_CODEC_ID_H264, 1); if (err < 0) { av_log(ctx->log_ctx, AV_LOG_ERROR, "Failed to split AVCC PPS array.\n"); return err; @@ -626,7 +668,7 @@ static int cbs_h2645_split_fragment(CodedBitstreamContext *ctx, err = ff_h2645_packet_split(&priv->read_packet, frag->data + start, end - start, - ctx->log_ctx, 1, 2, AV_CODEC_ID_HEVC); + ctx->log_ctx, 1, 2, AV_CODEC_ID_HEVC, 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", @@ -645,7 +687,7 @@ static int cbs_h2645_split_fragment(CodedBitstreamContext *ctx, frag->data, frag->data_size, ctx->log_ctx, priv->mp4, priv->nal_length_size, - codec_id); + codec_id, 1); if (err < 0) return err; @@ -659,9 +701,10 @@ static int cbs_h2645_split_fragment(CodedBitstreamContext *ctx, #define cbs_h2645_replace_ps(h26n, ps_name, ps_var, id_element) \ static int cbs_h26 ## h26n ## _replace_ ## ps_var(CodedBitstreamContext *ctx, \ - const H26 ## h26n ## Raw ## ps_name *ps_var) \ + 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; \ if (id > FF_ARRAY_ELEMS(priv->ps_var)) { \ av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid " #ps_name \ @@ -670,11 +713,16 @@ static int cbs_h26 ## h26n ## _replace_ ## ps_var(CodedBitstreamContext *ctx, \ } \ if (priv->ps_var[id] == priv->active_ ## ps_var) \ priv->active_ ## ps_var = NULL ; \ - av_freep(&priv->ps_var[id]); \ - priv->ps_var[id] = av_malloc(sizeof(*ps_var)); \ - if (!priv->ps_var[id]) \ + av_buffer_unref(&priv->ps_var ## _ref[id]); \ + if (unit->content_ref) \ + priv->ps_var ## _ref[id] = av_buffer_ref(unit->content_ref); \ + else \ + priv->ps_var ## _ref[id] = av_buffer_alloc(sizeof(*ps_var)); \ + if (!priv->ps_var ## _ref[id]) \ return AVERROR(ENOMEM); \ - memcpy(priv->ps_var[id], ps_var, sizeof(*ps_var)); \ + priv->ps_var[id] = (H26 ## h26n ## Raw ## ps_name *)priv->ps_var ## _ref[id]->data; \ + if (!unit->content_ref) \ + memcpy(priv->ps_var[id], ps_var, sizeof(*ps_var)); \ return 0; \ } @@ -687,10 +735,10 @@ cbs_h2645_replace_ps(5, PPS, pps, pps_pic_parameter_set_id) static int cbs_h264_read_nal_unit(CodedBitstreamContext *ctx, CodedBitstreamUnit *unit) { - BitstreamContext bc; + GetBitContext gbc; int err; - err = bitstream_init(&bc, unit->data, 8 * unit->data_size); + err = init_get_bits(&gbc, unit->data, 8 * unit->data_size); if (err < 0) return err; @@ -704,11 +752,11 @@ static int cbs_h264_read_nal_unit(CodedBitstreamContext *ctx, return err; sps = unit->content; - err = cbs_h264_read_sps(ctx, &bc, sps); + err = cbs_h264_read_sps(ctx, &gbc, sps); if (err < 0) return err; - err = cbs_h264_replace_sps(ctx, sps); + err = cbs_h264_replace_sps(ctx, unit); if (err < 0) return err; } @@ -722,7 +770,7 @@ static int cbs_h264_read_nal_unit(CodedBitstreamContext *ctx, if (err < 0) return err; - err = cbs_h264_read_sps_extension(ctx, &bc, unit->content); + err = cbs_h264_read_sps_extension(ctx, &gbc, unit->content); if (err < 0) return err; } @@ -738,11 +786,11 @@ static int cbs_h264_read_nal_unit(CodedBitstreamContext *ctx, return err; pps = unit->content; - err = cbs_h264_read_pps(ctx, &bc, pps); + err = cbs_h264_read_pps(ctx, &gbc, pps); if (err < 0) return err; - err = cbs_h264_replace_pps(ctx, pps); + err = cbs_h264_replace_pps(ctx, unit); if (err < 0) return err; } @@ -761,11 +809,11 @@ static int cbs_h264_read_nal_unit(CodedBitstreamContext *ctx, return err; slice = unit->content; - err = cbs_h264_read_slice_header(ctx, &bc, &slice->header); + err = cbs_h264_read_slice_header(ctx, &gbc, &slice->header); if (err < 0) return err; - pos = bitstream_tell(&bc); + pos = get_bits_count(&gbc); len = unit->data_size; if (!unit->data[len - 1]) { int z; @@ -776,15 +824,10 @@ static int cbs_h264_read_nal_unit(CodedBitstreamContext *ctx, } slice->data_size = len - pos / 8; - slice->data_ref = av_buffer_alloc(slice->data_size + - AV_INPUT_BUFFER_PADDING_SIZE); + slice->data_ref = av_buffer_ref(unit->data_ref); if (!slice->data_ref) return AVERROR(ENOMEM); - slice->data = slice->data_ref->data; - memcpy(slice->data, - unit->data + pos / 8, slice->data_size); - memset(slice->data + slice->data_size, 0, - AV_INPUT_BUFFER_PADDING_SIZE); + slice->data = unit->data + pos / 8; slice->data_bit_start = pos % 8; } break; @@ -796,7 +839,7 @@ static int cbs_h264_read_nal_unit(CodedBitstreamContext *ctx, if (err < 0) return err; - err = cbs_h264_read_aud(ctx, &bc, unit->content); + err = cbs_h264_read_aud(ctx, &gbc, unit->content); if (err < 0) return err; } @@ -809,7 +852,20 @@ static int cbs_h264_read_nal_unit(CodedBitstreamContext *ctx, if (err < 0) return err; - err = cbs_h264_read_sei(ctx, &bc, unit->content); + err = cbs_h264_read_sei(ctx, &gbc, unit->content); + if (err < 0) + return err; + } + break; + + case H264_NAL_FILLER_DATA: + { + err = ff_cbs_alloc_unit_content(ctx, unit, + sizeof(H264RawFiller), NULL); + if (err < 0) + return err; + + err = cbs_h264_read_filler(ctx, &gbc, unit->content); if (err < 0) return err; } @@ -825,10 +881,10 @@ static int cbs_h264_read_nal_unit(CodedBitstreamContext *ctx, static int cbs_h265_read_nal_unit(CodedBitstreamContext *ctx, CodedBitstreamUnit *unit) { - BitstreamContext bc; + GetBitContext gbc; int err; - err = bitstream_init(&bc, unit->data, 8 * unit->data_size); + err = init_get_bits(&gbc, unit->data, 8 * unit->data_size); if (err < 0) return err; @@ -843,11 +899,11 @@ static int cbs_h265_read_nal_unit(CodedBitstreamContext *ctx, return err; vps = unit->content; - err = cbs_h265_read_vps(ctx, &bc, vps); + err = cbs_h265_read_vps(ctx, &gbc, vps); if (err < 0) return err; - err = cbs_h265_replace_vps(ctx, vps); + err = cbs_h265_replace_vps(ctx, unit); if (err < 0) return err; } @@ -862,11 +918,11 @@ static int cbs_h265_read_nal_unit(CodedBitstreamContext *ctx, return err; sps = unit->content; - err = cbs_h265_read_sps(ctx, &bc, sps); + err = cbs_h265_read_sps(ctx, &gbc, sps); if (err < 0) return err; - err = cbs_h265_replace_sps(ctx, sps); + err = cbs_h265_replace_sps(ctx, unit); if (err < 0) return err; } @@ -882,11 +938,11 @@ static int cbs_h265_read_nal_unit(CodedBitstreamContext *ctx, return err; pps = unit->content; - err = cbs_h265_read_pps(ctx, &bc, pps); + err = cbs_h265_read_pps(ctx, &gbc, pps); if (err < 0) return err; - err = cbs_h265_replace_pps(ctx, pps); + err = cbs_h265_replace_pps(ctx, unit); if (err < 0) return err; } @@ -918,11 +974,11 @@ static int cbs_h265_read_nal_unit(CodedBitstreamContext *ctx, return err; slice = unit->content; - err = cbs_h265_read_slice_segment_header(ctx, &bc, &slice->header); + err = cbs_h265_read_slice_segment_header(ctx, &gbc, &slice->header); if (err < 0) return err; - pos = bitstream_tell(&bc); + pos = get_bits_count(&gbc); len = unit->data_size; if (!unit->data[len - 1]) { int z; @@ -933,15 +989,10 @@ static int cbs_h265_read_nal_unit(CodedBitstreamContext *ctx, } slice->data_size = len - pos / 8; - slice->data_ref = av_buffer_alloc(slice->data_size + - AV_INPUT_BUFFER_PADDING_SIZE); + slice->data_ref = av_buffer_ref(unit->data_ref); if (!slice->data_ref) return AVERROR(ENOMEM); - slice->data = slice->data_ref->data; - memcpy(slice->data, - unit->data + pos / 8, slice->data_size); - memset(slice->data + slice->data_size, 0, - AV_INPUT_BUFFER_PADDING_SIZE); + slice->data = unit->data + pos / 8; slice->data_bit_start = pos % 8; } break; @@ -953,7 +1004,22 @@ static int cbs_h265_read_nal_unit(CodedBitstreamContext *ctx, if (err < 0) return err; - err = cbs_h265_read_aud(ctx, &bc, unit->content); + err = cbs_h265_read_aud(ctx, &gbc, unit->content); + if (err < 0) + return err; + } + break; + + case HEVC_NAL_SEI_PREFIX: + { + err = ff_cbs_alloc_unit_content(ctx, unit, sizeof(H265RawSEI), + &cbs_h265_free_sei); + + if (err < 0) + return err; + + err = cbs_h265_read_sei(ctx, &gbc, unit->content); + if (err < 0) return err; } @@ -981,7 +1047,7 @@ static int cbs_h264_write_nal_unit(CodedBitstreamContext *ctx, if (err < 0) return err; - err = cbs_h264_replace_sps(ctx, sps); + err = cbs_h264_replace_sps(ctx, unit); if (err < 0) return err; } @@ -1005,7 +1071,7 @@ static int cbs_h264_write_nal_unit(CodedBitstreamContext *ctx, if (err < 0) return err; - err = cbs_h264_replace_pps(ctx, pps); + err = cbs_h264_replace_pps(ctx, unit); if (err < 0) return err; } @@ -1016,7 +1082,7 @@ static int cbs_h264_write_nal_unit(CodedBitstreamContext *ctx, case H264_NAL_AUXILIARY_SLICE: { H264RawSlice *slice = unit->content; - BitstreamContext bc; + GetBitContext gbc; int bits_left, end, zeroes; err = cbs_h264_write_slice_header(ctx, pbc, &slice->header); @@ -1027,16 +1093,16 @@ static int cbs_h264_write_nal_unit(CodedBitstreamContext *ctx, if (slice->data_size * 8 + 8 > put_bits_left(pbc)) return AVERROR(ENOSPC); - bitstream_init(&bc, slice->data, slice->data_size * 8); - bitstream_skip(&bc, slice->data_bit_start); + init_get_bits(&gbc, slice->data, slice->data_size * 8); + skip_bits_long(&gbc, slice->data_bit_start); // Copy in two-byte blocks, but stop before copying the // rbsp_stop_one_bit in the final byte. - while (bitstream_bits_left(&bc) > 23) - put_bits(pbc, 16, bitstream_read(&bc, 16)); + while (get_bits_left(&gbc) > 23) + put_bits(pbc, 16, get_bits(&gbc, 16)); - bits_left = bitstream_bits_left(&bc); - end = bitstream_read(&bc, bits_left); + bits_left = get_bits_left(&gbc); + end = get_bits(&gbc, bits_left); // rbsp_stop_one_bit must be present here. av_assert0(end); @@ -1070,6 +1136,14 @@ static int cbs_h264_write_nal_unit(CodedBitstreamContext *ctx, } break; + case H264_NAL_FILLER_DATA: + { + err = cbs_h264_write_filler(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); @@ -1094,7 +1168,7 @@ static int cbs_h265_write_nal_unit(CodedBitstreamContext *ctx, if (err < 0) return err; - err = cbs_h265_replace_vps(ctx, vps); + err = cbs_h265_replace_vps(ctx, unit); if (err < 0) return err; } @@ -1108,7 +1182,7 @@ static int cbs_h265_write_nal_unit(CodedBitstreamContext *ctx, if (err < 0) return err; - err = cbs_h265_replace_sps(ctx, sps); + err = cbs_h265_replace_sps(ctx, unit); if (err < 0) return err; } @@ -1122,7 +1196,7 @@ static int cbs_h265_write_nal_unit(CodedBitstreamContext *ctx, if (err < 0) return err; - err = cbs_h265_replace_pps(ctx, pps); + err = cbs_h265_replace_pps(ctx, unit); if (err < 0) return err; } @@ -1146,7 +1220,7 @@ static int cbs_h265_write_nal_unit(CodedBitstreamContext *ctx, case HEVC_NAL_CRA_NUT: { H265RawSlice *slice = unit->content; - BitstreamContext bc; + GetBitContext gbc; int bits_left, end, zeroes; err = cbs_h265_write_slice_segment_header(ctx, pbc, &slice->header); @@ -1157,16 +1231,16 @@ static int cbs_h265_write_nal_unit(CodedBitstreamContext *ctx, if (slice->data_size * 8 + 8 > put_bits_left(pbc)) return AVERROR(ENOSPC); - bitstream_init(&bc, slice->data, slice->data_size * 8); - bitstream_skip(&bc, slice->data_bit_start); + init_get_bits(&gbc, slice->data, slice->data_size * 8); + skip_bits_long(&gbc, slice->data_bit_start); // Copy in two-byte blocks, but stop before copying the // rbsp_stop_one_bit in the final byte. - while (bitstream_bits_left(&bc) > 23) - put_bits(pbc, 16, bitstream_read(&bc, 16)); + while (get_bits_left(&gbc) > 23) + put_bits(pbc, 16, get_bits(&gbc, 16)); - bits_left = bitstream_bits_left(&bc); - end = bitstream_read(&bc, bits_left); + bits_left = get_bits_left(&gbc); + end = get_bits(&gbc, bits_left); // rbsp_stop_one_bit must be present here. av_assert0(end); @@ -1191,6 +1265,15 @@ static int cbs_h265_write_nal_unit(CodedBitstreamContext *ctx, } break; + case HEVC_NAL_SEI_PREFIX: + { + err = cbs_h265_write_sei(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); @@ -1217,7 +1300,7 @@ static int cbs_h2645_write_nal_unit(CodedBitstreamContext *ctx, if (err < 0) { av_log(ctx->log_ctx, AV_LOG_ERROR, "Unable to allocate a " "sufficiently large write buffer (last attempt " - "%zu bytes).\n", priv->write_buffer_size); + "%"SIZE_SPECIFIER" bytes).\n", priv->write_buffer_size); return err; } } @@ -1277,7 +1360,7 @@ static int cbs_h2645_assemble_fragment(CodedBitstreamContext *ctx, max_size += 3 + frag->units[i].data_size * 3 / 2; } - data = av_malloc(max_size); + data = av_malloc(max_size + AV_INPUT_BUFFER_PADDING_SIZE); if (!data) return AVERROR(ENOMEM); @@ -1328,11 +1411,13 @@ static int cbs_h2645_assemble_fragment(CodedBitstreamContext *ctx, } av_assert0(dp <= max_size); - err = av_reallocp(&data, dp); + 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, NULL, NULL, 0); + 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); @@ -1354,9 +1439,9 @@ static void cbs_h264_close(CodedBitstreamContext *ctx) av_freep(&h264->common.write_buffer); for (i = 0; i < FF_ARRAY_ELEMS(h264->sps); i++) - av_freep(&h264->sps[i]); + av_buffer_unref(&h264->sps_ref[i]); for (i = 0; i < FF_ARRAY_ELEMS(h264->pps); i++) - av_freep(&h264->pps[i]); + av_buffer_unref(&h264->pps_ref[i]); } static void cbs_h265_close(CodedBitstreamContext *ctx) @@ -1369,11 +1454,11 @@ static void cbs_h265_close(CodedBitstreamContext *ctx) av_freep(&h265->common.write_buffer); for (i = 0; i < FF_ARRAY_ELEMS(h265->vps); i++) - av_freep(&h265->vps[i]); + av_buffer_unref(&h265->vps_ref[i]); for (i = 0; i < FF_ARRAY_ELEMS(h265->sps); i++) - av_freep(&h265->sps[i]); + av_buffer_unref(&h265->sps_ref[i]); for (i = 0; i < FF_ARRAY_ELEMS(h265->pps); i++) - av_freep(&h265->pps[i]); + av_buffer_unref(&h265->pps_ref[i]); } const CodedBitstreamType ff_cbs_type_h264 = {