From 9da43e7f4d027d916e6801c57a2763c45f66fb4c Mon Sep 17 00:00:00 2001 From: Antonio Ospite Date: Fri, 5 Apr 2013 23:29:58 +0200 Subject: [PATCH 01/16] picoproj: show the image resolution when image does not fit the native one This may help spotting a missing or wrong dimension parameter on the command line. --- examples/picoproj.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/examples/picoproj.c b/examples/picoproj.c index e15b2a2..8341527 100644 --- a/examples/picoproj.c +++ b/examples/picoproj.c @@ -267,7 +267,9 @@ int main(int argc, char *argv[]) if ((unsigned int)width > device_info.native_width || (unsigned int)height > device_info.native_height) - fprintf(stderr, "WARNING: image not fitting the native resolution, it may be displayed wrongly!\n"); + fprintf(stderr, + "WARNING: image is %dx%d, not fitting the native resolution, it may be displayed wrongly!\n", + width, height); ret = am7xxx_send_image(dev, format, width, height, image, size); if (ret < 0) { -- 2.1.4 From 6d960cf72946c2f05d60dfcf8fb21efbdb69c9c7 Mon Sep 17 00:00:00 2001 From: Antonio Ospite Date: Fri, 5 Apr 2013 23:35:34 +0200 Subject: [PATCH 02/16] am7xxx: use the symbolic constant for libusb log level --- src/am7xxx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/am7xxx.c b/src/am7xxx.c index acf04a4..1f75c60 100644 --- a/src/am7xxx.c +++ b/src/am7xxx.c @@ -688,7 +688,7 @@ AM7XXX_PUBLIC int am7xxx_init(am7xxx_context **ctx) if (ret < 0) goto out_free_context; - libusb_set_debug((*ctx)->usb_context, 3); + libusb_set_debug((*ctx)->usb_context, LIBUSB_LOG_LEVEL_INFO); ret = scan_devices(*ctx, SCAN_OP_BUILD_DEVLIST , 0, NULL); if (ret < 0) { -- 2.1.4 From 3245aa702260b7ca45cef26622d9a90f6e602506 Mon Sep 17 00:00:00 2001 From: Antonio Ospite Date: Sun, 26 May 2013 23:53:13 +0200 Subject: [PATCH 03/16] CMakeLists.txt: fix enabling verbose debug output In 024af793fa6d6af644c225804d140cc13aa56307 the definition -DDEBUG=1 got lost, add it back. --- CMakeLists.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 89f0437..8264845 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -69,7 +69,8 @@ if (CMAKE_COMPILER_IS_GNUCC) --param=ssp-buffer-size=4) add_flags(DEBUG_FLAGS - -ggdb) + -ggdb + -DDEBUG=1) add_flags(RELEASE_FLAGS -Wp,-D_FORTIFY_SOURCE=2) -- 2.1.4 From 74c1a41d0765df9716732ac053df9ed7f24f38f0 Mon Sep 17 00:00:00 2001 From: Antonio Ospite Date: Mon, 27 May 2013 00:05:00 +0200 Subject: [PATCH 04/16] examples: print the usage message when a required option is missing While at it specify which option is missing when picoproj fails.. --- examples/am7xxx-play.c | 3 ++- examples/picoproj.c | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/examples/am7xxx-play.c b/examples/am7xxx-play.c index 38812a4..e958eee 100644 --- a/examples/am7xxx-play.c +++ b/examples/am7xxx-play.c @@ -777,7 +777,8 @@ int main(int argc, char *argv[]) } if (input_path == NULL) { - fprintf(stderr, "The -i option must always be passed\n"); + fprintf(stderr, "The -i option must always be passed\n\n"); + usage(argv[0]); ret = -EINVAL; goto out; } diff --git a/examples/picoproj.c b/examples/picoproj.c index 8341527..610e148 100644 --- a/examples/picoproj.c +++ b/examples/picoproj.c @@ -168,7 +168,8 @@ int main(int argc, char *argv[]) } if (filename[0] == '\0') { - fprintf(stderr, "An image file MUST be specified.\n"); + fprintf(stderr, "An image file MUST be specified with the -f option.\n\n"); + usage(argv[0]); exit_code = EXIT_FAILURE; goto out; } -- 2.1.4 From 8c35b7b5ecb4bdca110bd29adae7b5e47f141d3c Mon Sep 17 00:00:00 2001 From: Antonio Ospite Date: Mon, 27 May 2013 00:06:23 +0200 Subject: [PATCH 05/16] picoproj: remove an unneeded blank line --- examples/picoproj.c | 1 - 1 file changed, 1 deletion(-) diff --git a/examples/picoproj.c b/examples/picoproj.c index 610e148..92dbfbf 100644 --- a/examples/picoproj.c +++ b/examples/picoproj.c @@ -265,7 +265,6 @@ int main(int argc, char *argv[]) goto cleanup; } - if ((unsigned int)width > device_info.native_width || (unsigned int)height > device_info.native_height) fprintf(stderr, -- 2.1.4 From ad533681e384694d1b680d793ce00eab9f2bb6f2 Mon Sep 17 00:00:00 2001 From: Antonio Ospite Date: Sat, 29 Jun 2013 23:02:13 +0200 Subject: [PATCH 06/16] README.asciidoc: mention the TEC PP700 projector as supported Mention the Top-Height/TEC PP700 amongst the supported devices, it has been verified to be work with libam7xxx (thanks to the user nicknamed MHz). The projector looks exactly like an Acer C112 from the software point of view. --- README.asciidoc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.asciidoc b/README.asciidoc index b7f0c26..ef981d4 100644 --- a/README.asciidoc +++ b/README.asciidoc @@ -62,6 +62,9 @@ Examples of devices based on AM7XXX are: - CEL-TEC MP-01: * http://www.kabelmanie.cz/miniprojektor-cel-tec-mp-01/ + - Top-Height/TEC PP700 + * http://www.ishopiwin.com/en/appliances-electronics/electronics/projectors/pico-projector-pp-700.html + - Royaltek PJU-2100: * http://www.royaltek.com/index.php/pju-2100-pico-projector -- 2.1.4 From f2694ace893656d1629dd8dc33659e59b32f2d16 Mon Sep 17 00:00:00 2001 From: Antonio Ospite Date: Sat, 29 Jun 2013 23:11:57 +0200 Subject: [PATCH 07/16] HACKING.asciidoc: mention the patch needed for older libav/ffmpeg libav/ffmpeg 0.8.X series do not have avcodec_encode_video2() which the code uses, so for these older versions a patch is needed to undo the changes which added support for that call. --- HACKING.asciidoc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/HACKING.asciidoc b/HACKING.asciidoc index 3c1bc74..a6595fe 100644 --- a/HACKING.asciidoc +++ b/HACKING.asciidoc @@ -19,6 +19,9 @@ On a Debian based system, the dependencies can be installed with this command: libavdevice-dev \ libswscale-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/0002-Revert-am7xxx-play-switch-to-avcodec_encode_video2.patch + The library and the example programs can be compiled following these steps: $ git clone git://git.ao2.it/libam7xxx.git -- 2.1.4 From 3c1290c4aa1bb9cc5e964b014cee8b6c4034983d Mon Sep 17 00:00:00 2001 From: Antonio Ospite Date: Sun, 30 Jun 2013 00:12:59 +0200 Subject: [PATCH 08/16] CMakeLists.txt: add support for clang and isolate gcc-only options --- CMakeLists.txt | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8264845..d908f1c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -31,7 +31,9 @@ macro(add_flags var) set(${var} "${${var}} ${_flags}") endmacro(add_flags) -if (CMAKE_COMPILER_IS_GNUCC) +string(REGEX MATCH "clang" CMAKE_COMPILER_IS_CLANG "${CMAKE_C_COMPILER}") + +if (CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_CLANG) add_definitions(-Wall) # let CFLAGS env override this @@ -63,10 +65,8 @@ if (CMAKE_COMPILER_IS_GNUCC) -Wswitch-enum -Wundef -Wunreachable-code - -Wunsafe-loop-optimizations -Wwrite-strings - -fstack-protector - --param=ssp-buffer-size=4) + -fstack-protector) add_flags(DEBUG_FLAGS -ggdb @@ -79,10 +79,20 @@ if (CMAKE_COMPILER_IS_GNUCC) add_flags(STRICT_FLAGS -Werror # NOTE: Vanilla libusb-1.0.8 can't live with -pedantic-errors - -pedantic-errors + -pedantic-errors) + + endif() +endif() + +if (CMAKE_COMPILER_IS_GNUCC) + add_flags(CMAKE_C_FLAGS + -Wunsafe-loop-optimizations + --param=ssp-buffer-size=4) + + if (STRICT_COMPILATION_CHECKS) + add_flags(STRICT_FLAGS # NOTE: GCC >= 4.6 is needed for -Wunused-but-set-variable -Wunused-but-set-variable) - endif() endif() -- 2.1.4 From 4c7287240fd97699708dd835aca141e6ac8bd036 Mon Sep 17 00:00:00 2001 From: Antonio Ospite Date: Sun, 30 Jun 2013 00:15:30 +0200 Subject: [PATCH 09/16] am7xxx-play: uniform coding style Uniform the coding style of error paths to the one use throughout in the file. --- examples/am7xxx-play.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/examples/am7xxx-play.c b/examples/am7xxx-play.c index e958eee..21e5187 100644 --- a/examples/am7xxx-play.c +++ b/examples/am7xxx-play.c @@ -762,7 +762,8 @@ int main(int argc, char *argv[]) default: fprintf(stderr, "Invalid zoom mode value, must be between %d and %d\n", AM7XXX_ZOOM_ORIGINAL, AM7XXX_ZOOM_TEST); - exit(EXIT_FAILURE); + ret = -EINVAL; + goto out; } break; case 'h': -- 2.1.4 From 15c717cbc1a51c9a5551dc314f9697aa750d6ecb Mon Sep 17 00:00:00 2001 From: Antonio Ospite Date: Sun, 30 Jun 2013 00:20:51 +0200 Subject: [PATCH 10/16] picoproj: remove an unreachable break statement --- examples/picoproj.c | 1 - 1 file changed, 1 deletion(-) diff --git a/examples/picoproj.c b/examples/picoproj.c index 92dbfbf..d6d1c59 100644 --- a/examples/picoproj.c +++ b/examples/picoproj.c @@ -160,7 +160,6 @@ int main(int argc, char *argv[]) case 'h': usage(argv[0]); exit(EXIT_SUCCESS); - break; default: /* '?' */ usage(argv[0]); exit(EXIT_FAILURE); -- 2.1.4 From f641ad3eaaada89be7816332f2804dad9d9ecd39 Mon Sep 17 00:00:00 2001 From: Antonio Ospite Date: Sun, 30 Jun 2013 00:22:07 +0200 Subject: [PATCH 11/16] am7xxx: add quirks for devices not supporting some operations MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit For instance Philips/SagemoCm PicoPix PPX 2330 does not support power modes and zoom modes, and the device even gets confused when trying to use them; so for reliable operation it is better to just skip these operations on such devices. Thanks-to: Grégory Lemesre --- src/am7xxx.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/am7xxx.c b/src/am7xxx.c index 1f75c60..f37ad70 100644 --- a/src/am7xxx.c +++ b/src/am7xxx.c @@ -64,12 +64,16 @@ static void log_message(am7xxx_context *ctx, #define debug(ctx, ...) log_message(ctx, AM7XXX_LOG_DEBUG, __func__, 0, __VA_ARGS__) #define trace(ctx, ...) log_message(ctx, AM7XXX_LOG_TRACE, NULL, 0, __VA_ARGS__) +#define AM7XXX_QUIRK_NO_POWER_MODE (1 << 0) +#define AM7XXX_QUIRK_NO_ZOOM_MODE (1 << 1) + struct am7xxx_usb_device_descriptor { const char *name; uint16_t vendor_id; uint16_t product_id; uint8_t configuration; /* The bConfigurationValue of the device */ uint8_t interface_number; /* The bInterfaceNumber of the device */ + unsigned long quirks; }; static const struct am7xxx_usb_device_descriptor supported_devices[] = { @@ -114,6 +118,7 @@ static const struct am7xxx_usb_device_descriptor supported_devices[] = { .product_id = 0x0019, .configuration = 1, .interface_number = 0, + .quirks = AM7XXX_QUIRK_NO_POWER_MODE | AM7XXX_QUIRK_NO_ZOOM_MODE, }, }; @@ -956,6 +961,12 @@ AM7XXX_PUBLIC int am7xxx_set_power_mode(am7xxx_device *dev, am7xxx_power_mode po .unknown3 = 0x10, }; + if (dev->desc->quirks & AM7XXX_QUIRK_NO_POWER_MODE) { + debug(dev->ctx, + "setting power mode is unsupported on this device\n"); + return 0; + } + switch(power) { case AM7XXX_POWER_OFF: h.header_data.power.bit2 = 0; @@ -1010,6 +1021,12 @@ AM7XXX_PUBLIC int am7xxx_set_zoom_mode(am7xxx_device *dev, am7xxx_zoom_mode zoom .unknown3 = 0x10, }; + if (dev->desc->quirks & AM7XXX_QUIRK_NO_ZOOM_MODE) { + debug(dev->ctx, + "setting zoom mode is unsupported on this device\n"); + return 0; + } + switch(zoom) { case AM7XXX_ZOOM_ORIGINAL: h.header_data.zoom.bit1 = 0; -- 2.1.4 From 7d098152afd41bf21d3815af58293f6ea58d296e Mon Sep 17 00:00:00 2001 From: Antonio Ospite Date: Sat, 13 Jul 2013 11:05:00 +0200 Subject: [PATCH 12/16] CMakeLists.txt: enable two new compiler warnings Enable -Wsign-conversion as a strict compilation check for both gcc and clang. For clang also enable -Wshorten-64-to-32 as a strict compilation check. --- CMakeLists.txt | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index d908f1c..49c3ac0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -78,6 +78,7 @@ if (CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_CLANG) if (STRICT_COMPILATION_CHECKS) add_flags(STRICT_FLAGS -Werror + -Wsign-conversion # NOTE: Vanilla libusb-1.0.8 can't live with -pedantic-errors -pedantic-errors) @@ -96,6 +97,13 @@ if (CMAKE_COMPILER_IS_GNUCC) endif() endif() +if (CMAKE_COMPILER_IS_CLANG) + if (STRICT_COMPILATION_CHECKS) + add_flags(STRICT_FLAGS + -Wshorten-64-to-32) + endif() +endif() + set(CMAKE_C_FLAGS_DEBUG "-O0 ${DEBUG_FLAGS} ${STRICT_FLAGS}") set(CMAKE_C_FLAGS_RELEASE "-O2 ${RELEASE_FLAGS} ${STRICT_FLAGS}") set(CMAKE_C_FLAGS_RELWITHDEBINFO "-O2 ${RELEASE_FLAGS} ${DEBUG_FLAGS} ${STRICT_FLAGS}") -- 2.1.4 From d47271bd71355511535687f47e8a0f6c3784b8dc Mon Sep 17 00:00:00 2001 From: Antonio Ospite Date: Sun, 14 Jul 2013 13:25:25 +0200 Subject: [PATCH 13/16] am7xxx: fix a typo in a comment s/a am7xxx device/an am7xxx device/ --- src/am7xxx.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/am7xxx.h b/src/am7xxx.h index 24636c3..1c353ab 100644 --- a/src/am7xxx.h +++ b/src/am7xxx.h @@ -219,7 +219,7 @@ int am7xxx_calc_scaled_image_dimensions(am7xxx_device *dev, unsigned int *scaled_width, unsigned int *scaled_height); /** - * Send an image for display on a am7xxx device. + * Send an image for display on an am7xxx device. * * This is the function that actually makes the device display something. * Static pictures can be sent just once and the device will keep showing them -- 2.1.4 From 860428c1b8ee26b327ec3c9fb8943fd17a49d755 Mon Sep 17 00:00:00 2001 From: Antonio Ospite Date: Sun, 21 Jul 2013 00:10:28 +0200 Subject: [PATCH 14/16] am7xxx: implement am7xxx_send_image_async() Implement am7xxx_send_image_async() the non-blocking version of am7xxx_send_image(). This way user programs can more easily overlap encoding and communication and achieve higher framerates. --- src/am7xxx.c | 151 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/am7xxx.h | 26 ++++++++++ 2 files changed, 177 insertions(+) diff --git a/src/am7xxx.c b/src/am7xxx.c index f37ad70..3e6b461 100644 --- a/src/am7xxx.c +++ b/src/am7xxx.c @@ -130,6 +130,8 @@ static const struct am7xxx_usb_device_descriptor supported_devices[] = { struct _am7xxx_device { libusb_device_handle *usb_device; + struct libusb_transfer *transfer; + int transfer_completed; uint8_t buffer[AM7XXX_HEADER_WIRE_SIZE]; am7xxx_device_info *device_info; am7xxx_context *ctx; @@ -372,6 +374,117 @@ 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) +{ + am7xxx_device *dev = (am7xxx_device *)(transfer->user_data); + int *completed = &(dev->transfer_completed); + int transferred = transfer->actual_length; + int ret; + + if (transferred != transfer->length) { + error(dev->ctx, "transferred: %d (expected %u)\n", + transferred, transfer->length); + } + + switch (transfer->status) { + case LIBUSB_TRANSFER_COMPLETED: + ret = 0; + break; + case LIBUSB_TRANSFER_TIMED_OUT: + ret = LIBUSB_ERROR_TIMEOUT; + break; + case LIBUSB_TRANSFER_STALL: + ret = LIBUSB_ERROR_PIPE; + break; + case LIBUSB_TRANSFER_OVERFLOW: + ret = LIBUSB_ERROR_OVERFLOW; + break; + case LIBUSB_TRANSFER_NO_DEVICE: + ret = LIBUSB_ERROR_NO_DEVICE; + break; + case LIBUSB_TRANSFER_ERROR: + case LIBUSB_TRANSFER_CANCELLED: + ret = LIBUSB_ERROR_IO; + break; + default: + error(dev->ctx, "unrecognised status code %d", transfer->status); + ret = LIBUSB_ERROR_OTHER; + } + + if (ret < 0) + error(dev->ctx, "libusb transfer failed: %s", + libusb_error_name(ret)); + + libusb_free_transfer(transfer); + transfer = NULL; + + *completed = 1; +} + +static inline void wait_for_trasfer_completed(am7xxx_device *dev) +{ + while (!dev->transfer_completed) { + int ret = libusb_handle_events_completed(dev->ctx->usb_context, + &(dev->transfer_completed)); + if (ret < 0) { + if (ret == LIBUSB_ERROR_INTERRUPTED) + continue; + error(dev->ctx, "libusb_handle_events failed: %s, cancelling transfer and retrying", + libusb_error_name(ret)); + libusb_cancel_transfer(dev->transfer); + continue; + } + } +} + +static int send_data_async(am7xxx_device *dev, uint8_t *buffer, unsigned int len) +{ + int ret; + uint8_t *transfer_buffer; + + dev->transfer = libusb_alloc_transfer(0); + if (dev->transfer == NULL) { + error(dev->ctx, "cannot allocate transfer (%s)\n", + strerror(errno)); + return -ENOMEM; + } + + /* Make a copy of the buffer so the caller can safely reuse it just + * after libusb_submit_transfer() has returned. This technique + * requires more allocations than a proper double-buffering approach + * but it takes a lot less code. */ + transfer_buffer = malloc(len); + if (transfer_buffer == NULL) { + error(dev->ctx, "cannot allocate transfer buffer (%s)\n", + strerror(errno)); + ret = -ENOMEM; + goto err; + } + memcpy(transfer_buffer, buffer, len); + + dev->transfer->flags |= LIBUSB_TRANSFER_FREE_BUFFER; + libusb_fill_bulk_transfer(dev->transfer, dev->usb_device, 0x1, + transfer_buffer, len, + send_data_async_complete_cb, dev, 0); + + /* wait for the previous transfer to complete */ + wait_for_trasfer_completed(dev); + + trace_dump_buffer(dev->ctx, "sending -->", buffer, len); + + dev->transfer_completed = 0; + ret = libusb_submit_transfer(dev->transfer); + if (ret < 0) + goto err; + + return 0; + +err: + libusb_free_transfer(dev->transfer); + dev->transfer = NULL; + return ret; +} + static void serialize_header(struct am7xxx_header *h, uint8_t *buffer) { uint8_t **buffer_iterator = &buffer; @@ -496,6 +609,7 @@ static am7xxx_device *add_new_device(am7xxx_context *ctx, new_device->ctx = ctx; new_device->desc = desc; + new_device->transfer_completed = 1; devices_list = &(ctx->devices_list); @@ -786,6 +900,7 @@ AM7XXX_PUBLIC int am7xxx_close_device(am7xxx_device *dev) return -EINVAL; } if (dev->usb_device) { + wait_for_trasfer_completed(dev); libusb_release_interface(dev->usb_device, dev->desc->interface_number); libusb_close(dev->usb_device); dev->usb_device = NULL; @@ -950,6 +1065,42 @@ AM7XXX_PUBLIC int am7xxx_send_image(am7xxx_device *dev, return send_data(dev, image, image_size); } +AM7XXX_PUBLIC int am7xxx_send_image_async(am7xxx_device *dev, + am7xxx_image_format format, + unsigned int width, + unsigned int height, + uint8_t *image, + unsigned int image_size) +{ + int ret; + struct am7xxx_header h = { + .packet_type = AM7XXX_PACKET_TYPE_IMAGE, + .direction = AM7XXX_DIRECTION_OUT, + .header_data_len = sizeof(struct am7xxx_image_header), + .unknown2 = 0x3e, + .unknown3 = 0x10, + .header_data = { + .image = { + .format = format, + .width = width, + .height = height, + .image_size = image_size, + }, + }, + }; + + ret = send_header(dev, &h); + if (ret < 0) + return ret; + + if (image == NULL || image_size == 0) { + warning(dev->ctx, "Not sending any data, check the 'image' or 'image_size' parameters\n"); + return 0; + } + + return send_data_async(dev, image, image_size); +} + AM7XXX_PUBLIC int am7xxx_set_power_mode(am7xxx_device *dev, am7xxx_power_mode power) { int ret; diff --git a/src/am7xxx.h b/src/am7xxx.h index 1c353ab..ec9869d 100644 --- a/src/am7xxx.h +++ b/src/am7xxx.h @@ -242,6 +242,32 @@ int am7xxx_send_image(am7xxx_device *dev, unsigned int image_size); /** + * Queue transfer of an image for display on an am7xxx device and return immediately. + * + * This is the function that actually makes the device display something. + * Static pictures can be sent just once and the device will keep showing them + * until another image get sent or some command resets or turns off the display. + * + * @note This _async() variant makes a copy of the image buffer, so the caller + * is free to reuse the buffer just after the function returns. + * + * @param[in] dev A pointer to the structure representing the device to get info of + * @param[in] format The format the image is in (see @link am7xxx_image_format @endlink enum) + * @param[in] width The width of the image + * @param[in] height The height of the image + * @param[in] image A buffer holding data in the format specified by the format parameter + * @param[in] image_size The size in bytes of the image buffer + * + * @return 0 on success, a negative value on error + */ +int am7xxx_send_image_async(am7xxx_device *dev, + am7xxx_image_format format, + unsigned int width, + unsigned int height, + unsigned char *image, + unsigned int image_size); + +/** * Set the power mode of an am7xxx device. * * @note When setting the mode to AM7XXX_POWER_OFF the display can't be turned -- 2.1.4 From 68c88cb6a713359b60583cc04a47ca7c9a1ad267 Mon Sep 17 00:00:00 2001 From: Antonio Ospite Date: Sun, 21 Jul 2013 00:13:33 +0200 Subject: [PATCH 15/16] am7xxx-play: use am7xxx_send_image_async() Woot, this change alone doubles the frame rate :) --- examples/am7xxx-play.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/am7xxx-play.c b/examples/am7xxx-play.c index 21e5187..4506358 100644 --- a/examples/am7xxx-play.c +++ b/examples/am7xxx-play.c @@ -427,7 +427,7 @@ static int am7xxx_play(const char *input_format_string, fclose(file); #endif - ret = am7xxx_send_image(dev, + ret = am7xxx_send_image_async(dev, image_format, (output_ctx.codec_ctx)->width, (output_ctx.codec_ctx)->height, -- 2.1.4 From 77c53124a302f02f45b7d881746157dc9fcfd683 Mon Sep 17 00:00:00 2001 From: Antonio Ospite Date: Sat, 27 Jul 2013 20:23:30 +0200 Subject: [PATCH 16/16] doc: add some lsusb dumps for reference --- doc/lsusb_dumps/lsusb_Acer-C110.log | 68 ++++++++++++++++++++++++++ doc/lsusb_dumps/lsusb_Philips-PicoPix-2330.log | 68 ++++++++++++++++++++++++++ 2 files changed, 136 insertions(+) create mode 100644 doc/lsusb_dumps/lsusb_Acer-C110.log create mode 100644 doc/lsusb_dumps/lsusb_Philips-PicoPix-2330.log diff --git a/doc/lsusb_dumps/lsusb_Acer-C110.log b/doc/lsusb_dumps/lsusb_Acer-C110.log new file mode 100644 index 0000000..53f74e2 --- /dev/null +++ b/doc/lsusb_dumps/lsusb_Acer-C110.log @@ -0,0 +1,68 @@ + +Bus 004 Device 012: ID 1de1:c101 Actions Microelectronics Co. Generic Display Device +Device Descriptor: + bLength 18 + bDescriptorType 1 + bcdUSB 2.00 + bDeviceClass 255 Vendor Specific Class + bDeviceSubClass 0 + bDeviceProtocol 0 + bMaxPacketSize0 64 + idVendor 0x1de1 Actions Microelectronics Co. + idProduct 0xc101 Generic Display Device + bcdDevice 1.00 + iManufacturer 1 actions + iProduct 2 Usb Device + iSerial 3 00000000000000000000000000000000 + bNumConfigurations 1 + Configuration Descriptor: + bLength 9 + bDescriptorType 2 + wTotalLength 32 + bNumInterfaces 1 + bConfigurationValue 2 + iConfiguration 6 PICO PROJECTOR + bmAttributes 0xc0 + Self Powered + MaxPower 2mA + Interface Descriptor: + bLength 9 + bDescriptorType 4 + bInterfaceNumber 0 + bAlternateSetting 0 + bNumEndpoints 2 + bInterfaceClass 255 Vendor Specific Class + bInterfaceSubClass 8 + bInterfaceProtocol 8 + iInterface 7 USB PICO + 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 new file mode 100644 index 0000000..fc57c0d --- /dev/null +++ b/doc/lsusb_dumps/lsusb_Philips-PicoPix-2330.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 -- 2.1.4