From: Antonio Ospite Date: Thu, 1 Mar 2018 17:24:21 +0000 (+0100) Subject: Merge tag 'v0.1.7' into debian/master X-Git-Tag: debian/0.1.7-1~23 X-Git-Url: https://git.ao2.it/libam7xxx.git/commitdiff_plain/ca9d15b4f083d6b7f8257550f0a43839c3e052d9?hp=189a9391eb6cbc584cc0cc9d72dd4b91b9c71f4f Merge tag 'v0.1.7' into debian/master Release version 0.1.7 --- diff --git a/ChangeLog b/ChangeLog deleted file mode 100644 index 2e2a652..0000000 --- a/ChangeLog +++ /dev/null @@ -1,987 +0,0 @@ -2014-05-15 12:33:41 +0200 Antonio Ospite - - * HACKING.asciidoc: update Windows cross-build section to use libav10 (HEAD, origin/master, master) - -2014-05-12 23:02:28 +0200 Antonio Ospite - - * am7xxx-play: port to libav10 - -2014-05-08 12:59:02 +0200 Antonio Ospite - - * Update email address and copyright years - -2014-05-08 12:37:44 +0200 Antonio Ospite - - * contrib/performance/README: fix some typos - -2014-05-08 12:27:23 +0200 Antonio Ospite - - * cosmetics: remove some trailing spaces - -2014-05-08 12:26:04 +0200 Antonio Ospite - - * README.asciidoc: update instructions to test libam7xxx on Windows - -2014-05-08 12:15:16 +0200 Antonio Ospite - - * HACKING.asciidoc: update the build instructions for Windows - -2014-05-08 11:37:34 +0200 Antonio Ospite - - * am7xxx: don't use partial designated initializers - -2014-05-08 11:22:31 +0200 Antonio Ospite - - * am7xxx: add a portable_endian.h - -2014-05-07 21:40:44 +0200 Antonio Ospite - - * Merge branch 'zoom-tele-picopix' - -2014-05-07 18:05:11 +0200 Antonio Ospite - - * am7xxx-play: allow setting the AM7XXX_ZOOM_TELE zoom mode - -2014-05-07 18:04:16 +0200 Antonio Ospite - - * picoproj: allow setting the AM7XXX_ZOOM_TELE zoom mode - -2014-05-07 18:01:58 +0200 Antonio Ospite - - * am7xxx: implement the set_zoom_mode() operation for the PicoPix 2055 - -2014-05-07 17:59:30 +0200 Antonio Ospite - - * am7xxx: add support for a new AM7XXX_ZOOM_TELE zoom mode - -2014-05-07 17:46:50 +0200 Antonio Ospite - - * am7xxx: add a msleep() implementation in tools.[ch] - -2013-12-04 11:32:26 +0100 Antonio Ospite - - * Merge branch 'powermode-PicoPix2055' - -2013-11-28 15:23:04 +0100 Antonio Ospite - - * am7xxx: add support for setting the power mode on the PicoPix 2055 - -2013-11-28 15:13:12 +0100 Antonio Ospite - - * am7xxx: dump fields of unknown packet types - -2013-11-28 14:57:09 +0100 Antonio Ospite - - * am7xxx: factor out a send_command() function - -2013-11-28 13:49:52 +0100 Antonio Ospite - - * am7xxx: switch from device quirks to device ops - -2013-11-18 14:41:42 +0100 Antonio Ospite - - * doc/lsusb_dumps: add lsusb_Philips-PicoPix-2055.log - -2013-11-18 14:38:26 +0100 Antonio Ospite - - * doc/lsusb_dumps: strip trailing spaces - -2013-11-18 14:35:37 +0100 Antonio Ospite - - * doc/man: misc fixes to man pages - -2013-10-30 10:41:06 +0100 Antonio Ospite - - * CMakeLists.txt: define DEBUG=1 only when CMAKE_BUILD_TYPE=Debug - -2013-10-13 15:50:11 +0200 Antonio Ospite - - * HACKING.asciidoc: fix the url of the avcodec_encode_video2 patch - -2013-09-07 17:30:28 +0200 Antonio Ospite - - * am7xxx-play: cosmetics, fix coding style - -2013-08-03 15:14:34 +0200 Antonio Ospite - - * am7xxx: add quirks for Philips/Sagemcom PicoPix 2055 - -2013-07-28 23:22:15 +0200 Antonio Ospite - - * NEWS: fix a typo s/mode/more/ - -2013-07-28 11:15:18 +0200 Antonio Ospite - - * Release version 0.1.4 (tag: v0.1.4) - -2013-07-28 01:11:42 +0200 Antonio Ospite - - * contrib: add some benchmarking data about am7xxx_send_image_async - -2013-07-28 00:50:30 +0200 Antonio Ospite - - * am7xxx-play: fix a crash when a packet cannot be encoded - -2013-07-28 00:38:13 +0200 Antonio Ospite - - * am7xxx-play: don't initialize variables when not needed - -2013-07-28 00:19:04 +0200 Antonio Ospite - - * TODO: mention that atoi() must go away - -2013-07-28 00:10:08 +0200 Antonio Ospite - - * picoproj: get rid of exit(), return more meaningful values to userspace - -2013-07-27 23:47:26 +0200 Antonio Ospite - - * HACKING.asciidoc: add commands to compile with clang - -2013-07-27 23:44:45 +0200 Antonio Ospite - - * HACKING.asciidoc: add an example of testing am7xxx-play with valgrind - -2013-07-27 23:36:08 +0200 Antonio Ospite - - * doc: update Doxyfile.in - -2013-07-27 23:27:01 +0200 Antonio Ospite - - * contrib: add a udev rule to invoke am7xxx-modeswitch - -2013-07-27 23:25:34 +0200 Antonio Ospite - - * Rename am7xxx_mode_switch to am7xxx-modeswitch - -2013-07-27 23:02:34 +0200 Antonio Ospite - - * TODO: mention that data types could be improved in the API - -2013-07-27 23:01:16 +0200 Antonio Ospite - - * picoporj: fix another -Wshorten-64-to-32 warning from clang - -2013-07-27 22:55:53 +0200 Antonio Ospite - - * picoproj: silence a -Wshorten-64-to-32 warning from clang - -2013-07-27 22:53:19 +0200 Antonio Ospite - - * CMakeLists.txt: disable -Wsign-conversion warnings - -2013-07-27 21:33:28 +0200 Antonio Ospite - - * am7xxx: fix a clang warning - -2013-07-27 20:55:48 +0200 Antonio Ospite - - * examples: silence a couple of clang warnings - -2013-07-27 20:26:06 +0200 Antonio Ospite - - * doc: mention the Top-Height/TEC PP700 in the Doxygen documentation - -2013-07-27 20:23:30 +0200 Antonio Ospite - - * doc: add some lsusb dumps for reference - -2013-07-21 00:13:33 +0200 Antonio Ospite - - * am7xxx-play: use am7xxx_send_image_async() - -2013-07-21 00:10:28 +0200 Antonio Ospite - - * am7xxx: implement am7xxx_send_image_async() - -2013-07-14 13:25:25 +0200 Antonio Ospite - - * am7xxx: fix a typo in a comment s/a am7xxx device/an am7xxx device/ - -2013-07-13 11:05:00 +0200 Antonio Ospite - - * CMakeLists.txt: enable two new compiler warnings - -2013-06-30 00:22:07 +0200 Antonio Ospite - - * am7xxx: add quirks for devices not supporting some operations - -2013-06-30 00:20:51 +0200 Antonio Ospite - - * picoproj: remove an unreachable break statement - -2013-06-30 00:15:30 +0200 Antonio Ospite - - * am7xxx-play: uniform coding style - -2013-06-30 00:12:59 +0200 Antonio Ospite - - * CMakeLists.txt: add support for clang and isolate gcc-only options - -2013-06-29 23:11:57 +0200 Antonio Ospite - - * HACKING.asciidoc: mention the patch needed for older libav/ffmpeg - -2013-06-29 23:02:13 +0200 Antonio Ospite - - * README.asciidoc: mention the TEC PP700 projector as supported - -2013-05-27 00:06:23 +0200 Antonio Ospite - - * picoproj: remove an unneeded blank line - -2013-05-27 00:05:00 +0200 Antonio Ospite - - * examples: print the usage message when a required option is missing - -2013-05-26 23:53:13 +0200 Antonio Ospite - - * CMakeLists.txt: fix enabling verbose debug output - -2013-04-05 23:35:34 +0200 Antonio Ospite - - * am7xxx: use the symbolic constant for libusb log level - -2013-04-05 23:29:58 +0200 Antonio Ospite - - * picoproj: show the image resolution when image does not fit the native one - -2013-04-05 23:28:24 +0200 Antonio Ospite - - * picoproj: remove one of two consecutive blank lines - -2013-03-25 23:04:03 +0100 Antonio Ospite - - * doc, contrib: add PicoPix 2330 to the list of supported devices - -2013-03-25 22:47:21 +0100 Antonio Ospite - - * am7xxx: add support for Philips/Sagemcom PicoPix 2330 - -2013-03-25 22:44:35 +0100 Antonio Ospite - - * Merge branch 'per-device-usb-config' - -2013-03-23 23:30:54 +0100 Antonio Ospite - - * am7xxx: make the supported_device array const - -2013-03-23 22:55:04 +0100 Antonio Ospite - - * am7xxx: improve setting USB configuration and interface_number - -2012-11-14 15:41:48 +0100 Antonio Ospite - - * am7xxx: reference am7xxx_usb_device_descriptor in struct _am7xxx_device - -2013-03-23 22:40:25 +0100 Antonio Ospite - - * am7xxx: fail if USB configuration or interface are not right - -2013-03-23 23:03:48 +0100 Antonio Ospite - - * am7xxx_mode_switch: release interface only if claimed - -2013-03-14 23:04:20 +0100 Antonio Ospite - - * doc: add a man page for am7xxx_mode_switch - -2013-03-15 00:13:21 +0100 Antonio Ospite - - * Add a NEWS file - -2013-03-14 20:23:49 +0100 Antonio Ospite - - * Release version 0.1.3 (tag: v0.1.3) - -2013-03-14 19:48:14 +0100 Antonio Ospite - - * am7xxx-play: switch to avcodec_encode_video2() - -2013-03-14 19:30:07 +0100 Antonio Ospite - - * am7xxx-play: remove an unreachable break - -2013-03-14 12:28:32 +0100 Antonio Ospite - - * am7xxx-play: rename 'packet' to 'in_packet' - -2013-03-14 11:22:05 +0100 Antonio Ospite - - * am7xxx: fix coding style - -2013-03-14 11:13:16 +0100 Antonio Ospite - - * contrib: add the am7xxx-play-window.sh script - -2012-12-17 23:54:51 +0100 Antonio Ospite - - * Merge branch 'fix-devinfo-for-PicoPix' - -2012-12-07 11:59:32 +0100 Antonio Ospite - - * am7xxx: make libam7xxx work with Philips/Sagemcom PPX projectors - -2012-12-07 11:51:16 +0100 Antonio Ospite - - * am7xxx: cache device info in am7xxx_get_device_info() - -2012-12-07 12:22:45 +0100 Antonio Ospite - - * am7xxx: detect unexpected responses to AM7XXX_PACKET_TYPE_DEVINFO requests - -2012-12-04 11:46:12 +0100 Antonio Ospite - - * Fix an error when compiling with both -O0 and -Wp,-D_FORTIFY_SOURCE=2 - -2012-11-14 12:31:01 +0100 Antonio Ospite - - * am7xxx: don't mention AM7XXX_DIRECTION_OUT in read_header() - -2012-11-14 12:08:07 +0100 Antonio Ospite - - * am7xxx: add a note on the symmetry of read_header() and send_header() - -2012-11-14 12:01:34 +0100 Antonio Ospite - - * am7xxx: assign device_list next to its first use - -2012-11-14 11:00:58 +0100 Antonio Ospite - - * am7xxx: print text description of the 'direction' field - -2012-10-14 18:23:04 +0200 Antonio Ospite - - * picoproj: clarify that when AM7XXX_ZOOM_TEST is set no image gets sent - -2012-10-14 18:03:54 +0200 Antonio Ospite - - * am7xxx: add support for Philips/SagemCom PicoPix PPX 2055 - -2012-09-17 10:07:55 +0200 Antonio Ospite - - * examples: support multiple devices - -2012-09-17 10:10:07 +0200 Antonio Ospite - - * doc: update Doxygen configuration - -2012-07-27 12:57:44 +0200 Antonio Ospite - - * Merge branch 'am7xxx_set_zoom_mode' - -2012-06-21 10:12:14 +0200 Antonio Ospite - - * contrib: add a test image to show how zoom modes work - -2012-06-21 10:41:42 +0200 Antonio Ospite - - * am7xxx-play: make the help about power mode more consistent - -2012-06-20 15:32:13 +0200 Antonio Ospite - - * picoproj: make the help about power mode more consistent - -2012-06-20 13:13:20 +0200 Antonio Ospite - - * am7xxx: update signature and documentation of am7xxx_set_power_mode() - -2012-06-21 10:32:32 +0200 Antonio Ospite - - * am7xxx-play: support setting the zoom mode - -2012-02-20 13:43:03 +0100 Antonio Ospite - - * picoproj: support setting the zoom mode - -2012-02-20 13:37:20 +0100 Antonio Ospite - - * am7xxx: implement support for the AM7XXX_PACKET_TYPE_ZOOM - -2012-07-08 23:17:20 +0200 Antonio Ospite - - * Merge remote-tracking branch 'origin/rettichschnidi' - -2012-07-08 22:56:08 +0200 Reto Schneider - - * Add missing break. - -2012-07-06 00:48:31 +0200 Reto Schneider - - * Fix typo. - -2012-06-29 13:22:55 +0200 Antonio Ospite - - * contrib: add an example of how to start displaying images automatically - -2012-06-21 10:23:28 +0200 Antonio Ospite - - * contrib: add other supported devices to 55-am7xxx.rules - -2012-06-20 15:01:02 +0200 Antonio Ospite - - * doc: update the list of supported devices - -2012-06-12 12:48:28 +0200 Antonio Ospite - - * am7xxx: rename am7xxx_header.unknown0 to am7xxx_header.direction - -2012-06-09 12:21:36 +0200 Antonio Ospite - - * README.asciidoc: add Aiptek PocketCinema T25 to the AM7XXX devices list - -2012-06-09 12:19:28 +0200 Matti Koskinen - - * am7xxx: add support for Aiptek PocketCinema T25 - -2012-05-22 16:34:29 +0200 Antonio Ospite - - * README.asciidoc: add info about running am7xxx-play.exe on Windows - -2012-05-22 16:33:44 +0200 Antonio Ospite - - * HACKING.asciidoc: add info about compiling am7xxx-play for Windows - -2012-05-22 16:23:10 +0200 Antonio Ospite - - * am7xxx-play: check if strtok_r is available - -2012-05-22 16:21:25 +0200 Antonio Ospite - - * am7xxx-play: check if sigaction is available - -2012-05-22 16:16:15 +0200 Antonio Ospite - - * am7xxx-play: add a fallback definition for ENOTSUP - -2012-05-22 15:42:26 +0200 Antonio Ospite - - * am7xxx-play: get the framerate from the video stream - -2012-05-22 15:29:55 +0200 Antonio Ospite - - * mingw_cross_toolchain.cmake: set the MINGW variable to True - -2012-05-15 10:35:05 +0200 Antonio Ospite - - * HACKING.asciidoc: add info about getting and building libam7xxx - -2012-05-14 14:42:44 +0200 Antonio Ospite - - * README.asciidoc: add Royaltek PJU-2100 to the AM7XXX based devices list - -2012-05-13 10:25:52 +0200 Richard Wisenoecker - - * am7xxx: add support for Acer C112 - -2012-05-11 21:52:29 +0200 Antonio Ospite - - * README.asciidoc document how to get libam7xx running on MS Windows - -2012-05-11 21:50:36 +0200 Antonio Ospite - - * Add a simple usb_mode_switch clone for am7xxx devices - -2012-05-10 17:00:27 +0200 Antonio Ospite - - * TODO: mention the plan about GStreamer - -2012-05-10 16:02:16 +0200 Antonio Ospite - - * Merge branch 'mingw-port' - -2012-05-10 15:46:47 +0200 Antonio Ospite - - * HACKING.asciidoc: add a section to explain Windows cross compilation - -2012-05-10 15:29:56 +0200 Antonio Ospite - - * Add a CMAKE_TOOLCHAIN_FILE to compile with MinGW - -2012-05-10 14:58:26 +0200 Antonio Ospite - - * Don't set -pedantic-errors in CMAKE_C_FLAGS, it breaks check_symbol_exists() - -2012-05-10 12:13:03 +0200 Antonio Ospite - - * picoproj: replace mmap() with more portable file stream operations - -2012-05-10 12:11:33 +0200 Antonio Ospite - - * picoproj: fix a typo - -2012-05-10 12:10:45 +0200 Antonio Ospite - - * picoproj: issue a warning when passing "-f" more than once - -2012-05-10 09:34:01 +0200 Antonio Ospite - - * am7xxx: don't look for the math library when compiling for Windows - -2012-05-10 09:01:40 +0200 Antonio Ospite - - * am7xxx: MinGW does not have endian.h, provide fallbacks - -2012-05-10 08:16:04 +0200 Antonio Ospite - - * am7xxx: fix setting the USB configuration - -2012-05-10 08:11:14 +0200 Antonio Ospite - - * am7xxx: use hex notation for USB endpoints - -2012-05-10 07:57:01 +0200 Antonio Ospite - - * picoproj: use MAP_PRIVATE in the mmap call - -2012-05-10 07:49:46 +0200 Antonio Ospite - - * HACKING.asciidoc: fix cmake invocation examples - -2012-05-10 15:57:19 +0200 Antonio Ospite - - * Merge remote-tracking branch 'origin/rettichschnidi' into mingw-port - -2012-05-06 23:24:40 +0200 Antonio Ospite - - * picoproj: add a note about image dimensions and native resolution - -2012-04-08 14:24:43 +0200 Reto Schneider - - * Fix usage of FIND_PATH, allow $FFMPEG_DIR to be used. - -2012-04-07 12:39:43 +0200 Reto Schneider - - * Stop CMake if function avformat_open_input not available, print an error message. Prevents compile errors later on. - -2012-04-07 08:39:33 +0200 Reto Schneider - - * Make example programs optional. - -2012-03-28 13:37:00 +0200 Antonio Ospite - - * Release version 0.1.2 (tag: v0.1.2) - -2012-03-28 13:08:23 +0200 Antonio Ospite - - * doc: fix the "custom install targets" to handle DESTDIR - -2012-03-28 10:55:14 +0200 Antonio Ospite - - * Release version 0.1.1 (tag: v0.1.1) - -2012-03-28 10:43:04 +0200 Antonio Ospite - - * doc: use ${DOC_OUTPUT_PATH} in the targets once we have it defined - -2012-03-28 10:31:22 +0200 Antonio Ospite - - * examples: keep the -h option as the last one in am7xxx-play - -2012-03-28 10:27:12 +0200 Antonio Ospite - - * examples: add power level setting to picoproj - -2012-03-28 10:11:54 +0200 Antonio Ospite - - * TODO: remove the entry about signals and picoproj - -2012-03-28 10:09:08 +0200 Antonio Ospite - - * cosmetics: remove some trailing spaces - -2012-03-28 10:02:03 +0200 Antonio Ospite - - * am7xxx: control shared library symbols visibility - -2012-03-28 09:11:51 +0200 Antonio Ospite - - * doc: make sure docs have been generated when installing - -2012-03-26 13:50:05 +0200 Antonio Ospite - - * Increase project number to 0.1.0 (tag: v0.1.0) - -2012-03-26 13:49:31 +0200 Antonio Ospite - - * Merge branch 'unstable' - -2012-03-26 13:27:43 +0200 Antonio Ospite - - * TODO: remove the entry about documenting the API with Doxygen (origin/unstable) - -2012-03-24 00:25:57 +0100 Antonio Ospite - - * doc: add generation of man pages from asciidoc sources - -2012-03-24 00:01:25 +0100 Antonio Ospite - - * doc: add a link to the public API on the main page - -2012-03-24 00:26:59 +0100 Antonio Ospite - - * examples: rephrase picoproj example description - -2012-03-23 23:32:59 +0100 Antonio Ospite - - * examples: make picoproj usage look more like am7xxx-play one - -2012-03-23 22:01:45 +0100 Antonio Ospite - - * doc: add examples to the Doxygen documentation - -2012-03-23 17:03:36 +0100 Antonio Ospite - - * sm7xxx-play: add missing newline on some error messages - -2012-03-21 14:47:20 +0100 Antonio Ospite - - * am7xxx: round scaled_height and scaled_width - -2012-03-21 12:06:16 +0100 Antonio Ospite - - * cmake: make stricter compilation checks conditional - -2012-03-21 11:45:36 +0100 Antonio Ospite - - * Merge remote-tracking branch 'origin/rettichschnidi' into unstable - -2012-03-20 22:59:03 +0100 Antonio Ospite - - * examples: set proper return codes in am7xxx-play - -2012-03-19 22:13:04 +0100 Antonio Ospite - - * examples: add a -l option to am7xxx-play - -2012-03-20 23:39:05 +0100 Reto Schneider - - * Fix typo: dimesions -> dimensions - -2012-03-20 23:36:20 +0100 Reto Schneider - - * All modes above LOW need both connectors to be plugged in. - -2012-03-20 23:33:50 +0100 Reto Schneider - - * Fix typo: architechtures -> architectures - -2012-03-20 23:32:46 +0100 Reto Schneider - - * Remove douled semicolons - -2012-03-20 21:16:14 +0100 Reto Schneider - - * Check the user submitted value for the rescaling method. - -2012-03-20 21:15:29 +0100 Reto Schneider - - * Fix the wording of the help message for the rescaling method. - -2012-03-20 21:06:30 +0100 Reto Schneider - - * Update the help message to make it clear that the quality argument needs a parameter. - -2012-03-20 20:53:38 +0100 Reto Schneider - - * Let the user set the power mode via the switch '-p ' - -2012-03-20 19:55:27 +0100 Reto Schneider - - * Merge remote-tracking branch 'origin/unstable' into rettichschnidi - -2012-03-19 22:07:16 +0100 Antonio Ospite - - * cmake: disable optimizations in debug builds - -2012-03-18 23:45:48 +0100 Reto Schneider - - * Link to all ffmpeg libraries, not just to avdevice. - -2012-03-17 10:17:19 +0100 Antonio Ospite - - * am7xxx: fix a typo, s/it's/its/ - -2012-03-16 20:46:29 +0100 Reto Schneider - - * Merge branch 'unstable' into rettichschnidi - -2012-03-16 20:36:05 +0100 Reto Schneider - - * Purely cosmetic change: add missing newline - -2012-03-09 19:47:54 +0100 Reto Schneider - - * Use commas to separate different pico projector names. - -2012-03-15 15:30:28 +0100 Antonio Ospite - - * examples: add a am7xxx-play example program - -2012-03-15 14:11:28 +0100 Antonio Ospite - - * am7xxx: cosmetics, remove some useless double spaces - -2012-03-15 14:05:25 +0100 Antonio Ospite - - * am7xxx: add am7xxx_calc_scaled_image_dimensions() - -2012-03-08 14:35:36 +0100 Antonio Ospite - - * contrib: add PicoPix 1020 USB IDs to 55-am7xxx.rules - -2012-03-08 14:22:20 +0100 Antonio Ospite - - * picoproj: move it to an example/ directory - -2012-03-07 23:32:29 +0100 Antonio Ospite - - * cmake: split out the maintenance targets to a new cmake module - -2012-03-07 23:12:30 +0100 Antonio Ospite - - * doc: add an install target - -2012-03-07 17:48:49 +0100 Antonio Ospite - - * am7xxx, doc: add Doxygen documentation for the public API - -2012-03-06 17:28:57 +0100 Antonio Ospite - - * am7xxx: rename the 'size' argument of am7xxx_send_image() to 'image_size' - -2012-03-01 23:47:00 +0100 Antonio Ospite - - * cosmetics: remove some unneeded white spaces - -2012-03-01 23:05:50 +0100 Antonio Ospite - - * CmakeLists.txt: add some hardening options to CMAKE_C_FLAGS - -2012-03-01 21:52:06 +0100 Antonio Ospite - - * am7xxx: introduce a new am7xxx_device_info type - -2012-02-29 23:54:22 +0100 Antonio Ospite - - * HACKING.asciidoc: mention how to use valgrind - -2012-02-29 23:31:14 +0100 Antonio Ospite - - * picoproj: add an option to set the log level - -2012-02-29 23:29:12 +0100 Antonio Ospite - - * am7xxx: use the logging infrastructure - -2012-02-28 23:51:37 +0100 Antonio Ospite - - * am7xxx: add a simple logging infrastructure - -2012-02-28 22:37:06 +0100 Antonio Ospite - - * am7xxx: track the context in am7xxx_device - -2012-02-28 21:57:45 +0100 Antonio Ospite - - * am7xxx: pass the context to add_new_device() and find_device() - -2012-02-28 21:44:34 +0100 Antonio Ospite - - * am7xxx: silent a warning enabled by 'sparse' about an uninitialized variable - -2012-02-29 23:33:13 +0100 Antonio Ospite - - * TODO: remove the entry about multi-device support - -2012-02-23 18:05:48 +0100 Antonio Ospite - - * am7xxx: add multi-device support - -2012-02-23 16:23:41 +0100 Antonio Ospite - - * TODO: handle signals in picoproj and do the proper cleanup - -2012-02-22 13:14:24 +0100 Antonio Ospite - - * am7xxx: support other devices which talk the same protocol - -2012-02-21 14:48:06 +0100 Antonio Ospite - - * cmake: fix libusb search - -2012-02-21 13:19:28 +0100 Antonio Ospite - - * am7xxx: change am7xx_device definition, better buffer handling - -2012-02-23 15:26:44 +0100 Antonio Ospite - - * am7xxx: initialize the 'transferred' variable before USB transfers - -2012-02-21 19:55:24 +0100 Antonio Ospite - - * README.asciidoc: Acer C120 is not based on AM7XXX - -2012-02-20 21:31:36 +0100 Antonio Ospite - - * README.asciidoc: rephrase the part about USB IDs - -2012-02-20 17:51:11 +0100 Antonio Ospite - - * README.asciidoc: fix a typo s/trasfers/transfers/ - -2012-02-20 17:50:06 +0100 Antonio Ospite - - * README.asciidoc: mention Thomas Baquet's project and fix some style - -2012-02-20 13:44:23 +0100 Antonio Ospite - - * contrib: add some udev rules to let normal users access the devices - -2012-02-20 13:28:29 +0100 Antonio Ospite - - * README.asciidoc: highlight USB IDs by using an unformatted style - -2012-01-25 15:50:41 +0100 Antonio Ospite - - * Don't use fixed size integer types in the public header - -2012-01-25 15:44:24 +0100 Antonio Ospite - - * Make struct am7xxx_header and related types private - -2012-01-25 15:26:44 +0100 Antonio Ospite - - * Implement am7xxx_get_device_info() - -2012-01-25 12:24:53 +0100 Antonio Ospite - - * Add info about transfer direction in debug messages, add newline - -2012-01-24 17:15:50 +0100 Antonio Ospite - - * picoproj: make the -f option mandatory - -2012-01-24 16:43:23 +0100 Antonio Ospite - - * Implement am7xxx_set_power_mode() - -2012-01-24 16:03:33 +0100 Antonio Ospite - - * Indent header_data fields when dumping headers - -2012-01-24 15:45:00 +0100 Antonio Ospite - - * Document in_80chars() and remove reference_image_header[] - -2012-01-24 15:39:24 +0100 Antonio Ospite - - * Dump the data only in DEBUG builds - -2012-01-24 14:55:54 +0100 Antonio Ospite - - * Add a HACKING.asciidoc file - -2012-01-24 13:38:35 +0100 Antonio Ospite - - * Serialize struct am7xxx_header properly before sending it on the wire - -2012-01-24 10:41:47 +0100 Antonio Ospite - - * picoproj: exit with success when the -h option is used - -2012-01-24 10:27:25 +0100 Antonio Ospite - - * Document usb_modeswitch command to change the device mode - -2012-01-23 17:13:15 +0100 Reto Schneider - - * Renamed AM7XXX_IMAGE_FORMAT_YUV_NV12 to AM7XXX_IMAGE_FORMAT_NV12. - -2012-01-21 16:22:04 +0100 Reto Schneider - - * Added support for imageformat YUV - NV12 - -2012-01-21 16:15:50 +0100 Reto Schneider - - * Stop build process if a warning shows up - -2012-01-16 00:03:42 +0100 Reto Schneider - - * corrected some spelling mistakes - -2012-01-15 22:58:15 +0100 Antonio Ospite - - * Relicense under GPLv2+ - -2012-01-15 21:12:14 +0100 Antonio Ospite - - * Add a TODO file - -2012-01-15 21:11:58 +0100 Antonio Ospite - - * Add a README.asciidoc - -2012-01-15 01:40:19 +0100 Antonio Ospite - - * Fix Copyright year - -2012-01-15 01:39:15 +0100 Antonio Ospite - - * Add GPL-3 license text - -2012-01-13 13:43:59 +0100 Antonio Ospite - - * Rename the header_len field to header_data_len - -2012-01-13 13:37:32 +0100 Antonio Ospite - - * Make including am7xxx.h in C++ code safe - -2012-01-13 03:20:14 +0100 Antonio Ospite - - * Use Cmake and make libam7xxx a shared library - -2012-01-12 13:46:14 +0100 Antonio Ospite - - * Split am7xxx functions and definitions - -2012-01-07 03:16:17 +0100 Antonio Ospite - - * Add backup and changelog rules to Makefile - -2012-01-07 02:53:08 +0100 Antonio Ospite - - * Add initial support for USB output communication - -2012-01-07 01:46:38 +0100 Antonio Ospite - - * Add support for sending an actual JPEG image - -2012-01-07 01:45:20 +0100 Antonio Ospite - - * Image size is always unsigned - -2012-01-07 01:44:01 +0100 Antonio Ospite - - * Wrap lines when dumping big buffers - -2012-01-07 00:03:55 +0100 Antonio Ospite - - * Add some command line options - -2012-01-07 00:03:16 +0100 Antonio Ospite - - * Minor Makefile cleanup - -2012-01-06 22:51:02 +0100 Antonio Ospite - - * Rewrite to support different packet types - -2012-01-07 01:58:10 +0100 Antonio Ospite - - * Fix a typo - -2012-01-06 18:16:37 +0100 Antonio Ospite - - * Initial import diff --git a/HACKING.asciidoc b/HACKING.asciidoc index 3e55f6a..8c8a3ce 100644 --- a/HACKING.asciidoc +++ b/HACKING.asciidoc @@ -7,8 +7,8 @@ http://kernel.org/doc/Documentation/CodingStyle === Getting and compiling libam7xxx -libam7xxx depends on 'libusb-1.0' and optionally on 'libav' or 'ffmpeg' for -its example programs, the build system used is 'cmake'. +libam7xxx depends on 'libusb-1.0' and optionally on 'libav' or 'ffmpeg' (3.1+) +for its example programs, the build system used is 'cmake'. On a Debian based system, the dependencies can be installed with this command: @@ -17,10 +17,11 @@ On a Debian based system, the dependencies can be installed with this command: libavformat-dev \ libavcodec-dev \ libavdevice-dev \ - libswscale-dev + libswscale-dev \ + libxcb1-dev With libav/ffmpeg version previous than 0.9 this patch is needed: -http://git.ao2.it/libam7xxx.git/blob_plain/refs/heads/debian:/debian/patches/0001-Revert-am7xxx-play-switch-to-avcodec_encode_video2.patch +https://git.ao2.it/libam7xxx.git/blob/6d2d8613958e1f0ef011e9d848426086caafe9db:/debian/patches/0002-Revert-am7xxx-play-switch-to-avcodec_encode_video2.patch The library and the example programs can be compiled following these steps: @@ -64,17 +65,17 @@ If you want to build for MS Windows: $ sudo aptitude install mingw-w64 $ mkdir build $ cd build - $ wget -nv http://download.sourceforge.net/project/libusb/libusb-1.0/libusb-1.0.18/libusb-1.0.18-win.7z - $ 7z -olibusb-1.0.18-win x libusb-1.0.18-win.7z - $ wget -nv http://win32.libav.org/releases/libav-10.1-win32.7z - $ 7z -olibav-10.1-win32 x libav-10.1-win32.7z + $ wget -nv https://github.com/libusb/libusb/releases/download/v1.0.21/libusb-1.0.21.7z + $ 7z -olibusb-1.0.21 x libusb-1.0.21.7z + $ wget -nv https://ffmpeg.zeranoe.com/builds/win32/dev/ffmpeg-3.4.2-win32-dev.zip + $ unzip ffmpeg-3.4.2-win32-dev.zip $ cmake \ -D GNU_HOST=i686-w64-mingw32 \ -D CMAKE_TOOLCHAIN_FILE=../cmake_modules/mingw_cross_toolchain.cmake \ -D CMAKE_INSTALL_PREFIX=libam7xxx-win/ \ - -D LIBUSB_1_INCLUDE_DIR=libusb-1.0.18-win/include/libusb-1.0 \ - -D LIBUSB_1_LIBRARY=libusb-1.0.18-win/MinGW32/dll/libusb-1.0.dll \ - -D FFMPEG_ROOT=$(pwd)/libav-10.1-win32/win32/usr \ + -D LIBUSB_1_INCLUDE_DIR=libusb-1.0.21/include/libusb-1.0 \ + -D LIBUSB_1_LIBRARY=libusb-1.0.21/MinGW32/dll/libusb-1.0.dll \ + -D FFMPEG_ROOT=$(pwd)/ffmpeg-3.4.2-win32-dev \ ../ $ make diff --git a/NEWS b/NEWS index 4b63b2d..c9980aa 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,15 @@ +News for v0.1.7: +================ + + * Fix FFMpeg deprecation warnings, the code now depends on FFMpeg 3.1+ + * Fix compilation on Windows + * Update the Windows build instructions in HACKING.asciidoc + * Add a HOWTO for new users in contrib/howto-picopix.asciidoc + * Add a patch to contrib/ to allow compiling libam7xxx on Ubuntu 14.04 LTS + * Make sure am7xxx_get_device_info() always returns sensible values + * Fix warnings about _BSD_SOURCE deprecation + * Misc code and build system cleanups + News for v0.1.6: ================ @@ -7,8 +19,8 @@ News for v0.1.6: mode, add an option to enable the frame dump, but this is only active in DEBUG mode * Fix some compilation warnings from clang - * Replace deprecated FFmpeg API symbol PIX_FMT_NV12 in am7xx-play (Thanks to - Andreas Cadhalpun) + * Replace deprecated FFmpeg API symbol PIX_FMT_NV12 in am7xxx-play (Thanks + to Andreas Cadhalpun) * Fix the Length field in the switch command in am7xxx-modeswitch (Thanks to Balasubramanian S) * More robust handling of USB configurations diff --git a/README.asciidoc b/README.asciidoc index ffa2e5d..839a19e 100644 --- a/README.asciidoc +++ b/README.asciidoc @@ -88,12 +88,13 @@ this needs still needs to be verified. All the needed files below must be in the same location: - 'MinGW32/dll/libusb-1.0.dll' from - http://download.sourceforge.net/project/libusb/libusb-1.0/libusb-1.0.18/libusb-1.0.18-win.7z + https://github.com/libusb/libusb/releases/download/v1.0.21/libusb-1.0.21.7z - 'libssp-0.dll' from MinGW; - - all the '*.dll' files from the 'win32/usr/bin/' directory in - http://win32.libav.org/releases/libav-9.13-win32.7z + - all the '*.dll' files in the 'bin/' directory from + https://ffmpeg.zeranoe.com/builds/win32/shared/ffmpeg-3.4.2-win32-shared.zip + - 'am7xxx-modeswitch.exe', 'am7xxx-play.exe', 'libam7xxx.dll' and 'picoproj.exe' which can all be built by following the instructions in the diff --git a/cmake_modules/mingw_cross_toolchain.cmake b/cmake_modules/mingw_cross_toolchain.cmake index e3ae052..2b6bb35 100644 --- a/cmake_modules/mingw_cross_toolchain.cmake +++ b/cmake_modules/mingw_cross_toolchain.cmake @@ -3,8 +3,9 @@ include(CMakeForceCompiler) IF("${GNU_HOST}" STREQUAL "") SET(GNU_HOST i586-mingw32msvc) ENDIF() -# Prefix detection only works with compiler id "GNU" -CMAKE_FORCE_C_COMPILER(${GNU_HOST}-gcc GNU) + +SET(CMAKE_C_COMPILER ${GNU_HOST}-gcc) + # CMake doesn't automatically look for prefixed 'windres', do it manually: SET(CMAKE_RC_COMPILER ${GNU_HOST}-windres) diff --git a/contrib/howto-picopix.asciidoc b/contrib/howto-picopix.asciidoc new file mode 100644 index 0000000..1e1e3e4 --- /dev/null +++ b/contrib/howto-picopix.asciidoc @@ -0,0 +1,117 @@ +HOW-TO use a PicoPix on GNU/Linux +================================= + +Philips/SagemCom pico projectors, like for instance the PicoPix 2055, usually +have a WVGA (854 x 480 pixels) native resolution, however they can be used to +project other resolutions if the software rescales the image. + +First, update your system and download the free libam7xxx library and the +related programs. + +On Debian and Ubuntu systems this can be done with the following commands: + + sudo apt-get update + sudo apt-get install libam7xxx0.1-bin + +Plug your PicoPix into one or two USB slots of your personal computer +(sometimes the second USB port is needed to ensure that the PicoPix has enough +power). + +Wait for Philips logo to appear. + +After the logo has disappeared, execute the following command in a terminal: + + am7xxx-play -f x11grab -i :0.0 + +The video projection is on. + +You can have two simple scripts to execute and terminate the program from +a graphical interface. + +PicoPix-START.sh: + + #!/bin/sh + am7xxx-play -f x11grab -i :0.0 -p 1 -z 0 + + +PicoPix-STOP.sh: + + #!/bin/sh + killall am7xxx-play + am7xxx-play -f x11grab -i :0.0 -p 0 -z 1 & + sleep 1 + killall am7xxx-play + + +Save the shell scripts from above in files, and give the execute permissions +to the owner (or user group) via the command line or via the graphical +interface +(http://sourcedigit.com/20111-how-to-run-a-shell-file-in-ubuntu-run-sh-file-in-ubuntu/). +You will then be able to execute the file by double-clicking on it. + +If you want to specify a particular resolution you can pass it as a command +line option: + + am7xxx-play -f x11grab -i :0.0 -o video_size=1280x768 + +When doing so you may notice that your PicoPix does not fully displays the +content of your desktop screen, which can be truncated at the bottom and at +the right. This is because of the WXGA (1280 x 768 pixels) resolution may be +different from your personal computer screen resolution. It is therefore +necessary to modify —temporarily— your personal computer screen resolution to +wanted resolution. + +Take the following script: + + #!/bin/sh + + WIDTH=1280 + HEIGHT=768 + + OUTPUT="LVDS-1" # See 'xrandr --listmonitors' + + xrandr --newmode $(gtf ${WIDTH} ${HEIGHT} 60 | sed -ne 's/"//g;s/ Modeline //p') + xrandr --addmode ${OUTPUT} ${WIDTH}x${HEIGHT}_60.00 + xrandr --output ${OUTPUT} --mode ${WIDTH}x${HEIGHT}_60.00 + sleep 1 + am7xxx-play -f x11grab -i :0.0 -p 1 -z 0 -o video_size=${WIDTH}x${HEIGHT} + +Note: + +In the example above, the personal computer screen is identified as "LVDS-1". +Maybe your computer screen has a different identifier. In this case, you will +have to replace "LVDS-1" with the correct identifier: open your terminal, +type "xrandr" and the terminal will list and describe your different screen +devices (more about xrandr utility here: +http://pkg-xorg.alioth.debian.org/howto/use-xrandr.html). + +Also, in order to give back your computer screen its original resolution, you +should create a PicoPix-STOP.sh script like the following: + + #!/bin/sh + + ORIGINAL_WIDTH=1600 + ORIGINAL_HEIGHT=900 + + OUTPUT="LVDS-1" # See 'xrandr --listmonitors' + + killall am7xxx-play + am7xxx-play -f x11grab -i :0.0 -p 0 -z 1 & + sleep 1 + killall am7xxx-play + xrandr --output ${OUTPUT} --mode ${ORIGINAL_WIDTH}x${ORIGINAL_HEIGHT} + +Note: + +In the example above, the original screen resolution is 1600x900 pixels. You +have to change this value and put your screen resolution value which you can +know via xrandr. Same for LVDS-1. + +Once your video projection is over, you can execute the PicoPix-STOP.sh script +so that your computer screen returns to its original state. + +You can then unplug the projector. + +That's all folks! + +This text is licensed under WTFPL. See http://www.wtfpl.net/ for more informations. diff --git a/contrib/libam7xxx-compile-on-Ubuntu-14.04-LTS.diff b/contrib/libam7xxx-compile-on-Ubuntu-14.04-LTS.diff new file mode 100644 index 0000000..d8b6b6f --- /dev/null +++ b/contrib/libam7xxx-compile-on-Ubuntu-14.04-LTS.diff @@ -0,0 +1,401 @@ +diff --git a/examples/am7xxx-modeswitch.c b/examples/am7xxx-modeswitch.c +index c304515..4f132d6 100644 +--- a/examples/am7xxx-modeswitch.c ++++ b/examples/am7xxx-modeswitch.c +@@ -46,7 +46,7 @@ int main(void) + goto out; + } + +- libusb_set_debug(NULL, LIBUSB_LOG_LEVEL_INFO); ++ libusb_set_debug(NULL, 3); + + usb_device = libusb_open_device_with_vid_pid(NULL, + AM7XXX_STORAGE_VID, +diff --git a/examples/am7xxx-play.c b/examples/am7xxx-play.c +index 81aff84..1ee42e0 100644 +--- a/examples/am7xxx-play.c ++++ b/examples/am7xxx-play.c +@@ -31,7 +31,6 @@ + + #include + #include +-#include + #include + + #include +@@ -51,10 +50,10 @@ static int video_input_init(struct video_input_ctx *input_ctx, + { + AVInputFormat *input_format = NULL; + AVFormatContext *input_format_ctx; +- AVCodecParameters *input_codec_params; + AVCodecContext *input_codec_ctx; + AVCodec *input_codec; + int video_index; ++ unsigned int i; + int ret; + + avdevice_register_all(); +@@ -99,32 +98,34 @@ static int video_input_init(struct video_input_ctx *input_ctx, + av_dump_format(input_format_ctx, 0, input_path, 0); + + /* look for the first video_stream */ +- video_index = av_find_best_stream(input_format_ctx, AVMEDIA_TYPE_VIDEO, -1, -1, &input_codec, 0); +- if (video_index < 0) { ++ video_index = -1; ++ for (i = 0; i < input_format_ctx->nb_streams; i++) ++ if (input_format_ctx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO) { ++ video_index = i; ++ break; ++ } ++ if (video_index == -1) { + fprintf(stderr, "cannot find any video streams\n"); + ret = -EINVAL; + goto cleanup; + } + +- input_codec_ctx = avcodec_alloc_context3(input_codec); +- if (input_codec_ctx == NULL) { +- fprintf(stderr, "failed to allocate the input codec context\n"); +- ret = -ENOMEM; +- goto cleanup; +- } ++ /* get a pointer to the codec context for the video stream */ ++ input_codec_ctx = input_format_ctx->streams[video_index]->codec; + +- input_codec_params = input_format_ctx->streams[video_index]->codecpar; +- ret = avcodec_parameters_to_context(input_codec_ctx, input_codec_params); +- if (ret < 0) { +- fprintf(stderr, "cannot copy parameters to input codec context\n"); +- goto cleanup_ctx; ++ /* find the decoder for the video stream */ ++ input_codec = avcodec_find_decoder(input_codec_ctx->codec_id); ++ if (input_codec == NULL) { ++ fprintf(stderr, "input_codec is NULL!\n"); ++ ret = -EINVAL; ++ goto cleanup; + } + + /* open the decoder */ + ret = avcodec_open2(input_codec_ctx, input_codec, NULL); + if (ret < 0) { + fprintf(stderr, "cannot open input codec\n"); +- goto cleanup_ctx; ++ goto cleanup; + } + + input_ctx->format_ctx = input_format_ctx; +@@ -134,8 +135,6 @@ static int video_input_init(struct video_input_ctx *input_ctx, + ret = 0; + goto out; + +-cleanup_ctx: +- avcodec_free_context(&input_codec_ctx); + cleanup: + avformat_close_input(&input_format_ctx); + out: +@@ -177,7 +176,7 @@ static int video_output_init(struct video_output_ctx *output_ctx, + goto out; + } + +- /* Calculate the new output dimension so the original frame is shown ++ /* Calculate the new output dimension so the original picture is shown + * in its entirety */ + ret = am7xxx_calc_scaled_image_dimensions(dev, + upscale, +@@ -226,7 +225,7 @@ static int video_output_init(struct video_output_ctx *output_ctx, + output_codec_ctx->qmin = output_codec_ctx->qmax = ((100 - (quality - 1)) * FF_QUALITY_SCALE) / 100; + output_codec_ctx->mb_lmin = output_codec_ctx->qmin * FF_QP2LAMBDA; + output_codec_ctx->mb_lmax = output_codec_ctx->qmax * FF_QP2LAMBDA; +- output_codec_ctx->flags |= AV_CODEC_FLAG_QSCALE; ++ output_codec_ctx->flags |= CODEC_FLAG_QSCALE; + output_codec_ctx->global_quality = output_codec_ctx->qmin * FF_QP2LAMBDA; + + /* find the encoder */ +@@ -257,67 +256,6 @@ out: + } + + +-/* +- * Wrap the new avcodec API from FFMpeg 3.1 to minimize the changes in the +- * user code. +- * +- * If the use of the wrappers were to be made conditional, a check like the +- * following could be used: +- * +- * #if (LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 48, 101)) +- * +- * As derived from the APIchanges document: +- * https://github.com/FFmpeg/FFmpeg/blob/master/doc/APIchanges +- * +- * The wrapper implementation has been taken from: +- * https://blogs.gentoo.org/lu_zero/2016/03/29/new-avcodec-api/ +- */ +-static int decode(AVCodecContext *avctx, AVFrame *frame, int *got_frame, AVPacket *pkt) +-{ +- int ret; +- +- *got_frame = 0; +- +- if (pkt) { +- ret = avcodec_send_packet(avctx, pkt); +- /* +- * In particular, we don't expect AVERROR(EAGAIN), because we +- * read all decoded frames with avcodec_receive_frame() until +- * done. +- */ +- if (ret < 0) +- return ret == AVERROR_EOF ? 0 : ret; +- } +- +- ret = avcodec_receive_frame(avctx, frame); +- if (ret < 0 && ret != AVERROR(EAGAIN) && ret != AVERROR_EOF) +- return ret; +- if (ret >= 0) +- *got_frame = 1; +- +- return 0; +-} +- +-static int encode(AVCodecContext *avctx, AVPacket *pkt, int *got_packet, AVFrame *frame) +-{ +- int ret; +- +- *got_packet = 0; +- +- ret = avcodec_send_frame(avctx, frame); +- if (ret < 0) +- return ret; +- +- ret = avcodec_receive_packet(avctx, pkt); +- if (!ret) +- *got_packet = 1; +- if (ret == AVERROR(EAGAIN)) +- return 0; +- +- return ret; +-} +- +- + static int am7xxx_play(const char *input_format_string, + AVDictionary **input_options, + const char *input_path, +@@ -330,16 +268,16 @@ static int am7xxx_play(const char *input_format_string, + { + struct video_input_ctx input_ctx; + struct video_output_ctx output_ctx; +- AVFrame *frame_raw; +- AVFrame *frame_scaled; ++ AVFrame *picture_raw; ++ AVFrame *picture_scaled; + int out_buf_size; + uint8_t *out_buf; +- int out_frame_size; +- uint8_t *out_frame; ++ int out_picture_size; ++ uint8_t *out_picture; + struct SwsContext *sw_scale_ctx; + AVPacket in_packet; + AVPacket out_packet; +- int got_frame; ++ int got_picture; + int got_packet; + int ret; + +@@ -356,44 +294,41 @@ static int am7xxx_play(const char *input_format_string, + } + + /* allocate an input frame */ +- frame_raw = av_frame_alloc(); +- if (frame_raw == NULL) { +- fprintf(stderr, "cannot allocate the raw frame!\n"); ++ picture_raw = avcodec_alloc_frame(); ++ if (picture_raw == NULL) { ++ fprintf(stderr, "cannot allocate the raw picture frame!\n"); + ret = -ENOMEM; + goto cleanup_output; + } + + /* allocate output frame */ +- frame_scaled = av_frame_alloc(); +- if (frame_scaled == NULL) { +- fprintf(stderr, "cannot allocate the scaled frame!\n"); ++ picture_scaled = avcodec_alloc_frame(); ++ if (picture_scaled == NULL) { ++ fprintf(stderr, "cannot allocate the scaled picture!\n"); + ret = -ENOMEM; +- goto cleanup_frame_raw; ++ goto cleanup_picture_raw; + } +- frame_scaled->format = (output_ctx.codec_ctx)->pix_fmt; +- frame_scaled->width = (output_ctx.codec_ctx)->width; +- frame_scaled->height = (output_ctx.codec_ctx)->height; ++ picture_scaled->format = (output_ctx.codec_ctx)->pix_fmt; ++ picture_scaled->width = (output_ctx.codec_ctx)->width; ++ picture_scaled->height = (output_ctx.codec_ctx)->height; + + /* calculate the bytes needed for the output image and create buffer for the output image */ +- out_buf_size = av_image_get_buffer_size((output_ctx.codec_ctx)->pix_fmt, +- (output_ctx.codec_ctx)->width, +- (output_ctx.codec_ctx)->height, +- 1); ++ out_buf_size = avpicture_get_size((output_ctx.codec_ctx)->pix_fmt, ++ (output_ctx.codec_ctx)->width, ++ (output_ctx.codec_ctx)->height); + out_buf = av_malloc(out_buf_size * sizeof(uint8_t)); + if (out_buf == NULL) { + fprintf(stderr, "cannot allocate output data buffer!\n"); + ret = -ENOMEM; +- goto cleanup_frame_scaled; ++ goto cleanup_picture_scaled; + } + +- /* assign appropriate parts of buffer to image planes in frame_scaled */ +- av_image_fill_arrays(frame_scaled->data, +- frame_scaled->linesize, +- out_buf, +- (output_ctx.codec_ctx)->pix_fmt, +- (output_ctx.codec_ctx)->width, +- (output_ctx.codec_ctx)->height, +- 1); ++ /* assign appropriate parts of buffer to image planes in picture_scaled */ ++ avpicture_fill((AVPicture *)picture_scaled, ++ out_buf, ++ (output_ctx.codec_ctx)->pix_fmt, ++ (output_ctx.codec_ctx)->width, ++ (output_ctx.codec_ctx)->height); + + sw_scale_ctx = sws_getCachedContext(NULL, + (input_ctx.codec_ctx)->width, +@@ -430,8 +365,8 @@ static int am7xxx_play(const char *input_format_string, + } + + /* decode */ +- got_frame = 0; +- ret = decode(input_ctx.codec_ctx, frame_raw, &got_frame, &in_packet); ++ got_picture = 0; ++ ret = avcodec_decode_video2(input_ctx.codec_ctx, picture_raw, &got_picture, &in_packet); + if (ret < 0) { + fprintf(stderr, "cannot decode video\n"); + run = 0; +@@ -439,41 +374,41 @@ static int am7xxx_play(const char *input_format_string, + } + + /* if we got the complete frame */ +- if (got_frame) { ++ if (got_picture) { + /* +- * Rescaling the frame also changes its pixel format ++ * Rescaling the picture also changes its pixel format + * to the raw format supported by the projector if + * this was set in video_output_init() + */ + sws_scale(sw_scale_ctx, +- (const uint8_t * const *)frame_raw->data, +- frame_raw->linesize, ++ (const uint8_t * const *)picture_raw->data, ++ picture_raw->linesize, + 0, + (input_ctx.codec_ctx)->height, +- frame_scaled->data, +- frame_scaled->linesize); ++ picture_scaled->data, ++ picture_scaled->linesize); + + if (output_ctx.raw_output) { +- out_frame = out_buf; +- out_frame_size = out_buf_size; ++ out_picture = out_buf; ++ out_picture_size = out_buf_size; + } else { +- frame_scaled->quality = (output_ctx.codec_ctx)->global_quality; ++ picture_scaled->quality = (output_ctx.codec_ctx)->global_quality; + av_init_packet(&out_packet); + out_packet.data = NULL; + out_packet.size = 0; + got_packet = 0; +- ret = encode(output_ctx.codec_ctx, +- &out_packet, +- &got_packet, +- frame_scaled); ++ ret = avcodec_encode_video2(output_ctx.codec_ctx, ++ &out_packet, ++ picture_scaled, ++ &got_packet); + if (ret < 0 || !got_packet) { + fprintf(stderr, "cannot encode video\n"); + run = 0; + goto end_while; + } + +- out_frame = out_packet.data; +- out_frame_size = out_packet.size; ++ out_picture = out_packet.data; ++ out_picture_size = out_packet.size; + } + + #ifdef DEBUG +@@ -485,7 +420,7 @@ static int am7xxx_play(const char *input_format_string, + else + snprintf(filename, NAME_MAX, "out.raw"); + file = fopen(filename, "wb"); +- fwrite(out_frame, 1, out_frame_size, file); ++ fwrite(out_picture, 1, out_picture_size, file); + fclose(file); + } + #else +@@ -496,8 +431,8 @@ static int am7xxx_play(const char *input_format_string, + image_format, + (output_ctx.codec_ctx)->width, + (output_ctx.codec_ctx)->height, +- out_frame, +- out_frame_size); ++ out_picture, ++ out_picture_size); + if (ret < 0) { + perror("am7xxx_send_image_async"); + run = 0; +@@ -506,17 +441,17 @@ static int am7xxx_play(const char *input_format_string, + } + end_while: + if (!output_ctx.raw_output && got_packet) +- av_packet_unref(&out_packet); +- av_packet_unref(&in_packet); ++ av_free_packet(&out_packet); ++ av_free_packet(&in_packet); + } + + sws_freeContext(sw_scale_ctx); + cleanup_out_buf: + av_free(out_buf); +-cleanup_frame_scaled: +- av_frame_free(&frame_scaled); +-cleanup_frame_raw: +- av_frame_free(&frame_raw); ++cleanup_picture_scaled: ++ avcodec_free_frame(&picture_scaled); ++cleanup_picture_raw: ++ avcodec_free_frame(&picture_raw); + + cleanup_output: + /* Freeing the codec context is needed as well, +@@ -527,7 +462,6 @@ cleanup_output: + + cleanup_input: + avcodec_close(input_ctx.codec_ctx); +- avcodec_free_context(&(input_ctx.codec_ctx)); + avformat_close_input(&(input_ctx.format_ctx)); + + out: +diff --git a/src/am7xxx.c b/src/am7xxx.c +index 8573a59..fd726af 100644 +--- a/src/am7xxx.c ++++ b/src/am7xxx.c +@@ -1117,7 +1117,7 @@ AM7XXX_PUBLIC int am7xxx_init(am7xxx_context **ctx) + goto out_free_context; + } + +- libusb_set_debug((*ctx)->usb_context, LIBUSB_LOG_LEVEL_INFO); ++ libusb_set_debug((*ctx)->usb_context, 3); + + ret = scan_devices(*ctx, SCAN_OP_BUILD_DEVLIST , 0, NULL); + if (ret < 0) { diff --git a/contrib/performance/0001-Instrument-code-with-fps-meter.patch b/contrib/performance/0001-Instrument-code-with-fps-meter.patch index ef81acb..1a74b76 100644 --- a/contrib/performance/0001-Instrument-code-with-fps-meter.patch +++ b/contrib/performance/0001-Instrument-code-with-fps-meter.patch @@ -1,4 +1,4 @@ -From ab3f910957638300224f1f114df6e73115ec86b7 Mon Sep 17 00:00:00 2001 +From bf1163a19667377a1861b38fa64a8cf7ee2d0e40 Mon Sep 17 00:00:00 2001 From: Antonio Ospite Date: Tue, 17 Nov 2015 16:28:03 +0100 Subject: [PATCH] Instrument code with fps-meter @@ -9,42 +9,30 @@ X-Face: z*RaLf`X<@C75u6Ig9}{oW$H;1_\2t5)({*|jhM/Vb;]yA5 #include +#include "fps-meter.h" - /* On some systems ENOTSUP is not defined, fallback to its value on - * linux which is equal to EOPNOTSUPP which is 95 -@@ -293,6 +294,7 @@ static int am7xxx_play(const char *input_format_string, - int got_picture; + static unsigned int run = 1; + +@@ -342,6 +343,7 @@ static int am7xxx_play(const char *input_format_string, + int got_frame; int got_packet; int ret; + struct fps_meter_stats stats; ret = video_input_init(&input_ctx, input_format_string, input_path, input_options); if (ret < 0) { -@@ -358,6 +360,8 @@ static int am7xxx_play(const char *input_format_string, +@@ -410,6 +412,8 @@ static int am7xxx_play(const char *input_format_string, goto cleanup_out_buf; } @@ -53,7 +41,7 @@ index 6b0d206..271677b 100644 got_packet = 0; while (run) { /* read packet */ -@@ -447,6 +451,7 @@ static int am7xxx_play(const char *input_format_string, +@@ -503,6 +507,7 @@ static int am7xxx_play(const char *input_format_string, run = 0; goto end_while; } @@ -62,5 +50,5 @@ index 6b0d206..271677b 100644 end_while: if (!output_ctx.raw_output && got_packet) -- -2.6.2 +2.16.2 diff --git a/doc/Doxyfile.in b/doc/Doxyfile.in index fa85ae9..60d1fba 100644 --- a/doc/Doxyfile.in +++ b/doc/Doxyfile.in @@ -1,4 +1,4 @@ -# Doxyfile 1.8.8 +# Doxyfile 1.8.13 #--------------------------------------------------------------------------- # Project related configuration options @@ -35,12 +35,14 @@ OPTIMIZE_FOR_FORTRAN = NO OPTIMIZE_OUTPUT_VHDL = NO EXTENSION_MAPPING = MARKDOWN_SUPPORT = YES +TOC_INCLUDE_HEADINGS = 0 AUTOLINK_SUPPORT = YES BUILTIN_STL_SUPPORT = NO CPP_CLI_SUPPORT = NO SIP_SUPPORT = NO IDL_PROPERTY_SUPPORT = YES DISTRIBUTE_GROUP_DOC = NO +GROUP_NESTED_COMPOUNDS = NO SUBGROUPING = YES INLINE_GROUPED_CLASSES = NO INLINE_SIMPLE_STRUCTS = NO @@ -63,6 +65,7 @@ HIDE_IN_BODY_DOCS = NO INTERNAL_DOCS = NO CASE_SENSE_NAMES = YES HIDE_SCOPE_NAMES = NO +HIDE_COMPOUND_REFERENCE= NO SHOW_INCLUDE_FILES = YES SHOW_GROUPED_MEMB_INC = NO FORCE_LOCAL_INCLUDES = NO @@ -93,6 +96,7 @@ WARNINGS = YES WARN_IF_UNDOCUMENTED = YES WARN_IF_DOC_ERROR = YES WARN_NO_PARAMDOC = NO +WARN_AS_ERROR = NO WARN_FORMAT = "$file:$line: $text" WARN_LOGFILE = #--------------------------------------------------------------------------- @@ -209,6 +213,7 @@ PAPER_TYPE = a4 EXTRA_PACKAGES = LATEX_HEADER = LATEX_FOOTER = +LATEX_EXTRA_STYLESHEET = LATEX_EXTRA_FILES = PDF_HYPERLINKS = YES USE_PDFLATEX = YES @@ -216,6 +221,7 @@ LATEX_BATCHMODE = NO LATEX_HIDE_INDICES = NO LATEX_SOURCE_CODE = NO LATEX_BIB_STYLE = plain +LATEX_TIMESTAMP = NO #--------------------------------------------------------------------------- # Configuration options related to the RTF output #--------------------------------------------------------------------------- @@ -225,6 +231,7 @@ COMPACT_RTF = NO RTF_HYPERLINKS = NO RTF_STYLESHEET_FILE = RTF_EXTENSIONS_FILE = +RTF_SOURCE_CODE = NO #--------------------------------------------------------------------------- # Configuration options related to the man page output #--------------------------------------------------------------------------- @@ -308,6 +315,8 @@ DOTFILE_DIRS = MSCFILE_DIRS = DIAFILE_DIRS = PLANTUML_JAR_PATH = +PLANTUML_CFG_FILE = +PLANTUML_INCLUDE_PATH = DOT_GRAPH_MAX_NODES = 50 MAX_DOT_GRAPH_DEPTH = 0 DOT_TRANSPARENT = NO diff --git a/doc/lsusb_dumps/lsusb_Philips-PicoPix-2330-2340.log b/doc/lsusb_dumps/lsusb_Philips-PicoPix-2330-2340.log new file mode 100644 index 0000000..3a7c3dc --- /dev/null +++ b/doc/lsusb_dumps/lsusb_Philips-PicoPix-2330-2340.log @@ -0,0 +1,68 @@ + +Bus 002 Device 004: ID 21e7:0019 +Device Descriptor: + bLength 18 + bDescriptorType 1 + bcdUSB 2.00 + bDeviceClass 255 Vendor Specific Class + bDeviceSubClass 0 + bDeviceProtocol 0 + bMaxPacketSize0 64 + idVendor 0x21e7 + idProduct 0x0019 + bcdDevice 0.00 + iManufacturer 1 actions-micro + iProduct 2 actions-subdisplay + iSerial 3 00000000000000000000000000000000 + bNumConfigurations 1 + Configuration Descriptor: + bLength 9 + bDescriptorType 2 + wTotalLength 32 + bNumInterfaces 1 + bConfigurationValue 1 + iConfiguration 4 Self-powered + bmAttributes 0xc0 + Self Powered + MaxPower 2mA + Interface Descriptor: + bLength 9 + bDescriptorType 4 + bInterfaceNumber 0 + bAlternateSetting 0 + bNumEndpoints 2 + bInterfaceClass 255 Vendor Specific Class + bInterfaceSubClass 0 + bInterfaceProtocol 0 + iInterface 5 vendor subdisp + Endpoint Descriptor: + bLength 7 + bDescriptorType 5 + bEndpointAddress 0x81 EP 1 IN + bmAttributes 2 + Transfer Type Bulk + Synch Type None + Usage Type Data + wMaxPacketSize 0x0200 1x 512 bytes + bInterval 0 + Endpoint Descriptor: + bLength 7 + bDescriptorType 5 + bEndpointAddress 0x01 EP 1 OUT + bmAttributes 2 + Transfer Type Bulk + Synch Type None + Usage Type Data + wMaxPacketSize 0x0200 1x 512 bytes + bInterval 1 +Device Qualifier (for other device speed): + bLength 10 + bDescriptorType 6 + bcdUSB 2.00 + bDeviceClass 0 (Defined at Interface level) + bDeviceSubClass 0 + bDeviceProtocol 0 + bMaxPacketSize0 64 + bNumConfigurations 1 +Device Status: 0x0001 + Self Powered diff --git a/doc/lsusb_dumps/lsusb_Philips-PicoPix-2330.log b/doc/lsusb_dumps/lsusb_Philips-PicoPix-2330.log deleted file mode 100644 index 3a7c3dc..0000000 --- a/doc/lsusb_dumps/lsusb_Philips-PicoPix-2330.log +++ /dev/null @@ -1,68 +0,0 @@ - -Bus 002 Device 004: ID 21e7:0019 -Device Descriptor: - bLength 18 - bDescriptorType 1 - bcdUSB 2.00 - bDeviceClass 255 Vendor Specific Class - bDeviceSubClass 0 - bDeviceProtocol 0 - bMaxPacketSize0 64 - idVendor 0x21e7 - idProduct 0x0019 - bcdDevice 0.00 - iManufacturer 1 actions-micro - iProduct 2 actions-subdisplay - iSerial 3 00000000000000000000000000000000 - bNumConfigurations 1 - Configuration Descriptor: - bLength 9 - bDescriptorType 2 - wTotalLength 32 - bNumInterfaces 1 - bConfigurationValue 1 - iConfiguration 4 Self-powered - bmAttributes 0xc0 - Self Powered - MaxPower 2mA - Interface Descriptor: - bLength 9 - bDescriptorType 4 - bInterfaceNumber 0 - bAlternateSetting 0 - bNumEndpoints 2 - bInterfaceClass 255 Vendor Specific Class - bInterfaceSubClass 0 - bInterfaceProtocol 0 - iInterface 5 vendor subdisp - Endpoint Descriptor: - bLength 7 - bDescriptorType 5 - bEndpointAddress 0x81 EP 1 IN - bmAttributes 2 - Transfer Type Bulk - Synch Type None - Usage Type Data - wMaxPacketSize 0x0200 1x 512 bytes - bInterval 0 - Endpoint Descriptor: - bLength 7 - bDescriptorType 5 - bEndpointAddress 0x01 EP 1 OUT - bmAttributes 2 - Transfer Type Bulk - Synch Type None - Usage Type Data - wMaxPacketSize 0x0200 1x 512 bytes - bInterval 1 -Device Qualifier (for other device speed): - bLength 10 - bDescriptorType 6 - bcdUSB 2.00 - bDeviceClass 0 (Defined at Interface level) - bDeviceSubClass 0 - bDeviceProtocol 0 - bMaxPacketSize0 64 - bNumConfigurations 1 -Device Status: 0x0001 - Self Powered diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index c563f5f..d44a26f 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -1,7 +1,5 @@ include(CheckSymbolExists) -add_definitions("-D_POSIX_C_SOURCE=2") # for getopt() -add_definitions("-D_POSIX_SOURCE") # for sigaction -add_definitions("-D_BSD_SOURCE") # for strdup +add_definitions("-D_POSIX_C_SOURCE=200809L") # for getopt(), sigaction(), and strdup() include_directories(${CMAKE_SOURCE_DIR}/src/) @@ -18,10 +16,10 @@ endif() option(BUILD_AM7XXX-PLAY "Build a more complete example: am7xxx-play" TRUE) if(BUILD_AM7XXX-PLAY) find_package(FFmpeg REQUIRED) - set(CMAKE_REQUIRED_LIBRARIES ${FFMPEG_LIBRARIES}) + set(CMAKE_REQUIRED_LIBRARIES ${FFMPEG_LIBAVFORMAT_LIBRARIES}) set(CMAKE_REQUIRED_INCLUDES ${FFMPEG_LIBAVFORMAT_INCLUDE_DIRS}) check_symbol_exists(avformat_open_input - "${FFMPEG_LIBAVFORMAT_INCLUDE_DIRS}/libavformat/avformat.h" + "libavformat/avformat.h" HAVE_AVFORMAT_OPEN_INPUT) if(NOT HAVE_AVFORMAT_OPEN_INPUT) message(FATAL_ERROR diff --git a/examples/am7xxx-modeswitch.c b/examples/am7xxx-modeswitch.c index 793130e..c304515 100644 --- a/examples/am7xxx-modeswitch.c +++ b/examples/am7xxx-modeswitch.c @@ -88,7 +88,8 @@ int main(void) goto out_libusb_close; } - /* Checking that the configuration has not changed, as suggested in + /* + * Checking that the configuration has not changed, as suggested in * http://libusb.sourceforge.net/api-1.0/caveats.html */ current_configuration = -1; @@ -100,7 +101,7 @@ int main(void) } if (current_configuration != AM7XXX_STORAGE_CONFIGURATION) { - fprintf(stderr, "libusb configuration changed (expected: %d, current: %d\n", + fprintf(stderr, "libusb configuration changed (expected: %d, current: %d)\n", AM7XXX_STORAGE_CONFIGURATION, current_configuration); ret = -EINVAL; goto out_libusb_release_interface; diff --git a/examples/am7xxx-play.c b/examples/am7xxx-play.c index 6b0d206..81aff84 100644 --- a/examples/am7xxx-play.c +++ b/examples/am7xxx-play.c @@ -31,17 +31,11 @@ #include #include +#include #include #include -/* On some systems ENOTSUP is not defined, fallback to its value on - * linux which is equal to EOPNOTSUPP which is 95 - */ -#ifndef ENOTSUP -#define ENOTSUP 95 -#endif - static unsigned int run = 1; struct video_input_ctx { @@ -57,10 +51,10 @@ static int video_input_init(struct video_input_ctx *input_ctx, { AVInputFormat *input_format = NULL; AVFormatContext *input_format_ctx; + AVCodecParameters *input_codec_params; AVCodecContext *input_codec_ctx; AVCodec *input_codec; int video_index; - unsigned int i; int ret; avdevice_register_all(); @@ -105,40 +99,32 @@ static int video_input_init(struct video_input_ctx *input_ctx, av_dump_format(input_format_ctx, 0, input_path, 0); /* look for the first video_stream */ - video_index = -1; - for (i = 0; i < input_format_ctx->nb_streams; i++) - if (input_format_ctx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO) { - video_index = i; - break; - } - if (video_index == -1) { + video_index = av_find_best_stream(input_format_ctx, AVMEDIA_TYPE_VIDEO, -1, -1, &input_codec, 0); + if (video_index < 0) { fprintf(stderr, "cannot find any video streams\n"); - ret = -ENOTSUP; + ret = -EINVAL; goto cleanup; } - /* get a pointer to the codec context for the video stream */ - input_codec_ctx = input_format_ctx->streams[video_index]->codec; + input_codec_ctx = avcodec_alloc_context3(input_codec); if (input_codec_ctx == NULL) { - fprintf(stderr, "input codec context is not valid\n"); - ret = -ENOTSUP; + fprintf(stderr, "failed to allocate the input codec context\n"); + ret = -ENOMEM; goto cleanup; } - /* find the decoder for the video stream */ - input_codec = avcodec_find_decoder(input_codec_ctx->codec_id); - if (input_codec == NULL) { - fprintf(stderr, "input_codec is NULL!\n"); - ret = -ENOTSUP; - goto cleanup; + input_codec_params = input_format_ctx->streams[video_index]->codecpar; + ret = avcodec_parameters_to_context(input_codec_ctx, input_codec_params); + if (ret < 0) { + fprintf(stderr, "cannot copy parameters to input codec context\n"); + goto cleanup_ctx; } /* open the decoder */ ret = avcodec_open2(input_codec_ctx, input_codec, NULL); if (ret < 0) { fprintf(stderr, "cannot open input codec\n"); - ret = -ENOTSUP; - goto cleanup; + goto cleanup_ctx; } input_ctx->format_ctx = input_format_ctx; @@ -148,6 +134,8 @@ static int video_input_init(struct video_input_ctx *input_ctx, ret = 0; goto out; +cleanup_ctx: + avcodec_free_context(&input_codec_ctx); cleanup: avformat_close_input(&input_format_ctx); out: @@ -189,7 +177,7 @@ static int video_output_init(struct video_output_ctx *output_ctx, goto out; } - /* Calculate the new output dimension so the original picture is shown + /* Calculate the new output dimension so the original frame is shown * in its entirety */ ret = am7xxx_calc_scaled_image_dimensions(dev, upscale, @@ -223,6 +211,7 @@ static int video_output_init(struct video_output_ctx *output_ctx, goto out; } + /* YUVJ420P is deprecated in swscaler, but mjpeg still relies on it. */ output_codec_ctx->pix_fmt = AV_PIX_FMT_YUVJ420P; output_codec_ctx->codec_id = AV_CODEC_ID_MJPEG; output_codec_ctx->codec_type = AVMEDIA_TYPE_VIDEO; @@ -237,14 +226,14 @@ static int video_output_init(struct video_output_ctx *output_ctx, output_codec_ctx->qmin = output_codec_ctx->qmax = ((100 - (quality - 1)) * FF_QUALITY_SCALE) / 100; output_codec_ctx->mb_lmin = output_codec_ctx->qmin * FF_QP2LAMBDA; output_codec_ctx->mb_lmax = output_codec_ctx->qmax * FF_QP2LAMBDA; - output_codec_ctx->flags |= CODEC_FLAG_QSCALE; + output_codec_ctx->flags |= AV_CODEC_FLAG_QSCALE; output_codec_ctx->global_quality = output_codec_ctx->qmin * FF_QP2LAMBDA; /* find the encoder */ output_codec = avcodec_find_encoder(output_codec_ctx->codec_id); if (output_codec == NULL) { fprintf(stderr, "cannot find output codec!\n"); - ret = -ENOTSUP; + ret = -EINVAL; goto cleanup; } @@ -262,13 +251,73 @@ static int video_output_init(struct video_output_ctx *output_ctx, goto out; cleanup: - avcodec_close(output_codec_ctx); - av_free(output_codec_ctx); + avcodec_free_context(&output_codec_ctx); out: return ret; } +/* + * Wrap the new avcodec API from FFMpeg 3.1 to minimize the changes in the + * user code. + * + * If the use of the wrappers were to be made conditional, a check like the + * following could be used: + * + * #if (LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 48, 101)) + * + * As derived from the APIchanges document: + * https://github.com/FFmpeg/FFmpeg/blob/master/doc/APIchanges + * + * The wrapper implementation has been taken from: + * https://blogs.gentoo.org/lu_zero/2016/03/29/new-avcodec-api/ + */ +static int decode(AVCodecContext *avctx, AVFrame *frame, int *got_frame, AVPacket *pkt) +{ + int ret; + + *got_frame = 0; + + if (pkt) { + ret = avcodec_send_packet(avctx, pkt); + /* + * In particular, we don't expect AVERROR(EAGAIN), because we + * read all decoded frames with avcodec_receive_frame() until + * done. + */ + if (ret < 0) + return ret == AVERROR_EOF ? 0 : ret; + } + + ret = avcodec_receive_frame(avctx, frame); + if (ret < 0 && ret != AVERROR(EAGAIN) && ret != AVERROR_EOF) + return ret; + if (ret >= 0) + *got_frame = 1; + + return 0; +} + +static int encode(AVCodecContext *avctx, AVPacket *pkt, int *got_packet, AVFrame *frame) +{ + int ret; + + *got_packet = 0; + + ret = avcodec_send_frame(avctx, frame); + if (ret < 0) + return ret; + + ret = avcodec_receive_packet(avctx, pkt); + if (!ret) + *got_packet = 1; + if (ret == AVERROR(EAGAIN)) + return 0; + + return ret; +} + + static int am7xxx_play(const char *input_format_string, AVDictionary **input_options, const char *input_path, @@ -281,16 +330,16 @@ static int am7xxx_play(const char *input_format_string, { struct video_input_ctx input_ctx; struct video_output_ctx output_ctx; - AVFrame *picture_raw; - AVFrame *picture_scaled; + AVFrame *frame_raw; + AVFrame *frame_scaled; int out_buf_size; uint8_t *out_buf; - int out_picture_size; - uint8_t *out_picture; + int out_frame_size; + uint8_t *out_frame; struct SwsContext *sw_scale_ctx; AVPacket in_packet; AVPacket out_packet; - int got_picture; + int got_frame; int got_packet; int ret; @@ -307,41 +356,44 @@ static int am7xxx_play(const char *input_format_string, } /* allocate an input frame */ - picture_raw = av_frame_alloc(); - if (picture_raw == NULL) { - fprintf(stderr, "cannot allocate the raw picture frame!\n"); + frame_raw = av_frame_alloc(); + if (frame_raw == NULL) { + fprintf(stderr, "cannot allocate the raw frame!\n"); ret = -ENOMEM; goto cleanup_output; } /* allocate output frame */ - picture_scaled = av_frame_alloc(); - if (picture_scaled == NULL) { - fprintf(stderr, "cannot allocate the scaled picture!\n"); + frame_scaled = av_frame_alloc(); + if (frame_scaled == NULL) { + fprintf(stderr, "cannot allocate the scaled frame!\n"); ret = -ENOMEM; - goto cleanup_picture_raw; + goto cleanup_frame_raw; } - picture_scaled->format = (output_ctx.codec_ctx)->pix_fmt; - picture_scaled->width = (output_ctx.codec_ctx)->width; - picture_scaled->height = (output_ctx.codec_ctx)->height; + frame_scaled->format = (output_ctx.codec_ctx)->pix_fmt; + frame_scaled->width = (output_ctx.codec_ctx)->width; + frame_scaled->height = (output_ctx.codec_ctx)->height; /* calculate the bytes needed for the output image and create buffer for the output image */ - out_buf_size = avpicture_get_size((output_ctx.codec_ctx)->pix_fmt, - (output_ctx.codec_ctx)->width, - (output_ctx.codec_ctx)->height); + out_buf_size = av_image_get_buffer_size((output_ctx.codec_ctx)->pix_fmt, + (output_ctx.codec_ctx)->width, + (output_ctx.codec_ctx)->height, + 1); out_buf = av_malloc(out_buf_size * sizeof(uint8_t)); if (out_buf == NULL) { fprintf(stderr, "cannot allocate output data buffer!\n"); ret = -ENOMEM; - goto cleanup_picture_scaled; + goto cleanup_frame_scaled; } - /* assign appropriate parts of buffer to image planes in picture_scaled */ - avpicture_fill((AVPicture *)picture_scaled, - out_buf, - (output_ctx.codec_ctx)->pix_fmt, - (output_ctx.codec_ctx)->width, - (output_ctx.codec_ctx)->height); + /* assign appropriate parts of buffer to image planes in frame_scaled */ + av_image_fill_arrays(frame_scaled->data, + frame_scaled->linesize, + out_buf, + (output_ctx.codec_ctx)->pix_fmt, + (output_ctx.codec_ctx)->width, + (output_ctx.codec_ctx)->height, + 1); sw_scale_ctx = sws_getCachedContext(NULL, (input_ctx.codec_ctx)->width, @@ -378,8 +430,8 @@ static int am7xxx_play(const char *input_format_string, } /* decode */ - got_picture = 0; - ret = avcodec_decode_video2(input_ctx.codec_ctx, picture_raw, &got_picture, &in_packet); + got_frame = 0; + ret = decode(input_ctx.codec_ctx, frame_raw, &got_frame, &in_packet); if (ret < 0) { fprintf(stderr, "cannot decode video\n"); run = 0; @@ -387,37 +439,41 @@ static int am7xxx_play(const char *input_format_string, } /* if we got the complete frame */ - if (got_picture) { - /* convert it to YUV */ + if (got_frame) { + /* + * Rescaling the frame also changes its pixel format + * to the raw format supported by the projector if + * this was set in video_output_init() + */ sws_scale(sw_scale_ctx, - (const uint8_t * const *)picture_raw->data, - picture_raw->linesize, + (const uint8_t * const *)frame_raw->data, + frame_raw->linesize, 0, (input_ctx.codec_ctx)->height, - picture_scaled->data, - picture_scaled->linesize); + frame_scaled->data, + frame_scaled->linesize); if (output_ctx.raw_output) { - out_picture = out_buf; - out_picture_size = out_buf_size; + out_frame = out_buf; + out_frame_size = out_buf_size; } else { - picture_scaled->quality = (output_ctx.codec_ctx)->global_quality; + frame_scaled->quality = (output_ctx.codec_ctx)->global_quality; av_init_packet(&out_packet); out_packet.data = NULL; out_packet.size = 0; got_packet = 0; - ret = avcodec_encode_video2(output_ctx.codec_ctx, - &out_packet, - picture_scaled, - &got_packet); + ret = encode(output_ctx.codec_ctx, + &out_packet, + &got_packet, + frame_scaled); if (ret < 0 || !got_packet) { fprintf(stderr, "cannot encode video\n"); run = 0; goto end_while; } - out_picture = out_packet.data; - out_picture_size = out_packet.size; + out_frame = out_packet.data; + out_frame_size = out_packet.size; } #ifdef DEBUG @@ -429,7 +485,7 @@ static int am7xxx_play(const char *input_format_string, else snprintf(filename, NAME_MAX, "out.raw"); file = fopen(filename, "wb"); - fwrite(out_picture, 1, out_picture_size, file); + fwrite(out_frame, 1, out_frame_size, file); fclose(file); } #else @@ -440,8 +496,8 @@ static int am7xxx_play(const char *input_format_string, image_format, (output_ctx.codec_ctx)->width, (output_ctx.codec_ctx)->height, - out_picture, - out_picture_size); + out_frame, + out_frame_size); if (ret < 0) { perror("am7xxx_send_image_async"); run = 0; @@ -450,27 +506,28 @@ static int am7xxx_play(const char *input_format_string, } end_while: if (!output_ctx.raw_output && got_packet) - av_free_packet(&out_packet); - av_free_packet(&in_packet); + av_packet_unref(&out_packet); + av_packet_unref(&in_packet); } sws_freeContext(sw_scale_ctx); cleanup_out_buf: av_free(out_buf); -cleanup_picture_scaled: - av_frame_free(&picture_scaled); -cleanup_picture_raw: - av_frame_free(&picture_raw); +cleanup_frame_scaled: + av_frame_free(&frame_scaled); +cleanup_frame_raw: + av_frame_free(&frame_raw); cleanup_output: - /* av_free is needed as well, - * see http://libav.org/doxygen/master/avcodec_8h.html#a5d7440cd7ea195bd0b14f21a00ef36dd + /* Freeing the codec context is needed as well, + * see https://libav.org/documentation/doxygen/master/group__lavc__core.html#gaf4daa92361efb3523ef5afeb0b54077f */ avcodec_close(output_ctx.codec_ctx); - av_free(output_ctx.codec_ctx); + avcodec_free_context(&(output_ctx.codec_ctx)); cleanup_input: avcodec_close(input_ctx.codec_ctx); + avcodec_free_context(&(input_ctx.codec_ctx)); avformat_close_input(&(input_ctx.format_ctx)); out: @@ -548,7 +605,7 @@ static char *get_x_screen_size(const char *input_path) static char *get_x_screen_size(const char *input_path) { (void) input_path; - fprintf(stderr, "%s: fallback implementation\n", __func__); + fprintf(stderr, "%s: fallback implementation, assuming a vga screen\n", __func__); return strdup("vga"); } #endif diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index f743b1a..d6cdaad 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,5 +1,9 @@ -add_definitions("-D_BSD_SOURCE") # for htole32() -add_definitions("-D_POSIX_C_SOURCE=199309L") # for nanosleep() +add_definitions("-D_DEFAULT_SOURCE") # for htole32() +add_definitions("-D_POSIX_C_SOURCE=200112L") # for nanosleep() and lroundf() + +# Express a preference for C99 format strings when using MinGW, see: +# https://sourceforge.net/p/mingw-w64/wiki2/gnu%20printf/ +add_definitions("-D__USE_MINGW_ANSI_STDIO=1") # Find packages needed to build library find_package(libusb-1.0 REQUIRED) diff --git a/src/am7xxx.c b/src/am7xxx.c index 76df87d..8573a59 100644 --- a/src/am7xxx.c +++ b/src/am7xxx.c @@ -30,11 +30,22 @@ #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) -/* If we're not using GNU C, elide __attribute__ +/* + * If we're not using GNU C, elide __attribute__ * taken from: http://unixwiz.net/techtips/gnu-c-attributes.html) */ #ifndef __GNUC__ -# define __attribute__(x) /* NOTHING */ + #define __attribute__(x) /* NOTHING */ +#endif + +/* + * Fix printf format when compiling for Windows with MinGW, see: + * https://sourceforge.net/p/mingw-w64/wiki2/gnu%20printf/ + */ +#ifdef __MINGW_PRINTF_FORMAT + #define AM7XXX_PRINTF_FORMAT __MINGW_PRINTF_FORMAT +#else + #define AM7XXX_PRINTF_FORMAT printf #endif /* Control shared library symbols visibility */ @@ -56,7 +67,7 @@ static void log_message(am7xxx_context *ctx, const char *function_name, int line, const char *fmt, - ...) __attribute__ ((format (printf, 5, 6))); + ...) __attribute__ ((format (AM7XXX_PRINTF_FORMAT, 5, 6))); #define fatal(...) log_message(NULL, AM7XXX_LOG_FATAL, __func__, __LINE__, __VA_ARGS__) #define error(ctx, ...) log_message(ctx, AM7XXX_LOG_ERROR, __func__, __LINE__, __VA_ARGS__) @@ -414,7 +425,7 @@ static int send_data(am7xxx_device *dev, uint8_t *buffer, unsigned int len) return 0; } -static void send_data_async_complete_cb(struct libusb_transfer *transfer) +static void LIBUSB_CALL send_data_async_complete_cb(struct libusb_transfer *transfer) { am7xxx_device *dev = (am7xxx_device *)(transfer->user_data); int *completed = &(dev->transfer_completed); @@ -800,7 +811,7 @@ static int open_device(am7xxx_context *ctx, } if (current_configuration != (*dev)->desc->configuration) { - debug(ctx, "libusb configuration changed (expected: %hhu, current: %d\n", + debug(ctx, "libusb configuration changed (expected: %hhu, current: %d)\n", (*dev)->desc->configuration, current_configuration); ret = -EINVAL; goto out_libusb_release_interface; @@ -1093,8 +1104,7 @@ AM7XXX_PUBLIC int am7xxx_init(am7xxx_context **ctx) *ctx = malloc(sizeof(**ctx)); if (*ctx == NULL) { fatal("cannot allocate the context (%s)\n", strerror(errno)); - ret = -ENOMEM; - goto out; + return -ENOMEM; } memset(*ctx, 0, sizeof(**ctx)); @@ -1180,14 +1190,14 @@ AM7XXX_PUBLIC int am7xxx_open_device(am7xxx_context *ctx, am7xxx_device **dev, * is the first one to be sent to the device in order for it to * successfully return the correct device information. * - * So, if there is not a cached version of it (from a previous open), - * we ask for device info at open time, + * NOTE: am7xxx_get_device_info() will fetch the actual device info + * from the device only the very first time it's called for a given + * device, otherwise, it'll return a cached version of the device info + * (from a previous call to am7xxx_open_device(), for instance). */ - if ((*dev)->device_info == NULL) { - ret = am7xxx_get_device_info(*dev, NULL); - if (ret < 0) - error(ctx, "cannot get device info\n"); - } + ret = am7xxx_get_device_info(*dev, NULL); + if (ret < 0) + error(ctx, "cannot get device info\n"); out: return ret; @@ -1214,10 +1224,9 @@ AM7XXX_PUBLIC int am7xxx_get_device_info(am7xxx_device *dev, int ret; struct am7xxx_header h; - if (dev->device_info) { - memcpy(device_info, dev->device_info, sizeof(*device_info)); - return 0; - } + /* if there is a cached copy of the device info, just return that */ + if (dev->device_info) + goto return_value; ret = send_command(dev, AM7XXX_PACKET_TYPE_DEVINFO); if (ret < 0) @@ -1231,8 +1240,8 @@ AM7XXX_PUBLIC int am7xxx_get_device_info(am7xxx_device *dev, if (h.packet_type != AM7XXX_PACKET_TYPE_DEVINFO) { error(dev->ctx, "expected packet type: %d, got %d instead!\n", AM7XXX_PACKET_TYPE_DEVINFO, h.packet_type); - errno = ENOTSUP; - return -ENOTSUP; + errno = EINVAL; + return -EINVAL; } dev->device_info = malloc(sizeof(*dev->device_info)); @@ -1251,6 +1260,9 @@ AM7XXX_PUBLIC int am7xxx_get_device_info(am7xxx_device *dev, dev->device_info->unknown1 = h.header_data.devinfo.unknown1; #endif +return_value: + if (device_info) + memcpy(device_info, dev->device_info, sizeof(*device_info)); return 0; } @@ -1261,7 +1273,6 @@ AM7XXX_PUBLIC int am7xxx_calc_scaled_image_dimensions(am7xxx_device *dev, unsigned int *scaled_width, unsigned int *scaled_height) { - am7xxx_device_info device_info; float width_ratio; float height_ratio; diff --git a/src/tools.c b/src/tools.c index be63ac6..b9c85e1 100644 --- a/src/tools.c +++ b/src/tools.c @@ -1,6 +1,6 @@ /* am7xxx - communication with AM7xxx based USB Pico Projectors and DPFs * - * Copyright (C) 2014 Antonio Ospite + * Copyright (C) 2014-2018 Antonio Ospite * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,8 +16,12 @@ * along with this program. If not, see . */ +#ifdef _WIN32 +#include +#else #include #include +#endif #include "tools.h" @@ -30,6 +34,9 @@ */ int msleep(unsigned long msecs) { +#ifdef _WIN32 + Sleep(msecs); +#else struct timespec delay; int ret; @@ -43,6 +50,7 @@ int msleep(unsigned long msecs) } if (ret == -1) return ret; +#endif return 0; }