File: hevc_vps.go

package info (click to toggle)
fq 0.9.0-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 106,624 kB
  • sloc: xml: 2,835; makefile: 250; sh: 241; exp: 57; ansic: 21
file content (76 lines) | stat: -rw-r--r-- 2,443 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
package mpeg

// https://www.itu.int/rec/T-REC-H.265

import (
	"github.com/wader/fq/format"
	"github.com/wader/fq/pkg/decode"
	"github.com/wader/fq/pkg/interp"
)

func init() {
	interp.RegisterFormat(
		format.HEVC_VPS,
		&decode.Format{
			Description: "H.265/HEVC Video Parameter Set",
			DecodeFn:    hevcVPSDecode,
		})
}

const maxVpsLayers = 1000

// H.265 page 33
func hevcVPSDecode(d *decode.D) any {
	d.FieldU4("vps_video_parameter_set_id")
	d.FieldBool("vps_base_layer_internal_flag")
	d.FieldBool("vps_base_layer_available_flag")
	d.FieldU6("vps_max_layers_minus1")
	vpsMaxSubLayersMinus1 := d.FieldU3("vps_max_sub_layers_minus1")
	d.FieldBool("vps_temporal_id_nesting_flag")
	d.FieldU16("vps_reserved_0xffff_16bits")
	profileTierLevelDecode(d, true, vpsMaxSubLayersMinus1)
	vpsSubLayerOrderingInfoPresentFlag := d.FieldBool("vps_sub_layer_ordering_info_present_flag")
	d.FieldArray("vps_sub_layer_ordering_infos", func(d *decode.D) {
		i := vpsMaxSubLayersMinus1
		if vpsSubLayerOrderingInfoPresentFlag {
			i = 0
		}
		for ; i <= vpsMaxSubLayersMinus1; i++ {
			d.FieldStruct("sps_sub_layer_ordering_info", func(d *decode.D) {
				d.FieldUintFn("sps_max_dec_pic_buffering_minus1", uEV)
				d.FieldUintFn("sps_max_num_reorder_pics", uEV)
				d.FieldUintFn("sps_max_latency_increase_plus1", uEV)
			})
		}
	})
	vpsMaxLayerID := d.FieldU6("vps_max_layer_id")
	vpsNumLayerSetsMinus1 := d.FieldUintFn("vps_num_layer_sets_minus1", uEV)
	if vpsNumLayerSetsMinus1 > maxVpsLayers {
		d.Errorf("too many vps layers %d > %d", vpsNumLayerSetsMinus1, maxVpsLayers)
	}
	d.FieldArray("layer_id_included_sets_flags", func(d *decode.D) {
		for i := uint64(0); i <= vpsNumLayerSetsMinus1; i++ {
			d.FieldArray("layer_id_included_sets_flags", func(d *decode.D) {
				for j := uint64(0); j <= vpsMaxLayerID; j++ {
					d.FieldBool("layer_id_included_flag_sets_flag")
				}
			})
		}
	})
	vpsTimingInfoPresentFlag := d.FieldBool("vps_timing_info_present_flag")
	if vpsTimingInfoPresentFlag {
		d.FieldU32("vps_num_units_in_tick")
		d.FieldU32("vps_time_scale")
		vpsPocProportionalToTimingFlag := d.FieldBool("vps_poc_proportional_to_timing_flag")
		if vpsPocProportionalToTimingFlag {
			d.FieldUintFn("vps_num_ticks_poc_diff_one_minus1", uEV)
		}
		vpsHrdParametersPresentFlag := d.FieldBool("vps_hrd_parameters_present_flag")
		if vpsHrdParametersPresentFlag {
			hevcHrdParameters(d, true, vpsMaxSubLayersMinus1)
		}
	}
	// TODO:

	return nil
}