Skip to content

Commit 09f9c49

Browse files
xaionaro@dx.centerxaionaro@dx.center
authored andcommitted
feat(camera): generate missing Camera2 APIs
1 parent 1d0ecce commit 09f9c49

13 files changed

Lines changed: 717 additions & 63 deletions

File tree

camera/metadata.go

Lines changed: 23 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

camera/session_output.go

Lines changed: 10 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

capi/camera/bridge_c.go

Lines changed: 57 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

capi/camera/cgo_helpers.go

Lines changed: 10 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

spec/generated/camera.yaml

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2313,6 +2313,7 @@ functions:
23132313
type: '*ACameraMetadata'
23142314
- name: numEntries
23152315
type: '*int32'
2316+
direction: out
23162317
- name: tags
23172318
type: '**uint32'
23182319
direction: out
@@ -2326,6 +2327,7 @@ functions:
23262327
type: uint32
23272328
- name: entry
23282329
type: '*ACameraMetadata_const_entry'
2330+
direction: out
23292331
returns: camera_status_t
23302332
ACameraMetadata_getTagFromName:
23312333
c_name: ACameraMetadata_getTagFromName
@@ -2390,6 +2392,7 @@ functions:
23902392
type: '*ACaptureRequest'
23912393
- name: numTags
23922394
type: '*int32'
2395+
direction: out
23932396
- name: tags
23942397
type: '**uint32'
23952398
direction: out
@@ -3328,6 +3331,19 @@ structs:
33283331
type: uint32
33293332
- name: data
33303333
type: union
3334+
fields:
3335+
- name: u8
3336+
type: '*uint8'
3337+
- name: i32
3338+
type: '*int32'
3339+
- name: f
3340+
type: '*float32'
3341+
- name: i64
3342+
type: '*int64'
3343+
- name: d
3344+
type: '*float64'
3345+
- name: r
3346+
type: '*ACameraMetadata_rational'
33313347
ACameraMetadata_entry:
33323348
fields:
33333349
- name: tag
@@ -3338,6 +3354,19 @@ structs:
33383354
type: uint32
33393355
- name: data
33403356
type: union
3357+
fields:
3358+
- name: u8
3359+
type: '*uint8'
3360+
- name: i32
3361+
type: '*int32'
3362+
- name: f
3363+
type: '*float32'
3364+
- name: i64
3365+
type: '*int64'
3366+
- name: d
3367+
type: '*float64'
3368+
- name: r
3369+
type: '*ACameraMetadata_rational'
33413370
ACameraMetadata_rational:
33423371
fields:
33433372
- name: numerator

spec/overlays/camera.yaml

Lines changed: 0 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -135,35 +135,6 @@ extra_enums:
135135
- name: ACAMERA_SCALER_AVAILABLE_STREAM_CONFIGURATIONS
136136
value: 851978
137137

138-
extra_bridge_c: |
139-
static inline int32_t bridge_metadataI32Count(
140-
const ACameraMetadata* metadata, uint32_t tag
141-
) {
142-
ACameraMetadata_const_entry entry;
143-
if (ACameraMetadata_getConstEntry(metadata, tag, &entry) != ACAMERA_OK) return 0;
144-
return (int32_t)entry.count;
145-
}
146-
147-
static inline int32_t bridge_metadataI32At(
148-
const ACameraMetadata* metadata, uint32_t tag, int32_t idx
149-
) {
150-
ACameraMetadata_const_entry entry;
151-
if (ACameraMetadata_getConstEntry(metadata, tag, &entry) != ACAMERA_OK) return 0;
152-
if ((uint32_t)idx >= entry.count) return 0;
153-
return entry.data.i32[idx];
154-
}
155-
156-
extra_bridge_go: |
157-
// BridgeMetadataI32Count returns the count of i32 values for a metadata tag.
158-
func BridgeMetadataI32Count(metadata *ACameraMetadata, tag uint32) int32 {
159-
return int32(C.bridge_metadataI32Count((*C.ACameraMetadata)(unsafe.Pointer(metadata)), C.uint32_t(tag)))
160-
}
161-
162-
// BridgeMetadataI32At returns the i32 value at the given index for a metadata tag.
163-
func BridgeMetadataI32At(metadata *ACameraMetadata, tag uint32, idx int32) int32 {
164-
return int32(C.bridge_metadataI32At((*C.ACameraMetadata)(unsafe.Pointer(metadata)), C.uint32_t(tag), C.int32_t(idx)))
165-
}
166-
167138
functions:
168139
# Manager functions
169140
ACameraManager_getCameraCharacteristics:
@@ -176,26 +147,6 @@ functions:
176147
go_name: CameraIDList
177148
returns_list_struct: ACameraIdList
178149

179-
# Metadata bridge functions (defined in extra_bridge_go, not in spec)
180-
BridgeMetadataI32Count:
181-
receiver: Metadata
182-
go_name: I32Count
183-
pure: true
184-
bridge_params:
185-
- {name: metadata, type: "*ACameraMetadata"}
186-
- {name: tag, type: uint32}
187-
bridge_returns: int32
188-
189-
BridgeMetadataI32At:
190-
receiver: Metadata
191-
go_name: I32At
192-
pure: true
193-
bridge_params:
194-
- {name: metadata, type: "*ACameraMetadata"}
195-
- {name: tag, type: uint32}
196-
- {name: idx, type: int32}
197-
bridge_returns: int32
198-
199150
ACameraManager_deleteCameraIdList:
200151
skip: true
201152

tools/pkg/c2ffi/callback.go

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"regexp"
77
"strings"
88

9+
"github.com/AndroidGoLab/ndk/tools/pkg/specgen"
910
"github.com/AndroidGoLab/ndk/tools/pkg/specmodel"
1011
)
1112

@@ -97,6 +98,42 @@ func supplementCallbacks(
9798
}
9899
}
99100

101+
func supplementFunctionParams(
102+
spec *specmodel.Spec,
103+
headerDirs []string,
104+
) {
105+
for _, dir := range headerDirs {
106+
funcs, err := specgen.ParseFunctionsFromDir(dir)
107+
if err != nil {
108+
continue
109+
}
110+
for name, headerFunc := range funcs {
111+
specFunc, ok := spec.Functions[name]
112+
if !ok {
113+
continue
114+
}
115+
if len(specFunc.Params) != len(headerFunc.Params) {
116+
continue
117+
}
118+
for idx := range specFunc.Params {
119+
if specFunc.Params[idx].Name != headerFunc.Params[idx].Name {
120+
continue
121+
}
122+
if specFunc.Params[idx].Type != headerFunc.Params[idx].Type {
123+
continue
124+
}
125+
if headerFunc.Params[idx].Direction != "" {
126+
specFunc.Params[idx].Direction = headerFunc.Params[idx].Direction
127+
}
128+
if headerFunc.Params[idx].Const {
129+
specFunc.Params[idx].Const = true
130+
}
131+
}
132+
spec.Functions[name] = specFunc
133+
}
134+
}
135+
}
136+
100137
func isBuiltinGoType(t string) bool {
101138
switch t {
102139
case "int8", "uint8", "int16", "uint16",

tools/pkg/c2ffi/tospec.go

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,7 @@ func Convert(
130130
// Supplement callback params from C headers.
131131
if len(opts.NDKHeaderDirs) > 0 {
132132
supplementCallbacks(spec, opts.NDKHeaderDirs)
133+
supplementFunctionParams(spec, opts.NDKHeaderDirs)
133134
}
134135

135136
// Extract #define macro constants from original headers.
@@ -343,6 +344,9 @@ func addStruct(spec *specmodel.Spec, d *Declaration) {
343344
// Mark as func_ptr; params/returns will be filled by
344345
// supplementCallbacks from the C header source.
345346
sf.Type = "func_ptr"
347+
} else if isInlineAggregate(f.Type) {
348+
sf.Type = f.Type.Tag
349+
sf.Fields = convertInlineAggregateFields(f.Type.Fields)
346350
} else {
347351
sf.Type = typeRefToGoType(f.Type)
348352
}
@@ -355,6 +359,41 @@ func addStruct(spec *specmodel.Spec, d *Declaration) {
355359
}
356360
}
357361

362+
func isInlineAggregate(t *TypeRef) bool {
363+
if t == nil {
364+
return false
365+
}
366+
switch t.Tag {
367+
case "union", ":union", "struct", ":struct":
368+
return len(t.Fields) > 0
369+
default:
370+
return false
371+
}
372+
}
373+
374+
func convertInlineAggregateFields(fields []Field) []specmodel.StructField {
375+
result := make([]specmodel.StructField, 0, len(fields))
376+
for _, f := range fields {
377+
if f.Tag != "field" || f.Type == nil {
378+
continue
379+
}
380+
381+
sf := specmodel.StructField{
382+
Name: f.Name,
383+
}
384+
if f.Type.Tag == ":function-pointer" {
385+
sf.Type = "func_ptr"
386+
} else if isInlineAggregate(f.Type) {
387+
sf.Type = f.Type.Tag
388+
sf.Fields = convertInlineAggregateFields(f.Type.Fields)
389+
} else {
390+
sf.Type = typeRefToGoType(f.Type)
391+
}
392+
result = append(result, sf)
393+
}
394+
return result
395+
}
396+
358397
// typeRefToGoType converts a c2ffi TypeRef to a Go type string.
359398
func typeRefToGoType(t *TypeRef) string {
360399
if t == nil {

0 commit comments

Comments
 (0)