| 
				
				
					
				
				
				 | 
			
			 | 
			@@ -1050,6 +1050,64 @@ static int cbs_h265_read_nal_unit(CodedBitstreamContext *ctx, | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    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 && | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			               8 * data_size > data_bit_start); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    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) | 
		
		
	
	
		
			
				| 
				
					
				
				
					
				
				
				 | 
			
			 | 
			@@ -1100,37 +1158,17 @@ static int cbs_h264_write_nal_unit(CodedBitstreamContext *ctx, | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    case H264_NAL_AUXILIARY_SLICE: | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            H264RawSlice *slice = unit->content; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            GetBitContext gbc; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            int bits_left, end, zeroes; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            err = cbs_h264_write_slice_header(ctx, pbc, &slice->header); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            if (err < 0) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                return err; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            if (slice->data) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                if (slice->data_size * 8 + 8 > put_bits_left(pbc)) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                    return AVERROR(ENOSPC); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                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 (get_bits_left(&gbc) > 23) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                    put_bits(pbc, 16, get_bits(&gbc, 16)); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                bits_left = get_bits_left(&gbc); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                end = get_bits(&gbc, bits_left); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                // rbsp_stop_one_bit must be present here. | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                av_assert0(end); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                zeroes = ff_ctz(end); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                if (bits_left > zeroes + 1) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                    put_bits(pbc, bits_left - zeroes - 1, | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                             end >> (zeroes + 1)); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                put_bits(pbc, 1, 1); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                while (put_bits_count(pbc) % 8 != 0) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                    put_bits(pbc, 1, 0); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                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!) | 
		
		
	
	
		
			
				| 
				
					
				
				
					
				
				
				 | 
			
			 | 
			@@ -1254,37 +1292,17 @@ static int cbs_h265_write_nal_unit(CodedBitstreamContext *ctx, | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    case HEVC_NAL_CRA_NUT: | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            H265RawSlice *slice = unit->content; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            GetBitContext gbc; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            int bits_left, end, zeroes; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            err = cbs_h265_write_slice_segment_header(ctx, pbc, &slice->header); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            if (err < 0) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                return err; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            if (slice->data) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                if (slice->data_size * 8 + 8 > put_bits_left(pbc)) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                    return AVERROR(ENOSPC); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                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 (get_bits_left(&gbc) > 23) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                    put_bits(pbc, 16, get_bits(&gbc, 16)); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                bits_left = get_bits_left(&gbc); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                end = get_bits(&gbc, bits_left); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                // rbsp_stop_one_bit must be present here. | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                av_assert0(end); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                zeroes = ff_ctz(end); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                if (bits_left > zeroes + 1) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                    put_bits(pbc, bits_left - zeroes - 1, | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                             end >> (zeroes + 1)); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                put_bits(pbc, 1, 1); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                while (put_bits_count(pbc) % 8 != 0) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                    put_bits(pbc, 1, 0); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                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. | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            } | 
		
		
	
	
		
			
				| 
				
					
				
				
				
				 | 
			
			 | 
			
  |