mirror of
				https://github.com/superseriousbusiness/gotosocial.git
				synced 2025-10-31 02:22:26 -05:00 
			
		
		
		
	[feature] Enable basic video support (mp4 only) (#1274)
* [feature] basic video support * fix missing semicolon * replace text shadow with stacked icons Co-authored-by: f0x <f0x@cthu.lu>
This commit is contained in:
		
					parent
					
						
							
								0f38e7c9b0
							
						
					
				
			
			
				commit
				
					
						2bbc64be43
					
				
			
		
					 39 changed files with 6276 additions and 93 deletions
				
			
		
							
								
								
									
										290
									
								
								vendor/github.com/abema/go-mp4/field.go
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										290
									
								
								vendor/github.com/abema/go-mp4/field.go
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,290 @@ | |||
| package mp4 | ||||
| 
 | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"os" | ||||
| 	"reflect" | ||||
| 	"sort" | ||||
| 	"strconv" | ||||
| 	"strings" | ||||
| ) | ||||
| 
 | ||||
| type ( | ||||
| 	stringType uint8 | ||||
| 	fieldFlag  uint16 | ||||
| ) | ||||
| 
 | ||||
| const ( | ||||
| 	stringType_C stringType = iota | ||||
| 	stringType_C_P | ||||
| 
 | ||||
| 	fieldString        fieldFlag = 1 << iota // 0 | ||||
| 	fieldExtend                              // 1 | ||||
| 	fieldDec                                 // 2 | ||||
| 	fieldHex                                 // 3 | ||||
| 	fieldISO639_2                            // 4 | ||||
| 	fieldUUID                                // 5 | ||||
| 	fieldHidden                              // 6 | ||||
| 	fieldOptDynamic                          // 7 | ||||
| 	fieldVarint                              // 8 | ||||
| 	fieldSizeDynamic                         // 9 | ||||
| 	fieldLengthDynamic                       // 10 | ||||
| ) | ||||
| 
 | ||||
| type field struct { | ||||
| 	children []*field | ||||
| 	name     string | ||||
| 	cnst     string | ||||
| 	order    int | ||||
| 	optFlag  uint32 | ||||
| 	nOptFlag uint32 | ||||
| 	size     uint | ||||
| 	length   uint | ||||
| 	flags    fieldFlag | ||||
| 	strType  stringType | ||||
| 	version  uint8 | ||||
| 	nVersion uint8 | ||||
| } | ||||
| 
 | ||||
| func (f *field) set(flag fieldFlag) { | ||||
| 	f.flags |= flag | ||||
| } | ||||
| 
 | ||||
| func (f *field) is(flag fieldFlag) bool { | ||||
| 	return f.flags&flag != 0 | ||||
| } | ||||
| 
 | ||||
| func buildFields(box IImmutableBox) []*field { | ||||
| 	t := reflect.TypeOf(box).Elem() | ||||
| 	return buildFieldsStruct(t) | ||||
| } | ||||
| 
 | ||||
| func buildFieldsStruct(t reflect.Type) []*field { | ||||
| 	fs := make([]*field, 0, 8) | ||||
| 	for i := 0; i < t.NumField(); i++ { | ||||
| 		ft := t.Field(i).Type | ||||
| 		tag, ok := t.Field(i).Tag.Lookup("mp4") | ||||
| 		if !ok { | ||||
| 			continue | ||||
| 		} | ||||
| 		f := buildField(t.Field(i).Name, tag) | ||||
| 		f.children = buildFieldsAny(ft) | ||||
| 		fs = append(fs, f) | ||||
| 	} | ||||
| 	sort.SliceStable(fs, func(i, j int) bool { | ||||
| 		return fs[i].order < fs[j].order | ||||
| 	}) | ||||
| 	return fs | ||||
| } | ||||
| 
 | ||||
| func buildFieldsAny(t reflect.Type) []*field { | ||||
| 	switch t.Kind() { | ||||
| 	case reflect.Struct: | ||||
| 		return buildFieldsStruct(t) | ||||
| 	case reflect.Ptr, reflect.Array, reflect.Slice: | ||||
| 		return buildFieldsAny(t.Elem()) | ||||
| 	default: | ||||
| 		return nil | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func buildField(fieldName string, tag string) *field { | ||||
| 	f := &field{ | ||||
| 		name: fieldName, | ||||
| 	} | ||||
| 	tagMap := parseFieldTag(tag) | ||||
| 	for key, val := range tagMap { | ||||
| 		if val != "" { | ||||
| 			continue | ||||
| 		} | ||||
| 		if order, err := strconv.Atoi(key); err == nil { | ||||
| 			f.order = order | ||||
| 			break | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	if val, contained := tagMap["string"]; contained { | ||||
| 		f.set(fieldString) | ||||
| 		if val == "c_p" { | ||||
| 			f.strType = stringType_C_P | ||||
| 			fmt.Fprint(os.Stderr, "go-mp4: string=c_p tag is deprecated!! See https://github.com/abema/go-mp4/issues/76\n") | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	if _, contained := tagMap["varint"]; contained { | ||||
| 		f.set(fieldVarint) | ||||
| 	} | ||||
| 
 | ||||
| 	if val, contained := tagMap["opt"]; contained { | ||||
| 		if val == "dynamic" { | ||||
| 			f.set(fieldOptDynamic) | ||||
| 		} else { | ||||
| 			base := 10 | ||||
| 			if strings.HasPrefix(val, "0x") { | ||||
| 				val = val[2:] | ||||
| 				base = 16 | ||||
| 			} | ||||
| 			opt, err := strconv.ParseUint(val, base, 32) | ||||
| 			if err != nil { | ||||
| 				panic(err) | ||||
| 			} | ||||
| 			f.optFlag = uint32(opt) | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	if val, contained := tagMap["nopt"]; contained { | ||||
| 		base := 10 | ||||
| 		if strings.HasPrefix(val, "0x") { | ||||
| 			val = val[2:] | ||||
| 			base = 16 | ||||
| 		} | ||||
| 		nopt, err := strconv.ParseUint(val, base, 32) | ||||
| 		if err != nil { | ||||
| 			panic(err) | ||||
| 		} | ||||
| 		f.nOptFlag = uint32(nopt) | ||||
| 	} | ||||
| 
 | ||||
| 	if _, contained := tagMap["extend"]; contained { | ||||
| 		f.set(fieldExtend) | ||||
| 	} | ||||
| 
 | ||||
| 	if _, contained := tagMap["dec"]; contained { | ||||
| 		f.set(fieldDec) | ||||
| 	} | ||||
| 
 | ||||
| 	if _, contained := tagMap["hex"]; contained { | ||||
| 		f.set(fieldHex) | ||||
| 	} | ||||
| 
 | ||||
| 	if _, contained := tagMap["iso639-2"]; contained { | ||||
| 		f.set(fieldISO639_2) | ||||
| 	} | ||||
| 
 | ||||
| 	if _, contained := tagMap["uuid"]; contained { | ||||
| 		f.set(fieldUUID) | ||||
| 	} | ||||
| 
 | ||||
| 	if _, contained := tagMap["hidden"]; contained { | ||||
| 		f.set(fieldHidden) | ||||
| 	} | ||||
| 
 | ||||
| 	if val, contained := tagMap["const"]; contained { | ||||
| 		f.cnst = val | ||||
| 	} | ||||
| 
 | ||||
| 	f.version = anyVersion | ||||
| 	if val, contained := tagMap["ver"]; contained { | ||||
| 		ver, err := strconv.Atoi(val) | ||||
| 		if err != nil { | ||||
| 			panic(err) | ||||
| 		} | ||||
| 		f.version = uint8(ver) | ||||
| 	} | ||||
| 
 | ||||
| 	f.nVersion = anyVersion | ||||
| 	if val, contained := tagMap["nver"]; contained { | ||||
| 		ver, err := strconv.Atoi(val) | ||||
| 		if err != nil { | ||||
| 			panic(err) | ||||
| 		} | ||||
| 		f.nVersion = uint8(ver) | ||||
| 	} | ||||
| 
 | ||||
| 	if val, contained := tagMap["size"]; contained { | ||||
| 		if val == "dynamic" { | ||||
| 			f.set(fieldSizeDynamic) | ||||
| 		} else { | ||||
| 			size, err := strconv.ParseUint(val, 10, 32) | ||||
| 			if err != nil { | ||||
| 				panic(err) | ||||
| 			} | ||||
| 			f.size = uint(size) | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	f.length = LengthUnlimited | ||||
| 	if val, contained := tagMap["len"]; contained { | ||||
| 		if val == "dynamic" { | ||||
| 			f.set(fieldLengthDynamic) | ||||
| 		} else { | ||||
| 			l, err := strconv.ParseUint(val, 10, 32) | ||||
| 			if err != nil { | ||||
| 				panic(err) | ||||
| 			} | ||||
| 			f.length = uint(l) | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return f | ||||
| } | ||||
| 
 | ||||
| func parseFieldTag(str string) map[string]string { | ||||
| 	tag := make(map[string]string, 8) | ||||
| 
 | ||||
| 	list := strings.Split(str, ",") | ||||
| 	for _, e := range list { | ||||
| 		kv := strings.SplitN(e, "=", 2) | ||||
| 		if len(kv) == 2 { | ||||
| 			tag[strings.Trim(kv[0], " ")] = strings.Trim(kv[1], " ") | ||||
| 		} else { | ||||
| 			tag[strings.Trim(kv[0], " ")] = "" | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return tag | ||||
| } | ||||
| 
 | ||||
| type fieldInstance struct { | ||||
| 	field | ||||
| 	cfo ICustomFieldObject | ||||
| } | ||||
| 
 | ||||
| func resolveFieldInstance(f *field, box IImmutableBox, parent reflect.Value, ctx Context) *fieldInstance { | ||||
| 	fi := fieldInstance{ | ||||
| 		field: *f, | ||||
| 	} | ||||
| 
 | ||||
| 	cfo, ok := parent.Addr().Interface().(ICustomFieldObject) | ||||
| 	if ok { | ||||
| 		fi.cfo = cfo | ||||
| 	} else { | ||||
| 		fi.cfo = box | ||||
| 	} | ||||
| 
 | ||||
| 	if fi.is(fieldSizeDynamic) { | ||||
| 		fi.size = fi.cfo.GetFieldSize(f.name, ctx) | ||||
| 	} | ||||
| 
 | ||||
| 	if fi.is(fieldLengthDynamic) { | ||||
| 		fi.length = fi.cfo.GetFieldLength(f.name, ctx) | ||||
| 	} | ||||
| 
 | ||||
| 	return &fi | ||||
| } | ||||
| 
 | ||||
| func isTargetField(box IImmutableBox, fi *fieldInstance, ctx Context) bool { | ||||
| 	if box.GetVersion() != anyVersion { | ||||
| 		if fi.version != anyVersion && box.GetVersion() != fi.version { | ||||
| 			return false | ||||
| 		} | ||||
| 
 | ||||
| 		if fi.nVersion != anyVersion && box.GetVersion() == fi.nVersion { | ||||
| 			return false | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	if fi.optFlag != 0 && box.GetFlags()&fi.optFlag == 0 { | ||||
| 		return false | ||||
| 	} | ||||
| 
 | ||||
| 	if fi.nOptFlag != 0 && box.GetFlags()&fi.nOptFlag != 0 { | ||||
| 		return false | ||||
| 	} | ||||
| 
 | ||||
| 	if fi.is(fieldOptDynamic) && !fi.cfo.IsOptFieldEnabled(fi.name, ctx) { | ||||
| 		return false | ||||
| 	} | ||||
| 
 | ||||
| 	return true | ||||
| } | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue