1
1
mirror of https://github.com/wader/fq.git synced 2024-12-18 10:52:44 +03:00
fq/format/mpeg/avc_sei.go
2021-09-12 13:08:50 +02:00

119 lines
4.5 KiB
Go

package mpeg
import (
"github.com/wader/fq/format"
"github.com/wader/fq/format/registry"
"github.com/wader/fq/pkg/decode"
)
func init() {
registry.MustRegister(&decode.Format{
Name: format.AVC_SEI,
Description: "H.264/AVC Supplemental Enhancement Information",
DecodeFn: avcSEIDecode,
})
}
const (
avcSEIUserDataUnregistered = 5
)
var seiNames = map[uint64]string{
0: "buffering_period",
1: "pic_timing",
2: "pan_scan_rect",
3: "filler_payload",
4: "user_data_registered_itu_t_t35",
avcSEIUserDataUnregistered: "user_data_unregistered",
6: "recovery_point",
7: "dec_ref_pic_marking_repetition",
8: "spare_pic",
9: "scene_info",
10: "sub_seq_info",
11: "sub_seq_layer_characteristics",
12: "sub_seq_characteristics",
13: "full_frame_freeze",
14: "full_frame_freeze_release",
15: "full_frame_snapshot",
16: "progressive_refinement_segment_start",
17: "progressive_refinement_segment_end",
18: "motion_constrained_slice_group_set",
19: "film_grain_characteristics",
20: "deblocking_filter_display_preference",
21: "stereo_video_info",
22: "post_filter_hint",
23: "tone_mapping_info",
24: "scalability_info",
25: "sub_pic_scalable_layer",
26: "non_required_layer_rep",
27: "priority_layer_info",
28: "layers_not_present",
29: "layer_dependency_change",
30: "scalable_nesting",
31: "base_layer_temporal_hrd",
32: "quality_layer_integrity_check",
33: "redundant_pic_property",
34: "tl0_dep_rep_index",
35: "tl_switching_point",
36: "parallel_decoding_info",
37: "mvc_scalable_nesting",
38: "view_scalability_info",
39: "multiview_scene_info",
40: "multiview_acquisition_info",
41: "non_required_view_component",
42: "view_dependency_change",
43: "operation_points_not_present",
44: "base_view_temporal_hrd",
45: "frame_packing_arrangement",
46: "multiview_view_position",
47: "display_orientation",
48: "mvcd_scalable_nesting",
49: "mvcd_view_scalability_info",
50: "depth_representation_info",
51: "three_dimensional_reference_displays_info",
52: "depth_timing",
53: "depth_sampling_info",
54: "constrained_depth_parameter_set_identifier",
56: "green_metadata",
137: "mastering_display_colour_volume",
181: "alternative_depth_info",
}
var userDataUnregisteredNames = map[[16]byte]string{
{0xdc, 0x45, 0xe9, 0xbd, 0xe6, 0xd9, 0x48, 0xb7, 0x96, 0x2c, 0xd8, 0x20, 0xd9, 0x23, 0xee, 0xef}: "x264",
}
// sum bytes until < 0xff
func ffSum(d *decode.D) uint64 {
var s uint64
for {
b := d.U8()
s += b
if b < 0xff {
break
}
}
return s
}
func avcSEIDecode(d *decode.D, in interface{}) interface{} {
payloadType, _ := d.FieldStringMapFn("payload_type", seiNames, "Unknown", func() uint64 { return ffSum(d) }, decode.NumberDecimal)
payloadSize := d.FieldUFn("payload_size", func() (uint64, decode.DisplayFormat, string) {
return ffSum(d), decode.NumberDecimal, ""
})
d.DecodeLenFn(int64(payloadSize)*8, func(d *decode.D) {
switch payloadType {
case avcSEIUserDataUnregistered:
d.FieldStringUUIDMapFn("uuid", userDataUnregisteredNames, "Unknown", func() []byte { return d.BytesLen(16) })
d.FieldBytesLen("data", int(d.BitsLeft()/8))
default:
d.FieldBitBufLen("data", d.BitsLeft())
}
})
d.FieldBitBufLen("rbsp_trailing_bits", d.BitsLeft())
return nil
}