Ver Fonte

Code style

Martijn Braam há 4 anos atrás
pai
commit
72105c9491
20 ficheiros alterados com 3388 adições e 2713 exclusões
  1. 548 0
      .clang-format
  2. 997 933
      camera.c
  3. 37 35
      camera.h
  4. 231 225
      camera_config.c
  5. 30 30
      camera_config.h
  6. 315 275
      device.c
  7. 26 13
      device.h
  8. 113 110
      ini.c
  9. 7 7
      ini.h
  10. 412 377
      io_pipeline.c
  11. 8 8
      io_pipeline.h
  12. 118 106
      main.c
  13. 10 11
      main.h
  14. 7 6
      matrix.c
  15. 72 70
      pipeline.c
  16. 5 2
      pipeline.h
  17. 307 305
      process_pipeline.c
  18. 12 12
      process_pipeline.h
  19. 123 165
      quickpreview.c
  20. 10 23
      quickpreview.h

+ 548 - 0
.clang-format

@@ -0,0 +1,548 @@
+# SPDX-License-Identifier: GPL-2.0
+#
+# clang-format configuration file. Intended for clang-format >= 4.
+#
+# For more information, see:
+#
+#   Documentation/process/clang-format.rst
+#   https://clang.llvm.org/docs/ClangFormat.html
+#   https://clang.llvm.org/docs/ClangFormatStyleOptions.html
+#
+---
+AccessModifierOffset: -4
+AlignAfterOpenBracket: Align
+AlignConsecutiveAssignments: false
+AlignConsecutiveDeclarations: false
+#AlignEscapedNewlines: Left # Unknown to clang-format-4.0
+AlignOperands: true
+AlignTrailingComments: false
+AllowAllParametersOfDeclarationOnNextLine: false
+AllowShortBlocksOnASingleLine: false
+AllowShortCaseLabelsOnASingleLine: false
+AllowShortFunctionsOnASingleLine: None
+AllowShortIfStatementsOnASingleLine: false
+AllowShortLoopsOnASingleLine: false
+AlwaysBreakAfterDefinitionReturnType: All
+AlwaysBreakAfterReturnType: None
+AlwaysBreakBeforeMultilineStrings: false
+AlwaysBreakTemplateDeclarations: false
+BinPackArguments: true
+BinPackParameters: true
+BraceWrapping:
+  AfterClass: false
+  AfterControlStatement: false
+  AfterEnum: false
+  AfterFunction: true
+  AfterNamespace: true
+  AfterObjCDeclaration: false
+  AfterStruct: false
+  AfterUnion: false
+  #AfterExternBlock: false # Unknown to clang-format-5.0
+  BeforeCatch: false
+  BeforeElse: false
+  IndentBraces: false
+  #SplitEmptyFunction: true # Unknown to clang-format-4.0
+  #SplitEmptyRecord: true # Unknown to clang-format-4.0
+  #SplitEmptyNamespace: true # Unknown to clang-format-4.0
+BreakBeforeBinaryOperators: None
+BreakBeforeBraces: Custom
+#BreakBeforeInheritanceComma: false # Unknown to clang-format-4.0
+BreakBeforeTernaryOperators: false
+BreakConstructorInitializersBeforeComma: false
+#BreakConstructorInitializers: BeforeComma # Unknown to clang-format-4.0
+BreakAfterJavaFieldAnnotations: false
+BreakStringLiterals: false
+ColumnLimit: 85
+CommentPragmas: '^ IWYU pragma:'
+#CompactNamespaces: false # Unknown to clang-format-4.0
+ConstructorInitializerAllOnOneLineOrOnePerLine: false
+ConstructorInitializerIndentWidth: 8
+ContinuationIndentWidth: 8
+Cpp11BracedListStyle: false
+DerivePointerAlignment: false
+DisableFormat: false
+ExperimentalAutoDetectBinPacking: false
+#FixNamespaceComments: false # Unknown to clang-format-4.0
+
+# Taken from:
+#   git grep -h '^#define [^[:space:]]*for_each[^[:space:]]*(' include/ \
+#   | sed "s,^#define \([^[:space:]]*for_each[^[:space:]]*\)(.*$,  - '\1'," \
+#   | sort | uniq
+ForEachMacros:
+  - 'apei_estatus_for_each_section'
+  - 'ata_for_each_dev'
+  - 'ata_for_each_link'
+  - '__ata_qc_for_each'
+  - 'ata_qc_for_each'
+  - 'ata_qc_for_each_raw'
+  - 'ata_qc_for_each_with_internal'
+  - 'ax25_for_each'
+  - 'ax25_uid_for_each'
+  - '__bio_for_each_bvec'
+  - 'bio_for_each_bvec'
+  - 'bio_for_each_bvec_all'
+  - 'bio_for_each_integrity_vec'
+  - '__bio_for_each_segment'
+  - 'bio_for_each_segment'
+  - 'bio_for_each_segment_all'
+  - 'bio_list_for_each'
+  - 'bip_for_each_vec'
+  - 'bitmap_for_each_clear_region'
+  - 'bitmap_for_each_set_region'
+  - 'blkg_for_each_descendant_post'
+  - 'blkg_for_each_descendant_pre'
+  - 'blk_queue_for_each_rl'
+  - 'bond_for_each_slave'
+  - 'bond_for_each_slave_rcu'
+  - 'bpf_for_each_spilled_reg'
+  - 'btree_for_each_safe128'
+  - 'btree_for_each_safe32'
+  - 'btree_for_each_safe64'
+  - 'btree_for_each_safel'
+  - 'card_for_each_dev'
+  - 'cgroup_taskset_for_each'
+  - 'cgroup_taskset_for_each_leader'
+  - 'cpufreq_for_each_entry'
+  - 'cpufreq_for_each_entry_idx'
+  - 'cpufreq_for_each_valid_entry'
+  - 'cpufreq_for_each_valid_entry_idx'
+  - 'css_for_each_child'
+  - 'css_for_each_descendant_post'
+  - 'css_for_each_descendant_pre'
+  - 'device_for_each_child_node'
+  - 'dma_fence_chain_for_each'
+  - 'do_for_each_ftrace_op'
+  - 'drm_atomic_crtc_for_each_plane'
+  - 'drm_atomic_crtc_state_for_each_plane'
+  - 'drm_atomic_crtc_state_for_each_plane_state'
+  - 'drm_atomic_for_each_plane_damage'
+  - 'drm_client_for_each_connector_iter'
+  - 'drm_client_for_each_modeset'
+  - 'drm_connector_for_each_possible_encoder'
+  - 'drm_for_each_bridge_in_chain'
+  - 'drm_for_each_connector_iter'
+  - 'drm_for_each_crtc'
+  - 'drm_for_each_encoder'
+  - 'drm_for_each_encoder_mask'
+  - 'drm_for_each_fb'
+  - 'drm_for_each_legacy_plane'
+  - 'drm_for_each_plane'
+  - 'drm_for_each_plane_mask'
+  - 'drm_for_each_privobj'
+  - 'drm_mm_for_each_hole'
+  - 'drm_mm_for_each_node'
+  - 'drm_mm_for_each_node_in_range'
+  - 'drm_mm_for_each_node_safe'
+  - 'flow_action_for_each'
+  - 'for_each_active_dev_scope'
+  - 'for_each_active_drhd_unit'
+  - 'for_each_active_iommu'
+  - 'for_each_aggr_pgid'
+  - 'for_each_available_child_of_node'
+  - 'for_each_bio'
+  - 'for_each_board_func_rsrc'
+  - 'for_each_bvec'
+  - 'for_each_card_auxs'
+  - 'for_each_card_auxs_safe'
+  - 'for_each_card_components'
+  - 'for_each_card_dapms'
+  - 'for_each_card_pre_auxs'
+  - 'for_each_card_prelinks'
+  - 'for_each_card_rtds'
+  - 'for_each_card_rtds_safe'
+  - 'for_each_card_widgets'
+  - 'for_each_card_widgets_safe'
+  - 'for_each_cgroup_storage_type'
+  - 'for_each_child_of_node'
+  - 'for_each_clear_bit'
+  - 'for_each_clear_bit_from'
+  - 'for_each_cmsghdr'
+  - 'for_each_compatible_node'
+  - 'for_each_component_dais'
+  - 'for_each_component_dais_safe'
+  - 'for_each_comp_order'
+  - 'for_each_console'
+  - 'for_each_cpu'
+  - 'for_each_cpu_and'
+  - 'for_each_cpu_not'
+  - 'for_each_cpu_wrap'
+  - 'for_each_dapm_widgets'
+  - 'for_each_dev_addr'
+  - 'for_each_dev_scope'
+  - 'for_each_displayid_db'
+  - 'for_each_dma_cap_mask'
+  - 'for_each_dpcm_be'
+  - 'for_each_dpcm_be_rollback'
+  - 'for_each_dpcm_be_safe'
+  - 'for_each_dpcm_fe'
+  - 'for_each_drhd_unit'
+  - 'for_each_dss_dev'
+  - 'for_each_efi_memory_desc'
+  - 'for_each_efi_memory_desc_in_map'
+  - 'for_each_element'
+  - 'for_each_element_extid'
+  - 'for_each_element_id'
+  - 'for_each_endpoint_of_node'
+  - 'for_each_evictable_lru'
+  - 'for_each_fib6_node_rt_rcu'
+  - 'for_each_fib6_walker_rt'
+  - 'for_each_free_mem_pfn_range_in_zone'
+  - 'for_each_free_mem_pfn_range_in_zone_from'
+  - 'for_each_free_mem_range'
+  - 'for_each_free_mem_range_reverse'
+  - 'for_each_func_rsrc'
+  - 'for_each_hstate'
+  - 'for_each_if'
+  - 'for_each_iommu'
+  - 'for_each_ip_tunnel_rcu'
+  - 'for_each_irq_nr'
+  - 'for_each_link_codecs'
+  - 'for_each_link_cpus'
+  - 'for_each_link_platforms'
+  - 'for_each_lru'
+  - 'for_each_matching_node'
+  - 'for_each_matching_node_and_match'
+  - 'for_each_member'
+  - 'for_each_mem_region'
+  - 'for_each_memblock_type'
+  - 'for_each_memcg_cache_index'
+  - 'for_each_mem_pfn_range'
+  - '__for_each_mem_range'
+  - 'for_each_mem_range'
+  - '__for_each_mem_range_rev'
+  - 'for_each_mem_range_rev'
+  - 'for_each_migratetype_order'
+  - 'for_each_msi_entry'
+  - 'for_each_msi_entry_safe'
+  - 'for_each_net'
+  - 'for_each_net_continue_reverse'
+  - 'for_each_netdev'
+  - 'for_each_netdev_continue'
+  - 'for_each_netdev_continue_rcu'
+  - 'for_each_netdev_continue_reverse'
+  - 'for_each_netdev_feature'
+  - 'for_each_netdev_in_bond_rcu'
+  - 'for_each_netdev_rcu'
+  - 'for_each_netdev_reverse'
+  - 'for_each_netdev_safe'
+  - 'for_each_net_rcu'
+  - 'for_each_new_connector_in_state'
+  - 'for_each_new_crtc_in_state'
+  - 'for_each_new_mst_mgr_in_state'
+  - 'for_each_new_plane_in_state'
+  - 'for_each_new_private_obj_in_state'
+  - 'for_each_node'
+  - 'for_each_node_by_name'
+  - 'for_each_node_by_type'
+  - 'for_each_node_mask'
+  - 'for_each_node_state'
+  - 'for_each_node_with_cpus'
+  - 'for_each_node_with_property'
+  - 'for_each_nonreserved_multicast_dest_pgid'
+  - 'for_each_of_allnodes'
+  - 'for_each_of_allnodes_from'
+  - 'for_each_of_cpu_node'
+  - 'for_each_of_pci_range'
+  - 'for_each_old_connector_in_state'
+  - 'for_each_old_crtc_in_state'
+  - 'for_each_old_mst_mgr_in_state'
+  - 'for_each_oldnew_connector_in_state'
+  - 'for_each_oldnew_crtc_in_state'
+  - 'for_each_oldnew_mst_mgr_in_state'
+  - 'for_each_oldnew_plane_in_state'
+  - 'for_each_oldnew_plane_in_state_reverse'
+  - 'for_each_oldnew_private_obj_in_state'
+  - 'for_each_old_plane_in_state'
+  - 'for_each_old_private_obj_in_state'
+  - 'for_each_online_cpu'
+  - 'for_each_online_node'
+  - 'for_each_online_pgdat'
+  - 'for_each_pci_bridge'
+  - 'for_each_pci_dev'
+  - 'for_each_pci_msi_entry'
+  - 'for_each_pcm_streams'
+  - 'for_each_physmem_range'
+  - 'for_each_populated_zone'
+  - 'for_each_possible_cpu'
+  - 'for_each_present_cpu'
+  - 'for_each_prime_number'
+  - 'for_each_prime_number_from'
+  - 'for_each_process'
+  - 'for_each_process_thread'
+  - 'for_each_property_of_node'
+  - 'for_each_registered_fb'
+  - 'for_each_requested_gpio'
+  - 'for_each_requested_gpio_in_range'
+  - 'for_each_reserved_mem_range'
+  - 'for_each_reserved_mem_region'
+  - 'for_each_rtd_codec_dais'
+  - 'for_each_rtd_codec_dais_rollback'
+  - 'for_each_rtd_components'
+  - 'for_each_rtd_cpu_dais'
+  - 'for_each_rtd_cpu_dais_rollback'
+  - 'for_each_rtd_dais'
+  - 'for_each_set_bit'
+  - 'for_each_set_bit_from'
+  - 'for_each_set_clump8'
+  - 'for_each_sg'
+  - 'for_each_sg_dma_page'
+  - 'for_each_sg_page'
+  - 'for_each_sgtable_dma_page'
+  - 'for_each_sgtable_dma_sg'
+  - 'for_each_sgtable_page'
+  - 'for_each_sgtable_sg'
+  - 'for_each_sibling_event'
+  - 'for_each_subelement'
+  - 'for_each_subelement_extid'
+  - 'for_each_subelement_id'
+  - '__for_each_thread'
+  - 'for_each_thread'
+  - 'for_each_unicast_dest_pgid'
+  - 'for_each_wakeup_source'
+  - 'for_each_zone'
+  - 'for_each_zone_zonelist'
+  - 'for_each_zone_zonelist_nodemask'
+  - 'fwnode_for_each_available_child_node'
+  - 'fwnode_for_each_child_node'
+  - 'fwnode_graph_for_each_endpoint'
+  - 'gadget_for_each_ep'
+  - 'genradix_for_each'
+  - 'genradix_for_each_from'
+  - 'hash_for_each'
+  - 'hash_for_each_possible'
+  - 'hash_for_each_possible_rcu'
+  - 'hash_for_each_possible_rcu_notrace'
+  - 'hash_for_each_possible_safe'
+  - 'hash_for_each_rcu'
+  - 'hash_for_each_safe'
+  - 'hctx_for_each_ctx'
+  - 'hlist_bl_for_each_entry'
+  - 'hlist_bl_for_each_entry_rcu'
+  - 'hlist_bl_for_each_entry_safe'
+  - 'hlist_for_each'
+  - 'hlist_for_each_entry'
+  - 'hlist_for_each_entry_continue'
+  - 'hlist_for_each_entry_continue_rcu'
+  - 'hlist_for_each_entry_continue_rcu_bh'
+  - 'hlist_for_each_entry_from'
+  - 'hlist_for_each_entry_from_rcu'
+  - 'hlist_for_each_entry_rcu'
+  - 'hlist_for_each_entry_rcu_bh'
+  - 'hlist_for_each_entry_rcu_notrace'
+  - 'hlist_for_each_entry_safe'
+  - '__hlist_for_each_rcu'
+  - 'hlist_for_each_safe'
+  - 'hlist_nulls_for_each_entry'
+  - 'hlist_nulls_for_each_entry_from'
+  - 'hlist_nulls_for_each_entry_rcu'
+  - 'hlist_nulls_for_each_entry_safe'
+  - 'i3c_bus_for_each_i2cdev'
+  - 'i3c_bus_for_each_i3cdev'
+  - 'ide_host_for_each_port'
+  - 'ide_port_for_each_dev'
+  - 'ide_port_for_each_present_dev'
+  - 'idr_for_each_entry'
+  - 'idr_for_each_entry_continue'
+  - 'idr_for_each_entry_continue_ul'
+  - 'idr_for_each_entry_ul'
+  - 'in_dev_for_each_ifa_rcu'
+  - 'in_dev_for_each_ifa_rtnl'
+  - 'inet_bind_bucket_for_each'
+  - 'inet_lhash2_for_each_icsk_rcu'
+  - 'key_for_each'
+  - 'key_for_each_safe'
+  - 'klp_for_each_func'
+  - 'klp_for_each_func_safe'
+  - 'klp_for_each_func_static'
+  - 'klp_for_each_object'
+  - 'klp_for_each_object_safe'
+  - 'klp_for_each_object_static'
+  - 'kunit_suite_for_each_test_case'
+  - 'kvm_for_each_memslot'
+  - 'kvm_for_each_vcpu'
+  - 'list_for_each'
+  - 'list_for_each_codec'
+  - 'list_for_each_codec_safe'
+  - 'list_for_each_continue'
+  - 'list_for_each_entry'
+  - 'list_for_each_entry_continue'
+  - 'list_for_each_entry_continue_rcu'
+  - 'list_for_each_entry_continue_reverse'
+  - 'list_for_each_entry_from'
+  - 'list_for_each_entry_from_rcu'
+  - 'list_for_each_entry_from_reverse'
+  - 'list_for_each_entry_lockless'
+  - 'list_for_each_entry_rcu'
+  - 'list_for_each_entry_reverse'
+  - 'list_for_each_entry_safe'
+  - 'list_for_each_entry_safe_continue'
+  - 'list_for_each_entry_safe_from'
+  - 'list_for_each_entry_safe_reverse'
+  - 'list_for_each_prev'
+  - 'list_for_each_prev_safe'
+  - 'list_for_each_safe'
+  - 'llist_for_each'
+  - 'llist_for_each_entry'
+  - 'llist_for_each_entry_safe'
+  - 'llist_for_each_safe'
+  - 'mci_for_each_dimm'
+  - 'media_device_for_each_entity'
+  - 'media_device_for_each_intf'
+  - 'media_device_for_each_link'
+  - 'media_device_for_each_pad'
+  - 'nanddev_io_for_each_page'
+  - 'netdev_for_each_lower_dev'
+  - 'netdev_for_each_lower_private'
+  - 'netdev_for_each_lower_private_rcu'
+  - 'netdev_for_each_mc_addr'
+  - 'netdev_for_each_uc_addr'
+  - 'netdev_for_each_upper_dev_rcu'
+  - 'netdev_hw_addr_list_for_each'
+  - 'nft_rule_for_each_expr'
+  - 'nla_for_each_attr'
+  - 'nla_for_each_nested'
+  - 'nlmsg_for_each_attr'
+  - 'nlmsg_for_each_msg'
+  - 'nr_neigh_for_each'
+  - 'nr_neigh_for_each_safe'
+  - 'nr_node_for_each'
+  - 'nr_node_for_each_safe'
+  - 'of_for_each_phandle'
+  - 'of_property_for_each_string'
+  - 'of_property_for_each_u32'
+  - 'pci_bus_for_each_resource'
+  - 'pcm_for_each_format'
+  - 'ping_portaddr_for_each_entry'
+  - 'plist_for_each'
+  - 'plist_for_each_continue'
+  - 'plist_for_each_entry'
+  - 'plist_for_each_entry_continue'
+  - 'plist_for_each_entry_safe'
+  - 'plist_for_each_safe'
+  - 'pnp_for_each_card'
+  - 'pnp_for_each_dev'
+  - 'protocol_for_each_card'
+  - 'protocol_for_each_dev'
+  - 'queue_for_each_hw_ctx'
+  - 'radix_tree_for_each_slot'
+  - 'radix_tree_for_each_tagged'
+  - 'rbtree_postorder_for_each_entry_safe'
+  - 'rdma_for_each_block'
+  - 'rdma_for_each_port'
+  - 'rdma_umem_for_each_dma_block'
+  - 'resource_list_for_each_entry'
+  - 'resource_list_for_each_entry_safe'
+  - 'rhl_for_each_entry_rcu'
+  - 'rhl_for_each_rcu'
+  - 'rht_for_each'
+  - 'rht_for_each_entry'
+  - 'rht_for_each_entry_from'
+  - 'rht_for_each_entry_rcu'
+  - 'rht_for_each_entry_rcu_from'
+  - 'rht_for_each_entry_safe'
+  - 'rht_for_each_from'
+  - 'rht_for_each_rcu'
+  - 'rht_for_each_rcu_from'
+  - '__rq_for_each_bio'
+  - 'rq_for_each_bvec'
+  - 'rq_for_each_segment'
+  - 'scsi_for_each_prot_sg'
+  - 'scsi_for_each_sg'
+  - 'sctp_for_each_hentry'
+  - 'sctp_skb_for_each'
+  - 'shdma_for_each_chan'
+  - '__shost_for_each_device'
+  - 'shost_for_each_device'
+  - 'sk_for_each'
+  - 'sk_for_each_bound'
+  - 'sk_for_each_entry_offset_rcu'
+  - 'sk_for_each_from'
+  - 'sk_for_each_rcu'
+  - 'sk_for_each_safe'
+  - 'sk_nulls_for_each'
+  - 'sk_nulls_for_each_from'
+  - 'sk_nulls_for_each_rcu'
+  - 'snd_array_for_each'
+  - 'snd_pcm_group_for_each_entry'
+  - 'snd_soc_dapm_widget_for_each_path'
+  - 'snd_soc_dapm_widget_for_each_path_safe'
+  - 'snd_soc_dapm_widget_for_each_sink_path'
+  - 'snd_soc_dapm_widget_for_each_source_path'
+  - 'tb_property_for_each'
+  - 'tcf_exts_for_each_action'
+  - 'udp_portaddr_for_each_entry'
+  - 'udp_portaddr_for_each_entry_rcu'
+  - 'usb_hub_for_each_child'
+  - 'v4l2_device_for_each_subdev'
+  - 'v4l2_m2m_for_each_dst_buf'
+  - 'v4l2_m2m_for_each_dst_buf_safe'
+  - 'v4l2_m2m_for_each_src_buf'
+  - 'v4l2_m2m_for_each_src_buf_safe'
+  - 'virtio_device_for_each_vq'
+  - 'while_for_each_ftrace_op'
+  - 'xa_for_each'
+  - 'xa_for_each_marked'
+  - 'xa_for_each_range'
+  - 'xa_for_each_start'
+  - 'xas_for_each'
+  - 'xas_for_each_conflict'
+  - 'xas_for_each_marked'
+  - 'xbc_array_for_each_value'
+  - 'xbc_for_each_key_value'
+  - 'xbc_node_for_each_array_value'
+  - 'xbc_node_for_each_child'
+  - 'xbc_node_for_each_key_value'
+  - 'zorro_for_each_dev'
+
+#IncludeBlocks: Preserve # Unknown to clang-format-5.0
+IncludeCategories:
+  - Regex: '.*'
+    Priority: 1
+IncludeIsMainRegex: '(Test)?$'
+IndentCaseLabels: false
+#IndentPPDirectives: None # Unknown to clang-format-5.0
+IndentWidth: 8
+IndentWrappedFunctionNames: false
+JavaScriptQuotes: Leave
+JavaScriptWrapImports: true
+KeepEmptyLinesAtTheStartOfBlocks: false
+MacroBlockBegin: ''
+MacroBlockEnd: ''
+MaxEmptyLinesToKeep: 1
+NamespaceIndentation: None
+#ObjCBinPackProtocolList: Auto # Unknown to clang-format-5.0
+ObjCBlockIndentWidth: 8
+ObjCSpaceAfterProperty: true
+ObjCSpaceBeforeProtocolList: true
+
+# Taken from git's rules
+#PenaltyBreakAssignment: 10 # Unknown to clang-format-4.0
+PenaltyBreakBeforeFirstCallParameter: 30
+PenaltyBreakComment: 10
+PenaltyBreakFirstLessLess: 0
+PenaltyBreakString: 10
+PenaltyExcessCharacter: 100
+PenaltyReturnTypeOnItsOwnLine: 60
+
+PointerAlignment: Right
+ReflowComments: false
+SortIncludes: false
+#SortUsingDeclarations: false # Unknown to clang-format-4.0
+SpaceAfterCStyleCast: false
+SpaceAfterTemplateKeyword: true
+SpaceBeforeAssignmentOperators: true
+#SpaceBeforeCtorInitializerColon: true # Unknown to clang-format-5.0
+#SpaceBeforeInheritanceColon: true # Unknown to clang-format-5.0
+SpaceBeforeParens: ControlStatements
+#SpaceBeforeRangeBasedForLoopColon: true # Unknown to clang-format-5.0
+SpaceInEmptyParentheses: false
+SpacesBeforeTrailingComments: 1
+SpacesInAngles: false
+SpacesInContainerLiterals: false
+SpacesInCStyleCastParentheses: false
+SpacesInParentheses: false
+SpacesInSquareBrackets: false
+Standard: Cpp03
+TabWidth: 8
+UseTab: Always
+...

+ 997 - 933
camera.c

@@ -10,1130 +10,1194 @@
 #define MAX_VIDEO_BUFFERS 20
 
 static const char *pixel_format_names[MP_PIXEL_FMT_MAX] = {
-    "unsupported",
-    "BGGR8",
-    "GBRG8",
-    "GRBG8",
-    "RGGB8",
-    "BGGR10P",
-    "GBRG10P",
-    "GRBG10P",
-    "RGGB10P",
-    "UYVY",
-    "YUYV",
+	"unsupported", "BGGR8",	  "GBRG8",   "GRBG8", "RGGB8", "BGGR10P",
+	"GBRG10P",     "GRBG10P", "RGGB10P", "UYVY",  "YUYV",
 };
 
-const char *mp_pixel_format_to_str(uint32_t pixel_format)
+const char *
+mp_pixel_format_to_str(uint32_t pixel_format)
 {
-    g_return_val_if_fail(pixel_format < MP_PIXEL_FMT_MAX, "INVALID");
-    return pixel_format_names[pixel_format];
+	g_return_val_if_fail(pixel_format < MP_PIXEL_FMT_MAX, "INVALID");
+	return pixel_format_names[pixel_format];
 }
 
-MPPixelFormat mp_pixel_format_from_str(const char *name)
+MPPixelFormat
+mp_pixel_format_from_str(const char *name)
 {
-    for (MPPixelFormat i = 0; i < MP_PIXEL_FMT_MAX; ++i) {
-        if (strcasecmp(pixel_format_names[i], name) == 0) {
-            return i;
-        }
-    }
-    g_return_val_if_reached(MP_PIXEL_FMT_UNSUPPORTED);
+	for (MPPixelFormat i = 0; i < MP_PIXEL_FMT_MAX; ++i) {
+		if (strcasecmp(pixel_format_names[i], name) == 0) {
+			return i;
+		}
+	}
+	g_return_val_if_reached(MP_PIXEL_FMT_UNSUPPORTED);
 }
 
 static const uint32_t pixel_format_v4l_pixel_formats[MP_PIXEL_FMT_MAX] = {
-    0,
-    V4L2_PIX_FMT_SBGGR8,
-    V4L2_PIX_FMT_SGBRG8,
-    V4L2_PIX_FMT_SGRBG8,
-    V4L2_PIX_FMT_SRGGB8,
-    V4L2_PIX_FMT_SBGGR10P,
-    V4L2_PIX_FMT_SGBRG10P,
-    V4L2_PIX_FMT_SGRBG10P,
-    V4L2_PIX_FMT_SRGGB10P,
-    V4L2_PIX_FMT_UYVY,
-    V4L2_PIX_FMT_YUYV,
+	0,
+	V4L2_PIX_FMT_SBGGR8,
+	V4L2_PIX_FMT_SGBRG8,
+	V4L2_PIX_FMT_SGRBG8,
+	V4L2_PIX_FMT_SRGGB8,
+	V4L2_PIX_FMT_SBGGR10P,
+	V4L2_PIX_FMT_SGBRG10P,
+	V4L2_PIX_FMT_SGRBG10P,
+	V4L2_PIX_FMT_SRGGB10P,
+	V4L2_PIX_FMT_UYVY,
+	V4L2_PIX_FMT_YUYV,
 };
 
-uint32_t mp_pixel_format_to_v4l_pixel_format(MPPixelFormat pixel_format)
+uint32_t
+mp_pixel_format_to_v4l_pixel_format(MPPixelFormat pixel_format)
 {
-    g_return_val_if_fail(pixel_format < MP_PIXEL_FMT_MAX, 0);
-    return pixel_format_v4l_pixel_formats[pixel_format];
+	g_return_val_if_fail(pixel_format < MP_PIXEL_FMT_MAX, 0);
+	return pixel_format_v4l_pixel_formats[pixel_format];
 }
 
-MPPixelFormat mp_pixel_format_from_v4l_pixel_format(uint32_t v4l_pixel_format)
+MPPixelFormat
+mp_pixel_format_from_v4l_pixel_format(uint32_t v4l_pixel_format)
 {
-    for (MPPixelFormat i = 0; i < MP_PIXEL_FMT_MAX; ++i) {
-        if (pixel_format_v4l_pixel_formats[i] == v4l_pixel_format) {
-            return i;
-        }
-    }
-    return MP_PIXEL_FMT_UNSUPPORTED;
+	for (MPPixelFormat i = 0; i < MP_PIXEL_FMT_MAX; ++i) {
+		if (pixel_format_v4l_pixel_formats[i] == v4l_pixel_format) {
+			return i;
+		}
+	}
+	return MP_PIXEL_FMT_UNSUPPORTED;
 }
 
 static const uint32_t pixel_format_v4l_bus_codes[MP_PIXEL_FMT_MAX] = {
-    0,
-    MEDIA_BUS_FMT_SBGGR8_1X8,
-    MEDIA_BUS_FMT_SGBRG8_1X8,
-    MEDIA_BUS_FMT_SGRBG8_1X8,
-    MEDIA_BUS_FMT_SRGGB8_1X8,
-    MEDIA_BUS_FMT_SBGGR10_1X10,
-    MEDIA_BUS_FMT_SGBRG10_1X10,
-    MEDIA_BUS_FMT_SGRBG10_1X10,
-    MEDIA_BUS_FMT_SRGGB10_1X10,
-    MEDIA_BUS_FMT_UYVY8_2X8,
-    MEDIA_BUS_FMT_YUYV8_2X8,
+	0,
+	MEDIA_BUS_FMT_SBGGR8_1X8,
+	MEDIA_BUS_FMT_SGBRG8_1X8,
+	MEDIA_BUS_FMT_SGRBG8_1X8,
+	MEDIA_BUS_FMT_SRGGB8_1X8,
+	MEDIA_BUS_FMT_SBGGR10_1X10,
+	MEDIA_BUS_FMT_SGBRG10_1X10,
+	MEDIA_BUS_FMT_SGRBG10_1X10,
+	MEDIA_BUS_FMT_SRGGB10_1X10,
+	MEDIA_BUS_FMT_UYVY8_2X8,
+	MEDIA_BUS_FMT_YUYV8_2X8,
 };
 
-uint32_t mp_pixel_format_to_v4l_bus_code(MPPixelFormat pixel_format)
+uint32_t
+mp_pixel_format_to_v4l_bus_code(MPPixelFormat pixel_format)
 {
-    g_return_val_if_fail(pixel_format < MP_PIXEL_FMT_MAX, 0);
-    return pixel_format_v4l_bus_codes[pixel_format];
+	g_return_val_if_fail(pixel_format < MP_PIXEL_FMT_MAX, 0);
+	return pixel_format_v4l_bus_codes[pixel_format];
 }
 
-MPPixelFormat mp_pixel_format_from_v4l_bus_code(uint32_t v4l_bus_code)
+MPPixelFormat
+mp_pixel_format_from_v4l_bus_code(uint32_t v4l_bus_code)
 {
-    for (MPPixelFormat i = 0; i < MP_PIXEL_FMT_MAX; ++i) {
-        if (pixel_format_v4l_bus_codes[i] == v4l_bus_code) {
-            return i;
-        }
-    }
-    return MP_PIXEL_FMT_UNSUPPORTED;
+	for (MPPixelFormat i = 0; i < MP_PIXEL_FMT_MAX; ++i) {
+		if (pixel_format_v4l_bus_codes[i] == v4l_bus_code) {
+			return i;
+		}
+	}
+	return MP_PIXEL_FMT_UNSUPPORTED;
 }
 
-uint32_t mp_pixel_format_bits_per_pixel(MPPixelFormat pixel_format)
+uint32_t
+mp_pixel_format_bits_per_pixel(MPPixelFormat pixel_format)
 {
-    g_return_val_if_fail(pixel_format < MP_PIXEL_FMT_MAX, 0);
-    switch (pixel_format) {
-        case MP_PIXEL_FMT_BGGR8:
-        case MP_PIXEL_FMT_GBRG8:
-        case MP_PIXEL_FMT_GRBG8:
-        case MP_PIXEL_FMT_RGGB8: return 8;
-        case MP_PIXEL_FMT_BGGR10P:
-        case MP_PIXEL_FMT_GBRG10P:
-        case MP_PIXEL_FMT_GRBG10P:
-        case MP_PIXEL_FMT_RGGB10P: return 10;
-        case MP_PIXEL_FMT_UYVY:
-        case MP_PIXEL_FMT_YUYV: return 16;
-        default: return 0;
-    }
+	g_return_val_if_fail(pixel_format < MP_PIXEL_FMT_MAX, 0);
+	switch (pixel_format) {
+	case MP_PIXEL_FMT_BGGR8:
+	case MP_PIXEL_FMT_GBRG8:
+	case MP_PIXEL_FMT_GRBG8:
+	case MP_PIXEL_FMT_RGGB8:
+		return 8;
+	case MP_PIXEL_FMT_BGGR10P:
+	case MP_PIXEL_FMT_GBRG10P:
+	case MP_PIXEL_FMT_GRBG10P:
+	case MP_PIXEL_FMT_RGGB10P:
+		return 10;
+	case MP_PIXEL_FMT_UYVY:
+	case MP_PIXEL_FMT_YUYV:
+		return 16;
+	default:
+		return 0;
+	}
 }
 
-uint32_t mp_pixel_format_width_to_bytes(MPPixelFormat pixel_format, uint32_t width)
+uint32_t
+mp_pixel_format_width_to_bytes(MPPixelFormat pixel_format, uint32_t width)
 {
-    uint32_t bits_per_pixel = mp_pixel_format_bits_per_pixel(pixel_format);
-    uint64_t bits_per_width = width * (uint64_t) bits_per_pixel;
+	uint32_t bits_per_pixel = mp_pixel_format_bits_per_pixel(pixel_format);
+	uint64_t bits_per_width = width * (uint64_t)bits_per_pixel;
 
-    uint64_t remainder = bits_per_width % 8;
-    if (remainder == 0)
-        return bits_per_width / 8;
+	uint64_t remainder = bits_per_width % 8;
+	if (remainder == 0)
+		return bits_per_width / 8;
 
-    return (bits_per_width + 8 - remainder) / 8;
+	return (bits_per_width + 8 - remainder) / 8;
 }
 
-uint32_t mp_pixel_format_width_to_colors(MPPixelFormat pixel_format, uint32_t width)
+uint32_t
+mp_pixel_format_width_to_colors(MPPixelFormat pixel_format, uint32_t width)
 {
-    g_return_val_if_fail(pixel_format < MP_PIXEL_FMT_MAX, 0);
-    switch (pixel_format) {
-        case MP_PIXEL_FMT_BGGR8:
-        case MP_PIXEL_FMT_GBRG8:
-        case MP_PIXEL_FMT_GRBG8:
-        case MP_PIXEL_FMT_RGGB8: return width / 2;
-        case MP_PIXEL_FMT_BGGR10P:
-        case MP_PIXEL_FMT_GBRG10P:
-        case MP_PIXEL_FMT_GRBG10P:
-        case MP_PIXEL_FMT_RGGB10P: return width / 2 * 5;
-        case MP_PIXEL_FMT_UYVY:
-        case MP_PIXEL_FMT_YUYV: return width;
-        default: return 0;
-    }
+	g_return_val_if_fail(pixel_format < MP_PIXEL_FMT_MAX, 0);
+	switch (pixel_format) {
+	case MP_PIXEL_FMT_BGGR8:
+	case MP_PIXEL_FMT_GBRG8:
+	case MP_PIXEL_FMT_GRBG8:
+	case MP_PIXEL_FMT_RGGB8:
+		return width / 2;
+	case MP_PIXEL_FMT_BGGR10P:
+	case MP_PIXEL_FMT_GBRG10P:
+	case MP_PIXEL_FMT_GRBG10P:
+	case MP_PIXEL_FMT_RGGB10P:
+		return width / 2 * 5;
+	case MP_PIXEL_FMT_UYVY:
+	case MP_PIXEL_FMT_YUYV:
+		return width;
+	default:
+		return 0;
+	}
 }
 
-uint32_t mp_pixel_format_height_to_colors(MPPixelFormat pixel_format, uint32_t height)
+uint32_t
+mp_pixel_format_height_to_colors(MPPixelFormat pixel_format, uint32_t height)
 {
-    g_return_val_if_fail(pixel_format < MP_PIXEL_FMT_MAX, 0);
-    switch (pixel_format) {
-        case MP_PIXEL_FMT_BGGR8:
-        case MP_PIXEL_FMT_GBRG8:
-        case MP_PIXEL_FMT_GRBG8:
-        case MP_PIXEL_FMT_RGGB8:
-        case MP_PIXEL_FMT_BGGR10P:
-        case MP_PIXEL_FMT_GBRG10P:
-        case MP_PIXEL_FMT_GRBG10P:
-        case MP_PIXEL_FMT_RGGB10P: return height / 2;
-        case MP_PIXEL_FMT_UYVY:
-        case MP_PIXEL_FMT_YUYV: return height;
-        default: return 0;
-    }
+	g_return_val_if_fail(pixel_format < MP_PIXEL_FMT_MAX, 0);
+	switch (pixel_format) {
+	case MP_PIXEL_FMT_BGGR8:
+	case MP_PIXEL_FMT_GBRG8:
+	case MP_PIXEL_FMT_GRBG8:
+	case MP_PIXEL_FMT_RGGB8:
+	case MP_PIXEL_FMT_BGGR10P:
+	case MP_PIXEL_FMT_GBRG10P:
+	case MP_PIXEL_FMT_GRBG10P:
+	case MP_PIXEL_FMT_RGGB10P:
+		return height / 2;
+	case MP_PIXEL_FMT_UYVY:
+	case MP_PIXEL_FMT_YUYV:
+		return height;
+	default:
+		return 0;
+	}
 }
 
-bool mp_camera_mode_is_equivalent(const MPCameraMode *m1, const MPCameraMode *m2)
+bool
+mp_camera_mode_is_equivalent(const MPCameraMode *m1, const MPCameraMode *m2)
 {
-    return m1->pixel_format == m2->pixel_format
-        && m1->frame_interval.numerator == m2->frame_interval.numerator
-        && m1->frame_interval.denominator == m2->frame_interval.denominator
-        && m1->width == m2->width
-        && m1->height == m2->height;
+	return m1->pixel_format == m2->pixel_format &&
+	       m1->frame_interval.numerator == m2->frame_interval.numerator &&
+	       m1->frame_interval.denominator == m2->frame_interval.denominator &&
+	       m1->width == m2->width && m1->height == m2->height;
 }
 
-static void errno_printerr(const char *s)
+static void
+errno_printerr(const char *s)
 {
-    g_printerr("MPCamera: %s error %d, %s\n", s, errno, strerror(errno));
+	g_printerr("MPCamera: %s error %d, %s\n", s, errno, strerror(errno));
 }
 
-static int xioctl(int fd, int request, void *arg)
+static int
+xioctl(int fd, int request, void *arg)
 {
-    int r;
-    do {
-        r = ioctl(fd, request, arg);
-    } while (r == -1 && errno == EINTR);
-    return r;
+	int r;
+	do {
+		r = ioctl(fd, request, arg);
+	} while (r == -1 && errno == EINTR);
+	return r;
 }
 
 struct video_buffer {
-    uint32_t length;
-    uint8_t *data;
+	uint32_t length;
+	uint8_t *data;
 };
 
 struct _MPCamera {
-    int video_fd;
-    int subdev_fd;
+	int video_fd;
+	int subdev_fd;
 
-    bool has_set_mode;
-    MPCameraMode current_mode;
+	bool has_set_mode;
+	MPCameraMode current_mode;
 
-    struct video_buffer buffers[MAX_VIDEO_BUFFERS];
-    uint32_t num_buffers;
+	struct video_buffer buffers[MAX_VIDEO_BUFFERS];
+	uint32_t num_buffers;
 
-    bool use_mplane;
+	bool use_mplane;
 };
 
-MPCamera *mp_camera_new(int video_fd, int subdev_fd)
+MPCamera *
+mp_camera_new(int video_fd, int subdev_fd)
 {
-    g_return_val_if_fail(video_fd != -1, NULL);
-
-    // Query capabilities
-    struct v4l2_capability cap;
-    if (xioctl(video_fd, VIDIOC_QUERYCAP, &cap) == -1) {
-        return NULL;
-    }
-
-    // Check whether this is a video capture device
-    bool use_mplane;
-    if (cap.capabilities & V4L2_CAP_VIDEO_CAPTURE_MPLANE) {
-        use_mplane = true;
-        printf("!!\n");
-    } else if (cap.capabilities & V4L2_CAP_VIDEO_CAPTURE) {
-        use_mplane = false;
-    } else {
-        return NULL;
-    }
-
-    MPCamera *camera = malloc(sizeof(MPCamera));
-    camera->video_fd = video_fd;
-    camera->subdev_fd = subdev_fd;
-    camera->has_set_mode = false;
-    camera->num_buffers = 0;
-    camera->use_mplane = use_mplane;
-    return camera;
+	g_return_val_if_fail(video_fd != -1, NULL);
+
+	// Query capabilities
+	struct v4l2_capability cap;
+	if (xioctl(video_fd, VIDIOC_QUERYCAP, &cap) == -1) {
+		return NULL;
+	}
+
+	// Check whether this is a video capture device
+	bool use_mplane;
+	if (cap.capabilities & V4L2_CAP_VIDEO_CAPTURE_MPLANE) {
+		use_mplane = true;
+		printf("!!\n");
+	} else if (cap.capabilities & V4L2_CAP_VIDEO_CAPTURE) {
+		use_mplane = false;
+	} else {
+		return NULL;
+	}
+
+	MPCamera *camera = malloc(sizeof(MPCamera));
+	camera->video_fd = video_fd;
+	camera->subdev_fd = subdev_fd;
+	camera->has_set_mode = false;
+	camera->num_buffers = 0;
+	camera->use_mplane = use_mplane;
+	return camera;
 }
 
-void mp_camera_free(MPCamera *camera)
+void
+mp_camera_free(MPCamera *camera)
 {
-    g_warn_if_fail(camera->num_buffers == 0);
-    if (camera->num_buffers != 0) {
-        mp_camera_stop_capture(camera);
-    }
+	g_warn_if_fail(camera->num_buffers == 0);
+	if (camera->num_buffers != 0) {
+		mp_camera_stop_capture(camera);
+	}
 
-    free(camera);
+	free(camera);
 }
 
-bool mp_camera_is_subdev(MPCamera *camera)
+bool
+mp_camera_is_subdev(MPCamera *camera)
 {
-    return camera->subdev_fd != -1;
+	return camera->subdev_fd != -1;
 }
 
-int mp_camera_get_video_fd(MPCamera *camera)
+int
+mp_camera_get_video_fd(MPCamera *camera)
 {
-    return camera->video_fd;
+	return camera->video_fd;
 }
 
-int mp_camera_get_subdev_fd(MPCamera *camera)
+int
+mp_camera_get_subdev_fd(MPCamera *camera)
 {
-    return camera->subdev_fd;
+	return camera->subdev_fd;
 }
 
-static bool camera_mode_impl(MPCamera *camera, int request, MPCameraMode *mode)
+static bool
+camera_mode_impl(MPCamera *camera, int request, MPCameraMode *mode)
 {
-    uint32_t pixfmt = mp_pixel_format_from_v4l_pixel_format(mode->pixel_format);
-    struct v4l2_format fmt = {};
-    if (camera->use_mplane) {
-        fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
-        fmt.fmt.pix_mp.width = mode->width;
-        fmt.fmt.pix_mp.height = mode->height;
-        fmt.fmt.pix_mp.pixelformat = pixfmt;
-        fmt.fmt.pix_mp.field = V4L2_FIELD_ANY;
-    } else {
-        fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-        fmt.fmt.pix.width = mode->width;
-        fmt.fmt.pix.height = mode->height;
-        fmt.fmt.pix.pixelformat = pixfmt;
-        fmt.fmt.pix.field = V4L2_FIELD_ANY;
-    }
-
-    if (xioctl(camera->video_fd, request, &fmt) == -1) {
-        return false;
-    }
-
-    if (camera->use_mplane) {
-        mode->width = fmt.fmt.pix_mp.width;
-        mode->height = fmt.fmt.pix_mp.height;
-        mode->pixel_format = mp_pixel_format_from_v4l_pixel_format(
-            fmt.fmt.pix_mp.pixelformat);
-    } else {
-        mode->width = fmt.fmt.pix.width;
-        mode->height = fmt.fmt.pix.height;
-        mode->pixel_format = mp_pixel_format_from_v4l_pixel_format(
-            fmt.fmt.pix.pixelformat);
-    }
-
-    return true;
+	uint32_t pixfmt = mp_pixel_format_from_v4l_pixel_format(mode->pixel_format);
+	struct v4l2_format fmt = {};
+	if (camera->use_mplane) {
+		fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+		fmt.fmt.pix_mp.width = mode->width;
+		fmt.fmt.pix_mp.height = mode->height;
+		fmt.fmt.pix_mp.pixelformat = pixfmt;
+		fmt.fmt.pix_mp.field = V4L2_FIELD_ANY;
+	} else {
+		fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+		fmt.fmt.pix.width = mode->width;
+		fmt.fmt.pix.height = mode->height;
+		fmt.fmt.pix.pixelformat = pixfmt;
+		fmt.fmt.pix.field = V4L2_FIELD_ANY;
+	}
+
+	if (xioctl(camera->video_fd, request, &fmt) == -1) {
+		return false;
+	}
+
+	if (camera->use_mplane) {
+		mode->width = fmt.fmt.pix_mp.width;
+		mode->height = fmt.fmt.pix_mp.height;
+		mode->pixel_format = mp_pixel_format_from_v4l_pixel_format(
+			fmt.fmt.pix_mp.pixelformat);
+	} else {
+		mode->width = fmt.fmt.pix.width;
+		mode->height = fmt.fmt.pix.height;
+		mode->pixel_format = mp_pixel_format_from_v4l_pixel_format(
+			fmt.fmt.pix.pixelformat);
+	}
+
+	return true;
 }
 
-bool mp_camera_try_mode(MPCamera *camera, MPCameraMode *mode)
+bool
+mp_camera_try_mode(MPCamera *camera, MPCameraMode *mode)
 {
-    if (!camera_mode_impl(camera, VIDIOC_TRY_FMT, mode)) {
-        errno_printerr("VIDIOC_S_FMT");
-        return false;
-    }
-    return true;
+	if (!camera_mode_impl(camera, VIDIOC_TRY_FMT, mode)) {
+		errno_printerr("VIDIOC_S_FMT");
+		return false;
+	}
+	return true;
 }
 
-const MPCameraMode *mp_camera_get_mode(const MPCamera *camera)
+const MPCameraMode *
+mp_camera_get_mode(const MPCamera *camera)
 {
-    return &camera->current_mode;
+	return &camera->current_mode;
 }
 
-bool mp_camera_set_mode(MPCamera *camera, MPCameraMode *mode)
+bool
+mp_camera_set_mode(MPCamera *camera, MPCameraMode *mode)
 {
-    // Set the mode in the subdev the camera is one
-    if (mp_camera_is_subdev(camera))
-    {
-        struct v4l2_subdev_frame_interval interval = {};
-        interval.pad = 0;
-        interval.interval = mode->frame_interval;
-        if (xioctl(camera->subdev_fd, VIDIOC_SUBDEV_S_FRAME_INTERVAL, &interval) == -1) {
-            errno_printerr("VIDIOC_SUBDEV_S_FRAME_INTERVAL");
-            return false;
-        }
-
-        bool did_set_frame_rate =
-            interval.interval.numerator == mode->frame_interval.numerator
-            && interval.interval.denominator == mode->frame_interval.denominator;
-
-        struct v4l2_subdev_format fmt = {};
-        fmt.pad = 0;
-        fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
-        fmt.format.width = mode->width;
-        fmt.format.height = mode->height;
-        fmt.format.code = mp_pixel_format_to_v4l_bus_code(mode->pixel_format);
-        fmt.format.field = V4L2_FIELD_ANY;
-        if (xioctl(camera->subdev_fd, VIDIOC_SUBDEV_S_FMT, &fmt) == -1) {
-            errno_printerr("VIDIOC_SUBDEV_S_FMT");
-            return false;
-        }
-
-        // Some drivers like ov5640 don't allow you to set the frame format with
-        // too high a frame-rate, but that means the frame-rate won't be set
-        // after the format change. So we need to try again here if we didn't
-        // succeed before. Ideally we'd be able to set both at once.
-        if (!did_set_frame_rate)
-        {
-            interval.interval = mode->frame_interval;
-            if (xioctl(camera->subdev_fd, VIDIOC_SUBDEV_S_FRAME_INTERVAL, &interval) == -1) {
-                errno_printerr("VIDIOC_SUBDEV_S_FRAME_INTERVAL");
-            }
-        }
-
-        // Update the mode
-        mode->pixel_format = mp_pixel_format_from_v4l_bus_code(fmt.format.code);
-        mode->frame_interval = interval.interval;
-        mode->width = fmt.format.width;
-        mode->height = fmt.format.height;
-    }
-
-    // Set the mode for the video device
-    {
-        if (!camera_mode_impl(camera, VIDIOC_S_FMT, mode)) {
-            errno_printerr("VIDIOC_S_FMT");
-            return false;
-        }
-    }
-
-    camera->has_set_mode = true;
-    camera->current_mode = *mode;
-
-    return true;
+	// Set the mode in the subdev the camera is one
+	if (mp_camera_is_subdev(camera)) {
+		struct v4l2_subdev_frame_interval interval = {};
+		interval.pad = 0;
+		interval.interval = mode->frame_interval;
+		if (xioctl(camera->subdev_fd, VIDIOC_SUBDEV_S_FRAME_INTERVAL,
+			   &interval) == -1) {
+			errno_printerr("VIDIOC_SUBDEV_S_FRAME_INTERVAL");
+			return false;
+		}
+
+		bool did_set_frame_rate = interval.interval.numerator ==
+						  mode->frame_interval.numerator &&
+					  interval.interval.denominator ==
+						  mode->frame_interval.denominator;
+
+		struct v4l2_subdev_format fmt = {};
+		fmt.pad = 0;
+		fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
+		fmt.format.width = mode->width;
+		fmt.format.height = mode->height;
+		fmt.format.code =
+			mp_pixel_format_to_v4l_bus_code(mode->pixel_format);
+		fmt.format.field = V4L2_FIELD_ANY;
+		if (xioctl(camera->subdev_fd, VIDIOC_SUBDEV_S_FMT, &fmt) == -1) {
+			errno_printerr("VIDIOC_SUBDEV_S_FMT");
+			return false;
+		}
+
+		// Some drivers like ov5640 don't allow you to set the frame format with
+		// too high a frame-rate, but that means the frame-rate won't be set
+		// after the format change. So we need to try again here if we didn't
+		// succeed before. Ideally we'd be able to set both at once.
+		if (!did_set_frame_rate) {
+			interval.interval = mode->frame_interval;
+			if (xioctl(camera->subdev_fd, VIDIOC_SUBDEV_S_FRAME_INTERVAL,
+				   &interval) == -1) {
+				errno_printerr("VIDIOC_SUBDEV_S_FRAME_INTERVAL");
+			}
+		}
+
+		// Update the mode
+		mode->pixel_format =
+			mp_pixel_format_from_v4l_bus_code(fmt.format.code);
+		mode->frame_interval = interval.interval;
+		mode->width = fmt.format.width;
+		mode->height = fmt.format.height;
+	}
+
+	// Set the mode for the video device
+	{
+		if (!camera_mode_impl(camera, VIDIOC_S_FMT, mode)) {
+			errno_printerr("VIDIOC_S_FMT");
+			return false;
+		}
+	}
+
+	camera->has_set_mode = true;
+	camera->current_mode = *mode;
+
+	return true;
 }
 
-bool mp_camera_start_capture(MPCamera *camera)
+bool
+mp_camera_start_capture(MPCamera *camera)
 {
-    g_return_val_if_fail(camera->has_set_mode, false);
-    g_return_val_if_fail(camera->num_buffers == 0, false);
-
-    enum v4l2_buf_type buftype = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-    if (camera->use_mplane) {
-        buftype = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
-    }
-
-    // Start by requesting buffers
-    struct v4l2_requestbuffers req = {};
-    req.count = MAX_VIDEO_BUFFERS;
-    req.type = buftype;
-    req.memory = V4L2_MEMORY_MMAP;
-
-    if (xioctl(camera->video_fd, VIDIOC_REQBUFS, &req) == -1) {
-        errno_printerr("VIDIOC_REQBUFS");
-        return false;
-    }
-
-    if (req.count < 2) {
-        g_printerr("Insufficient buffer memory. Only %d buffers available.\n",
-                   req.count);
-        goto error;
-    }
-
-    for (uint32_t i = 0; i < req.count; ++i) {
-        // Query each buffer and mmap it
-        struct v4l2_buffer buf = {
-            .type = buftype,
-            .memory = V4L2_MEMORY_MMAP,
-            .index = i,
-        };
-
-        struct v4l2_plane planes[1];
-        if (camera->use_mplane) {
-            buf.m.planes = planes;
-            buf.length = 1;
-        }
-
-        if (xioctl(camera->video_fd, VIDIOC_QUERYBUF, &buf) == -1) {
-            errno_printerr("VIDIOC_QUERYBUF");
-            break;
-        }
-
-        if (camera->use_mplane) {
-            camera->buffers[i].length = planes[0].length;
-            camera->buffers[i].data = mmap(
-                NULL,
-                planes[0].length,
-                PROT_READ,
-                MAP_SHARED,
-                camera->video_fd,
-                planes[0].m.mem_offset);
-        } else {
-            camera->buffers[i].length = buf.length;
-            camera->buffers[i].data = mmap(
-                NULL,
-                buf.length,
-                PROT_READ,
-                MAP_SHARED,
-                camera->video_fd,
-                buf.m.offset);
-        }
-
-        if (camera->buffers[i].data == MAP_FAILED) {
-            errno_printerr("mmap");
-            break;
-        }
-
-        ++camera->num_buffers;
-    }
-
-    if (camera->num_buffers != req.count) {
-        g_printerr("Unable to map all buffers\n");
-        goto error;
-    }
-
-    for (uint32_t i = 0; i < camera->num_buffers; ++i) {
-        struct v4l2_buffer buf = {
-            .type = buftype,
-            .memory = V4L2_MEMORY_MMAP,
-            .index = i,
-        };
-
-        struct v4l2_plane planes[1];
-        if (camera->use_mplane) {
-            buf.m.planes = planes;
-            buf.length = 1;
-        }
-
-        // Queue the buffer for capture
-        if (xioctl(camera->video_fd, VIDIOC_QBUF, &buf) == -1) {
-            errno_printerr("VIDIOC_QBUF");
-            goto error;
-        }
-    }
-
-    // Start capture
-    enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-    if (xioctl(camera->video_fd, VIDIOC_STREAMON, &type) == -1) {
-        errno_printerr("VIDIOC_STREAMON");
-        goto error;
-    }
-
-    return true;
+	g_return_val_if_fail(camera->has_set_mode, false);
+	g_return_val_if_fail(camera->num_buffers == 0, false);
+
+	enum v4l2_buf_type buftype = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+	if (camera->use_mplane) {
+		buftype = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+	}
+
+	// Start by requesting buffers
+	struct v4l2_requestbuffers req = {};
+	req.count = MAX_VIDEO_BUFFERS;
+	req.type = buftype;
+	req.memory = V4L2_MEMORY_MMAP;
+
+	if (xioctl(camera->video_fd, VIDIOC_REQBUFS, &req) == -1) {
+		errno_printerr("VIDIOC_REQBUFS");
+		return false;
+	}
+
+	if (req.count < 2) {
+		g_printerr(
+			"Insufficient buffer memory. Only %d buffers available.\n",
+			req.count);
+		goto error;
+	}
+
+	for (uint32_t i = 0; i < req.count; ++i) {
+		// Query each buffer and mmap it
+		struct v4l2_buffer buf = {
+			.type = buftype,
+			.memory = V4L2_MEMORY_MMAP,
+			.index = i,
+		};
+
+		struct v4l2_plane planes[1];
+		if (camera->use_mplane) {
+			buf.m.planes = planes;
+			buf.length = 1;
+		}
+
+		if (xioctl(camera->video_fd, VIDIOC_QUERYBUF, &buf) == -1) {
+			errno_printerr("VIDIOC_QUERYBUF");
+			break;
+		}
+
+		if (camera->use_mplane) {
+			camera->buffers[i].length = planes[0].length;
+			camera->buffers[i].data =
+				mmap(NULL, planes[0].length, PROT_READ, MAP_SHARED,
+				     camera->video_fd, planes[0].m.mem_offset);
+		} else {
+			camera->buffers[i].length = buf.length;
+			camera->buffers[i].data =
+				mmap(NULL, buf.length, PROT_READ, MAP_SHARED,
+				     camera->video_fd, buf.m.offset);
+		}
+
+		if (camera->buffers[i].data == MAP_FAILED) {
+			errno_printerr("mmap");
+			break;
+		}
+
+		++camera->num_buffers;
+	}
+
+	if (camera->num_buffers != req.count) {
+		g_printerr("Unable to map all buffers\n");
+		goto error;
+	}
+
+	for (uint32_t i = 0; i < camera->num_buffers; ++i) {
+		struct v4l2_buffer buf = {
+			.type = buftype,
+			.memory = V4L2_MEMORY_MMAP,
+			.index = i,
+		};
+
+		struct v4l2_plane planes[1];
+		if (camera->use_mplane) {
+			buf.m.planes = planes;
+			buf.length = 1;
+		}
+
+		// Queue the buffer for capture
+		if (xioctl(camera->video_fd, VIDIOC_QBUF, &buf) == -1) {
+			errno_printerr("VIDIOC_QBUF");
+			goto error;
+		}
+	}
+
+	// Start capture
+	enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+	if (xioctl(camera->video_fd, VIDIOC_STREAMON, &type) == -1) {
+		errno_printerr("VIDIOC_STREAMON");
+		goto error;
+	}
+
+	return true;
 
 error:
-    // Unmap any mapped buffers
-    assert(camera->num_buffers <= MAX_VIDEO_BUFFERS);
-    for (uint32_t i = 0; i < camera->num_buffers; ++i) {
-        if (munmap(camera->buffers[i].data, camera->buffers[i].length) == -1) {
-            errno_printerr("munmap");
-        }
-    }
-
-    // Reset allocated buffers
-    {
-        struct v4l2_requestbuffers req = {};
-        req.count = 0;
-        req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-        req.memory = V4L2_MEMORY_MMAP;
-
-        if (xioctl(camera->video_fd, VIDIOC_REQBUFS, &req) == -1) {
-            errno_printerr("VIDIOC_REQBUFS");
-        }
-    }
-
-    return false;
+	// Unmap any mapped buffers
+	assert(camera->num_buffers <= MAX_VIDEO_BUFFERS);
+	for (uint32_t i = 0; i < camera->num_buffers; ++i) {
+		if (munmap(camera->buffers[i].data, camera->buffers[i].length) ==
+		    -1) {
+			errno_printerr("munmap");
+		}
+	}
+
+	// Reset allocated buffers
+	{
+		struct v4l2_requestbuffers req = {};
+		req.count = 0;
+		req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+		req.memory = V4L2_MEMORY_MMAP;
+
+		if (xioctl(camera->video_fd, VIDIOC_REQBUFS, &req) == -1) {
+			errno_printerr("VIDIOC_REQBUFS");
+		}
+	}
+
+	return false;
 }
 
-bool mp_camera_stop_capture(MPCamera *camera)
+bool
+mp_camera_stop_capture(MPCamera *camera)
 {
-    g_return_val_if_fail(camera->num_buffers > 0, false);
-
-    enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-    if (xioctl(camera->video_fd, VIDIOC_STREAMOFF, &type) == -1) {
-        errno_printerr("VIDIOC_STREAMOFF");
-    }
-
-    assert(camera->num_buffers <= MAX_VIDEO_BUFFERS);
-    for (int i = 0; i < camera->num_buffers; ++i) {
-        if (munmap(camera->buffers[i].data, camera->buffers[i].length) == -1) {
-            errno_printerr("munmap");
-        }
-    }
-
-    camera->num_buffers = 0;
-
-    struct v4l2_requestbuffers req = {};
-    req.count = 0;
-    req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-    req.memory = V4L2_MEMORY_MMAP;
-    if (xioctl(camera->video_fd, VIDIOC_REQBUFS, &req) == -1) {
-        errno_printerr("VIDIOC_REQBUFS");
-    }
-
-    return true;
+	g_return_val_if_fail(camera->num_buffers > 0, false);
+
+	enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+	if (xioctl(camera->video_fd, VIDIOC_STREAMOFF, &type) == -1) {
+		errno_printerr("VIDIOC_STREAMOFF");
+	}
+
+	assert(camera->num_buffers <= MAX_VIDEO_BUFFERS);
+	for (int i = 0; i < camera->num_buffers; ++i) {
+		if (munmap(camera->buffers[i].data, camera->buffers[i].length) ==
+		    -1) {
+			errno_printerr("munmap");
+		}
+	}
+
+	camera->num_buffers = 0;
+
+	struct v4l2_requestbuffers req = {};
+	req.count = 0;
+	req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+	req.memory = V4L2_MEMORY_MMAP;
+	if (xioctl(camera->video_fd, VIDIOC_REQBUFS, &req) == -1) {
+		errno_printerr("VIDIOC_REQBUFS");
+	}
+
+	return true;
 }
 
-bool mp_camera_is_capturing(MPCamera *camera)
+bool
+mp_camera_is_capturing(MPCamera *camera)
 {
-    return camera->num_buffers > 0;
+	return camera->num_buffers > 0;
 }
 
-bool mp_camera_capture_image(MPCamera *camera, void (*callback)(MPImage, void *), void *user_data)
+bool
+mp_camera_capture_image(MPCamera *camera, void (*callback)(MPImage, void *),
+			void *user_data)
 {
-    struct v4l2_buffer buf = {};
-    buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-    buf.memory = V4L2_MEMORY_MMAP;
-
-    struct v4l2_plane planes[1];
-    if (camera->use_mplane) {
-        buf.m.planes = planes;
-        buf.length = 1;
-    }
-
-    if (xioctl(camera->video_fd, VIDIOC_DQBUF, &buf) == -1) {
-        switch (errno) {
-            case EAGAIN:
-                return true;
-            case EIO:
-                /* Could ignore EIO, see spec. */
-                /* fallthrough */
-            default:
-                errno_printerr("VIDIOC_DQBUF");
-                return false;
-        }
-    }
-
-    uint32_t pixel_format = camera->current_mode.pixel_format;
-    uint32_t width = camera->current_mode.width;
-    uint32_t height = camera->current_mode.height;
-
-    uint32_t bytesused;
-    if (camera->use_mplane) {
-        bytesused = planes[0].bytesused;
-    } else {
-        bytesused = buf.bytesused;
-    }
-
-    assert(bytesused == mp_pixel_format_width_to_bytes(pixel_format, width) * height);
-    assert(bytesused == camera->buffers[buf.index].length);
-
-    MPImage image = {
-        .pixel_format = pixel_format,
-        .width = width,
-        .height = height,
-        .data = camera->buffers[buf.index].data,
-    };
-
-    callback(image, user_data);
-
-    // The callback may have stopped the capture, only queue the buffer if we're
-    // still capturing.
-    if (mp_camera_is_capturing(camera)) {
-        if (xioctl(camera->video_fd, VIDIOC_QBUF, &buf) == -1) {
-            errno_printerr("VIDIOC_QBUF");
-            return false;
-        }
-    }
-
-    return true;
+	struct v4l2_buffer buf = {};
+	buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+	buf.memory = V4L2_MEMORY_MMAP;
+
+	struct v4l2_plane planes[1];
+	if (camera->use_mplane) {
+		buf.m.planes = planes;
+		buf.length = 1;
+	}
+
+	if (xioctl(camera->video_fd, VIDIOC_DQBUF, &buf) == -1) {
+		switch (errno) {
+		case EAGAIN:
+			return true;
+		case EIO:
+			/* Could ignore EIO, see spec. */
+			/* fallthrough */
+		default:
+			errno_printerr("VIDIOC_DQBUF");
+			return false;
+		}
+	}
+
+	uint32_t pixel_format = camera->current_mode.pixel_format;
+	uint32_t width = camera->current_mode.width;
+	uint32_t height = camera->current_mode.height;
+
+	uint32_t bytesused;
+	if (camera->use_mplane) {
+		bytesused = planes[0].bytesused;
+	} else {
+		bytesused = buf.bytesused;
+	}
+
+	assert(bytesused ==
+	       mp_pixel_format_width_to_bytes(pixel_format, width) * height);
+	assert(bytesused == camera->buffers[buf.index].length);
+
+	MPImage image = {
+		.pixel_format = pixel_format,
+		.width = width,
+		.height = height,
+		.data = camera->buffers[buf.index].data,
+	};
+
+	callback(image, user_data);
+
+	// The callback may have stopped the capture, only queue the buffer if we're
+	// still capturing.
+	if (mp_camera_is_capturing(camera)) {
+		if (xioctl(camera->video_fd, VIDIOC_QBUF, &buf) == -1) {
+			errno_printerr("VIDIOC_QBUF");
+			return false;
+		}
+	}
+
+	return true;
 }
 
 struct _MPCameraModeList {
-    MPCameraMode mode;
-    MPCameraModeList *next;
+	MPCameraMode mode;
+	MPCameraModeList *next;
 };
 
 static MPCameraModeList *
 get_subdev_modes(MPCamera *camera, bool (*check)(MPCamera *, MPCameraMode *))
 {
-    MPCameraModeList *item = NULL;
-
-    for (uint32_t fmt_index = 0;; ++fmt_index) {
-        struct v4l2_subdev_mbus_code_enum fmt = {};
-        fmt.index = fmt_index;
-        fmt.pad = 0;
-        fmt.which = V4L2_SUBDEV_FORMAT_TRY;
-        if (xioctl(camera->subdev_fd, VIDIOC_SUBDEV_ENUM_MBUS_CODE, &fmt) == -1) {
-            if (errno != EINVAL) {
-                errno_printerr("VIDIOC_SUBDEV_ENUM_MBUS_CODE");
-            }
-            break;
-        }
-
-        // Skip unsupported formats
-        uint32_t format = mp_pixel_format_from_v4l_bus_code(fmt.code);
-        if (format == MP_PIXEL_FMT_UNSUPPORTED) {
-            continue;
-        }
-
-        for (uint32_t frame_index = 0;; ++frame_index) {
-            struct v4l2_subdev_frame_size_enum frame = {};
-            frame.index = frame_index;
-            frame.pad = 0;
-            frame.code = fmt.code;
-            frame.which = V4L2_SUBDEV_FORMAT_TRY;
-            if (xioctl(camera->subdev_fd, VIDIOC_SUBDEV_ENUM_FRAME_SIZE, &frame) == -1) {
-                if (errno != EINVAL) {
-                    errno_printerr("VIDIOC_SUBDEV_ENUM_FRAME_SIZE");
-                }
-                break;
-            }
-
-            // TODO: Handle other types
-            if (frame.min_width != frame.max_width
-                || frame.min_height != frame.max_height) {
-                break;
-            }
-
-            for (uint32_t interval_index = 0;; ++interval_index) {
-                struct v4l2_subdev_frame_interval_enum interval = {};
-                interval.index = interval_index;
-                interval.pad = 0;
-                interval.code = fmt.code;
-                interval.width = frame.max_width;
-                interval.height = frame.max_height;
-                interval.which = V4L2_SUBDEV_FORMAT_TRY;
-                if (xioctl(camera->subdev_fd, VIDIOC_SUBDEV_ENUM_FRAME_INTERVAL, &interval) == -1) {
-                    if (errno != EINVAL) {
-                        errno_printerr("VIDIOC_SUBDEV_ENUM_FRAME_INTERVAL");
-                    }
-                    break;
-                }
-
-                MPCameraMode mode = {
-                    .pixel_format = format,
-                    .frame_interval = interval.interval,
-                    .width = frame.max_width,
-                    .height = frame.max_height,
-                };
-
-                if (!check(camera, &mode)) {
-                    continue;
-                }
-
-                MPCameraModeList *new_item = malloc(sizeof(MPCameraModeList));
-                new_item->mode = mode;
-                new_item->next = item;
-                item = new_item;
-            }
-        }
-    }
-
-    return item;
+	MPCameraModeList *item = NULL;
+
+	for (uint32_t fmt_index = 0;; ++fmt_index) {
+		struct v4l2_subdev_mbus_code_enum fmt = {};
+		fmt.index = fmt_index;
+		fmt.pad = 0;
+		fmt.which = V4L2_SUBDEV_FORMAT_TRY;
+		if (xioctl(camera->subdev_fd, VIDIOC_SUBDEV_ENUM_MBUS_CODE, &fmt) ==
+		    -1) {
+			if (errno != EINVAL) {
+				errno_printerr("VIDIOC_SUBDEV_ENUM_MBUS_CODE");
+			}
+			break;
+		}
+
+		// Skip unsupported formats
+		uint32_t format = mp_pixel_format_from_v4l_bus_code(fmt.code);
+		if (format == MP_PIXEL_FMT_UNSUPPORTED) {
+			continue;
+		}
+
+		for (uint32_t frame_index = 0;; ++frame_index) {
+			struct v4l2_subdev_frame_size_enum frame = {};
+			frame.index = frame_index;
+			frame.pad = 0;
+			frame.code = fmt.code;
+			frame.which = V4L2_SUBDEV_FORMAT_TRY;
+			if (xioctl(camera->subdev_fd, VIDIOC_SUBDEV_ENUM_FRAME_SIZE,
+				   &frame) == -1) {
+				if (errno != EINVAL) {
+					errno_printerr(
+						"VIDIOC_SUBDEV_ENUM_FRAME_SIZE");
+				}
+				break;
+			}
+
+			// TODO: Handle other types
+			if (frame.min_width != frame.max_width ||
+			    frame.min_height != frame.max_height) {
+				break;
+			}
+
+			for (uint32_t interval_index = 0;; ++interval_index) {
+				struct v4l2_subdev_frame_interval_enum interval = {};
+				interval.index = interval_index;
+				interval.pad = 0;
+				interval.code = fmt.code;
+				interval.width = frame.max_width;
+				interval.height = frame.max_height;
+				interval.which = V4L2_SUBDEV_FORMAT_TRY;
+				if (xioctl(camera->subdev_fd,
+					   VIDIOC_SUBDEV_ENUM_FRAME_INTERVAL,
+					   &interval) == -1) {
+					if (errno != EINVAL) {
+						errno_printerr(
+							"VIDIOC_SUBDEV_ENUM_FRAME_INTERVAL");
+					}
+					break;
+				}
+
+				MPCameraMode mode = {
+					.pixel_format = format,
+					.frame_interval = interval.interval,
+					.width = frame.max_width,
+					.height = frame.max_height,
+				};
+
+				if (!check(camera, &mode)) {
+					continue;
+				}
+
+				MPCameraModeList *new_item =
+					malloc(sizeof(MPCameraModeList));
+				new_item->mode = mode;
+				new_item->next = item;
+				item = new_item;
+			}
+		}
+	}
+
+	return item;
 }
 
 static MPCameraModeList *
 get_video_modes(MPCamera *camera, bool (*check)(MPCamera *, MPCameraMode *))
 {
-    MPCameraModeList *item = NULL;
-
-    for (uint32_t fmt_index = 0;; ++fmt_index) {
-        struct v4l2_fmtdesc fmt = {};
-        fmt.index = fmt_index;
-        fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-        if (xioctl(camera->video_fd, VIDIOC_ENUM_FMT, &fmt) == -1) {
-            if (errno != EINVAL) {
-                errno_printerr("VIDIOC_ENUM_FMT");
-            }
-            break;
-        }
-
-        // Skip unsupported formats
-        uint32_t format = mp_pixel_format_from_v4l_pixel_format(fmt.pixelformat);
-        if (format == MP_PIXEL_FMT_UNSUPPORTED) {
-            continue;
-        }
-
-        for (uint32_t frame_index = 0;; ++frame_index) {
-            struct v4l2_frmsizeenum frame = {};
-            frame.index = frame_index;
-            frame.pixel_format = fmt.pixelformat;
-            if (xioctl(camera->video_fd, VIDIOC_ENUM_FRAMESIZES, &frame) == -1) {
-                if (errno != EINVAL) {
-                    errno_printerr("VIDIOC_ENUM_FRAMESIZES");
-                }
-                break;
-            }
-
-            // TODO: Handle other types
-            if (frame.type != V4L2_FRMSIZE_TYPE_DISCRETE) {
-                break;
-            }
-
-            for (uint32_t interval_index = 0;; ++interval_index) {
-                struct v4l2_frmivalenum interval = {};
-                interval.index = interval_index;
-                interval.pixel_format = fmt.pixelformat;
-                interval.width = frame.discrete.width;
-                interval.height = frame.discrete.height;
-                if (xioctl(camera->video_fd, VIDIOC_ENUM_FRAMEINTERVALS, &interval) == -1) {
-                    if (errno != EINVAL) {
-                        errno_printerr("VIDIOC_ENUM_FRAMESIZES");
-                    }
-                    break;
-                }
-
-                // TODO: Handle other types
-                if (interval.type != V4L2_FRMIVAL_TYPE_DISCRETE) {
-                    break;
-                }
-
-                MPCameraMode mode = {
-                    .pixel_format = format,
-                    .frame_interval = interval.discrete,
-                    .width = frame.discrete.width,
-                    .height = frame.discrete.height,
-                };
-
-                if (!check(camera, &mode)) {
-                    continue;
-                }
-
-                MPCameraModeList *new_item = malloc(sizeof(MPCameraModeList));
-                new_item->mode = mode;
-                new_item->next = item;
-                item = new_item;
-            }
-        }
-    }
-
-    return item;
+	MPCameraModeList *item = NULL;
+
+	for (uint32_t fmt_index = 0;; ++fmt_index) {
+		struct v4l2_fmtdesc fmt = {};
+		fmt.index = fmt_index;
+		fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+		if (xioctl(camera->video_fd, VIDIOC_ENUM_FMT, &fmt) == -1) {
+			if (errno != EINVAL) {
+				errno_printerr("VIDIOC_ENUM_FMT");
+			}
+			break;
+		}
+
+		// Skip unsupported formats
+		uint32_t format =
+			mp_pixel_format_from_v4l_pixel_format(fmt.pixelformat);
+		if (format == MP_PIXEL_FMT_UNSUPPORTED) {
+			continue;
+		}
+
+		for (uint32_t frame_index = 0;; ++frame_index) {
+			struct v4l2_frmsizeenum frame = {};
+			frame.index = frame_index;
+			frame.pixel_format = fmt.pixelformat;
+			if (xioctl(camera->video_fd, VIDIOC_ENUM_FRAMESIZES,
+				   &frame) == -1) {
+				if (errno != EINVAL) {
+					errno_printerr("VIDIOC_ENUM_FRAMESIZES");
+				}
+				break;
+			}
+
+			// TODO: Handle other types
+			if (frame.type != V4L2_FRMSIZE_TYPE_DISCRETE) {
+				break;
+			}
+
+			for (uint32_t interval_index = 0;; ++interval_index) {
+				struct v4l2_frmivalenum interval = {};
+				interval.index = interval_index;
+				interval.pixel_format = fmt.pixelformat;
+				interval.width = frame.discrete.width;
+				interval.height = frame.discrete.height;
+				if (xioctl(camera->video_fd,
+					   VIDIOC_ENUM_FRAMEINTERVALS,
+					   &interval) == -1) {
+					if (errno != EINVAL) {
+						errno_printerr(
+							"VIDIOC_ENUM_FRAMESIZES");
+					}
+					break;
+				}
+
+				// TODO: Handle other types
+				if (interval.type != V4L2_FRMIVAL_TYPE_DISCRETE) {
+					break;
+				}
+
+				MPCameraMode mode = {
+					.pixel_format = format,
+					.frame_interval = interval.discrete,
+					.width = frame.discrete.width,
+					.height = frame.discrete.height,
+				};
+
+				if (!check(camera, &mode)) {
+					continue;
+				}
+
+				MPCameraModeList *new_item =
+					malloc(sizeof(MPCameraModeList));
+				new_item->mode = mode;
+				new_item->next = item;
+				item = new_item;
+			}
+		}
+	}
+
+	return item;
 }
 
-static bool all_modes(MPCamera *camera, MPCameraMode *mode)
+static bool
+all_modes(MPCamera *camera, MPCameraMode *mode)
 {
-    return true;
+	return true;
 }
 
-static bool available_modes(MPCamera *camera, MPCameraMode *mode)
+static bool
+available_modes(MPCamera *camera, MPCameraMode *mode)
 {
-    MPCameraMode attempt = *mode;
-    return mp_camera_try_mode(camera, &attempt)
-        && mp_camera_mode_is_equivalent(mode, &attempt);
+	MPCameraMode attempt = *mode;
+	return mp_camera_try_mode(camera, &attempt) &&
+	       mp_camera_mode_is_equivalent(mode, &attempt);
 }
 
-MPCameraModeList *mp_camera_list_supported_modes(MPCamera *camera)
+MPCameraModeList *
+mp_camera_list_supported_modes(MPCamera *camera)
 {
-    if (mp_camera_is_subdev(camera)) {
-        return get_subdev_modes(camera, all_modes);
-    } else {
-        return get_video_modes(camera, all_modes);
-    }
+	if (mp_camera_is_subdev(camera)) {
+		return get_subdev_modes(camera, all_modes);
+	} else {
+		return get_video_modes(camera, all_modes);
+	}
 }
 
-MPCameraModeList *mp_camera_list_available_modes(MPCamera *camera)
+MPCameraModeList *
+mp_camera_list_available_modes(MPCamera *camera)
 {
-    if (mp_camera_is_subdev(camera)) {
-        return get_subdev_modes(camera, available_modes);
-    } else {
-        return get_video_modes(camera, available_modes);
-    }
+	if (mp_camera_is_subdev(camera)) {
+		return get_subdev_modes(camera, available_modes);
+	} else {
+		return get_video_modes(camera, available_modes);
+	}
 }
 
-MPCameraMode *mp_camera_mode_list_get(MPCameraModeList *list)
+MPCameraMode *
+mp_camera_mode_list_get(MPCameraModeList *list)
 {
-    g_return_val_if_fail(list, NULL);
-    return &list->mode;
+	g_return_val_if_fail(list, NULL);
+	return &list->mode;
 }
 
-MPCameraModeList *mp_camera_mode_list_next(MPCameraModeList *list)
+MPCameraModeList *
+mp_camera_mode_list_next(MPCameraModeList *list)
 {
-    g_return_val_if_fail(list, NULL);
-    return list->next;
+	g_return_val_if_fail(list, NULL);
+	return list->next;
 }
 
-void mp_camera_mode_list_free(MPCameraModeList *list)
+void
+mp_camera_mode_list_free(MPCameraModeList *list)
 {
-    while (list) {
-        MPCameraModeList *tmp = list;
-        list = tmp->next;
-        free(tmp);
-    }
+	while (list) {
+		MPCameraModeList *tmp = list;
+		list = tmp->next;
+		free(tmp);
+	}
 }
 
 struct int_str_pair {
-    uint32_t value;
-    const char *str;
+	uint32_t value;
+	const char *str;
 };
 
 struct int_str_pair control_id_names[] = {
-    { V4L2_CID_BRIGHTNESS, "BRIGHTNESS" },
-    { V4L2_CID_CONTRAST, "CONTRAST" },
-    { V4L2_CID_SATURATION, "SATURATION" },
-    { V4L2_CID_HUE, "HUE" },
-    { V4L2_CID_AUDIO_VOLUME, "AUDIO_VOLUME" },
-    { V4L2_CID_AUDIO_BALANCE, "AUDIO_BALANCE" },
-    { V4L2_CID_AUDIO_BASS, "AUDIO_BASS" },
-    { V4L2_CID_AUDIO_TREBLE, "AUDIO_TREBLE" },
-    { V4L2_CID_AUDIO_MUTE, "AUDIO_MUTE" },
-    { V4L2_CID_AUDIO_LOUDNESS, "AUDIO_LOUDNESS" },
-    { V4L2_CID_BLACK_LEVEL, "BLACK_LEVEL" },
-    { V4L2_CID_AUTO_WHITE_BALANCE, "AUTO_WHITE_BALANCE" },
-    { V4L2_CID_DO_WHITE_BALANCE, "DO_WHITE_BALANCE" },
-    { V4L2_CID_RED_BALANCE, "RED_BALANCE" },
-    { V4L2_CID_BLUE_BALANCE, "BLUE_BALANCE" },
-    { V4L2_CID_GAMMA, "GAMMA" },
-    { V4L2_CID_WHITENESS, "WHITENESS" },
-    { V4L2_CID_EXPOSURE, "EXPOSURE" },
-    { V4L2_CID_AUTOGAIN, "AUTOGAIN" },
-    { V4L2_CID_GAIN, "GAIN" },
-    { V4L2_CID_HFLIP, "HFLIP" },
-    { V4L2_CID_VFLIP, "VFLIP" },
-    { V4L2_CID_POWER_LINE_FREQUENCY, "POWER_LINE_FREQUENCY" },
-    { V4L2_CID_HUE_AUTO, "HUE_AUTO" },
-    { V4L2_CID_WHITE_BALANCE_TEMPERATURE, "WHITE_BALANCE_TEMPERATURE" },
-    { V4L2_CID_SHARPNESS, "SHARPNESS" },
-    { V4L2_CID_BACKLIGHT_COMPENSATION, "BACKLIGHT_COMPENSATION" },
-    { V4L2_CID_CHROMA_AGC, "CHROMA_AGC" },
-    { V4L2_CID_COLOR_KILLER, "COLOR_KILLER" },
-    { V4L2_CID_COLORFX, "COLORFX" },
-    { V4L2_CID_AUTOBRIGHTNESS, "AUTOBRIGHTNESS" },
-    { V4L2_CID_BAND_STOP_FILTER, "BAND_STOP_FILTER" },
-    { V4L2_CID_ROTATE, "ROTATE" },
-    { V4L2_CID_BG_COLOR, "BG_COLOR" },
-    { V4L2_CID_CHROMA_GAIN, "CHROMA_GAIN" },
-    { V4L2_CID_ILLUMINATORS_1, "ILLUMINATORS_1" },
-    { V4L2_CID_ILLUMINATORS_2, "ILLUMINATORS_2" },
-    { V4L2_CID_MIN_BUFFERS_FOR_CAPTURE, "MIN_BUFFERS_FOR_CAPTURE" },
-    { V4L2_CID_MIN_BUFFERS_FOR_OUTPUT, "MIN_BUFFERS_FOR_OUTPUT" },
-    { V4L2_CID_ALPHA_COMPONENT, "ALPHA_COMPONENT" },
-    { V4L2_CID_COLORFX_CBCR, "COLORFX_CBCR" },
-    { V4L2_CID_LASTP1, "LASTP1" },
-    { V4L2_CID_USER_MEYE_BASE, "USER_MEYE_BASE" },
-    { V4L2_CID_USER_BTTV_BASE, "USER_BTTV_BASE" },
-    { V4L2_CID_USER_S2255_BASE, "USER_S2255_BASE" },
-    { V4L2_CID_USER_SI476X_BASE, "USER_SI476X_BASE" },
-    { V4L2_CID_USER_TI_VPE_BASE, "USER_TI_VPE_BASE" },
-    { V4L2_CID_USER_SAA7134_BASE, "USER_SAA7134_BASE" },
-    { V4L2_CID_USER_ADV7180_BASE, "USER_ADV7180_BASE" },
-    { V4L2_CID_USER_TC358743_BASE, "USER_TC358743_BASE" },
-    { V4L2_CID_USER_MAX217X_BASE, "USER_MAX217X_BASE" },
-    { V4L2_CID_USER_IMX_BASE, "USER_IMX_BASE" },
-    // { V4L2_CID_USER_ATMEL_ISC_BASE, "USER_ATMEL_ISC_BASE" },
-    { V4L2_CID_CAMERA_CLASS_BASE, "CAMERA_CLASS_BASE" },
-    { V4L2_CID_CAMERA_CLASS, "CAMERA_CLASS" },
-    { V4L2_CID_EXPOSURE_AUTO, "EXPOSURE_AUTO" },
-    { V4L2_CID_EXPOSURE_ABSOLUTE, "EXPOSURE_ABSOLUTE" },
-    { V4L2_CID_EXPOSURE_AUTO_PRIORITY, "EXPOSURE_AUTO_PRIORITY" },
-    { V4L2_CID_PAN_RELATIVE, "PAN_RELATIVE" },
-    { V4L2_CID_TILT_RELATIVE, "TILT_RELATIVE" },
-    { V4L2_CID_PAN_RESET, "PAN_RESET" },
-    { V4L2_CID_TILT_RESET, "TILT_RESET" },
-    { V4L2_CID_PAN_ABSOLUTE, "PAN_ABSOLUTE" },
-    { V4L2_CID_TILT_ABSOLUTE, "TILT_ABSOLUTE" },
-    { V4L2_CID_FOCUS_ABSOLUTE, "FOCUS_ABSOLUTE" },
-    { V4L2_CID_FOCUS_RELATIVE, "FOCUS_RELATIVE" },
-    { V4L2_CID_FOCUS_AUTO, "FOCUS_AUTO" },
-    { V4L2_CID_ZOOM_ABSOLUTE, "ZOOM_ABSOLUTE" },
-    { V4L2_CID_ZOOM_RELATIVE, "ZOOM_RELATIVE" },
-    { V4L2_CID_ZOOM_CONTINUOUS, "ZOOM_CONTINUOUS" },
-    { V4L2_CID_PRIVACY, "PRIVACY" },
-    { V4L2_CID_IRIS_ABSOLUTE, "IRIS_ABSOLUTE" },
-    { V4L2_CID_IRIS_RELATIVE, "IRIS_RELATIVE" },
-    { V4L2_CID_AUTO_EXPOSURE_BIAS, "AUTO_EXPOSURE_BIAS" },
-    { V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE, "AUTO_N_PRESET_WHITE_BALANCE" },
-    { V4L2_CID_WIDE_DYNAMIC_RANGE, "WIDE_DYNAMIC_RANGE" },
-    { V4L2_CID_IMAGE_STABILIZATION, "IMAGE_STABILIZATION" },
-    { V4L2_CID_ISO_SENSITIVITY, "ISO_SENSITIVITY" },
-    { V4L2_CID_ISO_SENSITIVITY_AUTO, "ISO_SENSITIVITY_AUTO" },
-    { V4L2_CID_EXPOSURE_METERING, "EXPOSURE_METERING" },
-    { V4L2_CID_SCENE_MODE, "SCENE_MODE" },
-    { V4L2_CID_3A_LOCK, "3A_LOCK" },
-    { V4L2_CID_AUTO_FOCUS_START, "AUTO_FOCUS_START" },
-    { V4L2_CID_AUTO_FOCUS_STOP, "AUTO_FOCUS_STOP" },
-    { V4L2_CID_AUTO_FOCUS_STATUS, "AUTO_FOCUS_STATUS" },
-    { V4L2_CID_AUTO_FOCUS_RANGE, "AUTO_FOCUS_RANGE" },
-    { V4L2_CID_PAN_SPEED, "PAN_SPEED" },
-    { V4L2_CID_TILT_SPEED, "TILT_SPEED" },
-    // { V4L2_CID_CAMERA_ORIENTATION, "CAMERA_ORIENTATION" },
-    // { V4L2_CID_CAMERA_SENSOR_ROTATION, "CAMERA_SENSOR_ROTATION" },
-    { V4L2_CID_FLASH_LED_MODE, "FLASH_LED_MODE" },
-    { V4L2_CID_FLASH_STROBE_SOURCE, "FLASH_STROBE_SOURCE" },
-    { V4L2_CID_FLASH_STROBE, "FLASH_STROBE" },
-    { V4L2_CID_FLASH_STROBE_STOP, "FLASH_STROBE_STOP" },
-    { V4L2_CID_FLASH_STROBE_STATUS, "FLASH_STROBE_STATUS" },
-    { V4L2_CID_FLASH_TIMEOUT, "FLASH_TIMEOUT" },
-    { V4L2_CID_FLASH_INTENSITY, "FLASH_INTENSITY" },
-    { V4L2_CID_FLASH_TORCH_INTENSITY, "FLASH_TORCH_INTENSITY" },
-    { V4L2_CID_FLASH_INDICATOR_INTENSITY, "FLASH_INDICATOR_INTENSITY" },
-    { V4L2_CID_FLASH_FAULT, "FLASH_FAULT" },
-    { V4L2_CID_FLASH_CHARGE, "FLASH_CHARGE" },
-    { V4L2_CID_FLASH_READY, "FLASH_READY" },
+	{ V4L2_CID_BRIGHTNESS, "BRIGHTNESS" },
+	{ V4L2_CID_CONTRAST, "CONTRAST" },
+	{ V4L2_CID_SATURATION, "SATURATION" },
+	{ V4L2_CID_HUE, "HUE" },
+	{ V4L2_CID_AUDIO_VOLUME, "AUDIO_VOLUME" },
+	{ V4L2_CID_AUDIO_BALANCE, "AUDIO_BALANCE" },
+	{ V4L2_CID_AUDIO_BASS, "AUDIO_BASS" },
+	{ V4L2_CID_AUDIO_TREBLE, "AUDIO_TREBLE" },
+	{ V4L2_CID_AUDIO_MUTE, "AUDIO_MUTE" },
+	{ V4L2_CID_AUDIO_LOUDNESS, "AUDIO_LOUDNESS" },
+	{ V4L2_CID_BLACK_LEVEL, "BLACK_LEVEL" },
+	{ V4L2_CID_AUTO_WHITE_BALANCE, "AUTO_WHITE_BALANCE" },
+	{ V4L2_CID_DO_WHITE_BALANCE, "DO_WHITE_BALANCE" },
+	{ V4L2_CID_RED_BALANCE, "RED_BALANCE" },
+	{ V4L2_CID_BLUE_BALANCE, "BLUE_BALANCE" },
+	{ V4L2_CID_GAMMA, "GAMMA" },
+	{ V4L2_CID_WHITENESS, "WHITENESS" },
+	{ V4L2_CID_EXPOSURE, "EXPOSURE" },
+	{ V4L2_CID_AUTOGAIN, "AUTOGAIN" },
+	{ V4L2_CID_GAIN, "GAIN" },
+	{ V4L2_CID_HFLIP, "HFLIP" },
+	{ V4L2_CID_VFLIP, "VFLIP" },
+	{ V4L2_CID_POWER_LINE_FREQUENCY, "POWER_LINE_FREQUENCY" },
+	{ V4L2_CID_HUE_AUTO, "HUE_AUTO" },
+	{ V4L2_CID_WHITE_BALANCE_TEMPERATURE, "WHITE_BALANCE_TEMPERATURE" },
+	{ V4L2_CID_SHARPNESS, "SHARPNESS" },
+	{ V4L2_CID_BACKLIGHT_COMPENSATION, "BACKLIGHT_COMPENSATION" },
+	{ V4L2_CID_CHROMA_AGC, "CHROMA_AGC" },
+	{ V4L2_CID_COLOR_KILLER, "COLOR_KILLER" },
+	{ V4L2_CID_COLORFX, "COLORFX" },
+	{ V4L2_CID_AUTOBRIGHTNESS, "AUTOBRIGHTNESS" },
+	{ V4L2_CID_BAND_STOP_FILTER, "BAND_STOP_FILTER" },
+	{ V4L2_CID_ROTATE, "ROTATE" },
+	{ V4L2_CID_BG_COLOR, "BG_COLOR" },
+	{ V4L2_CID_CHROMA_GAIN, "CHROMA_GAIN" },
+	{ V4L2_CID_ILLUMINATORS_1, "ILLUMINATORS_1" },
+	{ V4L2_CID_ILLUMINATORS_2, "ILLUMINATORS_2" },
+	{ V4L2_CID_MIN_BUFFERS_FOR_CAPTURE, "MIN_BUFFERS_FOR_CAPTURE" },
+	{ V4L2_CID_MIN_BUFFERS_FOR_OUTPUT, "MIN_BUFFERS_FOR_OUTPUT" },
+	{ V4L2_CID_ALPHA_COMPONENT, "ALPHA_COMPONENT" },
+	{ V4L2_CID_COLORFX_CBCR, "COLORFX_CBCR" },
+	{ V4L2_CID_LASTP1, "LASTP1" },
+	{ V4L2_CID_USER_MEYE_BASE, "USER_MEYE_BASE" },
+	{ V4L2_CID_USER_BTTV_BASE, "USER_BTTV_BASE" },
+	{ V4L2_CID_USER_S2255_BASE, "USER_S2255_BASE" },
+	{ V4L2_CID_USER_SI476X_BASE, "USER_SI476X_BASE" },
+	{ V4L2_CID_USER_TI_VPE_BASE, "USER_TI_VPE_BASE" },
+	{ V4L2_CID_USER_SAA7134_BASE, "USER_SAA7134_BASE" },
+	{ V4L2_CID_USER_ADV7180_BASE, "USER_ADV7180_BASE" },
+	{ V4L2_CID_USER_TC358743_BASE, "USER_TC358743_BASE" },
+	{ V4L2_CID_USER_MAX217X_BASE, "USER_MAX217X_BASE" },
+	{ V4L2_CID_USER_IMX_BASE, "USER_IMX_BASE" },
+	// { V4L2_CID_USER_ATMEL_ISC_BASE, "USER_ATMEL_ISC_BASE" },
+	{ V4L2_CID_CAMERA_CLASS_BASE, "CAMERA_CLASS_BASE" },
+	{ V4L2_CID_CAMERA_CLASS, "CAMERA_CLASS" },
+	{ V4L2_CID_EXPOSURE_AUTO, "EXPOSURE_AUTO" },
+	{ V4L2_CID_EXPOSURE_ABSOLUTE, "EXPOSURE_ABSOLUTE" },
+	{ V4L2_CID_EXPOSURE_AUTO_PRIORITY, "EXPOSURE_AUTO_PRIORITY" },
+	{ V4L2_CID_PAN_RELATIVE, "PAN_RELATIVE" },
+	{ V4L2_CID_TILT_RELATIVE, "TILT_RELATIVE" },
+	{ V4L2_CID_PAN_RESET, "PAN_RESET" },
+	{ V4L2_CID_TILT_RESET, "TILT_RESET" },
+	{ V4L2_CID_PAN_ABSOLUTE, "PAN_ABSOLUTE" },
+	{ V4L2_CID_TILT_ABSOLUTE, "TILT_ABSOLUTE" },
+	{ V4L2_CID_FOCUS_ABSOLUTE, "FOCUS_ABSOLUTE" },
+	{ V4L2_CID_FOCUS_RELATIVE, "FOCUS_RELATIVE" },
+	{ V4L2_CID_FOCUS_AUTO, "FOCUS_AUTO" },
+	{ V4L2_CID_ZOOM_ABSOLUTE, "ZOOM_ABSOLUTE" },
+	{ V4L2_CID_ZOOM_RELATIVE, "ZOOM_RELATIVE" },
+	{ V4L2_CID_ZOOM_CONTINUOUS, "ZOOM_CONTINUOUS" },
+	{ V4L2_CID_PRIVACY, "PRIVACY" },
+	{ V4L2_CID_IRIS_ABSOLUTE, "IRIS_ABSOLUTE" },
+	{ V4L2_CID_IRIS_RELATIVE, "IRIS_RELATIVE" },
+	{ V4L2_CID_AUTO_EXPOSURE_BIAS, "AUTO_EXPOSURE_BIAS" },
+	{ V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE, "AUTO_N_PRESET_WHITE_BALANCE" },
+	{ V4L2_CID_WIDE_DYNAMIC_RANGE, "WIDE_DYNAMIC_RANGE" },
+	{ V4L2_CID_IMAGE_STABILIZATION, "IMAGE_STABILIZATION" },
+	{ V4L2_CID_ISO_SENSITIVITY, "ISO_SENSITIVITY" },
+	{ V4L2_CID_ISO_SENSITIVITY_AUTO, "ISO_SENSITIVITY_AUTO" },
+	{ V4L2_CID_EXPOSURE_METERING, "EXPOSURE_METERING" },
+	{ V4L2_CID_SCENE_MODE, "SCENE_MODE" },
+	{ V4L2_CID_3A_LOCK, "3A_LOCK" },
+	{ V4L2_CID_AUTO_FOCUS_START, "AUTO_FOCUS_START" },
+	{ V4L2_CID_AUTO_FOCUS_STOP, "AUTO_FOCUS_STOP" },
+	{ V4L2_CID_AUTO_FOCUS_STATUS, "AUTO_FOCUS_STATUS" },
+	{ V4L2_CID_AUTO_FOCUS_RANGE, "AUTO_FOCUS_RANGE" },
+	{ V4L2_CID_PAN_SPEED, "PAN_SPEED" },
+	{ V4L2_CID_TILT_SPEED, "TILT_SPEED" },
+	// { V4L2_CID_CAMERA_ORIENTATION, "CAMERA_ORIENTATION" },
+	// { V4L2_CID_CAMERA_SENSOR_ROTATION, "CAMERA_SENSOR_ROTATION" },
+	{ V4L2_CID_FLASH_LED_MODE, "FLASH_LED_MODE" },
+	{ V4L2_CID_FLASH_STROBE_SOURCE, "FLASH_STROBE_SOURCE" },
+	{ V4L2_CID_FLASH_STROBE, "FLASH_STROBE" },
+	{ V4L2_CID_FLASH_STROBE_STOP, "FLASH_STROBE_STOP" },
+	{ V4L2_CID_FLASH_STROBE_STATUS, "FLASH_STROBE_STATUS" },
+	{ V4L2_CID_FLASH_TIMEOUT, "FLASH_TIMEOUT" },
+	{ V4L2_CID_FLASH_INTENSITY, "FLASH_INTENSITY" },
+	{ V4L2_CID_FLASH_TORCH_INTENSITY, "FLASH_TORCH_INTENSITY" },
+	{ V4L2_CID_FLASH_INDICATOR_INTENSITY, "FLASH_INDICATOR_INTENSITY" },
+	{ V4L2_CID_FLASH_FAULT, "FLASH_FAULT" },
+	{ V4L2_CID_FLASH_CHARGE, "FLASH_CHARGE" },
+	{ V4L2_CID_FLASH_READY, "FLASH_READY" },
 };
 
-const char *mp_control_id_to_str(uint32_t id)
+const char *
+mp_control_id_to_str(uint32_t id)
 {
-    size_t size = sizeof(control_id_names) / sizeof(*control_id_names);
+	size_t size = sizeof(control_id_names) / sizeof(*control_id_names);
 
-    for (size_t i = 0; i < size; ++i) {
-        if (control_id_names[i].value == id) {
-            return control_id_names[i].str;
-        }
-    }
+	for (size_t i = 0; i < size; ++i) {
+		if (control_id_names[i].value == id) {
+			return control_id_names[i].str;
+		}
+	}
 
-    return "UNKNOWN";
+	return "UNKNOWN";
 }
 
 struct int_str_pair control_type_names[] = {
-    { V4L2_CTRL_TYPE_INTEGER, "INTEGER" },
-    { V4L2_CTRL_TYPE_BOOLEAN, "BOOLEAN" },
-    { V4L2_CTRL_TYPE_MENU, "MENU" },
-    { V4L2_CTRL_TYPE_INTEGER_MENU, "INTEGER_MENU" },
-    { V4L2_CTRL_TYPE_BITMASK, "BITMASK" },
-    { V4L2_CTRL_TYPE_BUTTON, "BUTTON" },
-    { V4L2_CTRL_TYPE_INTEGER64, "INTEGER64" },
-    { V4L2_CTRL_TYPE_STRING, "STRING" },
-    { V4L2_CTRL_TYPE_CTRL_CLASS, "CTRL_CLASS" },
-    { V4L2_CTRL_TYPE_U8, "U8" },
-    { V4L2_CTRL_TYPE_U16, "U16" },
-    { V4L2_CTRL_TYPE_U32, "U32" },
-    // { V4L2_CTRL_TYPE_MPEG2_SLICE_PARAMS, "MPEG2_SLICE_PARAMS" },
-    // { V4L2_CTRL_TYPE_MPEG2_QUANTIZATION, "MPEG2_QUANTIZATION" },
-    // { V4L2_CTRL_TYPE_AREA, "AREA" },
-    // { V4L2_CTRL_TYPE_H264_SPS, "H264_SPS" },
-    // { V4L2_CTRL_TYPE_H264_PPS, "H264_PPS" },
-    // { V4L2_CTRL_TYPE_H264_SCALING_MATRIX, "H264_SCALING_MATRIX" },
-    // { V4L2_CTRL_TYPE_H264_SLICE_PARAMS, "H264_SLICE_PARAMS" },
-    // { V4L2_CTRL_TYPE_H264_DECODE_PARAMS, "H264_DECODE_PARAMS" },
-    // { V4L2_CTRL_TYPE_HEVC_SPS, "HEVC_SPS" },
-    // { V4L2_CTRL_TYPE_HEVC_PPS, "HEVC_PPS" },
-    // { V4L2_CTRL_TYPE_HEVC_SLICE_PARAMS, "HEVC_SLICE_PARAMS" },
+	{ V4L2_CTRL_TYPE_INTEGER, "INTEGER" },
+	{ V4L2_CTRL_TYPE_BOOLEAN, "BOOLEAN" },
+	{ V4L2_CTRL_TYPE_MENU, "MENU" },
+	{ V4L2_CTRL_TYPE_INTEGER_MENU, "INTEGER_MENU" },
+	{ V4L2_CTRL_TYPE_BITMASK, "BITMASK" },
+	{ V4L2_CTRL_TYPE_BUTTON, "BUTTON" },
+	{ V4L2_CTRL_TYPE_INTEGER64, "INTEGER64" },
+	{ V4L2_CTRL_TYPE_STRING, "STRING" },
+	{ V4L2_CTRL_TYPE_CTRL_CLASS, "CTRL_CLASS" },
+	{ V4L2_CTRL_TYPE_U8, "U8" },
+	{ V4L2_CTRL_TYPE_U16, "U16" },
+	{ V4L2_CTRL_TYPE_U32, "U32" },
+	// { V4L2_CTRL_TYPE_MPEG2_SLICE_PARAMS, "MPEG2_SLICE_PARAMS" },
+	// { V4L2_CTRL_TYPE_MPEG2_QUANTIZATION, "MPEG2_QUANTIZATION" },
+	// { V4L2_CTRL_TYPE_AREA, "AREA" },
+	// { V4L2_CTRL_TYPE_H264_SPS, "H264_SPS" },
+	// { V4L2_CTRL_TYPE_H264_PPS, "H264_PPS" },
+	// { V4L2_CTRL_TYPE_H264_SCALING_MATRIX, "H264_SCALING_MATRIX" },
+	// { V4L2_CTRL_TYPE_H264_SLICE_PARAMS, "H264_SLICE_PARAMS" },
+	// { V4L2_CTRL_TYPE_H264_DECODE_PARAMS, "H264_DECODE_PARAMS" },
+	// { V4L2_CTRL_TYPE_HEVC_SPS, "HEVC_SPS" },
+	// { V4L2_CTRL_TYPE_HEVC_PPS, "HEVC_PPS" },
+	// { V4L2_CTRL_TYPE_HEVC_SLICE_PARAMS, "HEVC_SLICE_PARAMS" },
 };
 
-const char *mp_control_type_to_str(uint32_t type)
+const char *
+mp_control_type_to_str(uint32_t type)
 {
-    size_t size = sizeof(control_type_names) / sizeof(*control_type_names);
+	size_t size = sizeof(control_type_names) / sizeof(*control_type_names);
 
-    for (size_t i = 0; i < size; ++i) {
-        if (control_type_names[i].value == type) {
-            return control_type_names[i].str;
-        }
-    }
+	for (size_t i = 0; i < size; ++i) {
+		if (control_type_names[i].value == type) {
+			return control_type_names[i].str;
+		}
+	}
 
-    return "UNKNOWN";
+	return "UNKNOWN";
 }
 
 struct _MPControlList {
-    MPControl control;
-    MPControlList *next;
+	MPControl control;
+	MPControlList *next;
 };
 
-static int control_fd(MPCamera *camera)
+static int
+control_fd(MPCamera *camera)
 {
-    if (camera->subdev_fd != -1) {
-        return camera->subdev_fd;
-    }
-    return camera->video_fd;
+	if (camera->subdev_fd != -1) {
+		return camera->subdev_fd;
+	}
+	return camera->video_fd;
 }
 
-MPControlList *mp_camera_list_controls(MPCamera *camera)
+MPControlList *
+mp_camera_list_controls(MPCamera *camera)
 {
-    MPControlList *item = NULL;
-
-    struct v4l2_query_ext_ctrl ctrl = {};
-    ctrl.id = V4L2_CTRL_FLAG_NEXT_CTRL | V4L2_CTRL_FLAG_NEXT_COMPOUND;
-    while (true) {
-        if (xioctl(control_fd(camera), VIDIOC_QUERY_EXT_CTRL, &ctrl) == -1) {
-            if (errno != EINVAL) {
-                errno_printerr("VIDIOC_QUERY_EXT_CTRL");
-            }
-            break;
-        }
-
-        MPControl control = {
-            .id = ctrl.id,
-            .type = ctrl.type,
-            .name = {},
-            .min = ctrl.minimum,
-            .max = ctrl.maximum,
-            .step = ctrl.step,
-            .default_value = ctrl.default_value,
-            .flags = ctrl.flags,
-            .element_size = ctrl.elem_size,
-            .element_count = ctrl.elems,
-            .dimensions_count = ctrl.nr_of_dims,
-            .dimensions = {},
-        };
-
-        strcpy(control.name, ctrl.name);
-        memcpy(control.dimensions, ctrl.dims, sizeof(uint32_t) * V4L2_CTRL_MAX_DIMS);
-
-        MPControlList *new_item = malloc(sizeof(MPControlList));
-        new_item->control = control;
-        new_item->next = item;
-        item = new_item;
-
-        ctrl.id |= V4L2_CTRL_FLAG_NEXT_CTRL | V4L2_CTRL_FLAG_NEXT_COMPOUND;
-    }
-
-    return item;
+	MPControlList *item = NULL;
+
+	struct v4l2_query_ext_ctrl ctrl = {};
+	ctrl.id = V4L2_CTRL_FLAG_NEXT_CTRL | V4L2_CTRL_FLAG_NEXT_COMPOUND;
+	while (true) {
+		if (xioctl(control_fd(camera), VIDIOC_QUERY_EXT_CTRL, &ctrl) == -1) {
+			if (errno != EINVAL) {
+				errno_printerr("VIDIOC_QUERY_EXT_CTRL");
+			}
+			break;
+		}
+
+		MPControl control = {
+			.id = ctrl.id,
+			.type = ctrl.type,
+			.name = {},
+			.min = ctrl.minimum,
+			.max = ctrl.maximum,
+			.step = ctrl.step,
+			.default_value = ctrl.default_value,
+			.flags = ctrl.flags,
+			.element_size = ctrl.elem_size,
+			.element_count = ctrl.elems,
+			.dimensions_count = ctrl.nr_of_dims,
+			.dimensions = {},
+		};
+
+		strcpy(control.name, ctrl.name);
+		memcpy(control.dimensions, ctrl.dims,
+		       sizeof(uint32_t) * V4L2_CTRL_MAX_DIMS);
+
+		MPControlList *new_item = malloc(sizeof(MPControlList));
+		new_item->control = control;
+		new_item->next = item;
+		item = new_item;
+
+		ctrl.id |= V4L2_CTRL_FLAG_NEXT_CTRL | V4L2_CTRL_FLAG_NEXT_COMPOUND;
+	}
+
+	return item;
 }
 
-MPControl *mp_control_list_get(MPControlList *list)
+MPControl *
+mp_control_list_get(MPControlList *list)
 {
-    g_return_val_if_fail(list, NULL);
-    return &list->control;
+	g_return_val_if_fail(list, NULL);
+	return &list->control;
 }
 
-MPControlList *mp_control_list_next(MPControlList *list)
+MPControlList *
+mp_control_list_next(MPControlList *list)
 {
-    g_return_val_if_fail(list, NULL);
-    return list->next;
+	g_return_val_if_fail(list, NULL);
+	return list->next;
 }
 
-void mp_control_list_free(MPControlList *list)
+void
+mp_control_list_free(MPControlList *list)
 {
-    while (list) {
-        MPControlList *tmp = list;
-        list = tmp->next;
-        free(tmp);
-    }
+	while (list) {
+		MPControlList *tmp = list;
+		list = tmp->next;
+		free(tmp);
+	}
 }
 
-bool mp_camera_query_control(MPCamera *camera, uint32_t id, MPControl *control)
+bool
+mp_camera_query_control(MPCamera *camera, uint32_t id, MPControl *control)
 {
-    struct v4l2_query_ext_ctrl ctrl = {};
-    ctrl.id = id;
-    if (xioctl(control_fd(camera), VIDIOC_QUERY_EXT_CTRL, &ctrl) == -1) {
-        if (errno != EINVAL) {
-            errno_printerr("VIDIOC_QUERY_EXT_CTRL");
-        }
-        return false;
-    }
-
-    if (control) {
-        control->id = ctrl.id;
-        control->type = ctrl.type;
-        strcpy(control->name, ctrl.name);
-        control->min = ctrl.minimum;
-        control->max = ctrl.maximum;
-        control->step = ctrl.step;
-        control->default_value = ctrl.default_value;
-        control->flags = ctrl.flags;
-        control->element_size = ctrl.elem_size;
-        control->element_count = ctrl.elems;
-        control->dimensions_count = ctrl.nr_of_dims;
-        memcpy(control->dimensions, ctrl.dims, sizeof(uint32_t) * V4L2_CTRL_MAX_DIMS);
-    }
-    return true;
+	struct v4l2_query_ext_ctrl ctrl = {};
+	ctrl.id = id;
+	if (xioctl(control_fd(camera), VIDIOC_QUERY_EXT_CTRL, &ctrl) == -1) {
+		if (errno != EINVAL) {
+			errno_printerr("VIDIOC_QUERY_EXT_CTRL");
+		}
+		return false;
+	}
+
+	if (control) {
+		control->id = ctrl.id;
+		control->type = ctrl.type;
+		strcpy(control->name, ctrl.name);
+		control->min = ctrl.minimum;
+		control->max = ctrl.maximum;
+		control->step = ctrl.step;
+		control->default_value = ctrl.default_value;
+		control->flags = ctrl.flags;
+		control->element_size = ctrl.elem_size;
+		control->element_count = ctrl.elems;
+		control->dimensions_count = ctrl.nr_of_dims;
+		memcpy(control->dimensions, ctrl.dims,
+		       sizeof(uint32_t) * V4L2_CTRL_MAX_DIMS);
+	}
+	return true;
 }
 
-static bool control_impl_int32(MPCamera *camera, uint32_t id, int request, int32_t *value)
+static bool
+control_impl_int32(MPCamera *camera, uint32_t id, int request, int32_t *value)
 {
-    struct v4l2_ext_control ctrl = {};
-    ctrl.id = id;
-    ctrl.value = *value;
-
-    struct v4l2_ext_controls ctrls = {
-        .ctrl_class = 0,
-        .which = V4L2_CTRL_WHICH_CUR_VAL,
-        .count = 1,
-        .controls = &ctrl,
-    };
-    if (xioctl(control_fd(camera), request, &ctrls) == -1) {
-        return false;
-    }
-
-    *value = ctrl.value;
-    return true;
+	struct v4l2_ext_control ctrl = {};
+	ctrl.id = id;
+	ctrl.value = *value;
+
+	struct v4l2_ext_controls ctrls = {
+		.ctrl_class = 0,
+		.which = V4L2_CTRL_WHICH_CUR_VAL,
+		.count = 1,
+		.controls = &ctrl,
+	};
+	if (xioctl(control_fd(camera), request, &ctrls) == -1) {
+		return false;
+	}
+
+	*value = ctrl.value;
+	return true;
 }
 
-bool mp_camera_control_try_int32(MPCamera *camera, uint32_t id, int32_t *v)
+bool
+mp_camera_control_try_int32(MPCamera *camera, uint32_t id, int32_t *v)
 {
-    return control_impl_int32(camera, id, VIDIOC_TRY_EXT_CTRLS, v);
+	return control_impl_int32(camera, id, VIDIOC_TRY_EXT_CTRLS, v);
 }
 
-bool mp_camera_control_set_int32(MPCamera *camera, uint32_t id, int32_t v)
+bool
+mp_camera_control_set_int32(MPCamera *camera, uint32_t id, int32_t v)
 {
-    return control_impl_int32(camera, id, VIDIOC_S_EXT_CTRLS, &v);
+	return control_impl_int32(camera, id, VIDIOC_S_EXT_CTRLS, &v);
 }
 
-int32_t mp_camera_control_get_int32(MPCamera *camera, uint32_t id)
+int32_t
+mp_camera_control_get_int32(MPCamera *camera, uint32_t id)
 {
-    int32_t v = 0;
-    control_impl_int32(camera, id, VIDIOC_G_EXT_CTRLS, &v);
-    return v;
+	int32_t v = 0;
+	control_impl_int32(camera, id, VIDIOC_G_EXT_CTRLS, &v);
+	return v;
 }
 
-bool mp_camera_control_try_boolean(MPCamera *camera, uint32_t id, bool *v)
+bool
+mp_camera_control_try_boolean(MPCamera *camera, uint32_t id, bool *v)
 {
-    int32_t value = *v;
-    bool s = control_impl_int32(camera, id, VIDIOC_TRY_EXT_CTRLS, &value);
-    *v = value;
-    return s;
+	int32_t value = *v;
+	bool s = control_impl_int32(camera, id, VIDIOC_TRY_EXT_CTRLS, &value);
+	*v = value;
+	return s;
 }
 
-bool mp_camera_control_set_bool(MPCamera *camera, uint32_t id, bool v)
+bool
+mp_camera_control_set_bool(MPCamera *camera, uint32_t id, bool v)
 {
-    int32_t value = v;
-    return control_impl_int32(camera, id, VIDIOC_S_EXT_CTRLS, &value);
+	int32_t value = v;
+	return control_impl_int32(camera, id, VIDIOC_S_EXT_CTRLS, &value);
 }
 
-bool mp_camera_control_get_bool(MPCamera *camera, uint32_t id)
+bool
+mp_camera_control_get_bool(MPCamera *camera, uint32_t id)
 {
-    int32_t v = false;
-    control_impl_int32(camera, id, VIDIOC_G_EXT_CTRLS, &v);
-    return v;
+	int32_t v = false;
+	control_impl_int32(camera, id, VIDIOC_G_EXT_CTRLS, &v);
+	return v;
 }

+ 37 - 35
camera.h

@@ -5,19 +5,19 @@
 #include <stdint.h>
 
 typedef enum {
-    MP_PIXEL_FMT_UNSUPPORTED,
-    MP_PIXEL_FMT_BGGR8,
-    MP_PIXEL_FMT_GBRG8,
-    MP_PIXEL_FMT_GRBG8,
-    MP_PIXEL_FMT_RGGB8,
-    MP_PIXEL_FMT_BGGR10P,
-    MP_PIXEL_FMT_GBRG10P,
-    MP_PIXEL_FMT_GRBG10P,
-    MP_PIXEL_FMT_RGGB10P,
-    MP_PIXEL_FMT_UYVY,
-    MP_PIXEL_FMT_YUYV,
-
-    MP_PIXEL_FMT_MAX,
+	MP_PIXEL_FMT_UNSUPPORTED,
+	MP_PIXEL_FMT_BGGR8,
+	MP_PIXEL_FMT_GBRG8,
+	MP_PIXEL_FMT_GRBG8,
+	MP_PIXEL_FMT_RGGB8,
+	MP_PIXEL_FMT_BGGR10P,
+	MP_PIXEL_FMT_GBRG10P,
+	MP_PIXEL_FMT_GRBG10P,
+	MP_PIXEL_FMT_RGGB10P,
+	MP_PIXEL_FMT_UYVY,
+	MP_PIXEL_FMT_YUYV,
+
+	MP_PIXEL_FMT_MAX,
 } MPPixelFormat;
 
 const char *mp_pixel_format_to_str(MPPixelFormat pixel_format);
@@ -31,23 +31,24 @@ uint32_t mp_pixel_format_to_v4l_bus_code(MPPixelFormat pixel_format);
 uint32_t mp_pixel_format_bits_per_pixel(MPPixelFormat pixel_format);
 uint32_t mp_pixel_format_width_to_bytes(MPPixelFormat pixel_format, uint32_t width);
 uint32_t mp_pixel_format_width_to_colors(MPPixelFormat pixel_format, uint32_t width);
-uint32_t mp_pixel_format_height_to_colors(MPPixelFormat pixel_format, uint32_t height);
+uint32_t mp_pixel_format_height_to_colors(MPPixelFormat pixel_format,
+					  uint32_t height);
 
 typedef struct {
-    MPPixelFormat pixel_format;
+	MPPixelFormat pixel_format;
 
-    struct v4l2_fract frame_interval;
-    uint32_t width;
-    uint32_t height;
+	struct v4l2_fract frame_interval;
+	uint32_t width;
+	uint32_t height;
 } MPCameraMode;
 
 bool mp_camera_mode_is_equivalent(const MPCameraMode *m1, const MPCameraMode *m2);
 
 typedef struct {
-    uint32_t pixel_format;
-    uint32_t width;
-    uint32_t height;
-    uint8_t *data;
+	uint32_t pixel_format;
+	uint32_t width;
+	uint32_t height;
+	uint8_t *data;
 } MPImage;
 
 typedef struct _MPCamera MPCamera;
@@ -66,7 +67,8 @@ bool mp_camera_set_mode(MPCamera *camera, MPCameraMode *mode);
 bool mp_camera_start_capture(MPCamera *camera);
 bool mp_camera_stop_capture(MPCamera *camera);
 bool mp_camera_is_capturing(MPCamera *camera);
-bool mp_camera_capture_image(MPCamera *camera, void (*callback)(MPImage, void *), void *user_data);
+bool mp_camera_capture_image(MPCamera *camera, void (*callback)(MPImage, void *),
+			     void *user_data);
 
 typedef struct _MPCameraModeList MPCameraModeList;
 
@@ -77,21 +79,21 @@ MPCameraModeList *mp_camera_mode_list_next(MPCameraModeList *list);
 void mp_camera_mode_list_free(MPCameraModeList *list);
 
 typedef struct {
-    uint32_t id;
-    uint32_t type;
-    char name[32];
+	uint32_t id;
+	uint32_t type;
+	char name[32];
 
-    int32_t min;
-    int32_t max;
-    int32_t step;
-    int32_t default_value;
+	int32_t min;
+	int32_t max;
+	int32_t step;
+	int32_t default_value;
 
-    uint32_t flags;
+	uint32_t flags;
 
-    uint32_t element_size;
-    uint32_t element_count;
-    uint32_t dimensions_count;
-    uint32_t dimensions[V4L2_CTRL_MAX_DIMS];
+	uint32_t element_size;
+	uint32_t element_count;
+	uint32_t dimensions_count;
+	uint32_t dimensions[V4L2_CTRL_MAX_DIMS];
 } MPControl;
 
 const char *mp_control_id_to_str(uint32_t id);

+ 231 - 225
camera_config.c

@@ -20,263 +20,269 @@ static char *exif_model;
 static bool
 find_config(char *conffile)
 {
-    char buf[512];
-    char *xdg_config_home;
-    wordexp_t exp_result;
-    FILE *fp;
-
-    // Resolve XDG stuff
-    if ((xdg_config_home = getenv("XDG_CONFIG_HOME")) == NULL) {
-        xdg_config_home = "~/.config";
-    }
-    wordexp(xdg_config_home, &exp_result, 0);
-    xdg_config_home = strdup(exp_result.we_wordv[0]);
-    wordfree(&exp_result);
-
-    if (access("/proc/device-tree/compatible", F_OK) != -1) {
-        // Reads to compatible string of the current device tree, looks like:
-        // pine64,pinephone-1.2\0allwinner,sun50i-a64\0
-        fp = fopen("/proc/device-tree/compatible", "r");
-        fgets(buf, 512, fp);
-        fclose(fp);
-
-        // Check config/%dt.ini in the current working directory
-        sprintf(conffile, "config/%s.ini", buf);
-        if(access(conffile, F_OK) != -1) {
-            printf("Found config file at %s\n", conffile);
-            return true;
-        }
-
-        // Check for a config file in XDG_CONFIG_HOME
-        sprintf(conffile, "%s/megapixels/config/%s.ini", xdg_config_home, buf);
-        if(access(conffile, F_OK) != -1) {
-            printf("Found config file at %s\n", conffile);
-            return true;
-        }
-
-        // Check user overridden /etc/megapixels/config/$dt.ini
-        sprintf(conffile, "%s/megapixels/config/%s.ini", SYSCONFDIR, buf);
-        if(access(conffile, F_OK) != -1) {
-            printf("Found config file at %s\n", conffile);
-            return true;
-        }
-        // Check packaged /usr/share/megapixels/config/$dt.ini
-        sprintf(conffile, "%s/megapixels/config/%s.ini", DATADIR, buf);
-        if(access(conffile, F_OK) != -1) {
-            printf("Found config file at %s\n", conffile);
-            return true;
-        }
-        printf("%s not found\n", conffile);
-    } else {
-        printf("Could not read device name from device tree\n");
-    }
-
-    // If all else fails, fall back to /etc/megapixels.ini
-    sprintf(conffile, "/etc/megapixels.ini");
-    if (access(conffile, F_OK) != -1) {
-        printf("Found config file at %s\n", conffile);
-        return true;
-    }
-
-    return false;
+	char buf[512];
+	char *xdg_config_home;
+	wordexp_t exp_result;
+	FILE *fp;
+
+	// Resolve XDG stuff
+	if ((xdg_config_home = getenv("XDG_CONFIG_HOME")) == NULL) {
+		xdg_config_home = "~/.config";
+	}
+	wordexp(xdg_config_home, &exp_result, 0);
+	xdg_config_home = strdup(exp_result.we_wordv[0]);
+	wordfree(&exp_result);
+
+	if (access("/proc/device-tree/compatible", F_OK) != -1) {
+		// Reads to compatible string of the current device tree, looks like:
+		// pine64,pinephone-1.2\0allwinner,sun50i-a64\0
+		fp = fopen("/proc/device-tree/compatible", "r");
+		fgets(buf, 512, fp);
+		fclose(fp);
+
+		// Check config/%dt.ini in the current working directory
+		sprintf(conffile, "config/%s.ini", buf);
+		if (access(conffile, F_OK) != -1) {
+			printf("Found config file at %s\n", conffile);
+			return true;
+		}
+
+		// Check for a config file in XDG_CONFIG_HOME
+		sprintf(conffile, "%s/megapixels/config/%s.ini", xdg_config_home,
+			buf);
+		if (access(conffile, F_OK) != -1) {
+			printf("Found config file at %s\n", conffile);
+			return true;
+		}
+
+		// Check user overridden /etc/megapixels/config/$dt.ini
+		sprintf(conffile, "%s/megapixels/config/%s.ini", SYSCONFDIR, buf);
+		if (access(conffile, F_OK) != -1) {
+			printf("Found config file at %s\n", conffile);
+			return true;
+		}
+		// Check packaged /usr/share/megapixels/config/$dt.ini
+		sprintf(conffile, "%s/megapixels/config/%s.ini", DATADIR, buf);
+		if (access(conffile, F_OK) != -1) {
+			printf("Found config file at %s\n", conffile);
+			return true;
+		}
+		printf("%s not found\n", conffile);
+	} else {
+		printf("Could not read device name from device tree\n");
+	}
+
+	// If all else fails, fall back to /etc/megapixels.ini
+	sprintf(conffile, "/etc/megapixels.ini");
+	if (access(conffile, F_OK) != -1) {
+		printf("Found config file at %s\n", conffile);
+		return true;
+	}
+
+	return false;
 }
 
 static int
 strtoint(const char *nptr, char **endptr, int base)
 {
-    long x = strtol(nptr, endptr, base);
-    assert(x <= INT_MAX);
-    return (int) x;
+	long x = strtol(nptr, endptr, base);
+	assert(x <= INT_MAX);
+	return (int)x;
 }
 
 static bool
-config_handle_camera_mode(const char *prefix, MPCameraMode * mode, const char *name, const char *value)
+config_handle_camera_mode(const char *prefix, MPCameraMode *mode, const char *name,
+			  const char *value)
 {
-    int prefix_length = strlen(prefix);
-    if (strncmp(prefix, name, prefix_length) != 0)
-        return false;
-
-    name += prefix_length;
-
-    if (strcmp(name, "width") == 0) {
-        mode->width = strtoint(value, NULL, 10);
-    } else if (strcmp(name, "height") == 0) {
-        mode->height = strtoint(value, NULL, 10);
-    } else if (strcmp(name, "rate") == 0) {
-        mode->frame_interval.numerator = 1;
-        mode->frame_interval.denominator = strtoint(value, NULL, 10);
-    } else if (strcmp(name, "fmt") == 0) {
-        mode->pixel_format = mp_pixel_format_from_str(value);
-        if (mode->pixel_format == MP_PIXEL_FMT_UNSUPPORTED) {
-            g_printerr("Unsupported pixelformat %s\n", value);
-            exit(1);
-        }
-    } else {
-        return false;
-    }
-    return true;
+	int prefix_length = strlen(prefix);
+	if (strncmp(prefix, name, prefix_length) != 0)
+		return false;
+
+	name += prefix_length;
+
+	if (strcmp(name, "width") == 0) {
+		mode->width = strtoint(value, NULL, 10);
+	} else if (strcmp(name, "height") == 0) {
+		mode->height = strtoint(value, NULL, 10);
+	} else if (strcmp(name, "rate") == 0) {
+		mode->frame_interval.numerator = 1;
+		mode->frame_interval.denominator = strtoint(value, NULL, 10);
+	} else if (strcmp(name, "fmt") == 0) {
+		mode->pixel_format = mp_pixel_format_from_str(value);
+		if (mode->pixel_format == MP_PIXEL_FMT_UNSUPPORTED) {
+			g_printerr("Unsupported pixelformat %s\n", value);
+			exit(1);
+		}
+	} else {
+		return false;
+	}
+	return true;
 }
 
 static int
 config_ini_handler(void *user, const char *section, const char *name,
-    const char *value)
+		   const char *value)
 {
-    if (strcmp(section, "device") == 0) {
-        if (strcmp(name, "make") == 0) {
-            exif_make = strdup(value);
-        } else if (strcmp(name, "model") == 0) {
-            exif_model = strdup(value);
-        } else {
-            g_printerr("Unknown key '%s' in [device]\n", name);
-            exit(1);
-        }
-    } else {
-        if (num_cameras == MP_MAX_CAMERAS) {
-            g_printerr("More cameras defined than NUM_CAMERAS\n");
-            exit(1);
-        }
-
-        size_t index = 0;
-        for (; index < num_cameras; ++index) {
-            if (strcmp(cameras[index].cfg_name, section) == 0) {
-                break;
-            }
-        }
-
-        if (index == num_cameras) {
-            printf("Adding camera %s from config\n", section);
-            ++num_cameras;
-
-            cameras[index].index = index;
-            strcpy(cameras[index].cfg_name, section);
-        }
-
-        struct mp_camera_config *cc = &cameras[index];
-
-        if (config_handle_camera_mode("capture-", &cc->capture_mode, name, value)) {
-        } else if (config_handle_camera_mode("preview-", &cc->preview_mode, name, value)) {
-        } else if (strcmp(name, "rotate") == 0) {
-            cc->rotate = strtoint(value, NULL, 10);
-        } else if (strcmp(name, "mirrored") == 0) {
-            cc->mirrored = strcmp(value, "true") == 0;
-        } else if (strcmp(name, "driver") == 0) {
-            strcpy(cc->dev_name, value);
-        } else if (strcmp(name, "media-driver") == 0) {
-            strcpy(cc->media_dev_name, value);
-        } else if (strcmp(name, "media-links") == 0) {
-            char **linkdefs = g_strsplit(value, ",", 0);
-
-            for (int i = 0; i < MP_MAX_LINKS && linkdefs[i] != NULL; ++i) {
-                char **linkdef = g_strsplit(linkdefs[i], "->", 2);
-                char **porta = g_strsplit(linkdef[0], ":", 2);
-                char **portb = g_strsplit(linkdef[1], ":", 2);
-
-                strcpy(cc->media_links[i].source_name, porta[0]);
-                strcpy(cc->media_links[i].target_name, portb[0]);
-                cc->media_links[i].source_port = strtoint(porta[1], NULL, 10);
-                cc->media_links[i].target_port = strtoint(portb[1], NULL, 10);
-
-                g_strfreev(portb);
-                g_strfreev(porta);
-                g_strfreev(linkdef);
-                ++cc->num_media_links;
-            }
-            g_strfreev(linkdefs);
-        } else if (strcmp(name, "colormatrix") == 0) {
-            sscanf(value, "%f,%f,%f,%f,%f,%f,%f,%f,%f",
-                    cc->colormatrix+0,
-                    cc->colormatrix+1,
-                    cc->colormatrix+2,
-                    cc->colormatrix+3,
-                    cc->colormatrix+4,
-                    cc->colormatrix+5,
-                    cc->colormatrix+6,
-                    cc->colormatrix+7,
-                    cc->colormatrix+8
-                    );
-        } else if (strcmp(name, "forwardmatrix") == 0) {
-            sscanf(value, "%f,%f,%f,%f,%f,%f,%f,%f,%f",
-                    cc->forwardmatrix+0,
-                    cc->forwardmatrix+1,
-                    cc->forwardmatrix+2,
-                    cc->forwardmatrix+3,
-                    cc->forwardmatrix+4,
-                    cc->forwardmatrix+5,
-                    cc->forwardmatrix+6,
-                    cc->forwardmatrix+7,
-                    cc->forwardmatrix+8
-                    );
-        } else if (strcmp(name, "whitelevel") == 0) {
-            cc->whitelevel = strtoint(value, NULL, 10);
-        } else if (strcmp(name, "blacklevel") == 0) {
-            cc->blacklevel = strtoint(value, NULL, 10);
-        } else if (strcmp(name, "focallength") == 0) {
-            cc->focallength = strtof(value, NULL);
-        } else if (strcmp(name, "cropfactor") == 0) {
-            cc->cropfactor = strtof(value, NULL);
-        } else if (strcmp(name, "fnumber") == 0) {
-            cc->fnumber = strtod(value, NULL);
-        } else if (strcmp(name, "iso-min") == 0) {
-            cc->iso_min = strtod(value, NULL);
-        } else if (strcmp(name, "iso-max") == 0) {
-            cc->iso_max = strtod(value, NULL);
-        } else {
-            g_printerr("Unknown key '%s' in [%s]\n", name, section);
-            exit(1);
-        }
-    }
-    return 1;
+	if (strcmp(section, "device") == 0) {
+		if (strcmp(name, "make") == 0) {
+			exif_make = strdup(value);
+		} else if (strcmp(name, "model") == 0) {
+			exif_model = strdup(value);
+		} else {
+			g_printerr("Unknown key '%s' in [device]\n", name);
+			exit(1);
+		}
+	} else {
+		if (num_cameras == MP_MAX_CAMERAS) {
+			g_printerr("More cameras defined than NUM_CAMERAS\n");
+			exit(1);
+		}
+
+		size_t index = 0;
+		for (; index < num_cameras; ++index) {
+			if (strcmp(cameras[index].cfg_name, section) == 0) {
+				break;
+			}
+		}
+
+		if (index == num_cameras) {
+			printf("Adding camera %s from config\n", section);
+			++num_cameras;
+
+			cameras[index].index = index;
+			strcpy(cameras[index].cfg_name, section);
+		}
+
+		struct mp_camera_config *cc = &cameras[index];
+
+		if (config_handle_camera_mode("capture-", &cc->capture_mode, name,
+					      value)) {
+		} else if (config_handle_camera_mode("preview-", &cc->preview_mode,
+						     name, value)) {
+		} else if (strcmp(name, "rotate") == 0) {
+			cc->rotate = strtoint(value, NULL, 10);
+		} else if (strcmp(name, "mirrored") == 0) {
+			cc->mirrored = strcmp(value, "true") == 0;
+		} else if (strcmp(name, "driver") == 0) {
+			strcpy(cc->dev_name, value);
+		} else if (strcmp(name, "media-driver") == 0) {
+			strcpy(cc->media_dev_name, value);
+		} else if (strcmp(name, "media-links") == 0) {
+			char **linkdefs = g_strsplit(value, ",", 0);
+
+			for (int i = 0; i < MP_MAX_LINKS && linkdefs[i] != NULL;
+			     ++i) {
+				char **linkdef = g_strsplit(linkdefs[i], "->", 2);
+				char **porta = g_strsplit(linkdef[0], ":", 2);
+				char **portb = g_strsplit(linkdef[1], ":", 2);
+
+				strcpy(cc->media_links[i].source_name, porta[0]);
+				strcpy(cc->media_links[i].target_name, portb[0]);
+				cc->media_links[i].source_port =
+					strtoint(porta[1], NULL, 10);
+				cc->media_links[i].target_port =
+					strtoint(portb[1], NULL, 10);
+
+				g_strfreev(portb);
+				g_strfreev(porta);
+				g_strfreev(linkdef);
+				++cc->num_media_links;
+			}
+			g_strfreev(linkdefs);
+		} else if (strcmp(name, "colormatrix") == 0) {
+			sscanf(value, "%f,%f,%f,%f,%f,%f,%f,%f,%f",
+			       cc->colormatrix + 0, cc->colormatrix + 1,
+			       cc->colormatrix + 2, cc->colormatrix + 3,
+			       cc->colormatrix + 4, cc->colormatrix + 5,
+			       cc->colormatrix + 6, cc->colormatrix + 7,
+			       cc->colormatrix + 8);
+		} else if (strcmp(name, "forwardmatrix") == 0) {
+			sscanf(value, "%f,%f,%f,%f,%f,%f,%f,%f,%f",
+			       cc->forwardmatrix + 0, cc->forwardmatrix + 1,
+			       cc->forwardmatrix + 2, cc->forwardmatrix + 3,
+			       cc->forwardmatrix + 4, cc->forwardmatrix + 5,
+			       cc->forwardmatrix + 6, cc->forwardmatrix + 7,
+			       cc->forwardmatrix + 8);
+		} else if (strcmp(name, "whitelevel") == 0) {
+			cc->whitelevel = strtoint(value, NULL, 10);
+		} else if (strcmp(name, "blacklevel") == 0) {
+			cc->blacklevel = strtoint(value, NULL, 10);
+		} else if (strcmp(name, "focallength") == 0) {
+			cc->focallength = strtof(value, NULL);
+		} else if (strcmp(name, "cropfactor") == 0) {
+			cc->cropfactor = strtof(value, NULL);
+		} else if (strcmp(name, "fnumber") == 0) {
+			cc->fnumber = strtod(value, NULL);
+		} else if (strcmp(name, "iso-min") == 0) {
+			cc->iso_min = strtod(value, NULL);
+		} else if (strcmp(name, "iso-max") == 0) {
+			cc->iso_max = strtod(value, NULL);
+		} else {
+			g_printerr("Unknown key '%s' in [%s]\n", name, section);
+			exit(1);
+		}
+	}
+	return 1;
 }
 
 void
-calculate_matrices() {
+calculate_matrices()
+{
 	for (size_t i = 0; i < MP_MAX_CAMERAS; ++i) {
-		if (cameras[i].colormatrix != NULL && cameras[i].forwardmatrix != NULL) {
-			multiply_matrices(cameras[i].colormatrix, cameras[i].forwardmatrix, cameras[i].previewmatrix);
+		if (cameras[i].colormatrix != NULL &&
+		    cameras[i].forwardmatrix != NULL) {
+			multiply_matrices(cameras[i].colormatrix,
+					  cameras[i].forwardmatrix,
+					  cameras[i].previewmatrix);
 		}
 	}
 }
 
-bool mp_load_config() {
-    char file[512];
-    if (!find_config(file)) {
-        g_printerr("Could not find any config file\n");
-        return false;
-    }
+bool
+mp_load_config()
+{
+	char file[512];
+	if (!find_config(file)) {
+		g_printerr("Could not find any config file\n");
+		return false;
+	}
 
-    int result = ini_parse(file, config_ini_handler, NULL);
-    if (result == -1) {
-        g_printerr("Config file not found\n");
-	return false;
-    } 
-    if (result == -2) {
-        g_printerr("Could not allocate memory to parse config file\n");
-	return false;
-    }
-    if (result != 0) {
-        g_printerr("Could not parse config file\n");
-	return false;
-    }
+	int result = ini_parse(file, config_ini_handler, NULL);
+	if (result == -1) {
+		g_printerr("Config file not found\n");
+		return false;
+	}
+	if (result == -2) {
+		g_printerr("Could not allocate memory to parse config file\n");
+		return false;
+	}
+	if (result != 0) {
+		g_printerr("Could not parse config file\n");
+		return false;
+	}
+
+	calculate_matrices();
 
-    calculate_matrices();
-    
-    return true;
+	return true;
 }
 
-const char * mp_get_device_make()
+const char *
+mp_get_device_make()
 {
-    return exif_make;
+	return exif_make;
 }
 
-const char * mp_get_device_model()
+const char *
+mp_get_device_model()
 {
-    return exif_model;
+	return exif_model;
 }
 
-const struct mp_camera_config * mp_get_camera_config(size_t index)
+const struct mp_camera_config *
+mp_get_camera_config(size_t index)
 {
-    if (index >= num_cameras)
-        return NULL;
+	if (index >= num_cameras)
+		return NULL;
 
-    return &cameras[index];
+	return &cameras[index];
 }

+ 30 - 30
camera_config.h

@@ -9,42 +9,42 @@
 #define MP_MAX_LINKS 10
 
 struct mp_media_link_config {
-    char source_name[100];
-    char target_name[100];
-    int source_port;
-    int target_port;
+	char source_name[100];
+	char target_name[100];
+	int source_port;
+	int target_port;
 };
 
 struct mp_camera_config {
-    size_t index;
-
-    char cfg_name[100];
-    char dev_name[260];
-    char media_dev_name[260];
-
-    MPCameraMode capture_mode;
-    MPCameraMode preview_mode;
-    int rotate;
-    bool mirrored;
-
-    struct mp_media_link_config media_links[MP_MAX_LINKS];
-    int num_media_links;
-
-    float colormatrix[9];
-    float forwardmatrix[9];
-    float previewmatrix[9];
-    int blacklevel;
-    int whitelevel;
-
-    float focallength;
-    float cropfactor;
-    double fnumber;
-    int iso_min;
-    int iso_max;
+	size_t index;
+
+	char cfg_name[100];
+	char dev_name[260];
+	char media_dev_name[260];
+
+	MPCameraMode capture_mode;
+	MPCameraMode preview_mode;
+	int rotate;
+	bool mirrored;
+
+	struct mp_media_link_config media_links[MP_MAX_LINKS];
+	int num_media_links;
+
+	float colormatrix[9];
+	float forwardmatrix[9];
+	float previewmatrix[9];
+	int blacklevel;
+	int whitelevel;
+
+	float focallength;
+	float cropfactor;
+	double fnumber;
+	int iso_min;
+	int iso_max;
 };
 
 bool mp_load_config();
 
 const char *mp_get_device_make();
 const char *mp_get_device_model();
-const struct mp_camera_config * mp_get_camera_config(size_t index);
+const struct mp_camera_config *mp_get_camera_config(size_t index);

+ 315 - 275
device.c

@@ -8,416 +8,456 @@
 #include <sys/ioctl.h>
 #include <unistd.h>
 
-bool mp_find_device_path(struct media_v2_intf_devnode devnode, char *path, int length)
+bool
+mp_find_device_path(struct media_v2_intf_devnode devnode, char *path, int length)
 {
-    char uevent_path[256];
-    snprintf(uevent_path, 256, "/sys/dev/char/%d:%d/uevent", devnode.major, devnode.minor);
+	char uevent_path[256];
+	snprintf(uevent_path, 256, "/sys/dev/char/%d:%d/uevent", devnode.major,
+		 devnode.minor);
 
-    FILE *f = fopen(uevent_path, "r");
-    if (!f) {
-        return false;
-    }
+	FILE *f = fopen(uevent_path, "r");
+	if (!f) {
+		return false;
+	}
 
-    char line[512];
-    while (fgets(line, 512, f)) {
-        if (strncmp(line, "DEVNAME=", 8) == 0) {
-            // Drop newline
-            int length = strlen(line);
-            if (line[length - 1] == '\n')
-                line[length - 1] = '\0';
+	char line[512];
+	while (fgets(line, 512, f)) {
+		if (strncmp(line, "DEVNAME=", 8) == 0) {
+			// Drop newline
+			int length = strlen(line);
+			if (line[length - 1] == '\n')
+				line[length - 1] = '\0';
 
-            snprintf(path, length, "/dev/%s", line + 8);
-            return true;
-        }
-    }
+			snprintf(path, length, "/dev/%s", line + 8);
+			return true;
+		}
+	}
 
-    fclose(f);
+	fclose(f);
 
-    return false;
+	return false;
 }
 
 struct _MPDevice {
-    int fd;
-
-    struct media_device_info info;
-
-    struct media_v2_entity *entities;
-    size_t num_entities;
-    struct media_v2_interface *interfaces;
-    size_t num_interfaces;
-    struct media_v2_pad *pads;
-    size_t num_pads;
-    struct media_v2_link *links;
-    size_t num_links;
+	int fd;
+
+	struct media_device_info info;
+
+	struct media_v2_entity *entities;
+	size_t num_entities;
+	struct media_v2_interface *interfaces;
+	size_t num_interfaces;
+	struct media_v2_pad *pads;
+	size_t num_pads;
+	struct media_v2_link *links;
+	size_t num_links;
 };
 
-static void errno_printerr(const char *s)
+static void
+errno_printerr(const char *s)
 {
-    g_printerr("MPDevice: %s error %d, %s\n", s, errno, strerror(errno));
+	g_printerr("MPDevice: %s error %d, %s\n", s, errno, strerror(errno));
 }
 
-static int xioctl(int fd, int request, void *arg)
+static int
+xioctl(int fd, int request, void *arg)
 {
-    int r;
-    do {
-        r = ioctl(fd, request, arg);
-    } while (r == -1 && errno == EINTR);
-    return r;
+	int r;
+	do {
+		r = ioctl(fd, request, arg);
+	} while (r == -1 && errno == EINTR);
+	return r;
 }
 
-MPDevice *mp_device_find(const char *driver_name)
+MPDevice *
+mp_device_find(const char *driver_name)
 {
-    MPDeviceList *list = mp_device_list_new();
+	MPDeviceList *list = mp_device_list_new();
 
-    MPDevice *found_device = mp_device_list_find_remove(&list, driver_name);
+	MPDevice *found_device = mp_device_list_find_remove(&list, driver_name);
 
+	mp_device_list_free(list);
 
-    mp_device_list_free(list);
-
-    return found_device;
+	return found_device;
 }
 
-MPDevice *mp_device_open(const char *path)
+MPDevice *
+mp_device_open(const char *path)
 {
-    int fd = open(path, O_RDWR);
-    if (fd == -1) {
-        errno_printerr("open");
-        return NULL;
-    }
+	int fd = open(path, O_RDWR);
+	if (fd == -1) {
+		errno_printerr("open");
+		return NULL;
+	}
 
-    return mp_device_new(fd);
+	return mp_device_new(fd);
 }
 
-MPDevice *mp_device_new(int fd)
+MPDevice *
+mp_device_new(int fd)
 {
-    // Get the topology of the media device
-    struct media_v2_topology topology = {};
-    if (xioctl(fd, MEDIA_IOC_G_TOPOLOGY, &topology) == -1
-        || topology.num_entities == 0) {
-        close(fd);
-        return NULL;
-    }
+	// Get the topology of the media device
+	struct media_v2_topology topology = {};
+	if (xioctl(fd, MEDIA_IOC_G_TOPOLOGY, &topology) == -1 ||
+	    topology.num_entities == 0) {
+		close(fd);
+		return NULL;
+	}
 
-    // Create the device
-    MPDevice *device = calloc(1, sizeof(MPDevice));
-    device->fd = fd;
-    device->entities = calloc(topology.num_entities, sizeof(struct media_v2_entity));
-    device->num_entities = topology.num_entities;
-    device->interfaces = calloc(topology.num_interfaces, sizeof(struct media_v2_interface));
-    device->num_interfaces = topology.num_interfaces;
-    device->pads = calloc(topology.num_pads, sizeof(struct media_v2_pad));
-    device->num_pads = topology.num_pads;
-    device->links = calloc(topology.num_links, sizeof(struct media_v2_link));
-    device->num_links = topology.num_links;
+	// Create the device
+	MPDevice *device = calloc(1, sizeof(MPDevice));
+	device->fd = fd;
+	device->entities =
+		calloc(topology.num_entities, sizeof(struct media_v2_entity));
+	device->num_entities = topology.num_entities;
+	device->interfaces =
+		calloc(topology.num_interfaces, sizeof(struct media_v2_interface));
+	device->num_interfaces = topology.num_interfaces;
+	device->pads = calloc(topology.num_pads, sizeof(struct media_v2_pad));
+	device->num_pads = topology.num_pads;
+	device->links = calloc(topology.num_links, sizeof(struct media_v2_link));
+	device->num_links = topology.num_links;
 
-    // Get the actual devices and interfaces
-    topology.ptr_entities = (uint64_t)device->entities;
-    topology.ptr_interfaces = (uint64_t)device->interfaces;
-    topology.ptr_pads = (uint64_t)device->pads;
-    topology.ptr_links = (uint64_t)device->links;
-    if (xioctl(fd, MEDIA_IOC_G_TOPOLOGY, &topology) == -1) {
-        errno_printerr("MEDIA_IOC_G_TOPOLOGY");
-        mp_device_close(device);
-        return NULL;
-    }
+	// Get the actual devices and interfaces
+	topology.ptr_entities = (uint64_t)device->entities;
+	topology.ptr_interfaces = (uint64_t)device->interfaces;
+	topology.ptr_pads = (uint64_t)device->pads;
+	topology.ptr_links = (uint64_t)device->links;
+	if (xioctl(fd, MEDIA_IOC_G_TOPOLOGY, &topology) == -1) {
+		errno_printerr("MEDIA_IOC_G_TOPOLOGY");
+		mp_device_close(device);
+		return NULL;
+	}
 
-    // Get device info
-    if (xioctl(fd, MEDIA_IOC_DEVICE_INFO, &device->info) == -1) {
-        errno_printerr("MEDIA_IOC_DEVICE_INFO");
-        mp_device_close(device);
-        return NULL;
-    }
+	// Get device info
+	if (xioctl(fd, MEDIA_IOC_DEVICE_INFO, &device->info) == -1) {
+		errno_printerr("MEDIA_IOC_DEVICE_INFO");
+		mp_device_close(device);
+		return NULL;
+	}
 
-    return device;
+	return device;
 }
 
-void mp_device_close(MPDevice *device)
+void
+mp_device_close(MPDevice *device)
 {
-    close(device->fd);
-    free(device->entities);
-    free(device->interfaces);
-    free(device->pads);
-    free(device->links);
-    free(device);
+	close(device->fd);
+	free(device->entities);
+	free(device->interfaces);
+	free(device->pads);
+	free(device->links);
+	free(device);
 }
 
-bool mp_device_setup_link(MPDevice *device, uint32_t source_pad_id, uint32_t sink_pad_id, bool enabled)
+bool
+mp_device_setup_link(MPDevice *device, uint32_t source_pad_id, uint32_t sink_pad_id,
+		     bool enabled)
 {
-    const struct media_v2_pad *source_pad = mp_device_get_pad(device, source_pad_id);
-    g_return_val_if_fail(source_pad, false);
+	const struct media_v2_pad *source_pad =
+		mp_device_get_pad(device, source_pad_id);
+	g_return_val_if_fail(source_pad, false);
 
-    const struct media_v2_pad *sink_pad = mp_device_get_pad(device, sink_pad_id);
-    g_return_val_if_fail(sink_pad, false);
+	const struct media_v2_pad *sink_pad = mp_device_get_pad(device, sink_pad_id);
+	g_return_val_if_fail(sink_pad, false);
 
-    struct media_link_desc link = {};
-    link.flags = enabled ? MEDIA_LNK_FL_ENABLED : 0;
-    link.source.entity = source_pad->entity_id;
-    link.source.index = 0;
-    link.sink.entity = sink_pad->entity_id;
-    link.sink.index = 0;
-    if (xioctl(device->fd, MEDIA_IOC_SETUP_LINK, &link) == -1) {
-        errno_printerr("MEDIA_IOC_SETUP_LINK");
-        return false;
-    }
+	struct media_link_desc link = {};
+	link.flags = enabled ? MEDIA_LNK_FL_ENABLED : 0;
+	link.source.entity = source_pad->entity_id;
+	link.source.index = 0;
+	link.sink.entity = sink_pad->entity_id;
+	link.sink.index = 0;
+	if (xioctl(device->fd, MEDIA_IOC_SETUP_LINK, &link) == -1) {
+		errno_printerr("MEDIA_IOC_SETUP_LINK");
+		return false;
+	}
 
-    return true;
+	return true;
 }
 
-const struct media_v2_entity *mp_device_find_entity(const MPDevice *device, const char *driver_name)
+const struct media_v2_entity *
+mp_device_find_entity(const MPDevice *device, const char *driver_name)
 {
-    int length = strlen(driver_name);
+	int length = strlen(driver_name);
 
-    // Find the entity from the name
-    for (uint32_t i = 0; i < device->num_entities; ++i) {
-        if (strncmp(device->entities[i].name, driver_name, length) == 0) {
-            return &device->entities[i];
-        }
-    }
-    return NULL;
+	// Find the entity from the name
+	for (uint32_t i = 0; i < device->num_entities; ++i) {
+		if (strncmp(device->entities[i].name, driver_name, length) == 0) {
+			return &device->entities[i];
+		}
+	}
+	return NULL;
 }
 
-const struct media_v2_entity *mp_device_find_entity_type(const MPDevice *device, const uint32_t type)
+const struct media_v2_entity *
+mp_device_find_entity_type(const MPDevice *device, const uint32_t type)
 {
-    // Find the entity from the entity type
-    for (uint32_t i = 0; i < device->num_entities; ++i) {
-        if (device->entities[i].function == type) {
-            return &device->entities[i];
-        }
-    }
-    return NULL;
+	// Find the entity from the entity type
+	for (uint32_t i = 0; i < device->num_entities; ++i) {
+		if (device->entities[i].function == type) {
+			return &device->entities[i];
+		}
+	}
+	return NULL;
 }
 
-const struct media_device_info *mp_device_get_info(const MPDevice *device)
+const struct media_device_info *
+mp_device_get_info(const MPDevice *device)
 {
-    return &device->info;
+	return &device->info;
 }
 
-const struct media_v2_entity *mp_device_get_entity(const MPDevice *device, uint32_t id)
+const struct media_v2_entity *
+mp_device_get_entity(const MPDevice *device, uint32_t id)
 {
-    for (int i = 0; i < device->num_entities; ++i) {
-        if (device->entities[i].id == id) {
-            return &device->entities[i];
-        }
-    }
-    return NULL;
+	for (int i = 0; i < device->num_entities; ++i) {
+		if (device->entities[i].id == id) {
+			return &device->entities[i];
+		}
+	}
+	return NULL;
 }
 
-const struct media_v2_entity *mp_device_get_entities(const MPDevice *device)
+const struct media_v2_entity *
+mp_device_get_entities(const MPDevice *device)
 {
-    return device->entities;
+	return device->entities;
 }
 
-size_t mp_device_get_num_entities(const MPDevice *device)
+size_t
+mp_device_get_num_entities(const MPDevice *device)
 {
-    return device->num_entities;
+	return device->num_entities;
 }
 
-const struct media_v2_interface *mp_device_find_entity_interface(const MPDevice *device, uint32_t entity_id)
+const struct media_v2_interface *
+mp_device_find_entity_interface(const MPDevice *device, uint32_t entity_id)
 {
-    // Find the interface through the link
-    const struct media_v2_link *link = mp_device_find_link_to(device, entity_id);
-    if (!link) {
-        return NULL;
-    }
-    return mp_device_get_interface(device, link->source_id);
+	// Find the interface through the link
+	const struct media_v2_link *link = mp_device_find_link_to(device, entity_id);
+	if (!link) {
+		return NULL;
+	}
+	return mp_device_get_interface(device, link->source_id);
 }
 
-const struct media_v2_interface *mp_device_get_interface(const MPDevice *device, uint32_t id)
+const struct media_v2_interface *
+mp_device_get_interface(const MPDevice *device, uint32_t id)
 {
-    for (int i = 0; i < device->num_interfaces; ++i) {
-        if (device->interfaces[i].id == id) {
-            return &device->interfaces[i];
-        }
-    }
-    return NULL;
+	for (int i = 0; i < device->num_interfaces; ++i) {
+		if (device->interfaces[i].id == id) {
+			return &device->interfaces[i];
+		}
+	}
+	return NULL;
 }
 
-const struct media_v2_interface *mp_device_get_interfaces(const MPDevice *device)
+const struct media_v2_interface *
+mp_device_get_interfaces(const MPDevice *device)
 {
-    return device->interfaces;
+	return device->interfaces;
 }
 
-size_t mp_device_get_num_interfaces(const MPDevice *device)
+size_t
+mp_device_get_num_interfaces(const MPDevice *device)
 {
-    return device->num_interfaces;
+	return device->num_interfaces;
 }
 
-const struct media_v2_pad *mp_device_get_pad_from_entity(const MPDevice *device, uint32_t entity_id)
+const struct media_v2_pad *
+mp_device_get_pad_from_entity(const MPDevice *device, uint32_t entity_id)
 {
-    for (int i = 0; i < device->num_pads; ++i) {
-        if (device->pads[i].entity_id == entity_id) {
-            return &device->pads[i];
-        }
-    }
-    return NULL;
+	for (int i = 0; i < device->num_pads; ++i) {
+		if (device->pads[i].entity_id == entity_id) {
+			return &device->pads[i];
+		}
+	}
+	return NULL;
 }
 
-const struct media_v2_pad *mp_device_get_pad(const MPDevice *device, uint32_t id)
+const struct media_v2_pad *
+mp_device_get_pad(const MPDevice *device, uint32_t id)
 {
-    for (int i = 0; i < device->num_pads; ++i) {
-        if (device->pads[i].id == id) {
-            return &device->pads[i];
-        }
-    }
-    return NULL;
+	for (int i = 0; i < device->num_pads; ++i) {
+		if (device->pads[i].id == id) {
+			return &device->pads[i];
+		}
+	}
+	return NULL;
 }
 
-const struct media_v2_pad *mp_device_get_pads(const MPDevice *device)
+const struct media_v2_pad *
+mp_device_get_pads(const MPDevice *device)
 {
-    return device->pads;
+	return device->pads;
 }
 
-size_t mp_device_get_num_pads(const MPDevice *device)
+size_t
+mp_device_get_num_pads(const MPDevice *device)
 {
-    return device->num_pads;
+	return device->num_pads;
 }
 
-const struct media_v2_link *mp_device_find_entity_link(const MPDevice *device, uint32_t entity_id)
+const struct media_v2_link *
+mp_device_find_entity_link(const MPDevice *device, uint32_t entity_id)
 {
-    const struct media_v2_pad *pad = mp_device_get_pad_from_entity(device, entity_id);
-    const struct media_v2_link *link = mp_device_find_link_to(device, pad->id);
-    if (link) {
-        return link;
-    }
-    return mp_device_find_link_from(device, pad->id);
+	const struct media_v2_pad *pad =
+		mp_device_get_pad_from_entity(device, entity_id);
+	const struct media_v2_link *link = mp_device_find_link_to(device, pad->id);
+	if (link) {
+		return link;
+	}
+	return mp_device_find_link_from(device, pad->id);
 }
 
-const struct media_v2_link *mp_device_find_link_from(const MPDevice *device, uint32_t source)
+const struct media_v2_link *
+mp_device_find_link_from(const MPDevice *device, uint32_t source)
 {
-    for (int i = 0; i < device->num_links; ++i) {
-        if (device->links[i].source_id == source) {
-            return &device->links[i];
-        }
-    }
-    return NULL;
+	for (int i = 0; i < device->num_links; ++i) {
+		if (device->links[i].source_id == source) {
+			return &device->links[i];
+		}
+	}
+	return NULL;
 }
 
-const struct media_v2_link *mp_device_find_link_to(const MPDevice *device, uint32_t sink)
+const struct media_v2_link *
+mp_device_find_link_to(const MPDevice *device, uint32_t sink)
 {
-    for (int i = 0; i < device->num_links; ++i) {
-        if (device->links[i].sink_id == sink) {
-            return &device->links[i];
-        }
-    }
-    return NULL;
+	for (int i = 0; i < device->num_links; ++i) {
+		if (device->links[i].sink_id == sink) {
+			return &device->links[i];
+		}
+	}
+	return NULL;
 }
 
-const struct media_v2_link *mp_device_find_link_between(const MPDevice *device, uint32_t source, uint32_t sink)
+const struct media_v2_link *
+mp_device_find_link_between(const MPDevice *device, uint32_t source, uint32_t sink)
 {
-    for (int i = 0; i < device->num_links; ++i) {
-        if (device->links[i].source_id == source
-            && device->links[i].sink_id == sink) {
-            return &device->links[i];
-        }
-    }
-    return NULL;
+	for (int i = 0; i < device->num_links; ++i) {
+		if (device->links[i].source_id == source &&
+		    device->links[i].sink_id == sink) {
+			return &device->links[i];
+		}
+	}
+	return NULL;
 }
 
-const struct media_v2_link *mp_device_get_link(const MPDevice *device, uint32_t id)
+const struct media_v2_link *
+mp_device_get_link(const MPDevice *device, uint32_t id)
 {
-    for (int i = 0; i < device->num_links; ++i) {
-        if (device->links[i].id == id) {
-            return &device->links[i];
-        }
-    }
-    return NULL;
+	for (int i = 0; i < device->num_links; ++i) {
+		if (device->links[i].id == id) {
+			return &device->links[i];
+		}
+	}
+	return NULL;
 }
 
-const struct media_v2_link *mp_device_get_links(const MPDevice *device)
+const struct media_v2_link *
+mp_device_get_links(const MPDevice *device)
 {
-    return device->links;
+	return device->links;
 }
 
-size_t mp_device_get_num_links(const MPDevice *device)
+size_t
+mp_device_get_num_links(const MPDevice *device)
 {
-    return device->num_links;
+	return device->num_links;
 }
 
 struct _MPDeviceList {
-    MPDevice *device;
-    MPDeviceList *next;
+	MPDevice *device;
+	MPDeviceList *next;
 };
 
-MPDeviceList *mp_device_list_new()
+MPDeviceList *
+mp_device_list_new()
 {
-    MPDeviceList *current = NULL;
+	MPDeviceList *current = NULL;
 
-    // Enumerate media device files
-    struct dirent *dir;
-    DIR *d = opendir("/dev");
-    while ((dir = readdir(d)) != NULL) {
-        if (strncmp(dir->d_name, "media", 5) == 0) {
-            char path[261];
-            snprintf(path, 261, "/dev/%s", dir->d_name);
+	// Enumerate media device files
+	struct dirent *dir;
+	DIR *d = opendir("/dev");
+	while ((dir = readdir(d)) != NULL) {
+		if (strncmp(dir->d_name, "media", 5) == 0) {
+			char path[261];
+			snprintf(path, 261, "/dev/%s", dir->d_name);
 
-            MPDevice *device = mp_device_open(path);
+			MPDevice *device = mp_device_open(path);
 
-            if (device) {
-                MPDeviceList *next = malloc(sizeof(MPDeviceList));
-                next->device = device;
-                next->next = current;
-                current = next;
-            }
-        }
-    }
-    closedir(d);
+			if (device) {
+				MPDeviceList *next = malloc(sizeof(MPDeviceList));
+				next->device = device;
+				next->next = current;
+				current = next;
+			}
+		}
+	}
+	closedir(d);
 
-    return current;
+	return current;
 }
 
-void mp_device_list_free(MPDeviceList *device_list)
+void
+mp_device_list_free(MPDeviceList *device_list)
 {
-    while (device_list) {
-        MPDeviceList *tmp = device_list;
-        device_list = tmp->next;
+	while (device_list) {
+		MPDeviceList *tmp = device_list;
+		device_list = tmp->next;
 
-        mp_device_close(tmp->device);
-        free(tmp);
-    }
+		mp_device_close(tmp->device);
+		free(tmp);
+	}
 }
 
-MPDevice *mp_device_list_find_remove(MPDeviceList **list, const char *driver_name)
+MPDevice *
+mp_device_list_find_remove(MPDeviceList **list, const char *driver_name)
 {
-    MPDevice *found_device = NULL;
-    int length = strlen(driver_name);
+	MPDevice *found_device = NULL;
+	int length = strlen(driver_name);
 
-    while (*list) {
-        MPDevice *device = mp_device_list_get(*list);
-        const struct media_device_info *info = mp_device_get_info(device);
+	while (*list) {
+		MPDevice *device = mp_device_list_get(*list);
+		const struct media_device_info *info = mp_device_get_info(device);
 
-        if (strncmp(info->driver, driver_name, length) == 0) {
-            found_device = mp_device_list_remove(list);
-            break;
-        }
+		if (strncmp(info->driver, driver_name, length) == 0) {
+			found_device = mp_device_list_remove(list);
+			break;
+		}
 
-        list = &(*list)->next;
-    }
+		list = &(*list)->next;
+	}
 
-    return found_device;
+	return found_device;
 }
 
-MPDevice *mp_device_list_remove(MPDeviceList **device_list)
+MPDevice *
+mp_device_list_remove(MPDeviceList **device_list)
 {
-    MPDevice *device = (*device_list)->device;
+	MPDevice *device = (*device_list)->device;
 
-    if ((*device_list)->next) {
-        MPDeviceList *tmp = (*device_list)->next;
-        **device_list = *tmp;
-        free(tmp);
-    } else {
-        free(*device_list);
-        *device_list = NULL;
-    }
+	if ((*device_list)->next) {
+		MPDeviceList *tmp = (*device_list)->next;
+		**device_list = *tmp;
+		free(tmp);
+	} else {
+		free(*device_list);
+		*device_list = NULL;
+	}
 
-    return device;
+	return device;
 }
 
-MPDevice *mp_device_list_get(const MPDeviceList *device_list)
+MPDevice *
+mp_device_list_get(const MPDeviceList *device_list)
 {
-    return device_list->device;
+	return device_list->device;
 }
 
-MPDeviceList *mp_device_list_next(const MPDeviceList *device_list)
+MPDeviceList *
+mp_device_list_next(const MPDeviceList *device_list)
 {
-    return device_list->next;
+	return device_list->next;
 }

+ 26 - 13
device.h

@@ -5,7 +5,8 @@
 #include <stddef.h>
 #include <stdint.h>
 
-bool mp_find_device_path(struct media_v2_intf_devnode devnode, char *path, int length);
+bool mp_find_device_path(struct media_v2_intf_devnode devnode, char *path,
+			 int length);
 
 typedef struct _MPDevice MPDevice;
 
@@ -14,26 +15,37 @@ MPDevice *mp_device_open(const char *path);
 MPDevice *mp_device_new(int fd);
 void mp_device_close(MPDevice *device);
 
-bool mp_device_setup_link(MPDevice *device, uint32_t source_pad_id, uint32_t sink_pad_id, bool enabled);
+bool mp_device_setup_link(MPDevice *device, uint32_t source_pad_id,
+			  uint32_t sink_pad_id, bool enabled);
 
 const struct media_device_info *mp_device_get_info(const MPDevice *device);
-const struct media_v2_entity *mp_device_find_entity(const MPDevice *device, const char *driver_name);
-const struct media_v2_entity *mp_device_find_entity_type(const MPDevice *device, const uint32_t type);
-const struct media_v2_entity *mp_device_get_entity(const MPDevice *device, uint32_t id);
+const struct media_v2_entity *mp_device_find_entity(const MPDevice *device,
+						    const char *driver_name);
+const struct media_v2_entity *mp_device_find_entity_type(const MPDevice *device,
+							 const uint32_t type);
+const struct media_v2_entity *mp_device_get_entity(const MPDevice *device,
+						   uint32_t id);
 const struct media_v2_entity *mp_device_get_entities(const MPDevice *device);
 size_t mp_device_get_num_entities(const MPDevice *device);
-const struct media_v2_interface *mp_device_find_entity_interface(const MPDevice *device, uint32_t entity_id);
-const struct media_v2_interface *mp_device_get_interface(const MPDevice *device, uint32_t id);
+const struct media_v2_interface *
+mp_device_find_entity_interface(const MPDevice *device, uint32_t entity_id);
+const struct media_v2_interface *mp_device_get_interface(const MPDevice *device,
+							 uint32_t id);
 const struct media_v2_interface *mp_device_get_interfaces(const MPDevice *device);
 size_t mp_device_get_num_interfaces(const MPDevice *device);
-const struct media_v2_pad *mp_device_get_pad_from_entity(const MPDevice *device, uint32_t entity_id);
+const struct media_v2_pad *mp_device_get_pad_from_entity(const MPDevice *device,
+							 uint32_t entity_id);
 const struct media_v2_pad *mp_device_get_pad(const MPDevice *device, uint32_t id);
 const struct media_v2_pad *mp_device_get_pads(const MPDevice *device);
 size_t mp_device_get_num_pads(const MPDevice *device);
-const struct media_v2_link *mp_device_find_entity_link(const MPDevice *device, uint32_t entity_id);
-const struct media_v2_link *mp_device_find_link_from(const MPDevice *device, uint32_t source);
-const struct media_v2_link *mp_device_find_link_to(const MPDevice *device, uint32_t sink);
-const struct media_v2_link *mp_device_find_link_between(const MPDevice *device, uint32_t source, uint32_t sink);
+const struct media_v2_link *mp_device_find_entity_link(const MPDevice *device,
+						       uint32_t entity_id);
+const struct media_v2_link *mp_device_find_link_from(const MPDevice *device,
+						     uint32_t source);
+const struct media_v2_link *mp_device_find_link_to(const MPDevice *device,
+						   uint32_t sink);
+const struct media_v2_link *
+mp_device_find_link_between(const MPDevice *device, uint32_t source, uint32_t sink);
 const struct media_v2_link *mp_device_get_link(const MPDevice *device, uint32_t id);
 const struct media_v2_link *mp_device_get_links(const MPDevice *device);
 size_t mp_device_get_num_links(const MPDevice *device);
@@ -43,7 +55,8 @@ typedef struct _MPDeviceList MPDeviceList;
 MPDeviceList *mp_device_list_new();
 void mp_device_list_free(MPDeviceList *device_list);
 
-MPDevice *mp_device_list_find_remove(MPDeviceList **device_list, const char *driver_name);
+MPDevice *mp_device_list_find_remove(MPDeviceList **device_list,
+				     const char *driver_name);
 MPDevice *mp_device_list_remove(MPDeviceList **device_list);
 
 MPDevice *mp_device_list_get(const MPDeviceList *device_list);

+ 113 - 110
ini.c

@@ -25,171 +25,174 @@ https://github.com/benhoyt/inih
 #define MAX_NAME 50
 
 /* Strip whitespace chars off end of given string, in place. Return s. */
-static char* rstrip(char* s)
+static char *
+rstrip(char *s)
 {
-    char* p = s + strlen(s);
-    while (p > s && isspace((unsigned char)(*--p)))
-        *p = '\0';
-    return s;
+	char *p = s + strlen(s);
+	while (p > s && isspace((unsigned char)(*--p)))
+		*p = '\0';
+	return s;
 }
 
 /* Return pointer to first non-whitespace char in given string. */
-static char* lskip(const char* s)
+static char *
+lskip(const char *s)
 {
-    while (*s && isspace((unsigned char)(*s)))
-        s++;
-    return (char*)s;
+	while (*s && isspace((unsigned char)(*s)))
+		s++;
+	return (char *)s;
 }
 
 /* Return pointer to first char (of chars) or inline comment in given string,
    or pointer to null at end of string if neither found. Inline comment must
    be prefixed by a whitespace character to register as a comment. */
-static char* find_chars_or_comment(const char* s, const char* chars)
+static char *
+find_chars_or_comment(const char *s, const char *chars)
 {
 #if INI_ALLOW_INLINE_COMMENTS
-    int was_space = 0;
-    while (*s && (!chars || !strchr(chars, *s)) &&
-           !(was_space && strchr(INI_INLINE_COMMENT_PREFIXES, *s))) {
-        was_space = isspace((unsigned char)(*s));
-        s++;
-    }
+	int was_space = 0;
+	while (*s && (!chars || !strchr(chars, *s)) &&
+	       !(was_space && strchr(INI_INLINE_COMMENT_PREFIXES, *s))) {
+		was_space = isspace((unsigned char)(*s));
+		s++;
+	}
 #else
-    while (*s && (!chars || !strchr(chars, *s))) {
-        s++;
-    }
+	while (*s && (!chars || !strchr(chars, *s))) {
+		s++;
+	}
 #endif
-    return (char*)s;
+	return (char *)s;
 }
 
 /* Version of strncpy that ensures dest (size bytes) is null-terminated. */
-static char* strncpy0(char* dest, const char* src, size_t size)
+static char *
+strncpy0(char *dest, const char *src, size_t size)
 {
-    strncpy(dest, src, size-1);
-    dest[size - 1] = '\0';
-    return dest;
+	strncpy(dest, src, size - 1);
+	dest[size - 1] = '\0';
+	return dest;
 }
 
 /* See documentation in header file. */
-int ini_parse_stream(ini_reader reader, void* stream, ini_handler handler,
-                     void* user)
+int
+ini_parse_stream(ini_reader reader, void *stream, ini_handler handler, void *user)
 {
-    /* Uses a fair bit of stack (use heap instead if you need to) */
+	/* Uses a fair bit of stack (use heap instead if you need to) */
 #if INI_USE_STACK
-    char line[INI_MAX_LINE];
+	char line[INI_MAX_LINE];
 #else
-    char* line;
+	char *line;
 #endif
-    char section[MAX_SECTION] = "";
-    char prev_name[MAX_NAME] = "";
+	char section[MAX_SECTION] = "";
+	char prev_name[MAX_NAME] = "";
 
-    char* start;
-    char* end;
-    char* name;
-    char* value;
-    int lineno = 0;
-    int error = 0;
+	char *start;
+	char *end;
+	char *name;
+	char *value;
+	int lineno = 0;
+	int error = 0;
 
 #if !INI_USE_STACK
-    line = (char*)malloc(INI_MAX_LINE);
-    if (!line) {
-        return -2;
-    }
+	line = (char *)malloc(INI_MAX_LINE);
+	if (!line) {
+		return -2;
+	}
 #endif
 
-    /* Scan through stream line by line */
-    while (reader(line, INI_MAX_LINE, stream) != NULL) {
-        lineno++;
+	/* Scan through stream line by line */
+	while (reader(line, INI_MAX_LINE, stream) != NULL) {
+		lineno++;
 
-        start = line;
+		start = line;
 #if INI_ALLOW_BOM
-        if (lineno == 1 && (unsigned char)start[0] == 0xEF &&
-                           (unsigned char)start[1] == 0xBB &&
-                           (unsigned char)start[2] == 0xBF) {
-            start += 3;
-        }
+		if (lineno == 1 && (unsigned char)start[0] == 0xEF &&
+		    (unsigned char)start[1] == 0xBB &&
+		    (unsigned char)start[2] == 0xBF) {
+			start += 3;
+		}
 #endif
-        start = lskip(rstrip(start));
+		start = lskip(rstrip(start));
 
-        if (*start == ';' || *start == '#') {
-            /* Per Python configparser, allow both ; and # comments at the
+		if (*start == ';' || *start == '#') {
+			/* Per Python configparser, allow both ; and # comments at the
                start of a line */
-        }
+		}
 #if INI_ALLOW_MULTILINE
-        else if (*prev_name && *start && start > line) {
-            /* Non-blank line with leading whitespace, treat as continuation
+		else if (*prev_name && *start && start > line) {
+			/* Non-blank line with leading whitespace, treat as continuation
                of previous name's value (as per Python configparser). */
-            if (!handler(user, section, prev_name, start) && !error)
-                error = lineno;
-        }
+			if (!handler(user, section, prev_name, start) && !error)
+				error = lineno;
+		}
 #endif
-        else if (*start == '[') {
-            /* A "[section]" line */
-            end = find_chars_or_comment(start + 1, "]");
-            if (*end == ']') {
-                *end = '\0';
-                strncpy0(section, start + 1, sizeof(section));
-                *prev_name = '\0';
-            }
-            else if (!error) {
-                /* No ']' found on section line */
-                error = lineno;
-            }
-        }
-        else if (*start) {
-            /* Not a comment, must be a name[=:]value pair */
-            end = find_chars_or_comment(start, "=:");
-            if (*end == '=' || *end == ':') {
-                *end = '\0';
-                name = rstrip(start);
-                value = lskip(end + 1);
+		else if (*start == '[') {
+			/* A "[section]" line */
+			end = find_chars_or_comment(start + 1, "]");
+			if (*end == ']') {
+				*end = '\0';
+				strncpy0(section, start + 1, sizeof(section));
+				*prev_name = '\0';
+			} else if (!error) {
+				/* No ']' found on section line */
+				error = lineno;
+			}
+		} else if (*start) {
+			/* Not a comment, must be a name[=:]value pair */
+			end = find_chars_or_comment(start, "=:");
+			if (*end == '=' || *end == ':') {
+				*end = '\0';
+				name = rstrip(start);
+				value = lskip(end + 1);
 #if INI_ALLOW_INLINE_COMMENTS
-                end = find_chars_or_comment(value, NULL);
-                if (*end)
-                    *end = '\0';
+				end = find_chars_or_comment(value, NULL);
+				if (*end)
+					*end = '\0';
 #endif
-                rstrip(value);
+				rstrip(value);
 
-                /* Valid name[=:]value pair found, call handler */
-                strncpy0(prev_name, name, sizeof(prev_name));
-                if (!handler(user, section, name, value) && !error)
-                    error = lineno;
+				/* Valid name[=:]value pair found, call handler */
+				strncpy0(prev_name, name, sizeof(prev_name));
+				if (!handler(user, section, name, value) && !error)
+					error = lineno;
 				memset(value, 0, strlen(value));
-            }
-            else if (!error) {
-                /* No '=' or ':' found on name[=:]value line */
-                error = lineno;
-            }
-        }
+			} else if (!error) {
+				/* No '=' or ':' found on name[=:]value line */
+				error = lineno;
+			}
+		}
 
 #if INI_STOP_ON_FIRST_ERROR
-        if (error)
-            break;
+		if (error)
+			break;
 #endif
-    }
+	}
 
 #if !INI_USE_STACK
-    free(line);
+	free(line);
 #endif
 
-    return error;
+	return error;
 }
 
 /* See documentation in header file. */
-int ini_parse_file(FILE* file, ini_handler handler, void* user)
+int
+ini_parse_file(FILE *file, ini_handler handler, void *user)
 {
-    return ini_parse_stream((ini_reader)fgets, file, handler, user);
+	return ini_parse_stream((ini_reader)fgets, file, handler, user);
 }
 
 /* See documentation in header file. */
-int ini_parse(const char* filename, ini_handler handler, void* user)
+int
+ini_parse(const char *filename, ini_handler handler, void *user)
 {
-    FILE* file;
-    int error;
-
-    file = fopen(filename, "r");
-    if (!file)
-        return -1;
-    error = ini_parse_file(file, handler, user);
-    fclose(file);
-    return error;
+	FILE *file;
+	int error;
+
+	file = fopen(filename, "r");
+	if (!file)
+		return -1;
+	error = ini_parse_file(file, handler, user);
+	fclose(file);
+	return error;
 }

+ 7 - 7
ini.h

@@ -18,11 +18,11 @@ extern "C" {
 #include <stdio.h>
 
 /* Typedef for prototype of handler function. */
-typedef int (*ini_handler)(void* user, const char* section,
-                           const char* name, const char* value);
+typedef int (*ini_handler)(void *user, const char *section, const char *name,
+			   const char *value);
 
 /* Typedef for prototype of fgets-style reader function. */
-typedef char* (*ini_reader)(char* str, int num, void* stream);
+typedef char *(*ini_reader)(char *str, int num, void *stream);
 
 /* Parse given INI-style file. May have [section]s, name=value pairs
    (whitespace stripped), and comments starting with ';' (semicolon). Section
@@ -37,16 +37,16 @@ typedef char* (*ini_reader)(char* str, int num, void* stream);
    stop on first error), -1 on file open error, or -2 on memory allocation
    error (only when INI_USE_STACK is zero).
 */
-int ini_parse(const char* filename, ini_handler handler, void* user);
+int ini_parse(const char *filename, ini_handler handler, void *user);
 
 /* Same as ini_parse(), but takes a FILE* instead of filename. This doesn't
    close the file when it's finished -- the caller must do that. */
-int ini_parse_file(FILE* file, ini_handler handler, void* user);
+int ini_parse_file(FILE *file, ini_handler handler, void *user);
 
 /* Same as ini_parse(), but takes an ini_reader function pointer instead of
    filename. Used for implementing custom or string-based I/O. */
-int ini_parse_stream(ini_reader reader, void* stream, ini_handler handler,
-                     void* user);
+int ini_parse_stream(ini_reader reader, void *stream, ini_handler handler,
+		     void *user);
 
 /* Nonzero to allow multi-line value parsing, in the style of Python's
    configparser. If allowed, ini_parse() will call the handler with the same

+ 412 - 377
io_pipeline.c

@@ -13,51 +13,49 @@
 #include <stdio.h>
 
 struct media_link_info {
-    unsigned int source_entity_id;
-    unsigned int target_entity_id;
-    char source_fname[260];
-    char target_fname[260];
+	unsigned int source_entity_id;
+	unsigned int target_entity_id;
+	char source_fname[260];
+	char target_fname[260];
 };
 
 struct camera_info {
-    size_t device_index;
+	size_t device_index;
 
-    unsigned int pad_id;
+	unsigned int pad_id;
 
-    char dev_fname[260];
-    int fd;
+	char dev_fname[260];
+	int fd;
 
-    MPCamera *camera;
+	MPCamera *camera;
 
-    int gain_ctrl;
-    int gain_max;
+	int gain_ctrl;
+	int gain_max;
 
-    bool has_auto_focus_continuous;
-    bool has_auto_focus_start;
+	bool has_auto_focus_continuous;
+	bool has_auto_focus_start;
 
+	// unsigned int entity_id;
+	// enum v4l2_buf_type type;
 
-    // unsigned int entity_id;
-    // enum v4l2_buf_type type;
+	// char media_dev_fname[260];
+	// char video_dev_fname[260];
+	// int media_fd;
 
-    // char media_dev_fname[260];
-    // char video_dev_fname[260];
-    // int media_fd;
+	// struct mp_media_link media_links[MP_MAX_LINKS];
+	// int num_media_links;
 
-
-    // struct mp_media_link media_links[MP_MAX_LINKS];
-    // int num_media_links;
-
-    // int gain_ctrl;
+	// int gain_ctrl;
 };
 
 struct device_info {
-    const char *media_dev_name; // owned by camera config
+	const char *media_dev_name; // owned by camera config
 
-    MPDevice *device;
+	MPDevice *device;
 
-    unsigned int interface_pad_id;
+	unsigned int interface_pad_id;
 
-    int video_fd;
+	int video_fd;
 };
 
 static struct camera_info cameras[MP_MAX_CAMERAS];
@@ -78,11 +76,11 @@ static int preview_width;
 static int preview_height;
 
 struct control_state {
-    bool gain_is_manual;
-    int gain;
+	bool gain_is_manual;
+	int gain;
 
-    bool exposure_is_manual;
-    int exposure;
+	bool exposure_is_manual;
+	int exposure;
 };
 
 static struct control_state desired_controls = {};
@@ -93,413 +91,450 @@ static bool want_focus = false;
 static MPPipeline *pipeline;
 static GSource *capture_source;
 
-static void setup_camera(MPDeviceList **device_list, const struct mp_camera_config *config)
+static void
+setup_camera(MPDeviceList **device_list, const struct mp_camera_config *config)
 {
-    // Find device info
-    size_t device_index = 0;
-    for (; device_index < num_devices; ++device_index) {
-        if (strcmp(config->media_dev_name, devices[device_index].media_dev_name) == 0) {
-            break;
-        }
-    }
-
-    if (device_index == num_devices)
-    {
-        device_index = num_devices;
-
-        // Initialize new device
-        struct device_info *info = &devices[device_index];
-        info->media_dev_name = config->media_dev_name;
-        info->device = mp_device_list_find_remove(device_list, info->media_dev_name);
-        if (!info->device) {
-            g_printerr("Could not find /dev/media* node matching '%s'\n", info->media_dev_name);
-            exit(EXIT_FAILURE);
-        }
-
-        const struct media_v2_entity *entity = mp_device_find_entity_type(info->device, MEDIA_ENT_F_IO_V4L);
-        if (!entity) {
-            g_printerr("Could not find device video entity\n");
-            exit(EXIT_FAILURE);
-        }
-
-        const struct media_v2_pad *pad = mp_device_get_pad_from_entity(info->device, entity->id);
-        info->interface_pad_id = pad->id;
-
-        const struct media_v2_interface *interface = mp_device_find_entity_interface(info->device, entity->id);
-        char dev_name[260];
-        if (!mp_find_device_path(interface->devnode, dev_name, 260)) {
-            g_printerr("Could not find video path\n");
-            exit(EXIT_FAILURE);
-        }
-
-        info->video_fd = open(dev_name, O_RDWR);
-        if (info->video_fd == -1) {
-            g_printerr("Could not open %s\n", dev_name);
-            exit(EXIT_FAILURE);
-        }
-
-        ++num_devices;
-    }
-
-    {
-        struct camera_info *info = &cameras[config->index];
-        struct device_info *dev_info = &devices[device_index];
-
-        info->device_index = device_index;
-
-        const struct media_v2_entity *entity = mp_device_find_entity(dev_info->device, config->dev_name);
-        if (!entity) {
-            g_printerr("Could not find camera entity matching '%s'\n", config->dev_name);
-            exit(EXIT_FAILURE);
-        }
-
-        const struct media_v2_pad *pad = mp_device_get_pad_from_entity(dev_info->device, entity->id);
-
-        info->pad_id = pad->id;
-
-        // Make sure the camera starts out as disabled
-        mp_device_setup_link(
-            dev_info->device,
-            info->pad_id,
-            dev_info->interface_pad_id,
-            false);
-
-        const struct media_v2_interface *interface = mp_device_find_entity_interface(dev_info->device, entity->id);
-
-        if (!mp_find_device_path(interface->devnode, info->dev_fname, 260)) {
-            g_printerr("Could not find camera device path\n");
-            exit(EXIT_FAILURE);
-        }
-
-        info->fd = open(info->dev_fname, O_RDWR);
-        if (info->fd == -1) {
-            g_printerr("Could not open %s\n", info->dev_fname);
-            exit(EXIT_FAILURE);
-        }
-
-        info->camera = mp_camera_new(dev_info->video_fd, info->fd);
-
-        // Trigger continuous auto focus if the sensor supports it
-        if (mp_camera_query_control(info->camera, V4L2_CID_FOCUS_AUTO, NULL)) {
-            info->has_auto_focus_continuous = true;
-            mp_camera_control_set_bool(info->camera, V4L2_CID_FOCUS_AUTO, true);
-        }
-        if (mp_camera_query_control(info->camera, V4L2_CID_AUTO_FOCUS_START, NULL)) {
-            info->has_auto_focus_start = true;
-        }
-
-        MPControl control;
-        if (mp_camera_query_control(info->camera, V4L2_CID_GAIN, &control)) {
-            info->gain_ctrl = V4L2_CID_GAIN;
-            info->gain_max = control.max;
-        }
-        else if (mp_camera_query_control(info->camera, V4L2_CID_ANALOGUE_GAIN, &control)) {
-            info->gain_ctrl = V4L2_CID_ANALOGUE_GAIN;
-            info->gain_max = control.max;
-        }
-    }
+	// Find device info
+	size_t device_index = 0;
+	for (; device_index < num_devices; ++device_index) {
+		if (strcmp(config->media_dev_name,
+			   devices[device_index].media_dev_name) == 0) {
+			break;
+		}
+	}
+
+	if (device_index == num_devices) {
+		device_index = num_devices;
+
+		// Initialize new device
+		struct device_info *info = &devices[device_index];
+		info->media_dev_name = config->media_dev_name;
+		info->device = mp_device_list_find_remove(device_list,
+							  info->media_dev_name);
+		if (!info->device) {
+			g_printerr("Could not find /dev/media* node matching '%s'\n",
+				   info->media_dev_name);
+			exit(EXIT_FAILURE);
+		}
+
+		const struct media_v2_entity *entity =
+			mp_device_find_entity_type(info->device, MEDIA_ENT_F_IO_V4L);
+		if (!entity) {
+			g_printerr("Could not find device video entity\n");
+			exit(EXIT_FAILURE);
+		}
+
+		const struct media_v2_pad *pad =
+			mp_device_get_pad_from_entity(info->device, entity->id);
+		info->interface_pad_id = pad->id;
+
+		const struct media_v2_interface *interface =
+			mp_device_find_entity_interface(info->device, entity->id);
+		char dev_name[260];
+		if (!mp_find_device_path(interface->devnode, dev_name, 260)) {
+			g_printerr("Could not find video path\n");
+			exit(EXIT_FAILURE);
+		}
+
+		info->video_fd = open(dev_name, O_RDWR);
+		if (info->video_fd == -1) {
+			g_printerr("Could not open %s\n", dev_name);
+			exit(EXIT_FAILURE);
+		}
+
+		++num_devices;
+	}
+
+	{
+		struct camera_info *info = &cameras[config->index];
+		struct device_info *dev_info = &devices[device_index];
+
+		info->device_index = device_index;
+
+		const struct media_v2_entity *entity =
+			mp_device_find_entity(dev_info->device, config->dev_name);
+		if (!entity) {
+			g_printerr("Could not find camera entity matching '%s'\n",
+				   config->dev_name);
+			exit(EXIT_FAILURE);
+		}
+
+		const struct media_v2_pad *pad =
+			mp_device_get_pad_from_entity(dev_info->device, entity->id);
+
+		info->pad_id = pad->id;
+
+		// Make sure the camera starts out as disabled
+		mp_device_setup_link(dev_info->device, info->pad_id,
+				     dev_info->interface_pad_id, false);
+
+		const struct media_v2_interface *interface =
+			mp_device_find_entity_interface(dev_info->device,
+							entity->id);
+
+		if (!mp_find_device_path(interface->devnode, info->dev_fname, 260)) {
+			g_printerr("Could not find camera device path\n");
+			exit(EXIT_FAILURE);
+		}
+
+		info->fd = open(info->dev_fname, O_RDWR);
+		if (info->fd == -1) {
+			g_printerr("Could not open %s\n", info->dev_fname);
+			exit(EXIT_FAILURE);
+		}
+
+		info->camera = mp_camera_new(dev_info->video_fd, info->fd);
+
+		// Trigger continuous auto focus if the sensor supports it
+		if (mp_camera_query_control(info->camera, V4L2_CID_FOCUS_AUTO,
+					    NULL)) {
+			info->has_auto_focus_continuous = true;
+			mp_camera_control_set_bool(info->camera, V4L2_CID_FOCUS_AUTO,
+						   true);
+		}
+		if (mp_camera_query_control(info->camera, V4L2_CID_AUTO_FOCUS_START,
+					    NULL)) {
+			info->has_auto_focus_start = true;
+		}
+
+		MPControl control;
+		if (mp_camera_query_control(info->camera, V4L2_CID_GAIN, &control)) {
+			info->gain_ctrl = V4L2_CID_GAIN;
+			info->gain_max = control.max;
+		} else if (mp_camera_query_control(
+				   info->camera, V4L2_CID_ANALOGUE_GAIN, &control)) {
+			info->gain_ctrl = V4L2_CID_ANALOGUE_GAIN;
+			info->gain_max = control.max;
+		}
+	}
 }
 
-static void setup(MPPipeline *pipeline, const void *data)
+static void
+setup(MPPipeline *pipeline, const void *data)
 {
-    MPDeviceList *device_list = mp_device_list_new();
+	MPDeviceList *device_list = mp_device_list_new();
 
-    for (size_t i = 0; i < MP_MAX_CAMERAS; ++i) {
-        const struct mp_camera_config *config = mp_get_camera_config(i);
-        if (!config) {
-            break;
-        }
+	for (size_t i = 0; i < MP_MAX_CAMERAS; ++i) {
+		const struct mp_camera_config *config = mp_get_camera_config(i);
+		if (!config) {
+			break;
+		}
 
-        setup_camera(&device_list, config);
-    }
+		setup_camera(&device_list, config);
+	}
 
-    mp_device_list_free(device_list);
+	mp_device_list_free(device_list);
 }
 
-void mp_io_pipeline_start()
+void
+mp_io_pipeline_start()
 {
-    mp_process_pipeline_start();
+	mp_process_pipeline_start();
 
-    pipeline = mp_pipeline_new();
+	pipeline = mp_pipeline_new();
 
-    mp_pipeline_invoke(pipeline, setup, NULL, 0);
+	mp_pipeline_invoke(pipeline, setup, NULL, 0);
 }
 
-void mp_io_pipeline_stop()
+void
+mp_io_pipeline_stop()
 {
-    if (capture_source) {
-        g_source_destroy(capture_source);
-    }
+	if (capture_source) {
+		g_source_destroy(capture_source);
+	}
 
-    mp_pipeline_free(pipeline);
+	mp_pipeline_free(pipeline);
 
-    mp_process_pipeline_stop();
+	mp_process_pipeline_stop();
 }
 
 static void
 update_process_pipeline()
 {
-    struct camera_info *info = &cameras[camera->index];
-
-    // Grab the latest control values
-    if (!current_controls.gain_is_manual) {
-        current_controls.gain = mp_camera_control_get_int32(info->camera, info->gain_ctrl);
-    }
-    if (!current_controls.exposure_is_manual) {
-        current_controls.exposure = mp_camera_control_get_int32(info->camera, V4L2_CID_EXPOSURE);
-    }
-
-    struct mp_process_pipeline_state pipeline_state = {
-        .camera = camera,
-        .mode = mode,
-        .burst_length = burst_length,
-        .preview_width = preview_width,
-        .preview_height = preview_height,
-        .gain_is_manual = current_controls.gain_is_manual,
-        .gain = current_controls.gain,
-        .gain_max = info->gain_max,
-        .exposure_is_manual = current_controls.exposure_is_manual,
-        .exposure = current_controls.exposure,
-        .has_auto_focus_continuous = info->has_auto_focus_continuous,
-        .has_auto_focus_start = info->has_auto_focus_start,
-    };
-    mp_process_pipeline_update_state(&pipeline_state);
+	struct camera_info *info = &cameras[camera->index];
+
+	// Grab the latest control values
+	if (!current_controls.gain_is_manual) {
+		current_controls.gain =
+			mp_camera_control_get_int32(info->camera, info->gain_ctrl);
+	}
+	if (!current_controls.exposure_is_manual) {
+		current_controls.exposure =
+			mp_camera_control_get_int32(info->camera, V4L2_CID_EXPOSURE);
+	}
+
+	struct mp_process_pipeline_state pipeline_state = {
+		.camera = camera,
+		.mode = mode,
+		.burst_length = burst_length,
+		.preview_width = preview_width,
+		.preview_height = preview_height,
+		.gain_is_manual = current_controls.gain_is_manual,
+		.gain = current_controls.gain,
+		.gain_max = info->gain_max,
+		.exposure_is_manual = current_controls.exposure_is_manual,
+		.exposure = current_controls.exposure,
+		.has_auto_focus_continuous = info->has_auto_focus_continuous,
+		.has_auto_focus_start = info->has_auto_focus_start,
+	};
+	mp_process_pipeline_update_state(&pipeline_state);
 }
 
 static void
 focus(MPPipeline *pipeline, const void *data)
 {
-    want_focus = true;
+	want_focus = true;
 }
 
-void mp_io_pipeline_focus()
+void
+mp_io_pipeline_focus()
 {
-    mp_pipeline_invoke(pipeline, focus, NULL, 0);
+	mp_pipeline_invoke(pipeline, focus, NULL, 0);
 }
 
 static void
 capture(MPPipeline *pipeline, const void *data)
 {
-    struct camera_info *info = &cameras[camera->index];
+	struct camera_info *info = &cameras[camera->index];
 
-    captures_remaining = burst_length;
+	captures_remaining = burst_length;
 
-    // Disable the autogain/exposure while taking the burst
-    mp_camera_control_set_int32(info->camera, V4L2_CID_AUTOGAIN, 0);
-    mp_camera_control_set_int32(info->camera, V4L2_CID_EXPOSURE_AUTO, V4L2_EXPOSURE_MANUAL);
+	// Disable the autogain/exposure while taking the burst
+	mp_camera_control_set_int32(info->camera, V4L2_CID_AUTOGAIN, 0);
+	mp_camera_control_set_int32(info->camera, V4L2_CID_EXPOSURE_AUTO,
+				    V4L2_EXPOSURE_MANUAL);
 
-    // Change camera mode for capturing
-    mp_camera_stop_capture(info->camera);
+	// Change camera mode for capturing
+	mp_camera_stop_capture(info->camera);
 
-    mode = camera->capture_mode;
-    mp_camera_set_mode(info->camera, &mode);
-    just_switched_mode = true;
+	mode = camera->capture_mode;
+	mp_camera_set_mode(info->camera, &mode);
+	just_switched_mode = true;
 
-    mp_camera_start_capture(info->camera);
+	mp_camera_start_capture(info->camera);
 
-    update_process_pipeline();
+	update_process_pipeline();
 
-    mp_process_pipeline_capture();
+	mp_process_pipeline_capture();
 }
 
-void mp_io_pipeline_capture()
+void
+mp_io_pipeline_capture()
 {
-    mp_pipeline_invoke(pipeline, capture, NULL, 0);
+	mp_pipeline_invoke(pipeline, capture, NULL, 0);
 }
 
 static void
 update_controls()
 {
-    // Don't update controls while capturing
-    if (captures_remaining > 0) {
-        return;
-    }
-
-    struct camera_info *info = &cameras[camera->index];
-
-    if (want_focus) {
-        if (info->has_auto_focus_continuous) {
-            mp_camera_control_set_bool(info->camera, V4L2_CID_FOCUS_AUTO, 1);
-        } else if (info->has_auto_focus_start) {
-            mp_camera_control_set_bool(info->camera, V4L2_CID_AUTO_FOCUS_START, 1);
-        }
-
-        want_focus = false;
-    }
-
-    if (current_controls.gain_is_manual != desired_controls.gain_is_manual) {
-        mp_camera_control_set_bool(info->camera, V4L2_CID_AUTOGAIN, !desired_controls.gain_is_manual);
-    }
-
-    if (desired_controls.gain_is_manual && current_controls.gain != desired_controls.gain) {
-        mp_camera_control_set_int32(info->camera, info->gain_ctrl, desired_controls.gain);
-    }
-
-    if (current_controls.exposure_is_manual != desired_controls.exposure_is_manual) {
-        mp_camera_control_set_int32(
-            info->camera,
-            V4L2_CID_EXPOSURE_AUTO,
-            desired_controls.exposure_is_manual ? V4L2_EXPOSURE_MANUAL : V4L2_EXPOSURE_AUTO);
-    }
-
-    if (desired_controls.exposure_is_manual && current_controls.exposure != desired_controls.exposure) {
-        mp_camera_control_set_int32(info->camera, V4L2_CID_EXPOSURE, desired_controls.exposure);
-    }
-
-    current_controls = desired_controls;
+	// Don't update controls while capturing
+	if (captures_remaining > 0) {
+		return;
+	}
+
+	struct camera_info *info = &cameras[camera->index];
+
+	if (want_focus) {
+		if (info->has_auto_focus_continuous) {
+			mp_camera_control_set_bool(info->camera, V4L2_CID_FOCUS_AUTO,
+						   1);
+		} else if (info->has_auto_focus_start) {
+			mp_camera_control_set_bool(info->camera,
+						   V4L2_CID_AUTO_FOCUS_START, 1);
+		}
+
+		want_focus = false;
+	}
+
+	if (current_controls.gain_is_manual != desired_controls.gain_is_manual) {
+		mp_camera_control_set_bool(info->camera, V4L2_CID_AUTOGAIN,
+					   !desired_controls.gain_is_manual);
+	}
+
+	if (desired_controls.gain_is_manual &&
+	    current_controls.gain != desired_controls.gain) {
+		mp_camera_control_set_int32(info->camera, info->gain_ctrl,
+					    desired_controls.gain);
+	}
+
+	if (current_controls.exposure_is_manual !=
+	    desired_controls.exposure_is_manual) {
+		mp_camera_control_set_int32(info->camera, V4L2_CID_EXPOSURE_AUTO,
+					    desired_controls.exposure_is_manual ?
+						    V4L2_EXPOSURE_MANUAL :
+						    V4L2_EXPOSURE_AUTO);
+	}
+
+	if (desired_controls.exposure_is_manual &&
+	    current_controls.exposure != desired_controls.exposure) {
+		mp_camera_control_set_int32(info->camera, V4L2_CID_EXPOSURE,
+					    desired_controls.exposure);
+	}
+
+	current_controls = desired_controls;
 }
 
 static void
 on_frame(MPImage image, void *data)
 {
-    // Only update controls right after a frame was captured
-    update_controls();
-
-    // When the mode is switched while capturing we get a couple blank frames,
-    // presumably from buffers made ready during the switch. Ignore these.
-    if (just_switched_mode)
-    {
-        if (blank_frame_count < 20) {
-            // Only check a 50x50 area
-            size_t test_size = MIN(50, image.width) * MIN(50, image.height);
-
-            bool image_is_blank = true;
-            for (size_t i = 0; i < test_size; ++i) {
-                if (image.data[i] != 0) {
-                    image_is_blank = false;
-                }
-            }
-
-            if (image_is_blank) {
-                ++blank_frame_count;
-                return;
-            }
-        } else {
-            printf("Blank image limit reached, resulting capture may be blank\n");
-        }
-
-        just_switched_mode = false;
-        blank_frame_count = 0;
-    }
-
-    // Copy from the camera buffer
-    size_t size = mp_pixel_format_width_to_bytes(image.pixel_format, image.width) * image.height;
-    uint8_t *buffer = malloc(size);
-    memcpy(buffer, image.data, size);
-
-    image.data = buffer;
-
-    // Send the image off for processing
-    mp_process_pipeline_process_image(image);
-
-    if (captures_remaining > 0) {
-        --captures_remaining;
-
-        if (captures_remaining == 0) {
-            struct camera_info *info = &cameras[camera->index];
-
-            // Restore the auto exposure and gain if needed
-            if (!current_controls.exposure_is_manual) {
-                mp_camera_control_set_int32(info->camera, V4L2_CID_EXPOSURE_AUTO, V4L2_EXPOSURE_AUTO);
-            }
-
-            if (!current_controls.gain_is_manual) {
-                mp_camera_control_set_bool(info->camera, V4L2_CID_AUTOGAIN, true);
-            }
-
-            // Go back to preview mode
-            mp_camera_stop_capture(info->camera);
-
-            mode = camera->preview_mode;
-            mp_camera_set_mode(info->camera, &mode);
-            just_switched_mode = true;
-
-            mp_camera_start_capture(info->camera);
-
-            update_process_pipeline();
-        }
-    }
+	// Only update controls right after a frame was captured
+	update_controls();
+
+	// When the mode is switched while capturing we get a couple blank frames,
+	// presumably from buffers made ready during the switch. Ignore these.
+	if (just_switched_mode) {
+		if (blank_frame_count < 20) {
+			// Only check a 50x50 area
+			size_t test_size =
+				MIN(50, image.width) * MIN(50, image.height);
+
+			bool image_is_blank = true;
+			for (size_t i = 0; i < test_size; ++i) {
+				if (image.data[i] != 0) {
+					image_is_blank = false;
+				}
+			}
+
+			if (image_is_blank) {
+				++blank_frame_count;
+				return;
+			}
+		} else {
+			printf("Blank image limit reached, resulting capture may be blank\n");
+		}
+
+		just_switched_mode = false;
+		blank_frame_count = 0;
+	}
+
+	// Copy from the camera buffer
+	size_t size =
+		mp_pixel_format_width_to_bytes(image.pixel_format, image.width) *
+		image.height;
+	uint8_t *buffer = malloc(size);
+	memcpy(buffer, image.data, size);
+
+	image.data = buffer;
+
+	// Send the image off for processing
+	mp_process_pipeline_process_image(image);
+
+	if (captures_remaining > 0) {
+		--captures_remaining;
+
+		if (captures_remaining == 0) {
+			struct camera_info *info = &cameras[camera->index];
+
+			// Restore the auto exposure and gain if needed
+			if (!current_controls.exposure_is_manual) {
+				mp_camera_control_set_int32(info->camera,
+							    V4L2_CID_EXPOSURE_AUTO,
+							    V4L2_EXPOSURE_AUTO);
+			}
+
+			if (!current_controls.gain_is_manual) {
+				mp_camera_control_set_bool(info->camera,
+							   V4L2_CID_AUTOGAIN, true);
+			}
+
+			// Go back to preview mode
+			mp_camera_stop_capture(info->camera);
+
+			mode = camera->preview_mode;
+			mp_camera_set_mode(info->camera, &mode);
+			just_switched_mode = true;
+
+			mp_camera_start_capture(info->camera);
+
+			update_process_pipeline();
+		}
+	}
 }
 
 static void
 update_state(MPPipeline *pipeline, const struct mp_io_pipeline_state *state)
 {
-    // Make sure the state isn't updated more than it needs to be by checking
-    // whether this state change actually changes anything.
-    bool has_changed = false;
-
-    if (camera != state->camera) {
-        has_changed = true;
-
-        if (camera) {
-            struct camera_info *info = &cameras[camera->index];
-            struct device_info *dev_info = &devices[info->device_index];
-
-            mp_camera_stop_capture(info->camera);
-            mp_device_setup_link(
-                dev_info->device,
-                info->pad_id,
-                dev_info->interface_pad_id,
-                false);
-        }
-
-        if (capture_source) {
-            g_source_destroy(capture_source);
-            capture_source = NULL;
-        }
-
-        camera = state->camera;
-
-        if (camera) {
-            struct camera_info *info = &cameras[camera->index];
-            struct device_info *dev_info = &devices[info->device_index];
-
-            mp_device_setup_link(
-                dev_info->device,
-                info->pad_id,
-                dev_info->interface_pad_id,
-                true);
-
-            mode = camera->preview_mode;
-            mp_camera_set_mode(info->camera, &mode);
-
-            mp_camera_start_capture(info->camera);
-            capture_source = mp_pipeline_add_capture_source(pipeline, info->camera, on_frame, NULL);
-
-            current_controls.gain_is_manual = mp_camera_control_get_int32(info->camera, V4L2_CID_EXPOSURE_AUTO) == V4L2_EXPOSURE_MANUAL;
-            current_controls.gain = mp_camera_control_get_int32(info->camera, info->gain_ctrl);
-
-            current_controls.exposure_is_manual = mp_camera_control_get_bool(info->camera, V4L2_CID_AUTOGAIN) == 0;
-            current_controls.exposure = mp_camera_control_get_int32(info->camera, V4L2_CID_EXPOSURE);
-        }
-    }
-
-    has_changed = has_changed
-        || burst_length != state->burst_length
-        || preview_width != state->preview_width
-        || preview_height != state->preview_height;
-
-    burst_length = state->burst_length;
-    preview_width = state->preview_width;
-    preview_height = state->preview_height;
-
-    if (camera) {
-        struct control_state previous_desired = desired_controls;
-
-        desired_controls.gain_is_manual = state->gain_is_manual;
-        desired_controls.gain = state->gain;
-        desired_controls.exposure_is_manual = state->exposure_is_manual;
-        desired_controls.exposure = state->exposure;
-
-        has_changed = has_changed || memcmp(&previous_desired, &desired_controls, sizeof(struct control_state)) != 0;
-    }
-
-    assert(has_changed);
-
-    update_process_pipeline();
+	// Make sure the state isn't updated more than it needs to be by checking
+	// whether this state change actually changes anything.
+	bool has_changed = false;
+
+	if (camera != state->camera) {
+		has_changed = true;
+
+		if (camera) {
+			struct camera_info *info = &cameras[camera->index];
+			struct device_info *dev_info = &devices[info->device_index];
+
+			mp_camera_stop_capture(info->camera);
+			mp_device_setup_link(dev_info->device, info->pad_id,
+					     dev_info->interface_pad_id, false);
+		}
+
+		if (capture_source) {
+			g_source_destroy(capture_source);
+			capture_source = NULL;
+		}
+
+		camera = state->camera;
+
+		if (camera) {
+			struct camera_info *info = &cameras[camera->index];
+			struct device_info *dev_info = &devices[info->device_index];
+
+			mp_device_setup_link(dev_info->device, info->pad_id,
+					     dev_info->interface_pad_id, true);
+
+			mode = camera->preview_mode;
+			mp_camera_set_mode(info->camera, &mode);
+
+			mp_camera_start_capture(info->camera);
+			capture_source = mp_pipeline_add_capture_source(
+				pipeline, info->camera, on_frame, NULL);
+
+			current_controls.gain_is_manual =
+				mp_camera_control_get_int32(
+					info->camera, V4L2_CID_EXPOSURE_AUTO) ==
+				V4L2_EXPOSURE_MANUAL;
+			current_controls.gain = mp_camera_control_get_int32(
+				info->camera, info->gain_ctrl);
+
+			current_controls.exposure_is_manual =
+				mp_camera_control_get_bool(info->camera,
+							   V4L2_CID_AUTOGAIN) == 0;
+			current_controls.exposure = mp_camera_control_get_int32(
+				info->camera, V4L2_CID_EXPOSURE);
+		}
+	}
+
+	has_changed = has_changed || burst_length != state->burst_length ||
+		      preview_width != state->preview_width ||
+		      preview_height != state->preview_height;
+
+	burst_length = state->burst_length;
+	preview_width = state->preview_width;
+	preview_height = state->preview_height;
+
+	if (camera) {
+		struct control_state previous_desired = desired_controls;
+
+		desired_controls.gain_is_manual = state->gain_is_manual;
+		desired_controls.gain = state->gain;
+		desired_controls.exposure_is_manual = state->exposure_is_manual;
+		desired_controls.exposure = state->exposure;
+
+		has_changed =
+			has_changed || memcmp(&previous_desired, &desired_controls,
+					      sizeof(struct control_state)) != 0;
+	}
+
+	assert(has_changed);
+
+	update_process_pipeline();
 }
 
-void mp_io_pipeline_update_state(const struct mp_io_pipeline_state *state)
+void
+mp_io_pipeline_update_state(const struct mp_io_pipeline_state *state)
 {
-    mp_pipeline_invoke(pipeline, (MPPipelineCallback)update_state, state, sizeof(struct mp_io_pipeline_state));
+	mp_pipeline_invoke(pipeline, (MPPipelineCallback)update_state, state,
+			   sizeof(struct mp_io_pipeline_state));
 }

+ 8 - 8
io_pipeline.h

@@ -3,18 +3,18 @@
 #include "camera_config.h"
 
 struct mp_io_pipeline_state {
-    const struct mp_camera_config *camera;
+	const struct mp_camera_config *camera;
 
-    int burst_length;
+	int burst_length;
 
-    int preview_width;
-    int preview_height;
+	int preview_width;
+	int preview_height;
 
-    bool gain_is_manual;
-    int gain;
+	bool gain_is_manual;
+	int gain;
 
-    bool exposure_is_manual;
-    int exposure;
+	bool exposure_is_manual;
+	int exposure;
 };
 
 void mp_io_pipeline_start();

+ 118 - 106
main.c

@@ -21,10 +21,7 @@
 #include "quickpreview.h"
 #include "io_pipeline.h"
 
-enum user_control {
-	USER_CONTROL_ISO,
-	USER_CONTROL_SHUTTER
-};
+enum user_control { USER_CONTROL_ISO, USER_CONTROL_SHUTTER };
 
 static bool camera_is_initialized = false;
 static const struct mp_camera_config *camera = NULL;
@@ -121,17 +118,14 @@ update_state(const struct mp_main_state *state)
 	return false;
 }
 
-void mp_main_update_state(const struct mp_main_state *state)
+void
+mp_main_update_state(const struct mp_main_state *state)
 {
 	struct mp_main_state *state_copy = malloc(sizeof(struct mp_main_state));
 	*state_copy = *state;
 
-	g_main_context_invoke_full(
-		g_main_context_default(),
-		G_PRIORITY_DEFAULT_IDLE,
-		(GSourceFunc)update_state,
-		state_copy,
-		free);
+	g_main_context_invoke_full(g_main_context_default(), G_PRIORITY_DEFAULT_IDLE,
+				   (GSourceFunc)update_state, state_copy, free);
 }
 
 static bool
@@ -145,19 +139,16 @@ set_preview(cairo_surface_t *image)
 	return false;
 }
 
-void mp_main_set_preview(cairo_surface_t *image)
+void
+mp_main_set_preview(cairo_surface_t *image)
 {
-	g_main_context_invoke_full(
-		g_main_context_default(),
-		G_PRIORITY_DEFAULT_IDLE,
-		(GSourceFunc)set_preview,
-		image,
-		NULL);
+	g_main_context_invoke_full(g_main_context_default(), G_PRIORITY_DEFAULT_IDLE,
+				   (GSourceFunc)set_preview, image, NULL);
 }
 
 static void
-draw_surface_scaled_centered(
-	cairo_t *cr, uint32_t dst_width, uint32_t dst_height, cairo_surface_t *surface)
+draw_surface_scaled_centered(cairo_t *cr, uint32_t dst_width, uint32_t dst_height,
+			     cairo_surface_t *surface)
 {
 	cairo_save(cr);
 
@@ -165,7 +156,7 @@ draw_surface_scaled_centered(
 
 	int width = cairo_image_surface_get_width(surface);
 	int height = cairo_image_surface_get_height(surface);
-	double scale = MIN(dst_width / (double) width, dst_height / (double) height);
+	double scale = MIN(dst_width / (double)width, dst_height / (double)height);
 	cairo_scale(cr, scale, scale);
 
 	cairo_translate(cr, -width / 2, -height / 2);
@@ -181,10 +172,8 @@ capture_completed(const char *fname)
 	strncpy(last_path, fname, 260);
 
 	// Create a thumbnail from the current surface
-	cairo_surface_t *thumb = cairo_image_surface_create(
-		CAIRO_FORMAT_ARGB32,
-		24,
-		24);
+	cairo_surface_t *thumb =
+		cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 24, 24);
 
 	cairo_t *cr = cairo_create(thumb);
 	draw_surface_scaled_centered(cr, 24, 24, surface);
@@ -196,16 +185,13 @@ capture_completed(const char *fname)
 	return false;
 }
 
-void mp_main_capture_completed(const char *fname)
+void
+mp_main_capture_completed(const char *fname)
 {
 	gchar *name = g_strdup(fname);
 
-	g_main_context_invoke_full(
-		g_main_context_default(),
-		G_PRIORITY_DEFAULT_IDLE,
-		(GSourceFunc)capture_completed,
-		name,
-		g_free);
+	g_main_context_invoke_full(g_main_context_default(), G_PRIORITY_DEFAULT_IDLE,
+				   (GSourceFunc)capture_completed, name, g_free);
 }
 
 static void
@@ -217,14 +203,16 @@ draw_controls()
 	char shutterangle[6];
 
 	if (exposure_is_manual) {
-		temp = (int)((float)exposure / (float)camera->capture_mode.height * 360);
+		temp = (int)((float)exposure / (float)camera->capture_mode.height *
+			     360);
 		sprintf(shutterangle, "%d\u00b0", temp);
 	} else {
 		sprintf(shutterangle, "auto");
 	}
 
 	if (gain_is_manual) {
-		temp = remap(gain - 1, 0, gain_max, camera->iso_min, camera->iso_max);
+		temp = remap(gain - 1, 0, gain_max, camera->iso_min,
+			     camera->iso_max);
 		sprintf(iso, "%d", temp);
 	} else {
 		sprintf(iso, "auto");
@@ -237,16 +225,18 @@ draw_controls()
 	if (gtk_widget_get_window(preview) == NULL) {
 		return;
 	}
-	status_surface = gdk_window_create_similar_surface(gtk_widget_get_window(preview),
-		CAIRO_CONTENT_COLOR_ALPHA,
-		preview_width, 32);
+	status_surface =
+		gdk_window_create_similar_surface(gtk_widget_get_window(preview),
+						  CAIRO_CONTENT_COLOR_ALPHA,
+						  preview_width, 32);
 
 	cr = cairo_create(status_surface);
 	cairo_set_source_rgba(cr, 0, 0, 0, 0.0);
 	cairo_paint(cr);
 
 	// Draw the outlines for the headings
-	cairo_select_font_face(cr, "sans-serif", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD);
+	cairo_select_font_face(cr, "sans-serif", CAIRO_FONT_SLANT_NORMAL,
+			       CAIRO_FONT_WEIGHT_BOLD);
 	cairo_set_font_size(cr, 9);
 	cairo_set_source_rgba(cr, 0, 0, 0, 1);
 
@@ -266,7 +256,8 @@ draw_controls()
 	cairo_show_text(cr, "Shutter");
 
 	// Draw the outlines for the values
-	cairo_select_font_face(cr, "sans-serif", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
+	cairo_select_font_face(cr, "sans-serif", CAIRO_FONT_SLANT_NORMAL,
+			       CAIRO_FONT_WEIGHT_NORMAL);
 	cairo_set_font_size(cr, 11);
 	cairo_set_source_rgba(cr, 0, 0, 0, 1);
 
@@ -286,7 +277,7 @@ draw_controls()
 	cairo_show_text(cr, shutterangle);
 
 	cairo_destroy(cr);
-	
+
 	gtk_widget_queue_draw_area(preview, 0, 0, preview_width, 32);
 }
 
@@ -302,7 +293,8 @@ preview_draw(GtkWidget *widget, cairo_t *cr, gpointer data)
 
 	// Draw camera preview
 	if (surface) {
-		draw_surface_scaled_centered(cr, preview_width, preview_height, surface);
+		draw_surface_scaled_centered(cr, preview_width, preview_height,
+					     surface);
 	}
 
 	// Draw control overlay
@@ -311,15 +303,14 @@ preview_draw(GtkWidget *widget, cairo_t *cr, gpointer data)
 	return FALSE;
 }
 
-
 static gboolean
 preview_configure(GtkWidget *widget, GdkEventConfigure *event)
 {
 	int new_preview_width = gtk_widget_get_allocated_width(widget);
 	int new_preview_height = gtk_widget_get_allocated_height(widget);
 
-	if (preview_width != new_preview_width || preview_height != new_preview_height)
-	{
+	if (preview_width != new_preview_width ||
+	    preview_height != new_preview_height) {
 		preview_width = new_preview_width;
 		preview_height = new_preview_height;
 		update_io_pipeline();
@@ -336,11 +327,11 @@ on_open_last_clicked(GtkWidget *widget, gpointer user_data)
 	char uri[275];
 	GError *error = NULL;
 
-	if(strlen(last_path) == 0) {
+	if (strlen(last_path) == 0) {
 		return;
 	}
 	sprintf(uri, "file://%s.tiff", last_path);
-	if(!g_app_info_launch_default_for_uri(uri, NULL, &error)){
+	if (!g_app_info_launch_default_for_uri(uri, NULL, &error)) {
 		g_printerr("Could not launch image viewer: %s\n", error->message);
 	}
 }
@@ -351,7 +342,7 @@ on_open_directory_clicked(GtkWidget *widget, gpointer user_data)
 	char uri[270];
 	GError *error = NULL;
 	sprintf(uri, "file://%s/Pictures", getenv("HOME"));
-	if(!g_app_info_launch_default_for_uri(uri, NULL, &error)){
+	if (!g_app_info_launch_default_for_uri(uri, NULL, &error)) {
 		g_printerr("Could not launch image viewer: %s\n", error->message);
 	}
 }
@@ -377,11 +368,12 @@ on_preview_tap(GtkWidget *widget, GdkEventButton *event, gpointer user_data)
 			gtk_widget_show(control_box);
 		}
 
-		if (event->x < 60 ) {
+		if (event->x < 60) {
 			// ISO
 			current_control = USER_CONTROL_ISO;
 			gtk_label_set_text(GTK_LABEL(control_name), "ISO");
-			gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(control_auto), !gain_is_manual);
+			gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(control_auto),
+						     !gain_is_manual);
 			gtk_adjustment_set_lower(control_slider, 0.0);
 			gtk_adjustment_set_upper(control_slider, (float)gain_max);
 			gtk_adjustment_set_value(control_slider, (double)gain);
@@ -390,7 +382,8 @@ on_preview_tap(GtkWidget *widget, GdkEventButton *event, gpointer user_data)
 			// Shutter angle
 			current_control = USER_CONTROL_SHUTTER;
 			gtk_label_set_text(GTK_LABEL(control_name), "Shutter");
-			gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(control_auto), !exposure_is_manual);
+			gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(control_auto),
+						     !exposure_is_manual);
 			gtk_adjustment_set_lower(control_slider, 1.0);
 			gtk_adjustment_set_upper(control_slider, 360.0);
 			gtk_adjustment_set_value(control_slider, (double)exposure);
@@ -415,7 +408,8 @@ void
 on_camera_switch_clicked(GtkWidget *widget, gpointer user_data)
 {
 	size_t next_index = camera->index + 1;
-	const struct mp_camera_config *next_camera = mp_get_camera_config(next_index);
+	const struct mp_camera_config *next_camera =
+		mp_get_camera_config(next_index);
 
 	if (!next_camera) {
 		next_index = 0;
@@ -445,18 +439,18 @@ on_control_auto_toggled(GtkToggleButton *widget, gpointer user_data)
 	bool has_changed;
 
 	switch (current_control) {
-		case USER_CONTROL_ISO:
-			if (gain_is_manual != is_manual) {
-				gain_is_manual = is_manual;
-				has_changed = true;
-			}
-			break;
-		case USER_CONTROL_SHUTTER:
-			if (exposure_is_manual != is_manual) {
-				exposure_is_manual = is_manual;
-				has_changed = true;
-			}
-			break;
+	case USER_CONTROL_ISO:
+		if (gain_is_manual != is_manual) {
+			gain_is_manual = is_manual;
+			has_changed = true;
+		}
+		break;
+	case USER_CONTROL_SHUTTER:
+		if (exposure_is_manual != is_manual) {
+			exposure_is_manual = is_manual;
+			has_changed = true;
+		}
+		break;
 	}
 
 	if (has_changed) {
@@ -472,22 +466,22 @@ on_control_slider_changed(GtkAdjustment *widget, gpointer user_data)
 
 	bool has_changed = false;
 	switch (current_control) {
-		case USER_CONTROL_ISO:
-			if (value != gain) {
-				gain = (int)value;
-				has_changed = true;
-			}
-			break;
-		case USER_CONTROL_SHUTTER:
-		{
-			// So far all sensors use exposure time in number of sensor rows
-			int new_exposure = (int)(value / 360.0 * camera->capture_mode.height);
-			if (new_exposure != exposure) {
-				exposure = new_exposure;
-				has_changed = true;
-			}
-			break;
+	case USER_CONTROL_ISO:
+		if (value != gain) {
+			gain = (int)value;
+			has_changed = true;
+		}
+		break;
+	case USER_CONTROL_SHUTTER: {
+		// So far all sensors use exposure time in number of sensor rows
+		int new_exposure =
+			(int)(value / 360.0 * camera->capture_mode.height);
+		if (new_exposure != exposure) {
+			exposure = new_exposure;
+			has_changed = true;
 		}
+		break;
+	}
 	}
 
 	if (has_changed) {
@@ -504,19 +498,26 @@ main(int argc, char *argv[])
 
 	setenv("LC_NUMERIC", "C", 1);
 
-
 	gtk_init(&argc, &argv);
-	g_object_set(gtk_settings_get_default(), "gtk-application-prefer-dark-theme", TRUE, NULL);
-	GtkBuilder *builder = gtk_builder_new_from_resource("/org/postmarketos/Megapixels/camera.glade");
+	g_object_set(gtk_settings_get_default(), "gtk-application-prefer-dark-theme",
+		     TRUE, NULL);
+	GtkBuilder *builder = gtk_builder_new_from_resource(
+		"/org/postmarketos/Megapixels/camera.glade");
 
 	GtkWidget *window = GTK_WIDGET(gtk_builder_get_object(builder, "window"));
 	GtkWidget *shutter = GTK_WIDGET(gtk_builder_get_object(builder, "shutter"));
-	GtkWidget *switch_btn = GTK_WIDGET(gtk_builder_get_object(builder, "switch_camera"));
-	GtkWidget *settings_btn = GTK_WIDGET(gtk_builder_get_object(builder, "settings"));
-	GtkWidget *settings_back = GTK_WIDGET(gtk_builder_get_object(builder, "settings_back"));
-	GtkWidget *error_close = GTK_WIDGET(gtk_builder_get_object(builder, "error_close"));
-	GtkWidget *open_last = GTK_WIDGET(gtk_builder_get_object(builder, "open_last"));
-	GtkWidget *open_directory = GTK_WIDGET(gtk_builder_get_object(builder, "open_directory"));
+	GtkWidget *switch_btn =
+		GTK_WIDGET(gtk_builder_get_object(builder, "switch_camera"));
+	GtkWidget *settings_btn =
+		GTK_WIDGET(gtk_builder_get_object(builder, "settings"));
+	GtkWidget *settings_back =
+		GTK_WIDGET(gtk_builder_get_object(builder, "settings_back"));
+	GtkWidget *error_close =
+		GTK_WIDGET(gtk_builder_get_object(builder, "error_close"));
+	GtkWidget *open_last =
+		GTK_WIDGET(gtk_builder_get_object(builder, "open_last"));
+	GtkWidget *open_directory =
+		GTK_WIDGET(gtk_builder_get_object(builder, "open_directory"));
 	preview = GTK_WIDGET(gtk_builder_get_object(builder, "preview"));
 	error_box = GTK_WIDGET(gtk_builder_get_object(builder, "error_box"));
 	error_message = GTK_WIDGET(gtk_builder_get_object(builder, "error_message"));
@@ -524,38 +525,49 @@ main(int argc, char *argv[])
 	thumb_last = GTK_WIDGET(gtk_builder_get_object(builder, "thumb_last"));
 	control_box = GTK_WIDGET(gtk_builder_get_object(builder, "control_box"));
 	control_name = GTK_WIDGET(gtk_builder_get_object(builder, "control_name"));
-	control_slider = GTK_ADJUSTMENT(gtk_builder_get_object(builder, "control_adj"));
+	control_slider =
+		GTK_ADJUSTMENT(gtk_builder_get_object(builder, "control_adj"));
 	control_auto = GTK_WIDGET(gtk_builder_get_object(builder, "control_auto"));
 	g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
 	g_signal_connect(shutter, "clicked", G_CALLBACK(on_shutter_clicked), NULL);
-	g_signal_connect(error_close, "clicked", G_CALLBACK(on_error_close_clicked), NULL);
-	g_signal_connect(switch_btn, "clicked", G_CALLBACK(on_camera_switch_clicked), NULL);
-	g_signal_connect(settings_btn, "clicked", G_CALLBACK(on_settings_btn_clicked), NULL);
-	g_signal_connect(settings_back, "clicked", G_CALLBACK(on_back_clicked), NULL);
-	g_signal_connect(open_last, "clicked", G_CALLBACK(on_open_last_clicked), NULL);
-	g_signal_connect(open_directory, "clicked", G_CALLBACK(on_open_directory_clicked), NULL);
+	g_signal_connect(error_close, "clicked", G_CALLBACK(on_error_close_clicked),
+			 NULL);
+	g_signal_connect(switch_btn, "clicked", G_CALLBACK(on_camera_switch_clicked),
+			 NULL);
+	g_signal_connect(settings_btn, "clicked",
+			 G_CALLBACK(on_settings_btn_clicked), NULL);
+	g_signal_connect(settings_back, "clicked", G_CALLBACK(on_back_clicked),
+			 NULL);
+	g_signal_connect(open_last, "clicked", G_CALLBACK(on_open_last_clicked),
+			 NULL);
+	g_signal_connect(open_directory, "clicked",
+			 G_CALLBACK(on_open_directory_clicked), NULL);
 	g_signal_connect(preview, "draw", G_CALLBACK(preview_draw), NULL);
-	g_signal_connect(preview, "configure-event", G_CALLBACK(preview_configure), NULL);
+	g_signal_connect(preview, "configure-event", G_CALLBACK(preview_configure),
+			 NULL);
 	gtk_widget_set_events(preview, gtk_widget_get_events(preview) |
-			GDK_BUTTON_PRESS_MASK | GDK_POINTER_MOTION_MASK);
-	g_signal_connect(preview, "button-press-event", G_CALLBACK(on_preview_tap), NULL);
-	g_signal_connect(control_auto, "toggled", G_CALLBACK(on_control_auto_toggled), NULL);
-	g_signal_connect(control_slider, "value-changed", G_CALLBACK(on_control_slider_changed), NULL);
+					       GDK_BUTTON_PRESS_MASK |
+					       GDK_POINTER_MOTION_MASK);
+	g_signal_connect(preview, "button-press-event", G_CALLBACK(on_preview_tap),
+			 NULL);
+	g_signal_connect(control_auto, "toggled",
+			 G_CALLBACK(on_control_auto_toggled), NULL);
+	g_signal_connect(control_slider, "value-changed",
+			 G_CALLBACK(on_control_slider_changed), NULL);
 
 	GtkCssProvider *provider = gtk_css_provider_new();
 	if (access("camera.css", F_OK) != -1) {
 		gtk_css_provider_load_from_path(provider, "camera.css", NULL);
 	} else {
-		gtk_css_provider_load_from_resource(provider, "/org/postmarketos/Megapixels/camera.css");
+		gtk_css_provider_load_from_resource(
+			provider, "/org/postmarketos/Megapixels/camera.css");
 	}
 	GtkStyleContext *context = gtk_widget_get_style_context(error_box);
-	gtk_style_context_add_provider(context,
-		GTK_STYLE_PROVIDER(provider),
-		GTK_STYLE_PROVIDER_PRIORITY_USER);
+	gtk_style_context_add_provider(context, GTK_STYLE_PROVIDER(provider),
+				       GTK_STYLE_PROVIDER_PRIORITY_USER);
 	context = gtk_widget_get_style_context(control_box);
-	gtk_style_context_add_provider(context,
-		GTK_STYLE_PROVIDER(provider),
-		GTK_STYLE_PROVIDER_PRIORITY_USER);
+	gtk_style_context_add_provider(context, GTK_STYLE_PROVIDER(provider),
+				       GTK_STYLE_PROVIDER_PRIORITY_USER);
 
 	mp_io_pipeline_start();
 

+ 10 - 11
main.h

@@ -4,18 +4,18 @@
 #include "gtk/gtk.h"
 
 struct mp_main_state {
-    const struct mp_camera_config *camera;
-    MPCameraMode mode;
+	const struct mp_camera_config *camera;
+	MPCameraMode mode;
 
-    bool gain_is_manual;
-    int gain;
-    int gain_max;
+	bool gain_is_manual;
+	int gain;
+	int gain_max;
 
-    bool exposure_is_manual;
-    int exposure;
+	bool exposure_is_manual;
+	int exposure;
 
-    bool has_auto_focus_continuous;
-    bool has_auto_focus_start;
+	bool has_auto_focus_continuous;
+	bool has_auto_focus_start;
 };
 
 void mp_main_update_state(const struct mp_main_state *state);
@@ -23,5 +23,4 @@ void mp_main_update_state(const struct mp_main_state *state);
 void mp_main_set_preview(cairo_surface_t *image);
 void mp_main_capture_completed(const char *fname);
 
-int
-remap(int value, int input_min, int input_max, int output_min, int output_max);
+int remap(int value, int input_min, int input_max, int output_min, int output_max);

+ 7 - 6
matrix.c

@@ -1,14 +1,15 @@
 void
-multiply_matrices(float a[9], float b[9], float out[9]) {
+multiply_matrices(float a[9], float b[9], float out[9])
+{
 	// zero out target matrix
-	for(int i=0; i<9; i++) {
+	for (int i = 0; i < 9; i++) {
 		out[i] = 0;
 	}
 
-	for(int i=0; i<3; i++) {
-		for(int j=0; j<3; j++) {
-			for(int k=0; k<3; k++) {
-				out[i*3+j] += a[i*3+k] * b[k*3+j];
+	for (int i = 0; i < 3; i++) {
+		for (int j = 0; j < 3; j++) {
+			for (int k = 0; k < 3; k++) {
+				out[i * 3 + j] += a[i * 3 + k] * b[k * 3 + j];
 			}
 		}
 	}

+ 72 - 70
pipeline.c

@@ -5,104 +5,106 @@
 #include <assert.h>
 
 struct _MPPipeline {
-    GMainContext *main_context;
-    GMainLoop *main_loop;
-    pthread_t thread;
+	GMainContext *main_context;
+	GMainLoop *main_loop;
+	pthread_t thread;
 };
 
-static void *thread_main_loop(void *arg)
+static void *
+thread_main_loop(void *arg)
 {
-    MPPipeline *pipeline = arg;
+	MPPipeline *pipeline = arg;
 
-    g_main_loop_run(pipeline->main_loop);
-    return NULL;
+	g_main_loop_run(pipeline->main_loop);
+	return NULL;
 }
 
-MPPipeline *mp_pipeline_new()
+MPPipeline *
+mp_pipeline_new()
 {
-    MPPipeline *pipeline = malloc(sizeof(MPPipeline));
-    pipeline->main_context = g_main_context_new();
-    pipeline->main_loop = g_main_loop_new(pipeline->main_context, false);
-    int res = pthread_create(
-        &pipeline->thread, NULL, thread_main_loop, pipeline);
-    assert(res == 0);
-
-    return pipeline;
+	MPPipeline *pipeline = malloc(sizeof(MPPipeline));
+	pipeline->main_context = g_main_context_new();
+	pipeline->main_loop = g_main_loop_new(pipeline->main_context, false);
+	int res =
+		pthread_create(&pipeline->thread, NULL, thread_main_loop, pipeline);
+	assert(res == 0);
+
+	return pipeline;
 }
 
 struct invoke_args {
-    MPPipeline *pipeline;
-    MPPipelineCallback callback;
+	MPPipeline *pipeline;
+	MPPipelineCallback callback;
 };
 
-static bool invoke_impl(struct invoke_args *args)
+static bool
+invoke_impl(struct invoke_args *args)
 {
-    args->callback(args->pipeline, args + 1);
-    return false;
+	args->callback(args->pipeline, args + 1);
+	return false;
 }
 
-void mp_pipeline_invoke(MPPipeline *pipeline, MPPipelineCallback callback, const void *data, size_t size)
+void
+mp_pipeline_invoke(MPPipeline *pipeline, MPPipelineCallback callback,
+		   const void *data, size_t size)
 {
-    if (pthread_self() != pipeline->thread) {
-        struct invoke_args *args = malloc(sizeof(struct invoke_args) + size);
-        args->pipeline = pipeline;
-        args->callback = callback;
-
-        if (size > 0) {
-            memcpy(args + 1, data, size);
-        }
-
-        g_main_context_invoke_full(
-            pipeline->main_context,
-            G_PRIORITY_DEFAULT,
-            (GSourceFunc)invoke_impl,
-            args,
-            free);
-    } else {
-        callback(pipeline, data);
-    }
+	if (pthread_self() != pipeline->thread) {
+		struct invoke_args *args = malloc(sizeof(struct invoke_args) + size);
+		args->pipeline = pipeline;
+		args->callback = callback;
+
+		if (size > 0) {
+			memcpy(args + 1, data, size);
+		}
+
+		g_main_context_invoke_full(pipeline->main_context,
+					   G_PRIORITY_DEFAULT,
+					   (GSourceFunc)invoke_impl, args, free);
+	} else {
+		callback(pipeline, data);
+	}
 }
 
-void mp_pipeline_free(MPPipeline *pipeline)
+void
+mp_pipeline_free(MPPipeline *pipeline)
 {
-    g_main_loop_quit(pipeline->main_loop);
+	g_main_loop_quit(pipeline->main_loop);
 
-    // Force the main thread loop to wake up, otherwise we might not exit
-    g_main_context_wakeup(pipeline->main_context);
+	// Force the main thread loop to wake up, otherwise we might not exit
+	g_main_context_wakeup(pipeline->main_context);
 
-    void *r;
-    pthread_join(pipeline->thread, &r);
-    free(pipeline);
+	void *r;
+	pthread_join(pipeline->thread, &r);
+	free(pipeline);
 }
 
-struct capture_source_args
-{
-    MPCamera *camera;
-    void (*callback)(MPImage, void *);
-    void *user_data;
+struct capture_source_args {
+	MPCamera *camera;
+	void (*callback)(MPImage, void *);
+	void *user_data;
 };
 
-static bool on_capture(int fd, GIOCondition condition, struct capture_source_args *args)
+static bool
+on_capture(int fd, GIOCondition condition, struct capture_source_args *args)
 {
-    mp_camera_capture_image(args->camera, args->callback, args->user_data);
-    return true;
+	mp_camera_capture_image(args->camera, args->callback, args->user_data);
+	return true;
 }
 
 // Not thread safe
-GSource *mp_pipeline_add_capture_source(MPPipeline *pipeline, MPCamera *camera, void (*callback)(MPImage, void *), void *user_data)
+GSource *
+mp_pipeline_add_capture_source(MPPipeline *pipeline, MPCamera *camera,
+			       void (*callback)(MPImage, void *), void *user_data)
 {
-    int video_fd = mp_camera_get_video_fd(camera);
-    GSource *video_source = g_unix_fd_source_new(video_fd, G_IO_IN);
-
-    struct capture_source_args *args = malloc(sizeof(struct capture_source_args));
-    args->camera = camera;
-    args->callback = callback;
-    args->user_data = user_data;
-    g_source_set_callback(
-        video_source,
-        (GSourceFunc)on_capture,
-        args,
-        free);
-    g_source_attach(video_source, pipeline->main_context);
-    return video_source;
+	int video_fd = mp_camera_get_video_fd(camera);
+	GSource *video_source = g_unix_fd_source_new(video_fd, G_IO_IN);
+
+	struct capture_source_args *args =
+		malloc(sizeof(struct capture_source_args));
+	args->camera = camera;
+	args->callback = callback;
+	args->user_data = user_data;
+	g_source_set_callback(video_source, (GSourceFunc)on_capture, args, free);
+	g_source_attach(video_source, pipeline->main_context);
+	return video_source;
 }

+ 5 - 2
pipeline.h

@@ -9,7 +9,10 @@ typedef struct _MPPipeline MPPipeline;
 typedef void (*MPPipelineCallback)(MPPipeline *, const void *);
 
 MPPipeline *mp_pipeline_new();
-void mp_pipeline_invoke(MPPipeline *pipeline, MPPipelineCallback callback, const void *data, size_t size);
+void mp_pipeline_invoke(MPPipeline *pipeline, MPPipelineCallback callback,
+			const void *data, size_t size);
 void mp_pipeline_free(MPPipeline *pipeline);
 
-GSource *mp_pipeline_add_capture_source(MPPipeline *pipeline, MPCamera *camera, void (*callback)(MPImage, void *), void *user_data);
+GSource *mp_pipeline_add_capture_source(MPPipeline *pipeline, MPCamera *camera,
+					void (*callback)(MPImage, void *),
+					void *user_data);

+ 307 - 305
process_pipeline.c

@@ -12,11 +12,8 @@
 
 #define TIFFTAG_FORWARDMATRIX1 50964
 
-static const float colormatrix_srgb[] = {
-    3.2409, -1.5373, -0.4986,
-    -0.9692, 1.8759, 0.0415,
-    0.0556, -0.2039, 1.0569
-};
+static const float colormatrix_srgb[] = { 3.2409, -1.5373, -0.4986, -0.9692, 1.8759,
+					  0.0415, 0.0556,  -0.2039, 1.0569 };
 
 static MPPipeline *pipeline;
 
@@ -49,373 +46,378 @@ static char capture_fname[255];
 static void
 register_custom_tiff_tags(TIFF *tif)
 {
-    static const TIFFFieldInfo custom_fields[] = {
-        {TIFFTAG_FORWARDMATRIX1, -1, -1, TIFF_SRATIONAL, FIELD_CUSTOM, 1, 1, "ForwardMatrix1"},
-    };
-
-    // Add missing dng fields
-    TIFFMergeFieldInfo(tif, custom_fields, sizeof(custom_fields) / sizeof(custom_fields[0]));
+	static const TIFFFieldInfo custom_fields[] = {
+		{ TIFFTAG_FORWARDMATRIX1, -1, -1, TIFF_SRATIONAL, FIELD_CUSTOM, 1, 1,
+		  "ForwardMatrix1" },
+	};
+
+	// Add missing dng fields
+	TIFFMergeFieldInfo(tif, custom_fields,
+			   sizeof(custom_fields) / sizeof(custom_fields[0]));
 }
 
 static bool
 find_processor(char *script)
 {
-    char *xdg_config_home;
-    char filename[] = "postprocess.sh";
-    wordexp_t exp_result;
-
-    // Resolve XDG stuff
-    if ((xdg_config_home = getenv("XDG_CONFIG_HOME")) == NULL) {
-        xdg_config_home = "~/.config";
-    }
-    wordexp(xdg_config_home, &exp_result, 0);
-    xdg_config_home = strdup(exp_result.we_wordv[0]);
-    wordfree(&exp_result);
-
-    // Check postprocess.h in the current working directory
-    sprintf(script, "%s", filename);
-    if(access(script, F_OK) != -1) {
-        sprintf(script, "./%s", filename);
-        printf("Found postprocessor script at %s\n", script);
-        return true;
-    }
-
-    // Check for a script in XDG_CONFIG_HOME
-    sprintf(script, "%s/megapixels/%s", xdg_config_home, filename);
-    if(access(script, F_OK) != -1) {
-        printf("Found postprocessor script at %s\n", script);
-        return true;
-    }
-
-    // Check user overridden /etc/megapixels/postprocessor.sh
-    sprintf(script, "%s/megapixels/%s", SYSCONFDIR, filename);
-    if(access(script, F_OK) != -1) {
-        printf("Found postprocessor script at %s\n", script);
-        return true;
-    }
-
-    // Check packaged /usr/share/megapixels/postprocessor.sh
-    sprintf(script, "%s/megapixels/%s", DATADIR, filename);
-    if(access(script, F_OK) != -1) {
-        printf("Found postprocessor script at %s\n", script);
-        return true;
-    }
-
-    return false;
+	char *xdg_config_home;
+	char filename[] = "postprocess.sh";
+	wordexp_t exp_result;
+
+	// Resolve XDG stuff
+	if ((xdg_config_home = getenv("XDG_CONFIG_HOME")) == NULL) {
+		xdg_config_home = "~/.config";
+	}
+	wordexp(xdg_config_home, &exp_result, 0);
+	xdg_config_home = strdup(exp_result.we_wordv[0]);
+	wordfree(&exp_result);
+
+	// Check postprocess.h in the current working directory
+	sprintf(script, "%s", filename);
+	if (access(script, F_OK) != -1) {
+		sprintf(script, "./%s", filename);
+		printf("Found postprocessor script at %s\n", script);
+		return true;
+	}
+
+	// Check for a script in XDG_CONFIG_HOME
+	sprintf(script, "%s/megapixels/%s", xdg_config_home, filename);
+	if (access(script, F_OK) != -1) {
+		printf("Found postprocessor script at %s\n", script);
+		return true;
+	}
+
+	// Check user overridden /etc/megapixels/postprocessor.sh
+	sprintf(script, "%s/megapixels/%s", SYSCONFDIR, filename);
+	if (access(script, F_OK) != -1) {
+		printf("Found postprocessor script at %s\n", script);
+		return true;
+	}
+
+	// Check packaged /usr/share/megapixels/postprocessor.sh
+	sprintf(script, "%s/megapixels/%s", DATADIR, filename);
+	if (access(script, F_OK) != -1) {
+		printf("Found postprocessor script at %s\n", script);
+		return true;
+	}
+
+	return false;
 }
 
-static void setup(MPPipeline *pipeline, const void *data)
+static void
+setup(MPPipeline *pipeline, const void *data)
 {
-    TIFFSetTagExtender(register_custom_tiff_tags);
+	TIFFSetTagExtender(register_custom_tiff_tags);
 
-    if (!find_processor(processing_script)) {
-        g_printerr("Could not find any post-process script\n");
-        exit(1);
-    }
+	if (!find_processor(processing_script)) {
+		g_printerr("Could not find any post-process script\n");
+		exit(1);
+	}
 }
 
-void mp_process_pipeline_start()
+void
+mp_process_pipeline_start()
 {
-    pipeline = mp_pipeline_new();
+	pipeline = mp_pipeline_new();
 
-    mp_pipeline_invoke(pipeline, setup, NULL, 0);
+	mp_pipeline_invoke(pipeline, setup, NULL, 0);
 }
 
-void mp_process_pipeline_stop()
+void
+mp_process_pipeline_stop()
 {
-    mp_pipeline_free(pipeline);
+	mp_pipeline_free(pipeline);
 }
 
 static void
 process_image_for_preview(const MPImage *image)
 {
-    uint32_t surface_width, surface_height, skip;
-    quick_preview_size(
-        &surface_width,
-        &surface_height,
-        &skip,
-        preview_width,
-        preview_height,
-        image->width,
-        image->height,
-        image->pixel_format,
-        camera->rotate);
-
-    cairo_surface_t *surface = cairo_image_surface_create(
-        CAIRO_FORMAT_RGB24,
-        surface_width,
-        surface_height);
-
-    uint8_t *pixels = cairo_image_surface_get_data(surface);
-
-    quick_preview(
-        (uint32_t *)pixels,
-        surface_width,
-        surface_height,
-        image->data,
-        image->width,
-        image->height,
-        image->pixel_format,
-        camera->rotate,
-        camera->mirrored,
-        camera->previewmatrix[0] == 0 ? NULL : camera->previewmatrix,
-        camera->blacklevel,
-        skip);
-
-    mp_main_set_preview(surface);
+	uint32_t surface_width, surface_height, skip;
+	quick_preview_size(&surface_width, &surface_height, &skip, preview_width,
+			   preview_height, image->width, image->height,
+			   image->pixel_format, camera->rotate);
+
+	cairo_surface_t *surface = cairo_image_surface_create(
+		CAIRO_FORMAT_RGB24, surface_width, surface_height);
+
+	uint8_t *pixels = cairo_image_surface_get_data(surface);
+
+	quick_preview((uint32_t *)pixels, surface_width, surface_height, image->data,
+		      image->width, image->height, image->pixel_format,
+		      camera->rotate, camera->mirrored,
+		      camera->previewmatrix[0] == 0 ? NULL : camera->previewmatrix,
+		      camera->blacklevel, skip);
+
+	mp_main_set_preview(surface);
 }
 
 static void
 process_image_for_capture(const MPImage *image, int count)
 {
-    time_t rawtime;
-    time(&rawtime);
-    struct tm tim = *(localtime(&rawtime));
-
-    char datetime[20] = {0};
-    strftime(datetime, 20, "%Y:%m:%d %H:%M:%S", &tim);
-
-    char fname[255];
-    sprintf(fname, "%s/%d.dng", burst_dir, count);
-
-    TIFF *tif = TIFFOpen(fname, "w");
-    if(!tif) {
-        printf("Could not open tiff\n");
-    }
-
-    // Define TIFF thumbnail
-    TIFFSetField(tif, TIFFTAG_SUBFILETYPE, 1);
-    TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, image->width >> 4);
-    TIFFSetField(tif, TIFFTAG_IMAGELENGTH, image->height >> 4);
-    TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 8);
-    TIFFSetField(tif, TIFFTAG_COMPRESSION, COMPRESSION_NONE);
-    TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB);
-    TIFFSetField(tif, TIFFTAG_MAKE, mp_get_device_make());
-    TIFFSetField(tif, TIFFTAG_MODEL, mp_get_device_model());
-    uint16_t orientation;
-    if (camera->rotate == 0) {
-        orientation = camera->mirrored ? ORIENTATION_TOPRIGHT : ORIENTATION_TOPLEFT;
-    } else if (camera->rotate == 90) {
-        orientation = camera->mirrored ? ORIENTATION_RIGHTBOT : ORIENTATION_LEFTBOT;
-    } else if (camera->rotate == 180) {
-        orientation = camera->mirrored ? ORIENTATION_BOTLEFT : ORIENTATION_BOTRIGHT;
-    } else {
-        orientation = camera->mirrored ? ORIENTATION_LEFTTOP : ORIENTATION_RIGHTTOP;
-    }
-    TIFFSetField(tif, TIFFTAG_ORIENTATION, orientation);
-    TIFFSetField(tif, TIFFTAG_DATETIME, datetime);
-    TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 3);
-    TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
-    TIFFSetField(tif, TIFFTAG_SOFTWARE, "Megapixels");
-    long sub_offset = 0;
-    TIFFSetField(tif, TIFFTAG_SUBIFD, 1, &sub_offset);
-    TIFFSetField(tif, TIFFTAG_DNGVERSION, "\001\001\0\0");
-    TIFFSetField(tif, TIFFTAG_DNGBACKWARDVERSION, "\001\0\0\0");
-    char uniquecameramodel[255];
-    sprintf(uniquecameramodel, "%s %s", mp_get_device_make(), mp_get_device_model());
-    TIFFSetField(tif, TIFFTAG_UNIQUECAMERAMODEL, uniquecameramodel);
-    if(camera->colormatrix[0]) {
-        TIFFSetField(tif, TIFFTAG_COLORMATRIX1, 9, camera->colormatrix);
-    } else {
-        TIFFSetField(tif, TIFFTAG_COLORMATRIX1, 9, colormatrix_srgb);
-    }
-    if(camera->forwardmatrix[0]) {
-        TIFFSetField(tif, TIFFTAG_FORWARDMATRIX1, 9, camera->forwardmatrix);
-    }
-    static const float neutral[] = {1.0, 1.0, 1.0};
-    TIFFSetField(tif, TIFFTAG_ASSHOTNEUTRAL, 3, neutral);
-    TIFFSetField(tif, TIFFTAG_CALIBRATIONILLUMINANT1, 21);
-    // Write black thumbnail, only windows uses this
-    {
-        unsigned char *buf = (unsigned char *)calloc(1, (int)image->width >> 4);
-        for (int row = 0; row < image->height>>4; row++) {
-            TIFFWriteScanline(tif, buf, row, 0);
-        }
-        free(buf);
-    }
-    TIFFWriteDirectory(tif);
-
-    // Define main photo
-    TIFFSetField(tif, TIFFTAG_SUBFILETYPE, 0);
-    TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, image->width);
-    TIFFSetField(tif, TIFFTAG_IMAGELENGTH, image->height);
-    TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 8);
-    TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_CFA);
-    TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 1);
-    TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
-    static const short cfapatterndim[] = {2, 2};
-    TIFFSetField(tif, TIFFTAG_CFAREPEATPATTERNDIM, cfapatterndim);
-    TIFFSetField(tif, TIFFTAG_CFAPATTERN, "\002\001\001\000"); // BGGR
-    if(camera->whitelevel) {
-        TIFFSetField(tif, TIFFTAG_WHITELEVEL, 1, &camera->whitelevel);
-    }
-    if(camera->blacklevel) {
-        TIFFSetField(tif, TIFFTAG_BLACKLEVEL, 1, &camera->blacklevel);
-    }
-    TIFFCheckpointDirectory(tif);
-    printf("Writing frame to %s\n", fname);
-
-    unsigned char *pLine = (unsigned char*)malloc(image->width);
-    for(int row = 0; row < image->height; row++){
-        TIFFWriteScanline(tif, image->data + (row * image->width), row, 0);
-    }
-    free(pLine);
-    TIFFWriteDirectory(tif);
-
-    // Add an EXIF block to the tiff
-    TIFFCreateEXIFDirectory(tif);
-    // 1 = manual, 2 = full auto, 3 = aperture priority, 4 = shutter priority
-    if (!exposure_is_manual) {
-        TIFFSetField(tif, EXIFTAG_EXPOSUREPROGRAM, 2);
-    } else {
-        TIFFSetField(tif, EXIFTAG_EXPOSUREPROGRAM, 1);
-    }
-
-    TIFFSetField(tif, EXIFTAG_EXPOSURETIME, (mode.frame_interval.numerator / (float)mode.frame_interval.denominator) / ((float)image->height / (float)exposure));
-    uint16_t isospeed[1];
-    isospeed[0] = (uint16_t)remap(gain - 1, 0, gain_max, camera->iso_min, camera->iso_max);
-    TIFFSetField(tif, EXIFTAG_ISOSPEEDRATINGS, 1, isospeed);
-    TIFFSetField(tif, EXIFTAG_FLASH, 0);
-
-    TIFFSetField(tif, EXIFTAG_DATETIMEORIGINAL, datetime);
-    TIFFSetField(tif, EXIFTAG_DATETIMEDIGITIZED, datetime);
-    if(camera->fnumber) {
-        TIFFSetField(tif, EXIFTAG_FNUMBER, camera->fnumber);
-    }
-    if(camera->focallength) {
-        TIFFSetField(tif, EXIFTAG_FOCALLENGTH, camera->focallength);
-    }
-    if(camera->focallength && camera->cropfactor) {
-        TIFFSetField(tif, EXIFTAG_FOCALLENGTHIN35MMFILM, (short)(camera->focallength * camera->cropfactor));
-    }
-    uint64_t exif_offset = 0;
-    TIFFWriteCustomDirectory(tif, &exif_offset);
-    TIFFFreeDirectory(tif);
-
-    // Update exif pointer
-    TIFFSetDirectory(tif, 0);
-    TIFFSetField(tif, TIFFTAG_EXIFIFD, exif_offset);
-    TIFFRewriteDirectory(tif);
-
-    TIFFClose(tif);
+	time_t rawtime;
+	time(&rawtime);
+	struct tm tim = *(localtime(&rawtime));
+
+	char datetime[20] = { 0 };
+	strftime(datetime, 20, "%Y:%m:%d %H:%M:%S", &tim);
+
+	char fname[255];
+	sprintf(fname, "%s/%d.dng", burst_dir, count);
+
+	TIFF *tif = TIFFOpen(fname, "w");
+	if (!tif) {
+		printf("Could not open tiff\n");
+	}
+
+	// Define TIFF thumbnail
+	TIFFSetField(tif, TIFFTAG_SUBFILETYPE, 1);
+	TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, image->width >> 4);
+	TIFFSetField(tif, TIFFTAG_IMAGELENGTH, image->height >> 4);
+	TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 8);
+	TIFFSetField(tif, TIFFTAG_COMPRESSION, COMPRESSION_NONE);
+	TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB);
+	TIFFSetField(tif, TIFFTAG_MAKE, mp_get_device_make());
+	TIFFSetField(tif, TIFFTAG_MODEL, mp_get_device_model());
+	uint16_t orientation;
+	if (camera->rotate == 0) {
+		orientation = camera->mirrored ? ORIENTATION_TOPRIGHT :
+						 ORIENTATION_TOPLEFT;
+	} else if (camera->rotate == 90) {
+		orientation = camera->mirrored ? ORIENTATION_RIGHTBOT :
+						 ORIENTATION_LEFTBOT;
+	} else if (camera->rotate == 180) {
+		orientation = camera->mirrored ? ORIENTATION_BOTLEFT :
+						 ORIENTATION_BOTRIGHT;
+	} else {
+		orientation = camera->mirrored ? ORIENTATION_LEFTTOP :
+						 ORIENTATION_RIGHTTOP;
+	}
+	TIFFSetField(tif, TIFFTAG_ORIENTATION, orientation);
+	TIFFSetField(tif, TIFFTAG_DATETIME, datetime);
+	TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 3);
+	TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
+	TIFFSetField(tif, TIFFTAG_SOFTWARE, "Megapixels");
+	long sub_offset = 0;
+	TIFFSetField(tif, TIFFTAG_SUBIFD, 1, &sub_offset);
+	TIFFSetField(tif, TIFFTAG_DNGVERSION, "\001\001\0\0");
+	TIFFSetField(tif, TIFFTAG_DNGBACKWARDVERSION, "\001\0\0\0");
+	char uniquecameramodel[255];
+	sprintf(uniquecameramodel, "%s %s", mp_get_device_make(),
+		mp_get_device_model());
+	TIFFSetField(tif, TIFFTAG_UNIQUECAMERAMODEL, uniquecameramodel);
+	if (camera->colormatrix[0]) {
+		TIFFSetField(tif, TIFFTAG_COLORMATRIX1, 9, camera->colormatrix);
+	} else {
+		TIFFSetField(tif, TIFFTAG_COLORMATRIX1, 9, colormatrix_srgb);
+	}
+	if (camera->forwardmatrix[0]) {
+		TIFFSetField(tif, TIFFTAG_FORWARDMATRIX1, 9, camera->forwardmatrix);
+	}
+	static const float neutral[] = { 1.0, 1.0, 1.0 };
+	TIFFSetField(tif, TIFFTAG_ASSHOTNEUTRAL, 3, neutral);
+	TIFFSetField(tif, TIFFTAG_CALIBRATIONILLUMINANT1, 21);
+	// Write black thumbnail, only windows uses this
+	{
+		unsigned char *buf =
+			(unsigned char *)calloc(1, (int)image->width >> 4);
+		for (int row = 0; row < (image->height >> 4); row++) {
+			TIFFWriteScanline(tif, buf, row, 0);
+		}
+		free(buf);
+	}
+	TIFFWriteDirectory(tif);
+
+	// Define main photo
+	TIFFSetField(tif, TIFFTAG_SUBFILETYPE, 0);
+	TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, image->width);
+	TIFFSetField(tif, TIFFTAG_IMAGELENGTH, image->height);
+	TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 8);
+	TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_CFA);
+	TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 1);
+	TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
+	static const short cfapatterndim[] = { 2, 2 };
+	TIFFSetField(tif, TIFFTAG_CFAREPEATPATTERNDIM, cfapatterndim);
+	TIFFSetField(tif, TIFFTAG_CFAPATTERN, "\002\001\001\000"); // BGGR
+	if (camera->whitelevel) {
+		TIFFSetField(tif, TIFFTAG_WHITELEVEL, 1, &camera->whitelevel);
+	}
+	if (camera->blacklevel) {
+		TIFFSetField(tif, TIFFTAG_BLACKLEVEL, 1, &camera->blacklevel);
+	}
+	TIFFCheckpointDirectory(tif);
+	printf("Writing frame to %s\n", fname);
+
+	unsigned char *pLine = (unsigned char *)malloc(image->width);
+	for (int row = 0; row < image->height; row++) {
+		TIFFWriteScanline(tif, image->data + (row * image->width), row, 0);
+	}
+	free(pLine);
+	TIFFWriteDirectory(tif);
+
+	// Add an EXIF block to the tiff
+	TIFFCreateEXIFDirectory(tif);
+	// 1 = manual, 2 = full auto, 3 = aperture priority, 4 = shutter priority
+	if (!exposure_is_manual) {
+		TIFFSetField(tif, EXIFTAG_EXPOSUREPROGRAM, 2);
+	} else {
+		TIFFSetField(tif, EXIFTAG_EXPOSUREPROGRAM, 1);
+	}
+
+	TIFFSetField(tif, EXIFTAG_EXPOSURETIME,
+		     (mode.frame_interval.numerator /
+		      (float)mode.frame_interval.denominator) /
+			     ((float)image->height / (float)exposure));
+	uint16_t isospeed[1];
+	isospeed[0] = (uint16_t)remap(gain - 1, 0, gain_max, camera->iso_min,
+				      camera->iso_max);
+	TIFFSetField(tif, EXIFTAG_ISOSPEEDRATINGS, 1, isospeed);
+	TIFFSetField(tif, EXIFTAG_FLASH, 0);
+
+	TIFFSetField(tif, EXIFTAG_DATETIMEORIGINAL, datetime);
+	TIFFSetField(tif, EXIFTAG_DATETIMEDIGITIZED, datetime);
+	if (camera->fnumber) {
+		TIFFSetField(tif, EXIFTAG_FNUMBER, camera->fnumber);
+	}
+	if (camera->focallength) {
+		TIFFSetField(tif, EXIFTAG_FOCALLENGTH, camera->focallength);
+	}
+	if (camera->focallength && camera->cropfactor) {
+		TIFFSetField(tif, EXIFTAG_FOCALLENGTHIN35MMFILM,
+			     (short)(camera->focallength * camera->cropfactor));
+	}
+	uint64_t exif_offset = 0;
+	TIFFWriteCustomDirectory(tif, &exif_offset);
+	TIFFFreeDirectory(tif);
+
+	// Update exif pointer
+	TIFFSetDirectory(tif, 0);
+	TIFFSetField(tif, TIFFTAG_EXIFIFD, exif_offset);
+	TIFFRewriteDirectory(tif);
+
+	TIFFClose(tif);
 }
 
 static void
 process_capture_burst()
 {
-    time_t rawtime;
-    time(&rawtime);
-    struct tm tim = *(localtime(&rawtime));
+	time_t rawtime;
+	time(&rawtime);
+	struct tm tim = *(localtime(&rawtime));
 
-    char timestamp[30];
-    strftime(timestamp, 30, "%Y%m%d%H%M%S", &tim);
+	char timestamp[30];
+	strftime(timestamp, 30, "%Y%m%d%H%M%S", &tim);
 
-    sprintf(capture_fname, "%s/Pictures/IMG%s", getenv("HOME"), timestamp);
+	sprintf(capture_fname, "%s/Pictures/IMG%s", getenv("HOME"), timestamp);
 
-    // Start post-processing the captured burst
-    g_print("Post process %s to %s.ext\n", burst_dir, capture_fname);
-    char command[1024];
-    sprintf(command, "%s %s %s &", processing_script, burst_dir, capture_fname);
-    system(command);
+	// Start post-processing the captured burst
+	g_print("Post process %s to %s.ext\n", burst_dir, capture_fname);
+	char command[1024];
+	sprintf(command, "%s %s %s &", processing_script, burst_dir, capture_fname);
+	system(command);
 }
 
 static void
 process_image(MPPipeline *pipeline, const MPImage *image)
 {
-    assert(image->width == mode.width && image->height == mode.height);
+	assert(image->width == mode.width && image->height == mode.height);
 
-    process_image_for_preview(image);
+	process_image_for_preview(image);
 
-    if (captures_remaining > 0) {
-        int count = burst_length - captures_remaining;
-        --captures_remaining;
+	if (captures_remaining > 0) {
+		int count = burst_length - captures_remaining;
+		--captures_remaining;
 
-        process_image_for_capture(image, count);
+		process_image_for_capture(image, count);
 
-        if (captures_remaining == 0) {
-            process_capture_burst();
+		if (captures_remaining == 0) {
+			process_capture_burst();
 
-            mp_main_capture_completed(capture_fname);
-        }
-    }
+			mp_main_capture_completed(capture_fname);
+		}
+	}
 
-    free(image->data);
+	free(image->data);
 
-    ++frames_processed;
-    if (captures_remaining == 0) {
-        is_capturing = false;
-    }
+	++frames_processed;
+	if (captures_remaining == 0) {
+		is_capturing = false;
+	}
 }
 
-void mp_process_pipeline_process_image(MPImage image)
+void
+mp_process_pipeline_process_image(MPImage image)
 {
-    // If we haven't processed the previous frame yet, drop this one
-    if (frames_received != frames_processed && !is_capturing) {
-        printf("Dropped frame at capture\n");
-        return;
-    }
+	// If we haven't processed the previous frame yet, drop this one
+	if (frames_received != frames_processed && !is_capturing) {
+		printf("Dropped frame at capture\n");
+		return;
+	}
 
-    ++frames_received;
+	++frames_received;
 
-    mp_pipeline_invoke(pipeline, (MPPipelineCallback)process_image, &image, sizeof(MPImage));
+	mp_pipeline_invoke(pipeline, (MPPipelineCallback)process_image, &image,
+			   sizeof(MPImage));
 }
 
-static void capture()
+static void
+capture()
 {
-    char template[] = "/tmp/megapixels.XXXXXX";
-    char *tempdir;
-    tempdir = mkdtemp(template);
+	char template[] = "/tmp/megapixels.XXXXXX";
+	char *tempdir;
+	tempdir = mkdtemp(template);
 
-    if (tempdir == NULL) {
-        g_printerr("Could not make capture directory %s\n", template);
-        exit(EXIT_FAILURE);
-    }
+	if (tempdir == NULL) {
+		g_printerr("Could not make capture directory %s\n", template);
+		exit(EXIT_FAILURE);
+	}
 
-    strcpy(burst_dir, tempdir);
+	strcpy(burst_dir, tempdir);
 
-    captures_remaining = burst_length;
+	captures_remaining = burst_length;
 }
 
-void mp_process_pipeline_capture()
+void
+mp_process_pipeline_capture()
 {
-    is_capturing = true;
+	is_capturing = true;
 
-    mp_pipeline_invoke(pipeline, capture, NULL, 0);
+	mp_pipeline_invoke(pipeline, capture, NULL, 0);
 }
 
 static void
 update_state(MPPipeline *pipeline, const struct mp_process_pipeline_state *state)
 {
-    camera = state->camera;
-    mode = state->mode;
-
-    burst_length = state->burst_length;
-
-    preview_width = state->preview_width;
-    preview_height = state->preview_height;
-
-    // gain_is_manual = state->gain_is_manual;
-    gain = state->gain;
-    gain_max = state->gain_max;
-
-    exposure_is_manual = state->exposure_is_manual;
-    exposure = state->exposure;
-
-    struct mp_main_state main_state = {
-        .camera = camera,
-        .mode = mode,
-        .gain_is_manual = state->gain_is_manual,
-        .gain = gain,
-        .gain_max = gain_max,
-        .exposure_is_manual = exposure_is_manual,
-        .exposure = exposure,
-        .has_auto_focus_continuous = state->has_auto_focus_continuous,
-        .has_auto_focus_start = state->has_auto_focus_start,
-    };
-    mp_main_update_state(&main_state);
+	camera = state->camera;
+	mode = state->mode;
+
+	burst_length = state->burst_length;
+
+	preview_width = state->preview_width;
+	preview_height = state->preview_height;
+
+	// gain_is_manual = state->gain_is_manual;
+	gain = state->gain;
+	gain_max = state->gain_max;
+
+	exposure_is_manual = state->exposure_is_manual;
+	exposure = state->exposure;
+
+	struct mp_main_state main_state = {
+		.camera = camera,
+		.mode = mode,
+		.gain_is_manual = state->gain_is_manual,
+		.gain = gain,
+		.gain_max = gain_max,
+		.exposure_is_manual = exposure_is_manual,
+		.exposure = exposure,
+		.has_auto_focus_continuous = state->has_auto_focus_continuous,
+		.has_auto_focus_start = state->has_auto_focus_start,
+	};
+	mp_main_update_state(&main_state);
 }
 
-void mp_process_pipeline_update_state(const struct mp_process_pipeline_state *new_state)
+void
+mp_process_pipeline_update_state(const struct mp_process_pipeline_state *new_state)
 {
-    mp_pipeline_invoke(pipeline, (MPPipelineCallback)update_state, new_state, sizeof(struct mp_process_pipeline_state));
+	mp_pipeline_invoke(pipeline, (MPPipelineCallback)update_state, new_state,
+			   sizeof(struct mp_process_pipeline_state));
 }

+ 12 - 12
process_pipeline.h

@@ -3,23 +3,23 @@
 #include "camera_config.h"
 
 struct mp_process_pipeline_state {
-    const struct mp_camera_config *camera;
-    MPCameraMode mode;
+	const struct mp_camera_config *camera;
+	MPCameraMode mode;
 
-    int burst_length;
+	int burst_length;
 
-    int preview_width;
-    int preview_height;
+	int preview_width;
+	int preview_height;
 
-    bool gain_is_manual;
-    int gain;
-    int gain_max;
+	bool gain_is_manual;
+	int gain;
+	int gain_max;
 
-    bool exposure_is_manual;
-    int exposure;
+	bool exposure_is_manual;
+	int exposure;
 
-    bool has_auto_focus_continuous;
-    bool has_auto_focus_start;
+	bool has_auto_focus_continuous;
+	bool has_auto_focus_start;
 };
 
 void mp_process_pipeline_start();

+ 123 - 165
quickpreview.c

@@ -7,12 +7,14 @@
 #include <assert.h>
 #include <stdio.h>
 
-static inline uint32_t pack_rgb(uint8_t r, uint8_t g, uint8_t b)
+static inline uint32_t
+pack_rgb(uint8_t r, uint8_t g, uint8_t b)
 {
 	return (r << 16) | (g << 8) | b;
 }
 
-static inline uint32_t convert_yuv_to_srgb(uint8_t y, uint8_t u, uint8_t v)
+static inline uint32_t
+convert_yuv_to_srgb(uint8_t y, uint8_t u, uint8_t v)
 {
 	uint32_t r = 1.164f * y + 1.596f * (v - 128);
 	uint32_t g = 1.164f * y - 0.813f * (v - 128) - 0.391f * (u - 128);
@@ -20,15 +22,22 @@ static inline uint32_t convert_yuv_to_srgb(uint8_t y, uint8_t u, uint8_t v)
 	return pack_rgb(r, g, b);
 }
 
-static inline uint32_t apply_colormatrix(uint32_t color, const float *colormatrix)
+static inline uint32_t
+apply_colormatrix(uint32_t color, const float *colormatrix)
 {
 	if (!colormatrix) {
 		return color;
 	}
 
-	uint32_t r = (color >> 16) * colormatrix[0] + ((color >> 8) & 0xFF) * colormatrix[1] + (color & 0xFF) * colormatrix[2];
-	uint32_t g = (color >> 16) * colormatrix[3] + ((color >> 8) & 0xFF) * colormatrix[4] + (color & 0xFF) * colormatrix[5];
-	uint32_t b = (color >> 16) * colormatrix[6] + ((color >> 8) & 0xFF) * colormatrix[7] + (color & 0xFF) * colormatrix[8];
+	uint32_t r = (color >> 16) * colormatrix[0] +
+		     ((color >> 8) & 0xFF) * colormatrix[1] +
+		     (color & 0xFF) * colormatrix[2];
+	uint32_t g = (color >> 16) * colormatrix[3] +
+		     ((color >> 8) & 0xFF) * colormatrix[4] +
+		     (color & 0xFF) * colormatrix[5];
+	uint32_t b = (color >> 16) * colormatrix[6] +
+		     ((color >> 8) & 0xFF) * colormatrix[7] +
+		     (color & 0xFF) * colormatrix[8];
 
 	// Clip colors
 	if (r > 0xFF)
@@ -40,7 +49,9 @@ static inline uint32_t apply_colormatrix(uint32_t color, const float *colormatri
 	return pack_rgb(r, g, b);
 }
 
-static inline uint32_t coord_map(uint32_t x, uint32_t y, uint32_t width, uint32_t height, int rotation, bool mirrored)
+static inline uint32_t
+coord_map(uint32_t x, uint32_t y, uint32_t width, uint32_t height, int rotation,
+	  bool mirrored)
 {
 	uint32_t x_r, y_r;
 	if (rotation == 0) {
@@ -68,19 +79,13 @@ static inline uint32_t coord_map(uint32_t x, uint32_t y, uint32_t width, uint32_
 	return index;
 }
 
-static void quick_preview_rggb8(
-	uint32_t *dst,
-	const uint32_t dst_width,
-	const uint32_t dst_height,
-	const uint8_t *src,
-	const uint32_t src_width,
-	const uint32_t src_height,
-	const MPPixelFormat format,
-	const uint32_t rotation,
-	const bool mirrored,
-	const float *colormatrix,
-	const uint8_t blacklevel,
-	const uint32_t skip)
+static void
+quick_preview_rggb8(uint32_t *dst, const uint32_t dst_width,
+		    const uint32_t dst_height, const uint8_t *src,
+		    const uint32_t src_width, const uint32_t src_height,
+		    const MPPixelFormat format, const uint32_t rotation,
+		    const bool mirrored, const float *colormatrix,
+		    const uint8_t blacklevel, const uint32_t skip)
 {
 	uint32_t src_y = 0, dst_y = 0;
 	while (src_y < src_height) {
@@ -94,25 +99,26 @@ static void quick_preview_rggb8(
 
 			uint32_t color;
 			switch (format) {
-				case MP_PIXEL_FMT_BGGR8:
-					color = pack_rgb(b2, b1, b0);
-					break;
-				case MP_PIXEL_FMT_GBRG8:
-					color = pack_rgb(b2, b0, b1);
-					break;
-				case MP_PIXEL_FMT_GRBG8:
-					color = pack_rgb(b1, b0, b2);
-					break;
-				case MP_PIXEL_FMT_RGGB8:
-					color = pack_rgb(b0, b1, b2);
-					break;
-				default:
-					assert(false);
+			case MP_PIXEL_FMT_BGGR8:
+				color = pack_rgb(b2, b1, b0);
+				break;
+			case MP_PIXEL_FMT_GBRG8:
+				color = pack_rgb(b2, b0, b1);
+				break;
+			case MP_PIXEL_FMT_GRBG8:
+				color = pack_rgb(b1, b0, b2);
+				break;
+			case MP_PIXEL_FMT_RGGB8:
+				color = pack_rgb(b0, b1, b2);
+				break;
+			default:
+				assert(false);
 			}
 
 			color = apply_colormatrix(color, colormatrix);
 
-			dst[coord_map(dst_x, dst_y, dst_width, dst_height, rotation, mirrored)] = color;
+			dst[coord_map(dst_x, dst_y, dst_width, dst_height, rotation,
+				      mirrored)] = color;
 
 			src_x += 2 + 2 * skip;
 			++dst_x;
@@ -123,19 +129,13 @@ static void quick_preview_rggb8(
 	}
 }
 
-static void quick_preview_rggb10(
-	uint32_t *dst,
-	const uint32_t dst_width,
-	const uint32_t dst_height,
-	const uint8_t *src,
-	const uint32_t src_width,
-	const uint32_t src_height,
-	const MPPixelFormat format,
-	const uint32_t rotation,
-	const bool mirrored,
-	const float *colormatrix,
-	const uint8_t blacklevel,
-	const uint32_t skip)
+static void
+quick_preview_rggb10(uint32_t *dst, const uint32_t dst_width,
+		     const uint32_t dst_height, const uint8_t *src,
+		     const uint32_t src_width, const uint32_t src_height,
+		     const MPPixelFormat format, const uint32_t rotation,
+		     const bool mirrored, const float *colormatrix,
+		     const uint8_t blacklevel, const uint32_t skip)
 {
 	assert(src_width % 2 == 0);
 
@@ -153,25 +153,26 @@ static void quick_preview_rggb10(
 
 			uint32_t color;
 			switch (format) {
-				case MP_PIXEL_FMT_BGGR10P:
-					color = pack_rgb(b2, b1, b0);
-					break;
-				case MP_PIXEL_FMT_GBRG10P:
-					color = pack_rgb(b2, b0, b1);
-					break;
-				case MP_PIXEL_FMT_GRBG10P:
-					color = pack_rgb(b1, b0, b2);
-					break;
-				case MP_PIXEL_FMT_RGGB10P:
-					color = pack_rgb(b0, b1, b2);
-					break;
-				default:
-					assert(false);
+			case MP_PIXEL_FMT_BGGR10P:
+				color = pack_rgb(b2, b1, b0);
+				break;
+			case MP_PIXEL_FMT_GBRG10P:
+				color = pack_rgb(b2, b0, b1);
+				break;
+			case MP_PIXEL_FMT_GRBG10P:
+				color = pack_rgb(b1, b0, b2);
+				break;
+			case MP_PIXEL_FMT_RGGB10P:
+				color = pack_rgb(b0, b1, b2);
+				break;
+			default:
+				assert(false);
 			}
 
 			color = apply_colormatrix(color, colormatrix);
 
-			dst[coord_map(dst_x, dst_y, dst_width, dst_height, rotation, mirrored)] = color;
+			dst[coord_map(dst_x, dst_y, dst_width, dst_height, rotation,
+				      mirrored)] = color;
 
 			uint32_t advance = 1 + skip;
 			if (src_x % 5 == 0) {
@@ -187,18 +188,12 @@ static void quick_preview_rggb10(
 	}
 }
 
-static void quick_preview_yuv(
-	uint32_t *dst,
-	const uint32_t dst_width,
-	const uint32_t dst_height,
-	const uint8_t *src,
-	const uint32_t src_width,
-	const uint32_t src_height,
-	const MPPixelFormat format,
-	const uint32_t rotation,
-	const bool mirrored,
-	const float *colormatrix,
-	const uint32_t skip)
+static void
+quick_preview_yuv(uint32_t *dst, const uint32_t dst_width, const uint32_t dst_height,
+		  const uint8_t *src, const uint32_t src_width,
+		  const uint32_t src_height, const MPPixelFormat format,
+		  const uint32_t rotation, const bool mirrored,
+		  const float *colormatrix, const uint32_t skip)
 {
 	assert(src_width % 2 == 0);
 
@@ -222,28 +217,31 @@ static void quick_preview_yuv(
 
 			uint32_t color1, color2;
 			switch (format) {
-				case MP_PIXEL_FMT_UYVY:
-					color1 = convert_yuv_to_srgb(b1, b0, b2);
-					color2 = convert_yuv_to_srgb(b3, b0, b2);
-					break;
-				case MP_PIXEL_FMT_YUYV:
-					color1 = convert_yuv_to_srgb(b0, b1, b3);
-					color2 = convert_yuv_to_srgb(b2, b1, b3);
-					break;
-				default:
-					assert(false);
+			case MP_PIXEL_FMT_UYVY:
+				color1 = convert_yuv_to_srgb(b1, b0, b2);
+				color2 = convert_yuv_to_srgb(b3, b0, b2);
+				break;
+			case MP_PIXEL_FMT_YUYV:
+				color1 = convert_yuv_to_srgb(b0, b1, b3);
+				color2 = convert_yuv_to_srgb(b2, b1, b3);
+				break;
+			default:
+				assert(false);
 			}
 
 			color1 = apply_colormatrix(color1, colormatrix);
 			color2 = apply_colormatrix(color2, colormatrix);
 
-			uint32_t dst_i1 = coord_map(dst_x, dst_y, dst_width, dst_height, rotation, mirrored);
+			uint32_t dst_i1 = coord_map(dst_x, dst_y, dst_width,
+						    dst_height, rotation, mirrored);
 			dst[dst_i1] = color1;
 			++dst_x;
 
 			// The last pixel needs to be skipped if we have an odd un-rotated width
 			if (dst_x < unrot_dst_width) {
-				uint32_t dst_i2 = coord_map(dst_x, dst_y, dst_width, dst_height, rotation, mirrored);
+				uint32_t dst_i2 =
+					coord_map(dst_x, dst_y, dst_width,
+						  dst_height, rotation, mirrored);
 				dst[dst_i2] = color2;
 				++dst_x;
 			}
@@ -256,92 +254,52 @@ static void quick_preview_yuv(
 	}
 }
 
-void quick_preview(
-	uint32_t *dst,
-	const uint32_t dst_width,
-	const uint32_t dst_height,
-	const uint8_t *src,
-	const uint32_t src_width,
-	const uint32_t src_height,
-	const MPPixelFormat format,
-	const uint32_t rotation,
-	const bool mirrored,
-	const float *colormatrix,
-	const uint8_t blacklevel,
-	const uint32_t skip)
+void
+quick_preview(uint32_t *dst, const uint32_t dst_width, const uint32_t dst_height,
+	      const uint8_t *src, const uint32_t src_width,
+	      const uint32_t src_height, const MPPixelFormat format,
+	      const uint32_t rotation, const bool mirrored, const float *colormatrix,
+	      const uint8_t blacklevel, const uint32_t skip)
 {
 	switch (format) {
-		case MP_PIXEL_FMT_BGGR8:
-		case MP_PIXEL_FMT_GBRG8:
-		case MP_PIXEL_FMT_GRBG8:
-		case MP_PIXEL_FMT_RGGB8:
-			quick_preview_rggb8(
-				dst,
-				dst_width,
-				dst_height,
-				src,
-				src_width,
-				src_height,
-				format,
-				rotation,
-				mirrored,
-				colormatrix,
-				blacklevel,
-				skip);
-			break;
-		case MP_PIXEL_FMT_BGGR10P:
-		case MP_PIXEL_FMT_GBRG10P:
-		case MP_PIXEL_FMT_GRBG10P:
-		case MP_PIXEL_FMT_RGGB10P:
-			quick_preview_rggb10(
-				dst,
-				dst_width,
-				dst_height,
-				src,
-				src_width,
-				src_height,
-				format,
-				rotation,
-				mirrored,
-				colormatrix,
-				blacklevel,
-				skip);
-			break;
-		case MP_PIXEL_FMT_UYVY:
-		case MP_PIXEL_FMT_YUYV:
-			quick_preview_yuv(
-				dst,
-				dst_width,
-				dst_height,
-				src,
-				src_width,
-				src_height,
-				format,
-				rotation,
-				mirrored,
-				colormatrix,
-				skip);
-			break;
-		default:
-			assert(false);
+	case MP_PIXEL_FMT_BGGR8:
+	case MP_PIXEL_FMT_GBRG8:
+	case MP_PIXEL_FMT_GRBG8:
+	case MP_PIXEL_FMT_RGGB8:
+		quick_preview_rggb8(dst, dst_width, dst_height, src, src_width,
+				    src_height, format, rotation, mirrored,
+				    colormatrix, blacklevel, skip);
+		break;
+	case MP_PIXEL_FMT_BGGR10P:
+	case MP_PIXEL_FMT_GBRG10P:
+	case MP_PIXEL_FMT_GRBG10P:
+	case MP_PIXEL_FMT_RGGB10P:
+		quick_preview_rggb10(dst, dst_width, dst_height, src, src_width,
+				     src_height, format, rotation, mirrored,
+				     colormatrix, blacklevel, skip);
+		break;
+	case MP_PIXEL_FMT_UYVY:
+	case MP_PIXEL_FMT_YUYV:
+		quick_preview_yuv(dst, dst_width, dst_height, src, src_width,
+				  src_height, format, rotation, mirrored,
+				  colormatrix, skip);
+		break;
+	default:
+		assert(false);
 	}
 }
 
-static uint32_t div_ceil(uint32_t x, uint32_t y)
+static uint32_t
+div_ceil(uint32_t x, uint32_t y)
 {
-	return x/y + !!(x % y);
+	return x / y + !!(x % y);
 }
 
-void quick_preview_size(
-	uint32_t *dst_width,
-	uint32_t *dst_height,
-	uint32_t *skip,
-	const uint32_t preview_width,
-	const uint32_t preview_height,
-	const uint32_t src_width,
-	const uint32_t src_height,
-	const MPPixelFormat format,
-	const int rotation)
+void
+quick_preview_size(uint32_t *dst_width, uint32_t *dst_height, uint32_t *skip,
+		   const uint32_t preview_width, const uint32_t preview_height,
+		   const uint32_t src_width, const uint32_t src_height,
+		   const MPPixelFormat format, const int rotation)
 {
 	uint32_t colors_x = mp_pixel_format_width_to_colors(format, src_width);
 	uint32_t colors_y = mp_pixel_format_height_to_colors(format, src_height);

+ 10 - 23
quickpreview.h

@@ -1,27 +1,14 @@
 #include "camera.h"
 #include <stdint.h>
 
-void quick_preview(
-	uint32_t *dst,
-	const uint32_t dst_width,
-	const uint32_t dst_height,
-	const uint8_t *src,
-	const uint32_t src_width,
-	const uint32_t src_height,
-	const MPPixelFormat format,
-	const uint32_t rotation,
-	const bool mirrored,
-	const float *colormatrix,
-	const uint8_t blacklevel,
-	const uint32_t skip);
+void quick_preview(uint32_t *dst, const uint32_t dst_width,
+		   const uint32_t dst_height, const uint8_t *src,
+		   const uint32_t src_width, const uint32_t src_height,
+		   const MPPixelFormat format, const uint32_t rotation,
+		   const bool mirrored, const float *colormatrix,
+		   const uint8_t blacklevel, const uint32_t skip);
 
-void quick_preview_size(
-	uint32_t *dst_width,
-	uint32_t *dst_height,
-	uint32_t *skip,
-	const uint32_t preview_width,
-	const uint32_t preview_height,
-	const uint32_t src_width,
-	const uint32_t src_height,
-	const MPPixelFormat format,
-	const int rotation);
+void quick_preview_size(uint32_t *dst_width, uint32_t *dst_height, uint32_t *skip,
+			const uint32_t preview_width, const uint32_t preview_height,
+			const uint32_t src_width, const uint32_t src_height,
+			const MPPixelFormat format, const int rotation);