1#
2# Copyright (c) 2017, Alliance for Open Media. All rights reserved
3#
4# This source code is subject to the terms of the BSD 2 Clause License and the
5# Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License was
6# not distributed with this source code in the LICENSE file, you can obtain it
7# at www.aomedia.org/license/software. If the Alliance for Open Media Patent
8# License 1.0 was not distributed with this source code in the PATENTS file, you
9# can obtain it at www.aomedia.org/license/patent.
10#
11if(AOM_DOCS_CMAKE_)
12  return()
13endif() # AOM_DOCS_CMAKE_
14set(AOM_DOCS_CMAKE_ 1)
15
16cmake_minimum_required(VERSION 3.5)
17
18set(AOM_DOXYFILE "${AOM_CONFIG_DIR}/doxyfile")
19set(AOM_DOXYGEN_CONFIG_TEMPLATE "libs.doxy_template")
20set(AOM_DOXYGEN_OUTPUT_DIR "${AOM_CONFIG_DIR}/dox")
21set(AOM_DOXYGEN_SECTIONS "av1")
22
23set(AOM_DOXYGEN_SOURCES
24    "${AOM_ROOT}/aom/aom.h"
25    "${AOM_ROOT}/aom/aom_codec.h"
26    "${AOM_ROOT}/aom/aom_decoder.h"
27    "${AOM_ROOT}/aom/aom_encoder.h"
28    "${AOM_ROOT}/aom/aom_external_partition.h"
29    "${AOM_ROOT}/aom/aom_frame_buffer.h"
30    "${AOM_ROOT}/aom/aom_image.h"
31    "${AOM_ROOT}/aom/aom_integer.h"
32    "${AOM_ROOT}/av1/common/av1_common_int.h"
33    "${AOM_ROOT}/av1/common/av1_loopfilter.h"
34    "${AOM_ROOT}/av1/common/blockd.h"
35    "${AOM_ROOT}/av1/common/cdef.h"
36    "${AOM_ROOT}/av1/common/enums.h"
37    "${AOM_ROOT}/av1/common/restoration.h"
38    "${AOM_ROOT}/keywords.dox"
39    "${AOM_ROOT}/mainpage.dox"
40    "${AOM_ROOT}/usage.dox")
41
42if(CONFIG_AV1_DECODER)
43  set(AOM_DOXYGEN_EXAMPLE_SOURCES ${AOM_DOXYGEN_EXAMPLE_SOURCES}
44                                  "${AOM_ROOT}/apps/aomdec.c"
45                                  "${AOM_ROOT}/examples/decode_to_md5.c"
46                                  "${AOM_ROOT}/examples/decode_with_drops.c"
47                                  "${AOM_ROOT}/examples/simple_decoder.c")
48
49  set(AOM_DOXYGEN_EXAMPLE_DESCRIPTIONS ${AOM_DOXYGEN_EXAMPLE_DESCRIPTIONS}
50                                       "Full featured decoder."
51                                       "Frame by frame MD5 checksum."
52                                       "Drops frames while decoding."
53                                       "Simplified decoder loop.")
54
55  set(AOM_DOXYGEN_SECTIONS ${AOM_DOXYGEN_SECTIONS} "av1_decoder decoder")
56
57  set(AOM_DOXYGEN_SOURCES ${AOM_DOXYGEN_SOURCES} "${AOM_ROOT}/aom/aomdx.h"
58                          "${AOM_ROOT}/usage_dx.dox"
59                          "${AOM_ROOT}/av1/decoder/decoder.h")
60
61  if(CONFIG_ANALYZER)
62    set(AOM_DOXYGEN_EXAMPLE_SOURCES ${AOM_DOXYGEN_EXAMPLE_SOURCES}
63                                    "${AOM_ROOT}/examples/analyzer.cc")
64
65    set(AOM_DOXYGEN_EXAMPLE_DESCRIPTIONS ${AOM_DOXYGEN_EXAMPLE_DESCRIPTIONS}
66                                         "Bitstream analyzer.")
67  endif()
68
69  if(CONFIG_INSPECTION)
70    set(AOM_DOXYGEN_EXAMPLE_SOURCES ${AOM_DOXYGEN_EXAMPLE_SOURCES}
71                                    "${AOM_ROOT}/examples/inspect.c")
72
73    set(AOM_DOXYGEN_EXAMPLE_DESCRIPTIONS ${AOM_DOXYGEN_EXAMPLE_DESCRIPTIONS}
74                                         "Bitstream inspector.")
75  endif()
76
77  set(AOM_DOXYGEN_SOURCES ${AOM_DOXYGEN_SOURCES}
78                          "${AOM_ROOT}/doc/dev_guide/av1_decoder.dox")
79endif()
80
81if(CONFIG_AV1_ENCODER)
82  set(AOM_DOXYGEN_EXAMPLE_SOURCES ${AOM_DOXYGEN_EXAMPLE_SOURCES}
83                                  "${AOM_ROOT}/apps/aomenc.c"
84                                  "${AOM_ROOT}/examples/lossless_encoder.c"
85                                  "${AOM_ROOT}/examples/set_maps.c"
86                                  "${AOM_ROOT}/examples/simple_encoder.c"
87                                  "${AOM_ROOT}/examples/twopass_encoder.c")
88
89  set(AOM_DOXYGEN_EXAMPLE_DESCRIPTIONS ${AOM_DOXYGEN_EXAMPLE_DESCRIPTIONS}
90                                       "Full featured encoder."
91                                       "Simplified lossless encoder."
92                                       "Set active and ROI maps."
93                                       "Simplified encoder loop."
94                                       "Two-pass encoder loop.")
95
96  set(AOM_DOXYGEN_EXAMPLE_SOURCES ${AOM_DOXYGEN_EXAMPLE_SOURCES}
97                                  "${AOM_ROOT}/examples/scalable_encoder.c")
98
99  set(AOM_DOXYGEN_EXAMPLE_DESCRIPTIONS ${AOM_DOXYGEN_EXAMPLE_DESCRIPTIONS}
100                                       "Scalable encoder loop.")
101
102  set(AOM_DOXYGEN_EXAMPLE_SOURCES ${AOM_DOXYGEN_EXAMPLE_SOURCES}
103                                  "${AOM_ROOT}/examples/svc_encoder_rtc.c")
104
105  set(AOM_DOXYGEN_EXAMPLE_DESCRIPTIONS ${AOM_DOXYGEN_EXAMPLE_DESCRIPTIONS}
106                                       "Layered encoder for RTC.")
107
108  set(AOM_DOXYGEN_SECTIONS ${AOM_DOXYGEN_SECTIONS} "av1_encoder encoder")
109
110  set(AOM_DOXYGEN_SOURCES ${AOM_DOXYGEN_SOURCES} "${AOM_ROOT}/aom/aomcx.h"
111                          "${AOM_ROOT}/usage_cx.dox")
112  set(AOM_DOXYGEN_SOURCES ${AOM_DOXYGEN_SOURCES}
113                          "${AOM_ROOT}/doc/dev_guide/av1_encoder.dox")
114  set(AOM_DOXYGEN_SOURCES
115      ${AOM_DOXYGEN_SOURCES}
116      "${AOM_ROOT}/aom_scale/yv12config.h"
117      "${AOM_ROOT}/av1/encoder/bitstream.h"
118      "${AOM_ROOT}/av1/encoder/block.h"
119      "${AOM_ROOT}/av1/encoder/aq_cyclicrefresh.h"
120      "${AOM_ROOT}/av1/encoder/encode_strategy.c"
121      "${AOM_ROOT}/av1/encoder/encode_strategy.h"
122      "${AOM_ROOT}/av1/encoder/encodeframe.c"
123      "${AOM_ROOT}/av1/encoder/encoder.c"
124      "${AOM_ROOT}/av1/encoder/encoder.h"
125      "${AOM_ROOT}/av1/encoder/encodetxb.h"
126      "${AOM_ROOT}/av1/encoder/firstpass.h"
127      "${AOM_ROOT}/av1/encoder/gop_structure.h"
128      "${AOM_ROOT}/av1/encoder/interp_search.c"
129      "${AOM_ROOT}/av1/encoder/intra_mode_search.h"
130      "${AOM_ROOT}/av1/encoder/intra_mode_search.c"
131      "${AOM_ROOT}/av1/encoder/intra_mode_search_utils.h"
132      "${AOM_ROOT}/av1/encoder/lookahead.h"
133      "${AOM_ROOT}/av1/encoder/palette.h"
134      "${AOM_ROOT}/av1/encoder/palette.c"
135      "${AOM_ROOT}/av1/encoder/partition_search.h"
136      "${AOM_ROOT}/av1/encoder/partition_search.c"
137      "${AOM_ROOT}/av1/encoder/pass2_strategy.h"
138      "${AOM_ROOT}/av1/encoder/pass2_strategy.c"
139      "${AOM_ROOT}/av1/encoder/pickcdef.h"
140      "${AOM_ROOT}/av1/encoder/picklpf.h"
141      "${AOM_ROOT}/av1/encoder/pickrst.h"
142      "${AOM_ROOT}/av1/encoder/ratectrl.c"
143      "${AOM_ROOT}/av1/encoder/ratectrl.h"
144      "${AOM_ROOT}/av1/encoder/rc_utils.h"
145      "${AOM_ROOT}/av1/encoder/rdopt.h"
146      "${AOM_ROOT}/av1/encoder/rdopt.c"
147      "${AOM_ROOT}/av1/encoder/speed_features.h"
148      "${AOM_ROOT}/av1/encoder/svc_layercontext.c"
149      "${AOM_ROOT}/av1/encoder/svc_layercontext.h"
150      "${AOM_ROOT}/av1/encoder/temporal_filter.h"
151      "${AOM_ROOT}/av1/encoder/temporal_filter.c"
152      "${AOM_ROOT}/av1/encoder/tpl_model.h"
153      "${AOM_ROOT}/av1/encoder/tx_search.h"
154      "${AOM_ROOT}/av1/encoder/txb_rdopt.h"
155      "${AOM_ROOT}/av1/encoder/var_based_part.h"
156      "${AOM_ROOT}/av1/encoder/nonrd_pickmode.c")
157endif()
158
159if(CONFIG_AV1_DECODER AND CONFIG_AV1_ENCODER)
160  set(AOM_DOXYGEN_EXAMPLE_SOURCES ${AOM_DOXYGEN_EXAMPLE_SOURCES}
161                                  "${AOM_ROOT}/examples/aom_cx_set_ref.c")
162
163  set(AOM_DOXYGEN_EXAMPLE_DESCRIPTIONS ${AOM_DOXYGEN_EXAMPLE_DESCRIPTIONS}
164                                       "Set encoder reference frame.")
165endif()
166
167if(CONFIG_AV1_ENCODER)
168  set(AOM_DOXYGEN_EXAMPLE_SOURCES ${AOM_DOXYGEN_EXAMPLE_SOURCES}
169                                  "${AOM_ROOT}/examples/lightfield_encoder.c")
170
171  set(AOM_DOXYGEN_EXAMPLE_DESCRIPTIONS ${AOM_DOXYGEN_EXAMPLE_DESCRIPTIONS}
172                                       "Lightfield encoder example.")
173endif()
174
175if(CONFIG_AV1_DECODER)
176  set(AOM_DOXYGEN_EXAMPLE_SOURCES
177      ${AOM_DOXYGEN_EXAMPLE_SOURCES}
178      "${AOM_ROOT}/examples/lightfield_tile_list_decoder.c")
179
180  set(AOM_DOXYGEN_EXAMPLE_DESCRIPTIONS ${AOM_DOXYGEN_EXAMPLE_DESCRIPTIONS}
181                                       "Lightfield tile list decoder example.")
182endif()
183
184if(CONFIG_AV1_DECODER)
185  set(AOM_DOXYGEN_EXAMPLE_SOURCES ${AOM_DOXYGEN_EXAMPLE_SOURCES}
186                                  "${AOM_ROOT}/examples/lightfield_decoder.c")
187
188  set(AOM_DOXYGEN_EXAMPLE_DESCRIPTIONS ${AOM_DOXYGEN_EXAMPLE_DESCRIPTIONS}
189                                       "Lightfield decoder example.")
190endif()
191
192if(CONFIG_AV1_DECODER AND CONFIG_AV1_ENCODER)
193  set(AOM_DOXYGEN_EXAMPLE_SOURCES
194      ${AOM_DOXYGEN_EXAMPLE_SOURCES}
195      "${AOM_ROOT}/examples/lightfield_bitstream_parsing.c")
196
197  set(AOM_DOXYGEN_EXAMPLE_DESCRIPTIONS ${AOM_DOXYGEN_EXAMPLE_DESCRIPTIONS}
198                                       "Lightfield bitstream parsing example.")
199endif()
200
201# Iterates over list named by $list_name and appends each item to $AOM_DOXYFILE
202# as values assigned to $var_name with no line breaks between list items.
203# Appends a new line after the entire config variable is expanded.
204function(write_cmake_list_to_doxygen_config_var var_name list_name)
205  unset(output_string)
206  foreach(list_item ${${list_name}})
207    set(output_string "${output_string} ${list_item} ")
208  endforeach()
209  string(STRIP "${output_string}" output_string)
210  file(APPEND "${AOM_DOXYFILE}" "${var_name} += ${output_string}\n")
211endfunction()
212
213function(get_name file_path name_var)
214  get_filename_component(file_basename ${file_path} NAME)
215  get_filename_component(${name_var} ${file_basename} NAME_WE)
216  set(${name_var} ${${name_var}} PARENT_SCOPE)
217endfunction()
218
219function(setup_documentation_targets)
220
221  # Sanity check: the lengths of these lists must match.
222  list(LENGTH AOM_DOXYGEN_EXAMPLE_SOURCES num_sources)
223  list(LENGTH AOM_DOXYGEN_EXAMPLE_DESCRIPTIONS num_descs)
224  if(NOT ${num_sources} EQUAL ${num_descs})
225    message(FATAL_ERROR "Unqeual example and description totals.")
226  endif()
227
228  # Take the list of examples and produce example_basename.dox for each file in
229  # the list.
230  file(MAKE_DIRECTORY "${AOM_DOXYGEN_OUTPUT_DIR}")
231  foreach(example_file ${AOM_DOXYGEN_EXAMPLE_SOURCES})
232    unset(example_basename)
233    get_name("${example_file}" "example_name")
234    set(example_dox "${AOM_DOXYGEN_OUTPUT_DIR}/${example_name}.dox")
235    set(dox_string "/*!\\page example_${example_name} ${example_name}\n")
236    set(dox_string "${dox_string} \\includelineno ${example_file}\n*/\n")
237    file(WRITE "${example_dox}" ${dox_string})
238    set(AOM_DOXYGEN_SOURCES ${AOM_DOXYGEN_SOURCES} "${example_dox}")
239  endforeach()
240
241  # Generate samples.dox, an index page that refers to the example_basename.dox
242  # files that were just created.
243  set(samples_header "
244/*!\\page samples Sample Code
245This SDK includes a number of sample applications. Each sample documents a
246feature of the SDK in both prose and the associated C code. The following
247samples are included:
248")
249
250  set(utils_desc "
251In addition, the SDK contains a number of utilities. Since these utilities are
252built upon the concepts described in the sample code listed above, they are not
253documented in pieces like the samples are. Their source is included here for
254reference. The following utilities are included:
255")
256
257  # Write the description for the samples section.
258  set(samples_dox "${AOM_CONFIG_DIR}/samples.dox")
259  file(WRITE "${samples_dox}" "${samples_header}\n")
260
261  # Iterate over $AOM_DOXYGEN_EXAMPLE_SOURCES and
262  # $AOM_DOXYGEN_EXAMPLE_DESCRIPTIONS and massage example names as required by
263  # AV1's doxygen setup.
264  math(EXPR max_example_index "${num_sources} - 1")
265  foreach(NUM RANGE ${max_example_index})
266    list(GET AOM_DOXYGEN_EXAMPLE_SOURCES ${NUM} ex_name)
267    get_name("${ex_name}" "ex_name")
268
269    # AV1's doxygen lists aomdec and aomenc as utils apart from the examples.
270    # Save the indexes for another pass.
271    if("${ex_name}" MATCHES "aomdec\|aomenc")
272      set(util_indexes "${util_indexes}" "${NUM}")
273      continue()
274    endif()
275    list(GET AOM_DOXYGEN_EXAMPLE_DESCRIPTIONS ${NUM} ex_desc)
276    file(APPEND "${samples_dox}" " - \\subpage example_${ex_name} ${ex_desc}\n")
277  endforeach()
278
279  # Write the description and index for the utils.
280  file(APPEND "${samples_dox}" "${utils_desc}\n")
281  foreach(util_index ${util_indexes})
282    list(GET AOM_DOXYGEN_EXAMPLE_SOURCES ${util_index} ex_name)
283    get_name("${ex_name}" "ex_name")
284    list(GET AOM_DOXYGEN_EXAMPLE_DESCRIPTIONS ${util_index} ex_desc)
285    file(APPEND "${samples_dox}" " - \\subpage example_${ex_name} ${ex_desc}\n")
286  endforeach()
287  file(APPEND "${samples_dox}" "*/")
288
289  # Add $samples_dox to the doxygen inputs.
290  get_filename_component(samples_dox ${samples_dox} NAME)
291  set(AOM_DOXYGEN_SOURCES ${AOM_DOXYGEN_SOURCES} ${samples_dox})
292
293  # There are issues to show Markdown file for old Doxygen version. Here, only
294  # enable Markdown support for 1.8.16 or newer.
295  if(${DOXYGEN_VERSION_VALUE} GREATER_EQUAL 1008016)
296    set(AOM_DOXYGEN_SECTIONS ${AOM_DOXYGEN_SECTIONS} "av1_md_support")
297    set(AOM_DOXYGEN_SOURCES ${AOM_DOXYGEN_SOURCES} "${AOM_ROOT}/README.md")
298    # Uncomment and add AlgorithmDescription.md in result page when it is done.
299    # set(AOM_DOXYGEN_SOURCES ${AOM_DOXYGEN_SOURCES}
300    # "${AOM_ROOT}/doc/AlgorithmDescription.md")
301  endif()
302
303  # Generate libaom's doxyfile.
304  file(WRITE "${AOM_DOXYFILE}" "##\n## GENERATED FILE. DO NOT EDIT\n##\n")
305  file(READ "${AOM_ROOT}/${AOM_DOXYGEN_CONFIG_TEMPLATE}" doxygen_template_data)
306  file(APPEND "${AOM_DOXYFILE}" ${doxygen_template_data})
307  file(APPEND "${AOM_DOXYFILE}"
308       "EXAMPLE_PATH += ${AOM_ROOT} ${AOM_ROOT}/examples\n")
309  file(APPEND "${AOM_DOXYFILE}"
310       "INCLUDE_PATH += ${AOM_CONFIG_DIR} ${AOM_ROOT}\n")
311  file(APPEND "${AOM_DOXYFILE}"
312       "STRIP_FROM_PATH += ${AOM_ROOT} ${AOM_CONFIG_DIR}\n")
313  write_cmake_list_to_doxygen_config_var("INPUT" "AOM_DOXYGEN_SOURCES")
314  write_cmake_list_to_doxygen_config_var("ENABLED_SECTIONS"
315                                         "AOM_DOXYGEN_SECTIONS")
316
317  # Add AOMedia logo.
318  set(aom_logo "aomedia_logo_200.png")
319  configure_file(${AOM_ROOT}/${aom_logo} ${AOM_CONFIG_DIR}/${aom_logo} COPYONLY)
320  file(APPEND "${AOM_DOXYFILE}"
321       "PROJECT_LOGO = ${AOM_CONFIG_DIR}/${aom_logo}\n")
322
323  # Only set HAVE_DOT to YES if dot tool is found.
324  if(DOXYGEN_DOT_FOUND)
325    file(APPEND "${AOM_DOXYFILE}" "HAVE_DOT = YES\n")
326    file(APPEND "${AOM_DOXYFILE}" "DOT_GRAPH_MAX_NODES = 10000\n")
327  endif()
328
329  # Add image path.
330  file(APPEND "${AOM_DOXYFILE}" "IMAGE_PATH += ${AOM_ROOT}/doc/dev_guide\n")
331
332  # Allow banner style comments
333  file(APPEND "${AOM_DOXYFILE}" "JAVADOC_BANNER = YES")
334
335  # Add the doxygen generation rule.
336  add_custom_target(docs ALL
337                    COMMAND "${DOXYGEN_EXECUTABLE}" "${AOM_DOXYFILE}"
338                    DEPENDS "${AOM_DOXYFILE}" ${AOM_DOXYGEN_SOURCES}
339                            ${AOM_DOXYGEN_EXAMPLE_SOURCES}
340                            "${AOM_DOXYGEN_CONFIG_TEMPLATE}"
341                    SOURCES "${AOM_DOXYFILE}" ${AOM_DOXYGEN_SOURCES}
342                            ${AOM_DOXYGEN_EXAMPLE_SOURCES}
343                            "${AOM_DOXYGEN_CONFIG_TEMPLATE}")
344endfunction()
345