Martijn Braam 4 år sedan
förälder
incheckning
72105c9491
20 ändrade filer med 3388 tillägg och 2713 borttagningar
  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
 #define MAX_VIDEO_BUFFERS 20
 
 
 static const char *pixel_format_names[MP_PIXEL_FMT_MAX] = {
 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] = {
 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] = {
 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 {
 struct video_buffer {
-    uint32_t length;
-    uint8_t *data;
+	uint32_t length;
+	uint8_t *data;
 };
 };
 
 
 struct _MPCamera {
 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:
 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 {
 struct _MPCameraModeList {
-    MPCameraMode mode;
-    MPCameraModeList *next;
+	MPCameraMode mode;
+	MPCameraModeList *next;
 };
 };
 
 
 static MPCameraModeList *
 static MPCameraModeList *
 get_subdev_modes(MPCamera *camera, bool (*check)(MPCamera *, MPCameraMode *))
 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 *
 static MPCameraModeList *
 get_video_modes(MPCamera *camera, bool (*check)(MPCamera *, MPCameraMode *))
 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 {
 struct int_str_pair {
-    uint32_t value;
-    const char *str;
+	uint32_t value;
+	const char *str;
 };
 };
 
 
 struct int_str_pair control_id_names[] = {
 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[] = {
 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 {
 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>
 #include <stdint.h>
 
 
 typedef enum {
 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;
 } MPPixelFormat;
 
 
 const char *mp_pixel_format_to_str(MPPixelFormat pixel_format);
 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_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_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_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 {
 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;
 } MPCameraMode;
 
 
 bool mp_camera_mode_is_equivalent(const MPCameraMode *m1, const MPCameraMode *m2);
 bool mp_camera_mode_is_equivalent(const MPCameraMode *m1, const MPCameraMode *m2);
 
 
 typedef struct {
 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;
 } MPImage;
 
 
 typedef struct _MPCamera MPCamera;
 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_start_capture(MPCamera *camera);
 bool mp_camera_stop_capture(MPCamera *camera);
 bool mp_camera_stop_capture(MPCamera *camera);
 bool mp_camera_is_capturing(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;
 typedef struct _MPCameraModeList MPCameraModeList;
 
 
@@ -77,21 +79,21 @@ MPCameraModeList *mp_camera_mode_list_next(MPCameraModeList *list);
 void mp_camera_mode_list_free(MPCameraModeList *list);
 void mp_camera_mode_list_free(MPCameraModeList *list);
 
 
 typedef struct {
 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;
 } MPControl;
 
 
 const char *mp_control_id_to_str(uint32_t id);
 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
 static bool
 find_config(char *conffile)
 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
 static int
 strtoint(const char *nptr, char **endptr, int base)
 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
 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
 static int
 config_ini_handler(void *user, const char *section, const char *name,
 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
 void
-calculate_matrices() {
+calculate_matrices()
+{
 	for (size_t i = 0; i < MP_MAX_CAMERAS; ++i) {
 	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
 #define MP_MAX_LINKS 10
 
 
 struct mp_media_link_config {
 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 {
 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();
 bool mp_load_config();
 
 
 const char *mp_get_device_make();
 const char *mp_get_device_make();
 const char *mp_get_device_model();
 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 <sys/ioctl.h>
 #include <unistd.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 {
 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 {
 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 <stddef.h>
 #include <stdint.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;
 typedef struct _MPDevice MPDevice;
 
 
@@ -14,26 +15,37 @@ MPDevice *mp_device_open(const char *path);
 MPDevice *mp_device_new(int fd);
 MPDevice *mp_device_new(int fd);
 void mp_device_close(MPDevice *device);
 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_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);
 const struct media_v2_entity *mp_device_get_entities(const MPDevice *device);
 size_t mp_device_get_num_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);
 const struct media_v2_interface *mp_device_get_interfaces(const MPDevice *device);
 size_t mp_device_get_num_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_pad(const MPDevice *device, uint32_t id);
 const struct media_v2_pad *mp_device_get_pads(const MPDevice *device);
 const struct media_v2_pad *mp_device_get_pads(const MPDevice *device);
 size_t mp_device_get_num_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_link(const MPDevice *device, uint32_t id);
 const struct media_v2_link *mp_device_get_links(const MPDevice *device);
 const struct media_v2_link *mp_device_get_links(const MPDevice *device);
 size_t mp_device_get_num_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();
 MPDeviceList *mp_device_list_new();
 void mp_device_list_free(MPDeviceList *device_list);
 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_remove(MPDeviceList **device_list);
 
 
 MPDevice *mp_device_list_get(const 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
 #define MAX_NAME 50
 
 
 /* Strip whitespace chars off end of given string, in place. Return s. */
 /* 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. */
 /* 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,
 /* 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
    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. */
    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
 #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
 #else
-    while (*s && (!chars || !strchr(chars, *s))) {
-        s++;
-    }
+	while (*s && (!chars || !strchr(chars, *s))) {
+		s++;
+	}
 #endif
 #endif
-    return (char*)s;
+	return (char *)s;
 }
 }
 
 
 /* Version of strncpy that ensures dest (size bytes) is null-terminated. */
 /* 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. */
 /* 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
 #if INI_USE_STACK
-    char line[INI_MAX_LINE];
+	char line[INI_MAX_LINE];
 #else
 #else
-    char* line;
+	char *line;
 #endif
 #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
 #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
 #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 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
 #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 */
                start of a line */
-        }
+		}
 #if INI_ALLOW_MULTILINE
 #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). */
                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
 #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
 #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
 #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));
 				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 INI_STOP_ON_FIRST_ERROR
-        if (error)
-            break;
+		if (error)
+			break;
 #endif
 #endif
-    }
+	}
 
 
 #if !INI_USE_STACK
 #if !INI_USE_STACK
-    free(line);
+	free(line);
 #endif
 #endif
 
 
-    return error;
+	return error;
 }
 }
 
 
 /* See documentation in header file. */
 /* 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. */
 /* 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>
 #include <stdio.h>
 
 
 /* Typedef for prototype of handler function. */
 /* 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 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
 /* Parse given INI-style file. May have [section]s, name=value pairs
    (whitespace stripped), and comments starting with ';' (semicolon). Section
    (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
    stop on first error), -1 on file open error, or -2 on memory allocation
    error (only when INI_USE_STACK is zero).
    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
 /* 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. */
    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
 /* Same as ini_parse(), but takes an ini_reader function pointer instead of
    filename. Used for implementing custom or string-based I/O. */
    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
 /* 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
    configparser. If allowed, ini_parse() will call the handler with the same

+ 412 - 377
io_pipeline.c

@@ -13,51 +13,49 @@
 #include <stdio.h>
 #include <stdio.h>
 
 
 struct media_link_info {
 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 {
 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 {
 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];
 static struct camera_info cameras[MP_MAX_CAMERAS];
@@ -78,11 +76,11 @@ static int preview_width;
 static int preview_height;
 static int preview_height;
 
 
 struct control_state {
 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 = {};
 static struct control_state desired_controls = {};
@@ -93,413 +91,450 @@ static bool want_focus = false;
 static MPPipeline *pipeline;
 static MPPipeline *pipeline;
 static GSource *capture_source;
 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
 static void
 update_process_pipeline()
 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
 static void
 focus(MPPipeline *pipeline, const void *data)
 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
 static void
 capture(MPPipeline *pipeline, const void *data)
 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
 static void
 update_controls()
 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
 static void
 on_frame(MPImage image, void *data)
 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
 static void
 update_state(MPPipeline *pipeline, const struct mp_io_pipeline_state *state)
 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"
 #include "camera_config.h"
 
 
 struct mp_io_pipeline_state {
 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();
 void mp_io_pipeline_start();

+ 118 - 106
main.c

@@ -21,10 +21,7 @@
 #include "quickpreview.h"
 #include "quickpreview.h"
 #include "io_pipeline.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 bool camera_is_initialized = false;
 static const struct mp_camera_config *camera = NULL;
 static const struct mp_camera_config *camera = NULL;
@@ -121,17 +118,14 @@ update_state(const struct mp_main_state *state)
 	return false;
 	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));
 	struct mp_main_state *state_copy = malloc(sizeof(struct mp_main_state));
 	*state_copy = *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
 static bool
@@ -145,19 +139,16 @@ set_preview(cairo_surface_t *image)
 	return false;
 	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
 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);
 	cairo_save(cr);
 
 
@@ -165,7 +156,7 @@ draw_surface_scaled_centered(
 
 
 	int width = cairo_image_surface_get_width(surface);
 	int width = cairo_image_surface_get_width(surface);
 	int height = cairo_image_surface_get_height(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_scale(cr, scale, scale);
 
 
 	cairo_translate(cr, -width / 2, -height / 2);
 	cairo_translate(cr, -width / 2, -height / 2);
@@ -181,10 +172,8 @@ capture_completed(const char *fname)
 	strncpy(last_path, fname, 260);
 	strncpy(last_path, fname, 260);
 
 
 	// Create a thumbnail from the current surface
 	// 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);
 	cairo_t *cr = cairo_create(thumb);
 	draw_surface_scaled_centered(cr, 24, 24, surface);
 	draw_surface_scaled_centered(cr, 24, 24, surface);
@@ -196,16 +185,13 @@ capture_completed(const char *fname)
 	return false;
 	return false;
 }
 }
 
 
-void mp_main_capture_completed(const char *fname)
+void
+mp_main_capture_completed(const char *fname)
 {
 {
 	gchar *name = g_strdup(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
 static void
@@ -217,14 +203,16 @@ draw_controls()
 	char shutterangle[6];
 	char shutterangle[6];
 
 
 	if (exposure_is_manual) {
 	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);
 		sprintf(shutterangle, "%d\u00b0", temp);
 	} else {
 	} else {
 		sprintf(shutterangle, "auto");
 		sprintf(shutterangle, "auto");
 	}
 	}
 
 
 	if (gain_is_manual) {
 	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);
 		sprintf(iso, "%d", temp);
 	} else {
 	} else {
 		sprintf(iso, "auto");
 		sprintf(iso, "auto");
@@ -237,16 +225,18 @@ draw_controls()
 	if (gtk_widget_get_window(preview) == NULL) {
 	if (gtk_widget_get_window(preview) == NULL) {
 		return;
 		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);
 	cr = cairo_create(status_surface);
 	cairo_set_source_rgba(cr, 0, 0, 0, 0.0);
 	cairo_set_source_rgba(cr, 0, 0, 0, 0.0);
 	cairo_paint(cr);
 	cairo_paint(cr);
 
 
 	// Draw the outlines for the headings
 	// 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_font_size(cr, 9);
 	cairo_set_source_rgba(cr, 0, 0, 0, 1);
 	cairo_set_source_rgba(cr, 0, 0, 0, 1);
 
 
@@ -266,7 +256,8 @@ draw_controls()
 	cairo_show_text(cr, "Shutter");
 	cairo_show_text(cr, "Shutter");
 
 
 	// Draw the outlines for the values
 	// 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_font_size(cr, 11);
 	cairo_set_source_rgba(cr, 0, 0, 0, 1);
 	cairo_set_source_rgba(cr, 0, 0, 0, 1);
 
 
@@ -286,7 +277,7 @@ draw_controls()
 	cairo_show_text(cr, shutterangle);
 	cairo_show_text(cr, shutterangle);
 
 
 	cairo_destroy(cr);
 	cairo_destroy(cr);
-	
+
 	gtk_widget_queue_draw_area(preview, 0, 0, preview_width, 32);
 	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
 	// Draw camera preview
 	if (surface) {
 	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
 	// Draw control overlay
@@ -311,15 +303,14 @@ preview_draw(GtkWidget *widget, cairo_t *cr, gpointer data)
 	return FALSE;
 	return FALSE;
 }
 }
 
 
-
 static gboolean
 static gboolean
 preview_configure(GtkWidget *widget, GdkEventConfigure *event)
 preview_configure(GtkWidget *widget, GdkEventConfigure *event)
 {
 {
 	int new_preview_width = gtk_widget_get_allocated_width(widget);
 	int new_preview_width = gtk_widget_get_allocated_width(widget);
 	int new_preview_height = gtk_widget_get_allocated_height(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_width = new_preview_width;
 		preview_height = new_preview_height;
 		preview_height = new_preview_height;
 		update_io_pipeline();
 		update_io_pipeline();
@@ -336,11 +327,11 @@ on_open_last_clicked(GtkWidget *widget, gpointer user_data)
 	char uri[275];
 	char uri[275];
 	GError *error = NULL;
 	GError *error = NULL;
 
 
-	if(strlen(last_path) == 0) {
+	if (strlen(last_path) == 0) {
 		return;
 		return;
 	}
 	}
 	sprintf(uri, "file://%s.tiff", last_path);
 	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);
 		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];
 	char uri[270];
 	GError *error = NULL;
 	GError *error = NULL;
 	sprintf(uri, "file://%s/Pictures", getenv("HOME"));
 	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);
 		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);
 			gtk_widget_show(control_box);
 		}
 		}
 
 
-		if (event->x < 60 ) {
+		if (event->x < 60) {
 			// ISO
 			// ISO
 			current_control = USER_CONTROL_ISO;
 			current_control = USER_CONTROL_ISO;
 			gtk_label_set_text(GTK_LABEL(control_name), "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_lower(control_slider, 0.0);
 			gtk_adjustment_set_upper(control_slider, (float)gain_max);
 			gtk_adjustment_set_upper(control_slider, (float)gain_max);
 			gtk_adjustment_set_value(control_slider, (double)gain);
 			gtk_adjustment_set_value(control_slider, (double)gain);
@@ -390,7 +382,8 @@ on_preview_tap(GtkWidget *widget, GdkEventButton *event, gpointer user_data)
 			// Shutter angle
 			// Shutter angle
 			current_control = USER_CONTROL_SHUTTER;
 			current_control = USER_CONTROL_SHUTTER;
 			gtk_label_set_text(GTK_LABEL(control_name), "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_lower(control_slider, 1.0);
 			gtk_adjustment_set_upper(control_slider, 360.0);
 			gtk_adjustment_set_upper(control_slider, 360.0);
 			gtk_adjustment_set_value(control_slider, (double)exposure);
 			gtk_adjustment_set_value(control_slider, (double)exposure);
@@ -415,7 +408,8 @@ void
 on_camera_switch_clicked(GtkWidget *widget, gpointer user_data)
 on_camera_switch_clicked(GtkWidget *widget, gpointer user_data)
 {
 {
 	size_t next_index = camera->index + 1;
 	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) {
 	if (!next_camera) {
 		next_index = 0;
 		next_index = 0;
@@ -445,18 +439,18 @@ on_control_auto_toggled(GtkToggleButton *widget, gpointer user_data)
 	bool has_changed;
 	bool has_changed;
 
 
 	switch (current_control) {
 	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) {
 	if (has_changed) {
@@ -472,22 +466,22 @@ on_control_slider_changed(GtkAdjustment *widget, gpointer user_data)
 
 
 	bool has_changed = false;
 	bool has_changed = false;
 	switch (current_control) {
 	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) {
 	if (has_changed) {
@@ -504,19 +498,26 @@ main(int argc, char *argv[])
 
 
 	setenv("LC_NUMERIC", "C", 1);
 	setenv("LC_NUMERIC", "C", 1);
 
 
-
 	gtk_init(&argc, &argv);
 	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 *window = GTK_WIDGET(gtk_builder_get_object(builder, "window"));
 	GtkWidget *shutter = GTK_WIDGET(gtk_builder_get_object(builder, "shutter"));
 	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"));
 	preview = GTK_WIDGET(gtk_builder_get_object(builder, "preview"));
 	error_box = GTK_WIDGET(gtk_builder_get_object(builder, "error_box"));
 	error_box = GTK_WIDGET(gtk_builder_get_object(builder, "error_box"));
 	error_message = GTK_WIDGET(gtk_builder_get_object(builder, "error_message"));
 	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"));
 	thumb_last = GTK_WIDGET(gtk_builder_get_object(builder, "thumb_last"));
 	control_box = GTK_WIDGET(gtk_builder_get_object(builder, "control_box"));
 	control_box = GTK_WIDGET(gtk_builder_get_object(builder, "control_box"));
 	control_name = GTK_WIDGET(gtk_builder_get_object(builder, "control_name"));
 	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"));
 	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(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
 	g_signal_connect(shutter, "clicked", G_CALLBACK(on_shutter_clicked), 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, "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) |
 	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();
 	GtkCssProvider *provider = gtk_css_provider_new();
 	if (access("camera.css", F_OK) != -1) {
 	if (access("camera.css", F_OK) != -1) {
 		gtk_css_provider_load_from_path(provider, "camera.css", NULL);
 		gtk_css_provider_load_from_path(provider, "camera.css", NULL);
 	} else {
 	} 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);
 	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);
 	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();
 	mp_io_pipeline_start();
 
 

+ 10 - 11
main.h

@@ -4,18 +4,18 @@
 #include "gtk/gtk.h"
 #include "gtk/gtk.h"
 
 
 struct mp_main_state {
 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);
 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_set_preview(cairo_surface_t *image);
 void mp_main_capture_completed(const char *fname);
 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
 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
 	// zero out target matrix
-	for(int i=0; i<9; i++) {
+	for (int i = 0; i < 9; i++) {
 		out[i] = 0;
 		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>
 #include <assert.h>
 
 
 struct _MPPipeline {
 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 {
 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
 // 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 *);
 typedef void (*MPPipelineCallback)(MPPipeline *, const void *);
 
 
 MPPipeline *mp_pipeline_new();
 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);
 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
 #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;
 static MPPipeline *pipeline;
 
 
@@ -49,373 +46,378 @@ static char capture_fname[255];
 static void
 static void
 register_custom_tiff_tags(TIFF *tif)
 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
 static bool
 find_processor(char *script)
 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
 static void
 process_image_for_preview(const MPImage *image)
 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
 static void
 process_image_for_capture(const MPImage *image, int count)
 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
 static void
 process_capture_burst()
 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
 static void
 process_image(MPPipeline *pipeline, const MPImage *image)
 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
 static void
 update_state(MPPipeline *pipeline, const struct mp_process_pipeline_state *state)
 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"
 #include "camera_config.h"
 
 
 struct mp_process_pipeline_state {
 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();
 void mp_process_pipeline_start();

+ 123 - 165
quickpreview.c

@@ -7,12 +7,14 @@
 #include <assert.h>
 #include <assert.h>
 #include <stdio.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;
 	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 r = 1.164f * y + 1.596f * (v - 128);
 	uint32_t g = 1.164f * y - 0.813f * (v - 128) - 0.391f * (u - 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);
 	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) {
 	if (!colormatrix) {
 		return color;
 		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
 	// Clip colors
 	if (r > 0xFF)
 	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);
 	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;
 	uint32_t x_r, y_r;
 	if (rotation == 0) {
 	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;
 	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;
 	uint32_t src_y = 0, dst_y = 0;
 	while (src_y < src_height) {
 	while (src_y < src_height) {
@@ -94,25 +99,26 @@ static void quick_preview_rggb8(
 
 
 			uint32_t color;
 			uint32_t color;
 			switch (format) {
 			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);
 			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;
 			src_x += 2 + 2 * skip;
 			++dst_x;
 			++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);
 	assert(src_width % 2 == 0);
 
 
@@ -153,25 +153,26 @@ static void quick_preview_rggb10(
 
 
 			uint32_t color;
 			uint32_t color;
 			switch (format) {
 			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);
 			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;
 			uint32_t advance = 1 + skip;
 			if (src_x % 5 == 0) {
 			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);
 	assert(src_width % 2 == 0);
 
 
@@ -222,28 +217,31 @@ static void quick_preview_yuv(
 
 
 			uint32_t color1, color2;
 			uint32_t color1, color2;
 			switch (format) {
 			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);
 			color1 = apply_colormatrix(color1, colormatrix);
 			color2 = apply_colormatrix(color2, 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[dst_i1] = color1;
 			++dst_x;
 			++dst_x;
 
 
 			// The last pixel needs to be skipped if we have an odd un-rotated width
 			// The last pixel needs to be skipped if we have an odd un-rotated width
 			if (dst_x < unrot_dst_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[dst_i2] = color2;
 				++dst_x;
 				++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) {
 	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_x = mp_pixel_format_width_to_colors(format, src_width);
 	uint32_t colors_y = mp_pixel_format_height_to_colors(format, src_height);
 	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 "camera.h"
 #include <stdint.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);