{"action":"created","issue":{"url":"https://api.github.com/repos/blackjack/webcam/issues/4","repository_url":"https://api.github.com/repos/blackjack/webcam","labels_url":"https://api.github.com/repos/blackjack/webcam/issues/4/labels{/name}","comments_url":"https://api.github.com/repos/blackjack/webcam/issues/4/comments","events_url":"https://api.github.com/repos/blackjack/webcam/issues/4/events","html_url":"https://github.com/blackjack/webcam/pull/4","id":155081065,"number":4,"title":"Replace C v4l2 API implementation with pure Go implementation","user":{"login":"fabian-z","id":6495713,"avatar_url":"https://avatars.githubusercontent.com/u/6495713?v=3","gravatar_id":"","url":"https://api.github.com/users/fabian-z","html_url":"https://github.com/fabian-z","followers_url":"https://api.github.com/users/fabian-z/followers","following_url":"https://api.github.com/users/fabian-z/following{/other_user}","gists_url":"https://api.github.com/users/fabian-z/gists{/gist_id}","starred_url":"https://api.github.com/users/fabian-z/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/fabian-z/subscriptions","organizations_url":"https://api.github.com/users/fabian-z/orgs","repos_url":"https://api.github.com/users/fabian-z/repos","events_url":"https://api.github.com/users/fabian-z/events{/privacy}","received_events_url":"https://api.github.com/users/fabian-z/received_events","type":"User","site_admin":false},"labels":[],"state":"closed","locked":false,"assignee":null,"milestone":null,"comments":13,"created_at":"2016-05-16T17:42:44Z","updated_at":"2016-05-17T22:52:33Z","closed_at":"2016-05-17T19:16:10Z","pull_request":{"url":"https://api.github.com/repos/blackjack/webcam/pulls/4","html_url":"https://github.com/blackjack/webcam/pull/4","diff_url":"https://github.com/blackjack/webcam/pull/4.diff","patch_url":"https://github.com/blackjack/webcam/pull/4.patch"},"body":"This pull request provides a pure Go implementation interacting directly with the v4l2 kernel API. It gives the following benefits:\r\n\r\n- over 60% reduction in memory usage (maximum resident set size)\r\n- easier cross compilation\r\n- better code readability\r\n\r\nNotes:\r\n- Only the needed constants and structs were ported from v4l2 includes. ```ioctl``` package is forked from [github.com/paypal/gatt/linux/gioctl](https://github.com/paypal/gatt/tree/master/linux/gioctl) and converted to use ```golang.org/x/sys/unix```.\r\n- The speed increase originally claimed was due to erroneous measurement. In fact execution speed is identical for both implementations (which should be logically expected).\r\n- Testing was done on kernel 4.5.3 (x86_64) so far\r\n\r\nLooking forward to your feedback."},"comment":{"url":"https://api.github.com/repos/blackjack/webcam/issues/comments/219877919","html_url":"https://github.com/blackjack/webcam/pull/4#issuecomment-219877919","issue_url":"https://api.github.com/repos/blackjack/webcam/issues/4","id":219877919,"user":{"login":"blackjack","id":221255,"avatar_url":"https://avatars.githubusercontent.com/u/221255?v=3","gravatar_id":"","url":"https://api.github.com/users/blackjack","html_url":"https://github.com/blackjack","followers_url":"https://api.github.com/users/blackjack/followers","following_url":"https://api.github.com/users/blackjack/following{/other_user}","gists_url":"https://api.github.com/users/blackjack/gists{/gist_id}","starred_url":"https://api.github.com/users/blackjack/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/blackjack/subscriptions","organizations_url":"https://api.github.com/users/blackjack/orgs","repos_url":"https://api.github.com/users/blackjack/repos","events_url":"https://api.github.com/users/blackjack/events{/privacy}","received_events_url":"https://api.github.com/users/blackjack/received_events","type":"User","site_admin":false},"created_at":"2016-05-17T22:52:33Z","updated_at":"2016-05-17T22:52:33Z","body":"Ok, I've found out the reason why it wasn't working. \r\nThe answer is padding of fields in structure. \r\nThis is a C structure: \r\n```c\r\nstruct v4l2_format {\r\n\t__u32\t type;\r\n\tunion {\r\n\t\tstruct v4l2_pix_format\t\tpix;     /* V4L2_BUF_TYPE_VIDEO_CAPTURE */\r\n\t\tstruct v4l2_pix_format_mplane\tpix_mp;  /* V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE */\r\n\t\tstruct v4l2_window\t\twin;     /* V4L2_BUF_TYPE_VIDEO_OVERLAY */\r\n\t\tstruct v4l2_vbi_format\t\tvbi;     /* V4L2_BUF_TYPE_VBI_CAPTURE */\r\n\t\tstruct v4l2_sliced_vbi_format\tsliced;  /* V4L2_BUF_TYPE_SLICED_VBI_CAPTURE */\r\n\t\tstruct v4l2_sdr_format\t\tsdr;     /* V4L2_BUF_TYPE_SDR_CAPTURE */\r\n\t\t__u8\traw_data[200];                   /* user-defined */\r\n\t} fmt;\r\n};\r\n```\r\nAnd this is it's hex dump:\r\n```\r\nSizeof fmt: 208\r\n00000000   01 00 00 00 00 00 00 00  ff ff ff ff d0 02 00 00  |................|\r\n00000010   4d 4a 50 47 00 00 00 00  00 00 00 00 00 00 00 00  |MJPG............|\r\n00000020   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|\r\n00000030   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|\r\n00000040   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|\r\n00000050   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|\r\n00000060   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|\r\n00000070   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|\r\n00000080   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|\r\n00000090   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|\r\n000000a0   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|\r\n000000b0   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|\r\n000000c0   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|\r\n```\r\n\r\nNow this is v4l2_format definition from v4l2.go:\r\n\r\n```go\r\ntype v4l2_format struct {\r\n\t_type uint32\r\n\tunion [204]uint8\r\n}\r\n```\r\n\r\nHexdump:\r\n```\r\n00000000  01 00 00 00 00 05 00 00  d0 02 00 00 4d 4a 50 47  |............MJPG|\r\n00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|\r\n00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|\r\n00000030  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|\r\n00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|\r\n00000050  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|\r\n00000060  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|\r\n00000070  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|\r\n00000080  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|\r\n00000090  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|\r\n000000a0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|\r\n000000b0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|\r\n000000c0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|\r\n```\r\n\r\nAs you can see, in Go structure there's 4 bytes missing before starting of union field. \r\n \r\nIf I change definition to this: \r\n```go\r\ntype v4l2_format struct {\r\n\t_type uint32\r\n\t_     [4]uint8 //padding\r\n\tunion [200]uint8\r\n}\r\n```\r\nit will work\r\nI wonder why Go compiler doesn't insert padding there by itself"}}