Updating prebuilts and/or headers

f07563fa1628a75c578152387638b1f217f730be - libv4lconvert/Makefile
6ac3c887c56c7d4345499cb5b7bfac9579a57d16 - libv4lconvert/cpia1.c
2d385802ec3690e78a961ce95431e98eb3f5fc6a - libv4lconvert/rgbyuv.c
43843cbdb81f3efee5873f5ed25ae1eb7745a9e5 - libv4lconvert/libv4lconvert-priv.h
002783c808dc565478c18bd27373792028264bb6 - libv4lconvert/ov518-decomp.c
4d49e6e897046e66e41c3563fec2eb2562abf813 - libv4lconvert/jpeg_memsrcdest.c
a38fdb4c79518e972678745c93cd62881d72972b - libv4lconvert/Makefile.dGPU
e9f783fb933606224252dfd3093afa36490f6f4c - libv4lconvert/Makefile.in
52900601a24ee9ffea87ca7fe6651e912e20235e - libv4lconvert/libv4lsyscall-priv.h
d37f854500cbd759ad93ae89c6aa75c00b000931 - libv4lconvert/bayer.c
2cd1b994bb7999d0c08c19b1a2efd11707250852 - libv4lconvert/helper.c
adac14b8826d05ddab33d595a803e92eaf84b797 - libv4lconvert/Makefile.am
6e806290f6e426c881322d362f189fa7b9e2f917 - libv4lconvert/sn9c10x.c
ba44b6ac00a643e6df484f3172022e1b2628c0cc - libv4lconvert/jpgl.c
fa06343de31dcf6d3d5862cc278396272fa838c4 - libv4lconvert/se401.c
4bd081bf25b63f5463d582ef36f77ba5e3711d0d - libv4lconvert/sq905c.c
940250beb5898bf254e7cd1ef9d7950a8db10af6 - libv4lconvert/mr97310a.c
5e177c3a7c157c25c4afcae031e79830237510f6 - libv4lconvert/libv4lconvert.c
1f362080c319355070cf409cfccf28d8c68d024e - libv4lconvert/sn9c2028-decomp.c
703ce22dc98d834490c7aa23ae73b9113e386221 - libv4lconvert/sn9c20x.c
018e503969b2e06a0ea639fc08f03a7476cc15b5 - libv4lconvert/jpeg_memsrcdest.h
fb3344cfa8df97688332ee4fd3b17968437e8ad5 - libv4lconvert/helper-funcs.h
d378cbdd377027e7528af47362a94ccb1ae15da3 - libv4lconvert/libv4lconvert.export
61710972d4e9bfcd00490c563d1bb5bde5480c9e - libv4lconvert/tinyjpeg.c
231571db9f8caa6fdc68138102029127a6b93812 - libv4lconvert/crop.c
d62448a06539ecf6e3daae7faa299b6da8878054 - libv4lconvert/pac207.c
72b65c9f0f3c87dcae86a2afbea65a76f2c6bafd - libv4lconvert/tinyjpeg-internal.h
a016f896e0e9f0cd8af7447b52651ed14c5a5b29 - libv4lconvert/jpeg.c
608a4c341a5df9daea647fbddc415cdaf27b0482 - libv4lconvert/spca561-decompress.c
b03b32eae024bf59b6ceaf6b6d342383cd0b0673 - libv4lconvert/jl2005bcd.c
803c4d0b9364050eda163452b8792e62e221ab6d - libv4lconvert/tinyjpeg.h
2df34af8f9d747fb0e5c7c71954c788aff1c483f - libv4lconvert/stv0680.c
3e8e6c1fb85e3c4b58c4e9b2b0a223ddc793edcb - libv4lconvert/libv4lconvert.pc.in
02aa2e7d12b72fe4ce79cdf4009da61f35091e94 - libv4lconvert/flip.c
05038ef9efab175322a12d3d6620dba6298aa2a9 - libv4lconvert/spca501.c
b2c19c2eac71d39d3fb883cdc159a69c2afa8fd6 - libv4lconvert/ov511-decomp.c
1d9c446cd8a232da87bd79acebc93e018ec72499 - libv4lconvert/jidctflt.c
ed215eca170d07a6838be3796aad933adf89ece2 - libv4lconvert/hm12.c
193e9d2c997e21ce8ca02f25050fb8d2d62b6bfd - libv4lconvert/processing/autogain.c
c894d4a9b9e0f95be9e7bade4f7f734ae0c6996c - libv4lconvert/processing/libv4lprocessing.c
4158e9c3d21cf0a064b99bdf8571df4f3ba6d5bb - libv4lconvert/processing/whitebalance.c
be34baf0d2ce1374c841494ba27ccc352c444e98 - libv4lconvert/processing/gamma.c
b48edcb4036ee5f4e77e9cb49dd1b52b1e7f2427 - libv4lconvert/processing/libv4lprocessing.h
967d27c0e09849338a69dc4b5647d1824f2cd2fb - libv4lconvert/processing/libv4lprocessing-priv.h
9f382ff1f2895b926f3596e0a8ae7637b5e6a2ac - libv4lconvert/control/libv4lcontrol.c
8c523bd3838004a4fa00430a38cbc6dbaa47286f - libv4lconvert/control/libv4lcontrol.h
4ce5e891af7857a3504d1350ef13015997dde62a - libv4lconvert/control/libv4lcontrol-priv.h
bda0c1296aad2b3b178a76f38e26c20ce3b81233 - include/libv4l1.h
a95818658d95c1602f2422e5f1fb54b9ca70536e - include/libv4l2rds.h
2d1932763a064ef1176450b1bb4dd242aa3c77bb - include/libv4lconvert.h
3517bc15e30852ad01ad9966ec7111a16a2263df - include/libv4l2.h
944cd9bc32420e73da3a7d3cb1d0ce707263c9f0 - include/libv4l1-videodev.h
7d9d199f4e6f4ba6f0d669ee5decd74355507137 - include/libv4l-plugin.h
cfeaf0c16571e0c64bce50bcb8a6cd8d8c976187 - include/config.h
d7d4fd219e36edadc17837bff78eb8323e2a115e - include/libdvbv5/libdvb-version.h
33071176eda60242f39927e572ac6b1c1bab32e2 - include/libdvbv5/desc_event_extended.h
29c2cd2554e4f4285ab8709e6eace38046d8ecdc - include/libdvbv5/desc_t2_delivery.h
b42819db457bc6a23324faf259c0db1104741d99 - include/libdvbv5/dvb-scan.h
bae10c2fa28bb522e9fc0bb5e4b0128ab6f90e65 - include/libdvbv5/desc_partial_reception.h
f797ddac8e1adc6b29750f076df0f3a23cf630eb - include/libdvbv5/dvb-v5-std.h
48079dcae511070a8eeb55b004bd8ac06735ecc7 - include/libdvbv5/desc_ca.h
f4eb8b615b7c5a245c76e3f448e6cd848d8cf765 - include/libdvbv5/desc_cable_delivery.h
170a50b570691975e0ff22faffeb0131fc47c7c8 - include/libdvbv5/desc_logical_channel.h
c8f11e89456fc078c607d424e887babe72cd3684 - include/libdvbv5/nit.h
d39a24d0d0a0fbe732881dd2734b10d842d88de9 - include/libdvbv5/header.h
badc03677ddbcfa1d1188ddaaa4c272fccfe4a21 - include/libdvbv5/desc_atsc_service_location.h
d3bad046037cad4a95778555021a1a1a6b3040d9 - include/libdvbv5/cat.h
a614739513f62affb1059df81c064203d9fe2fcd - include/libdvbv5/desc_ca_identifier.h
6d70f699eb912c974dc06a19f9bdcb7dd0c27932 - include/libdvbv5/desc_service.h
0eda1161b34ca39b8528bc53d05fb0fc7d457f80 - include/libdvbv5/desc_frequency_list.h
22f6b663d50de467539201ecfdb363e9252c88bd - include/libdvbv5/atsc_eit.h
1c1292f060664abf6c12273a41b2bf6f704dd19b - include/libdvbv5/desc_sat.h
22de6de5e65530aa1ab38a2373db128e81983a4c - include/libdvbv5/desc_network_name.h
91178a5945e63c81051b57b7b2842139947a3b39 - include/libdvbv5/desc_extension.h
9ca776ad159cf84b2f68101bf279472741829047 - include/libdvbv5/descriptors.h
fa7e8d5e996310e1dd47d5467780d533c8a93ad8 - include/libdvbv5/dvb-dev.h
fed6115825c5b23e1e31ff80aab997f0a7b6c3fc - include/libdvbv5/sdt.h
4b892acd2ce77c060b50cf67f5faf9dc9b76edbb - include/libdvbv5/dvb-frontend.h
8b9f9e00f7bcdce58aef1d8d7234567af82e49b8 - include/libdvbv5/dvb-file.h
b8a077b8e3c6e337223fc37685d217a81df112f1 - include/libdvbv5/dvb-demux.h
01a0afbe1a4f41cf58f9ce47d65b31e3df7c8680 - include/libdvbv5/pat.h
4a49c8b46947be16356d6355aa36d72d7baa946c - include/libdvbv5/vct.h
c83200debc98ff8fa82030d36371a2caa230281a - include/libdvbv5/desc_language.h
21cea15c5d4faff2726f18bdf5b83e2210d472c4 - include/libdvbv5/mpeg_pes.h
825f75350da9fb148acc7d36af513da977105169 - include/libdvbv5/desc_isdbt_delivery.h
8f60bf43907b1eac3c1c2f031cf68a9bdebb3662 - include/libdvbv5/desc_ts_info.h
89cbb75f3e0952e4dfb145fdea776b45e05b7e76 - include/libdvbv5/desc_hierarchy.h
5c80a7ee23d1da2c91f60e79f7292248694b4f65 - include/libdvbv5/crc32.h
93b7b27ccc89e1ad4279eb12560e1dfc3d2ff1eb - include/libdvbv5/dvb-fe.h
aeeb75989de4b2ecafa1b2fc5ed30787999eec1b - include/libdvbv5/mpeg_es.h
dc684983365ffef353993faad0b105bcb87f4218 - include/libdvbv5/desc_event_short.h
5e3be50d1292109d59c80f920ba1b7a4bcbbdf56 - include/libdvbv5/eit.h
f95a0206952db4cce561455accad66a37f9a4104 - include/libdvbv5/mgt.h
88f8c78bbaf22b345e2ccb68e9b787e649dac2c1 - include/libdvbv5/libdvb-version.h.in
74a66644980a66adeba21ecc40ebefa2b4480e25 - include/libdvbv5/pmt.h
7671f125c6f61eef85f55eb314097435b3772431 - include/libdvbv5/dvb-sat.h
26fd40a10548cdb9bd4aafdda4486f9d39fd5c9e - include/libdvbv5/countries.h
65db3beaf2ec19a43a870b2759e6aecb15a95c7b - include/libdvbv5/atsc_header.h
149f7eb3c71b8f65127d3c4f2143080b115697e5 - include/libdvbv5/desc_terrestrial_delivery.h
708af2b77b2c94ee9cf593b31e20471c80ea556b - include/libdvbv5/mpeg_ts.h
ba205468e43ca16edf1ebec59dce9822044c1064 - include/libdvbv5/desc_registration_id.h
e70b24d8d1f3a248735c2d724d3b92c49b7aaba5 - include/libdvbv5/dvb-log.h
2d0557eadd4cff02ab52e26778d35b6c34f09158 - libv4l2/libv4l2-priv.h
487af43db163be6d3604371b9a504c1df2a9bf6c - libv4l2/v4l2-plugin-android.c
0ac38b46fa1659db4c05660205f212389295e7ff - libv4l2/Makefile
8ac3789333a6cd18e7f35d3b66a8a4d0293feb78 - libv4l2/Makefile.dGPU
fdd6e5e27aa8b41d5da77cb3b9be3fc3b8a44763 - libv4l2/libv4l2.export
1d37e5ea9231e7e0eea7d1a02938c6d1ae8ba791 - libv4l2/Makefile.in
51892a60925c37c865fe6eb9c923a552df180ebf - libv4l2/v4l2-plugin.c
d4c7daee644a35244ac8a5e1009a3aeb1d4fd3da - libv4l2/Makefile.am
87856c7113d150dceb254b5d548f942e7fcaf8f1 - libv4l2/libv4l2.c
d11ec5b8ce8390a72fd61457d7b8667378311191 - libv4l2/log.c
cbcee4426c19c168c6f49d04af3a0b2e30c0b681 - libv4l2/libv4l2.pc.in
55bb16d05817a3ecf076174175b2ca5b56e729d8 - libv4l2/v4l2convert.c

Change-Id: I92b00c7d65c1689c9d6ff337a6f2ae790e88a7cb
This commit is contained in:
svcmobrel-release
2025-09-19 10:09:57 -07:00
parent e003da6fcd
commit 74b0ee4b0a
117 changed files with 35073 additions and 0 deletions

116
commitFile.txt Normal file
View File

@@ -0,0 +1,116 @@
Updating prebuilts and/or headers
f07563fa1628a75c578152387638b1f217f730be - libv4lconvert/Makefile
6ac3c887c56c7d4345499cb5b7bfac9579a57d16 - libv4lconvert/cpia1.c
2d385802ec3690e78a961ce95431e98eb3f5fc6a - libv4lconvert/rgbyuv.c
43843cbdb81f3efee5873f5ed25ae1eb7745a9e5 - libv4lconvert/libv4lconvert-priv.h
002783c808dc565478c18bd27373792028264bb6 - libv4lconvert/ov518-decomp.c
4d49e6e897046e66e41c3563fec2eb2562abf813 - libv4lconvert/jpeg_memsrcdest.c
a38fdb4c79518e972678745c93cd62881d72972b - libv4lconvert/Makefile.dGPU
e9f783fb933606224252dfd3093afa36490f6f4c - libv4lconvert/Makefile.in
52900601a24ee9ffea87ca7fe6651e912e20235e - libv4lconvert/libv4lsyscall-priv.h
d37f854500cbd759ad93ae89c6aa75c00b000931 - libv4lconvert/bayer.c
2cd1b994bb7999d0c08c19b1a2efd11707250852 - libv4lconvert/helper.c
adac14b8826d05ddab33d595a803e92eaf84b797 - libv4lconvert/Makefile.am
6e806290f6e426c881322d362f189fa7b9e2f917 - libv4lconvert/sn9c10x.c
ba44b6ac00a643e6df484f3172022e1b2628c0cc - libv4lconvert/jpgl.c
fa06343de31dcf6d3d5862cc278396272fa838c4 - libv4lconvert/se401.c
4bd081bf25b63f5463d582ef36f77ba5e3711d0d - libv4lconvert/sq905c.c
940250beb5898bf254e7cd1ef9d7950a8db10af6 - libv4lconvert/mr97310a.c
5e177c3a7c157c25c4afcae031e79830237510f6 - libv4lconvert/libv4lconvert.c
1f362080c319355070cf409cfccf28d8c68d024e - libv4lconvert/sn9c2028-decomp.c
703ce22dc98d834490c7aa23ae73b9113e386221 - libv4lconvert/sn9c20x.c
018e503969b2e06a0ea639fc08f03a7476cc15b5 - libv4lconvert/jpeg_memsrcdest.h
fb3344cfa8df97688332ee4fd3b17968437e8ad5 - libv4lconvert/helper-funcs.h
d378cbdd377027e7528af47362a94ccb1ae15da3 - libv4lconvert/libv4lconvert.export
61710972d4e9bfcd00490c563d1bb5bde5480c9e - libv4lconvert/tinyjpeg.c
231571db9f8caa6fdc68138102029127a6b93812 - libv4lconvert/crop.c
d62448a06539ecf6e3daae7faa299b6da8878054 - libv4lconvert/pac207.c
72b65c9f0f3c87dcae86a2afbea65a76f2c6bafd - libv4lconvert/tinyjpeg-internal.h
a016f896e0e9f0cd8af7447b52651ed14c5a5b29 - libv4lconvert/jpeg.c
608a4c341a5df9daea647fbddc415cdaf27b0482 - libv4lconvert/spca561-decompress.c
b03b32eae024bf59b6ceaf6b6d342383cd0b0673 - libv4lconvert/jl2005bcd.c
803c4d0b9364050eda163452b8792e62e221ab6d - libv4lconvert/tinyjpeg.h
2df34af8f9d747fb0e5c7c71954c788aff1c483f - libv4lconvert/stv0680.c
3e8e6c1fb85e3c4b58c4e9b2b0a223ddc793edcb - libv4lconvert/libv4lconvert.pc.in
02aa2e7d12b72fe4ce79cdf4009da61f35091e94 - libv4lconvert/flip.c
05038ef9efab175322a12d3d6620dba6298aa2a9 - libv4lconvert/spca501.c
b2c19c2eac71d39d3fb883cdc159a69c2afa8fd6 - libv4lconvert/ov511-decomp.c
1d9c446cd8a232da87bd79acebc93e018ec72499 - libv4lconvert/jidctflt.c
ed215eca170d07a6838be3796aad933adf89ece2 - libv4lconvert/hm12.c
193e9d2c997e21ce8ca02f25050fb8d2d62b6bfd - libv4lconvert/processing/autogain.c
c894d4a9b9e0f95be9e7bade4f7f734ae0c6996c - libv4lconvert/processing/libv4lprocessing.c
4158e9c3d21cf0a064b99bdf8571df4f3ba6d5bb - libv4lconvert/processing/whitebalance.c
be34baf0d2ce1374c841494ba27ccc352c444e98 - libv4lconvert/processing/gamma.c
b48edcb4036ee5f4e77e9cb49dd1b52b1e7f2427 - libv4lconvert/processing/libv4lprocessing.h
967d27c0e09849338a69dc4b5647d1824f2cd2fb - libv4lconvert/processing/libv4lprocessing-priv.h
9f382ff1f2895b926f3596e0a8ae7637b5e6a2ac - libv4lconvert/control/libv4lcontrol.c
8c523bd3838004a4fa00430a38cbc6dbaa47286f - libv4lconvert/control/libv4lcontrol.h
4ce5e891af7857a3504d1350ef13015997dde62a - libv4lconvert/control/libv4lcontrol-priv.h
bda0c1296aad2b3b178a76f38e26c20ce3b81233 - include/libv4l1.h
a95818658d95c1602f2422e5f1fb54b9ca70536e - include/libv4l2rds.h
2d1932763a064ef1176450b1bb4dd242aa3c77bb - include/libv4lconvert.h
3517bc15e30852ad01ad9966ec7111a16a2263df - include/libv4l2.h
944cd9bc32420e73da3a7d3cb1d0ce707263c9f0 - include/libv4l1-videodev.h
7d9d199f4e6f4ba6f0d669ee5decd74355507137 - include/libv4l-plugin.h
cfeaf0c16571e0c64bce50bcb8a6cd8d8c976187 - include/config.h
d7d4fd219e36edadc17837bff78eb8323e2a115e - include/libdvbv5/libdvb-version.h
33071176eda60242f39927e572ac6b1c1bab32e2 - include/libdvbv5/desc_event_extended.h
29c2cd2554e4f4285ab8709e6eace38046d8ecdc - include/libdvbv5/desc_t2_delivery.h
b42819db457bc6a23324faf259c0db1104741d99 - include/libdvbv5/dvb-scan.h
bae10c2fa28bb522e9fc0bb5e4b0128ab6f90e65 - include/libdvbv5/desc_partial_reception.h
f797ddac8e1adc6b29750f076df0f3a23cf630eb - include/libdvbv5/dvb-v5-std.h
48079dcae511070a8eeb55b004bd8ac06735ecc7 - include/libdvbv5/desc_ca.h
f4eb8b615b7c5a245c76e3f448e6cd848d8cf765 - include/libdvbv5/desc_cable_delivery.h
170a50b570691975e0ff22faffeb0131fc47c7c8 - include/libdvbv5/desc_logical_channel.h
c8f11e89456fc078c607d424e887babe72cd3684 - include/libdvbv5/nit.h
d39a24d0d0a0fbe732881dd2734b10d842d88de9 - include/libdvbv5/header.h
badc03677ddbcfa1d1188ddaaa4c272fccfe4a21 - include/libdvbv5/desc_atsc_service_location.h
d3bad046037cad4a95778555021a1a1a6b3040d9 - include/libdvbv5/cat.h
a614739513f62affb1059df81c064203d9fe2fcd - include/libdvbv5/desc_ca_identifier.h
6d70f699eb912c974dc06a19f9bdcb7dd0c27932 - include/libdvbv5/desc_service.h
0eda1161b34ca39b8528bc53d05fb0fc7d457f80 - include/libdvbv5/desc_frequency_list.h
22f6b663d50de467539201ecfdb363e9252c88bd - include/libdvbv5/atsc_eit.h
1c1292f060664abf6c12273a41b2bf6f704dd19b - include/libdvbv5/desc_sat.h
22de6de5e65530aa1ab38a2373db128e81983a4c - include/libdvbv5/desc_network_name.h
91178a5945e63c81051b57b7b2842139947a3b39 - include/libdvbv5/desc_extension.h
9ca776ad159cf84b2f68101bf279472741829047 - include/libdvbv5/descriptors.h
fa7e8d5e996310e1dd47d5467780d533c8a93ad8 - include/libdvbv5/dvb-dev.h
fed6115825c5b23e1e31ff80aab997f0a7b6c3fc - include/libdvbv5/sdt.h
4b892acd2ce77c060b50cf67f5faf9dc9b76edbb - include/libdvbv5/dvb-frontend.h
8b9f9e00f7bcdce58aef1d8d7234567af82e49b8 - include/libdvbv5/dvb-file.h
b8a077b8e3c6e337223fc37685d217a81df112f1 - include/libdvbv5/dvb-demux.h
01a0afbe1a4f41cf58f9ce47d65b31e3df7c8680 - include/libdvbv5/pat.h
4a49c8b46947be16356d6355aa36d72d7baa946c - include/libdvbv5/vct.h
c83200debc98ff8fa82030d36371a2caa230281a - include/libdvbv5/desc_language.h
21cea15c5d4faff2726f18bdf5b83e2210d472c4 - include/libdvbv5/mpeg_pes.h
825f75350da9fb148acc7d36af513da977105169 - include/libdvbv5/desc_isdbt_delivery.h
8f60bf43907b1eac3c1c2f031cf68a9bdebb3662 - include/libdvbv5/desc_ts_info.h
89cbb75f3e0952e4dfb145fdea776b45e05b7e76 - include/libdvbv5/desc_hierarchy.h
5c80a7ee23d1da2c91f60e79f7292248694b4f65 - include/libdvbv5/crc32.h
93b7b27ccc89e1ad4279eb12560e1dfc3d2ff1eb - include/libdvbv5/dvb-fe.h
aeeb75989de4b2ecafa1b2fc5ed30787999eec1b - include/libdvbv5/mpeg_es.h
dc684983365ffef353993faad0b105bcb87f4218 - include/libdvbv5/desc_event_short.h
5e3be50d1292109d59c80f920ba1b7a4bcbbdf56 - include/libdvbv5/eit.h
f95a0206952db4cce561455accad66a37f9a4104 - include/libdvbv5/mgt.h
88f8c78bbaf22b345e2ccb68e9b787e649dac2c1 - include/libdvbv5/libdvb-version.h.in
74a66644980a66adeba21ecc40ebefa2b4480e25 - include/libdvbv5/pmt.h
7671f125c6f61eef85f55eb314097435b3772431 - include/libdvbv5/dvb-sat.h
26fd40a10548cdb9bd4aafdda4486f9d39fd5c9e - include/libdvbv5/countries.h
65db3beaf2ec19a43a870b2759e6aecb15a95c7b - include/libdvbv5/atsc_header.h
149f7eb3c71b8f65127d3c4f2143080b115697e5 - include/libdvbv5/desc_terrestrial_delivery.h
708af2b77b2c94ee9cf593b31e20471c80ea556b - include/libdvbv5/mpeg_ts.h
ba205468e43ca16edf1ebec59dce9822044c1064 - include/libdvbv5/desc_registration_id.h
e70b24d8d1f3a248735c2d724d3b92c49b7aaba5 - include/libdvbv5/dvb-log.h
2d0557eadd4cff02ab52e26778d35b6c34f09158 - libv4l2/libv4l2-priv.h
487af43db163be6d3604371b9a504c1df2a9bf6c - libv4l2/v4l2-plugin-android.c
0ac38b46fa1659db4c05660205f212389295e7ff - libv4l2/Makefile
8ac3789333a6cd18e7f35d3b66a8a4d0293feb78 - libv4l2/Makefile.dGPU
fdd6e5e27aa8b41d5da77cb3b9be3fc3b8a44763 - libv4l2/libv4l2.export
1d37e5ea9231e7e0eea7d1a02938c6d1ae8ba791 - libv4l2/Makefile.in
51892a60925c37c865fe6eb9c923a552df180ebf - libv4l2/v4l2-plugin.c
d4c7daee644a35244ac8a5e1009a3aeb1d4fd3da - libv4l2/Makefile.am
87856c7113d150dceb254b5d548f942e7fcaf8f1 - libv4l2/libv4l2.c
d11ec5b8ce8390a72fd61457d7b8667378311191 - libv4l2/log.c
cbcee4426c19c168c6f49d04af3a0b2e30c0b681 - libv4l2/libv4l2.pc.in
55bb16d05817a3ecf076174175b2ca5b56e729d8 - libv4l2/v4l2convert.c

239
include/config.h Normal file
View File

@@ -0,0 +1,239 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: LGPL-2.1-or-later
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program. If not, see
* <http://www.gnu.org/licenses/>.
*/
/* config.h. Generated from config.h.in by configure. */
/* config.h.in. Generated from configure.ac by autoheader. */
/* Define to 1 if translation of program messages to the user's native
language is requested. */
#define ENABLE_NLS 1
/* alsa library is present */
#define HAVE_ALSA 1
/* glibc has functions to provide stack backtrace */
#define HAVE_BACKTRACE 1
/* Define to 1 if you have the Mac OS X function CFLocaleCopyCurrent in the
CoreFoundation framework. */
/* #undef HAVE_CFLOCALECOPYCURRENT */
/* Define to 1 if you have the Mac OS X function CFPreferencesCopyAppValue in
the CoreFoundation framework. */
/* #undef HAVE_CFPREFERENCESCOPYAPPVALUE */
/* Define if the GNU dcgettext() function is already present or preinstalled.
*/
#define HAVE_DCGETTEXT 1
/* Define to 1 if you have the <dlfcn.h> header file. */
#define HAVE_DLFCN_H 1
/* Usage of DVBv5 remote enabled */
#define HAVE_DVBV5_REMOTE 1
/* Define to 1 if you have the `fork' function. */
#define HAVE_FORK 1
/* Define if the GNU gettext() function is already present or preinstalled. */
#define HAVE_GETTEXT 1
/* Define if you have the iconv() function and it works. */
#define HAVE_ICONV 1
/* Define to 1 if you have the <inttypes.h> header file. */
#define HAVE_INTTYPES_H 1
/* whether we use libjpeg */
//#define HAVE_JPEG 0
/* Define to 1 if you have the `klogctl' function. */
#define HAVE_KLOGCTL 1
/* Use libudev */
#define HAVE_LIBUDEV /**/
/* whether to use libv4lconvert helpers */
#define HAVE_LIBV4LCONVERT_HELPERS 1
/* Define to 1 if you have the <memory.h> header file. */
#define HAVE_MEMORY_H 1
/* Have ioctl with POSIX signature */
/* #undef HAVE_POSIX_IOCTL */
/* Define if you have POSIX threads libraries and header files. */
#define HAVE_PTHREAD 1
/* Have PTHREAD_PRIO_INHERIT. */
#define HAVE_PTHREAD_PRIO_INHERIT 1
/* qt has opengl support */
#define HAVE_QTGL 1
/* Define to 1 if you have the `secure_getenv' function. */
#define HAVE_SECURE_GETENV 1
/* Define to 1 if you have the <stdint.h> header file. */
#define HAVE_STDINT_H 1
/* Define to 1 if you have the <stdlib.h> header file. */
#define HAVE_STDLIB_H 1
/* Define to 1 if you have the <strings.h> header file. */
#define HAVE_STRINGS_H 1
/* Define to 1 if you have the <string.h> header file. */
#define HAVE_STRING_H 1
/* Define to 1 if you have the <sys/klog.h> header file. */
#define HAVE_SYS_KLOG_H 1
/* Define to 1 if you have the <sys/stat.h> header file. */
#define HAVE_SYS_STAT_H 1
/* Define to 1 if you have the <sys/types.h> header file. */
#define HAVE_SYS_TYPES_H 1
/* Define to 1 if you have the <unistd.h> header file. */
#define HAVE_UNISTD_H 1
/* V4L plugin support enabled */
#define HAVE_V4L_PLUGINS 1
/* Define to 1 or 0, depending whether the compiler supports simple visibility
declarations. */
#define HAVE_VISIBILITY 1
/* Define to 1 if you have the `__secure_getenv' function. */
/* #undef HAVE___SECURE_GETENV */
/* Define as const if the declaration of iconv() needs const. */
#define ICONV_CONST
/* ir-keytable preinstalled tables directory */
#define IR_KEYTABLE_SYSTEM_DIR "/lib/udev/rc_keymaps"
/* ir-keytable user defined tables directory */
#define IR_KEYTABLE_USER_DIR "/usr/local/etc/rc_keymaps"
/* libdvbv5 domain */
#define LIBDVBV5_DOMAIN "libdvbv5"
/* libv4l1 private lib directory */
#define LIBV4L1_PRIV_DIR "/usr/local/lib/libv4l"
/* libv4l2 plugin directory */
#ifdef LIBV4L2_PLUGIN_DIR_PATH_X86
#define LIBV4L2_PLUGIN_DIR "/usr/lib/x86_64-linux-gnu/libv4l/plugins"
#else
#define LIBV4L2_PLUGIN_DIR "/usr/lib/aarch64-linux-gnu/libv4l/plugins/nv"
#endif
/* libv4l2 private lib directory */
#define LIBV4L2_PRIV_DIR "/usr/local/lib/libv4l"
/* libv4lconvert private lib directory */
#define LIBV4LCONVERT_PRIV_DIR "/usr/local/lib/libv4l"
/* locale directory */
#define LOCALEDIR "/usr/local/share/locale"
/* Define to the sub-directory where libtool stores uninstalled libraries. */
#define LT_OBJDIR ".libs/"
/* Define to 1 if `major', `minor', and `makedev' are declared in <mkdev.h>.
*/
/* #undef MAJOR_IN_MKDEV */
/* Define to 1 if `major', `minor', and `makedev' are declared in
<sysmacros.h>. */
/* #undef MAJOR_IN_SYSMACROS */
/* Name of package */
#define PACKAGE "v4l-utils"
/* Define to the address where bug reports for this package should be sent. */
#define PACKAGE_BUGREPORT ""
/* Define to the full name of this package. */
#define PACKAGE_NAME "v4l-utils"
/* Define to the full name and version of this package. */
#define PACKAGE_STRING "v4l-utils 1.14.2"
/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "v4l-utils"
/* Define to the home page for this package. */
#define PACKAGE_URL ""
/* Define to the version of this package. */
#define PACKAGE_VERSION "1.14.2"
/* Define to the type that is the result of default argument promotions of
type mode_t. */
#define PROMOTED_MODE_T mode_t
/* Define to necessary symbol if this constant uses a non-standard name on
your system. */
/* #undef PTHREAD_CREATE_JOINABLE */
/* Define to 1 if you have the ANSI C header files. */
#define STDC_HEADERS 1
/* Enable extensions on AIX 3, Interix. */
#ifndef _ALL_SOURCE
# define _ALL_SOURCE 1
#endif
/* Enable GNU extensions on systems that have them. */
#ifndef _GNU_SOURCE
# define _GNU_SOURCE 1
#endif
/* Enable threading extensions on Solaris. */
#ifndef _POSIX_PTHREAD_SEMANTICS
# define _POSIX_PTHREAD_SEMANTICS 1
#endif
/* Enable extensions on HP NonStop. */
#ifndef _TANDEM_SOURCE
# define _TANDEM_SOURCE 1
#endif
/* Enable general extensions on Solaris. */
#ifndef __EXTENSIONS__
# define __EXTENSIONS__ 1
#endif
/* v4l-utils version string */
#define V4L_UTILS_VERSION "1.14.2"
/* Version number of package */
#define VERSION "1.14.2"
/* Define to 1 if on MINIX. */
/* #undef _MINIX */
/* Define to 2 if the system does not provide POSIX.1 features except with
this defined. */
/* #undef _POSIX_1_SOURCE */
/* Define to 1 if you need to in order for `stat' and other things to work. */
/* #undef _POSIX_SOURCE */
/* Define to `int' if <sys/types.h> does not define. */
/* #undef mode_t */

221
include/libdvbv5/atsc_eit.h Normal file
View File

@@ -0,0 +1,221 @@
/*
* Copyright (c) 2013 - Andre Roth <neolynx@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation version 2.1 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
* Or, point your browser to http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
*/
/**
* @file atsc_eit.h
* @ingroup dvb_table
* @brief Provides the table parser for the ATSC EIT (Event Information Table)
* @copyright GNU Lesser General Public License version 2.1 (LGPLv2.1)
* @author Mauro Carvalho Chehab
* @author Andre Roth
*
* @par Relevant specs
* The table described herein is defined at:
* - ATSC A/65:2009
*
* @see
* http://www.etherguidesystems.com/help/sdos/atsc/syntax/tablesections/eitks.aspx
*
* @par Bug Report
* Please submit bug reports and patches to linux-media@vger.kernel.org
*/
#ifndef _ATSC_EIT_H
#define _ATSC_EIT_H
#include <stdint.h>
#include <unistd.h> /* ssize_t */
#include <time.h>
#include <libdvbv5/atsc_header.h>
/**
* @def ATSC_TABLE_EIT
* @brief ATSC EIT table ID
* @ingroup dvb_table
*/
#define ATSC_TABLE_EIT 0xCB
/**
* @struct atsc_table_eit_event
* @brief ATSC EIT event table
* @ingroup dvb_table
*
* @param event_id an uniquelly (inside a service ID) event ID
* @param title_length title length. Zero means no title
* @param duration duration in seconds
* @param etm Extended Text Message location
* @param descriptor pointer to struct dvb_desc
* @param next pointer to struct atsc_table_eit_event
* @param start event start (in struct tm format)
* @param source_id source id (obtained from ATSC header)
*
* This structure is used to store the original ATSC EIT event table,
* converting the integer fields to the CPU endianness, and converting the
* timestamps to a way that it is better handled on Linux.
*
* The undocumented parameters are used only internally by the API and/or
* are fields that are reserved. They shouldn't be used, as they may change
* on future API releases.
*
* Everything after atsc_table_eit_event::descriptor (including it) won't
* be bit-mapped to the data parsed from the MPEG TS. So, metadata are added
* there.
*/
struct atsc_table_eit_event {
union {
uint16_t bitfield;
struct {
uint16_t event_id:14;
uint16_t one:2;
} __attribute__((packed));
} __attribute__((packed));
uint32_t start_time;
union {
uint32_t bitfield2;
struct {
uint32_t title_length:8;
uint32_t duration:20;
uint32_t etm:2;
uint32_t one2:2;
uint32_t :2;
} __attribute__((packed));
} __attribute__((packed));
struct dvb_desc *descriptor;
struct atsc_table_eit_event *next;
struct tm start;
uint16_t source_id;
} __attribute__((packed));
/**
* @union atsc_table_eit_desc_length
* @brief ATSC EIT descriptor length
* @ingroup dvb_table
*
* @param desc_length descriptor length
*
* This structure is used to store the original ATSC EIT event table,
* converting the integer fields to the CPU endianness, and converting the
* timestamps to a way that it is better handled on Linux.
*
* The undocumented parameters are used only internally by the API and/or
* are fields that are reserved. They shouldn't be used, as they may change
* on future API releases.
*/
union atsc_table_eit_desc_length {
uint16_t bitfield;
struct {
uint16_t desc_length:12;
uint16_t reserved:4;
} __attribute__((packed));
} __attribute__((packed));
/**
* @struct atsc_table_eit
* @brief ATSC EIT table
* @ingroup dvb_table
*
* @param header struct dvb_table_header content
* @param protocol_version protocol version
* @param events events
* @param event pointer to struct atsc_table_eit_event
*
* This structure is used to store the original ATSC EIT table,
* converting the integer fields to the CPU endianness.
*
* Everything after atsc_table_eit::event (including it) won't
* be bit-mapped to the data parsed from the MPEG TS. So, metadata are added
* there.
*/
struct atsc_table_eit {
struct dvb_table_header header;
uint8_t protocol_version;
uint8_t events;
struct atsc_table_eit_event *event;
} __attribute__((packed));
/**
* @brief Macro used to find event on an ATSC EIT table
* @ingroup dvb_table
*
* @param _event event to seek
* @param _eit pointer to struct atsc_table_eit_event
*/
#define atsc_eit_event_foreach(_event, _eit) \
if (_eit && _eit->event) \
for( struct atsc_table_eit_event *_event = _eit->event; _event; _event = _event->next ) \
struct dvb_v5_fe_parms;
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Initializes and parses ATSC EIT table
* @ingroup dvb_table
*
* @param parms struct dvb_v5_fe_parms pointer to the opened device
* @param buf buffer containing the EIT raw data
* @param buflen length of the buffer
* @param table pointer to struct atsc_table_eit to be allocated and filled
*
* This function allocates an ATSC EIT table and fills the fields inside
* the struct. It also makes sure that all fields will follow the CPU
* endianness. Due to that, the content of the buffer may change.
*
* @return On success, it returns the size of the allocated struct.
* A negative value indicates an error.
*/
ssize_t atsc_table_eit_init(struct dvb_v5_fe_parms *parms, const uint8_t *buf,
ssize_t buflen, struct atsc_table_eit **table);
/**
* @brief Frees all data allocated by the ATSC EIT table parser
* @ingroup dvb_table
*
* @param table pointer to struct atsc_table_eit to be freed
*/
void atsc_table_eit_free(struct atsc_table_eit *table);
/**
* @brief Prints the content of the ATSC EIT table
* @ingroup dvb_table
*
* @param parms struct dvb_v5_fe_parms pointer to the opened device
* @param table pointer to struct atsc_table_eit
*/
void atsc_table_eit_print(struct dvb_v5_fe_parms *parms,
struct atsc_table_eit *table);
/**
* @brief Converts an ATSC EIT formatted timestamp into struct tm
* @ingroup ancillary
*
* @param start_time event on ATSC EIT time format
* @param tm pointer to struct tm where the converted timestamp will
* be stored.
*/
void atsc_time(const uint32_t start_time, struct tm *tm);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,59 @@
/*
* Copyright (c) 2013 - Andre Roth <neolynx@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation version 2.1 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
* Or, point your browser to http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
*/
#ifndef _ATSC_HEADER_H
#define _ATSC_HEADER_H
/**
* @file atsc_header.h
* @ingroup dvb_table
* @brief Provides some common ATSC stuff
* @copyright GNU Lesser General Public License version 2.1 (LGPLv2.1)
* @author Andre Roth
*
* @par Bug Report
* Please submit bug reports and patches to linux-media@vger.kernel.org
*/
#include <stdint.h>
#include <unistd.h> /* ssize_t */
#include <libdvbv5/header.h>
/**
* @def ATSC_BASE_PID
* @brief ATSC PID for the Program and System Information Protocol
* @ingroup dvb_table
*/
#define ATSC_BASE_PID 0x1FFB
#ifndef _DOXYGEN
/* Deprecated, as it causes troubles with doxygen */
#define ATSC_HEADER() \
struct dvb_table_header header; \
uint8_t protocol_version; \
#define ATSC_TABLE_HEADER_PRINT(_parms, _table) \
dvb_table_header_print(_parms, &_table->header); \
dvb_loginfo("| protocol_version %d", _table->protocol_version); \
#endif /* _DOXYGEN */
#endif /* _ATSC_HEADER_H */

106
include/libdvbv5/cat.h Normal file
View File

@@ -0,0 +1,106 @@
/*
* Copyright (c) 2013 - Andre Roth <neolynx@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation version 2.1 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
* Or, point your browser to http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
*/
/**
* @file cat.h
* @ingroup dvb_table
* @brief Provides the table parser for the CAT (Conditional Access Table)
* @copyright GNU Lesser General Public License version 2.1 (LGPLv2.1)
* @author Andre Roth
*
* @par Bug Report
* Please submit bug reports and patches to linux-media@vger.kernel.org
*/
#ifndef _CAT_H
#define _CAT_H
#include <stdint.h>
#include <unistd.h> /* ssize_t */
#include <libdvbv5/header.h>
/**
* @def DVB_TABLE_CAT
* @brief ATSC CAT table ID
* @ingroup dvb_table
* @def DVB_TABLE_CAT_PID
* @brief ATSC PID table ID
* @ingroup dvb_table
*/
#define DVB_TABLE_CAT 0x01
#define DVB_TABLE_CAT_PID 0x0001
/**
* @struct dvb_table_cat
* @brief ATSC CAT table
*
* @param header struct dvb_table_header content
* @param descriptor pointer to struct dvb_desc
*/
struct dvb_table_cat {
struct dvb_table_header header;
struct dvb_desc *descriptor;
} __attribute__((packed));
struct dvb_v5_fe_parms;
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Initializes and parses CAT table
*
* @param parms struct dvb_v5_fe_parms pointer to the opened device
* @param buf buffer containing the CAT raw data
* @param buflen length of the buffer
* @param table pointer to struct dvb_table_cat to be allocated and filled
*
* This function allocates an CAT table and fills the fields inside
* the struct. It also makes sure that all fields will follow the CPU
* endianness. Due to that, the content of the buffer may change.
*
* @return On success, it returns the size of the allocated struct.
* A negative value indicates an error.
*/
ssize_t dvb_table_cat_init(struct dvb_v5_fe_parms *parms, const uint8_t *buf,
ssize_t buflen, struct dvb_table_cat **table);
/**
* @brief Frees all data allocated by the CAT table parser
*
* @param table pointer to struct dvb_table_cat to be freed
*/
void dvb_table_cat_free(struct dvb_table_cat *table);
/**
* @brief Prints the content of the CAT table
*
* @param parms struct dvb_v5_fe_parms pointer to the opened device
* @param table pointer to struct dvb_table_cat
*/
void dvb_table_cat_print(struct dvb_v5_fe_parms *parms,
struct dvb_table_cat *table);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,869 @@
/*
* Copyright (C) 2006, 2007, 2008, 2009 Winfried Koehler
* Copyright (C) 2014 Akihiro Tsukada
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation version 2.1 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. if not, see <http://www.gnu.org/licenses/>.
*
*/
/**
* @file countries.h
* @ingroup ancillary
* @brief Provides ancillary code to convert ISO 3166-1 country codes
* @copyright GNU Lesser General Public License version 2.1 (LGPLv2.1)
* @author Winfried Koehler
* @author Akihiro Tsukada
*
* @par Bug Report
* Please submit bug reports and patches to linux-media@vger.kernel.org
*/
#ifndef _COUNTRIES_H_
#define _COUNTRIES_H_
#ifdef __cplusplus
extern "C" {
#endif
/**
* @enum dvb_country_t
* @brief ISO-3166-1 alpha-2 country code
* @ingroup ancillary
*
* @var COUNTRY_UNKNOWN
* @brief (Unknown Country)
* @var AD
* @brief Andorra
* @var AE
* @brief United Arab Emirates
* @var AF
* @brief Afghanistan
* @var AG
* @brief Antigua and Barbuda
* @var AI
* @brief Anguilla
* @var AL
* @brief Albania
* @var AM
* @brief Armenia
* @var AO
* @brief Angola
* @var AQ
* @brief Antarctica
* @var AR
* @brief Argentina
* @var AS
* @brief American Samoa
* @var AT
* @brief Austria
* @var AU
* @brief Australia
* @var AW
* @brief Aruba
* @var AX
* @brief Aland Islands
* @var AZ
* @brief Azerbaijan
* @var BA
* @brief Bosnia and Herzegovina
* @var BB
* @brief Barbados
* @var BD
* @brief Bangladesh
* @var BE
* @brief Belgium
* @var BF
* @brief Burkina Faso
* @var BG
* @brief Bulgaria
* @var BH
* @brief Bahrain
* @var BI
* @brief Burundi
* @var BJ
* @brief Benin
* @var BL
* @brief Saint Barthelemy
* @var BM
* @brief Bermuda
* @var BN
* @brief Brunei Darussalam
* @var BO
* @brief Plurinational State of Bolivia
* @var BQ
* @brief Bonaire, Saint Eustatius and Saba
* @var BR
* @brief Brazil
* @var BS
* @brief Bahamas
* @var BT
* @brief Bhutan
* @var BV
* @brief Bouvet Island
* @var BW
* @brief Botswana
* @var BY
* @brief Belarus
* @var BZ
* @brief Belize
* @var CA
* @brief Canada
* @var CC
* @brief Cocos (Keeling) Islands
* @var CD
* @brief The Democratic Republic of the Congo
* @var CF
* @brief Central African Republic
* @var CG
* @brief Congo
* @var CH
* @brief Switzerland
* @var CI
* @brief Cote d'Ivoire
* @var CK
* @brief Cook Islands
* @var CL
* @brief Chile
* @var CM
* @brief Cameroon
* @var CN
* @brief China
* @var CO
* @brief Colombia
* @var CR
* @brief Costa Rica
* @var CU
* @brief Cuba
* @var CV
* @brief Cape Verde
* @var CW
* @brief Curacao
* @var CX
* @brief Christmas Island
* @var CY
* @brief Cyprus
* @var CZ
* @brief Czech Republic
* @var DE
* @brief Germany
* @var DJ
* @brief Djibouti
* @var DK
* @brief Denmark
* @var DM
* @brief Dominica
* @var DO
* @brief Dominican Republic
* @var DZ
* @brief Algeria
* @var EC
* @brief Ecuador
* @var EE
* @brief Estonia
* @var EG
* @brief Egypt
* @var EH
* @brief Western Sahara
* @var ER
* @brief Eritrea
* @var ES
* @brief Spain
* @var ET
* @brief Ethiopia
* @var FI
* @brief Finland
* @var FJ
* @brief Fiji
* @var FK
* @brief Falkland Islands (Malvinas)
* @var FM
* @brief Federated States of Micronesia
* @var FO
* @brief Faroe Islands
* @var FR
* @brief France
* @var GA
* @brief Gabon
* @var GB
* @brief United Kingdom
* @var GD
* @brief Grenada
* @var GE
* @brief Georgia
* @var GF
* @brief French Guiana
* @var GG
* @brief Guernsey
* @var GH
* @brief Ghana
* @var GI
* @brief Gibraltar
* @var GL
* @brief Greenland
* @var GM
* @brief Gambia
* @var GN
* @brief Guinea
* @var GP
* @brief Guadeloupe
* @var GQ
* @brief Equatorial Guinea
* @var GR
* @brief Greece
* @var GS
* @brief South Georgia and the South Sandwich Islands
* @var GT
* @brief Guatemala
* @var GU
* @brief Guam
* @var GW
* @brief Guinea-Bissau
* @var GY
* @brief Guyana
* @var HK
* @brief Hong Kong
* @var HM
* @brief Heard Island and McDonald Islands
* @var HN
* @brief Honduras
* @var HR
* @brief Croatia
* @var HT
* @brief Haiti
* @var HU
* @brief Hungary
* @var ID
* @brief Indonesia
* @var IE
* @brief Ireland
* @var IL
* @brief Israel
* @var IM
* @brief Isle of Man
* @var IN
* @brief India
* @var IO
* @brief British Indian Ocean Territory
* @var IQ
* @brief Iraq
* @var IR
* @brief Islamic Republic of Iran
* @var IS
* @brief Iceland
* @var IT
* @brief Italy
* @var JE
* @brief Jersey
* @var JM
* @brief Jamaica
* @var JO
* @brief Jordan
* @var JP
* @brief Japan
* @var KE
* @brief Kenya
* @var KG
* @brief Kyrgyzstan
* @var KH
* @brief Cambodia
* @var KI
* @brief Kiribati
* @var KM
* @brief Comoros
* @var KN
* @brief Saint Kitts and Nevis
* @var KP
* @brief Democratic People's Republic of Korea
* @var KR
* @brief Republic of Korea
* @var KW
* @brief Kuwait
* @var KY
* @brief Cayman Islands
* @var KZ
* @brief Kazakhstan
* @var LA
* @brief Lao People's Democratic Republic
* @var LB
* @brief Lebanon
* @var LC
* @brief Saint Lucia
* @var LI
* @brief Liechtenstein
* @var LK
* @brief Sri Lanka
* @var LR
* @brief Liberia
* @var LS
* @brief Lesotho
* @var LT
* @brief Lithuania
* @var LU
* @brief Luxembourg
* @var LV
* @brief Latvia
* @var LY
* @brief Libyan Arab Jamahiriya
* @var MA
* @brief Morocco
* @var MC
* @brief Monaco
* @var MD
* @brief Republic of Moldova
* @var ME
* @brief Montenegro
* @var MF
* @brief Saint Martin (French part)
* @var MG
* @brief Madagascar
* @var MH
* @brief Marshall Islands
* @var MK
* @brief The Former Yugoslav Republic of Macedonia
* @var ML
* @brief Mali
* @var MM
* @brief Myanmar
* @var MN
* @brief Mongolia
* @var MO
* @brief Macao
* @var MP
* @brief Northern Mariana Islands
* @var MQ
* @brief Martinique
* @var MR
* @brief Mauritania
* @var MS
* @brief Montserrat
* @var MT
* @brief Malta
* @var MU
* @brief Mauritius
* @var MV
* @brief Maldives
* @var MW
* @brief Malawi
* @var MX
* @brief Mexico
* @var MY
* @brief Malaysia
* @var MZ
* @brief Mozambique
* @var NA
* @brief Namibia
* @var NC
* @brief New Caledonia
* @var NE
* @brief Niger
* @var NF
* @brief Norfolk Island
* @var NG
* @brief Nigeria
* @var NI
* @brief Nicaragua
* @var NL
* @brief Netherlands
* @var NO
* @brief Norway
* @var NP
* @brief Nepal
* @var NR
* @brief Nauru
* @var NU
* @brief Niue
* @var NZ
* @brief New Zealand
* @var OM
* @brief Oman
* @var PA
* @brief Panama
* @var PE
* @brief Peru
* @var PF
* @brief French Polynesia
* @var PG
* @brief Papua New Guinea
* @var PH
* @brief Philippines
* @var PK
* @brief Pakistan
* @var PL
* @brief Poland
* @var PM
* @brief Saint Pierre and Miquelon
* @var PN
* @brief Pitcairn
* @var PR
* @brief Puerto Rico
* @var PS
* @brief Occupied Palestinian Territory
* @var PT
* @brief Portugal
* @var PW
* @brief Palau
* @var PY
* @brief Paraguay
* @var QA
* @brief Qatar
* @var RE
* @brief Reunion
* @var RO
* @brief Romania
* @var RS
* @brief Serbia
* @var RU
* @brief Russian Federation
* @var RW
* @brief Rwanda
* @var SA
* @brief Saudi Arabia
* @var SB
* @brief Solomon Islands
* @var SC
* @brief Seychelles
* @var SD
* @brief Sudan
* @var SE
* @brief Sweden
* @var SG
* @brief Singapore
* @var SH
* @brief Saint Helena, Ascension and Tristan da Cunha
* @var SI
* @brief Slovenia
* @var SJ
* @brief Svalbard and Jan Mayen
* @var SK
* @brief Slovakia
* @var SL
* @brief Sierra Leone
* @var SM
* @brief San Marino
* @var SN
* @brief Senegal
* @var SO
* @brief Somalia
* @var SR
* @brief Suriname
* @var SS
* @brief South Sudan
* @var ST
* @brief Sao Tome and Principe
* @var SV
* @brief El Salvador
* @var SX
* @brief Sint Maarten (Dutch part)
* @var SY
* @brief Syrian Arab Republic
* @var SZ
* @brief Swaziland
* @var TC
* @brief Turks and Caicos Islands
* @var TD
* @brief Chad
* @var TF
* @brief French Southern Territories
* @var TG
* @brief Togo
* @var TH
* @brief Thailand
* @var TJ
* @brief Tajikistan
* @var TK
* @brief Tokelau
* @var TL
* @brief Timor-Leste
* @var TM
* @brief Turkmenistan
* @var TN
* @brief Tunisia
* @var TO
* @brief Tonga
* @var TR
* @brief Turkey
* @var TT
* @brief Trinidad and Tobago
* @var TV
* @brief Tuvalu
* @var TW
* @brief Taiwan, Province of China
* @var TZ
* @brief United Republic of Tanzania
* @var UA
* @brief Ukraine
* @var UG
* @brief Uganda
* @var UM
* @brief United States Minor Outlying Islands
* @var US
* @brief United States
* @var UY
* @brief Uruguay
* @var UZ
* @brief Uzbekistan
* @var VA
* @brief Holy See (Vatican City State)
* @var VC
* @brief Saint Vincent and The Grenadines
* @var VE
* @brief Bolivarian Republic of Venezuela
* @var VG
* @brief British Virgin Islands
* @var VI
* @brief U.S. Virgin Islands
* @var VN
* @brief Viet Nam
* @var VU
* @brief Vanuatu
* @var WF
* @brief Wallis and Futuna
* @var WS
* @brief Samoa
* @var YE
* @brief Yemen
* @var YT
* @brief Mayotte
* @var ZA
* @brief South Africa
* @var ZM
* @brief Zambia
* @var ZW
* @brief Zimbabwe
*/
enum dvb_country_t {
COUNTRY_UNKNOWN,
AD,
AE,
AF,
AG,
AI,
AL,
AM,
AO,
AQ,
AR,
AS,
AT,
AU,
AW,
AX,
AZ,
BA,
BB,
BD,
BE,
BF,
BG,
BH,
BI,
BJ,
BL,
BM,
BN,
BO,
BQ,
BR,
BS,
BT,
BV,
BW,
BY,
BZ,
CA,
CC,
CD,
CF,
CG,
CH,
CI,
CK,
CL,
CM,
CN,
CO,
CR,
CU,
CV,
CW,
CX,
CY,
CZ,
DE,
DJ,
DK,
DM,
DO,
DZ,
EC,
EE,
EG,
EH,
ER,
ES,
ET,
FI,
FJ,
FK,
FM,
FO,
FR,
GA,
GB,
GD,
GE,
GF,
GG,
GH,
GI,
GL,
GM,
GN,
GP,
GQ,
GR,
GS,
GT,
GU,
GW,
GY,
HK,
HM,
HN,
HR,
HT,
HU,
ID,
IE,
IL,
IM,
IN,
IO,
IQ,
IR,
IS,
IT,
JE,
JM,
JO,
JP,
KE,
KG,
KH,
KI,
KM,
KN,
KP,
KR,
KW,
KY,
KZ,
LA,
LB,
LC,
LI,
LK,
LR,
LS,
LT,
LU,
LV,
LY,
MA,
MC,
MD,
ME,
MF,
MG,
MH,
MK,
ML,
MM,
MN,
MO,
MP,
MQ,
MR,
MS,
MT,
MU,
MV,
MW,
MX,
MY,
MZ,
NA,
NC,
NE,
NF,
NG,
NI,
NL,
NO,
NP,
NR,
NU,
NZ,
OM,
PA,
PE,
PF,
PG,
PH,
PK,
PL,
PM,
PN,
PR,
PS,
PT,
PW,
PY,
QA,
RE,
RO,
RS,
RU,
RW,
SA,
SB,
SC,
SD,
SE,
SG,
SH,
SI,
SJ,
SK,
SL,
SM,
SN,
SO,
SR,
SS,
ST,
SV,
SX,
SY,
SZ,
TC,
TD,
TF,
TG,
TH,
TJ,
TK,
TL,
TM,
TN,
TO,
TR,
TT,
TV,
TW,
TZ,
UA,
UG,
UM,
US,
UY,
UZ,
VA,
VC,
VE,
VG,
VI,
VN,
VU,
WF,
WS,
YE,
YT,
ZA,
ZM,
ZW,
};
/**
* @brief Converts an Unix-like 2-letter Country code into enum dvb_country_t
* @ingroup ancillary
*
* @param name two-letter Country code.
*
* @return It returns the corresponding enum dvb_country_t ID. If not found,
* returns COUNTRY_UNKNOWN.
*/
enum dvb_country_t dvb_country_a2_to_id(const char *name);
/**
* @brief Converts a 3-letter Country code as used by MPEG-TS tables into
* enum dvb_country_t
* @ingroup ancillary
*
* @param name three-letter Country code.
*
* @return It returns the corresponding enum dvb_country_t ID. If not found,
* returns COUNTRY_UNKNOWN.
*/
enum dvb_country_t dvb_country_a3_to_id(const char *name);
/**
* @brief Converts an enum dvb_country_t into Unix-like 2-letter Country code
* @ingroup ancillary
*
* @param id enum dvb_country_t ID.
*
* @return It returns the 2-letter country code string that corresponts to the
* Country. If not found, returns NULL.
*/
const char *dvb_country_to_2letters(int id);
/**
* @brief Converts an enum dvb_country_t into a 3-letter Country code
* as used by MPEG-TS tables
* @ingroup ancillary
*
* @param id enum dvb_country_t ID.
*
* @return It returns the 3-letter country code string that corresponts to the
* Country. If not found, returns NULL.
*/
const char *dvb_country_to_3letters(int id);
/**
* @brief Converts an enum dvb_country_t into a Country name
* as used by MPEG-TS tables
* @ingroup ancillary
*
* @param id enum dvb_country_t ID.
*
* @return It returns a string with the Country name that corresponts to the
* country. If not found, returns NULL.
*/
const char *dvb_country_to_name(int id);
/**
* @brief Guess the country code from the Unix environment variables
* @ingroup ancillary
*
* @return It returns the corresponding enum dvb_country_t ID. If not found,
* returns COUNTRY_UNKNOWN.
*/
enum dvb_country_t dvb_guess_user_country(void);
#ifdef __cplusplus
}
#endif
#endif

58
include/libdvbv5/crc32.h Normal file
View File

@@ -0,0 +1,58 @@
/*
* Copyright (c) 2011-2012 - Mauro Carvalho Chehab
* Copyright (c) 2012-2014 - Andre Roth <neolynx@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation version 2.1 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
* Or, point your browser to http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
*/
/**
* @file crc32.h
* @ingroup ancillary
* @brief Provides ancillary code to calculate DVB crc32 checksum
* @copyright GNU Lesser General Public License version 2.1 (LGPLv2.1)
* @author Mauro Carvalho Chehab
* @author Andre Roth
*
* @par Bug Report
* Please submit bug reports and patches to linux-media@vger.kernel.org
*/
#ifndef _CRC32_H
#define _CRC32_H
#include <stdint.h>
#include <unistd.h> /* size_t */
#ifdef __cplusplus
extern "C" {
#endif
/** @brief Calculates the crc-32 as defined at the MPEG-TS specs
* @ingroup ancillary
*
* @param data Pointer to the buffer to be checked
* @param datalen Length of the buffer
* @param crc Initial value for the crc checksum. To calculate the
* checksum of the entire packet at once, use 0xFFFFFFFF
*/
uint32_t dvb_crc32(uint8_t *data, size_t datalen, uint32_t crc);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,140 @@
/*
* Copyright (c) 2013-2014 - Mauro Carvalho Chehab <mchehab@kernel.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation version 2.1 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
* Or, point your browser to http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
*/
#ifndef _ATSC_SERVICE_LOCATION_H
#define _ATSC_SERVICE_LOCATION_H
#include <libdvbv5/descriptors.h>
/**
* @file desc_atsc_service_location.h
* @ingroup descriptors
* @brief Provides the descriptors for ATSC service location
* @copyright GNU Lesser General Public License version 2.1 (LGPLv2.1)
* @author Mauro Carvalho Chehab
*
* @par Relevant specs
* The descriptor described herein is defined at:
* - ATSC A/53
*
* @see http://www.etherguidesystems.com/help/sdos/atsc/semantics/descriptors/ServiceLocation.aspx
*
* @par Bug Report
* Please submit bug reports and patches to linux-media@vger.kernel.org
*/
/**
* @struct atsc_desc_service_location_elementary
* @ingroup descriptors
* @brief service location elementary descriptors
*
* @param stream_type stream type
* @param elementary_pid elementary pid
* @param ISO_639_language_code ISO 639 language code
*/
struct atsc_desc_service_location_elementary {
uint8_t stream_type;
union {
uint16_t bitfield;
struct {
uint16_t elementary_pid:13;
uint16_t reserved:3;
} __attribute__((packed));
} __attribute__((packed));
unsigned char ISO_639_language_code[3];
} __attribute__((packed));
/**
* @struct atsc_desc_service_location
* @ingroup descriptors
* @brief Describes the elementary streams inside a PAT table for ATSC
*
* @param type descriptor tag
* @param length descriptor length
* @param next pointer to struct dvb_desc
* @param elementary pointer to struct atsc_desc_service_location_elementary
* @param pcr_pid PCR pid
* @param number_elements number elements
*/
struct atsc_desc_service_location {
uint8_t type;
uint8_t length;
struct dvb_desc *next;
struct atsc_desc_service_location_elementary *elementary;
union {
uint16_t bitfield;
struct {
uint16_t pcr_pid:13;
uint16_t reserved:3;
} __attribute__((packed));
} __attribute__((packed));
uint8_t number_elements;
} __attribute__((packed));
struct dvb_v5_fe_parms;
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Initializes and parses the service location descriptor
* @ingroup descriptors
*
* @param parms struct dvb_v5_fe_parms pointer to the opened device
* @param buf buffer containing the descriptor's raw data
* @param desc pointer to struct dvb_desc to be allocated and filled
*
* This function allocates a the descriptor and fills the fields inside
* the struct. It also makes sure that all fields will follow the CPU
* endianness. Due to that, the content of the buffer may change.
*
* @return On success, it returns the size of the allocated struct.
* A negative value indicates an error.
*/
int atsc_desc_service_location_init(struct dvb_v5_fe_parms *parms,
const uint8_t *buf,
struct dvb_desc *desc);
/**
* @brief Prints the content of the service location descriptor
* @ingroup descriptors
*
* @param parms struct dvb_v5_fe_parms pointer to the opened device
* @param desc pointer to struct dvb_desc
*/
void atsc_desc_service_location_print(struct dvb_v5_fe_parms *parms,
const struct dvb_desc *desc);
/**
* @brief Frees all data allocated by the service location descriptor
* @ingroup descriptors
*
* @param desc pointer to struct dvb_desc to be freed
*/
void atsc_desc_service_location_free(struct dvb_desc *desc);
#ifdef __cplusplus
}
#endif
#endif

125
include/libdvbv5/desc_ca.h Normal file
View File

@@ -0,0 +1,125 @@
/*
* Copyright (c) 2013 - Andre Roth <neolynx@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation version 2.1 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
* Or, point your browser to http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
* Described at ETSI EN 300 468 V1.11.1 (2010-04)
*/
/**
* @file desc_ca.h
* @ingroup descriptors
* @brief Provides the descriptors for Conditional Access
* @copyright GNU Lesser General Public License version 2.1 (LGPLv2.1)
* @author Andre Roth
*
* @par Relevant specs
* The descriptor described herein is defined at:
* - ETSI EN 300 468 V1.11.1 (2010-04)
*
* @see http://www.etherguidesystems.com/help/sdos/mpeg/semantics/mpeg-2/descriptors/CA_descriptor.aspx
*
* @par Bug Report
* Please submit bug reports and patches to linux-media@vger.kernel.org
*/
#ifndef _CA_H
#define _CA_H
#include <libdvbv5/descriptors.h>
/**
* @struct dvb_desc_ca
* @ingroup descriptors
* @brief Contains the private data for Conditional Access
*
* @param type descriptor tag
* @param length descriptor length
* @param next pointer to struct dvb_desc
* @param ca_id Conditional Access ID
* @param ca_pid Conditional Access ID
* @param privdata pointer to private data buffer
* @param privdata_len length of the private data
*/
struct dvb_desc_ca {
uint8_t type;
uint8_t length;
struct dvb_desc *next;
uint16_t ca_id;
union {
uint16_t bitfield1;
struct {
uint16_t ca_pid:13;
uint16_t reserved:3;
} __attribute__((packed));
} __attribute__((packed));
uint8_t *privdata;
uint8_t privdata_len;
} __attribute__((packed));
struct dvb_v5_fe_parms;
/** @brief initial descriptor field at dvb_desc_ca struct */
#define dvb_desc_ca_field_first ca_id
/** @brief last descriptor field at dvb_desc_ca struct */
#define dvb_desc_ca_field_last privdata
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Initializes and parses the CA descriptor
* @ingroup descriptors
*
* @param parms struct dvb_v5_fe_parms pointer to the opened device
* @param buf buffer containing the descriptor's raw data
* @param desc pointer to struct dvb_desc to be allocated and filled
*
* This function allocates a the descriptor and fills the fields inside
* the struct. It also makes sure that all fields will follow the CPU
* endianness. Due to that, the content of the buffer may change.
*
* @return On success, it returns the size of the allocated struct.
* A negative value indicates an error.
*/
int dvb_desc_ca_init(struct dvb_v5_fe_parms *parms, const uint8_t *buf,
struct dvb_desc *desc);
/**
* @brief Prints the content of the CA descriptor
* @ingroup descriptors
*
* @param parms struct dvb_v5_fe_parms pointer to the opened device
* @param desc pointer to struct dvb_desc
*/
void dvb_desc_ca_print(struct dvb_v5_fe_parms *parms,
const struct dvb_desc *desc);
/**
* @brief Frees all data allocated by the CA descriptor
* @ingroup descriptors
*
* @param desc pointer to struct dvb_desc to be freed
*/
void dvb_desc_ca_free(struct dvb_desc *desc);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,114 @@
/*
* Copyright (c) 2013 - Andre Roth <neolynx@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation version 2.1 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
* Or, point your browser to http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
* Described at ETSI EN 300 468 V1.11.1 (2010-04)
*/
/**
* @file desc_ca_identifier.h
* @ingroup descriptors
* @brief Provides the descriptors for the Conditional Access identifier
* @copyright GNU Lesser General Public License version 2.1 (LGPLv2.1)
* @author Andre Roth
*
* @par Relevant specs
* The descriptor described herein is defined at:
* - ETSI EN 300 468 V1.11.1 (2010-04)
*
* @par Bug Report
* Please submit bug reports and patches to linux-media@vger.kernel.org
*/
#ifndef _CA_IDENTIFIER_H
#define _CA_IDENTIFIER_H
#include <libdvbv5/descriptors.h>
/**
* @struct dvb_desc_ca_identifier
* @ingroup descriptors
* @brief Indicates if a particular bouquet, service or event is associated
* with a CA system
*
* @param type descriptor tag
* @param length descriptor length
* @param next pointer to struct dvb_desc
* @param caid_count Number of CA IDs
* @param caids CA Identifier IDs
*/
struct dvb_desc_ca_identifier {
uint8_t type;
uint8_t length;
struct dvb_desc *next;
uint8_t caid_count;
uint16_t *caids;
} __attribute__((packed));
struct dvb_v5_fe_parms;
/** @brief initial descriptor field at dvb_desc_ca_identifier struct */
#define dvb_desc_ca_identifier_field_first ca_id
/** @brief last descriptor field at dvb_desc_ca_identifier struct */
#define dvb_desc_ca_identifier_field_last privdata
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Initializes and parses the CA identifier descriptor
* @ingroup descriptors
*
* @param parms struct dvb_v5_fe_parms pointer to the opened device
* @param buf buffer containing the descriptor's raw data
* @param desc pointer to struct dvb_desc to be allocated and filled
*
* This function allocates a the descriptor and fills the fields inside
* the struct. It also makes sure that all fields will follow the CPU
* endianness. Due to that, the content of the buffer may change.
*
* @return On success, it returns the size of the allocated struct.
* A negative value indicates an error.
*/
int dvb_desc_ca_identifier_init(struct dvb_v5_fe_parms *parms,
const uint8_t *buf, struct dvb_desc *desc);
/**
* @brief Prints the content of the CA identifier descriptor
* @ingroup descriptors
*
* @param parms struct dvb_v5_fe_parms pointer to the opened device
* @param desc pointer to struct dvb_desc
*/
void dvb_desc_ca_identifier_print(struct dvb_v5_fe_parms *parms,
const struct dvb_desc *desc);
/**
* @brief Frees all data allocated by the CA identifier descriptor
* @ingroup descriptors
*
* @param desc pointer to struct dvb_desc to be freed
*/
void dvb_desc_ca_identifier_free(struct dvb_desc *desc);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,132 @@
/*
* Copyright (c) 2011-2014 - Mauro Carvalho Chehab
* Copyright (c) 2012 - Andre Roth <neolynx@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation version 2.1 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
* Or, point your browser to http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
* Described at ETSI EN 300 468 V1.11.1 (2010-04)
*/
/**
* @file desc_cable_delivery.h
* @ingroup descriptors
* @brief Provides the descriptors for the cable delivery system descriptor
* @copyright GNU Lesser General Public License version 2.1 (LGPLv2.1)
* @author Mauro Carvalho Chehab
* @author Andre Roth
*
* @par Relevant specs
* The descriptor described herein is defined at:
* - ETSI EN 300 468 V1.11.1 (2010-04)
*
* @par Bug Report
* Please submit bug reports and patches to linux-media@vger.kernel.org
*/
#ifndef _CABLE_DELIVERY_H
#define _CABLE_DELIVERY_H
#include <libdvbv5/descriptors.h>
/**
* @struct dvb_desc_cable_delivery
* @ingroup descriptors
* @brief Structure containing the cable delivery system descriptor
*
* @param type descriptor tag
* @param length descriptor length
* @param next pointer to struct dvb_desc
* @param frequency frequency, converted to Hz.
* @param fec_outer FEC outer (typically, Viterbi)
* @param modulation modulation
* @param fec_inner FEC inner (convolutional code)
* @param symbol_rate symbol rate, converted to symbols/sec (bauds)
*/
struct dvb_desc_cable_delivery {
uint8_t type;
uint8_t length;
struct dvb_desc *next;
uint32_t frequency;
union {
uint16_t bitfield1;
struct {
uint16_t fec_outer:4;
uint16_t reserved_future_use:12;
} __attribute__((packed));
} __attribute__((packed));
uint8_t modulation;
union {
uint32_t bitfield2;
struct {
uint32_t fec_inner:4;
uint32_t symbol_rate:28;
} __attribute__((packed));
} __attribute__((packed));
} __attribute__((packed));
struct dvb_v5_fe_parms;
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Initializes and parses the service location descriptor
* @ingroup descriptors
*
* @param parms struct dvb_v5_fe_parms pointer to the opened device
* @param buf buffer containing the descriptor's raw data
* @param desc pointer to struct dvb_desc to be allocated and filled
*
* This function initializes and makes sure that all fields will follow the CPU
* endianness. Due to that, the content of the buffer may change.
*
* Currently, no memory is allocated internally.
*
* @return On success, it returns the size of the allocated struct.
* A negative value indicates an error.
*/
int dvb_desc_cable_delivery_init(struct dvb_v5_fe_parms *parms,
const uint8_t *buf, struct dvb_desc *desc);
/**
* @brief Prints the content of the service location descriptor
* @ingroup descriptors
*
* @param parms struct dvb_v5_fe_parms pointer to the opened device
* @param desc pointer to struct dvb_desc
*/
void dvb_desc_cable_delivery_print(struct dvb_v5_fe_parms *parms,
const struct dvb_desc *desc);
/**
* @brief converts from the descriptor's modulation into enum fe_modulation,
* as defined by DVBv5 API.
*/
extern const unsigned dvbc_modulation_table[];
/**
* @brief converts from the descriptor's FEC into enum fe_code_rate,
* as defined by DVBv5 API.
*/
extern const unsigned dvbc_fec_table[];
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,134 @@
/*
* Copyright (c) 2011-2014 - Mauro Carvalho Chehab
* Copyright (c) 2012 - Andre Roth <neolynx@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation version 2.1 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
* Or, point your browser to http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
*/
/**
* @file desc_event_extended.h
* @ingroup descriptors
* @brief Provides the descriptors for the extended event descriptor
* @copyright GNU Lesser General Public License version 2.1 (LGPLv2.1)
* @author Mauro Carvalho Chehab
* @author Andre Roth
*
* @par Relevant specs
* The descriptor described herein is defined at:
* - ETSI EN 300 468 V1.11.1
*
* @par Bug Report
* Please submit bug reports and patches to linux-media@vger.kernel.org
*/
#ifndef _DESC_EVENT_EXTENDED_H
#define _DESC_EVENT_EXTENDED_H
#include <libdvbv5/descriptors.h>
struct dvb_desc_event_extended_item {
char *description;
char *description_emph;
char *item;
char *item_emph;
};
/**
* @struct dvb_desc_event_extended
* @ingroup descriptors
* @brief Structure containing the extended event descriptor
*
* @param type descriptor tag
* @param length descriptor length
* @param next pointer to struct dvb_desc
* @param id descriptor number
* @param last_id last descriptor number
* @param language ISO 639 language code
* @param text text string
* @param text_emph text emphasis string
*
* @details
* The emphasis text is the one that uses asterisks. For example, in the text:
* "the quick *fox* jumps over the lazy table" the emphasis would be "fox".
*/
struct dvb_desc_event_extended {
uint8_t type;
uint8_t length;
struct dvb_desc *next;
union {
struct {
uint8_t last_id:4;
uint8_t id:4;
} __attribute__((packed));
uint8_t ids;
} __attribute__((packed));
unsigned char language[4];
char *text;
char *text_emph;
struct dvb_desc_event_extended_item *items;
int num_items;
} __attribute__((packed));
struct dvb_v5_fe_parms;
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Initializes and parses the extended event descriptor
* @ingroup descriptors
*
* @param parms struct dvb_v5_fe_parms pointer to the opened device
* @param buf buffer containing the descriptor's raw data
* @param desc pointer to struct dvb_desc to be allocated and filled
*
* This function allocates a the descriptor and fills the fields inside
* the struct. It also makes sure that all fields will follow the CPU
* endianness. Due to that, the content of the buffer may change.
*
* @return On success, it returns the size of the allocated struct.
* A negative value indicates an error.
*/
int dvb_desc_event_extended_init(struct dvb_v5_fe_parms *parms,
const uint8_t *buf, struct dvb_desc *desc);
/**
* @brief Prints the content of the extended event descriptor
* @ingroup descriptors
*
* @param parms struct dvb_v5_fe_parms pointer to the opened device
* @param desc pointer to struct dvb_desc
*/
void dvb_desc_event_extended_print(struct dvb_v5_fe_parms *parms,
const struct dvb_desc *desc);
/**
* @brief Frees all data allocated by the extended event descriptor
* @ingroup descriptors
*
* @param desc pointer to struct dvb_desc to be freed
*/
void dvb_desc_event_extended_free(struct dvb_desc *desc);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,118 @@
/*
* Copyright (c) 2011-2014 - Mauro Carvalho Chehab
* Copyright (c) 2012 - Andre Roth <neolynx@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation version 2.1 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
* Or, point your browser to http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
*/
/**
* @file desc_event_short.h
* @ingroup descriptors
* @brief Provides the descriptors for the short event descriptor
* @copyright GNU Lesser General Public License version 2.1 (LGPLv2.1)
* @author Mauro Carvalho Chehab
* @author Andre Roth
*
* @par Relevant specs
* The descriptor described herein is defined at:
* - ETSI EN 300 468 V1.11.1
*
* @par Bug Report
* Please submit bug reports and patches to linux-media@vger.kernel.org
*/
#ifndef _DESC_EVENT_SHORT_H
#define _DESC_EVENT_SHORT_H
#include <libdvbv5/descriptors.h>
/**
* @struct dvb_desc_event_short
* @ingroup descriptors
* @brief Structure containing the short event descriptor
*
* @param type descriptor tag
* @param length descriptor length
* @param next pointer to struct dvb_desc
* @param language ISO 639 language code
* @param name event name string
* @param name_emph event name emphasis string
* @param text event text string
* @param text_emph event text emphasis string
*
* @details
* The emphasis text is the one that uses asterisks. For example, in the text:
* "the quick *fox* jumps over the lazy table" the emphasis would be "fox".
*/
struct dvb_desc_event_short {
uint8_t type;
uint8_t length;
struct dvb_desc *next;
unsigned char language[4];
char *name;
char *name_emph;
char *text;
char *text_emph;
} __attribute__((packed));
struct dvb_v5_fe_parms;
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Initializes and parses the short event descriptor
* @ingroup descriptors
*
* @param parms struct dvb_v5_fe_parms pointer to the opened device
* @param buf buffer containing the descriptor's raw data
* @param desc pointer to struct dvb_desc to be allocated and filled
*
* This function allocates a the descriptor and fills the fields inside
* the struct. It also makes sure that all fields will follow the CPU
* endianness. Due to that, the content of the buffer may change.
*
* @return On success, it returns the size of the allocated struct.
* A negative value indicates an error.
*/
int dvb_desc_event_short_init(struct dvb_v5_fe_parms *parms,
const uint8_t *buf, struct dvb_desc *desc);
/**
* @brief Prints the content of the short event descriptor
* @ingroup descriptors
*
* @param parms struct dvb_v5_fe_parms pointer to the opened device
* @param desc pointer to struct dvb_desc
*/
void dvb_desc_event_short_print(struct dvb_v5_fe_parms *parms,
const struct dvb_desc *desc);
/**
* @brief Frees all data allocated by the short event descriptor
* @ingroup descriptors
*
* @param desc pointer to struct dvb_desc to be freed
*/
void dvb_desc_event_short_free(struct dvb_desc *desc);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,224 @@
/*
* Copyright (c) 2013-2014 - Mauro Carvalho Chehab <mchehab@kernel.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation version 2.1 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
* Or, point your browser to http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
*/
/**
* @file desc_extension.h
* @ingroup descriptors
* @brief Provides the descriptors for the extension descriptor.
* The extension descriptor is used to extend the 8-bit namespace
* of the descriptor_tag field.
* @copyright GNU Lesser General Public License version 2.1 (LGPLv2.1)
* @author Mauro Carvalho Chehab
*
* @par Relevant specs
* The descriptor described herein is defined at:
*
* @see
* - ETSI EN 300 468 V1.11.1
*
* @par Bug Report
* Please submit bug reports and patches to linux-media@vger.kernel.org
*/
#ifndef _EXTENSION_DESC_H
#define _EXTENSION_DESC_H
#include <libdvbv5/descriptors.h>
struct dvb_v5_fe_parms;
/**
* @enum extension_descriptors
* @brief List containing all extended descriptors used by Digital TV MPEG-TS
* as defined at ETSI EN 300 468 V1.11.1
* @ingroup descriptors
*
* @var image_icon_descriptor
* @brief image icon descriptor
*
* @var cpcm_delivery_signalling_descriptor
* @brief Content Protection/Copy Management (CPCM) delivery signalling
* descriptor
*
* @var CP_descriptor
* @brief Content Protection descriptor
*
* @var CP_identifier_descriptor
* @brief Content Protection identifier descriptor
*
* @var T2_delivery_system_descriptor
* @brief DVB-T2 delivery system descriptor
*
* @var SH_delivery_system_descriptor
* @brief DVB-SH delivery system descriptor
*
* @var supplementary_audio_descriptor
* @brief supplementary audio descriptor
*
* @var network_change_notify_descriptor
* @brief network change notify descriptor
*
* @var message_descriptor
* @brief message descriptor
*
* @var target_region_descriptor
* @brief target region descriptor
*
* @var target_region_name_descriptor
* @brief target region name descriptor
*
* @var service_relocated_descriptor
* @brief service relocated descriptor
*/
enum extension_descriptors {
image_icon_descriptor = 0x00,
cpcm_delivery_signalling_descriptor = 0x01,
CP_descriptor = 0x02,
CP_identifier_descriptor = 0x03,
T2_delivery_system_descriptor = 0x04,
SH_delivery_system_descriptor = 0x05,
supplementary_audio_descriptor = 0x06,
network_change_notify_descriptor = 0x07,
message_descriptor = 0x08,
target_region_descriptor = 0x09,
target_region_name_descriptor = 0x0a,
service_relocated_descriptor = 0x0b,
};
/**
* @struct dvb_extension_descriptor
* @ingroup descriptors
* @brief Structure containing the extended descriptors
*
* @param type Descriptor type
* @param length Length of the descriptor
* @param next pointer to the dvb_desc descriptor
* @param extension_code extension code
* @param descriptor pointer to struct dvb_desc
*/
struct dvb_extension_descriptor {
uint8_t type;
uint8_t length;
struct dvb_desc *next;
uint8_t extension_code;
struct dvb_desc *descriptor;
} __attribute__((packed));
/**
* @brief Function prototype for the extended descriptors parsing init code
* @ingroup dvb_table
*
* @param parms Struct dvb_v5_fe_parms pointer
* @param buf buffer with the content of the descriptor
* @param ext struct dvb_extension_descriptor pointer
* @param desc struct dvb_desc pointer
*/
typedef int (*dvb_desc_ext_init_func) (struct dvb_v5_fe_parms *parms,
const uint8_t *buf,
struct dvb_extension_descriptor *ext,
void *desc);
/**
* @brief Function prototype for the extended descriptors parsing print code
* @ingroup dvb_table
*
* @param parms Struct dvb_v5_fe_parms pointer
* @param buf buffer with the content of the descriptor
* @param ext struct dvb_extension_descriptor pointer
* @param desc struct dvb_desc pointer
*/
typedef void (*dvb_desc_ext_print_func)(struct dvb_v5_fe_parms *parms,
const struct dvb_extension_descriptor *ext,
const void *desc);
/**
* @brief Function prototype for the extended descriptors parsing free code
* @ingroup dvb_table
*
* @param desc struct dvb_desc pointer
*/
typedef void (*dvb_desc_ext_free_func) (const void *desc);
/**
* @struct dvb_ext_descriptor
* @ingroup descriptors
* @brief Structure that describes the parser functions for the extended
* descriptors. Works on a similar way as struct dvb_descriptor.
*
* @param name name of the descriptor
* @param init init dvb_desc_ext_init_func pointer
* @param print print dvb_desc_ext_print_func pointer
* @param free free dvb_desc_ext_free_func pointer
* @param size size of the descriptor
*/
struct dvb_ext_descriptor {
const char *name;
dvb_desc_ext_init_func init;
dvb_desc_ext_print_func print;
dvb_desc_ext_free_func free;
ssize_t size;
};
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Initializes and parses the extended descriptor
* @ingroup descriptors
*
* @param parms struct dvb_v5_fe_parms pointer to the opened device
* @param buf buffer containing the descriptor's raw data
* @param desc pointer to struct dvb_desc to be allocated and filled
*
* This function allocates a the descriptor and fills the fields inside
* the struct. It also makes sure that all fields will follow the CPU
* endianness. Due to that, the content of the buffer may change.
*
* @return On success, it returns the size of the allocated struct.
* A negative value indicates an error.
*/
int dvb_extension_descriptor_init(struct dvb_v5_fe_parms *parms,
const uint8_t *buf, struct dvb_desc *desc);
/**
* @brief Prints the content of the extended descriptor
* @ingroup descriptors
*
* @param parms struct dvb_v5_fe_parms pointer to the opened device
* @param desc pointer to struct dvb_desc
*/
void dvb_extension_descriptor_print(struct dvb_v5_fe_parms *parms,
const struct dvb_desc *desc);
/**
* @brief Frees all data allocated by the extended descriptor
* @ingroup descriptors
*
* @param desc pointer to struct dvb_desc to be freed
*/
void dvb_extension_descriptor_free(struct dvb_desc *desc);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,112 @@
/*
* Copyright (c) 2011-2014 - Mauro Carvalho Chehab
* Copyright (c) 2012 - Andre Roth <neolynx@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation version 2.1 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
* Or, point your browser to http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
*/
#ifndef _DESC_FREQUENCY_LIST_H
#define _DESC_FREQUENCY_LIST_H
#include <libdvbv5/descriptors.h>
/**
* @file desc_frequency_list.h
* @ingroup descriptors
* @brief Provides the descriptors for the frequency list descriptor.
* This descriptor lists the additional frequencies used in transmission
* of a multiplex on other frequencies.
* @copyright GNU Lesser General Public License version 2.1 (LGPLv2.1)
* @author Mauro Carvalho Chehab
* @author Andre Roth
*
* @par Relevant specs
* The descriptor described herein is defined at:
* - ETSI EN 300 468 V1.11.1
*
* @par Bug Report
* Please submit bug reports and patches to linux-media@vger.kernel.org
*/
/**
* @struct dvb_desc_frequency_list
* @ingroup descriptors
* @brief Struct containing the frequency list descriptor
*
* @param type descriptor tag
* @param length descriptor length
* @param next pointer to struct dvb_desc
* @param frequencies number of frequencies in the frequency vector
* @param frequency vector with the centre frequency
* @param freq_type freq type, being: 0 = undefined,
* 1 = satelite, 2 = cable or 3 = terrestrial.
*/
struct dvb_desc_frequency_list {
uint8_t type;
uint8_t length;
struct dvb_desc *next;
uint8_t frequencies;
uint32_t *frequency;
union {
uint8_t bitfield;
struct {
uint8_t freq_type:2;
uint8_t reserved:6;
} __attribute__((packed));
} __attribute__((packed));
} __attribute__((packed));
struct dvb_v5_fe_parms;
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Initializes and parses the frequency list descriptor
* @ingroup descriptors
*
* @param parms struct dvb_v5_fe_parms pointer to the opened device
* @param buf buffer containing the descriptor's raw data
* @param desc pointer to struct dvb_desc to be allocated and filled
*
* This function initializes and makes sure that all fields will follow the CPU
* endianness. Due to that, the content of the buffer may change.
*
* Currently, no memory is allocated internally.
*
* @return On success, it returns the size of the allocated struct.
* A negative value indicates an error.
*/
int dvb_desc_frequency_list_init(struct dvb_v5_fe_parms *parms,
const uint8_t *buf, struct dvb_desc *desc);
/**
* @brief Prints the content of the frequency list descriptor
* @ingroup descriptors
*
* @param parms struct dvb_v5_fe_parms pointer to the opened device
* @param desc pointer to struct dvb_desc
*/
void dvb_desc_frequency_list_print(struct dvb_v5_fe_parms *parms,
const struct dvb_desc *desc);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,114 @@
/*
* Copyright (c) 2011-2012 - Mauro Carvalho Chehab
* Copyright (c) 2012 - Andre Roth <neolynx@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation version 2.1 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
* Or, point your browser to http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
*/
/**
* @file desc_hierarchy.h
* @ingroup descriptors
* @brief Provides the descriptors for the hierarchy descriptor
* @copyright GNU Lesser General Public License version 2.1 (LGPLv2.1)
* @author Mauro Carvalho Chehab
* @author Andre Roth
*
* @par Relevant specs
* The descriptor described herein is defined at:
* - ISO/IEC 13818-1
*
* @see
*
* @par Bug Report
* Please submit bug reports and patches to linux-media@vger.kernel.org
*/
#ifndef _HIERARCHY_H
#define _HIERARCHY_H
#include <libdvbv5/descriptors.h>
/**
* @struct dvb_desc_hierarchy
* @ingroup descriptors
* @brief Structure containing the hierarchy descriptor
*
* @param type descriptor tag
* @param length descriptor length
* @param next pointer to struct dvb_desc
* @param hierarchy_type hierarchy type
* @param layer hierarchy layer index
* @param embedded_layer hierarchy embedded layer index
* @param channel hierarchy channel
*/
struct dvb_desc_hierarchy {
uint8_t type;
uint8_t length;
struct dvb_desc *next;
uint8_t hierarchy_type:4;
uint8_t reserved:4;
uint8_t layer:6;
uint8_t reserved2:2;
uint8_t embedded_layer:6;
uint8_t reserved3:2;
uint8_t channel:6;
uint8_t reserved4:2;
} __attribute__((packed));
struct dvb_v5_fe_parms;
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Initializes and parses the hierarchy descriptor
* @ingroup descriptors
*
* @param parms struct dvb_v5_fe_parms pointer to the opened device
* @param buf buffer containing the descriptor's raw data
* @param desc pointer to struct dvb_desc to be allocated and filled
*
* This function initializes and makes sure that all fields will follow the CPU
* endianness. Due to that, the content of the buffer may change.
*
* Currently, no memory is allocated internally.
*
* @return On success, it returns the size of the allocated struct.
* A negative value indicates an error.
*/
int dvb_desc_hierarchy_init (struct dvb_v5_fe_parms *parms,
const uint8_t *buf, struct dvb_desc *desc);
/**
* @brief Prints the content of the hierarchy descriptor
* @ingroup descriptors
*
* @param parms struct dvb_v5_fe_parms pointer to the opened device
* @param desc pointer to struct dvb_desc
*/
void dvb_desc_hierarchy_print(struct dvb_v5_fe_parms *parms,
const struct dvb_desc *desc);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,134 @@
/*
* Copyright (c) 2013-2014 - Mauro Carvalho Chehab <mchehab@kernel.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation version 2.1 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
* Or, point your browser to http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
* Described on ARIB STD-B10 as Terrestrial delivery system descriptor
*/
/**
* @file desc_isdbt_delivery.h
* @ingroup descriptors
* @brief Provides the descriptors for the ISDB-T terrestrial delivery system
* @copyright GNU Lesser General Public License version 2.1 (LGPLv2.1)
* @author Mauro Carvalho Chehab
*
* @par Relevant specs
* The descriptor described herein is defined at:
* - ARIB STD-B10
*
* @par Bug Report
* Please submit bug reports and patches to linux-media@vger.kernel.org
*/
#ifndef _ISDBT_DELIVERY_H
#define _ISDBT_DELIVERY_H
#include <libdvbv5/descriptors.h>
/**
* @struct isdbt_desc_terrestrial_delivery_system
* @ingroup descriptors
* @brief Struct containing the ISDB-T terrestrial delivery system
*
* @param type descriptor tag
* @param length descriptor length
* @param next pointer to struct dvb_desc
* @param area_code area code. The area code definition varies from
* Country to Country.
* @param guard_interval guard interval
* @param transmission_mode transmission mode
* @param frequency vector with center frequencies
* @param num_freqs number of frequencies at the
* isdbt_desc_terrestrial_delivery_system::frequency vector
*/
struct isdbt_desc_terrestrial_delivery_system {
uint8_t type;
uint8_t length;
struct dvb_desc *next;
uint32_t *frequency;
unsigned num_freqs;
union {
uint16_t bitfield;
struct {
uint16_t transmission_mode:2;
uint16_t guard_interval:2;
uint16_t area_code:12;
} __attribute__((packed));
} __attribute__((packed));
} __attribute__((packed));
struct dvb_v5_fe_parms;
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Initializes and parses the ISDB-T terrestrial delivery system
* descriptor
* @ingroup descriptors
*
* @param parms struct dvb_v5_fe_parms pointer to the opened device
* @param buf buffer containing the descriptor's raw data
* @param desc pointer to struct dvb_desc to be allocated and filled
*
* This function allocates a the descriptor and fills the fields inside
* the struct. It also makes sure that all fields will follow the CPU
* endianness. Due to that, the content of the buffer may change.
*
* @return On success, it returns the size of the allocated struct.
* A negative value indicates an error.
*/
int isdbt_desc_delivery_init(struct dvb_v5_fe_parms *parms,
const uint8_t *buf, struct dvb_desc *desc);
/**
* @brief Prints the content of the ISDB-T terrestrial delivery system
* descriptor
* @ingroup descriptors
*
* @param parms struct dvb_v5_fe_parms pointer to the opened device
* @param desc pointer to struct dvb_desc
*/
void isdbt_desc_delivery_print(struct dvb_v5_fe_parms *parms,
const struct dvb_desc *desc);
/**
* @brief Frees all data allocated by the ISDB-T terrestrial delivery system
* descriptor
* @ingroup descriptors
*
* @param desc pointer to struct dvb_desc to be freed
*/
void isdbt_desc_delivery_free(struct dvb_desc *desc);
/**
* Converts an ISDB-T Interval code into a string
*/
extern const uint32_t isdbt_interval[];
/**
* Converts an ISDB-T mode into a string
*/
extern const uint32_t isdbt_mode[];
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,103 @@
/*
* Copyright (c) 2011-2014 - Mauro Carvalho Chehab
* Copyright (c) 2012 - Andre Roth <neolynx@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation version 2.1 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
* Or, point your browser to http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
*/
/**
* @file desc_language.h
* @ingroup descriptors
* @brief Provides the descriptors for the ISO639 language descriptor
* @copyright GNU Lesser General Public License version 2.1 (LGPLv2.1)
* @author Mauro Carvalho Chehab
* @author Andre Roth
*
* @par Relevant specs
* The descriptor described herein is defined at:
* - ISO/IEC 13818-1
*
* @par Bug Report
* Please submit bug reports and patches to linux-media@vger.kernel.org
*/
#ifndef _DESC_LANGUAGE_H
#define _DESC_LANGUAGE_H
#include <libdvbv5/descriptors.h>
/**
* @struct dvb_desc_language
* @ingroup descriptors
* @brief Structure containing the ISO639 language descriptor
*
* @param type descriptor tag
* @param length descriptor length
* @param next pointer to struct dvb_desc
* @param language ISO639 language string
* @param audio_type audio type: 0 = undefined, 1 = clean effects,
* 2 = hearing impaired, 3 = visual impired
* comentary, other values are reserved.
*/
struct dvb_desc_language {
uint8_t type;
uint8_t length;
struct dvb_desc *next;
unsigned char language[4];
uint8_t audio_type;
} __attribute__((packed));
struct dvb_v5_fe_parms;
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Initializes and parses the language descriptor
* @ingroup descriptors
*
* @param parms struct dvb_v5_fe_parms pointer to the opened device
* @param buf buffer containing the descriptor's raw data
* @param desc pointer to struct dvb_desc to be allocated and filled
*
* This function initializes and makes sure that all fields will follow the CPU
* endianness. Due to that, the content of the buffer may change.
*
* Currently, no memory is allocated internally.
*
* @return On success, it returns the size of the allocated struct.
* A negative value indicates an error.
*/
int dvb_desc_language_init(struct dvb_v5_fe_parms *parms, const uint8_t *buf,
struct dvb_desc *desc);
/**
* @brief Prints the content of the language descriptor
* @ingroup descriptors
*
* @param parms struct dvb_v5_fe_parms pointer to the opened device
* @param desc pointer to struct dvb_desc
*/
void dvb_desc_language_print(struct dvb_v5_fe_parms *parms,
const struct dvb_desc *desc);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,132 @@
/*
* Copyright (c) 2013 - Mauro Carvalho Chehab <mchehab@kernel.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation version 2.1 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
* Or, point your browser to http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
* Described on IEC/CENELEC DS/EN 62216-1:2011
*
* I couldn't find the original version, so I used what's there at:
* http://tdt.telecom.pt/recursos/apresentacoes/Signalling Specifications for DTT deployment in Portugal.pdf
*/
/**
* @file desc_logical_channel.h
* @ingroup descriptors
* @brief Provides the descriptors for the LCN - Logican Channel Number
* @copyright GNU Lesser General Public License version 2.1 (LGPLv2.1)
* @author Mauro Carvalho Chehab
*
* @par Relevant specs
* The descriptor described herein is defined at:
* - IEC/CENELEC DS/EN 62216-1:2011
*
* @see http://tdt.telecom.pt/recursos/apresentacoes/Signalling Specifications for DTT deployment in Portugal.pdf
*
* @par Bug Report
* Please submit bug reports and patches to linux-media@vger.kernel.org
*/
#ifndef _LCN_DESC_H
#define _LCN_DESC_H
#include <libdvbv5/descriptors.h>
/**
* @struct dvb_desc_logical_channel_number
* @ingroup descriptors
* @brief Structure containing the logical channel number entires
*
* @param service_id service id
* @param visible_service_flag visible service flag
* @param logical_channel_number logical channel number
*/
struct dvb_desc_logical_channel_number {
uint16_t service_id;
union {
uint16_t bitfield;
struct {
uint16_t logical_channel_number:10;
uint16_t reserved:5;
uint16_t visible_service_flag:1;
} __attribute__((packed));
} __attribute__((packed));
} __attribute__((packed));
/**
* @struct dvb_desc_logical_channel
* @ingroup descriptors
* @brief Structure containing the logical channel number descriptor
*
* @param type descriptor tag
* @param length descriptor length
* @param next pointer to struct dvb_desc
* @param lcn pointer to struct dvb_desc_logical_channel_number
*/
struct dvb_desc_logical_channel {
uint8_t type;
uint8_t length;
struct dvb_desc *next;
struct dvb_desc_logical_channel_number *lcn;
} __attribute__((packed));
struct dvb_v5_fe_parms;
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Initializes and parses the logical channel number descriptor
* @ingroup descriptors
*
* @param parms struct dvb_v5_fe_parms pointer to the opened device
* @param buf buffer containing the descriptor's raw data
* @param desc pointer to struct dvb_desc to be allocated and filled
*
* This function allocates a the descriptor and fills the fields inside
* the struct. It also makes sure that all fields will follow the CPU
* endianness. Due to that, the content of the buffer may change.
*
* @return On success, it returns the size of the allocated struct.
* A negative value indicates an error.
*/
int dvb_desc_logical_channel_init(struct dvb_v5_fe_parms *parms,
const uint8_t *buf, struct dvb_desc *desc);
/**
* @brief Prints the content of the logical channel number descriptor
* @ingroup descriptors
*
* @param parms struct dvb_v5_fe_parms pointer to the opened device
* @param desc pointer to struct dvb_desc
*/
void dvb_desc_logical_channel_print(struct dvb_v5_fe_parms *parms,
const struct dvb_desc *desc);
/**
* @brief Frees all data allocated by the logical channel number descriptor
* @ingroup descriptors
*
* @param desc pointer to struct dvb_desc to be freed
*/
void dvb_desc_logical_channel_free(struct dvb_desc *desc);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,112 @@
/*
* Copyright (c) 2011-2014 - Mauro Carvalho Chehab
* Copyright (c) 2012 - Andre Roth <neolynx@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation version 2.1 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
* Or, point your browser to http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
*/
/**
* @file desc_network_name.h
* @ingroup descriptors
* @brief Provides the descriptors for the network name descriptor
* @copyright GNU Lesser General Public License version 2.1 (LGPLv2.1)
* @author Mauro Carvalho Chehab
* @author Andre Roth
*
* @par Relevant specs
* The descriptor described herein is defined at:
* - ETSI EN 300 468 V1.11.1 (2010-04)
*
* @par Bug Report
* Please submit bug reports and patches to linux-media@vger.kernel.org
*/
#ifndef _DESC_NETWORK_NAME_H
#define _DESC_NETWORK_NAME_H
#include <libdvbv5/descriptors.h>
/**
* @struct dvb_desc_network_name
* @ingroup descriptors
* @brief Struct containing the network name descriptor
*
* @param type descriptor tag
* @param length descriptor length
* @param next pointer to struct dvb_desc
* @param network_name network name string
* @param network_name_emph network name emphasis string
*
* @details
* The emphasis text is the one that uses asterisks. For example, in the text:
* "the quick *fox* jumps over the lazy table" the emphasis would be "fox".
*/
struct dvb_desc_network_name {
uint8_t type;
uint8_t length;
struct dvb_desc *next;
char *network_name;
char *network_name_emph;
} __attribute__((packed));
struct dvb_v5_fe_parms;
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Initializes and parses the network name descriptor
* @ingroup descriptors
*
* @param parms struct dvb_v5_fe_parms pointer to the opened device
* @param buf buffer containing the descriptor's raw data
* @param desc pointer to struct dvb_desc to be allocated and filled
*
* This function allocates a the descriptor and fills the fields inside
* the struct. It also makes sure that all fields will follow the CPU
* endianness. Due to that, the content of the buffer may change.
*
* @return On success, it returns the size of the allocated struct.
* A negative value indicates an error.
*/
int dvb_desc_network_name_init(struct dvb_v5_fe_parms *parms,
const uint8_t *buf, struct dvb_desc *desc);
/**
* @brief Prints the content of the network name descriptor
* @ingroup descriptors
*
* @param parms struct dvb_v5_fe_parms pointer to the opened device
* @param desc pointer to struct dvb_desc
*/
void dvb_desc_network_name_print(struct dvb_v5_fe_parms *parms,
const struct dvb_desc *desc);
/**
* @brief Frees all data allocated by the network name descriptor
* @ingroup descriptors
*
* @param desc pointer to struct dvb_desc to be freed
*/
void dvb_desc_network_name_free(struct dvb_desc *desc);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,125 @@
/*
* Copyright (c) 2013 - Mauro Carvalho Chehab <mchehab@kernel.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation version 2.1 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
* Or, point your browser to http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
* Described on IEC/CENELEC DS/EN 62216-1:2011
*
* I couldn't find the original version, so I used what's there at:
* http://tdt.telecom.pt/recursos/apresentacoes/Signalling Specifications for DTT deployment in Portugal.pdf
*/
/**
* @file desc_partial_reception.h
* @ingroup descriptors
* @brief Provides the descriptors for the ISDB partial reception descriptor
* @copyright GNU Lesser General Public License version 2.1 (LGPLv2.1)
* @author Mauro Carvalho Chehab
* @author Andre Roth
*
* @par Relevant specs
* The descriptor described herein is defined at:
* - IEC/CENELEC DS/EN 62216-1:2011
*
* @see http://tdt.telecom.pt/recursos/apresentacoes/Signalling Specifications for DTT deployment in Portugal.pdf
*
* @par Bug Report
* Please submit bug reports and patches to linux-media@vger.kernel.org
*/
#ifndef _PARTIAL_RECEPTION_H
#define _PARTIAL_RECEPTION_H
#include <libdvbv5/descriptors.h>
/**
* @struct isdb_partial_reception_service_id
* @ingroup descriptors
* @brief Service ID that uses partial reception
*
* @param service_id service id
*/
struct isdb_partial_reception_service_id {
uint16_t service_id;
} __attribute__((packed));
/**
* @struct isdb_desc_partial_reception
* @ingroup descriptors
* @brief Structure containing the partial reception descriptor
*
* @param type descriptor tag
* @param length descriptor length
* @param next pointer to struct dvb_desc
* @param partial_reception vector of struct isdb_partial_reception_service_id.
* The length of the vector is given by:
* length / sizeof(struct isdb_partial_reception_service_id).
*/
struct isdb_desc_partial_reception {
uint8_t type;
uint8_t length;
struct dvb_desc *next;
struct isdb_partial_reception_service_id *partial_reception;
} __attribute__((packed));
struct dvb_v5_fe_parms;
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Initializes and parses the ISDB-T partial reception descriptor
* @ingroup descriptors
*
* @param parms struct dvb_v5_fe_parms pointer to the opened device
* @param buf buffer containing the descriptor's raw data
* @param desc pointer to struct dvb_desc to be allocated and filled
*
* This function allocates a the descriptor and fills the fields inside
* the struct. It also makes sure that all fields will follow the CPU
* endianness. Due to that, the content of the buffer may change.
*
* @return On success, it returns the size of the allocated struct.
* A negative value indicates an error.
*/
int isdb_desc_partial_reception_init(struct dvb_v5_fe_parms *parms,
const uint8_t *buf, struct dvb_desc *desc);
/**
* @brief Prints the content of the ISDB-T partial reception descriptor
* @ingroup descriptors
*
* @param parms struct dvb_v5_fe_parms pointer to the opened device
* @param desc pointer to struct dvb_desc
*/
void isdb_desc_partial_reception_print(struct dvb_v5_fe_parms *parms,
const struct dvb_desc *desc);
/**
* @brief Frees all data allocated by the ISDB-T partial reception descriptor
* @ingroup descriptors
*
* @param desc pointer to struct dvb_desc to be freed
*/
void isdb_desc_partial_reception_free(struct dvb_desc *desc);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,109 @@
/*
* Copyright (c) 2020 - Mauro Carvalho Chehab
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation version 2.1 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
* Or, point your browser to http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
*/
#ifndef _DESC_REGISTRATION_ID_H
#define _DESC_REGISTRATION_ID_H
#include <libdvbv5/descriptors.h>
/**
* @file desc_registration_id.h
* @ingroup descriptors
* @brief Provides the descriptors for the registration descriptor.
* This descriptor provides the format information for an
* Elementary Stream.
* @copyright GNU Lesser General Public License version 2.1 (LGPLv2.1)
* @author Mauro Carvalho Chehab
*
* @par Relevant specs
* The descriptor described herein is defined at:
* - ISO/IEC 13818-1
*
* @par Bug Report
* Please submit bug reports and patches to linux-media@vger.kernel.org
*/
/**
* @struct dvb_desc_registration
* @ingroup descriptors
* @brief Struct containing the frequency list descriptor
*
* @param type descriptor tag
* @param length descriptor length
* @param format_identifier 32-bit value obtained from ISO/IEC JTC 1/SC 29
* which describes the format of the ES
* The length of the vector is given by:
* length - 4.
*/
struct dvb_desc_registration {
uint8_t type;
uint8_t length;
struct dvb_desc *next;
uint8_t format_identifier[4];
uint8_t *additional_identification_info;
} __attribute__((packed));
struct dvb_v5_fe_parms;
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Initializes and parses the registration descriptor
* @ingroup descriptors
*
* @param parms struct dvb_v5_fe_parms pointer to the opened device
* @param buf buffer containing the descriptor's raw data
* @param desc pointer to struct dvb_desc to be allocated and filled
*
* This function initializes and makes sure that all fields will follow the CPU
* endianness. Due to that, the content of the buffer may change.
*
* Currently, no memory is allocated internally.
*
* @return On success, it returns the size of the allocated struct.
* A negative value indicates an error.
*/
int dvb_desc_registration_init(struct dvb_v5_fe_parms *parms,
const uint8_t *buf, struct dvb_desc *desc);
/**
* @brief Prints the content of the registration descriptor
* @ingroup descriptors
*
* @param parms struct dvb_v5_fe_parms pointer to the opened device
* @param desc pointer to struct dvb_desc
*/
void dvb_desc_registration_print(struct dvb_v5_fe_parms *parms,
const struct dvb_desc *desc);
/**
* @brief Frees all data allocated by the registration descriptor
* @ingroup descriptors
*
* @param desc pointer to struct dvb_desc to be freed
*/
void dvb_desc_registration_free(struct dvb_desc *desc);
#ifdef __cplusplus
}
#endif
#endif

147
include/libdvbv5/desc_sat.h Normal file
View File

@@ -0,0 +1,147 @@
/*
* Copyright (c) 2011-2014 - Mauro Carvalho Chehab
* Copyright (c) 2012 - Andre Roth <neolynx@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation version 2.1 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
* Or, point your browser to http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
*/
/**
* @file desc_sat.h
* @ingroup descriptors
* @brief Provides the descriptors for the satellite delivery system descriptor
* @copyright GNU Lesser General Public License version 2.1 (LGPLv2.1)
* @author Mauro Carvalho Chehab
* @author Andre Roth
*
* @par Relevant specs
* The descriptor described herein is defined at:
* - ETSI EN 300 468 V1.11.1
*
* @par Bug Report
* Please submit bug reports and patches to linux-media@vger.kernel.org
*/
#ifndef _SAT_H
#define _SAT_H
#include <libdvbv5/descriptors.h>
/**
* @struct dvb_desc_sat
* @ingroup descriptors
* @brief Structure containing the satellite delivery system descriptor
*
* @param type descriptor tag
* @param length descriptor length
* @param next pointer to struct dvb_desc
* @param frequency frequency in kHz
* @param orbit orbital position in degrees (multiplied by 10)
* @param west_east west east flag. 0 = west, 1 = east
* @param polarization polarization. 0 = horizontal, 1 = vertical,
* 2 = left, 3 = right.
* @param roll_off roll off alpha factor. 0 = 0.35, 1 = 0.25,
* 2 = 0.20, 3 = reserved.
* @param modulation_system modulation system. 0 = DVB-S, 1 = DVB-S2.
* @param modulation_type modulation type. 0 = auto, 1 = QPSK, 2 = 8PSK,
* 3 = 16-QAM (only for DVB-S2).
* @param symbol_rate symbol rate in Kbauds.
* @param fec inner FEC (convolutional code)
*/
struct dvb_desc_sat {
uint8_t type;
uint8_t length;
struct dvb_desc *next;
uint32_t frequency;
uint16_t orbit;
uint8_t modulation_type:2;
uint8_t modulation_system:1;
uint8_t roll_off:2;
uint8_t polarization:2;
uint8_t west_east:1;
union {
uint32_t bitfield;
struct {
uint32_t fec:4;
uint32_t symbol_rate:28;
} __attribute__((packed));
} __attribute__((packed));
} __attribute__((packed));
struct dvb_v5_fe_parms;
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Initializes and parses the satellite delivery system descriptor
* @ingroup descriptors
*
* @param parms struct dvb_v5_fe_parms pointer to the opened device
* @param buf buffer containing the descriptor's raw data
* @param desc pointer to struct dvb_desc to be allocated and filled
*
* This function initializes and makes sure that all fields will follow the CPU
* endianness. Due to that, the content of the buffer may change.
*
* Currently, no memory is allocated internally.
*
* @return On success, it returns the size of the allocated struct.
* A negative value indicates an error.
*/
int dvb_desc_sat_init(struct dvb_v5_fe_parms *parms,
const uint8_t *buf, struct dvb_desc *desc);
/**
* @brief Prints the content of the satellite delivery system descriptor
* @ingroup descriptors
*
* @param parms struct dvb_v5_fe_parms pointer to the opened device
* @param desc pointer to struct dvb_desc
*/
void dvb_desc_sat_print(struct dvb_v5_fe_parms *parms,
const struct dvb_desc *desc);
/**
* @brief converts from the descriptor's FEC into enum fe_code_rate,
* as defined by DVBv5 API.
*/
extern const unsigned dvbs_dvbc_dvbs_freq_inner[];
/**
* @brief converts from the descriptor's polarization into
* enum dvb_sat_polarization, as defined at dvb-v5-std.h.
*/
extern const unsigned dvbs_polarization[];
/**
* @brief converts from the descriptor's rolloff into enum fe_rolloff,
* as defined by DVBv5 API.
*/
extern const unsigned dvbs_rolloff[];
/**
* @brief converts from the descriptor's modulation into enum fe_modulation,
* as defined by DVBv5 API.
*/
extern const unsigned dvbs_modulation[];
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,118 @@
/*
* Copyright (c) 2011-2014 - Mauro Carvalho Chehab
* Copyright (c) 2012 - Andre Roth <neolynx@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation version 2.1 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
* Or, point your browser to http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
*/
/**
* @file desc_service.h
* @ingroup descriptors
* @brief Provides the descriptors for the service descriptor
* @copyright GNU Lesser General Public License version 2.1 (LGPLv2.1)
* @author Mauro Carvalho Chehab
* @author Andre Roth
*
* @par Relevant specs
* The descriptor described herein is defined at:
* - ETSI EN 300 468 V1.11.1
*
* @par Bug Report
* Please submit bug reports and patches to linux-media@vger.kernel.org
*/
#ifndef _DESC_SERVICE_H
#define _DESC_SERVICE_H
#include <libdvbv5/descriptors.h>
/**
* @struct dvb_desc_service
* @ingroup descriptors
* @brief Structure containing the service descriptor
*
* @param type descriptor tag
* @param length descriptor length
* @param next pointer to struct dvb_desc
* @param service_type service type
* @param name name string
* @param name_emph name emphasis string
* @param provider provider string
* @param provider_emph provider emphasis string
*
* @details
* The emphasis text is the one that uses asterisks. For example, in the text:
* "the quick *fox* jumps over the lazy table" the emphasis would be "fox".
*/
struct dvb_desc_service {
uint8_t type;
uint8_t length;
struct dvb_desc *next;
uint8_t service_type;
char *name;
char *name_emph;
char *provider;
char *provider_emph;
} __attribute__((packed));
struct dvb_v5_fe_parms;
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Initializes and parses the service descriptor
* @ingroup descriptors
*
* @param parms struct dvb_v5_fe_parms pointer to the opened device
* @param buf buffer containing the descriptor's raw data
* @param desc pointer to struct dvb_desc to be allocated and filled
*
* This function allocates a the descriptor and fills the fields inside
* the struct. It also makes sure that all fields will follow the CPU
* endianness. Due to that, the content of the buffer may change.
*
* @return On success, it returns the size of the allocated struct.
* A negative value indicates an error.
*/
int dvb_desc_service_init(struct dvb_v5_fe_parms *parms,
const uint8_t *buf, struct dvb_desc *desc);
/**
* @brief Prints the content of the service descriptor
* @ingroup descriptors
*
* @param parms struct dvb_v5_fe_parms pointer to the opened device
* @param desc pointer to struct dvb_desc
*/
void dvb_desc_service_print(struct dvb_v5_fe_parms *parms,
const struct dvb_desc *desc);
/**
* @brief Frees all data allocated by the service descriptor
* @ingroup descriptors
*
* @param desc pointer to struct dvb_desc to be freed
*/
void dvb_desc_service_free(struct dvb_desc *desc);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,224 @@
/*
* Copyright (c) 2013-2014 - Mauro Carvalho Chehab <mchehab@kernel.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation version 2.1 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
* Or, point your browser to http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
* Based on ETSI EN 300 468 V1.11.1 (2010-04)
*/
/**
* @file desc_t2_delivery.h
* @ingroup descriptors
* @brief Provides the descriptors for the DVB-T2 delivery system descriptor
* @copyright GNU Lesser General Public License version 2.1 (LGPLv2.1)
* @author Mauro Carvalho Chehab
*
* @par Relevant specs
* The descriptor described herein is defined at:
* - ETSI EN 300 468 V1.11.1
*
* @par Bug Report
* Please submit bug reports and patches to linux-media@vger.kernel.org
*/
#ifndef _T2_DELIVERY_H
#define _T2_DELIVERY_H
#include <libdvbv5/descriptors.h>
/**
* @struct dvb_desc_t2_delivery_subcell_old
* @ingroup descriptors
* @brief Structure to describe transponder subcell extension and frequencies
*
* @param cell_id_extension cell id extension
* @param transposer_frequency transposer frequency
*
* NOTE: This struct is deprecated and will never be filled.
* It is kept here just to avoid breaking ABI.
*
* All subcell transposer frequencies will be added to
* dvb_desc_t2_delivery::centre_frequency array.
*/
struct dvb_desc_t2_delivery_subcell_old {
uint8_t cell_id_extension;
uint16_t transposer_frequency; // Should be 32 bits, instead
} __attribute__((packed));
/**
* @struct dvb_desc_t2_delivery_subcell
* @ingroup descriptors
* @brief Structure to describe transponder subcell extension and frequencies
*
* @param cell_id_extension cell id extension
* @param transposer_frequency pointer to transposer frequency
*/
struct dvb_desc_t2_delivery_subcell {
uint8_t cell_id_extension;
uint32_t transposer_frequency;
} __attribute__((packed));
/**
* @struct dvb_desc_t2_delivery_cell
* @ingroup descriptors
* @brief Structure to describe transponder cells
*
* @param cell_id cell id extension
* @param num_freqs number of cell frequencies
* @param centre_frequency pointer to centre frequencies
* @param subcel_length number of subcells. May be zero
* @param subcell pointer to subcell array. May be NULL
*/
struct dvb_desc_t2_delivery_cell {
uint16_t cell_id;
int num_freqs;
uint32_t *centre_frequency;
uint8_t subcel_length;
struct dvb_desc_t2_delivery_subcell *subcel;
} __attribute__((packed));
/**
* @struct dvb_desc_t2_delivery
* @ingroup descriptors
* @brief Structure containing the T2 delivery system descriptor
*
* @param plp_id data PLP id
* @param system_id T2 system id
* @param SISO_MISO SISO MISO
* @param bandwidth bandwidth
* @param guard_interval guard interval
* @param transmission_mode transmission mode
* @param other_frequency_flag other frequency flag
* @param tfs_flag tfs flag
*
* @param centre_frequency centre frequency vector. It contains the full
* frequencies for all cells and subcells.
* @param frequency_loop_length size of the dvb_desc_t2_delivery::centre_frequency
* vector
*
* @param subcel_info_loop_length unused. Always 0
* @param subcell unused. Always NULL
* @param num_cell number of cells
* @param cell cell array. Contains per-cell and per-subcell
* pointers to the frequencies parsed.
*/
struct dvb_desc_t2_delivery {
/* extended descriptor */
uint8_t plp_id;
uint16_t system_id;
union {
uint16_t bitfield;
struct {
uint16_t tfs_flag:1;
uint16_t other_frequency_flag:1;
uint16_t transmission_mode:3;
uint16_t guard_interval:3;
uint16_t reserved:2;
uint16_t bandwidth:4;
uint16_t SISO_MISO:2;
} __attribute__((packed));
} __attribute__((packed));
uint32_t *centre_frequency;
uint8_t frequency_loop_length;
/* Unused, as the definitions here are incomplete. */
uint8_t subcel_info_loop_length;
struct dvb_desc_t2_delivery_subcell_old *subcell;
/* Since version 1.13 */
unsigned int num_cell;
struct dvb_desc_t2_delivery_cell *cell;
} __attribute__((packed));
struct dvb_v5_fe_parms;
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Initializes and parses the T2 delivery system descriptor
* @ingroup descriptors
*
* @param parms struct dvb_v5_fe_parms pointer to the opened device
* @param buf buffer containing the descriptor's raw data
* @param ext struct dvb_extension_descriptor pointer
* @param desc pointer to struct dvb_desc to be allocated and filled
*
* This function allocates a the descriptor and fills the fields inside
* the struct. It also makes sure that all fields will follow the CPU
* endianness. Due to that, the content of the buffer may change.
*
* @return On success, it returns the size of the allocated struct.
* A negative value indicates an error.
*/
int dvb_desc_t2_delivery_init(struct dvb_v5_fe_parms *parms,
const uint8_t *buf,
struct dvb_extension_descriptor *ext,
void *desc);
/**
* @brief Prints the content of the T2 delivery system descriptor
* @ingroup descriptors
*
* @param parms struct dvb_v5_fe_parms pointer to the opened device
* @param ext struct dvb_extension_descriptor pointer
* @param desc pointer to struct dvb_desc
*/
void dvb_desc_t2_delivery_print(struct dvb_v5_fe_parms *parms,
const struct dvb_extension_descriptor *ext,
const void *desc);
/**
* @brief Frees all data allocated by the T2 delivery system descriptor
* @ingroup descriptors
*
* @param desc pointer to struct dvb_desc to be freed
*/
void dvb_desc_t2_delivery_free(const void *desc);
/**
* @brief converts from internal representation into bandwidth in Hz
*/
extern const unsigned dvbt2_bw[];
/**
* @brief converts from internal representation into enum fe_guard_interval,
* as defined at DVBv5 API.
*/
extern const uint32_t dvbt2_interval[];
/**
* @brief converts from the descriptor's transmission mode into
* enum fe_transmit_mode, as defined by DVBv5 API.
*/
extern const unsigned dvbt2_transmission_mode[];
/**
* @brief converts from internal representation to string the SISO_MISO
* field of dvb_desc_t2_delivery:SISO_MISO field.
*/
extern const char *siso_miso[4];
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,160 @@
/*
* Copyright (c) 2011-2012 - Mauro Carvalho Chehab
* Copyright (c) 2012 - Andre Roth <neolynx@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation version 2.1 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
* Or, point your browser to http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
* Based on ETSI EN 300 468 V1.11.1 (2010-04)
*
*/
/**
* @file desc_terrestrial_delivery.h
* @ingroup descriptors
* @brief Provides the descriptors for the DVB-T terrestrial delivery system descriptor
* @copyright GNU Lesser General Public License version 2.1 (LGPLv2.1)
* @author Mauro Carvalho Chehab
* @author Andre Roth
*
* @par Relevant specs
* The descriptor described herein is defined at:
* - ETSI EN 300 468 V1.11.1
*
* @par Bug Report
* Please submit bug reports and patches to linux-media@vger.kernel.org
*/
#ifndef _TERRESTRIAL_DELIVERY_H
#define _TERRESTRIAL_DELIVERY_H
#include <libdvbv5/descriptors.h>
/**
* @struct dvb_desc_terrestrial_delivery
* @ingroup descriptors
* @brief Structure containing the DVB-T terrestrial delivery system descriptor
*
* @param type descriptor tag
* @param length descriptor length
* @param next pointer to struct dvb_desc
* @param centre_frequency centre frequency, multiplied by 10 Hz
* @param bandwidth bandwidth
* @param priority priority (0 = LP, 1 = HP)
* @param time_slice_indicator time slicing indicator
* @param mpe_fec_indicator mpe fec indicator. If 1, MPE-FEC is not used.
* @param constellation constellation
* @param hierarchy_information hierarchy information
* @param code_rate_hp_stream code rate hp stream
* @param code_rate_lp_stream code rate lp stream
* @param guard_interval guard interval
* @param transmission_mode transmission mode
* @param other_frequency_flag other frequency flag
*/
struct dvb_desc_terrestrial_delivery {
uint8_t type;
uint8_t length;
struct dvb_desc *next;
uint32_t centre_frequency;
uint8_t reserved_future_use1:2;
uint8_t mpe_fec_indicator:1;
uint8_t time_slice_indicator:1;
uint8_t priority:1;
uint8_t bandwidth:3;
uint8_t code_rate_hp_stream:3;
uint8_t hierarchy_information:3;
uint8_t constellation:2;
uint8_t other_frequency_flag:1;
uint8_t transmission_mode:2;
uint8_t guard_interval:2;
uint8_t code_rate_lp_stream:3;
uint32_t reserved_future_use2;
} __attribute__((packed));
struct dvb_v5_fe_parms;
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Initializes and parses the DVB-T terrestrial delivery system descriptor
*
* @param parms struct dvb_v5_fe_parms pointer to the opened device
* @param buf buffer containing the descriptor's raw data
* @param desc pointer to struct dvb_desc to be allocated and filled
*
* This function initializes and makes sure that all fields will follow the CPU
* endianness. Due to that, the content of the buffer may change.
*
* Currently, no memory is allocated internally.
*
* @return On success, it returns the size of the allocated struct.
* A negative value indicates an error.
*/
int dvb_desc_terrestrial_delivery_init(struct dvb_v5_fe_parms *parms,
const uint8_t *buf,
struct dvb_desc *desc);
/**
* @brief Prints the content of the DVB-T terrestrial delivery system descriptor
* @ingroup descriptors
*
* @param parms struct dvb_v5_fe_parms pointer to the opened device
* @param desc pointer to struct dvb_desc
*/
void dvb_desc_terrestrial_delivery_print(struct dvb_v5_fe_parms *parms,
const struct dvb_desc *desc);
/**
* @brief converts from internal representation into bandwidth in Hz
*/
extern const unsigned dvbt_bw[];
/**
* @brief converts from the descriptor's modulation into enum fe_modulation,
* as defined by DVBv5 API.
*/
extern const unsigned dvbt_modulation[];
/**
* @brief converts from the descriptor's hierarchy into enum fe_hierarchy,
* as defined by DVBv5 API.
*/
extern const unsigned dvbt_hierarchy[];
/**
* @brief converts from the descriptor's FEC into enum fe_code_rate,
* as defined by DVBv5 API.
*/
extern const unsigned dvbt_code_rate[];
/**
* @brief converts from internal representation into enum fe_guard_interval,
* as defined at DVBv5 API.
*/
extern const uint32_t dvbt_interval[];
/**
* @brief converts from the descriptor's transmission mode into
* enum fe_transmit_mode, as defined by DVBv5 API.
*/
extern const unsigned dvbt_transmission_mode[];
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,144 @@
/*
* Copyright (c) 2013-2014 - Mauro Carvalho Chehab <mchehab@kernel.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation version 2.1 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
* Or, point your browser to http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
* Described on ARIB STD-B10 as TS information descriptor
*/
/**
* @file desc_ts_info.h
* @ingroup descriptors
* @brief Provides the descriptors for the ISDB TS information descriptor.
* The TS information descriptor specifies the remote control key
* identifier assigned to the applicable TS and indicates the relationship
* between the service identifier and the transmission layer during
* hierarchical transmission.
*
* @copyright GNU Lesser General Public License version 2.1 (LGPLv2.1)
* @author Mauro Carvalho Chehab
*
* @par Relevant specs
* The descriptor described herein is defined at:
* - ARIB STD-B10
*
* @par Bug Report
* Please submit bug reports and patches to linux-media@vger.kernel.org
*/
#ifndef _TS_INFO_H
#define _TS_INFO_H
#include <libdvbv5/descriptors.h>
/**
* @struct dvb_desc_ts_info_transmission_type
* @ingroup descriptors
* @brief ISDB TS information transmission type
*
* @param transmission_type_info transmission type info
* @param num_of_service num of service
*/
struct dvb_desc_ts_info_transmission_type {
uint8_t transmission_type_info;
uint8_t num_of_service;
} __attribute__((packed));
/**
* @struct dvb_desc_ts_info
* @ingroup descriptors
* @brief Structure describing the ISDB TS information descriptor.
*
* @param type descriptor tag
* @param length descriptor length
* @param next pointer to struct dvb_desc
* @param remote_control_key_id remote control key id
* @param length_of_ts_name length of ts name
* @param transmission_type_count transmission type count
*
* @param ts_name ts name string
* @param ts_name_emph ts name emphasis string
* @param transmission_type struct dvb_desc_ts_info_transmission_type content
* @param service_id service id vector
*/
struct dvb_desc_ts_info {
uint8_t type;
uint8_t length;
struct dvb_desc *next;
char *ts_name, *ts_name_emph;
struct dvb_desc_ts_info_transmission_type transmission_type;
uint16_t *service_id;
union {
uint16_t bitfield;
struct {
uint8_t transmission_type_count:2;
uint8_t length_of_ts_name:6;
uint8_t remote_control_key_id:8;
} __attribute__((packed));
};
} __attribute__((packed));
struct dvb_v5_fe_parms;
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Initializes and parses the ISDB TS information descriptor.
* descriptor
* @ingroup descriptors
*
* @param parms struct dvb_v5_fe_parms pointer to the opened device
* @param buf buffer containing the descriptor's raw data
* @param desc pointer to struct dvb_desc to be allocated and filled
*
* This function allocates a the descriptor and fills the fields inside
* the struct. It also makes sure that all fields will follow the CPU
* endianness. Due to that, the content of the buffer may change.
*
* @return On success, it returns the size of the allocated struct.
* A negative value indicates an error.
*/
int dvb_desc_ts_info_init(struct dvb_v5_fe_parms *parms,
const uint8_t *buf, struct dvb_desc *desc);
/**
* @brief Prints the content of the ISDB TS information descriptor.
* descriptor
* @ingroup descriptors
*
* @param parms struct dvb_v5_fe_parms pointer to the opened device
* @param desc pointer to struct dvb_desc
*/
void dvb_desc_ts_info_print(struct dvb_v5_fe_parms *parms,
const struct dvb_desc *desc);
/**
* @brief Frees all data allocated by the ISDB TS information descriptor.
* descriptor
* @ingroup descriptors
*
* @param desc pointer to struct dvb_desc to be freed
*/
void dvb_desc_ts_info_free(struct dvb_desc *desc);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,780 @@
/*
* Copyright (c) 2011-2012 - Mauro Carvalho Chehab
* Copyright (c) 2012-2014 - Andre Roth <neolynx@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation version 2.1 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
* Or, point your browser to http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*/
/**
* @file descriptors.h
* @ingroup dvb_table
* @brief Provides a way to handle MPEG-TS descriptors found on Digital TV
* streams.
* @copyright GNU Lesser General Public License version 2.1 (LGPLv2.1)
* @author Mauro Carvalho Chehab
* @author Andre Roth
*
* @par Relevant specs
* The descriptors herein are defined on the following specs:
* - ISO/IEC 13818-1
* - ETSI EN 300 468 V1.11.1 (2010-04)
* - SCTE 35 2004
* - http://www.etherguidesystems.com/Help/SDOs/ATSC/Semantics/Descriptors/Default.aspx
* - http://www.coolstf.com/tsreader/descriptors.html
* - ABNT NBR 15603-1 2007
* - ATSC A/65:2009 spec
*
* @par Bug Report
* Please submit bug reports and patches to linux-media@vger.kernel.org
*/
#ifndef _DESCRIPTORS_H
#define _DESCRIPTORS_H
#include <unistd.h>
#include <stdint.h>
#include <arpa/inet.h>
/**
* @brief Maximum size of a table session to be parsed
* @ingroup dvb_table
*/
#define DVB_MAX_PAYLOAD_PACKET_SIZE 4096
/**
* @brief number of bytes for the descriptor's CRC check
* @ingroup dvb_table
*/
#define DVB_CRC_SIZE 4
#ifndef _DOXYGEN
struct dvb_v5_fe_parms;
#endif
/**
* @brief Function prototype for a function that initializes the
* descriptors parsing on a table
* @ingroup dvb_table
*
* @param parms Struct dvb_v5_fe_parms pointer
* @param buf Buffer with data to be parsed
* @param buflen Size of the buffer to be parsed
* @param table pointer to a place where the allocated memory with the
* table structure will be stored.
*/
typedef void (*dvb_table_init_func)(struct dvb_v5_fe_parms *parms,
const uint8_t *buf, ssize_t buflen,
void **table);
/**
* @brief Table with all possible descriptors
* @ingroup dvb_table
*/
extern const dvb_table_init_func dvb_table_initializers[256];
#ifndef _DOXYGEN
#define bswap16(b) do {\
b = ntohs(b); \
} while (0)
#define bswap32(b) do {\
b = ntohl(b); \
} while (0)
/* Deprecated */
#define DVB_DESC_HEADER() \
uint8_t type; \
uint8_t length; \
struct dvb_desc *next
#endif /* _DOXYGEN */
/**
* @struct dvb_desc
* @brief Linked list containing the several descriptors found on a
* MPEG-TS table
* @ingroup dvb_table
*
* @param type Descriptor type
* @param length Length of the descriptor
* @param next pointer to the dvb_desc descriptor
* @param data Descriptor data
*/
struct dvb_desc {
uint8_t type;
uint8_t length;
struct dvb_desc *next;
uint8_t data[];
} __attribute__((packed));
#ifndef _DOXYGEN
#define dvb_desc_foreach( _desc, _tbl ) \
if (_tbl && _tbl->descriptor) \
for( struct dvb_desc *_desc = _tbl->descriptor; _desc; _desc = _desc->next ) \
#define dvb_desc_find(_struct, _desc, _tbl, _type) \
if (_tbl && _tbl->descriptor) \
for( _struct *_desc = (_struct *) _tbl->descriptor; _desc; _desc = (_struct *) _desc->next ) \
if(_desc->type == _type) \
#endif /* _DOXYGEN */
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Converts from BCD to CPU integer internal representation
* @ingroup dvb_table
*
* @param bcd value in BCD encoding
*/
uint32_t dvb_bcd(uint32_t bcd);
/**
* @brief dumps data into the logs in hexadecimal format
* @ingroup dvb_table
*
* @param parms Struct dvb_v5_fe_parms pointer
* @param prefix String to be printed before the dvb_hexdump
* @param buf Buffer to hex dump
* @param len Number of bytes to show
*/
void dvb_hexdump(struct dvb_v5_fe_parms *parms, const char *prefix,
const unsigned char *buf, int len);
/**
* @brief parse MPEG-TS descriptors
* @ingroup dvb_table
*
* @param parms Struct dvb_v5_fe_parms pointer
* @param buf Buffer with data to be parsed
* @param buflen Size of the buffer to be parsed
* @param head_desc pointer to the place to store the parsed data
*
* This function takes a buf as argument and parses it to find the
* MPEG-TS descriptors inside it, creating a linked list.
*
* On success, head_desc will be allocated and filled with a linked list
* with the descriptors found inside the buffer.
*
* This function is used by the several MPEG-TS table handlers to parse
* the entire table that got read by dvb_read_sessions and other similar
* functions.
*
* @return Returns 0 on success, a negative value otherwise.
*/
int dvb_desc_parse(struct dvb_v5_fe_parms *parms, const uint8_t *buf,
uint16_t buflen, struct dvb_desc **head_desc);
/**
* @brief frees a dvb_desc linked list
* @ingroup dvb_table
*
* @param list struct dvb_desc pointer.
*/
void dvb_desc_free (struct dvb_desc **list);
/**
* @brief prints the contents of a struct dvb_desc linked list
* @ingroup dvb_table
*
* @param parms Struct dvb_v5_fe_parms pointer
* @param desc struct dvb_desc pointer.
*/
void dvb_desc_print(struct dvb_v5_fe_parms *parms, struct dvb_desc *desc);
#ifdef __cplusplus
}
#endif
/**
* @brief Function prototype for the descriptors parsing init code
* @ingroup dvb_table
*
* @param parms Struct dvb_v5_fe_parms pointer
* @param buf buffer with the content of the descriptor
* @param desc struct dvb_desc pointer
*/
typedef int (*dvb_desc_init_func) (struct dvb_v5_fe_parms *parms,
const uint8_t *buf, struct dvb_desc *desc);
/**
* @brief Function prototype for the descriptors parsing print code
* @ingroup dvb_table
*
* @param parms Struct dvb_v5_fe_parms pointer
* @param desc struct dvb_desc pointer
*/
typedef void (*dvb_desc_print_func)(struct dvb_v5_fe_parms *parms,
const struct dvb_desc *desc);
/**
* @brief Function prototype for the descriptors memory free code
* @ingroup dvb_table
*
* @param desc pointer to struct dvb_desc pointer to be freed
*/
typedef void (*dvb_desc_free_func) (struct dvb_desc *desc);
/**
* @struct dvb_descriptor
* @brief Contains the parser information for the MPEG-TS parser code
* @ingroup dvb_table
*
* @param name String containing the name of the descriptor
* @param init Pointer to a function to initialize the descriptor
* parser. This function fills the descriptor-specific
* internal structures
* @param print Prints the content of the descriptor
* @param free Frees all memory blocks allocated by the init function
* @param size Descriptor's size, in bytes.
*/
struct dvb_descriptor {
const char *name;
dvb_desc_init_func init;
dvb_desc_print_func print;
dvb_desc_free_func free;
ssize_t size;
};
/**
* @brief Contains the parsers for the several descriptors
* @ingroup dvb_table
*/
extern const struct dvb_descriptor dvb_descriptors[];
/**
* @enum descriptors
* @brief List containing all descriptors used by Digital TV MPEG-TS
* @ingroup dvb_table
*
* @var video_stream_descriptor
* @brief video_stream descriptor - ISO/IEC 13818-1
* @var audio_stream_descriptor
* @brief audio_stream descriptor - ISO/IEC 13818-1
* @var hierarchy_descriptor
* @brief hierarchy descriptor - ISO/IEC 13818-1
* @var registration_descriptor
* @brief registration descriptor - ISO/IEC 13818-1
* @var ds_alignment_descriptor
* @brief ds_alignment descriptor - ISO/IEC 13818-1
* @var target_background_grid_descriptor
* @brief target_background_grid descriptor - ISO/IEC 13818-1
* @var video_window_descriptor
* @brief video_window descriptor - ISO/IEC 13818-1
* @var conditional_access_descriptor
* @brief conditional_access descriptor - ISO/IEC 13818-1
* @var iso639_language_descriptor
* @brief iso639_language descriptor - ISO/IEC 13818-1
* @var system_clock_descriptor
* @brief system_clock descriptor - ISO/IEC 13818-1
* @var multiplex_buffer_utilization_descriptor
* @brief multiplex_buffer_utilization descriptor - ISO/IEC 13818-1
* @var copyright_descriptor
* @brief copyright descriptor - ISO/IEC 13818-1
* @var maximum_bitrate_descriptor
* @brief maximum_bitrate descriptor - ISO/IEC 13818-1
* @var private_data_indicator_descriptor
* @brief private_data_indicator descriptor - ISO/IEC 13818-1
* @var smoothing_buffer_descriptor
* @brief smoothing_buffer descriptor - ISO/IEC 13818-1
* @var std_descriptor
* @brief std descriptor - ISO/IEC 13818-1
* @var ibp_descriptor
* @brief ibp descriptor - ISO/IEC 13818-1
* @var mpeg4_video_descriptor
* @brief mpeg4_video descriptor - ISO/IEC 13818-1
* @var mpeg4_audio_descriptor
* @brief mpeg4_audio descriptor - ISO/IEC 13818-1
* @var iod_descriptor
* @brief iod descriptor - ISO/IEC 13818-1
* @var sl_descriptor
* @brief sl descriptor - ISO/IEC 13818-1
* @var fmc_descriptor
* @brief fmc descriptor - ISO/IEC 13818-1
* @var external_es_id_descriptor
* @brief external_es_id descriptor - ISO/IEC 13818-1
* @var muxcode_descriptor
* @brief muxcode descriptor - ISO/IEC 13818-1
* @var fmxbuffersize_descriptor
* @brief fmxbuffersize descriptor - ISO/IEC 13818-1
* @var multiplexbuffer_descriptor
* @brief multiplexbuffer descriptor - ISO/IEC 13818-1
* @var content_labeling_descriptor
* @brief content_labeling descriptor - ISO/IEC 13818-1
* @var metadata_pointer_descriptor
* @brief metadata_pointer descriptor - ISO/IEC 13818-1
* @var metadata_descriptor
* @brief metadata descriptor - ISO/IEC 13818-1
* @var metadata_std_descriptor
* @brief metadata_std descriptor - ISO/IEC 13818-1
* @var AVC_video_descriptor
* @brief AVC_video descriptor - ISO/IEC 13818-1
* @var ipmp_descriptor
* @brief ipmp descriptor - ISO/IEC 13818-1
* @var AVC_timing_and_HRD_descriptor
* @brief AVC_timing_and_HRD descriptor - ISO/IEC 13818-1
* @var mpeg2_aac_audio_descriptor
* @brief mpeg2_aac_audio descriptor - ISO/IEC 13818-1
* @var flexmux_timing_descriptor
* @brief flexmux_timing descriptor - ISO/IEC 13818-1
* @var network_name_descriptor
* @brief network_name descriptor - ETSI EN 300 468 V1.11.1 (2010-04)
* @var service_list_descriptor
* @brief service_list descriptor - ETSI EN 300 468 V1.11.1 (2010-04)
* @var stuffing_descriptor
* @brief stuffing descriptor - ETSI EN 300 468 V1.11.1 (2010-04)
* @var satellite_delivery_system_descriptor
* @brief satellite_delivery_system descriptor - ETSI EN 300 468 V1.11.1 (2010-04)
* @var cable_delivery_system_descriptor
* @brief cable_delivery_system descriptor - ETSI EN 300 468 V1.11.1 (2010-04)
* @var VBI_data_descriptor
* @brief VBI_data descriptor - ETSI EN 300 468 V1.11.1 (2010-04)
* @var VBI_teletext_descriptor
* @brief VBI_teletext descriptor - ETSI EN 300 468 V1.11.1 (2010-04)
* @var bouquet_name_descriptor
* @brief bouquet_name descriptor - ETSI EN 300 468 V1.11.1 (2010-04)
* @var service_descriptor
* @brief service descriptor - ETSI EN 300 468 V1.11.1 (2010-04)
* @var country_availability_descriptor
* @brief country_availability descriptor - ETSI EN 300 468 V1.11.1 (2010-04)
* @var linkage_descriptor
* @brief linkage descriptor - ETSI EN 300 468 V1.11.1 (2010-04)
* @var NVOD_reference_descriptor
* @brief NVOD_reference descriptor - ETSI EN 300 468 V1.11.1 (2010-04)
* @var time_shifted_service_descriptor
* @brief time_shifted_service descriptor - ETSI EN 300 468 V1.11.1 (2010-04)
* @var short_event_descriptor
* @brief short_event descriptor - ETSI EN 300 468 V1.11.1 (2010-04)
* @var extended_event_descriptor
* @brief extended_event descriptor - ETSI EN 300 468 V1.11.1 (2010-04)
* @var time_shifted_event_descriptor
* @brief time_shifted_event descriptor - ETSI EN 300 468 V1.11.1 (2010-04)
* @var component_descriptor
* @brief component descriptor - ETSI EN 300 468 V1.11.1 (2010-04)
* @var mosaic_descriptor
* @brief mosaic descriptor - ETSI EN 300 468 V1.11.1 (2010-04)
* @var stream_identifier_descriptor
* @brief stream_identifier descriptor - ETSI EN 300 468 V1.11.1 (2010-04)
* @var CA_identifier_descriptor
* @brief CA_identifier descriptor - ETSI EN 300 468 V1.11.1 (2010-04)
* @var content_descriptor
* @brief content descriptor - ETSI EN 300 468 V1.11.1 (2010-04)
* @var parental_rating_descriptor
* @brief parental_rating descriptor - ETSI EN 300 468 V1.11.1 (2010-04)
* @var teletext_descriptor
* @brief teletext descriptor - ETSI EN 300 468 V1.11.1 (2010-04)
* @var telephone_descriptor
* @brief telephone descriptor - ETSI EN 300 468 V1.11.1 (2010-04)
* @var local_time_offset_descriptor
* @brief local_time_offset descriptor - ETSI EN 300 468 V1.11.1 (2010-04)
* @var subtitling_descriptor
* @brief subtitling descriptor - ETSI EN 300 468 V1.11.1 (2010-04)
* @var terrestrial_delivery_system_descriptor
* @brief terrestrial_delivery_system descriptor - ETSI EN 300 468 V1.11.1 (2010-04)
* @var multilingual_network_name_descriptor
* @brief multilingual_network_name descriptor - ETSI EN 300 468 V1.11.1 (2010-04)
* @var multilingual_bouquet_name_descriptor
* @brief multilingual_bouquet_name descriptor - ETSI EN 300 468 V1.11.1 (2010-04)
* @var multilingual_service_name_descriptor
* @brief multilingual_service_name descriptor - ETSI EN 300 468 V1.11.1 (2010-04)
* @var multilingual_component_descriptor
* @brief multilingual_component descriptor - ETSI EN 300 468 V1.11.1 (2010-04)
* @var private_data_specifier_descriptor
* @brief private_data_specifier descriptor - ETSI EN 300 468 V1.11.1 (2010-04)
* @var service_move_descriptor
* @brief service_move descriptor - ETSI EN 300 468 V1.11.1 (2010-04)
* @var short_smoothing_buffer_descriptor
* @brief short_smoothing_buffer descriptor - ETSI EN 300 468 V1.11.1 (2010-04)
* @var frequency_list_descriptor
* @brief frequency_list descriptor - ETSI EN 300 468 V1.11.1 (2010-04)
* @var partial_transport_stream_descriptor
* @brief partial_transport_stream descriptor - ETSI EN 300 468 V1.11.1 (2010-04)
* @var data_broadcast_descriptor
* @brief data_broadcast descriptor - ETSI EN 300 468 V1.11.1 (2010-04)
* @var scrambling_descriptor
* @brief scrambling descriptor - ETSI EN 300 468 V1.11.1 (2010-04)
* @var data_broadcast_id_descriptor
* @brief data_broadcast_id descriptor - ETSI EN 300 468 V1.11.1 (2010-04)
* @var transport_stream_descriptor
* @brief transport_stream descriptor - ETSI EN 300 468 V1.11.1 (2010-04)
* @var DSNG_descriptor
* @brief DSNG descriptor - ETSI EN 300 468 V1.11.1 (2010-04)
* @var PDC_descriptor
* @brief PDC descriptor - ETSI EN 300 468 V1.11.1 (2010-04)
* @var AC_3_descriptor
* @brief AC_3 descriptor - ETSI EN 300 468 V1.11.1 (2010-04)
* @var ancillary_data_descriptor
* @brief ancillary_data descriptor - ETSI EN 300 468 V1.11.1 (2010-04)
* @var cell_list_descriptor
* @brief cell_list descriptor - ETSI EN 300 468 V1.11.1 (2010-04)
* @var cell_frequency_link_descriptor
* @brief cell_frequency_link descriptor - ETSI EN 300 468 V1.11.1 (2010-04)
* @var announcement_support_descriptor
* @brief announcement_support descriptor - ETSI EN 300 468 V1.11.1 (2010-04)
* @var application_signalling_descriptor
* @brief application_signalling descriptor - ETSI EN 300 468 V1.11.1 (2010-04)
* @var adaptation_field_data_descriptor
* @brief adaptation_field_data descriptor - ETSI EN 300 468 V1.11.1 (2010-04)
* @var service_identifier_descriptor
* @brief service_identifier descriptor - ETSI EN 300 468 V1.11.1 (2010-04)
* @var service_availability_descriptor
* @brief service_availability descriptor - ETSI EN 300 468 V1.11.1 (2010-04)
* @var default_authority_descriptor
* @brief default_authority descriptor - ETSI EN 300 468 V1.11.1 (2010-04)
* @var related_content_descriptor
* @brief related_content descriptor - ETSI EN 300 468 V1.11.1 (2010-04)
* @var TVA_id_descriptor
* @brief TVA_id descriptor - ETSI EN 300 468 V1.11.1 (2010-04)
* @var content_identifier_descriptor
* @brief content_identifier descriptor - ETSI EN 300 468 V1.11.1 (2010-04)
* @var time_slice_fec_identifier_descriptor
* @brief time_slice_fec_identifier descriptor - ETSI EN 300 468 V1.11.1 (2010-04)
* @var ECM_repetition_rate_descriptor
* @brief ECM_repetition_rate descriptor - ETSI EN 300 468 V1.11.1 (2010-04)
* @var S2_satellite_delivery_system_descriptor
* @brief S2_satellite_delivery_system descriptor - ETSI EN 300 468 V1.11.1 (2010-04)
* @var enhanced_AC_3_descriptor
* @brief enhanced_AC_3 descriptor - ETSI EN 300 468 V1.11.1 (2010-04)
* @var DTS_descriptor
* @brief DTS descriptor - ETSI EN 300 468 V1.11.1 (2010-04)
* @var AAC_descriptor
* @brief AAC descriptor - ETSI EN 300 468 V1.11.1 (2010-04)
* @var XAIT_location_descriptor
* @brief XAIT_location descriptor - ETSI EN 300 468 V1.11.1 (2010-04)
* @var FTA_content_management_descriptor
* @brief FTA_content_management descriptor - ETSI EN 300 468 V1.11.1 (2010-04)
* @var extension_descriptor
* @brief extension descriptor - ETSI EN 300 468 V1.11.1 (2010-04)
* @var CUE_identifier_descriptor
* @brief CUE_identifier descriptor - SCTE 35 2004
* @var extended_channel_name
* @brief extended_channel_name descriptor - SCTE 35 2004
* @var service_location
* @brief service_location descriptor - SCTE 35 2004
* @var component_name_descriptor
* @brief component_name descriptor - SCTE 35 2004
* @see http://www.etherguidesystems.com/Help/SDOs/ATSC/Semantics/Descriptors/Default.aspx
* @var logical_channel_number_descriptor
* @brief logical_channel_number descriptor - SCTE 35 2004
* @see http://www.coolstf.com/tsreader/descriptors.html
*
* @var carousel_id_descriptor
* @brief carousel_id descriptor - ABNT NBR 15603-1 2007
* @var association_tag_descriptor
* @brief association_tag descriptor - ABNT NBR 15603-1 2007
* @var deferred_association_tags_descriptor
* @brief deferred_association_tags descriptor - ABNT NBR 15603-1 2007
* @var hierarchical_transmission_descriptor
* @brief hierarchical_transmission descriptor - ABNT NBR 15603-1 2007
* @var digital_copy_control_descriptor
* @brief digital_copy_control descriptor - ABNT NBR 15603-1 2007
* @var network_identifier_descriptor
* @brief network_identifier descriptor - ABNT NBR 15603-1 2007
* @var partial_transport_stream_time_descriptor
* @brief partial_transport_stream_time descriptor - ABNT NBR 15603-1 2007
* @var audio_component_descriptor
* @brief audio_component descriptor - ABNT NBR 15603-1 2007
* @var hyperlink_descriptor
* @brief hyperlink descriptor - ABNT NBR 15603-1 2007
* @var target_area_descriptor
* @brief target_area descriptor - ABNT NBR 15603-1 2007
* @var data_contents_descriptor
* @brief data_contents descriptor - ABNT NBR 15603-1 2007
* @var video_decode_control_descriptor
* @brief video_decode_control descriptor - ABNT NBR 15603-1 2007
* @var download_content_descriptor
* @brief download_content descriptor - ABNT NBR 15603-1 2007
* @var CA_EMM_TS_descriptor
* @brief CA_EMM_TS descriptor - ABNT NBR 15603-1 2007
* @var CA_contract_information_descriptor
* @brief CA_contract_information descriptor - ABNT NBR 15603-1 2007
* @var CA_service_descriptor
* @brief CA_service descriptor - ABNT NBR 15603-1 2007
* @var TS_Information_descriptor
* @brief transport_stream_information descriptor - ABNT NBR 15603-1 2007
* @var extended_broadcaster_descriptor
* @brief extended_broadcaster descriptor - ABNT NBR 15603-1 2007
* @var logo_transmission_descriptor
* @brief logo_transmission descriptor - ABNT NBR 15603-1 2007
* @var basic_local_event_descriptor
* @brief basic_local_event descriptor - ABNT NBR 15603-1 2007
* @var reference_descriptor
* @brief reference descriptor - ABNT NBR 15603-1 2007
* @var node_relation_descriptor
* @brief node_relation descriptor - ABNT NBR 15603-1 2007
* @var short_node_information_descriptor
* @brief short_node_information descriptor - ABNT NBR 15603-1 2007
* @var STC_reference_descriptor
* @brief STC_reference descriptor - ABNT NBR 15603-1 2007
* @var series_descriptor
* @brief series descriptor - ABNT NBR 15603-1 2007
* @var event_group_descriptor
* @brief event_group descriptor - ABNT NBR 15603-1 2007
* @var SI_parameter_descriptor
* @brief SI_parameter descriptor - ABNT NBR 15603-1 2007
* @var broadcaster_Name_Descriptor
* @brief broadcaster_Name descriptor - ABNT NBR 15603-1 2007
* @var component_group_descriptor
* @brief component_group descriptor - ABNT NBR 15603-1 2007
* @var SI_prime_TS_descriptor
* @brief SI_prime_transport_stream descriptor - ABNT NBR 15603-1 2007
* @var board_information_descriptor
* @brief board_information descriptor - ABNT NBR 15603-1 2007
* @var LDT_linkage_descriptor
* @brief LDT_linkage descriptor - ABNT NBR 15603-1 2007
* @var connected_transmission_descriptor
* @brief connected_transmission descriptor - ABNT NBR 15603-1 2007
* @var content_availability_descriptor
* @brief content_availability descriptor - ABNT NBR 15603-1 2007
* @var service_group_descriptor
* @brief service_group descriptor - ABNT NBR 15603-1 2007
* @var carousel_compatible_composite_descriptor
* @brief carousel_compatible_composite descriptor - ABNT NBR 15603-1 2007
* @var conditional_playback_descriptor
* @brief conditional_playback descriptor - ABNT NBR 15603-1 2007
* @var ISDBT_delivery_system_descriptor
* @brief ISDBT terrestrial_delivery_system descriptor - ABNT NBR 15603-1 2007
* @var partial_reception_descriptor
* @brief partial_reception descriptor - ABNT NBR 15603-1 2007
* @var emergency_information_descriptor
* @brief emergency_information descriptor - ABNT NBR 15603-1 2007
* @var data_component_descriptor
* @brief data_component descriptor - ABNT NBR 15603-1 2007
* @var system_management_descriptor
* @brief system_management descriptor - ABNT NBR 15603-1 2007
*
* @var atsc_stuffing_descriptor
* @brief atsc_stuffing descriptor - ATSC A/65:2009
* @var atsc_ac3_audio_descriptor
* @brief atsc_ac3_audio descriptor - ATSC A/65:2009
* @var atsc_caption_service_descriptor
* @brief atsc_caption_service descriptor - ATSC A/65:2009
* @var atsc_content_advisory_descriptor
* @brief atsc_content_advisory descriptor - ATSC A/65:2009
* @var atsc_extended_channel_descriptor
* @brief atsc_extended_channel descriptor - ATSC A/65:2009
* @var atsc_service_location_descriptor
* @brief atsc_service_location descriptor - ATSC A/65:2009
* @var atsc_time_shifted_service_descriptor
* @brief atsc_time_shifted_service descriptor - ATSC A/65:2009
* @var atsc_component_name_descriptor
* @brief atsc_component_name descriptor - ATSC A/65:2009
* @var atsc_DCC_departing_request_descriptor
* @brief atsc_DCC_departing_request descriptor - ATSC A/65:2009
* @var atsc_DCC_arriving_request_descriptor
* @brief atsc_DCC_arriving_request descriptor - ATSC A/65:2009
* @var atsc_redistribution_control_descriptor
* @brief atsc_redistribution_control descriptor - ATSC A/65:2009
* @var atsc_ATSC_private_information_descriptor
* @brief atsc_ATSC_private_information descriptor - ATSC A/65:2009
* @var atsc_genre_descriptor
* @brief atsc_genre descriptor - ATSC A/65:2009
*/
enum descriptors {
/* ISO/IEC 13818-1 */
video_stream_descriptor = 0x02,
audio_stream_descriptor = 0x03,
hierarchy_descriptor = 0x04,
registration_descriptor = 0x05,
ds_alignment_descriptor = 0x06,
target_background_grid_descriptor = 0x07,
video_window_descriptor = 0x08,
conditional_access_descriptor = 0x09,
iso639_language_descriptor = 0x0a,
system_clock_descriptor = 0x0b,
multiplex_buffer_utilization_descriptor = 0x0c,
copyright_descriptor = 0x0d,
maximum_bitrate_descriptor = 0x0e,
private_data_indicator_descriptor = 0x0f,
smoothing_buffer_descriptor = 0x10,
std_descriptor = 0x11,
ibp_descriptor = 0x12,
mpeg4_video_descriptor = 0x1b,
mpeg4_audio_descriptor = 0x1c,
iod_descriptor = 0x1d,
sl_descriptor = 0x1e,
fmc_descriptor = 0x1f,
external_es_id_descriptor = 0x20,
muxcode_descriptor = 0x21,
fmxbuffersize_descriptor = 0x22,
multiplexbuffer_descriptor = 0x23,
content_labeling_descriptor = 0x24,
metadata_pointer_descriptor = 0x25,
metadata_descriptor = 0x26,
metadata_std_descriptor = 0x27,
AVC_video_descriptor = 0x28,
ipmp_descriptor = 0x29,
AVC_timing_and_HRD_descriptor = 0x2a,
mpeg2_aac_audio_descriptor = 0x2b,
flexmux_timing_descriptor = 0x2c,
/* ETSI EN 300 468 V1.11.1 (2010-04) */
network_name_descriptor = 0x40,
service_list_descriptor = 0x41,
stuffing_descriptor = 0x42,
satellite_delivery_system_descriptor = 0x43,
cable_delivery_system_descriptor = 0x44,
VBI_data_descriptor = 0x45,
VBI_teletext_descriptor = 0x46,
bouquet_name_descriptor = 0x47,
service_descriptor = 0x48,
country_availability_descriptor = 0x49,
linkage_descriptor = 0x4a,
NVOD_reference_descriptor = 0x4b,
time_shifted_service_descriptor = 0x4c,
short_event_descriptor = 0x4d,
extended_event_descriptor = 0x4e,
time_shifted_event_descriptor = 0x4f,
component_descriptor = 0x50,
mosaic_descriptor = 0x51,
stream_identifier_descriptor = 0x52,
CA_identifier_descriptor = 0x53,
content_descriptor = 0x54,
parental_rating_descriptor = 0x55,
teletext_descriptor = 0x56,
telephone_descriptor = 0x57,
local_time_offset_descriptor = 0x58,
subtitling_descriptor = 0x59,
terrestrial_delivery_system_descriptor = 0x5a,
multilingual_network_name_descriptor = 0x5b,
multilingual_bouquet_name_descriptor = 0x5c,
multilingual_service_name_descriptor = 0x5d,
multilingual_component_descriptor = 0x5e,
private_data_specifier_descriptor = 0x5f,
service_move_descriptor = 0x60,
short_smoothing_buffer_descriptor = 0x61,
frequency_list_descriptor = 0x62,
partial_transport_stream_descriptor = 0x63,
data_broadcast_descriptor = 0x64,
scrambling_descriptor = 0x65,
data_broadcast_id_descriptor = 0x66,
transport_stream_descriptor = 0x67,
DSNG_descriptor = 0x68,
PDC_descriptor = 0x69,
AC_3_descriptor = 0x6a,
ancillary_data_descriptor = 0x6b,
cell_list_descriptor = 0x6c,
cell_frequency_link_descriptor = 0x6d,
announcement_support_descriptor = 0x6e,
application_signalling_descriptor = 0x6f,
adaptation_field_data_descriptor = 0x70,
service_identifier_descriptor = 0x71,
service_availability_descriptor = 0x72,
default_authority_descriptor = 0x73,
related_content_descriptor = 0x74,
TVA_id_descriptor = 0x75,
content_identifier_descriptor = 0x76,
time_slice_fec_identifier_descriptor = 0x77,
ECM_repetition_rate_descriptor = 0x78,
S2_satellite_delivery_system_descriptor = 0x79,
enhanced_AC_3_descriptor = 0x7a,
DTS_descriptor = 0x7b,
AAC_descriptor = 0x7c,
XAIT_location_descriptor = 0x7d,
FTA_content_management_descriptor = 0x7e,
extension_descriptor = 0x7f,
/* SCTE 35 2004 */
CUE_identifier_descriptor = 0x8a,
extended_channel_name = 0xa0,
service_location = 0xa1,
/* From http://www.etherguidesystems.com/Help/SDOs/ATSC/Semantics/Descriptors/Default.aspx */
component_name_descriptor = 0xa3,
/* From http://www.coolstf.com/tsreader/descriptors.html */
logical_channel_number_descriptor = 0x83,
/* ISDB Descriptors, as defined on ABNT NBR 15603-1 2007 */
carousel_id_descriptor = 0x13,
association_tag_descriptor = 0x14,
deferred_association_tags_descriptor = 0x15,
hierarchical_transmission_descriptor = 0xc0,
digital_copy_control_descriptor = 0xc1,
network_identifier_descriptor = 0xc2,
partial_transport_stream_time_descriptor = 0xc3,
audio_component_descriptor = 0xc4,
hyperlink_descriptor = 0xc5,
target_area_descriptor = 0xc6,
data_contents_descriptor = 0xc7,
video_decode_control_descriptor = 0xc8,
download_content_descriptor = 0xc9,
CA_EMM_TS_descriptor = 0xca,
CA_contract_information_descriptor = 0xcb,
CA_service_descriptor = 0xcc,
TS_Information_descriptor = 0xcd,
extended_broadcaster_descriptor = 0xce,
logo_transmission_descriptor = 0xcf,
basic_local_event_descriptor = 0xd0,
reference_descriptor = 0xd1,
node_relation_descriptor = 0xd2,
short_node_information_descriptor = 0xd3,
STC_reference_descriptor = 0xd4,
series_descriptor = 0xd5,
event_group_descriptor = 0xd6,
SI_parameter_descriptor = 0xd7,
broadcaster_Name_Descriptor = 0xd8,
component_group_descriptor = 0xd9,
SI_prime_TS_descriptor = 0xda,
board_information_descriptor = 0xdb,
LDT_linkage_descriptor = 0xdc,
connected_transmission_descriptor = 0xdd,
content_availability_descriptor = 0xde,
service_group_descriptor = 0xe0,
carousel_compatible_composite_descriptor = 0xf7,
conditional_playback_descriptor = 0xf8,
ISDBT_delivery_system_descriptor = 0xfa,
partial_reception_descriptor = 0xfb,
emergency_information_descriptor = 0xfc,
data_component_descriptor = 0xfd,
system_management_descriptor = 0xfe,
/* ATSC descriptors - ATSC A/65:2009 spec */
atsc_stuffing_descriptor = 0x80,
atsc_ac3_audio_descriptor = 0x81,
atsc_caption_service_descriptor = 0x86,
atsc_content_advisory_descriptor = 0x87,
atsc_extended_channel_descriptor = 0xa0,
atsc_service_location_descriptor = 0xa1,
atsc_time_shifted_service_descriptor = 0xa2,
atsc_component_name_descriptor = 0xa3,
atsc_DCC_departing_request_descriptor = 0xa8,
atsc_DCC_arriving_request_descriptor = 0xa9,
atsc_redistribution_control_descriptor = 0xaa,
atsc_ATSC_private_information_descriptor = 0xad,
atsc_genre_descriptor = 0xab,
};
/*
* NOTE: this is here just to avoid API break. There was a typo
* on the name of this descriptor
*/
#define TS_Information_descriptior TS_Information_descriptor
/* Please see desc_extension.h for extension_descriptor types */
#endif

View File

@@ -0,0 +1,157 @@
/*
* Copyright (c) 2011-2014 - Mauro Carvalho Chehab
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation version 2.1 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* These routines were originally written as part of the dvb-apps, as:
* util functions for various ?zap implementations
*
* Copyright (C) 2001 Johannes Stezenbach (js@convergence.de)
* for convergence integrated media
*
* Originally licensed as GPLv2 or upper
*/
/**
* @file dvb-demux.h
* @ingroup demux
* @brief Provides interfaces to deal with DVB demux.
* @copyright GNU Lesser General Public License version 2.1 (LGPLv2.1)
* @author Mauro Carvalho Chehab
*
* @par Bug Report
* Please submit bug reports and patches to linux-media@vger.kernel.org
*/
#ifndef _DVB_DEMUX_H
#define _DVB_DEMUX_H
#include <linux/dvb/dmx.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Opens a DVB demux in read/write mode
* @ingroup demux
*
* @param adapter DVB adapter number to open
* @param demux DVB demux number to open
*
* @details This is a wrapper function to open(). File is always opened in
* blocking mode.
*
* @return Returns a file descriptor on success, -1 otherwise.
*
* @warning Deprecated. Please use dvb_dev_open() instead.
*/
int dvb_dmx_open(int adapter, int demux);
/**
* @brief Stops the DMX filter for the file descriptor and closes
* @ingroup demux
*
* @param dmx_fd File descriptor to close
*
* This is a wrapper function to close().
*
* @warning Deprecated. Please use dvb_dev_close() instead.
*/
void dvb_dmx_close(int dmx_fd);
/**
* @brief Stops the DMX filter for a given file descriptor
* @ingroup demux
*
* @param dmx_fd File descriptor to close
*
* This is a wrapper function to DMX_STOP ioctl.
* See http://linuxtv.org/downloads/v4l-dvb-apis/dvb_demux.html
* for more details.
*
* @warning Deprecated. Please use dvb_dev_dmx_stop() instead.
*/
void dvb_dmx_stop(int dmx_fd);
/**
* @brief Start a filter for a MPEG-TS Packetized Elementary
* Stream (PES)
* @ingroup demux
*
* @param dmxfd File descriptor for the demux device
* @param pid Program ID to filter. Use 0x2000 to select all PIDs
* @param type type of the PID (DMX_PES_VIDEO, DMX_PES_AUDIO,
* DMX_PES_OTHER, etc).
* @param output Where the data will be output (DMX_OUT_TS_TAP,
* DMX_OUT_DECODER, etc).
* @param buffersize Size of the buffer to be allocated to store the filtered data.
*
* This is a wrapper function for DMX_SET_PES_FILTER ioctl.
* See http://linuxtv.org/downloads/v4l-dvb-apis/dvb_demux.html
* for more details.
*
* @return Retuns zero on success, -1 otherwise.
*
* @warning Deprecated. Please use dvb_dev_dmx_set_pesfilter() instead.
*/
int dvb_set_pesfilter(int dmxfd, int pid, dmx_pes_type_t type,
dmx_output_t output, int buffersize);
/**
* @brief Sets a MPEG-TS section filter
* @ingroup demux
*
* @param dmxfd File descriptor for the demux device
* @param pid Program ID to filter. Use 0x2000 to select all PIDs
* @param filtsize Size of the filter (up to 18 btyes)
* @param filter data to filter. Can be NULL or should have filtsize length
* @param mask filter mask. Can be NULL or should have filtsize length
* @param mode mode mask. Can be NULL or should have filtsize length
* @param flags flags for set filter (DMX_CHECK_CRC,DMX_ONESHOT,
* DMX_IMMEDIATE_START).
*
* This is a wrapper function for DMX_SET_FILTER ioctl.
* See http://linuxtv.org/downloads/v4l-dvb-apis/dvb_demux.html
* for more details.
*
* @warning Deprecated. Please use dvb_dev_dmx_set_pesfilter() instead.
*
* @return Retuns zero on success, -1 otherwise.
*
*/
int dvb_set_section_filter(int dmxfd, int pid, unsigned filtsize,
unsigned char *filter,
unsigned char *mask,
unsigned char *mode,
unsigned int flags);
/**
* @brief read the contents of the MPEG-TS PAT table, seeking for
* an specific service ID
* @ingroup demux
*
* @param dmxfd File descriptor for the demux device
* @param sid Session ID to seeking
*
* @warning Deprecated. Please use dvb_get_pmt_pid() instead.
*
* @return At return, it returns a negative value if error or the PID associated with
* the desired Session ID.
*
* @warning This function currently assumes that the PAT fits into one session.
*/
int dvb_get_pmt_pid(int dmxfd, int sid);
#ifdef __cplusplus
}
#endif
#endif

510
include/libdvbv5/dvb-dev.h Normal file
View File

@@ -0,0 +1,510 @@
/*
* Copyright (c) 2016 - Mauro Carvalho Chehab
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation version 2.1 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
* Or, point your browser to http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*/
#ifndef _DVB_DEV_H
#define _DVB_DEV_H
#include "dvb-fe.h"
#include "dvb-scan.h"
#include <linux/dvb/dmx.h>
/**
* @file dvb-dev.h
* @ingroup dvb_device
* @brief Provides interfaces to handle Digital TV devices.
* @copyright GNU Lesser General Public License version 2.1 (LGPLv2.1)
* @author Mauro Carvalho Chehab
*
* Digital TV device node file names depend on udev configuration. For
* example, while frontends are typically found at/dev/dvb/adapter?/frontend?,
* the actual file name can vary from system to system, depending on the
* udev ruleset.
*
* The libdvbv5 provides a set of functions to allow detecting and getting
* the device paths in a sane way, via libudev.
*
* @par Bug Report
* Please submit bug reports and patches to linux-media@vger.kernel.org
*/
/**
* @enum dvb_dev_type
* @brief Type of a device entry to search
* @ingroup dvb_device
*
* @param DVB_DEVICE_FRONTEND Digital TV frontend
* @param DVB_DEVICE_DEMUX Digital TV demux
* @param DVB_DEVICE_DVR Digital TV Digital Video Record
* @param DVB_DEVICE_NET Digital TV network interface control
* @param DVB_DEVICE_CA Digital TV Conditional Access
* @param DVB_DEVICE_CA_SEC Digital TV Conditional Access serial
*/
enum dvb_dev_type {
DVB_DEVICE_FRONTEND,
DVB_DEVICE_DEMUX,
DVB_DEVICE_DVR,
DVB_DEVICE_NET,
DVB_DEVICE_CA,
DVB_DEVICE_CA_SEC,
DVB_DEVICE_VIDEO,
DVB_DEVICE_AUDIO,
};
/**
* @struct dvb_dev_list
* @brief Digital TV device node properties
* @ingroup dvb_device
*
* @param path path for the /dev file handler
* @param sysname Kernel's system name for the device (dvb?.frontend?,
* for example)
* @param dvb_type type of the DVB device, as defined by enum dvb_dev_type
* @param bus_addr address of the device at the bus. For USB devices,
* it will be like: usb:3-1.1.4; for PCI devices:
* pci:0000:01:00.0)
* @param bus_id Id of the device at the bus (optional, PCI ID or USB ID)
* @param manufacturer Device's manufacturer name (optional, only on USB)
* @param product Device's product name (optional, only on USB)
* @param serial Device's serial name (optional, only on USB)
*/
struct dvb_dev_list {
char *syspath;
char *path;
char *sysname;
enum dvb_dev_type dvb_type;
char *bus_addr;
char *bus_id;
char *manufacturer;
char *product;
char *serial;
};
/**
* @enum dvb_dev_change_type
* @brief Describes the type of change to be notifier_delay
*
* @param DVB_DEV_ADD New device detected
* @param DVB_DEV_CHANGE Device has changed something
* @param DVB_DEV_REMOVE A hot-pluggable device was removed
*/
enum dvb_dev_change_type {
DVB_DEV_ADD,
DVB_DEV_CHANGE,
DVB_DEV_REMOVE,
};
/**
* @brief Describes a callback for dvb_dev_find()
*
* sysname: Kernel's system name for the device (dvb?.frontend?,
* for example)
* @type: type of change, as defined by enum dvb_dev_change_type
*
* @note: the returned string should be freed with free().
*/
typedef int (*dvb_dev_change_t)(char *sysname,
enum dvb_dev_change_type type, void *priv);
/**
* @struct dvb_open_descriptor
*
* Opaque struct with a DVB open file descriptor
*/
struct dvb_open_descriptor;
/**
* @struct dvb_device
* @brief Digital TV list of devices
* @ingroup dvb_device
*
* @param devices Array with a dvb_dev_list of devices. Each device
* node is a different entry at the list.
* @param num_devices number of elements at the devices array.
*/
struct dvb_device {
/* Digital TV device lists */
struct dvb_dev_list *devices;
int num_devices;
/* Digital TV frontend access */
struct dvb_v5_fe_parms *fe_parms;
};
/**
* @brief Allocate a struct dvb_device
* @ingroup dvb_device
*
* @note Before using the dvb device function calls, the struct dvb_device should
* be allocated via this function call.
*
* @return on success, returns a pointer to the allocated struct dvb_device or
* NULL if not enough memory to allocate the struct.
*/
struct dvb_device *dvb_dev_alloc(void);
/**
* @brief free a struct dvb_device
* @ingroup dvb_device
*
* @param dvb pointer to struct dvb_device to be freed
*/
void dvb_dev_free(struct dvb_device *dvb);
/**
* @brief finds all DVB devices on the local machine
* @ingroup dvb_device
*
* @param dvb pointer to struct dvb_device to be filled
* @param enable_monitor if different than zero put the routine into
* monitor mode
* @param user_priv pointer to user private data
*
* This routine can be called on two modes: normal or monitor mode
*
* In normal mode, it will seek for the local Digital TV devices, store them
* at the struct dvb_device and return.
*
* In monitor mode, it will not only enumerate all devices, but it will also
* keep waiting for device changes. The device seek loop will only be
* interrupted after calling dvb_dev_stop_monitor().
*
* Please notice that, in such mode, the function will wait forever. So, it
* is up to the application to put start a separate thread to handle it in
* monitor mode, and add the needed mutexes to make it thread safe.
*
* @return returns 0 on success, a negative value otherwise.
*/
int dvb_dev_find(struct dvb_device *dvb, dvb_dev_change_t handler,
void *user_priv);
/**
* @brief Find a device that matches the search criteria given by this
* functions's parameters.
*
* @param dvb pointer to struct dvb_device to be used
* @param adapter Adapter number, as defined internally at the Kernel.
* Always start with 0;
* @param num Digital TV device number (e. g. frontend0, net0, etc);
* @param type Type of the device, as given by enum dvb_dev_type;
*
* @return returns a pointer to a struct dvb_dev_list object or NULL if the
* desired device was not found.
*/
struct dvb_dev_list *dvb_dev_seek_by_adapter(struct dvb_device *dvb,
unsigned int adapter,
unsigned int num,
enum dvb_dev_type type);
/**
* @brief Return data about a device from its sysname
*
* @param dvb pointer to struct dvb_device to be used
* @param sysname Kernel's name of the device to be opened, as obtained
* via dvb_dev_seek_by_adapter() or via dvb_dev_find().
*
* @return returns a pointer to a struct dvb_dev_list object or NULL if the
* desired device was not found.
*/
struct dvb_dev_list *dvb_get_dev_info(struct dvb_device *dvb,
const char *sysname);
/**
* @brief Stop the dvb_dev_find loop
* @ingroup dvb_device
*
* @param dvb pointer to struct dvb_device to be used
*
* This function stops dvb_dev_find() if it is running in monitor
* mode. It does nothing on other modes. Can be called even if the
* monitor mode was already stopped.
*/
void dvb_dev_stop_monitor(struct dvb_device *dvb);
/**
* @brief Sets the DVB verbosity and log function with context private data
* @ingroup dvb_device
*
* @param dvb pointer to struct dvb_device to be used
* @param verbose Verbosity level of the messages that will be printed
* @param logfunc Callback function to be called when a log event
* happens. Can either store the event into a file or
* to print it at the TUI/GUI. Can be null.
* @param logpriv Private data for log function
*
* @details Sets the function to report log errors and to set the verbosity
* level of debug report messages. If not called, or if logfunc is
* NULL, the libdvbv5 will report error and debug messages via stderr,
* and will use colors for the debug messages.
*
*/
void dvb_dev_set_logpriv(struct dvb_device *dvb,
unsigned verbose,
dvb_logfunc_priv logfunc, void *logpriv);
/**
* @brief Sets the DVB verbosity and log function
* @ingroup dvb_device
*
* @param dvb pointer to struct dvb_device to be used
* @param verbose Verbosity level of the messages that will be printed
* @param logfunc Callback function to be called when a log event
* happens. Can either store the event into a file or
* to print it at the TUI/GUI. Can be null.
*
* @details Sets the function to report log errors and to set the verbosity
* level of debug report messages. If not called, or if logfunc is
* NULL, the libdvbv5 will report error and debug messages via stderr,
* and will use colors for the debug messages.
*
*/
void dvb_dev_set_log(struct dvb_device *dvb,
unsigned verbose,
dvb_logfunc logfunc);
/**
* @brief Opens a dvb device
* @ingroup dvb_device
*
* @param dvb pointer to struct dvb_device to be used
* @param sysname Kernel's name of the device to be opened, as obtained
* via dvb_dev_seek_by_adapter() or via dvb_dev_find().
* @param flags Flags to be passed to open: O_RDONLY, O_RDWR and/or
* O_NONBLOCK
*
*
* @note Please notice that O_NONBLOCK is not supported for frontend devices,
* and will be silently ignored.
*
* @note the sysname will only work if a previous call to dvb_dev_find()
* is issued.
*
* @details This function is equivalent to open(2) system call: it opens a
* Digital TV given by the dev parameter, using the flags.
*
* @return returns a pointer to the dvb_open_descriptor that should be used
* on further calls if sucess. NULL otherwise.
*/
struct dvb_open_descriptor *dvb_dev_open(struct dvb_device *dvb,
const char *sysname, int flags);
/**
* @brief Closes a dvb device
* @ingroup dvb_device
*
* @param open_dev Points to the struct dvb_open_descriptor to be
* closed.
*/
void dvb_dev_close(struct dvb_open_descriptor *open_dev);
/**
* @brief returns fd from a local device
* This will not work for remote devices.
* @ingroup dvb_device
*
* @param open_dev Points to the struct dvb_open_descriptor
*
* @return On success, returns the fd.
* Returns -1 on error.
*/
int dvb_dev_get_fd(struct dvb_open_descriptor *open_dev);
/**
* @brief read from a dvb demux or dvr file
* @ingroup dvb_device
*
* @param open_dev Points to the struct dvb_open_descriptor to be
* closed.
* @param buf Buffer to store the data
* @param count number of bytes to read
*
* @return On success, returns the number of bytes read. Returns -1 on
* error.
*/
ssize_t dvb_dev_read(struct dvb_open_descriptor *open_dev,
void *buf, size_t count);
/**
* @brief Stops the demux filter for a given file descriptor
* @ingroup dvb_device
*
* @param open_dev Points to the struct dvb_open_descriptor
*
* This is a wrapper function for DMX_STOP ioctl.
*
* See http://linuxtv.org/downloads/v4l-dvb-apis/dvb_demux.html
* for more details.
*
* @note valid only for DVB_DEVICE_DEMUX.
*/
void dvb_dev_dmx_stop(struct dvb_open_descriptor *open_dev);
/**
* @brief Start a demux or dvr buffer size
* @ingroup dvb_device
*
* @param open_dev Points to the struct dvb_open_descriptor
* @param buffersize Size of the buffer to be allocated to store the filtered data.
*
* This is a wrapper function for DMX_SET_BUFFER_SIZE ioctl.
*
* See http://linuxtv.org/downloads/v4l-dvb-apis/dvb_demux.html
* for more details.
*
* @return Retuns zero on success, -1 otherwise.
*
* @note valid only for DVB_DEVICE_DEMUX or DVB_DEVICE_DVR.
*/
int dvb_dev_set_bufsize(struct dvb_open_descriptor *open_dev,
int buffersize);
/**
* @brief Start a filter for a MPEG-TS Packetized Elementary
* Stream (PES)
* @ingroup dvb_device
*
* @param open_dev Points to the struct dvb_open_descriptor
* @param pid Program ID to filter. Use 0x2000 to select all PIDs
* @param type type of the PID (DMX_PES_VIDEO, DMX_PES_AUDIO,
* DMX_PES_OTHER, etc).
* @param output Where the data will be output (DMX_OUT_TS_TAP,
* DMX_OUT_DECODER, etc).
* @param buffersize Size of the buffer to be allocated to store the filtered data.
*
* This is a wrapper function for DMX_SET_PES_FILTER and DMX_SET_BUFFER_SIZE
* ioctls.
*
* See http://linuxtv.org/downloads/v4l-dvb-apis/dvb_demux.html
* for more details.
*
* @return Retuns zero on success, -1 otherwise.
*
* @note valid only for DVB_DEVICE_DEMUX.
*/
int dvb_dev_dmx_set_pesfilter(struct dvb_open_descriptor *open_dev,
int pid, dmx_pes_type_t type,
dmx_output_t output, int buffersize);
/**
* @brief Sets a MPEG-TS section filter
* @ingroup dvb_device
*
* @param open_dev Points to the struct dvb_open_descriptor
* @param pid Program ID to filter. Use 0x2000 to select all PIDs
* @param filtsize Size of the filter (up to 18 btyes)
* @param filter data to filter. Can be NULL or should have filtsize length
* @param mask filter mask. Can be NULL or should have filtsize length
* @param mode mode mask. Can be NULL or should have filtsize length
* @param flags flags for set filter (DMX_CHECK_CRC,DMX_ONESHOT,
* DMX_IMMEDIATE_START).
*
* This is a wrapper function for DMX_SET_FILTER ioctl.
*
* See http://linuxtv.org/downloads/v4l-dvb-apis/dvb_demux.html
* for more details.
*
* @return Retuns zero on success, -1 otherwise.
*
* @note valid only for DVB_DEVICE_DEMUX.
*/
int dvb_dev_dmx_set_section_filter(struct dvb_open_descriptor *open_dev,
int pid, unsigned filtsize,
unsigned char *filter,
unsigned char *mask,
unsigned char *mode,
unsigned int flags);
/**
* @brief read the contents of the MPEG-TS PAT table, seeking for
* an specific service ID
* @ingroup dvb_device
*
* @param open_dev Points to the struct dvb_open_descriptor
* @param sid Session ID to seeking
*
* @return At return, it returns a negative value if error or the PID
* associated with the desired Session ID.
*
* @warning This function currently assumes that the PAT fits into one session.
*
* @note valid only for DVB_DEVICE_DEMUX.
*/
int dvb_dev_dmx_get_pmt_pid(struct dvb_open_descriptor *open_dev, int sid);
/**
* @brief Scans a DVB dvb_add_scaned_transponder
* @ingroup frontend_scan
*
* @param entry DVB file entry that corresponds to a transponder to be
* tuned
* @param open_dev Points to the struct dvb_open_descriptor
* @param check_frontend a pointer to a function that will show the frontend
* status while tuning into a transponder
* @param args a pointer, opaque to libdvbv5, that will be used when
* calling check_frontend. It should contain any parameters
* that could be needed by check_frontend.
* @param other_nit Use alternate table IDs for NIT and other tables
* @param timeout_multiply Improves the timeout for each table reception, by
*
* This is the function that applications should use when doing a transponders
* scan. It does everything needed to fill the entries with DVB programs
* (virtual channels) and detect the PIDs associated with them.
*
* This is the dvb_device variant of dvb_scan_transponder().
*/
struct dvb_v5_descriptors *dvb_dev_scan(struct dvb_open_descriptor *open_dev,
struct dvb_entry *entry,
check_frontend_t *check_frontend,
void *args,
unsigned other_nit,
unsigned timeout_multiply);
/* From dvb-dev-remote.c */
#ifdef HAVE_DVBV5_REMOTE
#define REMOTE_BUF_SIZE (87 * 188) /* 16356 bytes */
/**
* @brief initialize the dvb-dev to use a remote device running the
* dvbv5-daemon.
*
* @param dvb pointer to struct dvb_device to be used
* @param server server hostname or address
* @param port server port
*
* @note The protocol between the dvbv5-daemon and the dvb_dev library is
* highly experimental and is subject to changes in a near future. So,
* while this is not stable enough, you will only work if both the client
* and the server are running the same version of the v4l-utils library.
*/
int dvb_dev_remote_init(struct dvb_device *d, char *server, int port);
#else
static inline int dvb_dev_remote_init(struct dvb_device *d, char *server,
int port)
{
return -1;
};
#endif
#endif

770
include/libdvbv5/dvb-fe.h Normal file
View File

@@ -0,0 +1,770 @@
/*
* Copyright (c) 2011-2014 - Mauro Carvalho Chehab
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation version 2.1 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
* Or, point your browser to http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
*/
#ifndef _DVB_FE_H
#define _DVB_FE_H
#include <stdio.h>
#include <errno.h>
#include <stdint.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <string.h>
#include "dvb-frontend.h"
#include "dvb-sat.h"
#include "dvb-log.h"
/**
* @file dvb-fe.h
* @ingroup frontend
* @brief Provides interfaces to deal with DVB frontend.
* @copyright GNU Lesser General Public License version 2.1 (LGPLv2.1)
* @author Mauro Carvalho Chehab
*
* The libdvbv5 API works with a set of key/value properties.
* There are two types of properties:
*
* - The ones defined at the Kernel's frontent API, that are found at
* /usr/include/linux/dvb/frontend.h (actually, it uses a local copy
* of that file, stored at ./include/linux/dvb/frontend.h)
*
* - Some extra properties used by libdvbv5. Those can be found at
* lib/include/libdvbv5/dvb-v5-std.h and start at DTV_USER_COMMAND_START.
*
* Just like the DTV properties, the stats are cached. That warrants that
* all stats are got at the same time, when dvb_fe_get_stats() is called.
*
* @par Bug Report
* Please submit bug reports and patches to linux-media@vger.kernel.org
*/
/**
* @def ARRAY_SIZE(array)
* @brief Calculates the number of elements of an array
* @ingroup ancillary
*/
#define ARRAY_SIZE(x) (sizeof(x)/sizeof((x)[0]))
/**
* @def MAX_DELIVERY_SYSTEMS
* @brief Max number of delivery systems for a given frontend.
* @ingroup frontend
*/
#define MAX_DELIVERY_SYSTEMS 20
#ifndef _DOXYGEN
/*
* There are a few aliases for other properties. Those are needed just
* to avoid breaking apps that depend on the library but shoudn't be used
* anymore on newer apps.
*/
#define DTV_MAX_STATS DTV_NUM_STATS_PROPS
#define DTV_SIGNAL_STRENGTH DTV_STAT_SIGNAL_STRENGTH
#define DTV_SNR DTV_STAT_CNR
#define DTV_UNCORRECTED_BLOCKS DTV_STAT_ERROR_BLOCK_COUNT
#endif
/**
* @struct dvb_v5_fe_parms
* @ingroup frontend
* @brief Keeps data needed to handle the DVB frontend
*
* @param info Contains the DVB info properties (RO)
* @param version Version of the Linux DVB API (RO)
* @param has_v5_stats A value different than 0 indicates that the
* frontend supports DVBv5 stats (RO)
* @param current_sys Currently selected delivery system (RO)
* @param num_systems Number of delivery systems (RO)
* @param systems Delivery systems supported by the hardware (RO)
* @param legacy_fe A value different than 0 indicates a legacy
* Kernel driver using DVBv3 API only, or that
* DVBv3 only mode was forced by the client (RO)
* @param abort Client should set it to abort a pending
* operation like DTV scan (RW)
* @param lna: Sets the LNA mode 0 disables; 1 enables, -1 uses
* auto mode (RW)
* @param lnb LNBf description (RW)
* @param sat_number Number of the satellite (used by DISEqC setup) (RW)
* @param freq_bpf SCR/Unicable band-pass filter frequency to use, in kHz
* @param verbose Verbosity level of the library (RW)
* @param dvb_logfunc Function used to write log messages (RO)
* @param default_charset Name of the charset used by the DVB standard (RW)
* @param output_charset Name of the charset to output (system specific) (RW)
*
* @details The fields marked as RO should not be changed by the client, as otherwise
* undesired effects may happen. The ones marked as RW are ok to either read
* or write by the client.
*/
struct dvb_v5_fe_parms {
/* Information visible to the client - don't override those values */
struct dvb_frontend_info info;
uint32_t version;
int has_v5_stats;
fe_delivery_system_t current_sys;
int num_systems;
fe_delivery_system_t systems[MAX_DELIVERY_SYSTEMS];
int legacy_fe;
/* The values below are specified by the library client */
/* Flags from the client to the library */
int abort;
/* Linear Amplifier settings */
int lna;
/* Satellite settings */
const struct dvb_sat_lnb *lnb;
int sat_number;
unsigned freq_bpf;
unsigned diseqc_wait;
/* Function to write DVB logs */
unsigned verbose;
dvb_logfunc logfunc;
/* Charsets to be used by the conversion utilities */
char *default_charset;
char *output_charset;
};
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Allocates a dummy frontend structure
* @ingroup frontend
*
* @details This is useful for some applications that may want to just use the
* frontend structure internally, without associating it with a real hardware
*
* @return Returns a pointer to a dummy struct, or NULL if no memory.
*/
struct dvb_v5_fe_parms *dvb_fe_dummy(void);
/**
* @brief Opens a frontend and allocates a structure to work with
* @ingroup frontend
*
* @param adapter Number of the adapter to open
* @param frontend Number of the frontend to open
* @param verbose Verbosity level of the messages that will be
* printed
* @param use_legacy_call Force to use the DVBv3 calls, instead of using
* the DVBv5 API
* @param logfunc Callback function to be called when a log event
* happens. Can either store the event into a file
* or to print it at the TUI/GUI. If NULL, the
* library will use its internal handler.
* @param flags Flags to be passed to open. Currently only two
* flags are supported: O_RDONLY or O_RDWR.
* Using O_NONBLOCK may hit unexpected issues.
*
* @todo Add/check support for O_NONBLOCK at the scan routines.
*
* @details This function should be called before using any other function at
* the frontend library (or the other alternatives: dvb_fe_open() or
* dvb_fe_dummy().
*
* In general, this is called using O_RDWR, except if all that it is wanted
* is to check the DVB frontend statistics.
*
* @return Returns a pointer to an allocated data pointer or NULL on error.
*/
struct dvb_v5_fe_parms *dvb_fe_open_flags(int adapter, int frontend,
unsigned verbose,
unsigned use_legacy_call,
dvb_logfunc logfunc,
int flags);
/**
* @brief Opens a frontend and allocates a structure to work with
* @ingroup frontend
*
* @param adapter Number of the adapter to open
* @param frontend Number of the frontend to open
* @param verbose Verbosity level of the messages that will be
* printed
* @param use_legacy_call Force to use the DVBv3 calls, instead of using
* the DVBv5 API
*
* @details This function should be called before using any other function at
* the frontend library (or the other alternatives: dvb_fe_open2() or
* dvb_fe_dummy().
*
* @return Returns a pointer to an allocated data pointer or NULL on error.
*/
struct dvb_v5_fe_parms *dvb_fe_open(int adapter, int frontend,
unsigned verbose,
unsigned use_legacy_call);
/**
* @brief Opens a frontend and allocates a structure to work with
* @ingroup frontend
*
* @param adapter Number of the adapter to open
* @param frontend Number of the frontend to open
* @param verbose Verbosity level of the messages that will be
* printed
* @param use_legacy_call Force to use the DVBv3 calls, instead of using
* the DVBv5 API
* @param logfunc Callback function to be called when a log event
* happens. Can either store the event into a file
* or to print it at the TUI/GUI.
*
* @details This function should be called before using any other function at
* the frontend library (or the other alternatives: dvb_fe_open() or
* dvb_fe_dummy().
*
* @return Returns a pointer to an allocated data pointer or NULL on error.
*/
struct dvb_v5_fe_parms *dvb_fe_open2(int adapter, int frontend,
unsigned verbose, unsigned use_legacy_call,
dvb_logfunc logfunc);
/**
* @brief Closes the frontend and frees allocated resources
* @ingroup frontend
*
* @param parms struct dvb_v5_fe_parms pointer to the opened device
*/
void dvb_fe_close(struct dvb_v5_fe_parms *parms);
/**
* @brief Returns the string name associated with a DVBv5 command
* @ingroup frontend
*
* @param cmd DVBv5 or libdvbv5 property
*
* @details This function gets an integer argument (cmd) and returns a string
* that corresponds to the name of that property.
*
* @return it returns a string that corresponds to the property name.
* For example:
* dvb_cmd_name(DTV_GUARD_INTERVAL) would return "GUARD_INTERVAL"
* It also returns names for the properties used internally by libdvbv5.
*/
const char *dvb_cmd_name(int cmd);
/**
* @brief Returns an string array with the valid string values associated with a DVBv5 command
* @ingroup frontend
*
* @param cmd DVBv5 or libdvbv5 property
*
* @return it returns a string array that corresponds to the names associated
* with the possible values for that property, when available.
* For example:
* dvb_cmd_name(DTV_CODE_RATE_HP) would return an array with the
* possible values for the code rates:
* { "1/2", "2/3", ... NULL }
* @note The array always ends with NULL.
*/
const char *const *dvb_attr_names(int cmd);
/* Get/set delivery system parameters */
/**
* @brief Retrieves the value of a DVBv5/libdvbv5 property
* @ingroup frontend
*
* @param parms struct dvb_v5_fe_parms pointer to the opened device
* @param cmd DVBv5 or libdvbv5 property
* @param value Pointer to an uint32_t where the value will be stored.
*
* This reads the value of a property stored at the cache. Before using it,
* a dvb_fe_get_parms() is likely required.
*
* @return Return 0 if success, EINVAL otherwise.
*/
int dvb_fe_retrieve_parm(const struct dvb_v5_fe_parms *parms,
unsigned cmd, uint32_t *value);
/**
* @brief Stores the value of a DVBv5/libdvbv5 property
* @ingroup frontend
*
* @param parms struct dvb_v5_fe_parms pointer to the opened device
* @param cmd DVBv5 or libdvbv5 property
* @param value Pointer to an uint32_t where the value will be stored.
*
* This stores the value of a property at the cache. The value will only
* be send to the hardware after calling dvb_fe_set_parms().
*
* @return Return 0 if success, EINVAL otherwise.
*/
int dvb_fe_store_parm(struct dvb_v5_fe_parms *parms,
unsigned cmd, uint32_t value);
/**
* @brief Sets the delivery system
* @ingroup frontend
*
* @param parms struct dvb_v5_fe_parms pointer to the opened device
* @param sys delivery system to be selected
*
* This function changes the delivery system of the frontend. By default,
* the libdvbv5 will use the first available delivery system. If another
* delivery system is desirable, this function should be called before being
* able to store the properties for the new delivery system via
* dvb_fe_store_parm().
*
* @return Return 0 if success, EINVAL otherwise.
*/
int dvb_set_sys(struct dvb_v5_fe_parms *parms,
fe_delivery_system_t sys);
/**
* @brief Make dvb properties reflect the current standard
* @ingroup frontend
*
* @param parms struct dvb_v5_fe_parms pointer to the opened device
* @param sys delivery system to be selected
*
* This function prepares the properties cache for a given delivery system.
*
* It is automatically called by dvb_set_sys(), and should not be normally
* called, except when dvb_fe_dummy() is used.
*
* @return Return 0 if success, EINVAL otherwise.
*/
int dvb_add_parms_for_sys(struct dvb_v5_fe_parms *parms,
fe_delivery_system_t sys);
/**
* @brief Sets the delivery system
* @ingroup frontend
*
* @param parms struct dvb_v5_fe_parms pointer to the opened
* device
* @param desired_system delivery system to be selected
*
* This function changes the delivery system of the frontend. By default,
* the libdvbv5 will use the first available delivery system. If another
* delivery system is desirable, this function should be called before being
* able to store the properties for the new delivery system via
* dvb_fe_store_parm().
*
* This function is an enhanced version of dvb_set_sys(). It has an special
* logic inside to work with Kernels that supports only DVBv3.
*
* @return Return 0 if success, EINVAL otherwise.
*/
int dvb_set_compat_delivery_system(struct dvb_v5_fe_parms *parms,
uint32_t desired_system);
/**
* @brief Prints all the properties at the cache
* @ingroup frontend
*
* @param parms struct dvb_v5_fe_parms pointer to the opened device
*
* Used mostly for debugging issues.
*/
void dvb_fe_prt_parms(const struct dvb_v5_fe_parms *parms);
/**
* @brief Prints all the properties at the cache
* @ingroup frontend
*
* @param parms struct dvb_v5_fe_parms pointer to the opened device
*
* Writes the properties stored at the DVB cache at the DVB hardware. At
* return, some properties could have a different value, as the frontend
* may not support the values set.
*
* @return Return 0 if success, EINVAL otherwise.
*/
int dvb_fe_set_parms(struct dvb_v5_fe_parms *parms);
/**
* @brief Prints all the properties at the cache
* @ingroup frontend
*
* @param parms struct dvb_v5_fe_parms pointer to the opened device
*
* Gets the properties from the DVB hardware. The values will only reflect
* what's set at the hardware if the frontend is locked.
*
* @return Return 0 if success, EINVAL otherwise.
*/
int dvb_fe_get_parms(struct dvb_v5_fe_parms *parms);
/*
* statistics functions
*/
/**
* @brief Retrieve the stats for a DTV layer from cache
* @ingroup frontend
*
* @param parms struct dvb_v5_fe_parms pointer to the opened device
* @param cmd DVBv5 or libdvbv5 property
* @param layer DTV layer
*
* Gets the value for one stats cache, on a given layer. Layer 0 is
* always present. On DTV standards that doesn't have layers, it returns
* the same value as dvb_fe_retrieve_stats() for layer = 0.
*
* For DTV standards with multiple layers, like ISDB, layer=1 is layer 'A',
* layer=2 is layer 'B' and layer=3 is layer 'C'. Please notice that not all
* frontends support per-layer stats. Also, the layer value is only valid if
* the layer exists at the original stream.
* Also, on such standards, layer 0 is typically a mean value of the layers,
* or a sum of events (if FE_SCALE_COUNTER).
*
* For it to be valid, dvb_fe_get_stats() should be called first.
*
* @return It returns a struct dtv_stats if succeed or NULL otherwise.
*/
struct dtv_stats *dvb_fe_retrieve_stats_layer(struct dvb_v5_fe_parms *parms,
unsigned cmd, unsigned layer);
/**
* @brief Retrieve the stats for a DTV layer from cache
* @ingroup frontend
*
* @param parms struct dvb_v5_fe_parms pointer to the opened device
* @param cmd DVBv5 or libdvbv5 property
* @param value DTV value pointer
*
* Gets the value for one stats property for layer = 0.
*
* For it to be valid, dvb_fe_get_stats() should be called first.
*
* @return The returned value is 0 if success, EINVAL otherwise.
*/
int dvb_fe_retrieve_stats(struct dvb_v5_fe_parms *parms,
unsigned cmd, uint32_t *value);
/**
* @brief Retrieve the stats from the Kernel
* @ingroup frontend
*
* @param parms struct dvb_v5_fe_parms pointer to the opened device
*
* Updates the stats cache from the available stats at the Kernel.
*
* @return The returned value is 0 if success, EINVAL otherwise.
*/
int dvb_fe_get_stats(struct dvb_v5_fe_parms *parms);
/**
* @brief Retrieve the BER stats from cache
* @ingroup frontend
*
* @param parms struct dvb_v5_fe_parms pointer to the opened device
* @param layer DTV layer
* @param scale retrieves the scale
*
* Gets the value for BER stats from stats cache, on a given layer. Layer 0 is
* always present. On DTV standards that doesn't have layers, it returns
* the same value as dvb_fe_retrieve_stats() for layer = 0.
*
* For DTV standards with multiple layers, like ISDB, layer=1 is layer 'A',
* layer=2 is layer 'B' and layer=3 is layer 'C'. Please notice that not all
* frontends support per-layer stats. Also, the layer value is only valid if
* the layer exists at the original stream.
* Also, on such standards, layer 0 is typically a mean value of the layers,
* or a sum of events (if FE_SCALE_COUNTER).
*
* For it to be valid, dvb_fe_get_stats() should be called first.
*
* @return It returns a float number for the BER value.
* If the statistics is not available for any reason, scale will be equal to
* FE_SCALE_NOT_AVAILABLE.
*/
float dvb_fe_retrieve_ber(struct dvb_v5_fe_parms *parms, unsigned layer,
enum fecap_scale_params *scale);
/**
* @brief Retrieve the PER stats from cache
* @ingroup frontend
*
* @param parms struct dvb_v5_fe_parms pointer to the opened device
* @param layer DTV layer
*
* Gets the value for BER stats from stats cache, on a given layer. Layer 0 is
* always present. On DTV standards that doesn't have layers, it returns
* the same value as dvb_fe_retrieve_stats() for layer = 0.
*
* For DTV standards with multiple layers, like ISDB, layer=1 is layer 'A',
* layer=2 is layer 'B' and layer=3 is layer 'C'. Please notice that not all
* frontends support per-layer stats. Also, the layer value is only valid if
* the layer exists at the original stream.
* Also, on such standards, layer 0 is typically a mean value of the layers,
* or a sum of events (if FE_SCALE_COUNTER).
*
* For it to be valid, dvb_fe_get_stats() should be called first.
*
* @return A negative value indicates error.
*/
float dvb_fe_retrieve_per(struct dvb_v5_fe_parms *parms, unsigned layer);
/**
* @brief Retrieve the quality stats from cache
* @ingroup frontend
*
* @param parms struct dvb_v5_fe_parms pointer to the opened device
* @param layer DTV layer
*
* Gets a quality measure for a given layer. Layer 0 is
* always present. On DTV standards that doesn't have layers, it returns
* the same value as dvb_fe_retrieve_stats() for layer = 0.
*
* For DTV standards with multiple layers, like ISDB, layer=1 is layer 'A',
* layer=2 is layer 'B' and layer=3 is layer 'C'. Please notice that not all
* frontends support per-layer stats. Also, the layer value is only valid if
* the layer exists at the original stream.
* Also, on such standards, layer 0 is typically a mean value of the layers,
* or a sum of events (if FE_SCALE_COUNTER).
*
* For it to be valid, dvb_fe_get_stats() should be called first.
*
* @return returns an enum dvb_quantity, where DVB_QUAL_UNKNOWN means that
* the stat isnot available.
*/
enum dvb_quality dvb_fe_retrieve_quality(struct dvb_v5_fe_parms *parms,
unsigned layer);
/**
* @brief Ancillary function to sprintf on ENG format
* @ingroup frontend
*
* @param buf buffer to store the value
* @param len buffer length
* @param val value to be printed
*
* On ENG notation, the exponential value should be multiple of 3. This is
* good to display some values, like BER.
*
* @return At return, it shows the actual size of the print. A negative value
* indicates an error.
*/
int dvb_fe_snprintf_eng(char *buf, int len, float val);
/**
* @brief Ancillary function to sprintf on ENG format
* @ingroup frontend
*
* @param parms struct dvb_v5_fe_parms pointer to the opened device
* @param cmd DVBv5 or libdvbv5 property
* @param display_name String with the name of the property to be shown
* @param layer DTV Layer
* @param buf buffer to store the value
* @param len buffer length
* @param show_layer_name a value different than zero shows the layer name, if
* the layer is bigger than zero.
*
* This function calls internally dvb_fe_retrieve_stats_layer(). It allows to
* print a DVBv5 statistics value into a string. An extra property is available
* (DTV_QUALITY) with prints either one of the values: Poor, Ok or Good,
* depending on the overall measures.
*
* @return: It returns the length of the printed data. A negative value
* indicates an error.
*/
int dvb_fe_snprintf_stat(struct dvb_v5_fe_parms *parms, uint32_t cmd,
char *display_name, int layer,
char **buf, int *len, int *show_layer_name);
/**
* @brief Get both status statistics and dvb parameters
* @ingroup frontend
*
* @param parms struct dvb_v5_fe_parms pointer to the opened device
*
* That's similar of calling both dvb_fe_get_parms() and dvb_fe_get_stats().
*
* @return It returns 0 if success or an errorno otherwise.
*/
int dvb_fe_get_event(struct dvb_v5_fe_parms *parms);
/*
* Other functions, associated to SEC/LNB/DISEqC
*
* The functions below are just wrappers for the Kernel calls, in order to
* manually control satellite systems.
*
* Instead of using most them, the best is to set the LNBf parameters, and let
* the libdvbv5 to automatically handle the calls.
*
* NOTE: It currently lacks support for two ioctl's:
* FE_DISEQC_RESET_OVERLOAD used only on av7110.
* Spec says:
* If the bus has been automatically powered off due to power overload,
* this ioctl call restores the power to the bus. The call requires read/write
* access to the device. This call has no effect if the device is manually
* powered off. Not all DVB adapters support this ioctl.
*
* FE_DISHNETWORK_SEND_LEGACY_CMD is used on av7110, budget, gp8psk and stv0299
* Spec says:
* WARNING: This is a very obscure legacy command, used only at stv0299
* driver. Should not be used on newer drivers.
* It provides a non-standard method for selecting Diseqc voltage on the
* frontend, for Dish Network legacy switches.
* As support for this ioctl were added in 2004, this means that such dishes
* were already legacy in 2004.
*
* So, it doesn't make much sense on implementing support for them.
*/
/**
* @brief DVB ioctl wrapper for setting SEC voltage
* @ingroup frontend
*
* @param parms struct dvb_v5_fe_parms pointer to the opened device
* @param on a value different than zero indicates to enable
* voltage on a Satellite Equipment Control (SEC)
* @param v18 if on != 0, a value different than zero means 18 Volts;
* zero means 13 Volts.
*
* If dvb_v5_fe_parms::lnb is set, this is controlled automatically.
*/
int dvb_fe_sec_voltage(struct dvb_v5_fe_parms *parms, int on, int v18);
/**
* @brief DVB ioctl wrapper for setting SEC tone
* @ingroup frontend
*
* @param parms struct dvb_v5_fe_parms pointer to the opened device
* @param tone tone setting, as defined by DVB fe_sec_tone_mode_t type
*
* If dvb_v5_fe_parms::lnb is set, this is controlled automatically.
*/
int dvb_fe_sec_tone(struct dvb_v5_fe_parms *parms, fe_sec_tone_mode_t tone);
/**
* @brief DVB ioctl wrapper for setting LNBf high voltage
* @ingroup frontend
*
* @param parms struct dvb_v5_fe_parms pointer to the opened device
* @param on a value different than zero indicates to produce
* lightly higher voltages instead of 13/18V, in order
* to compensate for long cables.
*/
int dvb_fe_lnb_high_voltage(struct dvb_v5_fe_parms *parms, int on);
/**
* @brief DVB ioctl wrapper for setting SEC DiSeqC tone burst to select between
* satellite A or B
* @ingroup frontend
*
* @param parms struct dvb_v5_fe_parms pointer to the opened device
* @param mini_b if different than zero, sends a 22 KHz tone burst to
* select satellite B. Otherwise, sends tone to select
* satellite A.
*
* Valid only on certain DISEqC arrangements.
*
* If dvb_v5_fe_parms::lnb is set, this is controlled automatically.
*/
int dvb_fe_diseqc_burst(struct dvb_v5_fe_parms *parms, int mini_b);
/**
* @brief DVB ioctl wrapper for setting SEC DiSeqC command
* @ingroup frontend
*
* @param parms struct dvb_v5_fe_parms pointer to the opened device
* @param len size of the DiSEqC command
* @param buf DiSEqC command to be sent
*
* If dvb_v5_fe_parms::lnb is set, this is controlled automatically.
*/
int dvb_fe_diseqc_cmd(struct dvb_v5_fe_parms *parms, const unsigned len,
const unsigned char *buf);
/**
* @brief DVB ioctl wrapper for getting SEC DiSEqC reply
* @ingroup frontend
*
* @param parms struct dvb_v5_fe_parms pointer to the opened device
* @param len size of the DiSEqC command
* @param buf DiSEqC command to be sent
* @param timeout maximum time to receive the command, in ms.
*
* If dvb_v5_fe_parms::lnb is set, this is controlled automatically.
*/
int dvb_fe_diseqc_reply(struct dvb_v5_fe_parms *parms, unsigned *len, char *buf,
int timeout);
/**
* @brief DVB Ancillary routine to check if a given Delivery system is satellite
* @ingroup frontend
*
* @param delivery_system delivery system to be selected
*/
int dvb_fe_is_satellite(uint32_t delivery_system);
/**
* @brief Set default country variant of delivery systems like ISDB-T
* @ingroup frontend
*
* @param parms struct dvb_v5_fe_parms pointer to the opened device
* @param country default country, in ISO 3166-1 two letter code. If
* NULL, default charset is guessed from locale environment
* variables.
*
* @return 0 if success or an errorno otherwise.
*
* "COUNTRY" property in dvb_fe_set_parm() overrides the setting.
*/
int dvb_fe_set_default_country(struct dvb_v5_fe_parms *parms,
const char *country);
#ifdef __cplusplus
}
#endif
/*
* Arrays from dvb-v5.h
*
* Those arrays can be used to translate from a DVB property into a name.
*
* No need to directly access them from userspace, as dvb_attr_names()
* already handles them into a more standard way.
*/
#ifndef _DOXYGEN
extern const unsigned fe_bandwidth_name[8];
extern const char *dvb_v5_name[72];
extern const void *dvb_v5_attr_names[];
extern const char *delivery_system_name[20];
extern const char *fe_code_rate_name[14];
extern const char *fe_modulation_name[15];
extern const char *fe_transmission_mode_name[10];
extern const unsigned fe_bandwidth_name[8];
extern const char *fe_guard_interval_name[12];
extern const char *fe_hierarchy_name[6];
extern const char *fe_voltage_name[4];
extern const char *fe_tone_name[3];
extern const char *fe_inversion_name[4];
extern const char *fe_pilot_name[4];
extern const char *fe_rolloff_name[5];
#endif
#endif

520
include/libdvbv5/dvb-file.h Normal file
View File

@@ -0,0 +1,520 @@
/*
* Copyright (c) 2011-2014 - Mauro Carvalho Chehab
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation version 2.1 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
*/
#ifndef _DVB_FILE_H
#define _DVB_FILE_H
#include "dvb-fe.h"
/**
* @file dvb-file.h
* @ingroup file
* @brief Provides interfaces to deal with DVB channel and program files.
* @copyright GNU Lesser General Public License version 2.1 (LGPLv2.1)
* @author Mauro Carvalho Chehab
*
* There are basically two types of files used for DVB:
* - files that describe the physical channels (also called as transponders);
* - files that describe the several programs found on a MPEG-TS (also called
* as zap files).
*
* The libdvbv5 library defines an unified type for both types. Other
* applications generally use different formats.
*
* The purpose of the functions and structures defined herein is to provide
* support to read and write to those different formats.
*
* @par Bug Report
* Please submit bug reports and patches to linux-media@vger.kernel.org
*/
/*
* DVB structures used to represent all files opened by the libdvbv5 library.
*
* Those structs represents each individual entry on a file, and the file
* as a whole.
*/
/**
* @struct dvb_elementary_pid
* @brief associates an elementary stream type with its PID
* @ingroup file
*
* @param type Elementary stream type
* @param pid Elementary stream Program ID
*/
struct dvb_elementary_pid {
uint8_t type;
uint16_t pid;
};
/**
* @struct dvb_entry
* @brief Represents one entry on a DTV file
* @ingroup file
*
* @param props A property key/value pair. The keys are the ones
* specified at the DVB API, plus the ones defined
* internally by libdvbv5, at the dvb-v5-std.h
* header file.
* @param next a pointer to the next entry. NULL if this is
* the last one.
* @param service_id Service ID associated with a program inside a
* transponder. Please note that pure "channel"
* files will have this field filled with 0.
* @param video_pid Array with the video program IDs inside a service
* @param audio_pid Array with the audio program IDs inside a service
* @param other_el_pid Array with all non-audio/video program IDs
* inside a service
* @param video_pid_len Size of the video_pid array
* @param audio_pid_len Size of the audio_pid array
* @param other_el_pid_len Size of the other_el_pid array
* @param channel String containing the name of the channel
* @param vchannel String representing the Number of the channel
* @param location String representing the location of the channel
* @param sat_number For satellite streams, this represents the
* number of the satellite dish on a DiSeqC
* arrangement. Should be zero on arrangements
* without DiSeqC.
* @param freq_bpf SCR/Unicable band-pass filter frequency to
* use, in kHz.
* For non SRC/Unicable arrangements, it should
* be zero.
* @param diseqc_wait Extra time to wait for DiSeqC commands to
* complete, in ms. The library will use 15 ms
* as the minimal time,
* plus the time specified on this field.
* @param lnb String with the name of the LNBf to be used for
* satellite tuning. The names should match the
* names provided by dvb_sat_get_lnb() call
* (see dvb-sat.h).
*/
struct dvb_entry {
struct dtv_property props[DTV_MAX_COMMAND];
unsigned int n_props;
struct dvb_entry *next;
uint16_t service_id;
uint16_t *video_pid, *audio_pid;
struct dvb_elementary_pid *other_el_pid;
unsigned video_pid_len, audio_pid_len, other_el_pid_len;
char *channel;
char *vchannel;
char *location;
int sat_number;
unsigned freq_bpf;
unsigned diseqc_wait;
char *lnb;
uint16_t network_id;
uint16_t transport_id;
};
/**
* @struct dvb_file
* @brief Describes an entire DVB file opened
*
* @param fname name of the file
* @param n_entries number of the entries read
* @param first_entry entry for the first entry. NULL if the file is empty.
*/
struct dvb_file {
char *fname;
int n_entries;
struct dvb_entry *first_entry;
};
/*
* DVB file format tables
*
* The structs below are used to represent oneline formats like the ones
* commonly found on DVB legacy applications.
*/
/**
* @struct dvb_parse_table
* @brief Describes the fields to parse on a file
* @ingroup file
*
* @param prop Name of the DVBv5 or libdvbv5 property field
* @param table Name of a translation table for string to
* int conversion
* @param size Size of the translation table
* @param mult_factor Multiply factor - Used, for example, to
* multiply the symbol rate read from a DVB-S
* table by 1000.
* @param has_default_value It is different than zero when the property
* can be optional. In this case, the next field
* should be present
* @param default_value Default value for the optional field
*/
struct dvb_parse_table {
unsigned int prop;
const char **table;
unsigned int size;
int mult_factor;
int has_default_value;
int default_value;
};
/**
* @struct dvb_parse_struct
* @brief Describes the format to parse an specific delivery system
* @ingroup file
*
* @param id String that identifies the delivery system on the
* file to be parsed
* @param delsys Delivery system
* @param table the struct dvb_parse_table used to parse for this
* specific delivery system
* @param size Size of the table
*/
struct dvb_parse_struct {
char *id;
uint32_t delsys;
const struct dvb_parse_table *table;
unsigned int size;
};
/**
* @struct dvb_parse_file
* @brief Describes an entire file format
*
* @param has_delsys_id A non-zero value indicates that the id field
* at the formats vector should be used
* @param delimiter Delimiters to split entries on the format
* @param formats A struct dvb_parse_struct vector with the
* per delivery system parsers. This table should
* terminate with an empty entry.
*/
struct dvb_parse_file {
int has_delsys_id;
char *delimiter;
struct dvb_parse_struct formats[];
};
/**
* @enum dvb_file_formats
* @brief Known file formats
* @ingroup file
*
* @details
* Please notice that the channel format defined here has a few optional
* fields that aren't part of the dvb-apps format, for DVB-S2 and for DVB-T2.
* They're there to match the formats found at dtv-scan-tables package up to
* September, 5 2014.
*
* @var FILE_UNKNOWN
* @brief File format is unknown
* @var FILE_ZAP
* @brief File is at the dvb-apps "dvbzap" format
* @var FILE_CHANNEL
* @brief File is at the dvb-apps output format for dvb-zap
* @var FILE_DVBV5
* @brief File is at libdvbv5 format
* @var FILE_VDR
* @brief File is at DVR format (as supported on version 2.1.6).
* Note: this is only supported as an output format.
*/
enum dvb_file_formats {
FILE_UNKNOWN,
FILE_ZAP,
FILE_CHANNEL,
FILE_DVBV5,
FILE_VDR,
};
struct dvb_v5_descriptors;
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Deallocates memory associated with a struct dvb_file
* @ingroup file
*
* @param dvb_file dvb_file struct to be deallocated
*
* This function assumes that several functions were dynamically allocated
* by the library file functions.
*/
static inline void dvb_file_free(struct dvb_file *dvb_file)
{
struct dvb_entry *entry = dvb_file->first_entry, *next;
while (entry) {
next = entry->next;
if (entry->channel)
free(entry->channel);
if (entry->vchannel)
free(entry->vchannel);
if (entry->location)
free(entry->location);
if (entry->video_pid)
free(entry->video_pid);
if (entry->audio_pid)
free(entry->audio_pid);
if (entry->other_el_pid)
free(entry->other_el_pid);
if (entry->lnb)
free(entry->lnb);
free(entry);
entry = next;
}
free(dvb_file);
}
/*
* File format description structures defined for the several formats that
* the library can read natively.
*/
/**
* @brief File format definitions for dvb-apps channel format
* @ingroup file
*/
extern const struct dvb_parse_file channel_file_format;
/**
* @brief File format definitions for dvb-apps zap format
* @ingroup file
*/
extern const struct dvb_parse_file channel_file_zap_format;
/*
* Prototypes for the several functions defined at dvb-file.c
*/
/**
* @brief Read a file at libdvbv5 format
* @ingroup file
*
* @param fname file name
*
* @return It returns a pointer to struct dvb_file describing the entries that
* were read from the file. If it fails, NULL is returned.
*/
struct dvb_file *dvb_read_file(const char *fname);
/**
* @brief Write a file at libdvbv5 format
* @ingroup file
*
* @param fname file name
* @param dvb_file contents of the file to be written
*
* @return It returns zero if success, or a positive error number if it fails.
*/
int dvb_write_file(const char *fname, struct dvb_file *dvb_file);
/**
* @brief Read a file on any format natively supported by
* the library
* @ingroup file
*
* @param fname file name
* @param delsys Delivery system, as specified by enum fe_delivery_system
* @param format Name of the format to be read
*
* @return It returns a pointer to struct dvb_file describing the entries that
* were read from the file. If it fails, NULL is returned.
*/
struct dvb_file *dvb_read_file_format(const char *fname,
uint32_t delsys,
enum dvb_file_formats format);
/**
* @brief Write a file on any format natively supported by
* the library
* @ingroup file
*
* @param fname file name
* @param dvb_file contents of the file to be written
* @param delsys Delivery system, as specified by enum fe_delivery_system
* @param format Name of the format to be read
*
* @return It a pointer to struct dvb_file on success, NULL otherwise.
*/
int dvb_write_file_format(const char *fname,
struct dvb_file *dvb_file,
uint32_t delsys,
enum dvb_file_formats format);
/**
* @brief Stores a key/value pair on a DVB file entry
* @ingroup file
*
* @param entry entry to be filled
* @param cmd key for the property to be used. It be one of the DVBv5
* properties, plus the libdvbv5 ones, as defined at dvb-v5-std.h
* @param value value for the property.
*
* This function seeks for a property with the name specified by cmd and
* fills it with value. If the entry doesn't exist, it creates a new key.
*
* @return Returns 0 if success, or, if the entry has already DTV_MAX_COMMAND
* properties, it returns -1.
*/
int dvb_store_entry_prop(struct dvb_entry *entry,
uint32_t cmd, uint32_t value);
/**
* @brief Retrieves the value associated witha key on a DVB file entry
* @ingroup file
*
* @param entry entry to be used
* @param cmd key for the property to be found. It be one of the DVBv5
* properties, plus the libdvbv5 ones, as defined at dvb-v5-std.h
* @param value pointer to store the value associated with the property.
*
* This function seeks for a property with the name specified by cmd and
* fills value with its contents.
*
* @return Returns 0 if success, or, -1 if the entry doesn't exist.
*/
int dvb_retrieve_entry_prop(struct dvb_entry *entry,
uint32_t cmd, uint32_t *value);
/**
* @brief stored a new scanned channel into a dvb_file struct
* @ingroup file
*
* @param dvb_file file struct to be filled
* @param parms struct dvb_v5_fe_parms used by libdvbv5 frontend
* @param dvb_desc struct dvb_desc as described at descriptors.h, filled
* with the descriptors associated with a DVB channel.
* those descriptors can be filled by calling one of the
* scan functions defined at dvb-sat.h.
* @param get_detected if different than zero, uses the frontend parameters
* obtained from the device driver (such as modulation,
* FEC, etc)
* @param get_nit if true, uses the parameters obtained from the MPEG-TS
* NIT table to add newly detected transponders.
*
* This function should be used to store the services found on a scanned
* transponder. Initially, it copies the same parameters used to set the
* frontend, that came from a file where the Service ID and Elementary Stream
* PIDs are unknown. At tuning time, it is common to set the device to tune
* on auto-detection mode (e. g. using QAM/AUTO, for example, to autodetect
* the QAM modulation). The libdvbv5's logic will be to check the detected
* values. So, the modulation might, for example, have changed to QAM/256.
* In such case, if get_detected is 0, it will store QAM/AUTO at the struct.
* If get_detected is different than zero, it will store QAM/256.
* If get_nit is different than zero, and if the MPEG-TS has info about other
* physical channels/transponders, this function will add newer entries to
* dvb_file, for it to seek for new transponders. This is very useful especially
* for DVB-C, where all transponders belong to the same operator. Knowing one
* frequency is generally enough to get all DVB-C transponders.
*
* @return Returns 0 if success, or, -1 if error.
*/
int dvb_store_channel(struct dvb_file **dvb_file,
struct dvb_v5_fe_parms *parms,
struct dvb_v5_descriptors *dvb_desc,
int get_detected, int get_nit);
/**
* @brief Ancillary function that seeks for a delivery system
* @ingroup file
*
* @param name string containing the name of the Delivery System to seek
*
* If the name is found, this function returns the DVBv5 property that
* corresponds to the string given. The function is case-insensitive, and
* it can check for alternate ways to write the name of a Delivery System.
* Currently, it supports: DVB-C, DVB-H, DVB-S, DVB-S2, DVB-T, DVB-T2,
* ISDB-C, ISDB-S, ISDB-T, ATSC-MH, DVBC/ANNEX_A, DVBC/ANNEX_B, DVBT, DSS,
* DVBS, DVBS2, DVBH, ISDBT, ISDBS, ISDBC, ATSC, ATSCMH, DTMB, CMMB, DAB,
* DVBT2, TURBO, DVBC/ANNEX_C.
* Please notice that this doesn't mean that all those standards are properly
* supported by the library.
*
* @return Returns the Delivery System property number if success, -1 if error.
*/
int dvb_parse_delsys(const char *name);
/**
* @brief Ancillary function that parses the name of a file format
* @ingroup file
*
* @param name string containing the name of the format
* Current valid names are: ZAP, CHANNEL, VDR and DVBV5.
* The name is case-insensitive.
*
* @return It returns FILE_ZAP, FILE_CHANNEL, FILE_VDR or FILE_DVBV5
* if the name was translated. FILE_UNKNOWN otherwise.
*/
enum dvb_file_formats dvb_parse_format(const char *name);
/*
* Routines to read a non-libdvbv5 format. They're called by
* dvb_read_file_format() or dvb_write_file_format()
*/
/**
* @brief Read and parses a one line file format
* @ingroup file
*
* @param fname file name
* @param delsys delivery system
* @param parse_file pointer struct dvb_parse_file
*
* @return It a pointer to struct dvb_file on success, NULL otherwise.
*
* This function is called internally by dvb_read_file_format.
*/
struct dvb_file *dvb_parse_format_oneline(const char *fname,
uint32_t delsys,
const struct dvb_parse_file *parse_file);
/**
* @brief Writes a file into an one line file format
* @ingroup file
*
* @param fname file name
* @param dvb_file contents of the file to be written
* @param delsys delivery system
* @param parse_file pointer struct dvb_parse_file
*
* @return It returns zero if success, or a positive error number if it fails.
*
* This function is called internally by dvb_write_file_format.
*/
int dvb_write_format_oneline(const char *fname,
struct dvb_file *dvb_file,
uint32_t delsys,
const struct dvb_parse_file *parse_file);
/**
* @brief Writes a file into vdr format (compatible up to version 2.1)
* @ingroup file
*
* @param fname file name
* @param dvb_file contents of the file to be written
*
* @return It returns zero if success, or a positive error number if it fails.
*
* This function is called internally by dvb_write_file_format.
*/
int dvb_write_format_vdr(const char *fname,
struct dvb_file *dvb_file);
#ifdef __cplusplus
}
#endif
#endif // _DVB_FILE_H

View File

File diff suppressed because it is too large Load Diff

110
include/libdvbv5/dvb-log.h Normal file
View File

@@ -0,0 +1,110 @@
/*
* Copyright (c) 2011-2014 - Mauro Carvalho Chehab
* Copyright (c) 2012 - Andre Roth <neolynx@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation version 2.1 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
* Or, point your browser to http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
*/
#ifndef _LOG_H
#define _LOG_H
#include <syslog.h>
/**
* @file dvb-log.h
* @ingroup ancillary
* @brief Provides interfaces to handle libdvbv5 log messages.
* @copyright GNU Lesser General Public License version 2.1 (LGPLv2.1)
* @author Mauro Carvalho Chehab
* @author Andre Roth
*
* @par Bug Report
* Please submit bug reports and patches to linux-media@vger.kernel.org
*/
/**
* @typedef void (*dvb_logfunc)(int level, const char *fmt, ...)
* @brief typedef used by dvb_fe_open2 for the log function
* @ingroup ancillary
*/
typedef void (*dvb_logfunc)(int level, const char *fmt, ...) __attribute__ (( format( printf, 2, 3 )));
/**
* @typedef void (*dvb_logfunc)(void *logpriv, int level, const char *fmt, ...)
* @brief typedef used by dvb_fe_open2 for the log function with private context
* @ingroup ancillary
*/
typedef void (*dvb_logfunc_priv)(void *logpriv, int level, const char *fmt, ...);
/*
* Macros used internally inside libdvbv5 frontend part, to output logs
*/
#ifndef _DOXYGEN
struct dvb_v5_fe_parms;
/**
* @brief retrieve the logging function with private data from the private fe params.
*/
dvb_logfunc_priv dvb_get_log_priv(struct dvb_v5_fe_parms *, void **);
#ifndef __DVB_FE_PRIV_H
#define dvb_loglevel(level, fmt, arg...) do {\
void *priv;\
dvb_logfunc_priv f = dvb_get_log_priv(parms, &priv);\
if (f) {\
f(priv, level, fmt, ##arg);\
} else {\
parms->logfunc(level, fmt, ##arg); \
}\
} while (0)
#else
#define dvb_loglevel(level, fmt, arg...) do {\
if (parms->logfunc_priv) {\
parms->logfunc_priv(parms->logpriv, level, fmt, ##arg);\
} else {\
parms->p.logfunc(level, fmt, ##arg); \
}\
} while (0)
#endif
#define dvb_log(fmt, arg...) dvb_loglevel(LOG_INFO, fmt, ##arg)
#define dvb_logerr(fmt, arg...) dvb_loglevel(LOG_ERR, fmt, ##arg)
#define dvb_logdbg(fmt, arg...) dvb_loglevel(LOG_DEBUG, fmt, ##arg)
#define dvb_logwarn(fmt, arg...) dvb_loglevel(LOG_WARNING, fmt, ##arg)
#define dvb_loginfo(fmt, arg...) dvb_loglevel(LOG_NOTICE, fmt, ##arg)
#define dvb_perror(msg) dvb_logerr("%s: %s", msg, strerror(errno))
#endif /* _DOXYGEN */
/**
* @brief This is the prototype of the internal log function that it is used,
* if the library client doesn't desire to override with something else.
* @ingroup ancillary
*
* @param level level of the message, as defined at syslog.h
* @param fmt format string (same as format string on sprintf)
*/
void dvb_default_log(int level, const char *fmt, ...) __attribute__ (( format( printf, 2, 3 )));
#endif

163
include/libdvbv5/dvb-sat.h Normal file
View File

@@ -0,0 +1,163 @@
/*
* Copyright (c) 2011-2014 - Mauro Carvalho Chehab
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation version 2.1 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
* Or, point your browser to http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*/
#ifndef _LIBSAT_H
#define _LIBSAT_H
#include "dvb-v5-std.h"
/**
* @file dvb-sat.h
* @ingroup satellite
* @brief Provides interfaces to deal with DVB Satellite systems.
* @copyright GNU Lesser General Public License version 2.1 (LGPLv2.1)
* @author Mauro Carvalho Chehab
*
* @par Bug Report
* Please submit bug reports and patches to linux-media@vger.kernel.org
*/
/*
* Satellite handling functions
*/
/**
* @struct dvb_sat_lnb
* @brief Stores the information of a LNBf
* @ingroup satellite
*
* @param name long name of the LNBf type
* @param alias short name for the LNBf type
*
* The LNBf (low-noise block downconverter) is a type of amplifier that is
* installed inside the parabolic dishes. It converts the antenna signal to
* an Intermediate Frequency. Several Ku-band LNBf have more than one IF.
* The lower IF is stored at lowfreq, the higher IF at highfreq.
* The exact setup for those structs actually depend on the model of the LNBf,
* and its usage.
*/
struct dvb_sat_lnb {
const char *name;
const char *alias;
/*
* Legacy fields, kept just to avoid ABI breakages
* Should not be used by new applications
*/
unsigned lowfreq, highfreq;
unsigned rangeswitch;
struct dvbsat_freqrange {
unsigned low, high;
} freqrange[2];
};
struct dvb_v5_fe_parms;
#ifdef __cplusplus
extern "C" {
#endif
/* From libsat.c */
/**
* @brief search for a LNBf entry
* @ingroup satellite
*
* @param name name of the LNBf entry to seek.
*
* On sucess, it returns a non-negative number with corresponds to the LNBf
* entry inside the LNBf structure at dvb-sat.c.
*
* @return A -1 return code indicates that the LNBf was not found.
*/
int dvb_sat_search_lnb(const char *name);
/**
* @brief prints the contents of a LNBf entry at STDOUT.
* @ingroup satellite
*
* @param index index for the entry
*
* @return returns -1 if the index is out of range, zero otherwise.
*/
int dvb_print_lnb(int index);
/**
* @brief Prints all LNBf entries at STDOUT.
* @ingroup satellite
*
* This function doesn't return anything. Internally, it calls dvb_print_lnb()
* for all entries inside its LNBf database.
*/
void dvb_print_all_lnb(void);
/**
* @brief gets a LNBf entry at its internal database
* @ingroup satellite
*
* @param index index for the entry.
*
* @return returns NULL if not found, of a struct dvb_sat_lnb pointer otherwise.
*
* NOTE: none of the strings are i18n translated. In order to get the
* translated name, you should use dvb_sat_get_lnb_name()
*/
const struct dvb_sat_lnb *dvb_sat_get_lnb(int index);
/**
* @brief gets a LNBf entry at its internal database
* @ingroup satellite
*
* @param index index for the entry.
*
* @return returns NULL if not found, of the name of a LNBf,
* translated to the user language, if translation is available.
*/
const char *dvb_sat_get_lnb_name(int index);
/**
* @brief sets the satellite parameters
* @ingroup satellite
*
* @param parms struct dvb_v5_fe_parms pointer.
*
* This function is called internally by the library to set the LNBf
* parameters, if the dvb_v5_fe_parms::lnb field is filled.
*
* @return 0 on success.
*/
int dvb_sat_set_parms(struct dvb_v5_fe_parms *parms);
/**
* @brief return the real satellite frequency
* @ingroup satellite
*
* @param parms struct dvb_v5_fe_parms pointer.
*
* This function is called internally by the library to get the satellite
* frequency, considering the LO frequency.
*
* @return frequency.
*/
int dvb_sat_real_freq(struct dvb_v5_fe_parms *p, int freq);
#ifdef __cplusplus
}
#endif
#endif // _LIBSAT_H

434
include/libdvbv5/dvb-scan.h Normal file
View File

@@ -0,0 +1,434 @@
/*
* Copyright (c) 2011-2014 - Mauro Carvalho Chehab
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation version 2.1 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
* Or, point your browser to http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*/
#ifndef _LIBSCAN_H
#define _LIBSCAN_H
#include <stdint.h>
#include <linux/dvb/dmx.h>
#include <libdvbv5/descriptors.h>
#include <libdvbv5/dvb-sat.h>
/**
* @file dvb-scan.h
* @ingroup frontend_scan
* @brief Provides interfaces to scan programs inside MPEG-TS digital TV streams.
* @copyright GNU Lesser General Public License version 2.1 (LGPLv2.1)
* @author Mauro Carvalho Chehab
*
* @par Bug Report
* Please submit bug reports and patches to linux-media@vger.kernel.org
*/
/* According with ISO/IEC 13818-1:2007 */
#define MAX_TABLE_SIZE 1024 * 1024
#ifdef __cplusplus
extern "C" {
#endif
struct dvb_entry;
/**
* @struct dvb_v5_descriptors_program
* @brief Associates PMT with PAT tables
* @ingroup frontend_scan
*
* @param pat_pgm pointer for PAT descriptor
* @param pmt pointer for PMT descriptor
*/
struct dvb_v5_descriptors_program {
struct dvb_table_pat_program *pat_pgm;
struct dvb_table_pmt *pmt;
};
/**
* @struct dvb_v5_descriptors
* @brief Contains the descriptors needed to scan the Service ID and other relevant info at a MPEG-TS Digital TV stream
* @ingroup frontend_scan
*
* @param delivery_system Delivery system of the parsed MPEG-TS
* @param entry struct dvb_entry pointer (see dvb-file.h)
* @param pat PAT table descriptor pointer (table ID 0x00).
* @param vct VCT table descriptor pointer (either table ID 0xc8,
* for TVCT or table ID 0xc9, for CVCT)
* @param program PAT/PMT array associated programs found at MPEG-TS
* @param num_program Number of program entries at @ref program array.
* @param nit NIT table descriptor pointer for table ID 0x40.
* @param sdt SDT table descriptor pointer for table ID 0x42.
* @param other_nits Contains an array of pointers to the other NIT
* extension tables identified by table ID 0x41.
* @param num_other_nits Number of NIT tables at @ref other_nits array.
* @param other_sdts Contains an array of pointers to the other NIT
* extension tables identified by table ID 0x46.
* @param num_other_sdts Number of NIT tables at @ref other_sdts array.
*
* Those descriptors are filled by the scan routines when the tables are
* found. Otherwise, they're NULL.
*
* @note: Never alloc this struct yourself. This is meant to always be
* allocated via dvb_scan_alloc_handler_table() or via dvb_get_ts_tables().
*/
struct dvb_v5_descriptors {
uint32_t delivery_system;
struct dvb_entry *entry;
unsigned num_entry;
struct dvb_table_pat *pat;
struct atsc_table_vct *vct;
struct dvb_v5_descriptors_program *program;
struct dvb_table_nit *nit;
struct dvb_table_sdt *sdt;
unsigned num_program;
struct dvb_table_nit **other_nits;
unsigned num_other_nits;
struct dvb_table_sdt **other_sdts;
unsigned num_other_sdts;
};
/**
* @struct dvb_table_filter
* @brief Describes the PES filters used by DVB scan
* @ingroup frontend_scan
*
* @param tid Table ID
* @param pid Program ID
* @param ts_id Table section ID (for multisession filtering). If no
* specific table section is needed, -1 should be used
* @param table pointer to a pointer for the table struct to be filled
* @param allow_section_gaps Allow non-continuous section numbering
* @param priv Internal structure used inside the DVB core. shouldn't
* be touched externally.
*/
struct dvb_table_filter {
/* Input data */
unsigned char tid;
uint16_t pid;
int ts_id;
void **table;
int allow_section_gaps;
/*
* Private temp data used by dvb_read_sections().
* Should not be filled outside dvb-scan.c, as they'll be
* overrided
*/
void *priv;
};
/**
* @brief deallocates all data associated with a table filter
* @ingroup frontend_scan
*
* @param sect table filter pointer
*/
void dvb_table_filter_free(struct dvb_table_filter *sect);
/**
* @brief read MPEG-TS tables that comes from a DTV card
* @ingroup frontend_scan
*
* @param parms pointer to struct dvb_v5_fe_parms created when the
* frontend is opened
* @param dmx_fd an opened demux file descriptor
* @param tid Table ID
* @param pid Program ID
* @param table pointer to a pointer for the table struct to be filled
* @param timeout Limit, in seconds, to read a MPEG-TS table
*
* This function is used to read the DVB tables by specifying a table ID and
* a program ID. The libdvbv5 should have a parser for the descriptors of the
* table type that should be parsed.
* The table will be automatically allocated on success.
* The function will read on the specified demux and return when reading is
* done or an error has occurred. If table is not NULL after the call, it has
* to be freed with the apropriate free table function (even if an error has
* occurred).
*
* If the application wants to abort the read operation, it can change the
* value of parms->p.abort to 1.
*
* Returns 0 on success or a negative error code.
*
* Example usage:
* @code
* struct dvb_table_pat *pat;
* int r = dvb_read_section( parms, dmx_fd, DVB_TABLE_PAT, DVB_TABLE_PAT_PID,
* (void **) &pat, 5 );
* if (r < 0)
* dvb_logerr("error reading PAT table");
* else {
* // do something with pat
* }
* if (pat)
* dvb_table_pat_free( pat );
* @endcode
*/
int dvb_read_section(struct dvb_v5_fe_parms *parms, int dmx_fd,
unsigned char tid, uint16_t pid, void **table,
unsigned timeout);
/**
* @brief read MPEG-TS tables that comes from a DTV card
* with an specific table section ID
* @ingroup frontend_scan
*
* @param parms pointer to struct dvb_v5_fe_parms created when the
* frontend is opened
* @param dmx_fd an opened demux file descriptor
* @param tid Table ID
* @param pid Program ID
* @param ts_id Table section ID (for multisession filtering). If no
* specific table section is needed, -1 should be used
* @param table pointer to a pointer for the table struct to be filled
* @param timeout limit, in seconds, to read a MPEG-TS table
*
* This is a variant of dvb_read_section() that also seeks for an specific
* table section ID given by ts_id.
*/
int dvb_read_section_with_id(struct dvb_v5_fe_parms *parms, int dmx_fd,
unsigned char tid, uint16_t pid, int ts_id,
void **table, unsigned timeout);
/**
* @brief read MPEG-TS tables that comes from a DTV card
* @ingroup frontend_scan
*
* @param parms pointer to struct dvb_v5_fe_parms created when the
* frontend is opened
* @param dmx_fd an opened demux file descriptor
* @param sect section filter pointer
* @param timeout limit, in seconds, to read a MPEG-TS table
*
* This is a variant of dvb_read_section() that uses a struct dvb_table_filter
* to specify the filter to use.
*/
int dvb_read_sections(struct dvb_v5_fe_parms *parms, int dmx_fd,
struct dvb_table_filter *sect,
unsigned timeout);
/**
* @brief allocates a struct dvb_v5_descriptors
* @ingroup frontend_scan
*
* @param delivery_system Delivery system to be used on the table
*
* At success, returns a pointer. NULL otherwise.
*/
struct dvb_v5_descriptors *dvb_scan_alloc_handler_table(uint32_t delivery_system);
/**
* @brief frees a struct dvb_v5_descriptors
* @ingroup frontend_scan
*
* @param dvb_scan_handler pointer to the struct to be freed.
*/
void dvb_scan_free_handler_table(struct dvb_v5_descriptors *dvb_scan_handler);
/**
* @brief Scans a DVB stream, looking for the tables needed to
* identify the programs inside a MPEG-TS
* @ingroup frontend_scan
*
* @param parms pointer to struct dvb_v5_fe_parms created when
* the frontend is opened
* @param dmx_fd an opened demux file descriptor
* @param delivery_system delivery system to be scanned
* @param other_nit use alternate table IDs for NIT and other tables
* @param timeout_multiply improves the timeout for each table reception
* by using a value that will multiply the wait
* time.
*
* Given an opened frontend and demux, this function seeks for all programs
* available at the transport stream, and parses the following tables:
* PAT, PMT, NIT, SDT (and VCT, if the delivery system is ATSC).
*
* On sucess, it returns a pointer to a struct dvb_v5_descriptors, that can
* either be used to tune into a service or to be stored inside a file.
*/
struct dvb_v5_descriptors *dvb_get_ts_tables(struct dvb_v5_fe_parms *parms, int dmx_fd,
uint32_t delivery_system,
unsigned other_nit,
unsigned timeout_multiply);
/**
* @brief frees a struct dvb_v5_descriptors
* @ingroup frontend_scan
*
* @param dvb_desc pointed to the structure to be freed.
*
* This function recursively frees everything that is allocated by
* dvb_get_ts_tables() and stored at dvb_desc, including dvb_desc itself.
*/
void dvb_free_ts_tables(struct dvb_v5_descriptors *dvb_desc);
/**
* @brief Callback for the application to show the frontend status
* @ingroup frontend_scan
*
* @param args a pointer, opaque to libdvbv5, to be used by the
* application if needed.
* @param parms pointer to struct dvb_v5_fe_parms created when the
* frontend is opened
*/
typedef int (check_frontend_t)(void *args, struct dvb_v5_fe_parms *parms);
/**
* @brief Scans a DVB dvb_add_scaned_transponder
* @ingroup frontend_scan
*
* @param parms pointer to struct dvb_v5_fe_parms created when the
* frontend is opened
* @param entry DVB file entry that corresponds to a transponder to be
* tuned
* @param dmx_fd an opened demux file descriptor
* @param check_frontend a pointer to a function that will show the frontend
* status while tuning into a transponder
* @param args a pointer, opaque to libdvbv5, that will be used when
* calling check_frontend. It should contain any parameters
* that could be needed by check_frontend.
* @param other_nit Use alternate table IDs for NIT and other tables
* @param timeout_multiply Improves the timeout for each table reception, by
*
* This is the function that applications should use when doing a transponders
* scan. It does everything needed to fill the entries with DVB programs
* (virtual channels) and detect the PIDs associated with them.
*
* A typical usage is to after open a channel file, open a dmx_fd and open
* a frontend. Then, seek for the MPEG tables on all the transponder
* frequencies with:
*
* @code
* for (entry = dvb_file->first_entry; entry != NULL; entry = entry->next) {
* struct dvb_v5_descriptors *dvb_scan_handler = NULL;
*
* dvb_scan_handler = dvb_scan_transponder(parms, entry, dmx_fd,
* &check_frontend, args,
* args->other_nit,
* args->timeout_multiply);
* if (parms->abort) {
* dvb_scan_free_handler_table(dvb_scan_handler);
* break;
* }
* if (dvb_scan_handler) {
* dvb_store_channel(&dvb_file_new, parms, dvb_scan_handler,
* args->get_detected, args->get_nit);
* dvb_scan_free_handler_table(dvb_scan_handler);
* }
* }
* @endcode
*/
struct dvb_v5_descriptors *dvb_scan_transponder(struct dvb_v5_fe_parms *parms,
struct dvb_entry *entry,
int dmx_fd,
check_frontend_t *check_frontend,
void *args,
unsigned other_nit,
unsigned timeout_multiply);
/**
* @brief Add new transponders to a dvb_file
* @ingroup frontend_scan
*
* @param parms pointer to struct dvb_v5_fe_parms created when the
* frontend is opened
* @param dvb_scan_handler pointer to a struct dvb_v5_descriptors containing
* scaned MPEG-TS
* @param first_entry first entry of a DVB file struct
* @param entry current entry on a DVB file struct
*
* When the NIT table is parsed, some new transponders could be described
* inside. This function adds new entries to a dvb_file struct, pointing
* to those new transponders. It is used inside the scan loop, as shown at
* the dvb_scan_transponder(), to add new channels.
*
* Example:
* @code
* for (entry = dvb_file->first_entry; entry != NULL; entry = entry->next) {
* struct dvb_v5_descriptors *dvb_scan_handler = NULL;
*
* dvb_scan_handler = dvb_scan_transponder(parms, entry, dmx_fd,
* &check_frontend, args,
* args->other_nit,
* args->timeout_multiply);
* if (parms->abort) {
* dvb_scan_free_handler_table(dvb_scan_handler);
* break;
* }
* if (dvb_scan_handler) {
* dvb_store_channel(&dvb_file_new, parms, dvb_scan_handler,
* args->get_detected, args->get_nit);
* dvb_scan_free_handler_table(dvb_scan_handler);
*
* dvb_add_scaned_transponders(parms, dvb_scan_handler,
* dvb_file->first_entry, entry);
*
* dvb_scan_free_handler_table(dvb_scan_handler);
* }
* }
* @endcode
*/
void dvb_add_scaned_transponders(struct dvb_v5_fe_parms *parms,
struct dvb_v5_descriptors *dvb_scan_handler,
struct dvb_entry *first_entry,
struct dvb_entry *entry);
#ifndef _DOXYGEN
/*
* Some ancillary functions used internally inside the library, used to
* identify duplicated transport streams and add new found transponder entries
*/
int dvb_estimate_freq_shift(struct dvb_v5_fe_parms *parms);
int dvb_new_freq_is_needed(struct dvb_entry *entry, struct dvb_entry *last_entry,
uint32_t freq, enum dvb_sat_polarization pol, int shift);
struct dvb_entry *dvb_scan_add_entry(struct dvb_v5_fe_parms *parms,
struct dvb_entry *first_entry,
struct dvb_entry *entry,
uint32_t freq, uint32_t shift,
enum dvb_sat_polarization pol);
int dvb_new_entry_is_needed(struct dvb_entry *entry,
struct dvb_entry *last_entry,
uint32_t freq, int shift,
enum dvb_sat_polarization pol, uint32_t stream_id);
struct dvb_entry *dvb_scan_add_entry_ex(struct dvb_v5_fe_parms *parms,
struct dvb_entry *first_entry,
struct dvb_entry *entry,
uint32_t freq, uint32_t shift,
enum dvb_sat_polarization pol,
uint32_t stream_id);
void dvb_update_transponders(struct dvb_v5_fe_parms *parms,
struct dvb_v5_descriptors *dvb_scan_handler,
struct dvb_entry *first_entry,
struct dvb_entry *entry);
#endif
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,267 @@
/*
* Copyright (c) 2011-2014 - Mauro Carvalho Chehab
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation version 2.1 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
* Or, point your browser to http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
* Per-delivery system properties defined at libdvbv5 scope, following
* the same model as defined at the Linux DVB media specs:
* http://linuxtv.org/downloads/v4l-dvb-apis/FE_GET_SET_PROPERTY.html
*/
#ifndef _DVB_V5_STD_H
#define _DVB_V5_STD_H
#include <stddef.h>
#include "dvb-frontend.h"
/**
* @file dvb-v5-std.h
* @ingroup frontend
* @brief Provides libdvbv5 defined properties for the frontend.
* @copyright GNU Lesser General Public License version 2.1 (LGPLv2.1)
* @author Mauro Carvalho Chehab
*
* @par Bug Report
* Please submit bug reports and patches to linux-media@vger.kernel.org
*/
/*
* User DTV codes, for internal usage. There are two sets of
* properties. One for DTV properties and another one for statistics
*/
/*
* First set: DTV properties that don't belong to Kernelspace
*
* Those properties contain data that comes from the MPEG-TS
* tables, like audio/video/other PIDs, and satellite config
*/
/**
* @def DTV_USER_COMMAND_START
* @brief Start number for libdvbv5 user commands
* @ingroup frontend
* @def DTV_POLARIZATION
* @brief Satellite polarization (for Satellite delivery systems)
* @ingroup frontend
* @def DTV_AUDIO_PID
* @brief Audio PID
* @ingroup frontend
* @def DTV_VIDEO_PID
* @brief Video PID
* @ingroup frontend
* @def DTV_SERVICE_ID
* @brief MPEG TS service ID
* @ingroup frontend
* @def DTV_CH_NAME
* @brief Digital TV service name
* @ingroup frontend
* @def DTV_VCHANNEL
* @brief Digital TV channel number. May contain symbols
* @ingroup frontend
* @def DTV_SAT_NUMBER
* @brief Number of the satellite (used on multi-dish Satellite systems)
* @ingroup frontend
* @def DTV_DISEQC_WAIT
* @brief Extra time needed to wait for DiSeqC to complete, in ms.
* The minimal wait time is 15 ms. The time here will be
* added to the minimal time.
* @ingroup frontend
* @def DTV_DISEQC_LNB
* @brief LNBf name
* @ingroup frontend
* @def DTV_FREQ_BPF
* @brief SCR/Unicable band-pass filter frequency in kHz
* @ingroup frontend
* @def DTV_PLS_CODE
* @brief DVB-T2 PLS code. Not used internally. It is needed
* only for file conversion.
* @ingroup frontend
* @def DTV_PLS_MODE
* @brief DVB-T2 PLS mode. Not used internally. It is needed
* only for file conversion.
* @ingroup frontend
* @def DTV_COUNTRY_CODE
* @brief Country variant of international delivery system standard.
in ISO 3166-1 two letter code.
* @ingroup frontend
* @def DTV_MAX_USER_COMMAND
* @brief Last user command
* @ingroup frontend
* @def DTV_USER_NAME_SIZE
* @brief Number of user commands
* @ingroup frontend
*/
#define DTV_USER_COMMAND_START 256
#define DTV_POLARIZATION (DTV_USER_COMMAND_START + 0)
#define DTV_VIDEO_PID (DTV_USER_COMMAND_START + 1)
#define DTV_AUDIO_PID (DTV_USER_COMMAND_START + 2)
#define DTV_SERVICE_ID (DTV_USER_COMMAND_START + 3)
#define DTV_CH_NAME (DTV_USER_COMMAND_START + 4)
#define DTV_VCHANNEL (DTV_USER_COMMAND_START + 5)
#define DTV_SAT_NUMBER (DTV_USER_COMMAND_START + 6)
#define DTV_DISEQC_WAIT (DTV_USER_COMMAND_START + 7)
#define DTV_DISEQC_LNB (DTV_USER_COMMAND_START + 8)
#define DTV_FREQ_BPF (DTV_USER_COMMAND_START + 9)
#define DTV_PLS_CODE (DTV_USER_COMMAND_START + 10)
#define DTV_PLS_MODE (DTV_USER_COMMAND_START + 11)
#define DTV_COUNTRY_CODE (DTV_USER_COMMAND_START + 12)
#define DTV_MAX_USER_COMMAND DTV_COUNTRY_CODE
#define DTV_USER_NAME_SIZE (1 + DTV_MAX_USER_COMMAND - DTV_USER_COMMAND_START)
/**
* @enum dvb_sat_polarization
* @brief Polarization types for Satellite systems
* @ingroup satellite
*
* @param POLARIZATION_OFF Polarization disabled/unused.
* @param POLARIZATION_H Horizontal polarization
* @param POLARIZATION_V Vertical polarization
* @param POLARIZATION_L Left circular polarization (C-band)
* @param POLARIZATION_R Right circular polarization (C-band)
*/
enum dvb_sat_polarization {
POLARIZATION_OFF = 0,
POLARIZATION_H = 1,
POLARIZATION_V = 2,
POLARIZATION_L = 3,
POLARIZATION_R = 4,
};
/*
* Second set: DTV statistics
*
* Those properties contain statistics measurements that aren't
* either provided by the Kernel via property cmd/value pair,
* like status (with has its own ioctl), or that are derivated
* measures from two or more Kernel reported stats.
*/
/**
* @def DTV_STAT_COMMAND_START
* @brief Start number for libdvbv5 statistics commands
* @ingroup frontend
* @def DTV_STATUS
* @brief Lock status of a DTV frontend. This actually comes from
* the Kernel, but it uses a separate ioctl.
* @ingroup frontend
* @def DTV_BER
* @brief Bit Error Rate. This is a parameter that it is
* derivated from two counters at the Kernel side
* @ingroup frontend
* @def DTV_PER
* @brief Packet Error Rate. This is a parameter that it is
* derivated from two counters at the Kernel side
* @ingroup frontend
* @def DTV_QUALITY
* @brief A quality indicator that represents if a locked
* channel provides a good, OK or poor signal. This is
* estimated considering the error rates, signal strengh
* and/or S/N ratio of the carrier.
* @ingroup frontend
* @def DTV_PRE_BER
* @brief Bit Error Rate before Viterbi. This is the error rate
* before applying the Forward Error Correction. This is
* a parameter that it is derivated from two counters
* at the Kernel side.
* @ingroup frontend
* @def DTV_MAX_STAT_COMMAND
* @brief Last statistics command
* @ingroup frontend
* @def DTV_STAT_NAME_SIZE
* @brief Number of statistics commands
* @ingroup frontend
* @def DTV_NUM_KERNEL_STATS
* @brief Number of statistics commands provided by the Kernel
* @ingroup frontend
* @def DTV_NUM_STATS_PROPS
* @brief Total number of statistics commands
* @ingroup frontend
*/
#define DTV_STAT_COMMAND_START 512
#define DTV_STATUS (DTV_STAT_COMMAND_START + 0)
#define DTV_BER (DTV_STAT_COMMAND_START + 1)
#define DTV_PER (DTV_STAT_COMMAND_START + 2)
#define DTV_QUALITY (DTV_STAT_COMMAND_START + 3)
#define DTV_PRE_BER (DTV_STAT_COMMAND_START + 4)
#define DTV_MAX_STAT_COMMAND DTV_PRE_BER
#define DTV_STAT_NAME_SIZE (1 + DTV_MAX_STAT_COMMAND - DTV_STAT_COMMAND_START)
/* There are currently 8 stats provided on Kernelspace */
#define DTV_NUM_KERNEL_STATS 8
#define DTV_NUM_STATS_PROPS (DTV_NUM_KERNEL_STATS + DTV_STAT_NAME_SIZE)
/**
* @enum dvb_quality
* @brief Provides an estimation about the user's experience
* while watching to a given MPEG stream
* @ingroup frontend
*
* @param DVB_QUAL_UNKNOWN Quality could not be estimated, as the Kernel driver
* doesn't provide enough statistics
*
* @param DVB_QUAL_POOR The signal reception is poor. Signal loss or packets
* can be lost too frequently.
* @param DVB_QUAL_OK The signal reception is ok. Eventual artifacts could
* be expected, but it should work.
* @param DVB_QUAL_GOOD The signal is good, and not many errors are happening.
* The user should have a good experience watching the
* stream.
*/
enum dvb_quality {
DVB_QUAL_UNKNOWN = 0,
DVB_QUAL_POOR,
DVB_QUAL_OK,
DVB_QUAL_GOOD,
};
#ifndef _DOXYGEN
/*
* Some tables to translate from value to string
*
* These tables are raw ways to translate from some DTV values into strings.
* Please use the API-provided function dvb_cmd_name() and dvb_dvb_attr_names(),
* instead of using the tables directly.
*/
extern const unsigned int sys_dvbt_props[];
extern const unsigned int sys_dvbt2_props[];
extern const unsigned int sys_isdbt_props[];
extern const unsigned int sys_atsc_props[];
extern const unsigned int sys_atscmh_props[];
extern const unsigned int sys_dvbc_annex_ac_props[];
extern const unsigned int sys_dvbc_annex_b_props[];
extern const unsigned int sys_dvbs_props[];
extern const unsigned int sys_dvbs2_props[];
extern const unsigned int sys_turbo_props[];
extern const unsigned int sys_isdbs_props[];
extern const unsigned int *dvb_v5_delivery_system[];
extern const char *dvb_sat_pol_name[6];
extern const char *dvb_user_name[DTV_USER_NAME_SIZE + 1];
extern const char *dvb_stat_name[DTV_STAT_NAME_SIZE + 1];
extern const void *dvb_user_attr_names[];
#endif /* DOXYGEN_SHOULD_SKIP_THIS */
#endif

226
include/libdvbv5/eit.h Normal file
View File

@@ -0,0 +1,226 @@
/*
* Copyright (c) 2011-2012 - Mauro Carvalho Chehab
* Copyright (c) 2012 - Andre Roth <neolynx@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation version 2.1 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
* Or, point your browser to http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
*/
/**
* @file eit.h
* @ingroup dvb_table
* @brief Provides the table parser for the DVB EIT (Event Information Table)
* @copyright GNU Lesser General Public License version 2.1 (LGPLv2.1)
* @author Mauro Carvalho Chehab
* @author Andre Roth
*
* @par Relevant specs
* The table described herein is defined at:
* - ETSI EN 300 468
*
* @see
* http://www.etherguidesystems.com/Help/SDOs/dvb/syntax/tablesections/EIT.aspx
*
* @par Bug Report
* Please submit bug reports and patches to linux-media@vger.kernel.org
*/
#ifndef _EIT_H
#define _EIT_H
#include <stdint.h>
#include <unistd.h> /* ssize_t */
#include <time.h>
#include <libdvbv5/header.h>
/**
* @def DVB_TABLE_EIT
* @brief DVB EIT table ID for the actual TS
* @ingroup dvb_table
* @def DVB_TABLE_EIT_OTHER
* @brief DVB EIT table ID for other TS
* @ingroup dvb_table
* @def DVB_TABLE_EIT_PID
* @brief DVB EIT Program ID
* @ingroup dvb_table
* @def DVB_TABLE_EIT_SCHEDULE
* @brief Start table ID for the DVB EIT schedule data on the actual TS
* The range has 0x0f elements (0x50 to 0x5F).
* @ingroup dvb_table
* @def DVB_TABLE_EIT_SCHEDULE_OTHER
* @brief Start table ID for the DVB EIT schedule data on other TS
* The range has 0x0f elements (0x60 to 0x6F).
* @ingroup dvb_table
*/
#define DVB_TABLE_EIT 0x4E
#define DVB_TABLE_EIT_OTHER 0x4F
#define DVB_TABLE_EIT_PID 0x12
#define DVB_TABLE_EIT_SCHEDULE 0x50
#define DVB_TABLE_EIT_SCHEDULE_OTHER 0x60
/**
* @struct dvb_table_eit_event
* @brief DVB EIT event table
* @ingroup dvb_table
*
* @param event_id an uniquelly (inside a service ID) event ID
* @param desc_length descriptor's length
* @param free_CA_mode free CA mode. 0 indicates that the event
* is not scrambled
* @param running_status running status of the event. The status can
* be translated to string via
* dvb_eit_running_status_name string table.
* @param descriptor pointer to struct dvb_desc
* @param next pointer to struct dvb_table_eit_event
* @param tm_start event start (in struct tm format)
* @param duration duration in seconds
* @param service_id service ID
*
* This structure is used to store the original EIT event table,
* converting the integer fields to the CPU endianness, and converting the
* timestamps to a way that it is better handled on Linux.
*
* The undocumented parameters are used only internally by the API and/or
* are fields that are reserved. They shouldn't be used, as they may change
* on future API releases.
*
* Everything after dvb_table_eit_event::descriptor (including it) won't
* be bit-mapped to the data parsed from the MPEG TS. So, metadata are added
* there.
*/
struct dvb_table_eit_event {
uint16_t event_id;
union {
uint16_t bitfield1; /* first 2 bytes are MJD, they need to be bswapped */
uint8_t dvbstart[5];
} __attribute__((packed));
uint8_t dvbduration[3];
union {
uint16_t bitfield2;
struct {
uint16_t desc_length:12;
uint16_t free_CA_mode:1;
uint16_t running_status:3;
} __attribute__((packed));
} __attribute__((packed));
struct dvb_desc *descriptor;
struct dvb_table_eit_event *next;
struct tm start;
uint32_t duration;
uint16_t service_id;
} __attribute__((packed));
/**
* @struct dvb_table_eit
* @brief DVB EIT table
* @ingroup dvb_table
*
* @param header struct dvb_table_header content
* @param transport_id transport id
* @param network_id network id
* @param last_segment last segment
* @param last_table_id last table id
* @param event pointer to struct dvb_table_eit_event
*
* This structure is used to store the original EIT table,
* converting the integer fields to the CPU endianness.
*
* Everything after dvb_table_eit::event (including it) won't
* be bit-mapped to the data parsed from the MPEG TS. So, metadata are added
* there.
*/
struct dvb_table_eit {
struct dvb_table_header header;
uint16_t transport_id;
uint16_t network_id;
uint8_t last_segment;
uint8_t last_table_id;
struct dvb_table_eit_event *event;
} __attribute__((packed));
/**
* @brief Macro used to find event on a DVB EIT table
* @ingroup dvb_table
*
* @param _event event to seek
* @param _eit pointer to struct dvb_table_eit_event
*/
#define dvb_eit_event_foreach(_event, _eit) \
if (_eit && _eit->event) \
for( struct dvb_table_eit_event *_event = _eit->event; _event; _event = _event->next ) \
struct dvb_v5_fe_parms;
/** @brief Converts a running_status field into string */
extern const char *dvb_eit_running_status_name[8];
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Initializes and parses EIT table
* @ingroup dvb_table
*
* @param parms struct dvb_v5_fe_parms pointer to the opened device
* @param buf buffer containing the EIT raw data
* @param buflen length of the buffer
* @param table pointer to struct dvb_table_eit to be allocated and filled
*
* This function allocates an EIT table and fills the fields inside
* the struct. It also makes sure that all fields will follow the CPU
* endianness. Due to that, the content of the buffer may change.
*
* @return On success, it returns the size of the allocated struct.
* A negative value indicates an error.
*/
ssize_t dvb_table_eit_init (struct dvb_v5_fe_parms *parms, const uint8_t *buf,
ssize_t buflen, struct dvb_table_eit **table);
/**
* @brief Frees all data allocated by the DVB EIT table parser
* @ingroup dvb_table
*
* @param table pointer to struct dvb_table_eit to be freed
*/
void dvb_table_eit_free(struct dvb_table_eit *table);
/**
* @brief Prints the content of the DVB EIT table
* @ingroup dvb_table
*
* @param parms struct dvb_v5_fe_parms pointer to the opened device
* @param table pointer to struct dvb_table_eit
*/
void dvb_table_eit_print(struct dvb_v5_fe_parms *parms,
struct dvb_table_eit *table);
/**
* @brief Converts a DVB EIT formatted timestamp into struct tm
* @ingroup dvb_table
*
* @param data event on DVB EIT time format
* @param tm pointer to struct tm where the converted timestamp will
* be stored.
*/
void dvb_time(const uint8_t data[5], struct tm *tm);
#ifdef __cplusplus
}
#endif
#endif

150
include/libdvbv5/header.h Normal file
View File

@@ -0,0 +1,150 @@
/*
* Copyright (c) 2011-2012 - Mauro Carvalho Chehab
* Copyright (c) 2012 - Andre Roth <neolynx@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation version 2.1 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
* Or, point your browser to http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
* Described at ISO/IEC 13818-1
*/
#ifndef _HEADER_H
#define _HEADER_H
#include <stdint.h>
#include <unistd.h> /* ssize_t */
/**
* @file header.h
* @ingroup dvb_table
* @brief Provides the MPEG TS table headers
* @copyright GNU Lesser General Public License version 2.1 (LGPLv2.1)
* @author Mauro Carvalho Chehab
* @author Andre Roth
*
* @par Bug Report
* Please submit bug reports and patches to linux-media@vger.kernel.org
*/
/**
* @struct dvb_ts_packet_header
* @brief Header of a MPEG-TS transport packet
* @ingroup dvb_table
*
* @param sync_byte sync byte
* @param pid Program ID
* @param transport_priority transport priority
* @param payload_unit_start_indicator payload unit start indicator
* @param transport_error_indicator transport error indicator
* @param continuity_counter continuity counter
* @param adaptation_field_control adaptation field control
* @param transport_scrambling_control transport scrambling control
* @param adaptation_field_length adaptation field length
*
* @see http://www.etherguidesystems.com/Help/SDOs/MPEG/Semantics/MPEG-2/transport_packet.aspx
*/
struct dvb_ts_packet_header {
uint8_t sync_byte;
union {
uint16_t bitfield;
struct {
uint16_t pid:13;
uint16_t transport_priority:1;
uint16_t payload_unit_start_indicator:1;
uint16_t transport_error_indicator:1;
} __attribute__((packed));
} __attribute__((packed));
uint8_t continuity_counter:4;
uint8_t adaptation_field_control:2;
uint8_t transport_scrambling_control:2;
/* Only if adaptation_field_control > 1 */
uint8_t adaptation_field_length;
/* Only if adaptation_field_length >= 1 */
struct {
uint8_t extension:1;
uint8_t private_data:1;
uint8_t splicing_point:1;
uint8_t OPCR:1;
uint8_t PCR:1;
uint8_t priority:1;
uint8_t random_access:1;
uint8_t discontinued:1;
} __attribute__((packed));
} __attribute__((packed));
/**
* @struct dvb_table_header
* @brief Header of a MPEG-TS table
* @ingroup dvb_table
*
* @param table_id table id
* @param section_length section length
* @param syntax syntax
* @param id Table ID extension
* @param current_next current next
* @param version version
* @param section_id section number
* @param last_section last section number
*
* All MPEG-TS tables start with this header.
*/
struct dvb_table_header {
uint8_t table_id;
union {
uint16_t bitfield;
struct {
uint16_t section_length:12;
uint8_t one:2;
uint8_t zero:1;
uint8_t syntax:1;
} __attribute__((packed));
} __attribute__((packed));
uint16_t id; /* TS ID */
uint8_t current_next:1;
uint8_t version:5;
uint8_t one2:2;
uint8_t section_id; /* section_number */
uint8_t last_section; /* last_section_number */
} __attribute__((packed));
struct dvb_v5_fe_parms;
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Initializes and parses MPEG-TS table header
* @ingroup dvb_table
*
* @param header pointer to struct dvb_table_header to be parsed
*/
void dvb_table_header_init (struct dvb_table_header *header);
/**
* @brief Prints the content of the MPEG-TS table header
* @ingroup dvb_table
*
* @param parms struct dvb_v5_fe_parms pointer to the opened device
* @param header pointer to struct dvb_table_header to be printed
*/
void dvb_table_header_print(struct dvb_v5_fe_parms *parms,
const struct dvb_table_header *header);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,4 @@
#define LIBDVBV5_VERSION_MAJOR 1
#define LIBDVBV5_VERSION_MINOR 22
#define LIBDVBV5_VERSION_PATCH 1
#define LIBDVBV5_VERSION "1.22.1"

View File

@@ -0,0 +1,4 @@
#define LIBDVBV5_VERSION_MAJOR @MAJOR@
#define LIBDVBV5_VERSION_MINOR @MINOR@
#define LIBDVBV5_VERSION_PATCH @PATCH@
#define LIBDVBV5_VERSION "@PACKAGE_VERSION@"

187
include/libdvbv5/mgt.h Normal file
View File

@@ -0,0 +1,187 @@
/*
* Copyright (c) 2013 - Andre Roth <neolynx@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation version 2.1 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
* Or, point your browser to http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
*/
/**
* @file mgt.h
* @ingroup dvb_table
* @brief Provides the table parser for the ATSC MGT (Master Guide Table)
* @copyright GNU Lesser General Public License version 2.1 (LGPLv2.1)
* @author Andre Roth
*
* @par Relevant specs
* The table described herein is defined at:
* - ATSC A/65:2009
*
* @see
* http://www.etherguidesystems.com/help/sdos/atsc/syntax/tablesections/MGT.aspx
*
* @par Bug Report
* Please submit bug reports and patches to linux-media@vger.kernel.org
*/
#ifndef _MGT_H
#define _MGT_H
#include <stdint.h>
#include <unistd.h> /* ssize_t */
#include <libdvbv5/atsc_header.h>
/**
* @def ATSC_TABLE_MGT
* @brief ATSC MGT table ID
* @ingroup dvb_table
*/
#define ATSC_TABLE_MGT 0xC7
/**
* @struct atsc_table_mgt_table
* @brief ATSC tables descrition at MGT table
* @ingroup dvb_table
*
* @param type table type
* @param pid table type pid
* @param type_version type type version number
* @param size number of bytes for the table entry
* @param desc_length table type descriptors length
* @param descriptor pointer to struct dvb_desc
* @param next pointer to struct atsc_table_mgt_table
*
* This structure is used to store the original VCT channel table,
* converting the integer fields to the CPU endianness.
*
* The undocumented parameters are used only internally by the API and/or
* are fields that are reserved. They shouldn't be used, as they may change
* on future API releases.
*
* Everything after atsc_table_mgt_table::descriptor (including it) won't
* be bit-mapped * to the data parsed from the MPEG TS. So, metadata are
* added there.
*/
struct atsc_table_mgt_table {
uint16_t type;
union {
uint16_t bitfield;
struct {
uint16_t pid:13;
uint16_t one:3;
} __attribute__((packed));
} __attribute__((packed));
uint8_t type_version:5;
uint8_t one2:3;
uint32_t size;
union {
uint16_t bitfield2;
struct {
uint16_t desc_length:12;
uint16_t one3:4;
} __attribute__((packed));
} __attribute__((packed));
struct dvb_desc *descriptor;
struct atsc_table_mgt_table *next;
} __attribute__((packed));
/**
* @struct atsc_table_mgt
* @brief ATSC MGT table
* @ingroup dvb_table
*
* @param header struct dvb_table_header content
* @param protocol_version protocol version
* @param tables tables_defined Number of tables defined
* @param table pointer to struct atsc_table_mgt_table
* @param descriptor pointer to struct dvb_desc
*
* This structure is used to store the original MGT channel table,
* converting the integer fields to the CPU endianness.
*
* The undocumented parameters are used only internally by the API and/or
* are fields that are reserved. They shouldn't be used, as they may change
* on future API releases.
*
* Everything after atsc_table_mgt::table (including it) won't
* be bit-mapped * to the data parsed from the MPEG TS. So, metadata are
* added there.
*/
struct atsc_table_mgt {
struct dvb_table_header header;
uint8_t protocol_version;
uint16_t tables;
struct atsc_table_mgt_table *table;
struct dvb_desc *descriptor;
} __attribute__((packed));
/**
* @brief Macro used to find a table inside a MGT table
*
* @param _table channel to seek
* @param _mgt pointer to struct atsc_table_mgt_table
*/
#define atsc_mgt_table_foreach( _table, _mgt ) \
if (_mgt && _mgt->_table) \
for( struct atsc_table_mgt_table *_table = _mgt->table; _table; _table = _table->next ) \
struct dvb_v5_fe_parms;
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Initializes and parses MGT table
* @ingroup dvb_table
*
* @param parms struct dvb_v5_fe_parms pointer to the opened device
* @param buf buffer containing the MGT raw data
* @param buflen length of the buffer
* @param table pointer to struct atsc_table_mgt to be allocated and filled
*
* This function allocates an ATSC MGT table and fills the fields inside
* the struct. It also makes sure that all fields will follow the CPU
* endianness. Due to that, the content of the buffer may change.
*
* @return On success, it returns the size of the allocated struct.
* A negative value indicates an error.
*/
ssize_t atsc_table_mgt_init(struct dvb_v5_fe_parms *parms, const uint8_t *buf,
ssize_t buflen, struct atsc_table_mgt **table);
/**
* @brief Frees all data allocated by the MGT table parser
* @ingroup dvb_table
*
* @param table pointer to struct atsc_table_mgt to be freed
*/
void atsc_table_mgt_free(struct atsc_table_mgt *table);
/**
* @brief Prints the content of the MGT table
* @ingroup dvb_table
*
* @param parms struct dvb_v5_fe_parms pointer to the opened device
* @param table pointer to struct atsc_table_mgt
*/
void atsc_table_mgt_print(struct dvb_v5_fe_parms *parms,
struct atsc_table_mgt *table);
#ifdef __cplusplus
}
#endif
#endif

248
include/libdvbv5/mpeg_es.h Normal file
View File

@@ -0,0 +1,248 @@
/*
* Copyright (c) 2013-2014 - Andre Roth <neolynx@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation version 2.1 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
* Or, point your browser to http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
*/
#ifndef _MPEG_ES_H
#define _MPEG_ES_H
/**
* @file mpeg_es.h
* @ingroup dvb_table
* @brief Provides the table parser for the MPEG-TS Elementary Stream
* @copyright GNU Lesser General Public License version 2.1 (LGPLv2.1)
* @author Andre Roth
*
* @par Relevant specs
* The table described herein is defined in ISO 13818-2
*
* @see
* http://dvd.sourceforge.net/dvdinfo/mpeghdrs.html
*
* @par Bug Report
* Please submit bug reports and patches to linux-media@vger.kernel.org
*/
#include <stdint.h>
#include <unistd.h> /* ssize_t */
/**
* @def DVB_MPEG_ES_PIC_START
* @brief Picture Start
* @ingroup dvb_table
* @def DVB_MPEG_ES_USER_DATA
* @brief User Data
* @ingroup dvb_table
* @def DVB_MPEG_ES_SEQ_START
* @brief Sequence Start
* @ingroup dvb_table
* @def DVB_MPEG_ES_SEQ_EXT
* @brief Extension
* @ingroup dvb_table
* @def DVB_MPEG_ES_GOP
* @brief Group Of Pictures
* @ingroup dvb_table
* @def DVB_MPEG_ES_SLICES
* @brief Slices
* @ingroup dvb_table
*/
#define DVB_MPEG_ES_PIC_START 0x00
#define DVB_MPEG_ES_USER_DATA 0xb2
#define DVB_MPEG_ES_SEQ_START 0xb3
#define DVB_MPEG_ES_SEQ_EXT 0xb5
#define DVB_MPEG_ES_GOP 0xb8
#define DVB_MPEG_ES_SLICES 0x01 ... 0xaf
/**
* @struct dvb_mpeg_es_seq_start
* @brief MPEG ES Sequence header
* @ingroup dvb_table
*
* @param type DVB_MPEG_ES_SEQ_START
* @param sync Sync bytes
* @param framerate Framerate
* @param aspect Aspect ratio
* @param height Height
* @param width Width
* @param qm_nonintra Load non-intra quantizer matrix
* @param qm_intra Load intra quantizer matrix
* @param constrained Constrained parameters flag
* @param vbv VBV buffer size
* @param one Should be 1
* @param bitrate Bitrate
*/
struct dvb_mpeg_es_seq_start {
union {
uint32_t bitfield;
struct {
uint32_t type:8;
uint32_t sync:24;
} __attribute__((packed));
} __attribute__((packed));
union {
uint32_t bitfield2;
struct {
uint32_t framerate:4;
uint32_t aspect:4;
uint32_t height:12;
uint32_t width:12;
} __attribute__((packed));
} __attribute__((packed));
union {
uint32_t bitfield3;
struct {
uint32_t qm_nonintra:1;
uint32_t qm_intra:1;
uint32_t constrained:1;
uint32_t vbv:10; // Size of video buffer verifier = 16*1024*vbv buf size
uint32_t one:1;
uint32_t bitrate:18;
} __attribute__((packed));
} __attribute__((packed));
} __attribute__((packed));
/**
* @struct dvb_mpeg_es_pic_start
* @brief MPEG ES Picture start header
* @ingroup dvb_table
*
* @param type DVB_MPEG_ES_PIC_START
* @param sync Sync bytes
* @param dummy Unused
* @param vbv_delay VBV delay
* @param coding_type Frame type (enum dvb_mpeg_es_frame_t)
* @param temporal_ref Temporal sequence number
*/
struct dvb_mpeg_es_pic_start {
union {
uint32_t bitfield;
struct {
uint32_t type:8;
uint32_t sync:24;
} __attribute__((packed));
} __attribute__((packed));
union {
uint32_t bitfield2;
struct {
uint32_t dummy:3;
uint32_t vbv_delay:16;
uint32_t coding_type:3;
uint32_t temporal_ref:10;
} __attribute__((packed));
} __attribute__((packed));
} __attribute__((packed));
/**
* @enum dvb_mpeg_es_frame_t
* @brief MPEG frame types
* @ingroup dvb_table
*
* @var DVB_MPEG_ES_FRAME_UNKNOWN
* @brief Unknown frame
* @var DVB_MPEG_ES_FRAME_I
* @brief I frame
* @var DVB_MPEG_ES_FRAME_P
* @brief P frame
* @var DVB_MPEG_ES_FRAME_B
* @brief B frame
* @var DVB_MPEG_ES_FRAME_D
* @brief D frame
*/
enum dvb_mpeg_es_frame_t
{
DVB_MPEG_ES_FRAME_UNKNOWN,
DVB_MPEG_ES_FRAME_I,
DVB_MPEG_ES_FRAME_P,
DVB_MPEG_ES_FRAME_B,
DVB_MPEG_ES_FRAME_D
};
/**
* @brief Vector that translates from enum dvb_mpeg_es_frame_t to string.
* @ingroup dvb_table
*/
extern const char *dvb_mpeg_es_frame_names[5];
struct dvb_v5_fe_parms;
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Initialize a struct dvb_mpeg_es_seq_start from buffer
* @ingroup dvb_table
*
* @param buf Buffer
* @param buflen Length of buffer
* @param seq_start Pointer to allocated struct dvb_mpeg_es_seq_start
*
* @return If buflen too small, return -1, 0 otherwise.
*
* This function copies the length of struct dvb_mpeg_es_seq_start
* to seq_start and fixes endianness. seq_start has to be allocated
* with malloc.
*/
int dvb_mpeg_es_seq_start_init (const uint8_t *buf, ssize_t buflen,
struct dvb_mpeg_es_seq_start *seq_start);
/**
* @brief Print details of struct dvb_mpeg_es_seq_start
* @ingroup dvb_table
*
* @param parms struct dvb_v5_fe_parms for log functions
* @param seq_start Pointer to struct dvb_mpeg_es_seq_start to print
*
* This function prints the fields of struct dvb_mpeg_es_seq_start
*/
void dvb_mpeg_es_seq_start_print(struct dvb_v5_fe_parms *parms,
struct dvb_mpeg_es_seq_start *seq_start);
/**
* @brief Initialize a struct dvb_mpeg_es_pic_start from buffer
* @ingroup dvb_table
*
* @param buf Buffer
* @param buflen Length of buffer
* @param pic_start Pointer to allocated structdvb_mpeg_es_pic_start
*
* @return If buflen too small, return -1, 0 otherwise.
*
* This function copies the length of struct dvb_mpeg_es_pic_start
* to pic_start and fixes endianness. seq_start has to be allocated
* with malloc.
*/
int dvb_mpeg_es_pic_start_init (const uint8_t *buf, ssize_t buflen,
struct dvb_mpeg_es_pic_start *pic_start);
/**
* @brief Print details of struct dvb_mpeg_es_pic_start
* @ingroup dvb_table
*
* @param parms struct dvb_v5_fe_parms for log functions
* @param pic_start Pointer to struct dvb_mpeg_es_pic_start to print
*
* This function prints the fields of struct dvb_mpeg_es_pic_start
*/
void dvb_mpeg_es_pic_start_print(struct dvb_v5_fe_parms *parms,
struct dvb_mpeg_es_pic_start *pic_start);
#ifdef __cplusplus
}
#endif
#endif

248
include/libdvbv5/mpeg_pes.h Normal file
View File

@@ -0,0 +1,248 @@
/*
* Copyright (c) 2013-2014 - Andre Roth <neolynx@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation version 2.1 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
* Or, point your browser to http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
*/
#ifndef _MPEG_PES_H
#define _MPEG_PES_H
/**
* @file mpeg_pes.h
* @ingroup dvb_table
* @brief Provides the table parser for the MPEG-PES Elementary Stream
* @copyright GNU Lesser General Public License version 2.1 (LGPLv2.1)
* @author Andre Roth
*
* @par Relevant specs
* The table described herein is defined in ISO 13818-1
*
* @see
* http://dvd.sourceforge.net/dvdinfo/pes-hdr.html
*
* @par Bug Report
* Please submit bug reports and patches to linux-media@vger.kernel.org
*/
#include <stdint.h>
#include <unistd.h> /* ssize_t */
/**
* @def DVB_MPEG_PES
* @brief MPEG Packetized Elementary Stream magic
* @ingroup dvb_table
* @def DVB_MPEG_PES_AUDIO
* @brief PES Audio
* @ingroup dvb_table
* @def DVB_MPEG_PES_VIDEO
* @brief PES Video
* @ingroup dvb_table
* @def DVB_MPEG_STREAM_MAP
* @brief PES Stream map
* @ingroup dvb_table
* @def DVB_MPEG_STREAM_PADDING
* @brief PES padding
* @ingroup dvb_table
* @def DVB_MPEG_STREAM_PRIVATE_2
* @brief PES private
* @ingroup dvb_table
* @def DVB_MPEG_STREAM_ECM
* @brief PES ECM Stream
* @ingroup dvb_table
* @def DVB_MPEG_STREAM_EMM
* @brief PES EMM Stream
* @ingroup dvb_table
* @def DVB_MPEG_STREAM_DIRECTORY
* @brief PES Stream directory
* @ingroup dvb_table
* @def DVB_MPEG_STREAM_DSMCC
* @brief PES DSMCC
* @ingroup dvb_table
* @def DVB_MPEG_STREAM_H222E
* @brief PES H.222.1 type E
* @ingroup dvb_table
*/
#define DVB_MPEG_PES 0x00001
#define DVB_MPEG_PES_AUDIO 0xc0 ... 0xcf
#define DVB_MPEG_PES_VIDEO 0xe0 ... 0xef
#define DVB_MPEG_STREAM_MAP 0xBC
#define DVB_MPEG_STREAM_PADDING 0xBE
#define DVB_MPEG_STREAM_PRIVATE_2 0x5F
#define DVB_MPEG_STREAM_ECM 0x70
#define DVB_MPEG_STREAM_EMM 0x71
#define DVB_MPEG_STREAM_DIRECTORY 0xFF
#define DVB_MPEG_STREAM_DSMCC 0x7A
#define DVB_MPEG_STREAM_H222E 0xF8
/**
* @struct ts_t
* @brief MPEG PES timestamp structure, used for dts and pts
* @ingroup dvb_table
*
* @param tag 4 bits Should be 0010 for PTS and 0011 for DTS
* @param bits30 3 bits Timestamp bits 30-32
* @param one 1 bit Sould be 1
* @param bits15 15 bits Timestamp bits 15-29
* @param one1 1 bit Should be 1
* @param bits00 15 Bits Timestamp bits 0-14
* @param one2 1 bit Should be 1
*/
struct ts_t {
uint8_t one:1;
uint8_t bits30:3;
uint8_t tag:4;
union {
uint16_t bitfield;
struct {
uint16_t one1:1;
uint16_t bits15:15;
} __attribute__((packed));
} __attribute__((packed));
union {
uint16_t bitfield2;
struct {
uint16_t one2:1;
uint16_t bits00:15;
} __attribute__((packed));
} __attribute__((packed));
} __attribute__((packed));
/**
* @struct dvb_mpeg_pes_optional
* @brief MPEG PES optional header
* @ingroup dvb_table
*
* @param two 2 bits Should be 10
* @param PES_scrambling_control 2 bits PES Scrambling Control (Not Scrambled=00, otherwise scrambled)
* @param PES_priority 1 bit PES Priority
* @param data_alignment_indicator 1 bit PES data alignment
* @param copyright 1 bit PES content protected by copyright
* @param original_or_copy 1 bit PES content is original (=1) or copied (=0)
* @param PTS_DTS 2 bit PES header contains PTS (=10, =11) and/or DTS (=01, =11)
* @param ESCR 1 bit PES header contains ESCR fields
* @param ES_rate 1 bit PES header contains ES_rate field
* @param DSM_trick_mode 1 bit PES header contains DSM_trick_mode field
* @param additional_copy_info 1 bit PES header contains additional_copy_info field
* @param PES_CRC 1 bit PES header contains CRC field
* @param PES_extension 1 bit PES header contains extension field
* @param length 8 bit PES header data length
* @param pts 64 bit PES PTS timestamp
* @param dts 64 bit PES DTS timestamp
*/
struct dvb_mpeg_pes_optional {
union {
uint16_t bitfield;
struct {
uint16_t PES_extension:1;
uint16_t PES_CRC:1;
uint16_t additional_copy_info:1;
uint16_t DSM_trick_mode:1;
uint16_t ES_rate:1;
uint16_t ESCR:1;
uint16_t PTS_DTS:2;
uint16_t original_or_copy:1;
uint16_t copyright:1;
uint16_t data_alignment_indicator:1;
uint16_t PES_priority:1;
uint16_t PES_scrambling_control:2;
uint16_t two:2;
} __attribute__((packed));
} __attribute__((packed));
uint8_t length;
uint64_t pts;
uint64_t dts;
} __attribute__((packed));
/**
* @struct dvb_mpeg_pes
* @brief MPEG PES data structure
* @ingroup dvb_table
*
* @param sync 24 bits DVB_MPEG_PES
* @param stream_id 8 bits PES Stream ID
* @param length 16 bits PES packet length
* @param optional Pointer to optional PES header
*/
struct dvb_mpeg_pes {
union {
uint32_t bitfield;
struct {
uint32_t stream_id:8;
uint32_t sync:24;
} __attribute__((packed));
} __attribute__((packed));
uint16_t length;
struct dvb_mpeg_pes_optional optional[];
} __attribute__((packed));
struct dvb_v5_fe_parms;
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Initialize a struct dvb_mpeg_pes from buffer
* @ingroup dvb_table
*
* @param parms struct dvb_v5_fe_parms for log functions
* @param buf Buffer
* @param buflen Length of buffer
* @param table Pointer to allocated struct dvb_mpeg_pes
*
* @return Length of data in table
*
* This function copies the length of struct dvb_mpeg_pes
* to table and fixes endianness. The pointer table has to be
* allocated on stack or dynamically.
*/
ssize_t dvb_mpeg_pes_init(struct dvb_v5_fe_parms *parms, const uint8_t *buf, ssize_t buflen,
uint8_t *table);
/**
* @brief Deallocate memory associated with a struct dvb_mpeg_pes
* @ingroup dvb_table
*
* @param pes struct dvb_mpeg_pes to be deallocated
*
* If the pointer pes was allocated dynamically, this function
* can be used to free the memory.
*/
void dvb_mpeg_pes_free(struct dvb_mpeg_pes *pes);
/**
* @brief Print details of struct dvb_mpeg_pes
* @ingroup dvb_table
*
* @param parms struct dvb_v5_fe_parms for log functions
* @param pes Pointer to struct dvb_mpeg_pes to print
*
* This function prints the fields of struct dvb_mpeg_pes
*/
void dvb_mpeg_pes_print (struct dvb_v5_fe_parms *parms, struct dvb_mpeg_pes *pes);
#ifdef __cplusplus
}
#endif
#endif

172
include/libdvbv5/mpeg_ts.h Normal file
View File

@@ -0,0 +1,172 @@
/*
* Copyright (c) 2013-2014 - Andre Roth <neolynx@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation version 2.1 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
* Or, point your browser to http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
*/
#ifndef _MPEG_TS_H
#define _MPEG_TS_H
/**
* @file mpeg_ts.h
* @ingroup dvb_table
* @brief Provides the table parser for the MPEG-PES Elementary Stream
* @copyright GNU Lesser General Public License version 2.1 (LGPLv2.1)
* @author Andre Roth
*
* @par Relevant specs
* The table described herein is defined in ISO 13818-1
*
* @see
* http://en.wikipedia.org/wiki/MPEG_transport_stream
*
* @par Bug Report
* Please submit bug reports and patches to linux-media@vger.kernel.org
*/
#include <stdint.h>
#include <unistd.h> /* ssize_t */
/**
* @def DVB_MPEG_TS
* @brief MPEG Transport Stream magic
* @ingroup dvb_table
* @def DVB_MPEG_TS_PACKET_SIZE
* @brief Size of an MPEG packet
* @ingroup dvb_table
*/
#define DVB_MPEG_TS 0x47
#define DVB_MPEG_TS_PACKET_SIZE 188
/**
* @struct dvb_mpeg_ts_adaption
* @brief MPEG TS header adaption field
* @ingroup dvb_table
*
* @param type DVB_MPEG_ES_SEQ_START
* @param length 1 bit Adaptation Field Length
* @param discontinued 1 bit Discontinuity indicator
* @param random_access 1 bit Random Access indicator
* @param priority 1 bit Elementary stream priority indicator
* @param PCR 1 bit PCR flag
* @param OPCR 1 bit OPCR flag
* @param splicing_point 1 bit Splicing point flag
* @param private_data 1 bit Transport private data flag
* @param extension 1 bit Adaptation field extension flag
* @param data Pointer to data
*/
struct dvb_mpeg_ts_adaption {
uint8_t length;
struct {
uint8_t extension:1;
uint8_t private_data:1;
uint8_t splicing_point:1;
uint8_t OPCR:1;
uint8_t PCR:1;
uint8_t priority:1;
uint8_t random_access:1;
uint8_t discontinued:1;
} __attribute__((packed));
uint8_t data[];
} __attribute__((packed));
/**
* @struct dvb_mpeg_ts
* @brief MPEG TS header
* @ingroup dvb_table
*
* @param sync_byte DVB_MPEG_TS
* @param tei 1 bit Transport Error Indicator
* @param payload_start 1 bit Payload Unit Start Indicator
* @param priority 1 bit Transport Priority
* @param pid 13 bits Packet Identifier
* @param scrambling 2 bits Scrambling control
* @param adaptation_field 1 bit Adaptation field exist
* @param payload 1 bit Contains payload
* @param continuity_counter 4 bits Continuity counter
* @param adaption Pointer to optional adaption fiels (struct dvb_mpeg_ts_adaption)
*/
struct dvb_mpeg_ts {
uint8_t sync_byte;
union {
uint16_t bitfield;
struct {
uint16_t pid:13;
uint16_t priority:1;
uint16_t payload_start:1;
uint16_t tei:1;
} __attribute__((packed));
} __attribute__((packed));
struct {
uint8_t continuity_counter:4;
uint8_t payload:1;
uint8_t adaptation_field:1;
uint8_t scrambling:2;
} __attribute__((packed));
struct dvb_mpeg_ts_adaption adaption[];
} __attribute__((packed));
struct dvb_v5_fe_parms;
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Initialize a struct dvb_mpeg_ts from buffer
* @ingroup dvb_table
*
* @param parms struct dvb_v5_fe_parms for log functions
* @param buf Buffer
* @param buflen Length of buffer
* @param table Pointer to allocated struct dvb_mpeg_ts
* @param table_length Pointer to size_t where length will be written to
*
* @return Length of data in table
*
* This function copies the length of struct dvb_mpeg_ts
* to table and fixes endianness. The pointer table has to be allocated
* on stack or dynamically.
*/
ssize_t dvb_mpeg_ts_init (struct dvb_v5_fe_parms *parms, const uint8_t *buf, ssize_t buflen,
uint8_t *table, ssize_t *table_length);
/**
* @brief Deallocate memory associated with a struct dvb_mpeg_ts
* @ingroup dvb_table
*
* @param ts struct dvb_mpeg_ts to be deallocated
*
* If ts was allocated dynamically, this function
* can be used to free the memory.
*/
void dvb_mpeg_ts_free(struct dvb_mpeg_ts *ts);
/**
* @brief Print details of struct dvb_mpeg_ts
* @ingroup dvb_table
*
* @param parms struct dvb_v5_fe_parms for log functions
* @param ts Pointer to struct dvb_mpeg_ts to print
*
* This function prints the fields of struct dvb_mpeg_ts
*/
void dvb_mpeg_ts_print(struct dvb_v5_fe_parms *parms, struct dvb_mpeg_ts *ts);
#ifdef __cplusplus
}
#endif
#endif

276
include/libdvbv5/nit.h Normal file
View File

@@ -0,0 +1,276 @@
/*
* Copyright (c) 2011-2012 - Mauro Carvalho Chehab
* Copyright (c) 2012 - Andre Roth <neolynx@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation version 2.1 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
* Or, point your browser to http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
*/
#ifndef _NIT_H
#define _NIT_H
#include <stdint.h>
#include <unistd.h> /* ssize_t */
#include <libdvbv5/header.h>
#include <libdvbv5/descriptors.h>
/**
* @file nit.h
* @ingroup dvb_table
* @brief Provides the descriptors for NIT MPEG-TS table
* @copyright GNU Lesser General Public License version 2.1 (LGPLv2.1)
* @author Mauro Carvalho Chehab
* @author Andre Roth
*
* @par Bug Report
* Please submit bug report and patches to linux-media@vger.kernel.org
*
* @par Relevant specs
* The table described herein is defined at:
* - ISO/IEC 13818-1
* - ETSI EN 300 468
*
* @par Bug Report
* Please submit bug reports and patches to linux-media@vger.kernel.org
*/
/**
* @def DVB_TABLE_NIT
* @brief NIT table ID
* @ingroup dvb_table
* @def DVB_TABLE_NIT2
* @brief NIT table ID (alternative table ID)
* @ingroup dvb_table
* @def DVB_TABLE_NIT_PID
* @brief NIT Program ID
* @ingroup dvb_table
*/
#define DVB_TABLE_NIT 0x40
#define DVB_TABLE_NIT2 0x41
#define DVB_TABLE_NIT_PID 0x10
/**
* @union dvb_table_nit_transport_header
* @brief MPEG-TS NIT transport header
* @ingroup dvb_table
*
* @param transport_length transport length
*
* This structure is used to store the original NIT transport header,
* converting the integer fields to the CPU endianness.
*
* The undocumented parameters are used only internally by the API and/or
* are fields that are reserved. They shouldn't be used, as they may change
* on future API releases.
*/
union dvb_table_nit_transport_header {
uint16_t bitfield;
struct {
uint16_t transport_length:12;
uint16_t reserved:4;
} __attribute__((packed));
} __attribute__((packed));
/**
* @struct dvb_table_nit_transport
* @brief MPEG-TS NIT transport table
* @ingroup dvb_table
*
* @param transport_id transport id
* @param network_id network id
* @param desc_length desc length
* @param descriptor pointer to struct dvb_desc
* @param next pointer to struct dvb_table_nit_transport
*
* This structure is used to store the original NIT transport table,
* converting the integer fields to the CPU endianness.
*
* The undocumented parameters are used only internally by the API and/or
* are fields that are reserved. They shouldn't be used, as they may change
* on future API releases.
*
* Everything after dvb_table_nit_transport::descriptor (including it) won't
* be bit-mapped to the data parsed from the MPEG TS. So, metadata are added
* there.
*/
struct dvb_table_nit_transport {
uint16_t transport_id;
uint16_t network_id;
union {
uint16_t bitfield;
struct {
uint16_t desc_length:12;
uint16_t reserved:4;
} __attribute__((packed));
} __attribute__((packed));
struct dvb_desc *descriptor;
struct dvb_table_nit_transport *next;
} __attribute__((packed));
/**
* @struct dvb_table_nit
* @brief MPEG-TS NIT table
* @ingroup dvb_table
*
* @param header struct dvb_table_header content
* @param desc_length descriptor length
* @param descriptor pointer to struct dvb_desc
* @param transport pointer to struct dvb_table_nit_transport
*
* This structure is used to store the original NIT table,
* converting the integer fields to the CPU endianness.
*
* The undocumented parameters are used only internally by the API and/or
* are fields that are reserved. They shouldn't be used, as they may change
* on future API releases.
*
* Everything after dvb_table_nit::descriptor (including it) won't be bit-mapped
* to the data parsed from the MPEG TS. So, metadata are added there.
*/
struct dvb_table_nit {
struct dvb_table_header header;
union {
uint16_t bitfield;
struct {
uint16_t desc_length:12;
uint16_t reserved:4;
} __attribute__((packed));
} __attribute__((packed));
struct dvb_desc *descriptor;
struct dvb_table_nit_transport *transport;
} __attribute__((packed));
/**
* @brief typedef for a callback used when a NIT table entry is found
* @ingroup dvb_table
*
* @param nit a struct dvb_table_nit pointer
* @param desc a struct dvb_desc pointer
* @param priv an opaque optional pointer
*/
typedef void nit_handler_callback_t(struct dvb_table_nit *nit,
struct dvb_desc *desc,
void *priv);
/**
* @brief typedef for a callback used when a NIT transport table entry is found
* @ingroup dvb_table
*
* @param nit a struct dvb_table_nit pointer
* @param tran a struct dvb_table_nit_transport pointer
* @param desc a struct dvb_desc pointer
* @param priv an opaque optional pointer
*/
typedef void nit_tran_handler_callback_t(struct dvb_table_nit *nit,
struct dvb_table_nit_transport *tran,
struct dvb_desc *desc,
void *priv);
/**
* @brief Macro used to find a transport inside a NIT table
* @ingroup dvb_table
*
* @param _tran transport to seek
* @param _nit pointer to struct dvb_table_nit_transport
*/
#define dvb_nit_transport_foreach( _tran, _nit ) \
if (_nit && _nit->transport) \
for (struct dvb_table_nit_transport *_tran = _nit->transport; _tran; _tran = _tran->next) \
struct dvb_v5_fe_parms;
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Initializes and parses NIT table
* @ingroup dvb_table
*
* @param parms struct dvb_v5_fe_parms pointer to the opened device
* @param buf buffer containing the NIT raw data
* @param buflen length of the buffer
* @param table pointer to struct dvb_table_nit to be allocated and filled
*
* This function allocates a NIT table and fills the fields inside
* the struct. It also makes sure that all fields will follow the CPU
* endianness. Due to that, the content of the buffer may change.
*
* @return On success, it returns the size of the allocated struct.
* A negative value indicates an error.
*/
ssize_t dvb_table_nit_init (struct dvb_v5_fe_parms *parms, const uint8_t *buf,
ssize_t buflen, struct dvb_table_nit **table);
/**
* @brief Frees all data allocated by the NIT table parser
* @ingroup dvb_table
*
* @param table pointer to struct dvb_table_nit to be freed
*/
void dvb_table_nit_free(struct dvb_table_nit *table);
/**
* @brief Prints the content of the NIT table
* @ingroup dvb_table
*
* @param parms struct dvb_v5_fe_parms pointer to the opened device
* @param table pointer to struct dvb_table_nit
*/
void dvb_table_nit_print(struct dvb_v5_fe_parms *parms, struct dvb_table_nit *table);
/**
* @brief For each entry at NIT and NIT transport tables, call a callback
* @ingroup dvb_table
*
* @param parms struct dvb_v5_fe_parms pointer to the opened device
* @param table pointer to struct dvb_table_nit
* @param descriptor indicates the NIT table descriptor to seek
* @param call_nit a nit_handler_callback_t function to be called when a
* new entry at the NIT table is found (or NULL).
* @param call_tran a nit_tran_handler_callback_t function to be called
* when a new entry at the NIT transport table is found
* (or NULL).
* @param priv an opaque pointer to be optionally used by the
* callbacks. The function won't touch on it, just use
* as an argument for the callback functions.
*
* When parsing a NIT entry, we need to call some code to properly handle
* when a given descriptor in the table is found. This is used, for example,
* to create newer transponders to seek during scan.
*
* For example, to seek for the CATV delivery system descriptor and call a
* function that would add a new transponder to a scan procedure:
* @code
* dvb_table_nit_descriptor_handler(
* &parms->p, dvb_scan_handler->nit,
* cable_delivery_system_descriptor,
* NULL, add_update_nit_dvbc, &tr);
* @endcode
*/
void dvb_table_nit_descriptor_handler(
struct dvb_v5_fe_parms *parms,
struct dvb_table_nit *table,
enum descriptors descriptor,
nit_handler_callback_t *call_nit,
nit_tran_handler_callback_t *call_tran,
void *priv);
#ifdef __cplusplus
}
#endif
#endif

172
include/libdvbv5/pat.h Normal file
View File

@@ -0,0 +1,172 @@
/*
* Copyright (c) 2011-2012 - Mauro Carvalho Chehab
* Copyright (c) 2012 - Andre Roth <neolynx@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation version 2.1 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
* Or, point your browser to http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
*/
/**
* @file pat.h
* @ingroup dvb_table
* @brief Provides the descriptors for PAT MPEG-TS table
* @copyright GNU Lesser General Public License version 2.1 (LGPLv2.1)
* @author Mauro Carvalho Chehab
* @author Andre Roth
*
* @par Relevant specs
* The table described herein is defined at:
* - ISO/IEC 13818-1
*
* @see http://www.etherguidesystems.com/help/sdos/mpeg/syntax/tablesections/pat.aspx
*
* @par Bug Report
* Please submit bug reports and patches to linux-media@vger.kernel.org
*/
#ifndef _PAT_H
#define _PAT_H
#include <stdint.h>
#include <unistd.h> /* ssize_t */
#include <libdvbv5/header.h>
/**
* @def DVB_TABLE_PAT
* @brief PAT table ID
* @ingroup dvb_table
* @def DVB_TABLE_PAT_PID
* @brief PAT Program ID
* @ingroup dvb_table
*/
#define DVB_TABLE_PAT 0x00
#define DVB_TABLE_PAT_PID 0x0000
/**
* @struct dvb_table_pat_program
* @brief MPEG-TS PAT program table
* @ingroup dvb_table
*
* @param service_id service id
* @param pid pid
* @param next pointer to struct dvb_table_pat_program
*
* This structure is used to store the original PAT program table,
* converting the integer fields to the CPU endianness.
*
* The undocumented parameters are used only internally by the API and/or
* are fields that are reserved. They shouldn't be used, as they may change
* on future API releases.
*
* Everything after dvb_table_pat_program::next (including it) won't be bit-mapped
* to the data parsed from the MPEG TS. So, metadata are added there.
*/
struct dvb_table_pat_program {
uint16_t service_id;
union {
uint16_t bitfield;
struct {
uint16_t pid:13;
uint8_t reserved:3;
} __attribute__((packed));
} __attribute__((packed));
struct dvb_table_pat_program *next;
} __attribute__((packed));
/**
* @struct dvb_table_pat
* @brief MPEG-TS PAT table
* @ingroup dvb_table
*
* @param header struct dvb_table_header content
* @param programs number of programs
* @param program pointer to struct dvb_table_pat_program
* This structure is used to store the original PAT table,
* converting the integer fields to the CPU endianness.
*
* The undocumented parameters are used only internally by the API and/or
* are fields that are reserved. They shouldn't be used, as they may change
* on future API releases.
*
* Everything after dvb_table_pat_program::program (including it) won't be bit-mapped
* to the data parsed from the MPEG TS. So, metadata are added there.
*/
struct dvb_table_pat {
struct dvb_table_header header;
uint16_t programs;
struct dvb_table_pat_program *program;
} __attribute__((packed));
/**
* @brief Macro used to find programs on a PAT table
* @ingroup dvb_table
*
* @param _pgm program to seek
* @param _pat pointer to struct dvb_table_pat_program
*/
#define dvb_pat_program_foreach(_pgm, _pat) \
if (_pat && _pat->program) \
for (struct dvb_table_pat_program *_pgm = _pat->program; _pgm; _pgm = _pgm->next) \
struct dvb_v5_fe_parms;
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Initializes and parses PAT table
* @ingroup dvb_table
*
* @param parms struct dvb_v5_fe_parms pointer to the opened device
* @param buf buffer containing the PAT raw data
* @param buflen length of the buffer
* @param table pointer to struct dvb_table_pat to be allocated and filled
*
* This function allocates a PAT table and fills the fields inside
* the struct. It also makes sure that all fields will follow the CPU
* endianness. Due to that, the content of the buffer may change.
*
* @return On success, it returns the size of the allocated struct.
* A negative value indicates an error.
*/
ssize_t dvb_table_pat_init (struct dvb_v5_fe_parms *parms, const uint8_t *buf,
ssize_t buflen, struct dvb_table_pat **table);
/**
* @brief Frees all data allocated by the PAT table parser
* @ingroup dvb_table
*
* @param table pointer to struct dvb_table_pat to be freed
*/
void dvb_table_pat_free(struct dvb_table_pat *table);
/**
* @brief Prints the content of the PAT table
* @ingroup dvb_table
*
* @param parms struct dvb_v5_fe_parms pointer to the opened device
* @param table pointer to struct dvb_table_pat
*/
void dvb_table_pat_print(struct dvb_v5_fe_parms *parms,
struct dvb_table_pat *table);
#ifdef __cplusplus
}
#endif
#endif

300
include/libdvbv5/pmt.h Normal file
View File

@@ -0,0 +1,300 @@
/*
* Copyright (c) 2011-2012 - Mauro Carvalho Chehab
* Copyright (c) 2012 - Andre Roth <neolynx@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation version 2.1 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
* Or, point your browser to http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
*/
/**
* @file pmt.h
* @ingroup dvb_table
* @brief Provides the descriptors for PMT MPEG-TS table
* @copyright GNU Lesser General Public License version 2.1 (LGPLv2.1)
* @author Mauro Carvalho Chehab
* @author Andre Roth
*
* @par Relevant specs
* The table described herein is defined at:
* - ISO/IEC 13818-1
*
* @see http://www.etherguidesystems.com/help/sdos/mpeg/syntax/tablesections/pmts.aspx
*
* @par Bug Report
* Please submit bug reports and patches to linux-media@vger.kernel.org
*/
#ifndef _PMT_H
#define _PMT_H
#include <stdint.h>
#include <unistd.h> /* ssize_t */
#include <libdvbv5/header.h>
/**
* @def DVB_TABLE_PMT
* @brief PMT table ID
* @ingroup dvb_table
*/
#define DVB_TABLE_PMT 0x02
/**
* @enum dvb_streams
* @brief Add support for MPEG-TS Stream types
* @ingroup dvb_table
*
* @var stream_reserved0
* @brief ITU-T | ISO/IEC Reserved
* @var stream_video
* @brief ISO/IEC 11172 Video
* @var stream_video_h262
* @brief ITU-T Rec. H.262 | ISO/IEC 13818-2 Video or ISO/IEC 11172-2 constrained parameter video stream
* @var stream_audio
* @brief ISO/IEC 11172 Audio
* @var stream_audio_13818_3
* @brief ISO/IEC 13818-3 Audio
* @var stream_private_sections
* @brief ITU-T Rec. H.222.0 | ISO/IEC 13818-1 private_sections
* @var stream_private_data
* @brief ITU-T Rec. H.222.0 | ISO/IEC 13818-1 PES packets containing private data
* @var stream_mheg
* @brief ISO/IEC 13522 MHEG
* @var stream_h222
* @brief ITU-T Rec. H.222.0 | ISO/IEC 13818-1 Annex A DSM-CC
* @var stream_h222_1
* @brief ITU-T Rec. H.222.1
* @var stream_13818_6_A
* @brief ISO/IEC 13818-6 type A
* @var stream_13818_6_B
* @brief ISO/IEC 13818-6 type B
* @var stream_13818_6_C
* @brief ISO/IEC 13818-6 type C
* @var stream_13818_6_D
* @brief ISO/IEC 13818-6 type D
* @var stream_h222_aux
* @brief ITU-T Rec. H.222.0 | ISO/IEC 13818-1 auxiliary
* @var stream_audio_adts
* @brief ISO/IEC 13818-7 Audio with ADTS transport syntax
* @var stream_video_14496_2
* @brief ISO/IEC 14496-2 Visual
* @var stream_audio_latm
* @brief ISO/IEC 14496-3 Audio with the LATM transport syntax as defined in ISO/IEC 14496-3 / AMD 1
* @var stream_14496_1_pes
* @brief ISO/IEC 14496-1 SL-packetized stream or FlexMux stream carried in PES packets
* @var stream_14496_1_iso
* @brief ISO/IEC 14496-1 SL-packetized stream or FlexMux stream carried in ISO/IEC14496_sections.
* @var stream_download
* @brief ISO/IEC 13818-6 Synchronized Download Protocol
* @var stream_reserved
* @brief ITU-T Rec. H.222.0 | ISO/IEC 13818-1 Reserved (from 0x15 to 0x7f)
* @var stream_private
* @brief User Private (from 0x80 to 0xff)
*/
enum dvb_streams {
stream_video = 0x01,
stream_video_h262 = 0x02,
stream_audio = 0x03,
stream_audio_13818_3 = 0x04,
stream_private_sections = 0x05,
stream_private_data = 0x06,
stream_mheg = 0x07,
stream_h222 = 0x08,
stream_h222_1 = 0x09,
stream_13818_6_A = 0x0A,
stream_13818_6_B = 0x0B,
stream_13818_6_C = 0x0C,
stream_13818_6_D = 0x0D,
stream_h222_aux = 0x0E,
stream_audio_adts = 0x0F,
stream_video_14496_2 = 0x10,
stream_audio_latm = 0x11,
stream_14496_1_pes = 0x12,
stream_14496_1_iso = 0x13,
stream_download = 0x14,
stream_video_h264 = 0x1b,
stream_audio_14496_3 = 0x1c,
stream_video_hevc = 0x24,
stream_video_cavs = 0x42,
stream_video_moto = 0x80,
stream_audio_a52 = 0x81,
stream_scte_27 = 0x82,
stream_audio_sdds = 0x84,
stream_audio_dts_hdmv = 0x85,
stream_audio_e_ac3 = 0x87,
stream_audio_dts = 0x8a,
stream_audio_a52_vls = 0x91,
stream_spu_vls = 0x92,
stream_audio_sdds2 = 0x94,
};
/**
* @brief Converts from enum dvb_streams into a string
* @ingroup dvb_table
*/
extern const char *pmt_stream_name[];
/**
* @struct dvb_table_pmt_stream
* @brief MPEG-TS PMT stream table
* @ingroup dvb_table
*
* @param type stream type
* @param elementary_pid elementary pid
* @param desc_length descriptor length
* @param zero zero
* @param descriptor pointer to struct dvb_desc
* @param next pointer to struct dvb_table_pmt_stream
*
* This structure is used to store the original PMT stream table,
* converting the integer fields to the CPU endianness.
*
* The undocumented parameters are used only internally by the API and/or
* are fields that are reserved. They shouldn't be used, as they may change
* on future API releases.
*
* Everything after dvb_table_pmt_stream::descriptor (including it) won't be
* bit-mapped to the data parsed from the MPEG TS. So, metadata are added there.
*/
struct dvb_table_pmt_stream {
uint8_t type;
union {
uint16_t bitfield;
struct {
uint16_t elementary_pid:13;
uint16_t reserved:3;
} __attribute__((packed));
} __attribute__((packed));
union {
uint16_t bitfield2;
struct {
uint16_t desc_length:10;
uint16_t zero:2;
uint16_t reserved2:4;
} __attribute__((packed));
} __attribute__((packed));
struct dvb_desc *descriptor;
struct dvb_table_pmt_stream *next;
} __attribute__((packed));
/**
* @struct dvb_table_pmt
* @brief MPEG-TS PMT table
* @ingroup dvb_table
*
* @param header struct dvb_table_header content
* @param pcr_pid PCR PID
* @param desc_length descriptor length
* @param descriptor pointer to struct dvb_desc
* @param stream pointer to struct dvb_table_pmt_stream
*
* This structure is used to store the original PMT stream table,
* converting the integer fields to the CPU endianness.
*
* The undocumented parameters are used only internally by the API and/or
* are fields that are reserved. They shouldn't be used, as they may change
* on future API releases.
*
* Everything after dvb_table_pmt::descriptor (including it) won't be
* bit-mapped to the data parsed from the MPEG TS. So, metadata are added there.
*/
struct dvb_table_pmt {
struct dvb_table_header header;
union {
uint16_t bitfield;
struct {
uint16_t pcr_pid:13;
uint16_t reserved2:3;
} __attribute__((packed));
} __attribute__((packed));
union {
uint16_t bitfield2;
struct {
uint16_t desc_length:10;
uint16_t zero3:2;
uint16_t reserved3:4;
} __attribute__((packed));
} __attribute__((packed));
struct dvb_desc *descriptor;
struct dvb_table_pmt_stream *stream;
} __attribute__((packed));
/** @brief First field at the struct */
#define dvb_pmt_field_first header
/** @brief First field that are not part of the received data */
#define dvb_pmt_field_last descriptor
/**
* @brief Macro used to find streams on a PMT table
* @ingroup dvb_table
*
* @param _stream stream to seek
* @param _pmt pointer to struct dvb_table_pmt_stream
*/
#define dvb_pmt_stream_foreach(_stream, _pmt) \
if (_pmt && _pmt->stream) \
for (struct dvb_table_pmt_stream *_stream = _pmt->stream; _stream; _stream = _stream->next) \
struct dvb_v5_fe_parms;
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Initializes and parses PMT table
* @ingroup dvb_table
*
* @param parms struct dvb_v5_fe_parms pointer to the opened device
* @param buf buffer containing the PMT raw data
* @param buflen length of the buffer
* @param table pointer to struct dvb_table_pmt to be allocated and filled
*
* This function allocates a PMT table and fills the fields inside
* the struct. It also makes sure that all fields will follow the CPU
* endianness. Due to that, the content of the buffer may change.
*
* @return On success, it returns the size of the allocated struct.
* A negative value indicates an error.
*/
ssize_t dvb_table_pmt_init (struct dvb_v5_fe_parms *parms, const uint8_t *buf,
ssize_t buflen, struct dvb_table_pmt **table);
/**
* @brief Frees all data allocated by the PMT table parser
* @ingroup dvb_table
*
* @param table pointer to struct dvb_table_pmt to be freed
*/
void dvb_table_pmt_free(struct dvb_table_pmt *table);
/**
* @brief Prints the content of the PAT table
* @ingroup dvb_table
*
* @param parms struct dvb_v5_fe_parms pointer to the opened device
* @param table pointer to struct dvb_table_pmt
*/
void dvb_table_pmt_print(struct dvb_v5_fe_parms *parms,
const struct dvb_table_pmt *table);
#ifdef __cplusplus
}
#endif
#endif

187
include/libdvbv5/sdt.h Normal file
View File

@@ -0,0 +1,187 @@
/*
* Copyright (c) 2011-2012 - Mauro Carvalho Chehab
* Copyright (c) 2012 - Andre Roth <neolynx@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation version 2.1 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
* Or, point your browser to http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
*/
#ifndef _SDT_H
#define _SDT_H
/**
* @file sdt.h
* @ingroup dvb_table
* @brief Provides the descriptors for SDT MPEG-TS table
* @copyright GNU Lesser General Public License version 2.1 (LGPLv2.1)
* @author Mauro Carvalho Chehab
* @author Andre Roth
*
* @par Relevant specs
* The table described herein is defined at:
* - ISO/IEC 13818-1
*
* @see http://www.etherguidesystems.com/Help/SDOs/dvb/syntax/tablesections/SDT.aspx
*
* @par Bug Report
* Please submit bug reports and patches to linux-media@vger.kernel.org
*/
#include <stdint.h>
#include <unistd.h> /* ssize_t */
#include <libdvbv5/header.h>
/**
* @def DVB_TABLE_SDT
* @brief SDT table ID
* @ingroup dvb_table
* @def DVB_TABLE_SDT2
* @brief SDT table ID (alternative table ID)
* @ingroup dvb_table
* @def DVB_TABLE_SDT_PID
* @brief SDT Program ID
* @ingroup dvb_table
*/
#define DVB_TABLE_SDT 0x42
#define DVB_TABLE_SDT2 0x46
#define DVB_TABLE_SDT_PID 0x0011
/**
* @struct dvb_table_sdt_service
* @brief MPEG-TS SDT service table
* @ingroup dvb_table
*
* @param service_id service id
* @param EIT_present_following EIT present following
* @param EIT_schedule EIT schedule
* @param desc_length desc length
* @param free_CA_mode free CA mode
* @param running_status running status
* @param descriptor pointer to struct dvb_desc
* @param next pointer to struct dvb_table_sdt_service
*
* This structure is used to store the original SDT service table,
* converting the integer fields to the CPU endianness.
*
* The undocumented parameters are used only internally by the API and/or
* are fields that are reserved. They shouldn't be used, as they may change
* on future API releases.
*
* Everything after dvb_table_sdt_service::descriptor (including it) won't
* be bit-mapped to the data parsed from the MPEG TS. So, metadata are added
* there.
*/
struct dvb_table_sdt_service {
uint16_t service_id;
uint8_t EIT_present_following:1;
uint8_t EIT_schedule:1;
uint8_t reserved:6;
union {
uint16_t bitfield;
struct {
uint16_t desc_length:12;
uint16_t free_CA_mode:1;
uint16_t running_status:3;
} __attribute__((packed));
} __attribute__((packed));
struct dvb_desc *descriptor;
struct dvb_table_sdt_service *next;
} __attribute__((packed));
/**
* @struct dvb_table_sdt
* @brief MPEG-TS SDT table
* @ingroup dvb_table
*
* @param header struct dvb_table_header content
* @param network_id network id
* @param service pointer to struct dvb_table_sdt_service
*
* This structure is used to store the original SDT table,
* converting the integer fields to the CPU endianness.
*
* The undocumented parameters are used only internally by the API and/or
* are fields that are reserved. They shouldn't be used, as they may change
* on future API releases.
*
* Everything after dvb_table_sdt::service (including it) won't be bit-mapped
* to the data parsed from the MPEG TS. So, metadata are added there.
*/
struct dvb_table_sdt {
struct dvb_table_header header;
uint16_t network_id;
uint8_t reserved;
struct dvb_table_sdt_service *service;
} __attribute__((packed));
/**
* @brief Macro used to find services on a SDT table
* @ingroup dvb_table
*
* @param _service service to seek
* @param _sdt pointer to struct dvb_table_sdt_service
*/
#define dvb_sdt_service_foreach(_service, _sdt) \
if (_sdt && _sdt->service) \
for (struct dvb_table_sdt_service *_service = _sdt->service; _service; _service = _service->next ) \
struct dvb_v5_fe_parms;
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Initializes and parses SDT table
* @ingroup dvb_table
*
* @param parms struct dvb_v5_fe_parms pointer to the opened device
* @param buf buffer containing the SDT raw data
* @param buflen length of the buffer
* @param table pointer to struct dvb_table_sdt to be allocated and filled
*
* This function allocates a SDT table and fills the fields inside
* the struct. It also makes sure that all fields will follow the CPU
* endianness. Due to that, the content of the buffer may change.
*
* @return On success, it returns the size of the allocated struct.
* A negative value indicates an error.
*/
ssize_t dvb_table_sdt_init (struct dvb_v5_fe_parms *parms, const uint8_t *buf,
ssize_t buflen, struct dvb_table_sdt **table);
/**
* @brief Frees all data allocated by the SDT table parser
* @ingroup dvb_table
*
* @param table pointer to struct dvb_table_sdt to be freed
*/
void dvb_table_sdt_free(struct dvb_table_sdt *table);
/**
* @brief Prints the content of the SDT table
* @ingroup dvb_table
*
* @param parms struct dvb_v5_fe_parms pointer to the opened device
* @param table pointer to struct dvb_table_sdt
*/
void dvb_table_sdt_print(struct dvb_v5_fe_parms *parms, struct dvb_table_sdt *table);
#ifdef __cplusplus
}
#endif
#endif

251
include/libdvbv5/vct.h Normal file
View File

@@ -0,0 +1,251 @@
/*
* Copyright (c) 2013 - Mauro Carvalho Chehab <mchehab@kernel.org>
* Copyright (c) 2013 - Andre Roth <neolynx@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation version 2.1 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
* Or, point your browser to http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
*/
/**
* @file vct.h
* @ingroup dvb_table
* @brief Provides the descriptors for TVCT and CVCT tables
* @copyright GNU Lesser General Public License version 2.1 (LGPLv2.1)
* @author Mauro Carvalho Chehab
* @author Andre Roth
*
* @par Relevant specs
* The table described herein is defined at:
* - ATSC A/65:2009
*
* @see http://www.etherguidesystems.com/help/sdos/atsc/syntax/tablesections/TVCT.aspx
* @see http://www.etherguidesystems.com/help/sdos/atsc/syntax/tablesections/CVCT.aspx
*
* @par Bug Report
* Please submit bug reports and patches to linux-media@vger.kernel.org
*/
#ifndef _VCT_H
#define _VCT_H
#include <stdint.h>
#include <unistd.h> /* ssize_t */
#include <libdvbv5/atsc_header.h>
/**
* @def ATSC_TABLE_TVCT
* @brief TVCT table ID
* @ingroup dvb_table
* @def ATSC_TABLE_CVCT
* @brief CVCT table ID
* @ingroup dvb_table
* @def ATSC_TABLE_VCT_PID
* @brief Program ID with the VCT tables on it
* @ingroup dvb_table
*/
#define ATSC_TABLE_TVCT 0xc8
#define ATSC_TABLE_CVCT 0xc9
#define ATSC_TABLE_VCT_PID 0x1ffb
/**
* @struct atsc_table_vct_channel
* @brief ATSC VCT channel table (covers both CVCT and TVCT)
* @ingroup dvb_table
*
* @param modulation_mode modulation mode
* @param minor_channel_number minor channel number
* @param major_channel_number major channel number
* @param carrier_frequency carrier frequency
* @param channel_tsid channel tsid
* @param program_number program number
* @param service_type service type
* @param hide_guide hide guide
* @param out_of_band out of band (CVCT only)
* @param path_select path select (CVCT only)
* @param hidden hidden
* @param access_controlled access controlled
* @param ETM_location ETM location
* @param source_id source ID
* @param descriptors_length length of the descriptors
*
* @param descriptor pointer to struct dvb_desc
* @param next pointer to another struct atsc_table_vct_channel
* @param descriptors_length length of the descriptors
* @param short_name short name. The __short_name is converted
* from UTF-16 to locale charset when parsed
*
* This structure is used to store the original VCT channel table,
* converting the integer fields to the CPU endianness.
*
* The undocumented parameters are used only internally by the API and/or
* are fields that are reserved. They shouldn't be used, as they may change
* on future API releases.
*
* Everything after atsc_table_vct_channel::descriptor (including it) won't
* be bit-mapped * to the data parsed from the MPEG TS. So, metadata are
* added there.
*/
struct atsc_table_vct_channel {
uint16_t __short_name[7];
union {
uint32_t bitfield1;
struct {
uint32_t modulation_mode:8;
uint32_t minor_channel_number:10;
uint32_t major_channel_number:10;
uint32_t reserved1:4;
} __attribute__((packed));
} __attribute__((packed));
uint32_t carrier_frequency;
uint16_t channel_tsid;
uint16_t program_number;
union {
uint16_t bitfield2;
struct {
uint16_t service_type:6;
uint16_t reserved2:3;
uint16_t hide_guide:1;
uint16_t out_of_band:1; /* CVCT only */
uint16_t path_select:1; /* CVCT only */
uint16_t hidden:1;
uint16_t access_controlled:1;
uint16_t ETM_location:2;
} __attribute__((packed));
} __attribute__((packed));
uint16_t source_id;
union {
uint16_t bitfield3;
struct {
uint16_t descriptors_length:10;
uint16_t reserved3:6;
} __attribute__((packed));
} __attribute__((packed));
/*
* Everything after atsc_table_vct_channel::descriptor (including it)
* won't be bit-mapped to the data parsed from the MPEG TS. So,
* metadata are added there
*/
struct dvb_desc *descriptor;
struct atsc_table_vct_channel *next;
/* The channel_short_name is converted to locale charset by vct.c */
char short_name[32];
} __attribute__((packed));
/**
* @struct atsc_table_vct
* @brief ATSC VCT table (covers both CVCT and TVCT)
* @ingroup dvb_table
*
* @param header struct dvb_table_header content
* @param protocol_version protocol version
* @param num_channels_in_section num channels in section
* @param channel pointer to struct channel
* @param descriptor pointer to struct descriptor
*
* Everything after atsc_table_vct::channel (including it) won't be bit-mapped
* to the data parsed from the MPEG TS. So, metadata are added there
*/
struct atsc_table_vct {
struct dvb_table_header header;
uint8_t protocol_version;
uint8_t num_channels_in_section;
struct atsc_table_vct_channel *channel;
struct dvb_desc *descriptor;
} __attribute__((packed));
/**
* @union atsc_table_vct_descriptor_length
* @brief ATSC VCT descriptor length
* @ingroup dvb_table
*
* @param descriptor_length descriptor length
*
* Used internally by the library to parse the descriptor length endianness.
*/
union atsc_table_vct_descriptor_length {
uint16_t bitfield;
struct {
uint16_t descriptor_length:10;
uint16_t reserved:6;
} __attribute__((packed));
} __attribute__((packed));
/**
* @brief Macro used to find channels on a VCT table
* @ingroup dvb_table
*
* @param _channel channel to seek
* @param _vct pointer to struct atsc_table_vct_channel
*/
#define atsc_vct_channel_foreach(_channel, _vct) \
if (_vct && _vct->channel) \
for (struct atsc_table_vct_channel *_channel = _vct->channel; _channel; _channel = _channel->next) \
struct dvb_v5_fe_parms;
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Initializes and parses VCT table
* @ingroup dvb_table
*
* @param parms struct dvb_v5_fe_parms pointer to the opened device
* @param buf buffer containing the VCT raw data
* @param buflen length of the buffer
* @param table pointer to struct atsc_table_vct to be allocated and filled
*
* This function allocates an ATSC VCT table and fills the fields inside
* the struct. It also makes sure that all fields will follow the CPU
* endianness. Due to that, the content of the buffer may change.
*
* @return On success, it returns the size of the allocated struct.
* A negative value indicates an error.
*/
ssize_t atsc_table_vct_init(struct dvb_v5_fe_parms *parms, const uint8_t *buf,
ssize_t buflen, struct atsc_table_vct **table);
/**
* @brief Frees all data allocated by the VCT table parser
* @ingroup dvb_table
*
* @param table pointer to struct atsc_table_vct to be freed
*/
void atsc_table_vct_free(struct atsc_table_vct *table);
/**
* @brief Prints the content of the VCT table
* @ingroup dvb_table
*
* @param parms struct dvb_v5_fe_parms pointer to the opened device
* @param table pointer to struct atsc_table_vct
*/
void atsc_table_vct_print(struct dvb_v5_fe_parms *parms,
struct atsc_table_vct *table);
#ifdef __cplusplus
}
#endif
#endif

46
include/libv4l-plugin.h Normal file
View File

@@ -0,0 +1,46 @@
/*
* Copyright (C) 2010 Nokia Corporation <multimedia@maemo.org>
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef __LIBV4L_PLUGIN_H
#define __LIBV4L_PLUGIN_H
#include <sys/types.h>
/* Structure libv4l_dev_ops holds the calls from libv4ls to video nodes.
They can be normal open/close/ioctl etc. or any of them may be replaced
with a callback by a loaded plugin.
*/
struct libv4l_dev_ops {
void * (*init)(int fd);
void (*close)(void *dev_ops_priv);
int (*ioctl)(void *dev_ops_priv, int fd, unsigned long int request, void *arg);
ssize_t (*read)(void *dev_ops_priv, int fd, void *buffer, size_t n);
ssize_t (*write)(void *dev_ops_priv, int fd, const void *buffer, size_t n);
/* For future plugin API extension, plugins implementing the current API
must set these all to NULL, as future versions may check for these */
void (*reserved1)(void);
void (*reserved2)(void);
void (*reserved3)(void);
void (*reserved4)(void);
void (*reserved5)(void);
void (*reserved6)(void);
void (*reserved7)(void);
};
#endif

207
include/libv4l1-videodev.h Normal file
View File

@@ -0,0 +1,207 @@
/* libv4l1 linux/videodev.h replacement file */
#ifndef __LINUX_VIDEODEV_H
#define __LINUX_VIDEODEV_H
#ifdef linux
#include <linux/ioctl.h>
#endif
#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__OpenBSD__)
#include <sys/ioctl.h>
#endif
#include <stdint.h>
#define VID_TYPE_CAPTURE 1 /* Can capture */
#define VID_TYPE_TUNER 2 /* Can tune */
#define VID_TYPE_TELETEXT 4 /* Does teletext */
#define VID_TYPE_OVERLAY 8 /* Overlay onto frame buffer */
#define VID_TYPE_CHROMAKEY 16 /* Overlay by chromakey */
#define VID_TYPE_CLIPPING 32 /* Can clip */
#define VID_TYPE_FRAMERAM 64 /* Uses the frame buffer memory */
#define VID_TYPE_SCALES 128 /* Scalable */
#define VID_TYPE_MONOCHROME 256 /* Monochrome only */
#define VID_TYPE_SUBCAPTURE 512 /* Can capture subareas of the image */
#define VID_TYPE_MPEG_DECODER 1024 /* Can decode MPEG streams */
#define VID_TYPE_MPEG_ENCODER 2048 /* Can encode MPEG streams */
#define VID_TYPE_MJPEG_DECODER 4096 /* Can decode MJPEG streams */
#define VID_TYPE_MJPEG_ENCODER 8192 /* Can encode MJPEG streams */
struct video_capability
{
char name[32];
int type;
int channels; /* Num channels */
int audios; /* Num audio devices */
int maxwidth; /* Supported width */
int maxheight; /* And height */
int minwidth; /* Supported width */
int minheight; /* And height */
};
struct video_channel
{
int channel;
char name[32];
int tuners;
uint32_t flags;
#define VIDEO_VC_TUNER 1 /* Channel has a tuner */
#define VIDEO_VC_AUDIO 2 /* Channel has audio */
uint16_t type;
#define VIDEO_TYPE_TV 1
#define VIDEO_TYPE_CAMERA 2
uint16_t norm; /* Norm set by channel */
};
struct video_tuner
{
int tuner;
char name[32];
unsigned long rangelow, rangehigh; /* Tuner range */
uint32_t flags;
#define VIDEO_TUNER_PAL 1
#define VIDEO_TUNER_NTSC 2
#define VIDEO_TUNER_SECAM 4
#define VIDEO_TUNER_LOW 8 /* Uses KHz not MHz */
#define VIDEO_TUNER_NORM 16 /* Tuner can set norm */
#define VIDEO_TUNER_STEREO_ON 128 /* Tuner is seeing stereo */
#define VIDEO_TUNER_RDS_ON 256 /* Tuner is seeing an RDS datastream */
#define VIDEO_TUNER_MBS_ON 512 /* Tuner is seeing an MBS datastream */
uint16_t mode; /* PAL/NTSC/SECAM/OTHER */
#define VIDEO_MODE_PAL 0
#define VIDEO_MODE_NTSC 1
#define VIDEO_MODE_SECAM 2
#define VIDEO_MODE_AUTO 3
uint16_t signal; /* Signal strength 16bit scale */
};
struct video_picture
{
uint16_t brightness;
uint16_t hue;
uint16_t colour;
uint16_t contrast;
uint16_t whiteness; /* Black and white only */
uint16_t depth; /* Capture depth */
uint16_t palette; /* Palette in use */
#define VIDEO_PALETTE_GREY 1 /* Linear greyscale */
#define VIDEO_PALETTE_HI240 2 /* High 240 cube (BT848) */
#define VIDEO_PALETTE_RGB565 3 /* 565 16 bit RGB */
#define VIDEO_PALETTE_RGB24 4 /* 24bit RGB */
#define VIDEO_PALETTE_RGB32 5 /* 32bit RGB */
#define VIDEO_PALETTE_RGB555 6 /* 555 15bit RGB */
#define VIDEO_PALETTE_YUV422 7 /* YUV422 capture */
#define VIDEO_PALETTE_YUYV 8
#define VIDEO_PALETTE_UYVY 9 /* The great thing about standards is ... */
#define VIDEO_PALETTE_YUV420 10
#define VIDEO_PALETTE_YUV411 11 /* YUV411 capture */
#define VIDEO_PALETTE_RAW 12 /* RAW capture (BT848) */
#define VIDEO_PALETTE_YUV422P 13 /* YUV 4:2:2 Planar */
#define VIDEO_PALETTE_YUV411P 14 /* YUV 4:1:1 Planar */
#define VIDEO_PALETTE_YUV420P 15 /* YUV 4:2:0 Planar */
#define VIDEO_PALETTE_YUV410P 16 /* YUV 4:1:0 Planar */
#define VIDEO_PALETTE_PLANAR 13 /* start of planar entries */
#define VIDEO_PALETTE_COMPONENT 7 /* start of component entries */
};
struct video_audio
{
int audio; /* Audio channel */
uint16_t volume; /* If settable */
uint16_t bass, treble;
uint32_t flags;
#define VIDEO_AUDIO_MUTE 1
#define VIDEO_AUDIO_MUTABLE 2
#define VIDEO_AUDIO_VOLUME 4
#define VIDEO_AUDIO_BASS 8
#define VIDEO_AUDIO_TREBLE 16
#define VIDEO_AUDIO_BALANCE 32
char name[16];
#define VIDEO_SOUND_MONO 1
#define VIDEO_SOUND_STEREO 2
#define VIDEO_SOUND_LANG1 4
#define VIDEO_SOUND_LANG2 8
uint16_t mode;
uint16_t balance; /* Stereo balance */
uint16_t step; /* Step actual volume uses */
};
struct video_clip
{
int32_t x,y;
int32_t width, height;
struct video_clip *next; /* For user use/driver use only */
};
struct video_window
{
uint32_t x,y; /* Position of window */
uint32_t width,height; /* Its size */
uint32_t chromakey;
uint32_t flags;
struct video_clip *clips; /* Set only */
int clipcount;
#define VIDEO_WINDOW_INTERLACE 1
#define VIDEO_WINDOW_CHROMAKEY 16 /* Overlay by chromakey */
#define VIDEO_CLIP_BITMAP -1
/* bitmap is 1024x625, a '1' bit represents a clipped pixel */
#define VIDEO_CLIPMAP_SIZE (128 * 625)
};
struct video_buffer
{
void *base;
int height,width;
int depth;
int bytesperline;
};
struct video_mmap
{
unsigned int frame; /* Frame (0 - n) for double buffer */
int height,width;
unsigned int format; /* should be VIDEO_PALETTE_* */
};
struct video_mbuf
{
int size; /* Total memory to map */
int frames; /* Frames */
int offsets[32];
};
struct vbi_format {
uint32_t sampling_rate; /* in Hz */
uint32_t samples_per_line;
uint32_t sample_format; /* VIDEO_PALETTE_RAW only (1 byte) */
int32_t start[2]; /* starting line for each frame */
uint32_t count[2]; /* count of lines for each frame */
uint32_t flags;
#define VBI_UNSYNC 1 /* can distingues between top/bottom field */
#define VBI_INTERLACED 2 /* lines are interlaced */
};
#define VIDIOCGCAP _IOR('v',1,struct video_capability) /* Get capabilities */
#define VIDIOCGCHAN _IOWR('v',2,struct video_channel) /* Get channel info (sources) */
#define VIDIOCSCHAN _IOW('v',3,struct video_channel) /* Set channel */
#define VIDIOCGTUNER _IOWR('v',4,struct video_tuner) /* Get tuner abilities */
#define VIDIOCSTUNER _IOW('v',5,struct video_tuner) /* Tune the tuner for the current channel */
#define VIDIOCGPICT _IOR('v',6,struct video_picture) /* Get picture properties */
#define VIDIOCSPICT _IOW('v',7,struct video_picture) /* Set picture properties */
#define VIDIOCCAPTURE _IOW('v',8,int) /* Start, end capture */
#define VIDIOCGWIN _IOR('v',9, struct video_window) /* Get the video overlay window */
#define VIDIOCSWIN _IOW('v',10, struct video_window) /* Set the video overlay window - passes clip list for hardware smarts , chromakey etc */
#define VIDIOCGFBUF _IOR('v',11, struct video_buffer) /* Get frame buffer */
#define VIDIOCSFBUF _IOW('v',12, struct video_buffer) /* Set frame buffer - root only */
#define VIDIOCGFREQ _IOR('v',14, unsigned long) /* Set tuner */
#define VIDIOCSFREQ _IOW('v',15, unsigned long) /* Set tuner */
#define VIDIOCGAUDIO _IOR('v',16, struct video_audio) /* Get audio info */
#define VIDIOCSAUDIO _IOW('v',17, struct video_audio) /* Audio source, mute etc */
#define VIDIOCSYNC _IOW('v',18, int) /* Sync with mmap grabbing */
#define VIDIOCMCAPTURE _IOW('v',19, struct video_mmap) /* Grab frames */
#define VIDIOCGMBUF _IOR('v',20, struct video_mbuf) /* Memory map buffer info */
#define VIDIOCGVBIFMT _IOR('v',28, struct vbi_format) /* Get VBI information */
#define VIDIOCSVBIFMT _IOW('v',29, struct vbi_format) /* Set VBI information */
#endif

75
include/libv4l1.h Normal file
View File

@@ -0,0 +1,75 @@
/*
# (C) 2008 Hans de Goede <hdegoede@redhat.com>
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 2.1 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
*/
#ifndef __LIBV4L1_H
#define __LIBV4L1_H
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#include <stdio.h>
#include <stdint.h>
#include <unistd.h>
#include <libv4l1-videodev.h>
#if HAVE_VISIBILITY
#define LIBV4L_PUBLIC __attribute__ ((visibility("default")))
#else
#define LIBV4L_PUBLIC
#endif
/* Point this to a FILE opened for writing when you want to log error and
status messages to a file, when NULL errors will get send to stderr */
LIBV4L_PUBLIC extern FILE *v4l1_log_file;
/* Just like your regular open/close/etc, except that when opening a v4l2
capture only device, full v4l1 emulation is done including emulating the
often not implemented in v4l2 drivers CGMBUF ioctl and v4l1 style mmap call
in userspace.
Format conversion is done if necessary when capturing. That is if you
(try to) set a capture format which is not supported by the cam, but is
supported by libv4lconvert then SPICT will succeed and on SYNC / read the
data will be converted for you and returned in the request format.
Note that currently libv4l1 depends on the kernel v4l1 compatibility layer
for: 1) Devices which are not capture only, 2) Emulation of many basic
v4l1 ioctl's which require no driver specific handling.
Note that no functionality is added to v4l1 devices, so if for example an
obscure v4l1 device is opened which only supports some weird capture format
then libv4l1 will not be of any help (in this case it would be best to get
the driver converted to v4l2, as v4l2 has been designed to include weird
capture formats, like hw specific bayer compression methods).
*/
LIBV4L_PUBLIC int v4l1_open(const char *file, int oflag, ...);
LIBV4L_PUBLIC int v4l1_close(int fd);
LIBV4L_PUBLIC int v4l1_dup(int fd);
LIBV4L_PUBLIC int v4l1_ioctl(int fd, unsigned long int request, ...);
LIBV4L_PUBLIC ssize_t v4l1_read(int fd, void *buffer, size_t n);
LIBV4L_PUBLIC void *v4l1_mmap(void *start, size_t length, int prot, int flags,
int fd, int64_t offset);
LIBV4L_PUBLIC int v4l1_munmap(void *_start, size_t length);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif

116
include/libv4l2.h Normal file
View File

@@ -0,0 +1,116 @@
/*
# (C) 2008 Hans de Goede <hdegoede@redhat.com>
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 2.1 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
*/
#ifndef __LIBV4L2_H
#define __LIBV4L2_H
#include <stdio.h>
#include <unistd.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#if HAVE_VISIBILITY
#define LIBV4L_PUBLIC __attribute__ ((visibility("default")))
#else
#define LIBV4L_PUBLIC
#endif
/* Point this to a FILE opened for writing when you want to log error and
status messages to a file, when NULL errors will get send to stderr */
LIBV4L_PUBLIC extern FILE *v4l2_log_file;
/* Just like your regular open/close/etc, except that format conversion is
done if necessary when capturing. That is if you (try to) set a capture
format which is not supported by the cam, but is supported by libv4lconvert,
then the try_fmt / set_fmt will succeed as if the cam supports the format
and on dqbuf / read the data will be converted for you and returned in
the request format. enum_fmt will also report support for the formats to
which conversion is possible.
Another difference is that you can make v4l2_read() calls even on devices
which do not support the regular read() method.
Note the device name passed to v4l2_open must be of a video4linux2 device,
if it is anything else (including a video4linux1 device), v4l2_open will
fail.
Note that the argument to v4l2_ioctl after the request must be a valid
memory address of structure of the appropriate type for the request (for
v4l2 requests which expect a structure address). Passing in NULL or an
invalid memory address will not lead to failure with errno being EFAULT,
as it would with a real ioctl, but will cause libv4l2 to break, and you
get to keep both pieces.
*/
LIBV4L_PUBLIC int v4l2_open(const char *file, int oflag, ...);
LIBV4L_PUBLIC int v4l2_close(int fd);
LIBV4L_PUBLIC int v4l2_dup(int fd);
LIBV4L_PUBLIC int v4l2_ioctl(int fd, unsigned long int request, ...);
LIBV4L_PUBLIC ssize_t v4l2_read(int fd, void *buffer, size_t n);
LIBV4L_PUBLIC ssize_t v4l2_write(int fd, const void *buffer, size_t n);
LIBV4L_PUBLIC void *v4l2_mmap(void *start, size_t length, int prot, int flags,
int fd, int64_t offset);
LIBV4L_PUBLIC int v4l2_munmap(void *_start, size_t length);
/* Misc utility functions */
/* This function takes a value of 0 - 65535, and then scales that range to
the actual range of the given v4l control id, and then if the cid exists
and is not locked sets the cid to the scaled value.
Normally returns 0, even if the cid did not exist or was locked, returns
non 0 when an other error occurred. */
LIBV4L_PUBLIC int v4l2_set_control(int fd, int cid, int value);
/* This function returns a value of 0 - 65535, scaled to from the actual range
of the given v4l control id. When the cid does not exist, or could not be
accessed -1 is returned. */
LIBV4L_PUBLIC int v4l2_get_control(int fd, int cid);
/* "low level" access functions, these functions allow somewhat lower level
access to libv4l2 (currently there only is v4l2_fd_open here) */
/* Flags for v4l2_fd_open's v4l2_flags argument */
/* Disable all format conversion done by libv4l2, this includes the software
whitebalance, gamma correction, flipping, etc. libv4lconvert does. Use this
if you want raw frame data, but still want the additional error checks and
the read() emulation libv4l2 offers. */
#define V4L2_DISABLE_CONVERSION 0x01
/* This flag is *OBSOLETE*, since version 0.5.98 libv4l *always* reports
emulated formats to ENUM_FMT, except when conversion is disabled. */
#define V4L2_ENABLE_ENUM_FMT_EMULATION 0x02
/* v4l2_fd_open: open an already opened fd for further use through
v4l2lib and possibly modify libv4l2's default behavior through the
v4l2_flags argument.
Returns fd on success, -1 if the fd is not suitable for use through libv4l2
(note the fd is left open in this case). */
LIBV4L_PUBLIC int v4l2_fd_open(int fd, int v4l2_flags);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif

343
include/libv4l2rds.h Normal file
View File

@@ -0,0 +1,343 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
/*
* Copyright 2012 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
* Author: Konke Radlow <koradlow@gmail.com>
*/
#ifndef __LIBV4L2RDS
#define __LIBV4L2RDS
#include <stdbool.h>
#include <stdint.h>
#if defined(__OpenBSD__)
#include <sys/videoio.h>
#else
#include <linux/videodev2.h>
#endif
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#if HAVE_VISIBILITY
#define LIBV4L_PUBLIC __attribute__ ((visibility("default")))
#else
#define LIBV4L_PUBLIC
#endif
/* used to define the current version (version field) of the v4l2_rds struct */
#define V4L2_RDS_VERSION (2)
/* Constants used to define the size of arrays used to store RDS information */
#define MAX_ODA_CNT 18 /* there are 16 groups each with type a or b. Of these
* 32 distinct groups, 18 can be used for ODA purposes */
#define MAX_AF_CNT 25 /* AF Method A allows a maximum of 25 AFs to be defined
* AF Method B does not impose a limit on the number of AFs
* but it is not fully supported at the moment and will
* not receive more than 25 AFs */
#define MAX_TMC_ADDITIONAL 28 /* 28 is the maximal possible number of fields.
* Additional data is limited to 112 bit, and the smallest
* optional tuple has a size of 4 bit (4 bit identifier +
* 0 bits of data) */
#define MAX_TMC_ALT_STATIONS 32 /* defined by ISO 14819-1:2003, 7.5.3.3 */
#define MAX_TMC_AF_CNT 4 /* limit for the numbers of AFs stored per alternative TMC
* station. This value is not defined by the standard, but based on observation
* of real-world RDS-TMC streams. The maximum encountered number of AFs per
* station during testing was 2 */
#define MAX_EON_CNT 20 /* Maximal number of entries in the EON table (for storing
* information about other radio stations, broadcasted by the current station).
* This value is not defined by the standard, but based on observation
* of real-world RDS-TMC streams. EON doesn't seem to be a widely used feature
* and the maximum number of EON encountered during testing was 8 */
/* Define Constants for the possible types of RDS information
* used to address the relevant bit in the valid_fields bitmask */
#define V4L2_RDS_PI 0x01 /* Program Identification */
#define V4L2_RDS_PTY 0x02 /* Program Type */
#define V4L2_RDS_TP 0x04 /* Traffic Program */
#define V4L2_RDS_PS 0x08 /* Program Service Name */
#define V4L2_RDS_TA 0x10 /* Traffic Announcement */
#define V4L2_RDS_DI 0x20 /* Decoder Information */
#define V4L2_RDS_MS 0x40 /* Music / Speech flag */
#define V4L2_RDS_PTYN 0x80 /* Program Type Name */
#define V4L2_RDS_RT 0x100 /* Radio-Text */
#define V4L2_RDS_TIME 0x200 /* Date and Time information */
#define V4L2_RDS_TMC 0x400 /* TMC availability */
#define V4L2_RDS_AF 0x800 /* AF (alternative freq) available */
#define V4L2_RDS_ECC 0x1000 /* Extended County Code */
#define V4L2_RDS_LC 0x2000 /* Language Code */
#define V4L2_RDS_TMC_SG 0x4000 /* RDS-TMC single group */
#define V4L2_RDS_TMC_MG 0x8000 /* RDS-TMC multi group */
#define V4L2_RDS_TMC_SYS 0x10000 /* RDS-TMC system information */
#define V4L2_RDS_EON 0x20000 /* Enhanced Other Network Info */
#define V4L2_RDS_LSF 0x40000 /* Linkage information */
#define V4L2_RDS_TMC_TUNING 0x80000 /* RDS-TMC tuning information */
/* Define Constants for the state of the RDS decoding process
* used to address the relevant bit in the decode_information bitmask */
#define V4L2_RDS_GROUP_NEW 0x01 /* New group received */
#define V4L2_RDS_ODA 0x02 /* Open Data Group announced */
/* Decoder Information (DI) codes
* used to decode the DI information according to the RDS standard */
#define V4L2_RDS_FLAG_STEREO 0x01
#define V4L2_RDS_FLAG_ARTIFICIAL_HEAD 0x02
#define V4L2_RDS_FLAG_COMPRESSED 0x04
#define V4L2_RDS_FLAG_DYNAMIC_PTY 0x08
/* TMC related codes
* used to extract TMC fields from RDS-TMC groups
* see ISO 14819-1:2003, Figure 2 - RDS-TMC single-grp full message structure */
#define V4L2_TMC_TUNING_INFO 0x10 /* Bit 4 indicates Tuning Info / User msg */
#define V4L2_TMC_SINGLE_GROUP 0x08 /* Bit 3 indicates Single / Multi-group msg */
/* struct to encapsulate one complete RDS group */
/* This structure is used internally to store data until a complete RDS
* group was received and group id dependent decoding can be done.
* It is also used to provide external access to uninterpreted RDS groups
* when manual decoding is required (e.g. special ODA types) */
struct v4l2_rds_group {
uint16_t pi; /* Program Identification */
char group_version; /* group version ('A' / 'B') */
uint8_t group_id; /* group number (0..16) */
/* uninterpreted data blocks for decoding (e.g. ODA) */
uint8_t data_b_lsb;
uint8_t data_c_msb;
uint8_t data_c_lsb;
uint8_t data_d_msb;
uint8_t data_d_lsb;
};
/* struct to encapsulate some statistical information about the decoding process */
struct v4l2_rds_statistics {
uint32_t block_cnt; /* total amount of received blocks */
uint32_t group_cnt; /* total amount of successfully
* decoded groups */
uint32_t block_error_cnt; /* blocks that were marked as erroneous
* and had to be dropped */
uint32_t group_error_cnt; /* group decoding processes that had to be
* aborted because of erroneous blocks
* or wrong order of blocks */
uint32_t block_corrected_cnt; /* blocks that contained 1-bit errors
* which were corrected */
uint32_t group_type_cnt[16]; /* number of occurrence for each
* defined RDS group */
};
/* struct to encapsulate the definition of one ODA (Open Data Application) type */
struct v4l2_rds_oda {
uint8_t group_id; /* RDS group used to broadcast this ODA */
char group_version; /* group version (A / B) for this ODA */
uint16_t aid; /* Application Identification for this ODA,
* AIDs are centrally administered by the
* RDS Registration Office (rds.org.uk) */
};
/* struct to encapsulate an array of all defined ODA types for a channel */
/* This structure will grow with ODA announcements broadcasted in type 3A
* groups, that were verified not to be no duplicates or redefinitions */
struct v4l2_rds_oda_set {
uint8_t size; /* number of ODAs defined by this channel */
struct v4l2_rds_oda oda[MAX_ODA_CNT];
};
/* struct to encapsulate an array of Alternative Frequencies for a channel */
/* Every channel can send out AFs for his program. The number of AFs that
* will be broadcasted is announced by the channel */
struct v4l2_rds_af_set {
uint8_t size; /* size of the set (might be smaller
* than the announced size) */
uint8_t announced_af; /* number of announced AF */
uint32_t af[MAX_AF_CNT]; /* AFs defined in Hz */
};
/* struct to encapsulate one entry in the EON table (Enhanced Other Network) */
struct v4l2_rds_eon {
uint32_t valid_fields;
uint16_t pi;
uint8_t ps[9];
uint8_t pty;
bool ta;
bool tp;
uint16_t lsf; /* Linkage Set Number */
struct v4l2_rds_af_set af;
};
/* struct to encapsulate a table of EON information */
struct v4l2_rds_eon_set {
uint8_t size; /* size of the table */
uint8_t index; /* current position in the table */
struct v4l2_rds_eon eon[MAX_EON_CNT]; /* Information about other
* radio channels */
};
/* struct to encapsulate alternative frequencies (AFs) for RDS-TMC stations.
* AFs listed in af[] can be used unconditionally.
* AFs listed in mapped_af[n] should only be used if the current
* tuner frequency matches the value in mapped_af_tuning[n] */
struct v4l2_tmc_alt_freq {
uint8_t af_size; /* number of known AFs */
uint8_t af_index;
uint8_t mapped_af_size; /* number of mapped AFs */
uint8_t mapped_af_index;
uint32_t af[MAX_TMC_AF_CNT]; /* AFs defined in Hz */
uint32_t mapped_af[MAX_TMC_AF_CNT]; /* mapped AFs defined in Hz */
uint32_t mapped_af_tuning[MAX_TMC_AF_CNT]; /* mapped AFs defined in Hz */
};
/* struct to encapsulate information about stations carrying RDS-TMC services */
struct v4l2_tmc_station {
uint16_t pi;
uint8_t ltn; /* database-ID of ON */
uint8_t msg; /* msg parameters of ON */
uint8_t sid; /* service-ID of ON */
struct v4l2_tmc_alt_freq afi;
};
/* struct to encapsulate tuning information for TMC */
struct v4l2_tmc_tuning {
uint8_t station_cnt; /* number of announced alternative stations */
uint8_t index;
struct v4l2_tmc_station station[MAX_TMC_ALT_STATIONS]; /* information
* about other stations carrying the same RDS-TMC service */
};
/* struct to encapsulate an additional data field in a TMC message */
struct v4l2_tmc_additional {
uint8_t label;
uint16_t data;
};
/* struct to encapsulate an arbitrary number of additional data fields
* belonging to one TMC message */
struct v4l2_tmc_additional_set {
uint8_t size;
struct v4l2_tmc_additional fields[MAX_TMC_ADDITIONAL];
};
/* struct to encapsulate a decoded TMC message with optional additional
* data field (in case of a multi-group TMC message) */
struct v4l2_rds_tmc_msg {
uint8_t length; /* length of multi-group message (0..4) */
uint8_t sid; /* service identifier at time of reception */
uint8_t extent;
uint8_t dp; /* duration and persistence */
uint16_t event; /* TMC event code */
uint16_t location; /* TMC event location */
bool follow_diversion; /* indicates if the driver is adviced to
* follow the diversion */
bool neg_direction; /* indicates negative / positive direction */
/* decoded additional information (only available in multi-group
* messages) */
struct v4l2_tmc_additional_set additional;
};
/* struct to encapsulate all TMC related information, including TMC System
* Information, TMC Tuning information and a buffer for the last decoded
* TMC messages */
struct v4l2_rds_tmc {
uint8_t ltn; /* location_table_number */
bool afi; /* alternative frequency indicator */
bool enhanced_mode; /* mode of transmission,
* if false -> basic => gaps between tmc groups
* gap defines timing behavior
* if true -> enhanced => t_a, t_w and t_d
* define timing behavior of tmc groups */
uint8_t mgs; /* message geographical scope */
uint8_t sid; /* service identifier (unique ID on national level) */
uint8_t gap; /* Gap parameters */
uint8_t t_a; /* activity time (only if mode = enhanced) */
uint8_t t_w; /* window time (only if mode = enhanced */
uint8_t t_d; /* delay time (only if mode = enhanced */
uint8_t spn[9]; /* service provider name */
struct v4l2_rds_tmc_msg tmc_msg;
/* tuning information for alternative service providers */
struct v4l2_tmc_tuning tuning;
};
/* struct to encapsulate state and RDS information for current decoding process */
/* This is the structure that will be used by external applications, to
* communicate with the library and get access to RDS data */
struct v4l2_rds {
/** state information **/
uint32_t decode_information; /* state of decoding process */
uint32_t valid_fields; /* currently valid info fields
* of this structure */
/** RDS info fields **/
bool is_rbds; /* use RBDS standard version of LUTs */
uint16_t pi; /* Program Identification */
uint8_t ps[9]; /* Program Service Name, UTF-8 encoding,
* '\0' terminated */
uint8_t pty; /* Program Type */
uint8_t ptyn[9]; /* Program Type Name, UTF-8 encoding,
* '\0' terminated */
bool ptyn_ab_flag; /* PTYN A/B flag (toggled), to signal
* change of PTYN */
uint8_t rt_length; /* length of RT string */
uint8_t rt[65]; /* Radio-Text string, UTF-8 encoding,
* '\0' terminated */
bool rt_ab_flag; /* RT A/B flag (toggled), to signal
* transmission of new RT */
bool ta; /* Traffic Announcement */
bool tp; /* Traffic Program */
bool ms; /* Music / Speech flag */
uint8_t di; /* Decoder Information */
uint8_t ecc; /* Extended Country Code */
uint8_t lc; /* Language Code */
time_t time; /* local time and date of transmission */
struct v4l2_rds_statistics rds_statistics;
struct v4l2_rds_oda_set rds_oda; /* Open Data Services */
struct v4l2_rds_af_set rds_af; /* Alternative Frequencies */
struct v4l2_rds_eon_set rds_eon; /* EON information */
struct v4l2_rds_tmc tmc; /* TMC information */
};
/* v4l2_rds_init() - initializes a new decoding process
* @is_rbds: defines which standard is used: true=RBDS, false=RDS
*
* initialize a new instance of the RDS-decoding struct and return
* a handle containing state and RDS information, used to interact
* with the library functions */
LIBV4L_PUBLIC struct v4l2_rds *v4l2_rds_create(bool is_rbds);
/* frees all memory allocated for the RDS-decoding struct */
LIBV4L_PUBLIC void v4l2_rds_destroy(struct v4l2_rds *handle);
/* resets the RDS information in the handle to initial values
* e.g. can be used when radio channel is changed
* @reset_statistics: true = set all statistic values to 0, false = keep them untouched */
LIBV4L_PUBLIC void v4l2_rds_reset(struct v4l2_rds *handle, bool reset_statistics);
/* adds a raw RDS block to decode it into RDS groups
* @return: bitmask with with updated fields set to 1
* @rds_data: 3 bytes of raw RDS data, obtained by calling read()
* on RDS capable V4L2 devices */
LIBV4L_PUBLIC uint32_t v4l2_rds_add(struct v4l2_rds *handle, struct v4l2_rds_data *rds_data);
/*
* group of functions to translate numerical RDS data into strings
*
* return program description string defined in the RDS/RBDS Standard
* ! return value depends on selected Standard !*/
LIBV4L_PUBLIC const char *v4l2_rds_get_pty_str(const struct v4l2_rds *handle);
LIBV4L_PUBLIC const char *v4l2_rds_get_language_str(const struct v4l2_rds *handle);
LIBV4L_PUBLIC const char *v4l2_rds_get_country_str(const struct v4l2_rds *handle);
LIBV4L_PUBLIC const char *v4l2_rds_get_coverage_str(const struct v4l2_rds *handle);
/* returns a pointer to the last decoded RDS group, in order to give raw
* access to RDS data if it is required (e.g. ODA decoding) */
LIBV4L_PUBLIC const struct v4l2_rds_group *v4l2_rds_get_group
(const struct v4l2_rds *handle);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif

164
include/libv4lconvert.h Normal file
View File

@@ -0,0 +1,164 @@
/*
# (C) 2008 Hans de Goede <hdegoede@redhat.com>
#
# SPDX-FileCopyrightText: Copyright (c) 2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: LGPL-2.1-or-later
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 2.1 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
*/
#ifndef __LIBV4LCONVERT_H
#define __LIBV4LCONVERT_H
/* These headers are not needed by us, but by linux/videodev2.h,
which is broken on some systems and doesn't include them itself :( */
#ifdef linux
#include <sys/time.h>
#include <linux/types.h>
#include <linux/ioctl.h>
#endif
#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__OpenBSD__)
#include <sys/time.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#endif
/* end broken header workaround includes */
#if defined(__OpenBSD__)
#include <sys/videoio.h>
#else
#include <linux/videodev2.h>
#endif
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#if HAVE_VISIBILITY
#define LIBV4L_PUBLIC __attribute__ ((visibility("default")))
#else
#define LIBV4L_PUBLIC
#endif
struct libv4l_dev_ops;
struct v4lconvert_data;
LIBV4L_PUBLIC const struct libv4l_dev_ops *v4lconvert_get_default_dev_ops(void);
LIBV4L_PUBLIC struct v4lconvert_data *v4lconvert_create(int fd);
LIBV4L_PUBLIC struct v4lconvert_data *v4lconvert_create_with_dev_ops(int fd,
void *dev_ops_priv, const struct libv4l_dev_ops *dev_ops);
LIBV4L_PUBLIC void v4lconvert_destroy(struct v4lconvert_data *data);
/* When doing flipping / rotating / video-processing, only supported
destination formats can be used (as flipping / rotating / video-processing
is not supported on other formats). This function can be used to query
if that is the case. */
LIBV4L_PUBLIC int v4lconvert_supported_dst_fmt_only(
struct v4lconvert_data *data);
/* With regards to dest_fmt just like VIDIOC_TRY_FMT, except that the try
format will succeed and return the requested V4L2_PIX_FMT_foo in dest_fmt if
the cam has a format from which v4lconvert can convert to dest_fmt.
The real format to which the cam should be set is returned through src_fmt
when not NULL.
Note that just like the real VIDIOC_TRY_FMT this function will change the
dest_fmt when not supported. This includes changing it to a supported
destination format when trying a native format of the camera and
v4lconvert_supported_dst_fmt_only() returns true. */
LIBV4L_PUBLIC int v4lconvert_try_format(struct v4lconvert_data *data,
struct v4l2_format *dest_fmt, /* in / out */
struct v4l2_format *src_fmt); /* out */
/* Like VIDIOC_ENUM_FMT, but the emulated formats are added at the end of the
list, except if flipping / processing is active for the device, then only
supported destination formats are listed */
LIBV4L_PUBLIC int v4lconvert_enum_fmt(struct v4lconvert_data *data,
struct v4l2_fmtdesc *fmt);
/* Is conversion necessary or can the app use the data directly? */
LIBV4L_PUBLIC int v4lconvert_needs_conversion(struct v4lconvert_data *data,
const struct v4l2_format *src_fmt, /* in */
const struct v4l2_format *dest_fmt); /* in */
/* This function does the following conversions:
- format conversion
- cropping
if enabled:
- processing (auto whitebalance, auto gain, gamma correction)
- horizontal/vertical flipping
- 90 degree (clockwise) rotation
NOTE: the last 3 steps are enabled/disabled depending on
- the internal device list
- the state of the (software emulated) image controls
Therefore this function should
- not be used when getting the frames from libv4l
- be called only once per frame
Otherwise this may result in unintended double conversions !
Returns the amount of bytes written to dest and -1 on error */
LIBV4L_PUBLIC int v4lconvert_convert(struct v4lconvert_data *data,
const struct v4l2_format *src_fmt, /* in */
const struct v4l2_format *dest_fmt, /* in */
unsigned char *src, int src_size, unsigned char *dest, int dest_size);
/* get a string describing the last error */
LIBV4L_PUBLIC const char *v4lconvert_get_error_message(struct v4lconvert_data *data);
/* Just like VIDIOC_ENUM_FRAMESIZE, except that the framesizes of emulated
formats can be enumerated as well. */
LIBV4L_PUBLIC int v4lconvert_enum_framesizes(struct v4lconvert_data *data,
struct v4l2_frmsizeenum *frmsize);
/* Just like VIDIOC_ENUM_FRAMEINTERVALS, except that the intervals of emulated
formats can be enumerated as well. */
LIBV4L_PUBLIC int v4lconvert_enum_frameintervals(struct v4lconvert_data *data,
struct v4l2_frmivalenum *frmival);
/* Pass calls to query, get and set video controls to the libv4lcontrol class */
LIBV4L_PUBLIC int v4lconvert_vidioc_queryctrl(struct v4lconvert_data *data,
void *arg);
LIBV4L_PUBLIC int v4lconvert_vidioc_g_ctrl(struct v4lconvert_data *data,
void *arg);
LIBV4L_PUBLIC int v4lconvert_vidioc_s_ctrl(struct v4lconvert_data *data,
void *arg);
LIBV4L_PUBLIC int v4lconvert_vidioc_g_ext_ctrls(struct v4lconvert_data *data,
void *arg);
LIBV4L_PUBLIC int v4lconvert_vidioc_try_ext_ctrls(struct v4lconvert_data *data,
void *arg);
LIBV4L_PUBLIC int v4lconvert_vidioc_s_ext_ctrls(struct v4lconvert_data *data,
void *arg);
/* Is the passed in pixelformat supported as destination format? */
LIBV4L_PUBLIC int v4lconvert_supported_dst_format(unsigned int pixelformat);
/* Get/set the no fps libv4lconvert uses to decide if a compressed format
must be used as src fmt to stay within the bus bandwidth */
LIBV4L_PUBLIC int v4lconvert_get_fps(struct v4lconvert_data *data);
LIBV4L_PUBLIC void v4lconvert_set_fps(struct v4lconvert_data *data, int fps);
/* Fixup bytesperline and sizeimage for supported destination formats */
LIBV4L_PUBLIC void v4lconvert_fixup_fmt(struct v4l2_format *fmt);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif

68
libv4l2/Makefile Normal file
View File

@@ -0,0 +1,68 @@
###############################################################################
# SPDX-FileCopyrightText: Copyright (c) 2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: LGPL-2.1-or-later
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 2.1 of the License, or
# (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this program. If not, see
# <http://www.gnu.org/licenses/>.
###############################################################################
SO_NAME := libnvv4l2.so
SRCS := libv4l2.c log.c v4l2convert.c v4l2-plugin.c
INCLUDES += -I./ -I../include
OBJS := $(SRCS:.c=.o)
CFLAGS := -fPIC
MACHINE = $(shell uname -m)
ifeq ($(MACHINE),x86_64)
CFLAGS += -DLIBV4L2_PLUGIN_DIR_PATH_X86
DEST_DIR ?= /opt/nvidia/deepstream/deepstream-4.0/lib/
SYM_LINK_DIR = $(DEST_DIR)
else
DEST_DIR ?= /usr/lib/$(MACHINE)-linux-gnu/nvidia
SYM_LINK_DIR = $(shell realpath $(DEST_DIR)/..)
endif
LDFLAGS := -L$(DEST_DIR) -Wl,-soname,libv4l2.so.0
LIBS := -lv4lconvert -ldl
all: $(SO_NAME)
%.o: %.c
$(CC) -c $< $(CFLAGS) $(INCLUDES) -o $@
$(SO_NAME): $(OBJS)
$(CC) -shared -o $(SO_NAME) $(OBJS) $(LIBS) $(LDFLAGS)
.PHONY: install
install: $(SO_NAME)
cp -vp $(SO_NAME) $(DEST_DIR)
if [ "$(MACHINE)" = "aarch64" ]; then \
ln -sf nvidia/$(SO_NAME) $(SYM_LINK_DIR)/libv4l2.so.0.0.999999 ; \
else \
ln -sf $(SO_NAME) $(SYM_LINK_DIR)/libv4l2.so.0.0.999999 ; \
fi
ln -sf libv4l2.so.0.0.999999 \
$(SYM_LINK_DIR)/libv4l2.so
ln -sf libv4l2.so.0.0.999999 \
${SYM_LINK_DIR}/libv4l2.so.0
.PHONY: clean
clean:
rm -rf $(OBJS) $(SO_NAME)

32
libv4l2/Makefile.am Normal file
View File

@@ -0,0 +1,32 @@
if WITH_DYN_LIBV4L
lib_LTLIBRARIES = libv4l2.la
include_HEADERS = ../include/libv4l2.h ../include/libv4l-plugin.h
pkgconfig_DATA = libv4l2.pc
LIBV4L2_VERSION = -version-info 0
if WITH_V4L_WRAPPERS
libv4l2priv_LTLIBRARIES = v4l2convert.la
install-exec-hook:
$(mkdir_p) $(DESTDIR)/$(libdir)
(cd $(DESTDIR)/$(libdir) && rm -f v4l2convert.so && $(LN_S) $(libv4l2subdir)/v4l2convert.so v4l2convert.so)
endif
else
noinst_LTLIBRARIES = libv4l2.la
endif
libv4l2_la_SOURCES = libv4l2.c log.c libv4l2-priv.h
if WITH_V4L_PLUGINS
libv4l2_la_SOURCES += v4l2-plugin.c
endif
libv4l2_la_CPPFLAGS = $(CFLAG_VISIBILITY) $(ENFORCE_LIBV4L_STATIC)
libv4l2_la_LDFLAGS = $(LIBV4L2_VERSION) -lpthread $(DLOPEN_LIBS) $(ENFORCE_LIBV4L_STATIC)
libv4l2_la_LIBADD = ../libv4lconvert/libv4lconvert.la
v4l2convert_la_SOURCES = v4l2convert.c
v4l2convert_la_LIBADD = libv4l2.la
v4l2convert_la_LDFLAGS = -avoid-version -module -shared -export-dynamic
v4l2convert_la_LIBTOOLFLAGS = --tag=disable-static
EXTRA_DIST = Android.mk v4l2-plugin-android.c

38
libv4l2/Makefile.dGPU Normal file
View File

@@ -0,0 +1,38 @@
###############################################################################
#
# SPDX-FileCopyrightText: Copyright (c) 2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: LicenseRef-NvidiaProprietary
#
# NVIDIA CORPORATION, its affiliates and licensors retain all intellectual
# property and proprietary rights in and to this material, related
# documentation and any modifications thereto. Any use, reproduction,
# disclosure or distribution of this material and related documentation
# without an express license agreement from NVIDIA CORPORATION or
# its affiliates is strictly prohibited.
#
###############################################################################
CC:=gcc
TARGET_NAME:= libnvv4l2.so
SRCS := libv4l2.c log.c v4l2convert.c v4l2-plugin.c
INC_PATHS := ./ ../include ../../include
CFLAGS := -fPIC
CFLAGS += -DLIBV4L2_PLUGIN_DIR_PATH_X86
IGNORE_DS_PACKAGE_NAMING:=1
LDFLAGS:= -shared
LIBS:= -lv4lconvert -ldl -Wl,-soname,libv4l2.so.0
#IS_V4L2_LIB:=1
PACKAGE_BINARY_IN_DS:=1
BUILD_DIR:=../../../../../deepstream/sdk/build/libs/libv4l/
include ../../../../../deepstream/sdk/Rules.mk
install::
ln -sf $(INSTALL_DIR)/$(TARGET_NAME) /usr/lib/x86_64-linux-gnu/libv4l2.so.0.0.99999
ldconfig

966
libv4l2/Makefile.in Normal file
View File

@@ -0,0 +1,966 @@
# Makefile.in generated by automake 1.16.5 from Makefile.am.
# @configure_input@
# Copyright (C) 1994-2021 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
VPATH = @srcdir@
am__is_gnu_make = { \
if test -z '$(MAKELEVEL)'; then \
false; \
elif test -n '$(MAKE_HOST)'; then \
true; \
elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
true; \
else \
false; \
fi; \
}
am__make_running_with_option = \
case $${target_option-} in \
?) ;; \
*) echo "am__make_running_with_option: internal error: invalid" \
"target option '$${target_option-}' specified" >&2; \
exit 1;; \
esac; \
has_opt=no; \
sane_makeflags=$$MAKEFLAGS; \
if $(am__is_gnu_make); then \
sane_makeflags=$$MFLAGS; \
else \
case $$MAKEFLAGS in \
*\\[\ \ ]*) \
bs=\\; \
sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
| sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
esac; \
fi; \
skip_next=no; \
strip_trailopt () \
{ \
flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
}; \
for flg in $$sane_makeflags; do \
test $$skip_next = yes && { skip_next=no; continue; }; \
case $$flg in \
*=*|--*) continue;; \
-*I) strip_trailopt 'I'; skip_next=yes;; \
-*I?*) strip_trailopt 'I';; \
-*O) strip_trailopt 'O'; skip_next=yes;; \
-*O?*) strip_trailopt 'O';; \
-*l) strip_trailopt 'l'; skip_next=yes;; \
-*l?*) strip_trailopt 'l';; \
-[dEDm]) skip_next=yes;; \
-[JT]) skip_next=yes;; \
esac; \
case $$flg in \
*$$target_option*) has_opt=yes; break;; \
esac; \
done; \
test $$has_opt = yes
am__make_dryrun = (target_option=n; $(am__make_running_with_option))
am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkglibexecdir = $(libexecdir)/@PACKAGE@
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
@WITH_V4L_PLUGINS_TRUE@am__append_1 = v4l2-plugin.c
subdir = lib/libv4l2
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/ac_define_dir.m4 \
$(top_srcdir)/m4/ax_prog_doxygen.m4 \
$(top_srcdir)/m4/ax_pthread.m4 $(top_srcdir)/m4/libtool.m4 \
$(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
$(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
$(top_srcdir)/m4/mode_t.m4 $(top_srcdir)/m4/visibility.m4 \
$(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
DIST_COMMON = $(srcdir)/Makefile.am $(am__include_HEADERS_DIST) \
$(am__DIST_COMMON)
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES = libv4l2.pc
CONFIG_CLEAN_VPATH_FILES =
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
am__vpath_adj = case $$p in \
$(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
*) f=$$p;; \
esac;
am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
am__install_max = 40
am__nobase_strip_setup = \
srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
am__nobase_strip = \
for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
am__nobase_list = $(am__nobase_strip_setup); \
for p in $$list; do echo "$$p $$p"; done | \
sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
$(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
if (++n[$$2] == $(am__install_max)) \
{ print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
END { for (dir in files) print dir, files[dir] }'
am__base_list = \
sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
am__uninstall_files_from_dir = { \
test -z "$$files" \
|| { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
|| { echo " ( cd '$$dir' && rm -f" $$files ")"; \
$(am__cd) "$$dir" && rm -f $$files; }; \
}
am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(libv4l2privdir)" \
"$(DESTDIR)$(pkgconfigdir)" "$(DESTDIR)$(includedir)"
LTLIBRARIES = $(lib_LTLIBRARIES) $(libv4l2priv_LTLIBRARIES) \
$(noinst_LTLIBRARIES)
libv4l2_la_DEPENDENCIES = ../libv4lconvert/libv4lconvert.la
am__libv4l2_la_SOURCES_DIST = libv4l2.c log.c libv4l2-priv.h \
v4l2-plugin.c
@WITH_V4L_PLUGINS_TRUE@am__objects_1 = libv4l2_la-v4l2-plugin.lo
am_libv4l2_la_OBJECTS = libv4l2_la-libv4l2.lo libv4l2_la-log.lo \
$(am__objects_1)
libv4l2_la_OBJECTS = $(am_libv4l2_la_OBJECTS)
AM_V_lt = $(am__v_lt_@AM_V@)
am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
am__v_lt_0 = --silent
am__v_lt_1 =
libv4l2_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
$(libv4l2_la_LDFLAGS) $(LDFLAGS) -o $@
@WITH_DYN_LIBV4L_FALSE@am_libv4l2_la_rpath =
@WITH_DYN_LIBV4L_TRUE@am_libv4l2_la_rpath = -rpath $(libdir)
v4l2convert_la_DEPENDENCIES = libv4l2.la
am_v4l2convert_la_OBJECTS = v4l2convert_la-v4l2convert.lo
v4l2convert_la_OBJECTS = $(am_v4l2convert_la_OBJECTS)
v4l2convert_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
$(v4l2convert_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link \
$(CCLD) $(AM_CFLAGS) $(CFLAGS) $(v4l2convert_la_LDFLAGS) \
$(LDFLAGS) -o $@
@WITH_DYN_LIBV4L_TRUE@@WITH_V4L_WRAPPERS_TRUE@am_v4l2convert_la_rpath = \
@WITH_DYN_LIBV4L_TRUE@@WITH_V4L_WRAPPERS_TRUE@ -rpath \
@WITH_DYN_LIBV4L_TRUE@@WITH_V4L_WRAPPERS_TRUE@ $(libv4l2privdir)
AM_V_P = $(am__v_P_@AM_V@)
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
am__v_P_0 = false
am__v_P_1 = :
AM_V_GEN = $(am__v_GEN_@AM_V@)
am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
am__v_GEN_0 = @echo " GEN " $@;
am__v_GEN_1 =
AM_V_at = $(am__v_at_@AM_V@)
am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
am__v_at_0 = @
am__v_at_1 =
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
am__maybe_remake_depfiles = depfiles
am__depfiles_remade = ./$(DEPDIR)/libv4l2_la-libv4l2.Plo \
./$(DEPDIR)/libv4l2_la-log.Plo \
./$(DEPDIR)/libv4l2_la-v4l2-plugin.Plo \
./$(DEPDIR)/v4l2convert_la-v4l2convert.Plo
am__mv = mv -f
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
$(AM_CFLAGS) $(CFLAGS)
AM_V_CC = $(am__v_CC_@AM_V@)
am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
am__v_CC_0 = @echo " CC " $@;
am__v_CC_1 =
CCLD = $(CC)
LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
$(AM_LDFLAGS) $(LDFLAGS) -o $@
AM_V_CCLD = $(am__v_CCLD_@AM_V@)
am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
am__v_CCLD_0 = @echo " CCLD " $@;
am__v_CCLD_1 =
SOURCES = $(libv4l2_la_SOURCES) $(v4l2convert_la_SOURCES)
DIST_SOURCES = $(am__libv4l2_la_SOURCES_DIST) \
$(v4l2convert_la_SOURCES)
am__can_run_installinfo = \
case $$AM_UPDATE_INFO_DIR in \
n|no|NO) false;; \
*) (install-info --version) >/dev/null 2>&1;; \
esac
DATA = $(pkgconfig_DATA)
am__include_HEADERS_DIST = ../include/libv4l2.h \
../include/libv4l-plugin.h
HEADERS = $(include_HEADERS)
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
# Read a list of newline-separated strings from the standard input,
# and print each of them once, without duplicates. Input order is
# *not* preserved.
am__uniquify_input = $(AWK) '\
BEGIN { nonempty = 0; } \
{ items[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in items) print i; }; } \
'
# Make sure the list of sources is unique. This is necessary because,
# e.g., the same source file might be shared among _SOURCES variables
# for different programs/libraries.
am__define_uniq_tagged_files = \
list='$(am__tagged_files)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | $(am__uniquify_input)`
am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/libv4l2.pc.in \
$(top_srcdir)/build-aux/depcomp
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
ALSA_CFLAGS = @ALSA_CFLAGS@
ALSA_LIBS = @ALSA_LIBS@
AMTAR = @AMTAR@
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
AR = @AR@
ARGP_LIBS = @ARGP_LIBS@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CFLAG_VISIBILITY = @CFLAG_VISIBILITY@
CLANG = @CLANG@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CSCOPE = @CSCOPE@
CTAGS = @CTAGS@
CXX = @CXX@
CXXCPP = @CXXCPP@
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
DLLTOOL = @DLLTOOL@
DLOPEN_LIBS = @DLOPEN_LIBS@
DOXYGEN_PAPER_SIZE = @DOXYGEN_PAPER_SIZE@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
DX_CONFIG = @DX_CONFIG@
DX_DOCDIR = @DX_DOCDIR@
DX_DOT = @DX_DOT@
DX_DOXYGEN = @DX_DOXYGEN@
DX_DVIPS = @DX_DVIPS@
DX_EGREP = @DX_EGREP@
DX_ENV = @DX_ENV@
DX_FLAG_chi = @DX_FLAG_chi@
DX_FLAG_chm = @DX_FLAG_chm@
DX_FLAG_doc = @DX_FLAG_doc@
DX_FLAG_dot = @DX_FLAG_dot@
DX_FLAG_html = @DX_FLAG_html@
DX_FLAG_man = @DX_FLAG_man@
DX_FLAG_pdf = @DX_FLAG_pdf@
DX_FLAG_ps = @DX_FLAG_ps@
DX_FLAG_rtf = @DX_FLAG_rtf@
DX_FLAG_xml = @DX_FLAG_xml@
DX_HHC = @DX_HHC@
DX_LATEX = @DX_LATEX@
DX_MAKEINDEX = @DX_MAKEINDEX@
DX_PDFLATEX = @DX_PDFLATEX@
DX_PERL = @DX_PERL@
DX_PROJECT = @DX_PROJECT@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
ENFORCE_LIBDVBV5_STATIC = @ENFORCE_LIBDVBV5_STATIC@
ENFORCE_LIBV4L_STATIC = @ENFORCE_LIBV4L_STATIC@
ETAGS = @ETAGS@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
GIT_COMMIT_CNT = @GIT_COMMIT_CNT@
GIT_COMMIT_DATE = @GIT_COMMIT_DATE@
GIT_SHA = @GIT_SHA@
GLU_CFLAGS = @GLU_CFLAGS@
GLU_LIBS = @GLU_LIBS@
GL_CFLAGS = @GL_CFLAGS@
GL_LIBS = @GL_LIBS@
GMSGFMT = @GMSGFMT@
GMSGFMT_015 = @GMSGFMT_015@
GREP = @GREP@
HAVE_VISIBILITY = @HAVE_VISIBILITY@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
INTLLIBS = @INTLLIBS@
INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
IR_KEYTABLE_SYSTEM_DIR = @IR_KEYTABLE_SYSTEM_DIR@
IR_KEYTABLE_USER_DIR = @IR_KEYTABLE_USER_DIR@
JPEG_LIBS = @JPEG_LIBS@
LD = @LD@
LDFLAGS = @LDFLAGS@
LIBBPF_CFLAGS = @LIBBPF_CFLAGS@
LIBBPF_LIBS = @LIBBPF_LIBS@
LIBDVBV5_DOMAIN = @LIBDVBV5_DOMAIN@
LIBELF_CFLAGS = @LIBELF_CFLAGS@
LIBELF_LIBS = @LIBELF_LIBS@
LIBICONV = @LIBICONV@
LIBINTL = @LIBINTL@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LIBUDEV_CFLAGS = @LIBUDEV_CFLAGS@
LIBUDEV_LIBS = @LIBUDEV_LIBS@
LIBV4L1_PRIV_DIR = @LIBV4L1_PRIV_DIR@
LIBV4L2_PLUGIN_DIR = @LIBV4L2_PLUGIN_DIR@
LIBV4L2_PRIV_DIR = @LIBV4L2_PRIV_DIR@
LIBV4LCONVERT_PRIV_DIR = @LIBV4LCONVERT_PRIV_DIR@
LIPO = @LIPO@
LN_S = @LN_S@
LTLIBICONV = @LTLIBICONV@
LTLIBINTL = @LTLIBINTL@
LTLIBOBJS = @LTLIBOBJS@
LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
MAINT = @MAINT@
MAJOR = @MAJOR@
MAKEINFO = @MAKEINFO@
MANIFEST_TOOL = @MANIFEST_TOOL@
MINOR = @MINOR@
MKDIR_P = @MKDIR_P@
MOC = @MOC@
MSGFMT = @MSGFMT@
MSGMERGE = @MSGMERGE@
MSGMERGE_FOR_MSGFMT_OPTION = @MSGMERGE_FOR_MSGFMT_OPTION@
NM = @NM@
NMEDIT = @NMEDIT@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATCH = @PATCH@
PATH_SEPARATOR = @PATH_SEPARATOR@
PKG_CONFIG = @PKG_CONFIG@
PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
POSUB = @POSUB@
PTHREAD_CC = @PTHREAD_CC@
PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
PTHREAD_CXX = @PTHREAD_CXX@
PTHREAD_LIBS = @PTHREAD_LIBS@
QT5GL_CFLAGS = @QT5GL_CFLAGS@
QT5GL_LIBS = @QT5GL_LIBS@
QT5_CFLAGS = @QT5_CFLAGS@
QT5_LIBS = @QT5_LIBS@
QTGL_CFLAGS = @QTGL_CFLAGS@
QTGL_LIBS = @QTGL_LIBS@
QT_CFLAGS = @QT_CFLAGS@
QT_LIBS = @QT_LIBS@
RANLIB = @RANLIB@
RCC = @RCC@
SDL2_CFLAGS = @SDL2_CFLAGS@
SDL2_LIBS = @SDL2_LIBS@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
UIC = @UIC@
USE_NLS = @USE_NLS@
V4L_UTILS_VERSION = @V4L_UTILS_VERSION@
VERSION = @VERSION@
X11_CFLAGS = @X11_CFLAGS@
X11_LIBS = @X11_LIBS@
XGETTEXT = @XGETTEXT@
XGETTEXT_015 = @XGETTEXT_015@
XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_ct_AR = @ac_ct_AR@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
ax_pthread_config = @ax_pthread_config@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
gconvsysdir = @gconvsysdir@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
keytablesystemdir = @keytablesystemdir@
keytableuserdir = @keytableuserdir@
libdir = @libdir@
libexecdir = @libexecdir@
libudev_CFLAGS = @libudev_CFLAGS@
libudev_LIBS = @libudev_LIBS@
libv4l1privdir = @libv4l1privdir@
libv4l1subdir = @libv4l1subdir@
libv4l2plugindir = @libv4l2plugindir@
libv4l2privdir = @libv4l2privdir@
libv4l2subdir = @libv4l2subdir@
libv4lconvertprivdir = @libv4lconvertprivdir@
localedir = @localedir@
localstatedir = @localstatedir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
pkgconfigdir = @pkgconfigdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
runstatedir = @runstatedir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
sysconfdir = @sysconfdir@
systemdsystemunitdir = @systemdsystemunitdir@
target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
udevrulesdir = @udevrulesdir@
@WITH_DYN_LIBV4L_TRUE@lib_LTLIBRARIES = libv4l2.la
@WITH_DYN_LIBV4L_TRUE@include_HEADERS = ../include/libv4l2.h ../include/libv4l-plugin.h
@WITH_DYN_LIBV4L_TRUE@pkgconfig_DATA = libv4l2.pc
@WITH_DYN_LIBV4L_TRUE@LIBV4L2_VERSION = -version-info 0
@WITH_DYN_LIBV4L_TRUE@@WITH_V4L_WRAPPERS_TRUE@libv4l2priv_LTLIBRARIES = v4l2convert.la
@WITH_DYN_LIBV4L_FALSE@noinst_LTLIBRARIES = libv4l2.la
libv4l2_la_SOURCES = libv4l2.c log.c libv4l2-priv.h $(am__append_1)
libv4l2_la_CPPFLAGS = $(CFLAG_VISIBILITY) $(ENFORCE_LIBV4L_STATIC)
libv4l2_la_LDFLAGS = $(LIBV4L2_VERSION) -lpthread $(DLOPEN_LIBS) $(ENFORCE_LIBV4L_STATIC)
libv4l2_la_LIBADD = ../libv4lconvert/libv4lconvert.la
v4l2convert_la_SOURCES = v4l2convert.c
v4l2convert_la_LIBADD = libv4l2.la
v4l2convert_la_LDFLAGS = -avoid-version -module -shared -export-dynamic
v4l2convert_la_LIBTOOLFLAGS = --tag=disable-static
EXTRA_DIST = Android.mk v4l2-plugin-android.c
all: all-am
.SUFFIXES:
.SUFFIXES: .c .lo .o .obj
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
&& { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu lib/libv4l2/Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --gnu lib/libv4l2/Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(am__aclocal_m4_deps):
libv4l2.pc: $(top_builddir)/config.status $(srcdir)/libv4l2.pc.in
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
install-libLTLIBRARIES: $(lib_LTLIBRARIES)
@$(NORMAL_INSTALL)
@list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
list2=; for p in $$list; do \
if test -f $$p; then \
list2="$$list2 $$p"; \
else :; fi; \
done; \
test -z "$$list2" || { \
echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \
$(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \
echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \
$(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \
}
uninstall-libLTLIBRARIES:
@$(NORMAL_UNINSTALL)
@list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
for p in $$list; do \
$(am__strip_dir) \
echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \
$(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \
done
clean-libLTLIBRARIES:
-test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
@list='$(lib_LTLIBRARIES)'; \
locs=`for p in $$list; do echo $$p; done | \
sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
sort -u`; \
test -z "$$locs" || { \
echo rm -f $${locs}; \
rm -f $${locs}; \
}
install-libv4l2privLTLIBRARIES: $(libv4l2priv_LTLIBRARIES)
@$(NORMAL_INSTALL)
@list='$(libv4l2priv_LTLIBRARIES)'; test -n "$(libv4l2privdir)" || list=; \
list2=; for p in $$list; do \
if test -f $$p; then \
list2="$$list2 $$p"; \
else :; fi; \
done; \
test -z "$$list2" || { \
echo " $(MKDIR_P) '$(DESTDIR)$(libv4l2privdir)'"; \
$(MKDIR_P) "$(DESTDIR)$(libv4l2privdir)" || exit 1; \
echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libv4l2privdir)'"; \
$(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libv4l2privdir)"; \
}
uninstall-libv4l2privLTLIBRARIES:
@$(NORMAL_UNINSTALL)
@list='$(libv4l2priv_LTLIBRARIES)'; test -n "$(libv4l2privdir)" || list=; \
for p in $$list; do \
$(am__strip_dir) \
echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libv4l2privdir)/$$f'"; \
$(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libv4l2privdir)/$$f"; \
done
clean-libv4l2privLTLIBRARIES:
-test -z "$(libv4l2priv_LTLIBRARIES)" || rm -f $(libv4l2priv_LTLIBRARIES)
@list='$(libv4l2priv_LTLIBRARIES)'; \
locs=`for p in $$list; do echo $$p; done | \
sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
sort -u`; \
test -z "$$locs" || { \
echo rm -f $${locs}; \
rm -f $${locs}; \
}
clean-noinstLTLIBRARIES:
-test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
@list='$(noinst_LTLIBRARIES)'; \
locs=`for p in $$list; do echo $$p; done | \
sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
sort -u`; \
test -z "$$locs" || { \
echo rm -f $${locs}; \
rm -f $${locs}; \
}
libv4l2.la: $(libv4l2_la_OBJECTS) $(libv4l2_la_DEPENDENCIES) $(EXTRA_libv4l2_la_DEPENDENCIES)
$(AM_V_CCLD)$(libv4l2_la_LINK) $(am_libv4l2_la_rpath) $(libv4l2_la_OBJECTS) $(libv4l2_la_LIBADD) $(LIBS)
v4l2convert.la: $(v4l2convert_la_OBJECTS) $(v4l2convert_la_DEPENDENCIES) $(EXTRA_v4l2convert_la_DEPENDENCIES)
$(AM_V_CCLD)$(v4l2convert_la_LINK) $(am_v4l2convert_la_rpath) $(v4l2convert_la_OBJECTS) $(v4l2convert_la_LIBADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT)
distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libv4l2_la-libv4l2.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libv4l2_la-log.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libv4l2_la-v4l2-plugin.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/v4l2convert_la-v4l2convert.Plo@am__quote@ # am--include-marker
$(am__depfiles_remade):
@$(MKDIR_P) $(@D)
@echo '# dummy' >$@-t && $(am__mv) $@-t $@
am--depfiles: $(am__depfiles_remade)
.c.o:
@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
.c.obj:
@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
.c.lo:
@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
libv4l2_la-libv4l2.lo: libv4l2.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libv4l2_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libv4l2_la-libv4l2.lo -MD -MP -MF $(DEPDIR)/libv4l2_la-libv4l2.Tpo -c -o libv4l2_la-libv4l2.lo `test -f 'libv4l2.c' || echo '$(srcdir)/'`libv4l2.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libv4l2_la-libv4l2.Tpo $(DEPDIR)/libv4l2_la-libv4l2.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libv4l2.c' object='libv4l2_la-libv4l2.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libv4l2_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libv4l2_la-libv4l2.lo `test -f 'libv4l2.c' || echo '$(srcdir)/'`libv4l2.c
libv4l2_la-log.lo: log.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libv4l2_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libv4l2_la-log.lo -MD -MP -MF $(DEPDIR)/libv4l2_la-log.Tpo -c -o libv4l2_la-log.lo `test -f 'log.c' || echo '$(srcdir)/'`log.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libv4l2_la-log.Tpo $(DEPDIR)/libv4l2_la-log.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='log.c' object='libv4l2_la-log.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libv4l2_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libv4l2_la-log.lo `test -f 'log.c' || echo '$(srcdir)/'`log.c
libv4l2_la-v4l2-plugin.lo: v4l2-plugin.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libv4l2_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libv4l2_la-v4l2-plugin.lo -MD -MP -MF $(DEPDIR)/libv4l2_la-v4l2-plugin.Tpo -c -o libv4l2_la-v4l2-plugin.lo `test -f 'v4l2-plugin.c' || echo '$(srcdir)/'`v4l2-plugin.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libv4l2_la-v4l2-plugin.Tpo $(DEPDIR)/libv4l2_la-v4l2-plugin.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='v4l2-plugin.c' object='libv4l2_la-v4l2-plugin.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libv4l2_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libv4l2_la-v4l2-plugin.lo `test -f 'v4l2-plugin.c' || echo '$(srcdir)/'`v4l2-plugin.c
v4l2convert_la-v4l2convert.lo: v4l2convert.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(v4l2convert_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT v4l2convert_la-v4l2convert.lo -MD -MP -MF $(DEPDIR)/v4l2convert_la-v4l2convert.Tpo -c -o v4l2convert_la-v4l2convert.lo `test -f 'v4l2convert.c' || echo '$(srcdir)/'`v4l2convert.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/v4l2convert_la-v4l2convert.Tpo $(DEPDIR)/v4l2convert_la-v4l2convert.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='v4l2convert.c' object='v4l2convert_la-v4l2convert.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(v4l2convert_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o v4l2convert_la-v4l2convert.lo `test -f 'v4l2convert.c' || echo '$(srcdir)/'`v4l2convert.c
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
install-pkgconfigDATA: $(pkgconfig_DATA)
@$(NORMAL_INSTALL)
@list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \
if test -n "$$list"; then \
echo " $(MKDIR_P) '$(DESTDIR)$(pkgconfigdir)'"; \
$(MKDIR_P) "$(DESTDIR)$(pkgconfigdir)" || exit 1; \
fi; \
for p in $$list; do \
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
echo "$$d$$p"; \
done | $(am__base_list) | \
while read files; do \
echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pkgconfigdir)'"; \
$(INSTALL_DATA) $$files "$(DESTDIR)$(pkgconfigdir)" || exit $$?; \
done
uninstall-pkgconfigDATA:
@$(NORMAL_UNINSTALL)
@list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \
files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
dir='$(DESTDIR)$(pkgconfigdir)'; $(am__uninstall_files_from_dir)
install-includeHEADERS: $(include_HEADERS)
@$(NORMAL_INSTALL)
@list='$(include_HEADERS)'; test -n "$(includedir)" || list=; \
if test -n "$$list"; then \
echo " $(MKDIR_P) '$(DESTDIR)$(includedir)'"; \
$(MKDIR_P) "$(DESTDIR)$(includedir)" || exit 1; \
fi; \
for p in $$list; do \
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
echo "$$d$$p"; \
done | $(am__base_list) | \
while read files; do \
echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(includedir)'"; \
$(INSTALL_HEADER) $$files "$(DESTDIR)$(includedir)" || exit $$?; \
done
uninstall-includeHEADERS:
@$(NORMAL_UNINSTALL)
@list='$(include_HEADERS)'; test -n "$(includedir)" || list=; \
files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
dir='$(DESTDIR)$(includedir)'; $(am__uninstall_files_from_dir)
ID: $(am__tagged_files)
$(am__define_uniq_tagged_files); mkid -fID $$unique
tags: tags-am
TAGS: tags
tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
set x; \
here=`pwd`; \
$(am__define_uniq_tagged_files); \
shift; \
if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
if test $$# -gt 0; then \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
"$$@" $$unique; \
else \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$unique; \
fi; \
fi
ctags: ctags-am
CTAGS: ctags
ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
$(am__define_uniq_tagged_files); \
test -z "$(CTAGS_ARGS)$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& $(am__cd) $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) "$$here"
cscopelist: cscopelist-am
cscopelist-am: $(am__tagged_files)
list='$(am__tagged_files)'; \
case "$(srcdir)" in \
[\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
*) sdir=$(subdir)/$(srcdir) ;; \
esac; \
for i in $$list; do \
if test -f "$$i"; then \
echo "$(subdir)/$$i"; \
else \
echo "$$sdir/$$i"; \
fi; \
done >> $(top_builddir)/cscope.files
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
distdir: $(BUILT_SOURCES)
$(MAKE) $(AM_MAKEFLAGS) distdir-am
distdir-am: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
list='$(DISTFILES)'; \
dist_files=`for file in $$list; do echo $$file; done | \
sed -e "s|^$$srcdirstrip/||;t" \
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
case $$dist_files in \
*/*) $(MKDIR_P) `echo "$$dist_files" | \
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
sort -u` ;; \
esac; \
for file in $$dist_files; do \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
if test -d $$d/$$file; then \
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
if test -d "$(distdir)/$$file"; then \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
else \
test -f "$(distdir)/$$file" \
|| cp -p $$d/$$file "$(distdir)/$$file" \
|| exit 1; \
fi; \
done
check-am: all-am
check: check-am
all-am: Makefile $(LTLIBRARIES) $(DATA) $(HEADERS)
install-libv4l2privLTLIBRARIES: install-libLTLIBRARIES
installdirs:
for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(libv4l2privdir)" "$(DESTDIR)$(pkgconfigdir)" "$(DESTDIR)$(includedir)"; do \
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
done
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-am
install-strip:
if test -z '$(STRIP)'; then \
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
install; \
else \
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
"INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
fi
mostlyclean-generic:
clean-generic:
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
@WITH_DYN_LIBV4L_FALSE@install-exec-hook:
@WITH_V4L_WRAPPERS_FALSE@install-exec-hook:
clean: clean-am
clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \
clean-libv4l2privLTLIBRARIES clean-noinstLTLIBRARIES \
mostlyclean-am
distclean: distclean-am
-rm -f ./$(DEPDIR)/libv4l2_la-libv4l2.Plo
-rm -f ./$(DEPDIR)/libv4l2_la-log.Plo
-rm -f ./$(DEPDIR)/libv4l2_la-v4l2-plugin.Plo
-rm -f ./$(DEPDIR)/v4l2convert_la-v4l2convert.Plo
-rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \
distclean-tags
dvi: dvi-am
dvi-am:
html: html-am
html-am:
info: info-am
info-am:
install-data-am: install-includeHEADERS install-libv4l2privLTLIBRARIES \
install-pkgconfigDATA
install-dvi: install-dvi-am
install-dvi-am:
install-exec-am: install-libLTLIBRARIES
@$(NORMAL_INSTALL)
$(MAKE) $(AM_MAKEFLAGS) install-exec-hook
install-html: install-html-am
install-html-am:
install-info: install-info-am
install-info-am:
install-man:
install-pdf: install-pdf-am
install-pdf-am:
install-ps: install-ps-am
install-ps-am:
installcheck-am:
maintainer-clean: maintainer-clean-am
-rm -f ./$(DEPDIR)/libv4l2_la-libv4l2.Plo
-rm -f ./$(DEPDIR)/libv4l2_la-log.Plo
-rm -f ./$(DEPDIR)/libv4l2_la-v4l2-plugin.Plo
-rm -f ./$(DEPDIR)/v4l2convert_la-v4l2convert.Plo
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-compile mostlyclean-generic \
mostlyclean-libtool
pdf: pdf-am
pdf-am:
ps: ps-am
ps-am:
uninstall-am: uninstall-includeHEADERS uninstall-libLTLIBRARIES \
uninstall-libv4l2privLTLIBRARIES uninstall-pkgconfigDATA
.MAKE: install-am install-exec-am install-strip
.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \
clean-generic clean-libLTLIBRARIES clean-libtool \
clean-libv4l2privLTLIBRARIES clean-noinstLTLIBRARIES \
cscopelist-am ctags ctags-am distclean distclean-compile \
distclean-generic distclean-libtool distclean-tags distdir dvi \
dvi-am html html-am info info-am install install-am \
install-data install-data-am install-dvi install-dvi-am \
install-exec install-exec-am install-exec-hook install-html \
install-html-am install-includeHEADERS install-info \
install-info-am install-libLTLIBRARIES \
install-libv4l2privLTLIBRARIES install-man install-pdf \
install-pdf-am install-pkgconfigDATA install-ps install-ps-am \
install-strip installcheck installcheck-am installdirs \
maintainer-clean maintainer-clean-generic mostlyclean \
mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
pdf pdf-am ps ps-am tags tags-am uninstall uninstall-am \
uninstall-includeHEADERS uninstall-libLTLIBRARIES \
uninstall-libv4l2privLTLIBRARIES uninstall-pkgconfigDATA
.PRECIOUS: Makefile
@WITH_DYN_LIBV4L_TRUE@@WITH_V4L_WRAPPERS_TRUE@install-exec-hook:
@WITH_DYN_LIBV4L_TRUE@@WITH_V4L_WRAPPERS_TRUE@ $(mkdir_p) $(DESTDIR)/$(libdir)
@WITH_DYN_LIBV4L_TRUE@@WITH_V4L_WRAPPERS_TRUE@ (cd $(DESTDIR)/$(libdir) && rm -f v4l2convert.so && $(LN_S) $(libv4l2subdir)/v4l2convert.so v4l2convert.so)
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

136
libv4l2/libv4l2-priv.h Normal file
View File

@@ -0,0 +1,136 @@
/*
# (C) 2008 Hans de Goede <hdegoede@redhat.com>
#
# SPDX-FileCopyrightText: Copyright (c) 2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: LGPL-2.1-or-later
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 2.1 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
*/
#ifndef __LIBV4L2_PRIV_H
#define __LIBV4L2_PRIV_H
#include <stdio.h>
#include <pthread.h>
#include <libv4lconvert.h> /* includes videodev2.h for us */
#include "../libv4lconvert/libv4lsyscall-priv.h"
#define V4L2_MAX_DEVICES 1024
/* Warning when making this larger the frame_queued and frame_mapped members of
the v4l2_dev_info struct can no longer be a bitfield, so the code needs to
be adjusted! */
#define V4L2_MAX_NO_FRAMES 32
#define V4L2_DEFAULT_NREADBUFFERS 4
#define V4L2_IGNORE_FIRST_FRAME_ERRORS 3
#define V4L2_DEFAULT_FPS 30
#define V4L2_LOG_ERR(...) \
do { \
if (v4l2_log_file) { \
fprintf(v4l2_log_file, "libv4l2: error " __VA_ARGS__); \
fflush(v4l2_log_file); \
} else \
fprintf(stderr, "libv4l2: error " __VA_ARGS__); \
} while (0)
#define V4L2_PERROR(format, ...) \
do { \
if (errno == ENODEV) { \
devices[index].gone = 1;\
break; \
} \
V4L2_LOG_ERR(format ": %s\n", ##__VA_ARGS__, strerror(errno)); \
} while (0)
#define V4L2_LOG_WARN(...) \
do { \
if (v4l2_log_file) { \
fprintf(v4l2_log_file, "libv4l2: warning " __VA_ARGS__); \
fflush(v4l2_log_file); \
} else \
fprintf(stderr, "libv4l2: warning " __VA_ARGS__); \
} while (0)
#define V4L2_LOG(...) \
do { \
if (v4l2_log_file) { \
fprintf(v4l2_log_file, "libv4l2: " __VA_ARGS__); \
fflush(v4l2_log_file); \
} \
} while (0)
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
struct v4l2_dev_info {
int fd;
int flags;
int open_count;
int gone; /* Set to 1 when a device is detached (ENODEV encountered) */
long page_size;
/* actual format of the cam */
struct v4l2_format src_fmt;
/* fmt as seen by the application (iow after conversion) */
struct v4l2_format dest_fmt;
pthread_mutex_t stream_lock;
unsigned int no_frames;
unsigned int nreadbuffers;
int fps;
int first_frame;
struct v4lconvert_data *convert;
unsigned char *convert_mmap_buf;
size_t convert_mmap_buf_size;
size_t convert_mmap_frame_size;
/* Frame bookkeeping is only done when in read or mmap-conversion mode */
unsigned char *frame_pointers[V4L2_MAX_NO_FRAMES];
int frame_sizes[V4L2_MAX_NO_FRAMES];
int frame_queued; /* 1 status bit per frame */
int frame_info_generation;
/* mapping tracking of our fake (converting mmap) frame buffers */
unsigned char frame_map_count[V4L2_MAX_NO_FRAMES];
/* buffer when doing conversion and using read() for read() */
int readbuf_size;
unsigned char *readbuf;
/* plugin info */
void *plugin_library;
void *dev_ops_priv;
const struct libv4l_dev_ops *dev_ops;
};
/* From v4l2-plugin.c */
#if defined(HAVE_V4L_PLUGINS)
void v4l2_plugin_init(int fd, void **plugin_lib_ret, void **plugin_priv_ret,
const struct libv4l_dev_ops **dev_ops_ret);
void v4l2_plugin_cleanup(void *plugin_lib, void *plugin_priv,
const struct libv4l_dev_ops *dev_ops);
#else
static inline void v4l2_plugin_init(int fd, void **plugin_lib_ret, void **plugin_priv_ret,
const struct libv4l_dev_ops **dev_ops_ret)
{
*dev_ops_ret = v4lconvert_get_default_dev_ops();
*plugin_lib_ret = NULL;
*plugin_priv_ret = NULL;
}
static inline void v4l2_plugin_cleanup(void *plugin_lib, void *plugin_priv,
const struct libv4l_dev_ops *dev_ops)
{
}
#endif /* WITH_V4L_PLUGINS */
/* From log.c */
extern const char *v4l2_ioctls[];
void v4l2_log_ioctl(unsigned long int request, void *arg, int result);
#endif

1787
libv4l2/libv4l2.c Normal file
View File

File diff suppressed because it is too large Load Diff

14
libv4l2/libv4l2.export Normal file
View File

@@ -0,0 +1,14 @@
# SPDX-FileCopyrightText: Copyright (c) 2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: LGPL-2.1-or-later
v4l2_close
v4l2_dup
v4l2_fd_open
v4l2_get_control
v4l2_ioctl
v4l2_log_file
v4l2_mmap
v4l2_munmap
v4l2_open
v4l2_read
v4l2_set_control
v4l2_write

12
libv4l2/libv4l2.pc.in Normal file
View File

@@ -0,0 +1,12 @@
prefix=@prefix@
exec_prefix=@exec_prefix@
includedir=@includedir@
libdir=@libdir@
Name: libv4l2
Description: v4l2 device access library
Version: @PACKAGE_VERSION@
Requires.private: libv4lconvert
Libs: -L${libdir} -lv4l2
Libs.private: -lpthread
Cflags: -I${includedir}

263
libv4l2/log.c Normal file
View File

@@ -0,0 +1,263 @@
/*
# (C) 2008 Elmar Kleijn <elmar_kleijn@hotmail.com>
# (C) 2008 Sjoerd Piepenbrink <need4weed@gmail.com>
# (C) 2008 Hans de Goede <hdegoede@redhat.com>
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 2.1 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
*/
#ifdef ANDROID
#include <android-config.h>
#else
#include <config.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include "../libv4lconvert/libv4lsyscall-priv.h"
#if defined(__OpenBSD__)
#include <sys/videoio.h>
#else
#include <linux/videodev2.h>
#endif
#include "libv4l2.h"
#include "libv4l2-priv.h"
#define ARRAY_SIZE(x) (sizeof(x)/sizeof((x)[0]))
FILE *v4l2_log_file = NULL;
const char *v4l2_ioctls[] = {
/* start v4l2 ioctls */
[_IOC_NR(VIDIOC_QUERYCAP)] = "VIDIOC_QUERYCAP",
[_IOC_NR(VIDIOC_ENUM_FMT)] = "VIDIOC_ENUM_FMT",
[_IOC_NR(VIDIOC_G_FMT)] = "VIDIOC_G_FMT",
[_IOC_NR(VIDIOC_S_FMT)] = "VIDIOC_S_FMT",
[_IOC_NR(VIDIOC_REQBUFS)] = "VIDIOC_REQBUFS",
[_IOC_NR(VIDIOC_QUERYBUF)] = "VIDIOC_QUERYBUF",
[_IOC_NR(VIDIOC_G_FBUF)] = "VIDIOC_G_FBUF",
[_IOC_NR(VIDIOC_S_FBUF)] = "VIDIOC_S_FBUF",
[_IOC_NR(VIDIOC_OVERLAY)] = "VIDIOC_OVERLAY",
[_IOC_NR(VIDIOC_QBUF)] = "VIDIOC_QBUF",
[_IOC_NR(VIDIOC_DQBUF)] = "VIDIOC_DQBUF",
[_IOC_NR(VIDIOC_STREAMON)] = "VIDIOC_STREAMON",
[_IOC_NR(VIDIOC_STREAMOFF)] = "VIDIOC_STREAMOFF",
[_IOC_NR(VIDIOC_G_PARM)] = "VIDIOC_G_PARM",
[_IOC_NR(VIDIOC_S_PARM)] = "VIDIOC_S_PARM",
[_IOC_NR(VIDIOC_G_STD)] = "VIDIOC_G_STD",
[_IOC_NR(VIDIOC_S_STD)] = "VIDIOC_S_STD",
[_IOC_NR(VIDIOC_ENUMSTD)] = "VIDIOC_ENUMSTD",
[_IOC_NR(VIDIOC_ENUMINPUT)] = "VIDIOC_ENUMINPUT",
[_IOC_NR(VIDIOC_G_CTRL)] = "VIDIOC_G_CTRL",
[_IOC_NR(VIDIOC_S_CTRL)] = "VIDIOC_S_CTRL",
[_IOC_NR(VIDIOC_G_TUNER)] = "VIDIOC_G_TUNER",
[_IOC_NR(VIDIOC_S_TUNER)] = "VIDIOC_S_TUNER",
[_IOC_NR(VIDIOC_G_AUDIO)] = "VIDIOC_G_AUDIO",
[_IOC_NR(VIDIOC_S_AUDIO)] = "VIDIOC_S_AUDIO",
[_IOC_NR(VIDIOC_QUERYCTRL)] = "VIDIOC_QUERYCTRL",
[_IOC_NR(VIDIOC_QUERYMENU)] = "VIDIOC_QUERYMENU",
[_IOC_NR(VIDIOC_G_INPUT)] = "VIDIOC_G_INPUT",
[_IOC_NR(VIDIOC_S_INPUT)] = "VIDIOC_S_INPUT",
[_IOC_NR(VIDIOC_G_OUTPUT)] = "VIDIOC_G_OUTPUT",
[_IOC_NR(VIDIOC_S_OUTPUT)] = "VIDIOC_S_OUTPUT",
[_IOC_NR(VIDIOC_ENUMOUTPUT)] = "VIDIOC_ENUMOUTPUT",
[_IOC_NR(VIDIOC_G_AUDOUT)] = "VIDIOC_G_AUDOUT",
[_IOC_NR(VIDIOC_S_AUDOUT)] = "VIDIOC_S_AUDOUT",
[_IOC_NR(VIDIOC_G_MODULATOR)] = "VIDIOC_G_MODULATOR",
[_IOC_NR(VIDIOC_S_MODULATOR)] = "VIDIOC_S_MODULATOR",
[_IOC_NR(VIDIOC_G_FREQUENCY)] = "VIDIOC_G_FREQUENCY",
[_IOC_NR(VIDIOC_S_FREQUENCY)] = "VIDIOC_S_FREQUENCY",
[_IOC_NR(VIDIOC_CROPCAP)] = "VIDIOC_CROPCAP",
[_IOC_NR(VIDIOC_G_CROP)] = "VIDIOC_G_CROP",
[_IOC_NR(VIDIOC_S_CROP)] = "VIDIOC_S_CROP",
[_IOC_NR(VIDIOC_G_JPEGCOMP)] = "VIDIOC_G_JPEGCOMP",
[_IOC_NR(VIDIOC_S_JPEGCOMP)] = "VIDIOC_S_JPEGCOMP",
[_IOC_NR(VIDIOC_QUERYSTD)] = "VIDIOC_QUERYSTD",
[_IOC_NR(VIDIOC_TRY_FMT)] = "VIDIOC_TRY_FMT",
[_IOC_NR(VIDIOC_ENUMAUDIO)] = "VIDIOC_ENUMAUDIO",
[_IOC_NR(VIDIOC_ENUMAUDOUT)] = "VIDIOC_ENUMAUDOUT",
[_IOC_NR(VIDIOC_G_PRIORITY)] = "VIDIOC_G_PRIORITY",
[_IOC_NR(VIDIOC_S_PRIORITY)] = "VIDIOC_S_PRIORITY",
[_IOC_NR(VIDIOC_G_SLICED_VBI_CAP)] = "VIDIOC_G_SLICED_VBI_CAP",
[_IOC_NR(VIDIOC_LOG_STATUS)] = "VIDIOC_LOG_STATUS",
[_IOC_NR(VIDIOC_G_EXT_CTRLS)] = "VIDIOC_G_EXT_CTRLS",
[_IOC_NR(VIDIOC_S_EXT_CTRLS)] = "VIDIOC_S_EXT_CTRLS",
[_IOC_NR(VIDIOC_TRY_EXT_CTRLS)] = "VIDIOC_TRY_EXT_CTRLS",
[_IOC_NR(VIDIOC_ENUM_FRAMESIZES)] = "VIDIOC_ENUM_FRAMESIZES",
[_IOC_NR(VIDIOC_ENUM_FRAMEINTERVALS)] = "VIDIOC_ENUM_FRAMEINTERVALS",
[_IOC_NR(VIDIOC_G_ENC_INDEX)] = "VIDIOC_G_ENC_INDEX",
[_IOC_NR(VIDIOC_ENCODER_CMD)] = "VIDIOC_ENCODER_CMD",
[_IOC_NR(VIDIOC_TRY_ENCODER_CMD)] = "VIDIOC_TRY_ENCODER_CMD",
[_IOC_NR(VIDIOC_DBG_S_REGISTER)] = "VIDIOC_DBG_S_REGISTER",
[_IOC_NR(VIDIOC_DBG_G_REGISTER)] = "VIDIOC_DBG_G_REGISTER",
[_IOC_NR(VIDIOC_S_HW_FREQ_SEEK)] = "VIDIOC_S_HW_FREQ_SEEK",
[_IOC_NR(VIDIOC_S_DV_TIMINGS)] = "VIDIOC_S_DV_TIMINGS",
[_IOC_NR(VIDIOC_G_DV_TIMINGS)] = "VIDIOC_G_DV_TIMINGS",
[_IOC_NR(VIDIOC_DQEVENT)] = "VIDIOC_DQEVENT",
[_IOC_NR(VIDIOC_SUBSCRIBE_EVENT)] = "VIDIOC_SUBSCRIBE_EVENT",
[_IOC_NR(VIDIOC_UNSUBSCRIBE_EVENT)] = "VIDIOC_UNSUBSCRIBE_EVENT",
[_IOC_NR(VIDIOC_CREATE_BUFS)] = "VIDIOC_CREATE_BUFS",
[_IOC_NR(VIDIOC_PREPARE_BUF)] = "VIDIOC_PREPARE_BUF",
[_IOC_NR(VIDIOC_G_SELECTION)] = "VIDIOC_G_SELECTION",
[_IOC_NR(VIDIOC_S_SELECTION)] = "VIDIOC_S_SELECTION",
[_IOC_NR(VIDIOC_DECODER_CMD)] = "VIDIOC_DECODER_CMD",
[_IOC_NR(VIDIOC_TRY_DECODER_CMD)] = "VIDIOC_TRY_DECODER_CMD",
[_IOC_NR(VIDIOC_ENUM_DV_TIMINGS)] = "VIDIOC_ENUM_DV_TIMINGS",
[_IOC_NR(VIDIOC_QUERY_DV_TIMINGS)] = "VIDIOC_QUERY_DV_TIMINGS",
[_IOC_NR(VIDIOC_DV_TIMINGS_CAP)] = "VIDIOC_DV_TIMINGS_CAP",
[_IOC_NR(VIDIOC_ENUM_FREQ_BANDS)] = "VIDIOC_ENUM_FREQ_BANDS",
[_IOC_NR(VIDIOC_DBG_G_CHIP_INFO)] = "VIDIOC_DBG_G_CHIP_INFO",
};
void v4l2_log_ioctl(unsigned long int request, void *arg, int result)
{
const char *ioctl_str;
char buf[40];
int saved_errno = errno;
if (!v4l2_log_file)
return;
if (_IOC_TYPE(request) == 'V' && _IOC_NR(request) < ARRAY_SIZE(v4l2_ioctls))
ioctl_str = v4l2_ioctls[_IOC_NR(request)];
else {
snprintf(buf, sizeof(buf), "unknown request: %c %d",
(int)_IOC_TYPE(request), (int)_IOC_NR(request));
ioctl_str = buf;
}
fprintf(v4l2_log_file, "request == %s\n", ioctl_str);
switch (request) {
case VIDIOC_ENUM_FMT: {
struct v4l2_fmtdesc *fmt = arg;
fprintf(v4l2_log_file, " index: %u, description: %s\n",
fmt->index, (result < 0) ? "" : (const char *)fmt->description);
break;
}
case VIDIOC_G_FMT:
case VIDIOC_S_FMT:
case VIDIOC_TRY_FMT: {
struct v4l2_format *fmt = arg;
int pixfmt = fmt->fmt.pix.pixelformat;
if (fmt->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
fprintf(v4l2_log_file, " pixelformat: %c%c%c%c %ux%u\n",
pixfmt & 0xff,
(pixfmt >> 8) & 0xff,
(pixfmt >> 16) & 0xff,
pixfmt >> 24,
fmt->fmt.pix.width,
fmt->fmt.pix.height);
fprintf(v4l2_log_file, " field: %d bytesperline: %d imagesize: %d\n",
(int)fmt->fmt.pix.field, (int)fmt->fmt.pix.bytesperline,
(int)fmt->fmt.pix.sizeimage);
fprintf(v4l2_log_file, " colorspace: %d, priv: %x\n",
(int)fmt->fmt.pix.colorspace, (int)fmt->fmt.pix.priv);
} else {
fprintf(v4l2_log_file, " type: %d\n", (int)fmt->type);
}
break;
}
case VIDIOC_REQBUFS: {
struct v4l2_requestbuffers *req = arg;
fprintf(v4l2_log_file, " count: %u type: %d memory: %d\n",
req->count, (int)req->type, (int)req->memory);
break;
}
case VIDIOC_DQBUF: {
struct v4l2_buffer *buf = arg;
fprintf(v4l2_log_file, " timestamp %ld.%06ld\n",
(long)buf->timestamp.tv_sec,
(long)buf->timestamp.tv_usec);
break;
}
case VIDIOC_ENUM_FRAMESIZES: {
struct v4l2_frmsizeenum *frmsize = arg;
int pixfmt = frmsize->pixel_format;
fprintf(v4l2_log_file, " index: %u pixelformat: %c%c%c%c\n",
frmsize->index,
pixfmt & 0xff,
(pixfmt >> 8) & 0xff,
(pixfmt >> 16) & 0xff,
pixfmt >> 24);
switch (frmsize->type) {
case V4L2_FRMSIZE_TYPE_DISCRETE:
fprintf(v4l2_log_file, " %ux%u\n", frmsize->discrete.width,
frmsize->discrete.height);
break;
case V4L2_FRMSIZE_TYPE_CONTINUOUS:
case V4L2_FRMSIZE_TYPE_STEPWISE:
fprintf(v4l2_log_file, " %ux%u -> %ux%u\n",
frmsize->stepwise.min_width, frmsize->stepwise.min_height,
frmsize->stepwise.max_width, frmsize->stepwise.max_height);
break;
}
break;
}
case VIDIOC_ENUM_FRAMEINTERVALS: {
struct v4l2_frmivalenum *frmival = arg;
int pixfmt = frmival->pixel_format;
fprintf(v4l2_log_file, " index: %u pixelformat: %c%c%c%c %ux%u:\n",
frmival->index,
pixfmt & 0xff,
(pixfmt >> 8) & 0xff,
(pixfmt >> 16) & 0xff,
pixfmt >> 24,
frmival->width,
frmival->height);
switch (frmival->type) {
case V4L2_FRMIVAL_TYPE_DISCRETE:
fprintf(v4l2_log_file, " %u/%u\n", frmival->discrete.numerator,
frmival->discrete.denominator);
break;
case V4L2_FRMIVAL_TYPE_CONTINUOUS:
case V4L2_FRMIVAL_TYPE_STEPWISE:
fprintf(v4l2_log_file, " %u/%u -> %u/%u\n",
frmival->stepwise.min.numerator,
frmival->stepwise.min.denominator,
frmival->stepwise.max.numerator,
frmival->stepwise.max.denominator);
break;
}
break;
}
case VIDIOC_G_PARM:
case VIDIOC_S_PARM: {
struct v4l2_streamparm *parm = arg;
if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
break;
if (parm->parm.capture.capability & V4L2_CAP_TIMEPERFRAME)
fprintf(v4l2_log_file, "timeperframe: %u/%u\n",
parm->parm.capture.timeperframe.numerator,
parm->parm.capture.timeperframe.denominator);
break;
}
}
if (result < 0)
fprintf(v4l2_log_file, "result == %d (%s)\n", result, strerror(saved_errno));
else
fprintf(v4l2_log_file, "result == %d\n", result);
fflush(v4l2_log_file);
}

View File

@@ -0,0 +1,155 @@
/*
* Copyright (C) 2010 Nokia Corporation <multimedia@maemo.org>
*
* SPDX-FileCopyrightText: Copyright (c) 2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: LGPL-2.1-or-later
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifdef ANDROID
#include <android-config.h>
#else
#include <config.h>
#endif
#include <stdarg.h>
#include <dlfcn.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <dirent.h>
#include <stdlib.h>
#include <string.h>
#include "libv4l2.h"
#include "libv4l2-priv.h"
#include "libv4l-plugin.h"
/* libv4l plugin support:
it is provided by functions v4l2_plugin_[open,close,etc].
When open() is called libv4l dlopens files in /usr/lib[64]/libv4l/plugins
1 at a time and call open callback passing through the applications
parameters unmodified.
If a plugin is relevant for the specified device node, it can indicate so
by returning a value other than -1 (the actual file descriptor).
As soon as a plugin returns another value than -1 plugin loading stops and
information about it (fd and corresponding library handle) is stored. For
each function v4l2_[ioctl,read,close,etc] is called corresponding
v4l2_plugin_* function which looks if there is loaded plugin for that file
and call it's callbacks.
v4l2_plugin_* function indicates by it's first argument if plugin was used,
and if it was not then v4l2_* functions proceed with their usual behavior.
*/
/* list of plugin search paths */
static const char *g_plugin_search_paths[] = {
"/system/lib/libv4l/plugins",
"/vendor/lib/libv4l/plugins",
NULL /* list terminator */
};
void v4l2_plugin_init(int fd, void **plugin_lib_ret, void **plugin_priv_ret,
const struct libv4l_dev_ops **dev_ops_ret)
{
char *error;
void *plugin_library = NULL;
const struct libv4l_dev_ops *libv4l2_plugin = NULL;
DIR *plugin_dir = NULL;
struct dirent *entry;
char *suffix = NULL;
int length, i;
char filename[256];
/* initialize output params */
*dev_ops_ret = v4lconvert_get_default_dev_ops();
*plugin_lib_ret = NULL;
*plugin_priv_ret = NULL;
/* read the plugin directory for "*.so" files */
for (i = 0; g_plugin_search_paths[i] != NULL; i++) {
plugin_dir = opendir(g_plugin_search_paths[i]);
if (plugin_dir == NULL) {
V4L2_LOG_ERR("PLUGIN: opening plugin directory (%s) failed\n",
g_plugin_search_paths[i]);
continue;
}
while ((entry = readdir(plugin_dir))) {
/* get last 3 letter suffix from the filename */
length = strlen(entry->d_name);
if (length > 3)
suffix = entry->d_name + (length - 3);
if (!suffix || strcmp(suffix, ".so")) {
suffix = NULL; /* reset for next iteration */
continue;
}
/* load library and get desired symbol */
sprintf(filename, "%s/%s", g_plugin_search_paths[i], entry->d_name);
V4L2_LOG("PLUGIN: dlopen(%s);\n", filename);
plugin_library = dlopen(filename, RTLD_LAZY);
if (!plugin_library)
continue;
dlerror(); /* Clear any existing error */
libv4l2_plugin = (struct libv4l_dev_ops *)
dlsym(plugin_library, "libv4l2_plugin");
error = dlerror();
if (error != NULL) {
V4L2_LOG_ERR("PLUGIN: dlsym failed: %s\n", error);
dlclose(plugin_library);
continue;
}
if (!libv4l2_plugin->init ||
!libv4l2_plugin->close ||
!libv4l2_plugin->ioctl) {
V4L2_LOG("PLUGIN: does not have all mandatory ops\n");
dlclose(plugin_library);
continue;
}
*plugin_priv_ret = libv4l2_plugin->init(fd);
if (!*plugin_priv_ret) {
V4L2_LOG("PLUGIN: plugin open() returned NULL\n");
dlclose(plugin_library);
continue;
}
/* exit loop when a suitable plugin is found */
*plugin_lib_ret = plugin_library;
*dev_ops_ret = libv4l2_plugin;
break;
}
closedir(plugin_dir);
/* exit loop when a suitable plugin is found */
if (*plugin_lib_ret && *plugin_priv_ret && *dev_ops_ret)
break;
}
}
void v4l2_plugin_cleanup(void *plugin_lib, void *plugin_priv,
const struct libv4l_dev_ops *dev_ops)
{
if (plugin_lib) {
dev_ops->close(plugin_priv);
dlclose(plugin_lib);
}
}

128
libv4l2/v4l2-plugin.c Normal file
View File

@@ -0,0 +1,128 @@
/*
* Copyright (C) 2010 Nokia Corporation <multimedia@maemo.org>
*
* SPDX-FileCopyrightText: Copyright (c) 2024-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: LGPL-2.1-or-later
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <config.h>
#include <stdarg.h>
#include <dlfcn.h>
#include <fcntl.h>
#include <glob.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include "libv4l2.h"
#include "libv4l2-priv.h"
#include "libv4l-plugin.h"
/* libv4l plugin support:
it is provided by functions v4l2_plugin_[open,close,etc].
When open() is called libv4l dlopens files in /usr/lib[64]/libv4l/plugins
1 at a time and call open callback passing through the applications
parameters unmodified.
If a plugin is relevant for the specified device node, it can indicate so
by returning a value other than -1 (the actual file descriptor).
As soon as a plugin returns another value than -1 plugin loading stops and
information about it (fd and corresponding library handle) is stored. For
each function v4l2_[ioctl,read,close,etc] is called corresponding
v4l2_plugin_* function which looks if there is loaded plugin for that file
and call it's callbacks.
v4l2_plugin_* function indicates by it's first argument if plugin was used,
and if it was not then v4l2_* functions proceed with their usual behavior.
*/
#define PLUGINS_PATTERN LIBV4L2_PLUGIN_DIR "/*.so"
void v4l2_plugin_init(int fd, void **plugin_lib_ret, void **plugin_priv_ret,
const struct libv4l_dev_ops **dev_ops_ret)
{
char *error;
int glob_ret, i;
void *plugin_library = NULL;
const struct libv4l_dev_ops *libv4l2_plugin = NULL;
glob_t globbuf;
*dev_ops_ret = v4lconvert_get_default_dev_ops();
*plugin_lib_ret = NULL;
*plugin_priv_ret = NULL;
glob_ret = glob(PLUGINS_PATTERN, 0, NULL, &globbuf);
if (glob_ret == GLOB_NOSPACE)
return;
if (glob_ret == GLOB_ABORTED || glob_ret == GLOB_NOMATCH)
goto leave;
#ifdef LIBV4L2_PLUGIN_DIR_PATH_X86
for (i = 0; i < globbuf.gl_pathc; i++) {
#else
/* WAR: Reverse open the libs to avoid memleak - Bug 4697575 */
for (i = globbuf.gl_pathc - 1; i >= 0; i--) {
#endif
V4L2_LOG("PLUGIN: dlopen(%s);\n", globbuf.gl_pathv[i]);
plugin_library = dlopen(globbuf.gl_pathv[i], RTLD_LAZY);
if (!plugin_library)
continue;
dlerror(); /* Clear any existing error */
libv4l2_plugin = (struct libv4l_dev_ops *)
dlsym(plugin_library, "libv4l2_plugin");
error = dlerror();
if (error != NULL) {
V4L2_LOG_ERR("PLUGIN: dlsym failed: %s\n", error);
dlclose(plugin_library);
continue;
}
if (!libv4l2_plugin->init ||
!libv4l2_plugin->close ||
!libv4l2_plugin->ioctl) {
V4L2_LOG("PLUGIN: does not have all mandatory ops\n");
dlclose(plugin_library);
continue;
}
*plugin_priv_ret = libv4l2_plugin->init(fd);
if (!*plugin_priv_ret) {
V4L2_LOG("PLUGIN: plugin open() returned NULL\n");
dlclose(plugin_library);
continue;
}
*plugin_lib_ret = plugin_library;
*dev_ops_ret = libv4l2_plugin;
break;
}
leave:
globfree(&globbuf);
}
void v4l2_plugin_cleanup(void *plugin_lib, void *plugin_priv,
const struct libv4l_dev_ops *dev_ops)
{
if (plugin_lib) {
dev_ops->close(plugin_priv);
dlclose(plugin_lib);
}
}

175
libv4l2/v4l2convert.c Normal file
View File

@@ -0,0 +1,175 @@
/*
# open/close/ioctl/mmap/munmap library call wrapper doing format conversion
# for v4l2 applications which want to be able to simply capture bgr24 / yuv420
# from v4l2 devices with more exotic frame formats.
# (C) 2008 Hans de Goede <hdegoede@redhat.com>
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 2.1 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
*/
/* prevent GCC 4.7 inlining error */
#undef _FORTIFY_SOURCE
/* ensure we see *64 variants and they aren't transparently used */
#undef _LARGEFILE_SOURCE
#undef _FILE_OFFSET_BITS
#define _LARGEFILE64_SOURCE 1
#ifdef ANDROID
#include <android-config.h>
#else
#include <config.h>
#endif
#include <stdarg.h>
#include <stdlib.h>
#include <fcntl.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#if defined(__OpenBSD__)
#include <sys/videoio.h>
#else
#include <linux/videodev2.h>
#endif
#include <libv4l2.h>
#include "../libv4lconvert/libv4lsyscall-priv.h"
/* Check that open/read/mmap is not a define */
#if defined open || defined read || defined mmap
#error open/read/mmap is a prepocessor macro !!
#endif
#if HAVE_VISIBILITY
#define LIBV4L_PUBLIC __attribute__ ((visibility("default")))
#else
#define LIBV4L_PUBLIC
#endif
LIBV4L_PUBLIC int open(const char *file, int oflag, ...)
{
int fd;
int v4l_device = 0;
/* check if we're opening a video4linux2 device */
if (!strncmp(file, "/dev/video", 10) || !strncmp(file, "/dev/v4l/", 9)) {
/* Some apps open the device read-only, but we need rw rights as the
buffers *MUST* be mapped rw */
oflag = (oflag & ~O_ACCMODE) | O_RDWR;
v4l_device = 1;
}
/* original open code */
if (oflag & O_CREAT) {
va_list ap;
mode_t mode;
va_start(ap, oflag);
mode = va_arg(ap, PROMOTED_MODE_T);
fd = SYS_OPEN(file, oflag, mode);
va_end(ap);
} else {
fd = SYS_OPEN(file, oflag, 0);
}
/* end of original open code */
if (fd == -1 || !v4l_device)
return fd;
/* Try to Register with libv4l2 (in case of failure pass the fd to the
application as is) */
v4l2_fd_open(fd, 0);
return fd;
}
#if defined(linux) && defined(__GLIBC__)
LIBV4L_PUBLIC int open64(const char *file, int oflag, ...)
{
int fd;
/* original open code */
if (oflag & O_CREAT) {
va_list ap;
mode_t mode;
va_start(ap, oflag);
mode = va_arg(ap, PROMOTED_MODE_T);
fd = open(file, oflag | O_LARGEFILE, mode);
va_end(ap);
} else {
fd = open(file, oflag | O_LARGEFILE);
}
/* end of original open code */
return fd;
}
#endif
#ifndef ANDROID
LIBV4L_PUBLIC int close(int fd)
{
return v4l2_close(fd);
}
LIBV4L_PUBLIC int dup(int fd)
{
return v4l2_dup(fd);
}
#ifdef HAVE_POSIX_IOCTL
LIBV4L_PUBLIC int ioctl(int fd, int request, ...)
#else
LIBV4L_PUBLIC int ioctl(int fd, unsigned long int request, ...)
#endif
{
void *arg;
va_list ap;
va_start(ap, request);
arg = va_arg(ap, void *);
va_end(ap);
return v4l2_ioctl(fd, request, arg);
}
LIBV4L_PUBLIC ssize_t read(int fd, void *buffer, size_t n)
{
return v4l2_read(fd, buffer, n);
}
LIBV4L_PUBLIC void *mmap(void *start, size_t length, int prot, int flags, int fd,
off_t offset)
{
return v4l2_mmap(start, length, prot, flags, fd, offset);
}
#if defined(linux) && defined(__GLIBC__)
LIBV4L_PUBLIC void *mmap64(void *start, size_t length, int prot, int flags, int fd,
off64_t offset)
{
return v4l2_mmap(start, length, prot, flags, fd, offset);
}
#endif
LIBV4L_PUBLIC int munmap(void *start, size_t length)
{
return v4l2_munmap(start, length);
}
#endif

75
libv4lconvert/Makefile Normal file
View File

@@ -0,0 +1,75 @@
###############################################################################
#
# SPDX-FileCopyrightText: Copyright (c) 2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: LGPL-2.1-or-later
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License, version 2.1, as published by the Free Software Foundation.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this program. If not, see
# <http://www.gnu.org/licenses/>.
#
###############################################################################
SO_NAME := libnvv4lconvert.so
DEST_DIR ?= /usr/lib/aarch64-linux-gnu/nvidia
SRCS := libv4lconvert.c tinyjpeg.c sn9c10x.c sn9c20x.c pac207.c mr97310a.c \
flip.c crop.c jidctflt.c spca561-decompress.c \
rgbyuv.c sn9c2028-decomp.c spca501.c sq905c.c bayer.c hm12.c \
stv0680.c cpia1.c se401.c jpgl.c jpeg.c jl2005bcd.c helper.c \
$(wildcard processing/*.c) \
$(wildcard control/*.c)
INCLUDES += -I./ -I../include -I./control -I./processing
OBJS := $(SRCS:.c=.o)
CFLAGS := -fPIC
MACHINE = $(shell uname -m)
ifeq ($(MACHINE),x86_64)
CFLAGS += -DLIBV4L2_PLUGIN_DIR_PATH_X86
DEST_DIR ?= /opt/nvidia/deepstream/deepstream-4.0/lib
SYM_LINK_DIR := $(DEST_DIR)
else
DEST_DIR ?= /usr/lib/$(MACHINE)-linux-gnu/nvidia
SYM_LINK_DIR := $(shell realpath $(DEST_DIR)/..)
endif
LIBS = -lrt
LDFLAGS := -Wl,-soname,libv4lconvert.so.0
all: $(SO_NAME)
%.o: %.c
$(CC) -c $< $(CFLAGS) $(INCLUDES) -o $@
$(SO_NAME): $(OBJS)
$(CC) -shared -o $(SO_NAME) $(OBJS) $(LIBS) $(LDFLAGS)
.PHONY: install
install: $(SO_NAME)
cp -vp $(SO_NAME) $(DEST_DIR)
if [ "$(MACHINE)" = "aarch64" ]; then \
ln -sf nvidia/$(SO_NAME) $(SYM_LINK_DIR)/libv4lconvert.so.0.0.999999 ; \
else \
ln -sf $(SO_NAME) $(SYM_LINK_DIR)/libv4lconvert.so.0.0.999999 ; \
fi
ln -sf libv4lconvert.so.0.0.999999 \
$(SYM_LINK_DIR)/libv4lconvert.so
ln -sf libv4lconvert.so.0.0.999999 \
${SYM_LINK_DIR}/libv4lconvert.so.0
.PHONY: clean
clean:
rm -rf $(OBJS) $(SO_NAME)

36
libv4lconvert/Makefile.am Normal file
View File

@@ -0,0 +1,36 @@
if WITH_DYN_LIBV4L
lib_LTLIBRARIES = libv4lconvert.la
if HAVE_LIBV4LCONVERT_HELPERS
libv4lconvertpriv_PROGRAMS = ov511-decomp ov518-decomp
endif
include_HEADERS = ../include/libv4lconvert.h
pkgconfig_DATA = libv4lconvert.pc
LIBV4LCONVERT_VERSION = -version-info 0
else
noinst_LTLIBRARIES = libv4lconvert.la
endif
libv4lconvert_la_SOURCES = \
libv4lconvert.c tinyjpeg.c sn9c10x.c sn9c20x.c pac207.c mr97310a.c \
flip.c crop.c jidctflt.c spca561-decompress.c \
rgbyuv.c sn9c2028-decomp.c spca501.c sq905c.c bayer.c hm12.c \
stv0680.c cpia1.c se401.c jpgl.c jpeg.c jl2005bcd.c \
control/libv4lcontrol.c control/libv4lcontrol.h control/libv4lcontrol-priv.h \
processing/libv4lprocessing.c processing/whitebalance.c processing/autogain.c \
processing/gamma.c processing/libv4lprocessing.h processing/libv4lprocessing-priv.h \
helper-funcs.h libv4lconvert-priv.h libv4lsyscall-priv.h \
tinyjpeg.h tinyjpeg-internal.h
if HAVE_JPEG
libv4lconvert_la_SOURCES += jpeg_memsrcdest.c jpeg_memsrcdest.h
endif
if HAVE_LIBV4LCONVERT_HELPERS
libv4lconvert_la_SOURCES += helper.c
endif
libv4lconvert_la_CPPFLAGS = $(CFLAG_VISIBILITY) $(ENFORCE_LIBV4L_STATIC)
libv4lconvert_la_LDFLAGS = $(LIBV4LCONVERT_VERSION) -lrt -lm $(JPEG_LIBS) $(ENFORCE_LIBV4L_STATIC)
ov511_decomp_SOURCES = ov511-decomp.c
ov518_decomp_SOURCES = ov518-decomp.c
EXTRA_DIST = Android.mk

View File

@@ -0,0 +1,43 @@
###############################################################################
#
# SPDX-FileCopyrightText: Copyright (c) 2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: LicenseRef-NvidiaProprietary
#
# NVIDIA CORPORATION, its affiliates and licensors retain all intellectual
# property and proprietary rights in and to this material, related
# documentation and any modifications thereto. Any use, reproduction,
# disclosure or distribution of this material and related documentation
# without an express license agreement from NVIDIA CORPORATION or
# its affiliates is strictly prohibited.
#
###############################################################################
CC:=gcc
TARGET_NAME:= libnvv4lconvert.so
SRCS := libv4lconvert.c tinyjpeg.c sn9c10x.c sn9c20x.c pac207.c mr97310a.c \
flip.c crop.c jidctflt.c spca561-decompress.c \
rgbyuv.c sn9c2028-decomp.c spca501.c sq905c.c bayer.c hm12.c \
stv0680.c cpia1.c se401.c jpgl.c jpeg.c jl2005bcd.c helper.c \
$(wildcard processing/*.c) \
$(wildcard control/*.c)
INC_PATHS:= ../include ./control ./processing
CFLAGS:= -fPIC
CFLAGS += -DLIBV4L2_PLUGIN_DIR_PATH_X86
IGNORE_DS_PACKAGE_NAMING:=1
LDFLAGS:= -shared -Wl,-soname,libv4lconvert.so.0
LIBS:= -lrt -lm
#IS_V4L2_LIB:=1
PACKAGE_BINARY_IN_DS:=1
BUILD_DIR:=../../../../../deepstream/sdk/build/libs/libv4l/
include ../../../../../deepstream/sdk/Rules.mk
install::
ln -sf $(INSTALL_DIR)/$(TARGET_NAME) /usr/lib/x86_64-linux-gnu/libv4lconvert.so.0.0.99999
ldconfig

1333
libv4lconvert/Makefile.in Normal file
View File

File diff suppressed because it is too large Load Diff

673
libv4lconvert/bayer.c Normal file
View File

@@ -0,0 +1,673 @@
/*
* lib4lconvert, video4linux2 format conversion lib
* (C) 2008 Hans de Goede <hdegoede@redhat.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
*
* Note: original bayer_to_bgr24 code from :
* 1394-Based Digital Camera Control Library
*
* Bayer pattern decoding functions
*
* Written by Damien Douxchamps and Frederic Devernay
*
* Note that the original bayer.c in libdc1394 supports many different
* bayer decode algorithms, for lib4lconvert the one in this file has been
* chosen (and optimized a bit) and the other algorithms have been removed,
* see bayer.c from libdc1394 for all supported algorithms
*/
#include <string.h>
#include "libv4lconvert-priv.h"
/**************************************************************
* Color conversion functions for cameras that can *
* output raw-Bayer pattern images, such as some Basler and *
* Point Grey camera. Most of the algos presented here come *
* from http://www-ise.stanford.edu/~tingchen/ and have been *
* converted from Matlab to C and extended to all elementary *
* patterns. *
**************************************************************/
/* inspired by OpenCV's Bayer decoding */
static void v4lconvert_border_bayer_line_to_bgr24(
const unsigned char *bayer, const unsigned char *adjacent_bayer,
unsigned char *bgr, int width, const int start_with_green, const int blue_line)
{
int t0, t1;
if (start_with_green) {
/* First pixel */
if (blue_line) {
*bgr++ = bayer[1];
*bgr++ = bayer[0];
*bgr++ = adjacent_bayer[0];
} else {
*bgr++ = adjacent_bayer[0];
*bgr++ = bayer[0];
*bgr++ = bayer[1];
}
/* Second pixel */
t0 = (bayer[0] + bayer[2] + adjacent_bayer[1] + 1) / 3;
t1 = (adjacent_bayer[0] + adjacent_bayer[2] + 1) >> 1;
if (blue_line) {
*bgr++ = bayer[1];
*bgr++ = t0;
*bgr++ = t1;
} else {
*bgr++ = t1;
*bgr++ = t0;
*bgr++ = bayer[1];
}
bayer++;
adjacent_bayer++;
width -= 2;
} else {
/* First pixel */
t0 = (bayer[1] + adjacent_bayer[0] + 1) >> 1;
if (blue_line) {
*bgr++ = bayer[0];
*bgr++ = t0;
*bgr++ = adjacent_bayer[1];
} else {
*bgr++ = adjacent_bayer[1];
*bgr++ = t0;
*bgr++ = bayer[0];
}
width--;
}
if (blue_line) {
for ( ; width > 2; width -= 2) {
t0 = (bayer[0] + bayer[2] + 1) >> 1;
*bgr++ = t0;
*bgr++ = bayer[1];
*bgr++ = adjacent_bayer[1];
bayer++;
adjacent_bayer++;
t0 = (bayer[0] + bayer[2] + adjacent_bayer[1] + 1) / 3;
t1 = (adjacent_bayer[0] + adjacent_bayer[2] + 1) >> 1;
*bgr++ = bayer[1];
*bgr++ = t0;
*bgr++ = t1;
bayer++;
adjacent_bayer++;
}
} else {
for ( ; width > 2; width -= 2) {
t0 = (bayer[0] + bayer[2] + 1) >> 1;
*bgr++ = adjacent_bayer[1];
*bgr++ = bayer[1];
*bgr++ = t0;
bayer++;
adjacent_bayer++;
t0 = (bayer[0] + bayer[2] + adjacent_bayer[1] + 1) / 3;
t1 = (adjacent_bayer[0] + adjacent_bayer[2] + 1) >> 1;
*bgr++ = t1;
*bgr++ = t0;
*bgr++ = bayer[1];
bayer++;
adjacent_bayer++;
}
}
if (width == 2) {
/* Second to last pixel */
t0 = (bayer[0] + bayer[2] + 1) >> 1;
if (blue_line) {
*bgr++ = t0;
*bgr++ = bayer[1];
*bgr++ = adjacent_bayer[1];
} else {
*bgr++ = adjacent_bayer[1];
*bgr++ = bayer[1];
*bgr++ = t0;
}
/* Last pixel */
t0 = (bayer[1] + adjacent_bayer[2] + 1) >> 1;
if (blue_line) {
*bgr++ = bayer[2];
*bgr++ = t0;
*bgr++ = adjacent_bayer[1];
} else {
*bgr++ = adjacent_bayer[1];
*bgr++ = t0;
*bgr++ = bayer[2];
}
} else {
/* Last pixel */
if (blue_line) {
*bgr++ = bayer[0];
*bgr++ = bayer[1];
*bgr++ = adjacent_bayer[1];
} else {
*bgr++ = adjacent_bayer[1];
*bgr++ = bayer[1];
*bgr++ = bayer[0];
}
}
}
/* From libdc1394, which on turn was based on OpenCV's Bayer decoding */
static void bayer_to_rgbbgr24(const unsigned char *bayer,
unsigned char *bgr, int width, int height, const unsigned int stride, unsigned int pixfmt,
int start_with_green, int blue_line)
{
/* render the first line */
v4lconvert_border_bayer_line_to_bgr24(bayer, bayer + stride, bgr, width,
start_with_green, blue_line);
bgr += width * 3;
/* reduce height by 2 because of the special case top/bottom line */
for (height -= 2; height; height--) {
int t0, t1;
/* (width - 2) because of the border */
const unsigned char *bayer_end = bayer + (width - 2);
if (start_with_green) {
t0 = (bayer[1] + bayer[stride * 2 + 1] + 1) >> 1;
/* Write first pixel */
t1 = (bayer[0] + bayer[stride * 2] + bayer[stride + 1] + 1) / 3;
if (blue_line) {
*bgr++ = t0;
*bgr++ = t1;
*bgr++ = bayer[stride];
} else {
*bgr++ = bayer[stride];
*bgr++ = t1;
*bgr++ = t0;
}
/* Write second pixel */
t1 = (bayer[stride] + bayer[stride + 2] + 1) >> 1;
if (blue_line) {
*bgr++ = t0;
*bgr++ = bayer[stride + 1];
*bgr++ = t1;
} else {
*bgr++ = t1;
*bgr++ = bayer[stride + 1];
*bgr++ = t0;
}
bayer++;
} else {
/* Write first pixel */
t0 = (bayer[0] + bayer[stride * 2] + 1) >> 1;
if (blue_line) {
*bgr++ = t0;
*bgr++ = bayer[stride];
*bgr++ = bayer[stride + 1];
} else {
*bgr++ = bayer[stride + 1];
*bgr++ = bayer[stride];
*bgr++ = t0;
}
}
if (blue_line) {
for (; bayer <= bayer_end - 2; bayer += 2) {
t0 = (bayer[0] + bayer[2] + bayer[stride * 2] +
bayer[stride * 2 + 2] + 2) >> 2;
t1 = (bayer[1] + bayer[stride] + bayer[stride + 2] +
bayer[stride * 2 + 1] + 2) >> 2;
*bgr++ = t0;
*bgr++ = t1;
*bgr++ = bayer[stride + 1];
t0 = (bayer[2] + bayer[stride * 2 + 2] + 1) >> 1;
t1 = (bayer[stride + 1] + bayer[stride + 3] + 1) >> 1;
*bgr++ = t0;
*bgr++ = bayer[stride + 2];
*bgr++ = t1;
}
} else {
for (; bayer <= bayer_end - 2; bayer += 2) {
t0 = (bayer[0] + bayer[2] + bayer[stride * 2] +
bayer[stride * 2 + 2] + 2) >> 2;
t1 = (bayer[1] + bayer[stride] + bayer[stride + 2] +
bayer[stride * 2 + 1] + 2) >> 2;
*bgr++ = bayer[stride + 1];
*bgr++ = t1;
*bgr++ = t0;
t0 = (bayer[2] + bayer[stride * 2 + 2] + 1) >> 1;
t1 = (bayer[stride + 1] + bayer[stride + 3] + 1) >> 1;
*bgr++ = t1;
*bgr++ = bayer[stride + 2];
*bgr++ = t0;
}
}
if (bayer < bayer_end) {
/* write second to last pixel */
t0 = (bayer[0] + bayer[2] + bayer[stride * 2] +
bayer[stride * 2 + 2] + 2) >> 2;
t1 = (bayer[1] + bayer[stride] + bayer[stride + 2] +
bayer[stride * 2 + 1] + 2) >> 2;
if (blue_line) {
*bgr++ = t0;
*bgr++ = t1;
*bgr++ = bayer[stride + 1];
} else {
*bgr++ = bayer[stride + 1];
*bgr++ = t1;
*bgr++ = t0;
}
/* write last pixel */
t0 = (bayer[2] + bayer[stride * 2 + 2] + 1) >> 1;
if (blue_line) {
*bgr++ = t0;
*bgr++ = bayer[stride + 2];
*bgr++ = bayer[stride + 1];
} else {
*bgr++ = bayer[stride + 1];
*bgr++ = bayer[stride + 2];
*bgr++ = t0;
}
bayer++;
} else {
/* write last pixel */
t0 = (bayer[0] + bayer[stride * 2] + 1) >> 1;
t1 = (bayer[1] + bayer[stride * 2 + 1] + bayer[stride] + 1) / 3;
if (blue_line) {
*bgr++ = t0;
*bgr++ = t1;
*bgr++ = bayer[stride + 1];
} else {
*bgr++ = bayer[stride + 1];
*bgr++ = t1;
*bgr++ = t0;
}
}
/* skip 2 border pixels and padding */
bayer += (stride - width) + 2;
blue_line = !blue_line;
start_with_green = !start_with_green;
}
/* render the last line */
v4lconvert_border_bayer_line_to_bgr24(bayer + stride, bayer, bgr, width,
!start_with_green, !blue_line);
}
void v4lconvert_bayer_to_rgb24(const unsigned char *bayer,
unsigned char *bgr, int width, int height, const unsigned int stride, unsigned int pixfmt)
{
bayer_to_rgbbgr24(bayer, bgr, width, height, stride, pixfmt,
pixfmt == V4L2_PIX_FMT_SGBRG8 /* start with green */
|| pixfmt == V4L2_PIX_FMT_SGRBG8,
pixfmt != V4L2_PIX_FMT_SBGGR8 /* blue line */
&& pixfmt != V4L2_PIX_FMT_SGBRG8);
}
void v4lconvert_bayer_to_bgr24(const unsigned char *bayer,
unsigned char *bgr, int width, int height, const unsigned int stride, unsigned int pixfmt)
{
bayer_to_rgbbgr24(bayer, bgr, width, height, stride, pixfmt,
pixfmt == V4L2_PIX_FMT_SGBRG8 /* start with green */
|| pixfmt == V4L2_PIX_FMT_SGRBG8,
pixfmt == V4L2_PIX_FMT_SBGGR8 /* blue line */
|| pixfmt == V4L2_PIX_FMT_SGBRG8);
}
static void v4lconvert_border_bayer_line_to_y(
const unsigned char *bayer, const unsigned char *adjacent_bayer,
unsigned char *y, int width, int start_with_green, int blue_line)
{
int t0, t1;
if (start_with_green) {
/* First pixel */
if (blue_line) {
*y++ = (8453 * adjacent_bayer[0] + 16594 * bayer[0] +
3223 * bayer[1] + 524288) >> 15;
} else {
*y++ = (8453 * bayer[1] + 16594 * bayer[0] +
3223 * adjacent_bayer[0] + 524288) >> 15;
}
/* Second pixel */
t0 = bayer[0] + bayer[2] + adjacent_bayer[1];
t1 = adjacent_bayer[0] + adjacent_bayer[2];
if (blue_line)
*y++ = (4226 * t1 + 5531 * t0 + 3223 * bayer[1] + 524288) >> 15;
else
*y++ = (8453 * bayer[1] + 5531 * t0 + 1611 * t1 + 524288) >> 15;
bayer++;
adjacent_bayer++;
width -= 2;
} else {
/* First pixel */
t0 = bayer[1] + adjacent_bayer[0];
if (blue_line) {
*y++ = (8453 * adjacent_bayer[1] + 8297 * t0 +
3223 * bayer[0] + 524288) >> 15;
} else {
*y++ = (8453 * bayer[0] + 8297 * t0 +
3223 * adjacent_bayer[1] + 524288) >> 15;
}
width--;
}
if (blue_line) {
for ( ; width > 2; width -= 2) {
t0 = bayer[0] + bayer[2];
*y++ = (8453 * adjacent_bayer[1] + 16594 * bayer[1] +
1611 * t0 + 524288) >> 15;
bayer++;
adjacent_bayer++;
t0 = bayer[0] + bayer[2] + adjacent_bayer[1];
t1 = adjacent_bayer[0] + adjacent_bayer[2];
*y++ = (4226 * t1 + 5531 * t0 + 3223 * bayer[1] + 524288) >> 15;
bayer++;
adjacent_bayer++;
}
} else {
for ( ; width > 2; width -= 2) {
t0 = bayer[0] + bayer[2];
*y++ = (4226 * t0 + 16594 * bayer[1] +
3223 * adjacent_bayer[1] + 524288) >> 15;
bayer++;
adjacent_bayer++;
t0 = bayer[0] + bayer[2] + adjacent_bayer[1];
t1 = adjacent_bayer[0] + adjacent_bayer[2];
*y++ = (8453 * bayer[1] + 5531 * t0 + 1611 * t1 + 524288) >> 15;
bayer++;
adjacent_bayer++;
}
}
if (width == 2) {
/* Second to last pixel */
t0 = bayer[0] + bayer[2];
if (blue_line) {
*y++ = (8453 * adjacent_bayer[1] + 16594 * bayer[1] +
1611 * t0 + 524288) >> 15;
} else {
*y++ = (4226 * t0 + 16594 * bayer[1] +
3223 * adjacent_bayer[1] + 524288) >> 15;
}
/* Last pixel */
t0 = bayer[1] + adjacent_bayer[2];
if (blue_line) {
*y++ = (8453 * adjacent_bayer[1] + 8297 * t0 +
3223 * bayer[2] + 524288) >> 15;
} else {
*y++ = (8453 * bayer[2] + 8297 * t0 +
3223 * adjacent_bayer[1] + 524288) >> 15;
}
} else {
/* Last pixel */
if (blue_line) {
*y++ = (8453 * adjacent_bayer[1] + 16594 * bayer[1] +
3223 * bayer[0] + 524288) >> 15;
} else {
*y++ = (8453 * bayer[0] + 16594 * bayer[1] +
3223 * adjacent_bayer[1] + 524288) >> 15;
}
}
}
void v4lconvert_bayer_to_yuv420(const unsigned char *bayer, unsigned char *yuv,
int width, int height, const unsigned int stride, unsigned int src_pixfmt, int yvu)
{
int blue_line = 0, start_with_green = 0, x, y;
unsigned char *ydst = yuv;
unsigned char *udst, *vdst;
if (yvu) {
vdst = yuv + width * height;
udst = vdst + width * height / 4;
} else {
udst = yuv + width * height;
vdst = udst + width * height / 4;
}
/* First calculate the u and v planes 2x2 pixels at a time */
switch (src_pixfmt) {
case V4L2_PIX_FMT_SBGGR8:
for (y = 0; y < height; y += 2) {
for (x = 0; x < width; x += 2) {
int b, g, r;
b = bayer[x];
g = bayer[x + 1];
g += bayer[x + stride];
r = bayer[x + stride + 1];
*udst++ = (-4878 * r - 4789 * g + 14456 * b + 4210688) >> 15;
*vdst++ = (14456 * r - 6052 * g - 2351 * b + 4210688) >> 15;
}
bayer += 2 * stride;
}
blue_line = 1;
break;
case V4L2_PIX_FMT_SRGGB8:
for (y = 0; y < height; y += 2) {
for (x = 0; x < width; x += 2) {
int b, g, r;
r = bayer[x];
g = bayer[x + 1];
g += bayer[x + stride];
b = bayer[x + stride + 1];
*udst++ = (-4878 * r - 4789 * g + 14456 * b + 4210688) >> 15;
*vdst++ = (14456 * r - 6052 * g - 2351 * b + 4210688) >> 15;
}
bayer += 2 * stride;
}
break;
case V4L2_PIX_FMT_SGBRG8:
for (y = 0; y < height; y += 2) {
for (x = 0; x < width; x += 2) {
int b, g, r;
g = bayer[x];
b = bayer[x + 1];
r = bayer[x + stride];
g += bayer[x + stride + 1];
*udst++ = (-4878 * r - 4789 * g + 14456 * b + 4210688) >> 15;
*vdst++ = (14456 * r - 6052 * g - 2351 * b + 4210688) >> 15;
}
bayer += 2 * stride;
}
blue_line = 1;
start_with_green = 1;
break;
case V4L2_PIX_FMT_SGRBG8:
for (y = 0; y < height; y += 2) {
for (x = 0; x < width; x += 2) {
int b, g, r;
g = bayer[x];
r = bayer[x + 1];
b = bayer[x + stride];
g += bayer[x + stride + 1];
*udst++ = (-4878 * r - 4789 * g + 14456 * b + 4210688) >> 15;
*vdst++ = (14456 * r - 6052 * g - 2351 * b + 4210688) >> 15;
}
bayer += 2 * stride;
}
start_with_green = 1;
break;
}
/* Point bayer back to start of frame */
bayer -= stride * height;
/* render the first line */
v4lconvert_border_bayer_line_to_y(bayer, bayer + stride, ydst, width,
start_with_green, blue_line);
ydst += width;
/* reduce height by 2 because of the border */
for (height -= 2; height; height--) {
int t0, t1;
/* (width - 2) because of the border */
const unsigned char *bayer_end = bayer + (width - 2);
if (start_with_green) {
t0 = bayer[1] + bayer[stride * 2 + 1];
/* Write first pixel */
t1 = bayer[0] + bayer[stride * 2] + bayer[stride + 1];
if (blue_line)
*ydst++ = (8453 * bayer[stride] + 5516 * t1 +
1661 * t0 + 524288) >> 15;
else
*ydst++ = (4226 * t0 + 5516 * t1 +
3223 * bayer[stride] + 524288) >> 15;
/* Write second pixel */
t1 = bayer[stride] + bayer[stride + 2];
if (blue_line)
*ydst++ = (4226 * t1 + 16594 * bayer[stride + 1] +
1611 * t0 + 524288) >> 15;
else
*ydst++ = (4226 * t0 + 16594 * bayer[stride + 1] +
1611 * t1 + 524288) >> 15;
bayer++;
} else {
/* Write first pixel */
t0 = bayer[0] + bayer[stride * 2];
if (blue_line) {
*ydst++ = (8453 * bayer[stride + 1] + 16594 * bayer[stride] +
1661 * t0 + 524288) >> 15;
} else {
*ydst++ = (4226 * t0 + 16594 * bayer[stride] +
3223 * bayer[stride + 1] + 524288) >> 15;
}
}
if (blue_line) {
for (; bayer <= bayer_end - 2; bayer += 2) {
t0 = bayer[0] + bayer[2] + bayer[stride * 2] + bayer[stride * 2 + 2];
t1 = bayer[1] + bayer[stride] + bayer[stride + 2] + bayer[stride * 2 + 1];
*ydst++ = (8453 * bayer[stride + 1] + 4148 * t1 +
806 * t0 + 524288) >> 15;
t0 = bayer[2] + bayer[stride * 2 + 2];
t1 = bayer[stride + 1] + bayer[stride + 3];
*ydst++ = (4226 * t1 + 16594 * bayer[stride + 2] +
1611 * t0 + 524288) >> 15;
}
} else {
for (; bayer <= bayer_end - 2; bayer += 2) {
t0 = bayer[0] + bayer[2] + bayer[stride * 2] + bayer[stride * 2 + 2];
t1 = bayer[1] + bayer[stride] + bayer[stride + 2] + bayer[stride * 2 + 1];
*ydst++ = (2113 * t0 + 4148 * t1 +
3223 * bayer[stride + 1] + 524288) >> 15;
t0 = bayer[2] + bayer[stride * 2 + 2];
t1 = bayer[stride + 1] + bayer[stride + 3];
*ydst++ = (4226 * t0 + 16594 * bayer[stride + 2] +
1611 * t1 + 524288) >> 15;
}
}
if (bayer < bayer_end) {
/* Write second to last pixel */
t0 = bayer[0] + bayer[2] + bayer[stride * 2] + bayer[stride * 2 + 2];
t1 = bayer[1] + bayer[stride] + bayer[stride + 2] + bayer[stride * 2 + 1];
if (blue_line)
*ydst++ = (8453 * bayer[stride + 1] + 4148 * t1 +
806 * t0 + 524288) >> 15;
else
*ydst++ = (2113 * t0 + 4148 * t1 +
3223 * bayer[stride + 1] + 524288) >> 15;
/* write last pixel */
t0 = bayer[2] + bayer[stride * 2 + 2];
if (blue_line) {
*ydst++ = (8453 * bayer[stride + 1] + 16594 * bayer[stride + 2] +
1661 * t0 + 524288) >> 15;
} else {
*ydst++ = (4226 * t0 + 16594 * bayer[stride + 2] +
3223 * bayer[stride + 1] + 524288) >> 15;
}
bayer++;
} else {
/* write last pixel */
t0 = bayer[0] + bayer[stride * 2];
t1 = bayer[1] + bayer[stride * 2 + 1] + bayer[stride];
if (blue_line)
*ydst++ = (8453 * bayer[stride + 1] + 5516 * t1 +
1661 * t0 + 524288) >> 15;
else
*ydst++ = (4226 * t0 + 5516 * t1 +
3223 * bayer[stride + 1] + 524288) >> 15;
}
/* skip 2 border pixels and padding */
bayer += (stride - width) + 2;
blue_line = !blue_line;
start_with_green = !start_with_green;
}
/* render the last line */
v4lconvert_border_bayer_line_to_y(bayer + stride, bayer, ydst, width,
!start_with_green, !blue_line);
}
void v4lconvert_bayer10_to_bayer8(void *bayer10,
unsigned char *bayer8, int width, int height)
{
int i;
uint16_t *src = bayer10;
for (i = 0; i < width * height; i++)
bayer8[i] = src[i] >> 2;
}
void v4lconvert_bayer10p_to_bayer8(unsigned char *bayer10p,
unsigned char *bayer8, int width, int height)
{
unsigned long i;
unsigned long len = width * height;
for (i = 0; i < len ; i += 4) {
/*
* Do not use a second loop, hoping that
* a clever compiler with understand the
* pattern and will optimize it.
*/
bayer8[0] = bayer10p[0];
bayer8[1] = bayer10p[1];
bayer8[2] = bayer10p[2];
bayer8[3] = bayer10p[3];
bayer10p += 5;
bayer8 += 4;
}
}
void v4lconvert_bayer16_to_bayer8(unsigned char *bayer16,
unsigned char *bayer8, int width, int height)
{
int i;
for (i = 0; i < width * height; i++)
bayer8[i] = bayer16[2*i+1];
}

View File

@@ -0,0 +1,80 @@
/*
# (C) 2008-2009 Elmar Kleijn <elmar_kleijn@hotmail.com>
# (C) 2008-2009 Sjoerd Piepenbrink <need4weed@gmail.com>
# (C) 2008-2009 Radjnies Bhansingh <radjnies@gmail.com>
# (C) 2008-2009 Hans de Goede <hdegoede@redhat.com>
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 2.1 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
*/
#ifndef __LIBV4LCONTROL_PRIV_H
#define __LIBV4LCONTROL_PRIV_H
#include "libv4l-plugin.h"
#define V4LCONTROL_SHM_SIZE 4096
#define V4LCONTROL_SUPPORTS_NEXT_CTRL 0x01
#define V4LCONTROL_MEMORY_IS_MALLOCED 0x02
struct v4lcontrol_flags_info;
struct v4lcontrol_data {
int fd; /* Device fd */
int bandwidth; /* Connection bandwidth (0 = unknown) */
int flags; /* Flags for this device */
int priv_flags; /* Internal use only flags */
int controls; /* Which controls to use for this device */
unsigned int *shm_values; /* shared memory control value store */
unsigned int old_values[V4LCONTROL_COUNT]; /* for controls_changed() */
const struct v4lcontrol_flags_info *flags_info;
void *dev_ops_priv;
const struct libv4l_dev_ops *dev_ops;
};
struct v4lcontrol_flags_info {
unsigned short vendor_id;
unsigned short product_id;
unsigned short product_mask;
const char *dmi_board_vendor;
const char *dmi_board_name;
/* We could also use the USB manufacturer and product strings some devices have
const char *manufacturer;
const char *product; */
int flags;
int default_gamma;
/* Some seldom used dmi strings (for notebooks with bogus info in the board
entries, but usefull info elsewhere). We keep this at the end as to not
polute the initalizers for the normal case. */
/* System (product) vendor / name */
const char *dmi_system_vendor;
const char *dmi_system_name;
/* Board and System versions */
const char *dmi_board_version;
const char *dmi_system_version;
};
struct v4lcontrol_usb_id {
unsigned short vendor_id;
unsigned short product_id;
};
struct v4lcontrol_upside_down_table {
const char **board_vendor;
const char **board_name;
const struct v4lcontrol_usb_id *camera_id;
};
#endif

View File

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,79 @@
/*
# (C) 2008-2009 Elmar Kleijn <elmar_kleijn@hotmail.com>
# (C) 2008-2009 Sjoerd Piepenbrink <need4weed@gmail.com>
# (C) 2008-2009 Radjnies Bhansingh <radjnies@gmail.com>
# (C) 2008-2009 Hans de Goede <hdegoede@redhat.com>
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 2.1 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
*/
#ifndef __LIBV4LCONTROL_H
#define __LIBV4LCONTROL_H
#include "libv4l-plugin.h"
/* Flags */
#define V4LCONTROL_HFLIPPED 0x01
#define V4LCONTROL_VFLIPPED 0x02
#define V4LCONTROL_ROTATED_90_JPEG 0x04
#define V4LCONTROL_WANTS_WB 0x08
#define V4LCONTROL_WANTS_AUTOGAIN 0x10
#define V4LCONTROL_FORCE_TINYJPEG 0x20
/* Masks */
#define V4LCONTROL_WANTS_WB_AUTOGAIN (V4LCONTROL_WANTS_WB | V4LCONTROL_WANTS_AUTOGAIN)
/* Controls */
enum {
V4LCONTROL_WHITEBALANCE,
V4LCONTROL_HFLIP,
V4LCONTROL_VFLIP,
V4LCONTROL_GAMMA,
/* All fake controls above here are auto enabled when not present in hw */
V4LCONTROL_AUTO_ENABLE_COUNT,
V4LCONTROL_AUTOGAIN,
V4LCONTROL_AUTOGAIN_TARGET,
V4LCONTROL_COUNT
};
struct v4lcontrol_data;
struct v4lcontrol_data *v4lcontrol_create(int fd, void *dev_ops_priv,
const struct libv4l_dev_ops *dev_ops, int always_needs_conversion);
void v4lcontrol_destroy(struct v4lcontrol_data *data);
int v4lcontrol_get_bandwidth(struct v4lcontrol_data *data);
/* Functions used by v4lprocessing to get the control state */
int v4lcontrol_get_flags(struct v4lcontrol_data *data);
int v4lcontrol_get_ctrl(struct v4lcontrol_data *data, int ctrl);
/* Check if the controls have changed since the last time this function
was called */
int v4lcontrol_controls_changed(struct v4lcontrol_data *data);
/* Check if we must go through the conversion path (and thus alloc conversion
buffers, etc. in libv4l2). Note this always return 1 if we *may* need
rotate90 / flipping / processing, as if we actually need this may change
on the fly while the stream is active. */
int v4lcontrol_needs_conversion(struct v4lcontrol_data *data);
/* Functions used by v4lconvert to pass vidioc calls from libv4l2 */
int v4lcontrol_vidioc_queryctrl(struct v4lcontrol_data *data, void *arg);
int v4lcontrol_vidioc_g_ctrl(struct v4lcontrol_data *data, void *arg);
int v4lcontrol_vidioc_s_ctrl(struct v4lcontrol_data *data, void *arg);
int v4lcontrol_vidioc_g_ext_ctrls(struct v4lcontrol_data *data, void *arg);
int v4lcontrol_vidioc_try_ext_ctrls(struct v4lcontrol_data *data, void *arg);
int v4lcontrol_vidioc_s_ext_ctrls(struct v4lcontrol_data *data, void *arg);
#endif

214
libv4lconvert/cpia1.c Normal file
View File

@@ -0,0 +1,214 @@
/*
# (C) 2010 Hans de Goede <hdegoede@redhat.com>
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 2.1 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
*/
#include "libv4lconvert-priv.h"
#include <stdlib.h>
#include <string.h>
#define MAGIC_0 0x19
#define MAGIC_1 0x68
#define SUBSAMPLE_420 0
#define SUBSAMPLE_422 1
#define YUVORDER_YUYV 0
#define YUVORDER_UYVY 1
#define NOT_COMPRESSED 0
#define COMPRESSED 1
#define NO_DECIMATION 0
#define DECIMATION_ENAB 1
#define EOI 0xff /* End Of Image */
#define EOL 0xfd /* End Of Line */
#define FRAME_HEADER_SIZE 64
/* CPIA YUYV (sometimes sort of compressed) */
int v4lconvert_cpia1_to_yuv420(struct v4lconvert_data *data,
const unsigned char *src, int src_size,
unsigned char *dest, int width, int height, int yvu)
{
int x, y, ll, compressed;
unsigned char *udest, *vdest;
if (width > 352 || height > 288) {
fprintf(stderr, "FATAL ERROR CPIA1 size > 352x288, please report!\n");
return -1;
}
if (data->previous_frame == NULL) {
data->previous_frame = malloc(352 * 288 * 3 / 2);
if (data->previous_frame == NULL) {
fprintf(stderr, "cpia1 decode error: could not allocate buffer!\n");
return -1;
}
}
if (yvu) {
vdest = dest + width * height;
udest = vdest + width * height / 4;
} else {
udest = dest + width * height;
vdest = udest + width * height / 4;
}
/* Verify header */
if (src_size < FRAME_HEADER_SIZE ||
src[0] != MAGIC_0 || src[1] != MAGIC_1 ||
src[17] != SUBSAMPLE_420 ||
src[18] != YUVORDER_YUYV ||
(src[25] - src[24]) * 8 != width ||
(src[27] - src[26]) * 4 != height ||
(src[28] != NOT_COMPRESSED && src[28] != COMPRESSED) ||
(src[29] != NO_DECIMATION && src[29] != DECIMATION_ENAB)) {
fprintf(stderr, "cpia1 decode error: invalid header\n");
return -1;
}
if (src[29] == DECIMATION_ENAB) {
fprintf(stderr, "cpia1 decode error: decimation is not supported\n");
return -1;
}
compressed = src[28] == COMPRESSED;
src += FRAME_HEADER_SIZE;
src_size -= FRAME_HEADER_SIZE;
if (!compressed) {
for (y = 0; y < height && src_size > 2; y++) {
ll = src[0] | (src[1] << 8);
src += 2;
src_size -= 2;
if (src_size < ll) {
fprintf(stderr, "cpia1 decode error: short frame\n");
return -1;
}
if (src[ll - 1] != EOL) {
fprintf(stderr, "cpia1 decode error: invalid terminated line\n");
return -1;
}
if (!(y & 1)) { /* Even line Y + UV in the form of YUYV */
if (ll != 2 * width + 1) {
fprintf(stderr, "cpia1 decode error: invalid uncompressed even ll\n");
return -1;
}
/* copy the Y values */
for (x = 0; x < width; x += 2) {
*dest++ = src[0];
*dest++ = src[2];
src += 4;
}
/* copy the UV values */
src -= 2 * width;
for (x = 0; x < width; x += 2) {
*udest++ = src[1];
*vdest++ = src[3];
src += 4;
}
} else { /* Odd line only Y values */
if (ll != width + 1) {
fprintf(stderr, "cpia1 decode error: invalid uncompressed odd ll\n");
return -1;
}
memcpy(dest, src, width);
dest += width;
src += width;
}
src++; /* Skip EOL */
src_size -= ll;
}
} else { /* compressed */
/* Pre-fill dest with previous frame, as the cpia1 "compression" consists
of simply ommitting certain pixels */
memcpy(dest, data->previous_frame, width * height * 3 / 2);
for (y = 0; y < height && src_size > 2; y++) {
ll = src[0] | (src[1] << 8);
src += 2;
src_size -= 2;
if (src_size < ll) {
fprintf(stderr, "cpia1 decode error: short frame\n");
return -1;
}
if (src[ll - 1] != EOL) {
fprintf(stderr, "cpia1 decode error: invalid terminated line\n");
return -1;
}
/* Do this now as we use ll as loop variable below */
src_size -= ll;
for (x = 0; x < width && ll > 1; ) {
if (*src & 1) { /* skip N pixels */
int skip = *src >> 1;
if (skip & 1) {
fprintf(stderr, "cpia1 decode error: odd number of pixels to skip");
return -1;
}
if (!(y & 1)) { /* Even line Y + UV in the form of YUYV */
dest += skip;
udest += skip / 2;
vdest += skip / 2;
} else { /* Odd line only Y values */
dest += skip;
}
x += skip;
src++;
ll--;
} else {
if (!(y & 1)) { /* Even line Y + UV in the form of YUYV */
*dest++ = *src++;
*udest++ = *src++;
*dest++ = *src++;
*vdest++ = *src++;
ll -= 4;
} else { /* Odd line only Y values */
*dest++ = *src++;
*dest++ = *src++;
ll -= 2;
}
x += 2;
}
}
if (ll != 1 || x != width) {
fprintf(stderr, "cpia1 decode error: line length mismatch\n");
return -1;
}
src++; /* Skip EOL */
}
}
if (y != height) {
fprintf(stderr, "cpia1 decode error: frame height mismatch\n");
return -1;
}
if (src_size < 4 || src[src_size - 4] != EOI || src[src_size - 3] != EOI ||
src[src_size - 2] != EOI || src[src_size - 1] != EOI) {
fprintf(stderr, "cpia1 decode error: invaled EOI marker\n");
return -1;
}
/* Safe frame for decompression of the next frame */
dest -= width * height;
memcpy(data->previous_frame, dest, width * height * 3 / 2);
return 0;
}

291
libv4lconvert/crop.c Normal file
View File

@@ -0,0 +1,291 @@
/*
# RGB and YUV crop routines
# (C) 2008 Hans de Goede <hdegoede@redhat.com>
#
# SPDX-FileCopyrightText: Copyright (c) 2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: LGPL-2.1-or-later
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 2.1 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
*/
#include <string.h>
#include "libv4lconvert-priv.h"
static void v4lconvert_reduceandcrop_rgbbgr24(
unsigned char *src, unsigned char *dest,
const struct v4l2_format *src_fmt, const struct v4l2_format *dest_fmt)
{
unsigned int x, y;
int startx = src_fmt->fmt.pix.width / 2 - dest_fmt->fmt.pix.width;
int starty = src_fmt->fmt.pix.height / 2 - dest_fmt->fmt.pix.height;
src += starty * src_fmt->fmt.pix.bytesperline + 3 * startx;
for (y = 0; y < dest_fmt->fmt.pix.height; y++) {
unsigned char *mysrc = src;
for (x = 0; x < dest_fmt->fmt.pix.width; x++) {
*(dest++) = *(mysrc++);
*(dest++) = *(mysrc++);
*(dest++) = *(mysrc++);
mysrc += 3; /* skip one pixel */
}
src += 2 * src_fmt->fmt.pix.bytesperline; /* skip one line */
}
}
static void v4lconvert_crop_rgbbgr24(unsigned char *src, unsigned char *dest,
const struct v4l2_format *src_fmt, const struct v4l2_format *dest_fmt)
{
unsigned int x;
int startx = (src_fmt->fmt.pix.width - dest_fmt->fmt.pix.width) / 2;
int starty = (src_fmt->fmt.pix.height - dest_fmt->fmt.pix.height) / 2;
src += starty * src_fmt->fmt.pix.bytesperline + 3 * startx;
for (x = 0; x < dest_fmt->fmt.pix.height; x++) {
memcpy(dest, src, dest_fmt->fmt.pix.width * 3);
src += src_fmt->fmt.pix.bytesperline;
dest += dest_fmt->fmt.pix.bytesperline;
}
}
static void v4lconvert_reduceandcrop_yuv420(
unsigned char *src, unsigned char *dest,
const struct v4l2_format *src_fmt, const struct v4l2_format *dest_fmt)
{
unsigned int x, y;
unsigned int dest_height_half = dest_fmt->fmt.pix.height / 2;
unsigned int dest_width_half = dest_fmt->fmt.pix.width / 2;
int startx = (src_fmt->fmt.pix.width / 2 - dest_fmt->fmt.pix.width) & ~1;
int starty = (src_fmt->fmt.pix.height / 2 - dest_fmt->fmt.pix.height) & ~1;
unsigned char *mysrc, *mysrc2;
/* Y */
mysrc = src + starty * src_fmt->fmt.pix.bytesperline + startx;
for (y = 0; y < dest_fmt->fmt.pix.height; y++) {
mysrc2 = mysrc;
for (x = 0; x < dest_fmt->fmt.pix.width; x++) {
*(dest++) = *mysrc2;
mysrc2 += 2; /* skip one pixel */
}
mysrc += 2 * src_fmt->fmt.pix.bytesperline; /* skip one line */
}
/* U */
mysrc = src + src_fmt->fmt.pix.height * src_fmt->fmt.pix.bytesperline +
(starty / 2) * src_fmt->fmt.pix.bytesperline / 2 + startx / 2;
for (y = 0; y < dest_height_half; y++) {
mysrc2 = mysrc;
for (x = 0; x < dest_width_half; x++) {
*(dest++) = *mysrc2;
mysrc2 += 2; /* skip one pixel */
}
mysrc += src_fmt->fmt.pix.bytesperline ; /* skip one line */
}
/* V */
mysrc = src + src_fmt->fmt.pix.height * src_fmt->fmt.pix.bytesperline * 5 / 4
+ (starty / 2) * src_fmt->fmt.pix.bytesperline / 2 + startx / 2;
for (y = 0; y < dest_height_half; y++) {
mysrc2 = mysrc;
for (x = 0; x < dest_width_half; x++) {
*(dest++) = *mysrc2;
mysrc2 += 2; /* skip one pixel */
}
mysrc += src_fmt->fmt.pix.bytesperline ; /* skip one line */
}
}
static void v4lconvert_crop_yuv420(unsigned char *src, unsigned char *dest,
const struct v4l2_format *src_fmt, const struct v4l2_format *dest_fmt)
{
unsigned int x;
int startx = ((src_fmt->fmt.pix.width - dest_fmt->fmt.pix.width) / 2) & ~1;
int starty = ((src_fmt->fmt.pix.height - dest_fmt->fmt.pix.height) / 2) & ~1;
unsigned char *mysrc = src + starty * src_fmt->fmt.pix.bytesperline + startx;
/* Y */
for (x = 0; x < dest_fmt->fmt.pix.height; x++) {
memcpy(dest, mysrc, dest_fmt->fmt.pix.width);
mysrc += src_fmt->fmt.pix.bytesperline;
dest += dest_fmt->fmt.pix.bytesperline;
}
/* U */
mysrc = src + src_fmt->fmt.pix.height * src_fmt->fmt.pix.bytesperline +
(starty / 2) * src_fmt->fmt.pix.bytesperline / 2 + startx / 2;
for (x = 0; x < dest_fmt->fmt.pix.height / 2; x++) {
memcpy(dest, mysrc, dest_fmt->fmt.pix.width / 2);
mysrc += src_fmt->fmt.pix.bytesperline / 2;
dest += dest_fmt->fmt.pix.bytesperline / 2;
}
/* V */
mysrc = src + src_fmt->fmt.pix.height * src_fmt->fmt.pix.bytesperline * 5 / 4
+ (starty / 2) * src_fmt->fmt.pix.bytesperline / 2 + startx / 2;
for (x = 0; x < dest_fmt->fmt.pix.height / 2; x++) {
memcpy(dest, mysrc, dest_fmt->fmt.pix.width / 2);
mysrc += src_fmt->fmt.pix.bytesperline / 2;
dest += dest_fmt->fmt.pix.bytesperline / 2;
}
}
/* Ok, so this is not really cropping, but more the reverse, whatever */
static void v4lconvert_add_border_rgbbgr24(
unsigned char *src, unsigned char *dest,
const struct v4l2_format *src_fmt, const struct v4l2_format *dest_fmt)
{
int y;
int borderx = (dest_fmt->fmt.pix.width - src_fmt->fmt.pix.width) / 2;
int bordery = (dest_fmt->fmt.pix.height - src_fmt->fmt.pix.height) / 2;
for (y = 0; y < bordery; y++) {
memset(dest, 0, dest_fmt->fmt.pix.width * 3);
dest += dest_fmt->fmt.pix.bytesperline;
}
for (y = 0; (unsigned)y < src_fmt->fmt.pix.height; y++) {
memset(dest, 0, borderx * 3);
dest += borderx * 3;
memcpy(dest, src, src_fmt->fmt.pix.width * 3);
src += src_fmt->fmt.pix.bytesperline;
dest += src_fmt->fmt.pix.width * 3;
memset(dest, 0, borderx * 3);
dest += dest_fmt->fmt.pix.bytesperline -
(borderx + src_fmt->fmt.pix.width) * 3;
}
for (y = 0; y < bordery; y++) {
memset(dest, 0, dest_fmt->fmt.pix.width * 3);
dest += dest_fmt->fmt.pix.bytesperline;
}
}
static void v4lconvert_add_border_yuv420(
unsigned char *src, unsigned char *dest,
const struct v4l2_format *src_fmt, const struct v4l2_format *dest_fmt)
{
int y;
int borderx = ((dest_fmt->fmt.pix.width - src_fmt->fmt.pix.width) / 2) & ~1;
int bordery = ((dest_fmt->fmt.pix.height - src_fmt->fmt.pix.height) / 2) & ~1;
/* Y */
for (y = 0; y < bordery; y++) {
memset(dest, 16, dest_fmt->fmt.pix.width);
dest += dest_fmt->fmt.pix.bytesperline;
}
for (y = 0; (unsigned)y < src_fmt->fmt.pix.height; y++) {
memset(dest, 16, borderx);
dest += borderx;
memcpy(dest, src, src_fmt->fmt.pix.width);
src += src_fmt->fmt.pix.bytesperline;
dest += src_fmt->fmt.pix.width;
memset(dest, 16, borderx);
dest += dest_fmt->fmt.pix.bytesperline -
(borderx + src_fmt->fmt.pix.width);
}
for (y = 0; y < bordery; y++) {
memset(dest, 16, dest_fmt->fmt.pix.width);
dest += dest_fmt->fmt.pix.bytesperline;
}
/* U */
for (y = 0; y < bordery / 2; y++) {
memset(dest, 128, dest_fmt->fmt.pix.width / 2);
dest += dest_fmt->fmt.pix.bytesperline / 2;
}
for (y = 0; (unsigned)y < src_fmt->fmt.pix.height / 2; y++) {
memset(dest, 128, borderx / 2);
dest += borderx / 2;
memcpy(dest, src, src_fmt->fmt.pix.width / 2);
src += src_fmt->fmt.pix.bytesperline / 2;
dest += src_fmt->fmt.pix.width / 2;
memset(dest, 128, borderx / 2);
dest += (dest_fmt->fmt.pix.bytesperline -
(borderx + src_fmt->fmt.pix.width)) / 2;
}
for (y = 0; y < bordery / 2; y++) {
memset(dest, 128, dest_fmt->fmt.pix.width / 2);
dest += dest_fmt->fmt.pix.bytesperline / 2;
}
/* V */
for (y = 0; y < bordery / 2; y++) {
memset(dest, 128, dest_fmt->fmt.pix.width / 2);
dest += dest_fmt->fmt.pix.bytesperline / 2;
}
for (y = 0; (unsigned)y < src_fmt->fmt.pix.height / 2; y++) {
memset(dest, 128, borderx / 2);
dest += borderx / 2;
memcpy(dest, src, src_fmt->fmt.pix.width / 2);
src += src_fmt->fmt.pix.bytesperline / 2;
dest += src_fmt->fmt.pix.width / 2;
memset(dest, 128, borderx / 2);
dest += (dest_fmt->fmt.pix.bytesperline -
(borderx + src_fmt->fmt.pix.width)) / 2;
}
for (y = 0; y < bordery / 2; y++) {
memset(dest, 128, dest_fmt->fmt.pix.width / 2);
dest += dest_fmt->fmt.pix.bytesperline / 2;
}
}
void v4lconvert_crop(unsigned char *src, unsigned char *dest,
const struct v4l2_format *src_fmt, const struct v4l2_format *dest_fmt)
{
switch (dest_fmt->fmt.pix.pixelformat) {
case V4L2_PIX_FMT_RGB24:
case V4L2_PIX_FMT_BGR24:
if (src_fmt->fmt.pix.width <= dest_fmt->fmt.pix.width &&
src_fmt->fmt.pix.height <= dest_fmt->fmt.pix.height)
v4lconvert_add_border_rgbbgr24(src, dest, src_fmt, dest_fmt);
else if (src_fmt->fmt.pix.width >= 2 * dest_fmt->fmt.pix.width &&
src_fmt->fmt.pix.height >= 2 * dest_fmt->fmt.pix.height)
v4lconvert_reduceandcrop_rgbbgr24(src, dest, src_fmt, dest_fmt);
else
v4lconvert_crop_rgbbgr24(src, dest, src_fmt, dest_fmt);
break;
case V4L2_PIX_FMT_YUV420:
case V4L2_PIX_FMT_YVU420:
if (src_fmt->fmt.pix.width <= dest_fmt->fmt.pix.width &&
src_fmt->fmt.pix.height <= dest_fmt->fmt.pix.height)
v4lconvert_add_border_yuv420(src, dest, src_fmt, dest_fmt);
else if (src_fmt->fmt.pix.width >= 2 * dest_fmt->fmt.pix.width &&
src_fmt->fmt.pix.height >= 2 * dest_fmt->fmt.pix.height)
v4lconvert_reduceandcrop_yuv420(src, dest, src_fmt, dest_fmt);
else
v4lconvert_crop_yuv420(src, dest, src_fmt, dest_fmt);
break;
}
}

270
libv4lconvert/flip.c Normal file
View File

@@ -0,0 +1,270 @@
/*
# RGB / YUV flip/rotate routines
# (C) 2008 Hans de Goede <hdegoede@redhat.com>
#
# SPDX-FileCopyrightText: Copyright (c) 2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: LGPL-2.1-or-later
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 2.1 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
*/
#include <string.h>
#include "libv4lconvert-priv.h"
static void v4lconvert_vflip_rgbbgr24(unsigned char *src, unsigned char *dest,
struct v4l2_format *fmt)
{
unsigned int y;
src += fmt->fmt.pix.height * fmt->fmt.pix.bytesperline;
for (y = 0; y < fmt->fmt.pix.height; y++) {
src -= fmt->fmt.pix.bytesperline;
memcpy(dest, src, fmt->fmt.pix.width * 3);
dest += fmt->fmt.pix.width * 3;
}
}
static void v4lconvert_vflip_yuv420(unsigned char *src, unsigned char *dest,
struct v4l2_format *fmt)
{
unsigned int y;
/* First flip the Y plane */
src += fmt->fmt.pix.height * fmt->fmt.pix.bytesperline;
for (y = 0; y < fmt->fmt.pix.height; y++) {
src -= fmt->fmt.pix.bytesperline;
memcpy(dest, src, fmt->fmt.pix.width);
dest += fmt->fmt.pix.width;
}
/* Now flip the U plane */
src += fmt->fmt.pix.height * fmt->fmt.pix.bytesperline * 5 / 4;
for (y = 0; y < fmt->fmt.pix.height / 2; y++) {
src -= fmt->fmt.pix.bytesperline / 2;
memcpy(dest, src, fmt->fmt.pix.width / 2);
dest += fmt->fmt.pix.width / 2;
}
/* Last flip the V plane */
src += fmt->fmt.pix.height * fmt->fmt.pix.bytesperline / 2;
for (y = 0; y < fmt->fmt.pix.height / 2; y++) {
src -= fmt->fmt.pix.bytesperline / 2;
memcpy(dest, src, fmt->fmt.pix.width / 2);
dest += fmt->fmt.pix.width / 2;
}
}
static void v4lconvert_hflip_rgbbgr24(unsigned char *src, unsigned char *dest,
struct v4l2_format *fmt)
{
unsigned int x, y;
for (y = 0; y < fmt->fmt.pix.height; y++) {
src += fmt->fmt.pix.width * 3;
for (x = 0; x < fmt->fmt.pix.width; x++) {
src -= 3;
dest[0] = src[0];
dest[1] = src[1];
dest[2] = src[2];
dest += 3;
}
src += fmt->fmt.pix.bytesperline;
}
}
static void v4lconvert_hflip_yuv420(unsigned char *src, unsigned char *dest,
struct v4l2_format *fmt)
{
unsigned int x, y;
/* First flip the Y plane */
for (y = 0; y < fmt->fmt.pix.height; y++) {
src += fmt->fmt.pix.width;
for (x = 0; x < fmt->fmt.pix.width; x++)
*dest++ = *--src;
src += fmt->fmt.pix.bytesperline;
}
/* Now flip the U plane */
for (y = 0; y < fmt->fmt.pix.height / 2; y++) {
src += fmt->fmt.pix.width / 2;
for (x = 0; x < fmt->fmt.pix.width / 2; x++)
*dest++ = *--src;
src += fmt->fmt.pix.bytesperline / 2;
}
/* Last flip the V plane */
for (y = 0; y < fmt->fmt.pix.height / 2; y++) {
src += fmt->fmt.pix.width / 2;
for (x = 0; x < fmt->fmt.pix.width / 2; x++)
*dest++ = *--src;
src += fmt->fmt.pix.bytesperline / 2;
}
}
static void v4lconvert_rotate180_rgbbgr24(const unsigned char *src,
unsigned char *dst, int width, int height)
{
int i;
src += 3 * width * height - 3;
for (i = 0; i < width * height; i++) {
dst[0] = src[0];
dst[1] = src[1];
dst[2] = src[2];
dst += 3;
src -= 3;
}
}
static void v4lconvert_rotate180_yuv420(const unsigned char *src,
unsigned char *dst, int width, int height)
{
int i;
/* First flip x and y of the Y plane */
src += width * height - 1;
for (i = 0; i < width * height; i++)
*dst++ = *src--;
/* Now flip the U plane */
src += width * height * 5 / 4;
for (i = 0; i < width * height / 4; i++)
*dst++ = *src--;
/* Last flip the V plane */
src += width * height / 2;
for (i = 0; i < width * height / 4; i++)
*dst++ = *src--;
}
static void v4lconvert_rotate90_rgbbgr24(const unsigned char *src,
unsigned char *dst, int destwidth, int destheight)
{
int x, y;
#define srcwidth destheight
#define srcheight destwidth
for (y = 0; y < destheight; y++)
for (x = 0; x < destwidth; x++) {
int offset = ((srcheight - x - 1) * srcwidth + y) * 3;
*dst++ = src[offset++];
*dst++ = src[offset++];
*dst++ = src[offset];
}
}
static void v4lconvert_rotate90_yuv420(const unsigned char *src,
unsigned char *dst, int destwidth, int destheight)
{
int x, y;
/* Y-plane */
for (y = 0; y < destheight; y++)
for (x = 0; x < destwidth; x++) {
int offset = (srcheight - x - 1) * srcwidth + y;
*dst++ = src[offset];
}
/* U-plane */
src += srcwidth * srcheight;
destwidth /= 2;
destheight /= 2;
for (y = 0; y < destheight; y++)
for (x = 0; x < destwidth; x++) {
int offset = (srcheight - x - 1) * srcwidth + y;
*dst++ = src[offset];
}
/* V-plane */
src += srcwidth * srcheight;
for (y = 0; y < destheight; y++)
for (x = 0; x < destwidth; x++) {
int offset = (srcheight - x - 1) * srcwidth + y;
*dst++ = src[offset];
}
}
void v4lconvert_rotate90(unsigned char *src, unsigned char *dest,
struct v4l2_format *fmt)
{
int tmp;
tmp = fmt->fmt.pix.width;
fmt->fmt.pix.width = fmt->fmt.pix.height;
fmt->fmt.pix.height = tmp;
switch (fmt->fmt.pix.pixelformat) {
case V4L2_PIX_FMT_RGB24:
case V4L2_PIX_FMT_BGR24:
v4lconvert_rotate90_rgbbgr24(src, dest, fmt->fmt.pix.width,
fmt->fmt.pix.height);
break;
case V4L2_PIX_FMT_YUV420:
case V4L2_PIX_FMT_YVU420:
v4lconvert_rotate90_yuv420(src, dest, fmt->fmt.pix.width,
fmt->fmt.pix.height);
break;
}
v4lconvert_fixup_fmt(fmt);
}
void v4lconvert_flip(unsigned char *src, unsigned char *dest,
struct v4l2_format *fmt, int hflip, int vflip)
{
if (vflip && hflip) {
switch (fmt->fmt.pix.pixelformat) {
case V4L2_PIX_FMT_RGB24:
case V4L2_PIX_FMT_BGR24:
v4lconvert_rotate180_rgbbgr24(src, dest, fmt->fmt.pix.width,
fmt->fmt.pix.height);
break;
case V4L2_PIX_FMT_YUV420:
case V4L2_PIX_FMT_YVU420:
v4lconvert_rotate180_yuv420(src, dest, fmt->fmt.pix.width,
fmt->fmt.pix.height);
break;
}
} else if (hflip) {
switch (fmt->fmt.pix.pixelformat) {
case V4L2_PIX_FMT_RGB24:
case V4L2_PIX_FMT_BGR24:
v4lconvert_hflip_rgbbgr24(src, dest, fmt);
break;
case V4L2_PIX_FMT_YUV420:
case V4L2_PIX_FMT_YVU420:
v4lconvert_hflip_yuv420(src, dest, fmt);
break;
}
} else if (vflip) {
switch (fmt->fmt.pix.pixelformat) {
case V4L2_PIX_FMT_RGB24:
case V4L2_PIX_FMT_BGR24:
v4lconvert_vflip_rgbbgr24(src, dest, fmt);
break;
case V4L2_PIX_FMT_YUV420:
case V4L2_PIX_FMT_YVU420:
v4lconvert_vflip_yuv420(src, dest, fmt);
break;
}
}
/* Our newly written data has no padding */
v4lconvert_fixup_fmt(fmt);
}

View File

@@ -0,0 +1,79 @@
/* Utility functions for decompression helpers
*
* Copyright (c) 2009 Hans de Goede <hdegoede@redhat.com>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
static int v4lconvert_helper_write(int fd, const void *b, size_t count,
char *progname)
{
const unsigned char *buf = b;
size_t ret, written = 0;
while (written < count) {
ret = write(fd, buf + written, count - written);
if (ret == -1) {
if (errno == EINTR)
continue;
if (errno == EPIPE) /* Main program has quited */
exit(0);
fprintf(stderr, "%s: error writing: %s\n", progname, strerror(errno));
return -1;
}
written += ret;
}
return 0;
}
static int v4lconvert_helper_read(int fd, void *b, size_t count,
char *progname)
{
unsigned char *buf = b;
size_t ret, r = 0;
while (r < count) {
ret = read(fd, buf + r, count - r);
if (ret == -1) {
if (errno == EINTR)
continue;
fprintf(stderr, "%s: error reading: %s\n", progname, strerror(errno));
return -1;
}
if (ret == 0) /* EOF */
exit(0);
r += ret;
}
return 0;
}

223
libv4lconvert/helper.c Normal file
View File

@@ -0,0 +1,223 @@
/*
# (C) 2009 Hans de Goede <hdegoede@redhat.com>
#
# SPDX-FileCopyrightText: Copyright (c) 2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: LGPL-2.1-or-later
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 2.1 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <signal.h>
#include <sys/wait.h>
#include "libv4lconvert-priv.h"
#define READ_END 0
#define WRITE_END 1
/* <sigh> Unfortunately I've failed in contact some Authors of decompression
code of out of tree drivers. So I've no permission to relicense their code
their code from GPL to LGPL. To work around this, these decompression
algorithms are put in separate executables and we pipe data through these
to decompress.
The "protocol" is very simple:
From libv4l to the helper the following is send:
int width
int height
int flags
int data length
unsigned char[] data (data length long)
From the helper to libv4l the following is send:
int data length (-1 in case of a decompression error)
unsigned char[] data (not present when a decompression error happened)
*/
static int v4lconvert_helper_start(struct v4lconvert_data *data,
const char *helper)
{
if (pipe(data->decompress_in_pipe)) {
V4LCONVERT_ERR("with helper pipe: %s\n", strerror(errno));
goto error;
}
if (pipe(data->decompress_out_pipe)) {
V4LCONVERT_ERR("with helper pipe: %s\n", strerror(errno));
goto error_close_in_pipe;
}
data->decompress_pid = fork();
if (data->decompress_pid == -1) {
V4LCONVERT_ERR("with helper fork: %s\n", strerror(errno));
goto error_close_out_pipe;
}
if (data->decompress_pid == 0) {
/* We are the child */
/* Closed unused read / write end of the pipes */
close(data->decompress_out_pipe[WRITE_END]);
close(data->decompress_in_pipe[READ_END]);
/* Connect stdin / out to the pipes */
if (dup2(data->decompress_out_pipe[READ_END], STDIN_FILENO) == -1) {
perror("libv4lconvert: error with helper dup2");
exit(1);
}
if (dup2(data->decompress_in_pipe[WRITE_END], STDOUT_FILENO) == -1) {
perror("libv4lconvert: error with helper dup2");
exit(1);
}
/* And execute the helper */
execl(helper, helper, NULL);
/* We should never get here */
perror("libv4lconvert: error starting helper");
exit(1);
} else {
/* Closed unused read / write end of the pipes */
close(data->decompress_out_pipe[READ_END]);
close(data->decompress_in_pipe[WRITE_END]);
}
return 0;
error_close_out_pipe:
close(data->decompress_out_pipe[READ_END]);
close(data->decompress_out_pipe[WRITE_END]);
error_close_in_pipe:
close(data->decompress_in_pipe[READ_END]);
close(data->decompress_in_pipe[WRITE_END]);
error:
return -1;
}
/* IMPROVE ME: we could block SIGPIPE here using pthread_sigmask()
and then in case of EPIPE consume the signal using
sigtimedwait (we need to check if a blocked signal wasn't present
before the write, otherwise we will consume that) and
after consuming the signal try to restart the helper.
Note we currently do not do this, as SIGPIPE only happens if the
decompressor crashes, which in case of an embedded decompressor
would mean end of program, so by not handling SIGPIPE we treat
external decompressors identical. */
static int v4lconvert_helper_write(struct v4lconvert_data *data,
const void *b, size_t count)
{
const unsigned char *buf = b;
size_t ret, written = 0;
while (written < count) {
ret = write(data->decompress_out_pipe[WRITE_END], buf + written,
count - written);
if ((int)ret == -1) {
if (errno == EINTR)
continue;
V4LCONVERT_ERR("writing to helper: %s\n", strerror(errno));
return -1;
}
written += ret;
}
return 0;
}
static int v4lconvert_helper_read(struct v4lconvert_data *data, void *b,
size_t count)
{
unsigned char *buf = b;
size_t ret, r = 0;
while (r < count) {
ret = read(data->decompress_in_pipe[READ_END], buf + r, count - r);
if ((int)ret == -1) {
if (errno == EINTR)
continue;
V4LCONVERT_ERR("reading from helper: %s\n", strerror(errno));
return -1;
}
if (ret == 0) {
V4LCONVERT_ERR("reading from helper: unexpected EOF\n");
return -1;
}
r += ret;
}
return 0;
}
int v4lconvert_helper_decompress(struct v4lconvert_data *data,
const char *helper, const unsigned char *src, int src_size,
unsigned char *dest, int dest_size, int width, int height, int flags)
{
int r;
if (data->decompress_pid == -1) {
if (v4lconvert_helper_start(data, helper))
return -1;
}
if (v4lconvert_helper_write(data, &width, sizeof(int)))
return -1;
if (v4lconvert_helper_write(data, &height, sizeof(int)))
return -1;
if (v4lconvert_helper_write(data, &flags, sizeof(int)))
return -1;
if (v4lconvert_helper_write(data, &src_size, sizeof(int)))
return -1;
if (v4lconvert_helper_write(data, src, src_size))
return -1;
if (v4lconvert_helper_read(data, &r, sizeof(int)))
return -1;
if (r < 0) {
V4LCONVERT_ERR("decompressing frame data\n");
return -1;
}
if (dest_size < r) {
V4LCONVERT_ERR("destination buffer to small\n");
return -1;
}
return v4lconvert_helper_read(data, dest, r);
}
void v4lconvert_helper_cleanup(struct v4lconvert_data *data)
{
int status;
if (data->decompress_pid != -1) {
close(data->decompress_out_pipe[WRITE_END]);
close(data->decompress_in_pipe[READ_END]);
waitpid(data->decompress_pid, &status, 0);
data->decompress_pid = -1;
}
}

162
libv4lconvert/hm12.c Normal file
View File

@@ -0,0 +1,162 @@
/*
cx2341x HM12 conversion routines
(C) 2009 Hans Verkuil <hverkuil@xs4all.nl>
SPDX-FileCopyrightText: Copyright (c) 2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
SPDX-License-Identifier: LGPL-2.1-or-later
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
*/
#include "libv4lconvert-priv.h"
#include <string.h>
/* The HM12 format is used in the Conexant cx23415/6/8 MPEG encoder devices.
It is a macroblock format with separate Y and UV planes, each plane
consisting of 16x16 values. All lines are always 720 bytes long. If the
width of the image is less than 720, then the remainder is padding.
The height has to be a multiple of 32 in order to get correct chroma
values.
It is basically a by-product of the MPEG encoding inside the device,
which is available for raw video as a 'bonus feature'.
*/
#define CLIP(color) \
(unsigned char)(((color) > 0xff) ? 0xff : (((color) < 0) ? 0 : (color)))
static const int stride = 720;
static void v4lconvert_hm12_to_rgb(const unsigned char *src, unsigned char *dest,
int width, int height, int rgb)
{
unsigned int y, x, i, j;
const unsigned char *y_base = src;
const unsigned char *uv_base = src + stride * height;
const unsigned char *src_y;
const unsigned char *src_uv;
int mb_size = 256;
int r = rgb ? 0 : 2;
int b = 2 - r;
for (y = 0; y < (unsigned)height; y += 16) {
int mb_y = (y / 16) * (stride / 16);
int mb_uv = (y / 32) * (stride / 16);
int maxy = (height - y < 16 ? height - y : 16);
for (x = 0; x < (unsigned)width; x += 16, mb_y++, mb_uv++) {
int maxx = (width - x < 16 ? width - x : 16);
src_y = y_base + mb_y * mb_size;
src_uv = uv_base + mb_uv * mb_size;
if (y & 0x10)
src_uv += mb_size / 2;
for (i = 0; i < (unsigned)maxy; i++) {
int idx = (x + (y + i) * width) * 3;
for (j = 0; j < (unsigned)maxx; j++) {
int y = src_y[j];
int u = src_uv[j & ~1];
int v = src_uv[j | 1];
int u1 = (((u - 128) << 7) + (u - 128)) >> 6;
int rg = (((u - 128) << 1) + (u - 128) +
((v - 128) << 2) + ((v - 128) << 1)) >> 3;
int v1 = (((v - 128) << 1) + (v - 128)) >> 1;
dest[idx+r] = CLIP(y + v1);
dest[idx+1] = CLIP(y - rg);
dest[idx+b] = CLIP(y + u1);
idx += 3;
}
src_y += 16;
if (i & 1)
src_uv += 16;
}
}
}
}
void v4lconvert_hm12_to_rgb24(const unsigned char *src, unsigned char *dest,
int width, int height)
{
v4lconvert_hm12_to_rgb(src, dest, width, height, 1);
}
void v4lconvert_hm12_to_bgr24(const unsigned char *src, unsigned char *dest,
int width, int height)
{
v4lconvert_hm12_to_rgb(src, dest, width, height, 0);
}
static void de_macro_uv(unsigned char *dstu, unsigned char *dstv,
const unsigned char *src, int w, int h)
{
unsigned int y, x, i, j;
for (y = 0; y < (unsigned)h; y += 16) {
for (x = 0; x < (unsigned)w; x += 8) {
const unsigned char *src_uv = src + y * stride + x * 32;
int maxy = (h - y < 16 ? h - y : 16);
int maxx = (w - x < 8 ? w - x : 8);
for (i = 0; i < (unsigned)maxy; i++) {
int idx = x + (y + i) * w;
for (j = 0; j < (unsigned)maxx; j++) {
dstu[idx+j] = src_uv[2 * j];
dstv[idx+j] = src_uv[2 * j + 1];
}
src_uv += 16;
}
}
}
}
static void de_macro_y(unsigned char *dst, const unsigned char *src,
int w, int h)
{
unsigned int y, x, i;
for (y = 0; y < (unsigned)h; y += 16) {
for (x = 0; x < (unsigned)w; x += 16) {
const unsigned char *src_y = src + y * stride + x * 16;
int maxy = (h - y < 16 ? h - y : 16);
int maxx = (w - x < 16 ? w - x : 16);
for (i = 0; i < (unsigned)maxy; i++) {
memcpy(dst + x + (y + i) * w, src_y, maxx);
src_y += 16;
}
}
}
}
void v4lconvert_hm12_to_yuv420(const unsigned char *src, unsigned char *dest,
int width, int height, int yvu)
{
de_macro_y(dest, src, width, height);
dest += width * height;
src += stride * height;
if (yvu)
de_macro_uv(dest + width * height / 4, dest, src, width / 2, height / 2);
else
de_macro_uv(dest, dest + width * height / 4, src, width / 2, height / 2);
}

284
libv4lconvert/jidctflt.c Normal file
View File

@@ -0,0 +1,284 @@
/*
* jidctflt.c
*
* Copyright (C) 1994-1998, Thomas G. Lane.
* This file is part of the Independent JPEG Group's software.
*
* The authors make NO WARRANTY or representation, either express or implied,
* with respect to this software, its quality, accuracy, merchantability, or
* fitness for a particular purpose. This software is provided "AS IS", and you,
* its user, assume the entire risk as to its quality and accuracy.
*
* This software is copyright (C) 1991-1998, Thomas G. Lane.
* All Rights Reserved except as specified below.
*
* Permission is hereby granted to use, copy, modify, and distribute this
* software (or portions thereof) for any purpose, without fee, subject to these
* conditions:
* (1) If any part of the source code for this software is distributed, then this
* README file must be included, with this copyright and no-warranty notice
* unaltered; and any additions, deletions, or changes to the original files
* must be clearly indicated in accompanying documentation.
* (2) If only executable code is distributed, then the accompanying
* documentation must state that "this software is based in part on the work of
* the Independent JPEG Group".
* (3) Permission for use of this software is granted only if the user accepts
* full responsibility for any undesirable consequences; the authors accept
* NO LIABILITY for damages of any kind.
*
* These conditions apply to any software derived from or based on the IJG code,
* not just to the unmodified library. If you use our work, you ought to
* acknowledge us.
*
* Permission is NOT granted for the use of any IJG author's name or company name
* in advertising or publicity relating to this software or products derived from
* it. This software may be referred to only as "the Independent JPEG Group's
* software".
*
* We specifically permit and encourage the use of this software as the basis of
* commercial products, provided that all warranty or liability claims are
* assumed by the product vendor.
*
*
* This file contains a floating-point implementation of the
* inverse DCT (Discrete Cosine Transform). In the IJG code, this routine
* must also perform dequantization of the input coefficients.
*
* This implementation should be more accurate than either of the integer
* IDCT implementations. However, it may not give the same results on all
* machines because of differences in roundoff behavior. Speed will depend
* on the hardware's floating point capacity.
*
* A 2-D IDCT can be done by 1-D IDCT on each column followed by 1-D IDCT
* on each row (or vice versa, but it's more convenient to emit a row at
* a time). Direct algorithms are also available, but they are much more
* complex and seem not to be any faster when reduced to code.
*
* This implementation is based on Arai, Agui, and Nakajima's algorithm for
* scaled DCT. Their original paper (Trans. IEICE E-71(11):1095) is in
* Japanese, but the algorithm is described in the Pennebaker & Mitchell
* JPEG textbook (see REFERENCES section in file README). The following code
* is based directly on figure 4-8 in P&M.
* While an 8-point DCT cannot be done in less than 11 multiplies, it is
* possible to arrange the computation so that many of the multiplies are
* simple scalings of the final outputs. These multiplies can then be
* folded into the multiplications or divisions by the JPEG quantization
* table entries. The AA&N method leaves only 5 multiplies and 29 adds
* to be done in the DCT itself.
* The primary disadvantage of this method is that with a fixed-point
* implementation, accuracy is lost due to imprecise representation of the
* scaled quantization values. However, that problem does not arise if
* we use floating point arithmetic.
*/
#include <stdint.h>
#include "tinyjpeg-internal.h"
#define FAST_FLOAT float
#define DCTSIZE 8
#define DCTSIZE2 (DCTSIZE * DCTSIZE)
#define DEQUANTIZE(coef, quantval) (((FAST_FLOAT) (coef)) * (quantval))
#if defined(__GNUC__) && (defined(__i686__) || defined(__x86_64__))
static inline unsigned char descale_and_clamp(int x, int shift)
{
__asm__ (
"add %3,%1\n"
"\tsar %2,%1\n"
"\tsub $-128,%1\n"
"\tcmovl %5,%1\n" /* Use the sub to compare to 0 */
"\tcmpl %4,%1\n"
"\tcmovg %4,%1\n"
: "=r"(x)
: "0"(x), "Ic"((unsigned char)shift), "ir" (1U << (shift - 1)), "r" (0xff), "r" (0)
);
return x;
}
#else
static inline unsigned char descale_and_clamp(int x, int shift)
{
x += 1UL << (shift - 1);
if (x < 0)
x = (x >> shift) | ((~(0UL)) << (32 - (shift)));
else
x >>= shift;
x += 128;
if (x > 255)
return 255;
if (x < 0)
return 0;
return x;
}
#endif
/*
* Perform dequantization and inverse DCT on one block of coefficients.
*/
void tinyjpeg_idct_float(struct component *compptr, uint8_t *output_buf, int stride)
{
FAST_FLOAT tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
FAST_FLOAT tmp10, tmp11, tmp12, tmp13;
FAST_FLOAT z5, z10, z11, z12, z13;
int16_t *inptr;
FAST_FLOAT *quantptr;
FAST_FLOAT *wsptr;
uint8_t *outptr;
int ctr;
FAST_FLOAT workspace[DCTSIZE2]; /* buffers data between passes */
/* Pass 1: process columns from input, store into work array. */
inptr = compptr->DCT;
quantptr = compptr->Q_table;
wsptr = workspace;
for (ctr = DCTSIZE; ctr > 0; ctr--) {
/* Due to quantization, we will usually find that many of the input
* coefficients are zero, especially the AC terms. We can exploit this
* by short-circuiting the IDCT calculation for any column in which all
* the AC terms are zero. In that case each output is equal to the
* DC coefficient (with scale factor as needed).
* With typical images and quantization tables, half or more of the
* column DCT calculations can be simplified this way.
*/
if (inptr[DCTSIZE*1] == 0 && inptr[DCTSIZE*2] == 0 &&
inptr[DCTSIZE*3] == 0 && inptr[DCTSIZE*4] == 0 &&
inptr[DCTSIZE*5] == 0 && inptr[DCTSIZE*6] == 0 &&
inptr[DCTSIZE*7] == 0) {
/* AC terms all zero */
FAST_FLOAT dcval = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]);
wsptr[DCTSIZE*0] = dcval;
wsptr[DCTSIZE*1] = dcval;
wsptr[DCTSIZE*2] = dcval;
wsptr[DCTSIZE*3] = dcval;
wsptr[DCTSIZE*4] = dcval;
wsptr[DCTSIZE*5] = dcval;
wsptr[DCTSIZE*6] = dcval;
wsptr[DCTSIZE*7] = dcval;
inptr++; /* advance pointers to next column */
quantptr++;
wsptr++;
continue;
}
/* Even part */
tmp0 = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]);
tmp1 = DEQUANTIZE(inptr[DCTSIZE*2], quantptr[DCTSIZE*2]);
tmp2 = DEQUANTIZE(inptr[DCTSIZE*4], quantptr[DCTSIZE*4]);
tmp3 = DEQUANTIZE(inptr[DCTSIZE*6], quantptr[DCTSIZE*6]);
tmp10 = tmp0 + tmp2; /* phase 3 */
tmp11 = tmp0 - tmp2;
tmp13 = tmp1 + tmp3; /* phases 5-3 */
tmp12 = (tmp1 - tmp3) * ((FAST_FLOAT) 1.414213562) - tmp13; /* 2*c4 */
tmp0 = tmp10 + tmp13; /* phase 2 */
tmp3 = tmp10 - tmp13;
tmp1 = tmp11 + tmp12;
tmp2 = tmp11 - tmp12;
/* Odd part */
tmp4 = DEQUANTIZE(inptr[DCTSIZE*1], quantptr[DCTSIZE*1]);
tmp5 = DEQUANTIZE(inptr[DCTSIZE*3], quantptr[DCTSIZE*3]);
tmp6 = DEQUANTIZE(inptr[DCTSIZE*5], quantptr[DCTSIZE*5]);
tmp7 = DEQUANTIZE(inptr[DCTSIZE*7], quantptr[DCTSIZE*7]);
z13 = tmp6 + tmp5; /* phase 6 */
z10 = tmp6 - tmp5;
z11 = tmp4 + tmp7;
z12 = tmp4 - tmp7;
tmp7 = z11 + z13; /* phase 5 */
tmp11 = (z11 - z13) * ((FAST_FLOAT) 1.414213562); /* 2*c4 */
z5 = (z10 + z12) * ((FAST_FLOAT) 1.847759065); /* 2*c2 */
tmp10 = ((FAST_FLOAT) 1.082392200) * z12 - z5; /* 2*(c2-c6) */
tmp12 = ((FAST_FLOAT) -2.613125930) * z10 + z5; /* -2*(c2+c6) */
tmp6 = tmp12 - tmp7; /* phase 2 */
tmp5 = tmp11 - tmp6;
tmp4 = tmp10 + tmp5;
wsptr[DCTSIZE*0] = tmp0 + tmp7;
wsptr[DCTSIZE*7] = tmp0 - tmp7;
wsptr[DCTSIZE*1] = tmp1 + tmp6;
wsptr[DCTSIZE*6] = tmp1 - tmp6;
wsptr[DCTSIZE*2] = tmp2 + tmp5;
wsptr[DCTSIZE*5] = tmp2 - tmp5;
wsptr[DCTSIZE*4] = tmp3 + tmp4;
wsptr[DCTSIZE*3] = tmp3 - tmp4;
inptr++; /* advance pointers to next column */
quantptr++;
wsptr++;
}
/* Pass 2: process rows from work array, store into output array. */
/* Note that we must descale the results by a factor of 8 == 2**3. */
wsptr = workspace;
outptr = output_buf;
for (ctr = 0; ctr < DCTSIZE; ctr++) {
/* Rows of zeroes can be exploited in the same way as we did with columns.
* However, the column calculation has created many nonzero AC terms, so
* the simplification applies less often (typically 5% to 10% of the time).
* And testing floats for zero is relatively expensive, so we don't bother.
*/
/* Even part */
tmp10 = wsptr[0] + wsptr[4];
tmp11 = wsptr[0] - wsptr[4];
tmp13 = wsptr[2] + wsptr[6];
tmp12 = (wsptr[2] - wsptr[6]) * ((FAST_FLOAT) 1.414213562) - tmp13;
tmp0 = tmp10 + tmp13;
tmp3 = tmp10 - tmp13;
tmp1 = tmp11 + tmp12;
tmp2 = tmp11 - tmp12;
/* Odd part */
z13 = wsptr[5] + wsptr[3];
z10 = wsptr[5] - wsptr[3];
z11 = wsptr[1] + wsptr[7];
z12 = wsptr[1] - wsptr[7];
tmp7 = z11 + z13;
tmp11 = (z11 - z13) * ((FAST_FLOAT) 1.414213562);
z5 = (z10 + z12) * ((FAST_FLOAT) 1.847759065); /* 2*c2 */
tmp10 = ((FAST_FLOAT) 1.082392200) * z12 - z5; /* 2*(c2-c6) */
tmp12 = ((FAST_FLOAT) -2.613125930) * z10 + z5; /* -2*(c2+c6) */
tmp6 = tmp12 - tmp7;
tmp5 = tmp11 - tmp6;
tmp4 = tmp10 + tmp5;
/* Final output stage: scale down by a factor of 8 and range-limit */
outptr[0] = descale_and_clamp((int)(tmp0 + tmp7), 3);
outptr[7] = descale_and_clamp((int)(tmp0 - tmp7), 3);
outptr[1] = descale_and_clamp((int)(tmp1 + tmp6), 3);
outptr[6] = descale_and_clamp((int)(tmp1 - tmp6), 3);
outptr[2] = descale_and_clamp((int)(tmp2 + tmp5), 3);
outptr[5] = descale_and_clamp((int)(tmp2 - tmp5), 3);
outptr[4] = descale_and_clamp((int)(tmp3 + tmp4), 3);
outptr[3] = descale_and_clamp((int)(tmp3 - tmp4), 3);
wsptr += DCTSIZE; /* advance pointer to next row */
outptr += stride;
}
}

220
libv4lconvert/jl2005bcd.c Normal file
View File

@@ -0,0 +1,220 @@
/* jl2005bcd.c
*
* Converts raw output from Jeilin JL2005B/C/D to Bayer output.
*
* The code is based upon what is found in libgphoto2/camlibs/jl2005c,
* Copyright (c) 2010 Theodore Kilgore <kilgota@auburn.edu>
*
* The decompression code used is
* Copyright (c) 2010 Hans de Goede <hdegoede@redhat.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifdef ANDROID
#include <android-config.h>
#else
#include <config.h>
#endif
#include <stdlib.h>
#include <string.h>
#ifdef HAVE_JPEG
#include "libv4lconvert-priv.h"
#include "jpeg_memsrcdest.h"
#include "libv4lsyscall-priv.h"
#define JPEG_HEADER_SIZE 338
#define JPEG_HEIGHT_OFFSET 94
static int find_eoi(struct v4lconvert_data *data,
const unsigned char *jpeg_data, int jpeg_data_idx, int jpeg_data_size)
{
int i;
for (i = jpeg_data_idx; i < (jpeg_data_size - 1); i++)
if (jpeg_data[i] == 0xff && jpeg_data[i + 1] == 0xd9)
break;
if (i >= (jpeg_data_size - 1)) {
V4LCONVERT_ERR("incomplete jl2005bcd frame\n");
return -1;
}
return i + 2; /* + 2 -> Point to after EOI marker */
}
int v4lconvert_decode_jl2005bcd(struct v4lconvert_data *data,
const unsigned char *src, int src_size,
unsigned char *dest, int width, int height)
{
unsigned char jpeg_stripe[50000];
int q;
struct jpeg_compress_struct cinfo;
struct jpeg_decompress_struct dinfo;
struct jpeg_error_mgr jcerr, jderr;
JOCTET *jpeg_header = NULL;
unsigned long jpeg_header_size = 0;
int i, x, y, x1, y1, jpeg_data_size, jpeg_data_idx, eoi, size;
/* src_size had better be bigger than 16 */
if (src_size < 16)
return 1;
/* The first 16 bytes of src are a raw frame header */
q = src[13] & 0x7f;
if (height != src[4] << 3) {
V4LCONVERT_ERR("Height is %d, not %d\n", src[4] << 3, height);
return 1;
}
if (width != src[5] << 3) {
V4LCONVERT_ERR("Width is %d, not %d\n", src[5] << 3, width);
return 1;
}
/*
* And the fun begins, first of all create a dummy jpeg, which we use
* to get the headers from to feed to libjpeg when decompressing the
* stripes. This way we can use libjpeg's quant table handling
* (and built in default huffman tables).
*/
cinfo.err = jpeg_std_error (&jcerr);
jpeg_create_compress (&cinfo);
jpeg_mem_dest (&cinfo, &jpeg_header, &jpeg_header_size);
cinfo.image_width = 16;
cinfo.image_height = 16;
cinfo.input_components = 3;
cinfo.in_color_space = JCS_RGB;
jpeg_set_defaults (&cinfo);
/* Make comp[0] (which will be green) 1x2 subsampled */
cinfo.comp_info[0].h_samp_factor = 1;
cinfo.comp_info[0].v_samp_factor = 2;
/* Make comp[1] and [2] use huffman table and quanttable 0, as all
* components use luminance settings with the jl2005c/d/e */
cinfo.comp_info[1].quant_tbl_no = 0;
cinfo.comp_info[1].dc_tbl_no = 0;
cinfo.comp_info[1].ac_tbl_no = 0;
cinfo.comp_info[2].quant_tbl_no = 0;
cinfo.comp_info[2].dc_tbl_no = 0;
cinfo.comp_info[2].ac_tbl_no = 0;
/* Apply the quality setting from the header */
if (q <= 0)
i = 5000;
else if (q <= 50)
i = 5000 / q;
else if (q <= 100)
i = 2 * (100 - q);
else
i = 0;
jpeg_set_linear_quality(&cinfo, i, TRUE);
jpeg_start_compress (&cinfo, TRUE);
while( cinfo.next_scanline < cinfo.image_height ) {
JOCTET row[16 * 3];
JSAMPROW row_pointer[1] = { row };
jpeg_write_scanlines (&cinfo, row_pointer, 1);
}
jpeg_finish_compress (&cinfo);
jpeg_destroy_compress (&cinfo);
JSAMPLE green[8 * 16];
JSAMPLE red[8 * 8];
JSAMPLE blue[8 * 8];
JSAMPROW green_row_pointer[16];
JSAMPROW red_row_pointer[8];
JSAMPROW blue_row_pointer[8];
for (i = 0; i < 16; i++)
green_row_pointer[i] = green + i * 8;
for (i = 0; i < 8; i++) {
red_row_pointer[i] = red + i * 8;
blue_row_pointer[i] = blue + i * 8;
}
JSAMPARRAY samp_image[3] = { green_row_pointer,
red_row_pointer,
blue_row_pointer };
memcpy(jpeg_stripe, jpeg_header, JPEG_HEADER_SIZE);
jpeg_stripe[JPEG_HEIGHT_OFFSET ] = height >> 8;
jpeg_stripe[JPEG_HEIGHT_OFFSET + 1] = height;
jpeg_stripe[JPEG_HEIGHT_OFFSET + 2] = 0;
jpeg_stripe[JPEG_HEIGHT_OFFSET + 3] = 8;
free (jpeg_header);
/* Get past the raw frame header. */
src += 16;
jpeg_data_size = src_size - 16;
jpeg_data_idx = 0;
dinfo.err = jpeg_std_error (&jderr);
jpeg_create_decompress (&dinfo);
for (x = 0; x < width; x += 16) {
eoi = find_eoi(data, src, jpeg_data_idx, jpeg_data_size);
if (eoi < 0)
return eoi;
size = eoi - jpeg_data_idx;
if ((JPEG_HEADER_SIZE + size) > sizeof(jpeg_stripe)) {
V4LCONVERT_ERR("stripe size too big %d > %zd\n",
JPEG_HEADER_SIZE + size,
sizeof(jpeg_stripe));
return 1;
}
memcpy (jpeg_stripe + JPEG_HEADER_SIZE,
src + jpeg_data_idx, size);
jpeg_mem_src (&dinfo, jpeg_stripe, JPEG_HEADER_SIZE + size);
jpeg_read_header (&dinfo, TRUE);
dinfo.raw_data_out = TRUE;
#if JPEG_LIB_VERSION >= 70
dinfo.do_fancy_upsampling = FALSE;
#endif
jpeg_start_decompress (&dinfo);
for (y = 0; y < height; y += 16) {
jpeg_read_raw_data (&dinfo, samp_image, 16);
for (y1 = 0; y1 < 16; y1 += 2) {
for (x1 = 0; x1 < 16; x1 += 2) {
dest[((y + y1 + 0) * width
+ x + x1 + 0)]
= red[y1 * 4 + x1 / 2];
dest[((y + y1 + 0) * width
+ x + x1 + 1)]
= green[y1 * 8 + x1 / 2];
dest[((y + y1 + 1) * width
+ x + x1 + 0)]
= green[y1 * 8 + 8 + x1 / 2];
dest[((y + y1 + 1) * width
+ x + x1 + 1)]
= blue[y1 * 4 + x1 / 2];
}
}
}
jpeg_finish_decompress (&dinfo);
/* Set jpeg_data_idx for the next stripe */
jpeg_data_idx = (jpeg_data_idx + size + 0x0f) & ~0x0f;
}
jpeg_destroy_decompress(&dinfo);
return 0;
}
#endif /* HAVE_JPEG */

429
libv4lconvert/jpeg.c Normal file
View File

@@ -0,0 +1,429 @@
/*
# (C) 2008-2011 Hans de Goede <hdegoede@redhat.com>
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 2.1 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
*/
#ifdef ANDROID
#include <android-config.h>
#else
#include <config.h>
#endif
#include <errno.h>
#include <stdlib.h>
#include "libv4lconvert-priv.h"
#ifdef HAVE_JPEG
#include "jpeg_memsrcdest.h"
#endif
int v4lconvert_decode_jpeg_tinyjpeg(struct v4lconvert_data *data,
unsigned char *src, int src_size, unsigned char *dest,
struct v4l2_format *fmt, unsigned int dest_pix_fmt, int flags)
{
int result = 0;
unsigned char *components[3];
unsigned int header_width, header_height;
unsigned int width = fmt->fmt.pix.width;
unsigned int height = fmt->fmt.pix.height;
if (!data->tinyjpeg) {
data->tinyjpeg = tinyjpeg_init();
if (!data->tinyjpeg)
return v4lconvert_oom_error(data);
}
flags |= TINYJPEG_FLAGS_MJPEG_TABLE;
tinyjpeg_set_flags(data->tinyjpeg, flags);
if (tinyjpeg_parse_header(data->tinyjpeg, src, src_size)) {
V4LCONVERT_ERR("parsing JPEG header: %s",
tinyjpeg_get_errorstring(data->tinyjpeg));
errno = EAGAIN;
return -1;
}
tinyjpeg_get_size(data->tinyjpeg, &header_width, &header_height);
if (data->control_flags & V4LCONTROL_ROTATED_90_JPEG) {
unsigned int tmp = width;
width = height;
height = tmp;
}
if (header_width != width || header_height != height) {
V4LCONVERT_ERR("unexpected width / height in JPEG header: "
"expected: %ux%u, header: %ux%u\n",
width, height, header_width, header_height);
errno = EIO;
return -1;
}
fmt->fmt.pix.width = header_width;
fmt->fmt.pix.height = header_height;
components[0] = dest;
switch (dest_pix_fmt) {
case V4L2_PIX_FMT_RGB24:
tinyjpeg_set_components(data->tinyjpeg, components, 1);
result = tinyjpeg_decode(data->tinyjpeg, TINYJPEG_FMT_RGB24);
break;
case V4L2_PIX_FMT_BGR24:
tinyjpeg_set_components(data->tinyjpeg, components, 1);
result = tinyjpeg_decode(data->tinyjpeg, TINYJPEG_FMT_BGR24);
break;
case V4L2_PIX_FMT_YUV420:
components[1] = components[0] + width * height;
components[2] = components[1] + width * height / 4;
tinyjpeg_set_components(data->tinyjpeg, components, 3);
result = tinyjpeg_decode(data->tinyjpeg, TINYJPEG_FMT_YUV420P);
break;
case V4L2_PIX_FMT_YVU420:
components[2] = components[0] + width * height;
components[1] = components[2] + width * height / 4;
tinyjpeg_set_components(data->tinyjpeg, components, 3);
result = tinyjpeg_decode(data->tinyjpeg, TINYJPEG_FMT_YUV420P);
break;
}
if (result) {
/* The JPEG header checked out ok but we got an error
during decompression. Some webcams, esp pixart and
sn9c20x based ones regulary generate corrupt frames,
which are best thrown away to avoid flashes in the
video stream. We use EPIPE to signal the upper layer
we have some video data, but it is incomplete.
The upper layer (usually libv4l2) should respond to
this by trying a number of times to get a new frame
and if that fails just passing up whatever we did
manage to decompress. */
V4LCONVERT_ERR("decompressing JPEG: %s",
tinyjpeg_get_errorstring(data->tinyjpeg));
errno = EPIPE;
return -1;
}
return 0;
}
#ifdef HAVE_JPEG
static void jerr_error_exit(j_common_ptr cinfo)
{
struct v4lconvert_data *data = cinfo->client_data;
longjmp(data->jerr_jmp_state, data->jerr_errno);
}
static void jerr_emit_message(j_common_ptr cinfo, int msg_level)
{
char buffer[JMSG_LENGTH_MAX];
struct v4lconvert_data *data = cinfo->client_data;
/* < -1 error, == -1 warning, >= 0 trace */
if (msg_level < -1)
return;
cinfo->err->format_message(cinfo, buffer);
snprintf(data->error_msg, V4LCONVERT_ERROR_MSG_SIZE,
"v4l-convert: libjpeg error: %s\n", buffer);
}
static void init_libjpeg_cinfo(struct v4lconvert_data *data)
{
struct jpeg_compress_struct cinfo;
unsigned char *jpeg_header = NULL;
unsigned long jpeg_header_size = 0;
if (data->cinfo_initialized)
return;
/* Setup our error handling */
jpeg_std_error(&data->jerr);
data->jerr.error_exit = jerr_error_exit;
data->jerr.emit_message = jerr_emit_message;
/* Create a jpeg compression object with default params and write
default jpeg headers to a mem buffer, so that we can use them to
pre-fill a jpeg_decompress_struct with default quant and huffman
tables, so that libjpeg can be used to parse [m]jpg-s with
incomplete headers */
cinfo.err = &data->jerr;
cinfo.client_data = data;
jpeg_create_compress(&cinfo);
jpeg_mem_dest(&cinfo, &jpeg_header, &jpeg_header_size);
cinfo.input_components = 3;
cinfo.in_color_space = JCS_RGB;
jpeg_set_defaults(&cinfo);
jpeg_write_tables(&cinfo);
jpeg_destroy_compress(&cinfo);
/* Init the jpeg_decompress_struct */
data->cinfo.err = &data->jerr;
data->cinfo.client_data = data;
jpeg_create_decompress(&data->cinfo);
jpeg_mem_src(&data->cinfo, jpeg_header, jpeg_header_size);
jpeg_read_header(&data->cinfo, FALSE);
free(jpeg_header);
data->cinfo_initialized = 1;
}
static int decode_libjpeg_h_samp1(struct v4lconvert_data *data,
unsigned char *ydest, unsigned char *udest, unsigned char *vdest,
int v_samp)
{
struct jpeg_decompress_struct *cinfo = &data->cinfo;
int x, y;
unsigned char *uv_buf;
unsigned int width = cinfo->image_width;
JSAMPROW y_rows[16], u_rows[8], v_rows[8];
JSAMPARRAY rows[3] = { y_rows, u_rows, v_rows };
uv_buf = v4lconvert_alloc_buffer(width * 16,
&data->convert_pixfmt_buf,
&data->convert_pixfmt_buf_size);
if (!uv_buf)
return v4lconvert_oom_error(data);
for (y = 0; y < 8; y++) {
u_rows[y] = uv_buf;
uv_buf += width;
v_rows[y] = uv_buf;
uv_buf += width;
}
uv_buf -= width * 16;
while (cinfo->output_scanline < cinfo->image_height) {
for (y = 0; y < 8 * v_samp; y++) {
y_rows[y] = ydest;
ydest += cinfo->image_width;
}
y = jpeg_read_raw_data(cinfo, rows, 8 * v_samp);
if (y != 8 * v_samp)
return -1;
/* For v_samp == 1 skip copying uv vals every other time */
if (cinfo->output_scanline % 16)
continue;
/* Copy over every other u + v pixel for 8 lines */
for (y = 0; y < 8; y++) {
for (x = 0; x < width; x += 2) {
*udest++ = *uv_buf++;
uv_buf++;
}
for (x = 0; x < width; x += 2) {
*vdest++ = *uv_buf++;
uv_buf++;
}
}
uv_buf -= width * 16;
}
return 0;
}
static int decode_libjpeg_h_samp2(struct v4lconvert_data *data,
unsigned char *ydest, unsigned char *udest, unsigned char *vdest,
int v_samp)
{
struct jpeg_decompress_struct *cinfo = &data->cinfo;
int y;
unsigned int width = cinfo->image_width;
JSAMPROW y_rows[16], u_rows[8], v_rows[8];
JSAMPARRAY rows[3] = { y_rows, u_rows, v_rows };
while (cinfo->output_scanline < cinfo->image_height) {
for (y = 0; y < 8 * v_samp; y++) {
y_rows[y] = ydest;
ydest += width;
}
/*
* For v_samp == 1 were going to get 1 set of uv values per
* line, but we need only 1 set per 2 lines since our output
* has v_samp == 2. We store every 2 sets in 1 line,
* effectively using the second set for each output line.
*/
if (v_samp == 1) {
for (y = 0; y < 8; y++) {
u_rows[y] = udest;
v_rows[y] = vdest;
y++;
u_rows[y] = udest;
v_rows[y] = vdest;
udest += width / 2;
vdest += width / 2;
}
} else { /* v_samp == 2 */
for (y = 0; y < 8; y++) {
u_rows[y] = udest;
v_rows[y] = vdest;
udest += width / 2;
vdest += width / 2;
}
}
y = jpeg_read_raw_data(cinfo, rows, 8 * v_samp);
if (y != 8 * v_samp)
return -1;
}
return 0;
}
int v4lconvert_decode_jpeg_libjpeg(struct v4lconvert_data *data,
unsigned char *src, int src_size, unsigned char *dest,
struct v4l2_format *fmt, unsigned int dest_pix_fmt)
{
unsigned int width = fmt->fmt.pix.width;
unsigned int height = fmt->fmt.pix.height;
int result = 0;
/* libjpeg errors before decoding the first line should signal EAGAIN */
data->jerr_errno = EAGAIN;
result = setjmp(data->jerr_jmp_state);
if (result) {
if (data->cinfo_initialized)
jpeg_abort_decompress(&data->cinfo);
errno = result;
return -1;
}
init_libjpeg_cinfo(data);
jpeg_mem_src(&data->cinfo, src, src_size);
jpeg_read_header(&data->cinfo, TRUE);
if (data->cinfo.image_width != width ||
data->cinfo.image_height != height) {
V4LCONVERT_ERR("unexpected width / height in JPEG header: "
"expected: %ux%u, header: %ux%u\n", width,
height, data->cinfo.image_width,
data->cinfo.image_height);
errno = EIO;
return -1;
}
if (data->cinfo.num_components != 3) {
V4LCONVERT_ERR("unexpected no components in JPEG: %d\n",
data->cinfo.num_components);
errno = EIO;
return -1;
}
if (dest_pix_fmt == V4L2_PIX_FMT_RGB24 ||
dest_pix_fmt == V4L2_PIX_FMT_BGR24) {
JSAMPROW row_pointer[1];
#ifdef JCS_EXTENSIONS
if (dest_pix_fmt == V4L2_PIX_FMT_BGR24)
data->cinfo.out_color_space = JCS_EXT_BGR;
#endif
row_pointer[0] = dest;
jpeg_start_decompress(&data->cinfo);
/* Make libjpeg errors report that we've got some data */
data->jerr_errno = EPIPE;
while (data->cinfo.output_scanline < height) {
jpeg_read_scanlines(&data->cinfo, row_pointer, 1);
row_pointer[0] += 3 * width;
}
jpeg_finish_decompress(&data->cinfo);
#ifndef JCS_EXTENSIONS
if (dest_pix_fmt == V4L2_PIX_FMT_BGR24)
v4lconvert_swap_rgb(dest, dest, width, height);
#endif
} else {
int h_samp, v_samp;
unsigned char *udest, *vdest;
if (data->cinfo.max_h_samp_factor == 2 &&
data->cinfo.cur_comp_info[0]->h_samp_factor == 2 &&
data->cinfo.cur_comp_info[1]->h_samp_factor == 1 &&
data->cinfo.cur_comp_info[2]->h_samp_factor == 1) {
h_samp = 2;
#if 0 /* HDG: untested, disable for now */
} else if (data->cinfo.max_h_samp_factor == 1 &&
data->cinfo.cur_comp_info[0]->h_samp_factor == 1 &&
data->cinfo.cur_comp_info[1]->h_samp_factor == 1 &&
data->cinfo.cur_comp_info[2]->h_samp_factor == 1) {
h_samp = 1;
#endif
} else {
fprintf(stderr,
"libv4lconvert: unsupported jpeg h-sampling "
"factors %d:%d:%d, please report this to "
"hdegoede@redhat.com\n",
data->cinfo.cur_comp_info[0]->h_samp_factor,
data->cinfo.cur_comp_info[1]->h_samp_factor,
data->cinfo.cur_comp_info[2]->h_samp_factor);
errno = EOPNOTSUPP;
return -1;
}
if (data->cinfo.max_v_samp_factor == 2 &&
data->cinfo.cur_comp_info[0]->v_samp_factor == 2 &&
data->cinfo.cur_comp_info[1]->v_samp_factor == 1 &&
data->cinfo.cur_comp_info[2]->v_samp_factor == 1) {
v_samp = 2;
} else if (data->cinfo.max_v_samp_factor == 1 &&
data->cinfo.cur_comp_info[0]->v_samp_factor == 1 &&
data->cinfo.cur_comp_info[1]->v_samp_factor == 1 &&
data->cinfo.cur_comp_info[2]->v_samp_factor == 1) {
v_samp = 1;
} else {
fprintf(stderr,
"libv4lconvert: unsupported jpeg v-sampling "
"factors %d:%d:%d, please report this to "
"hdegoede@redhat.com\n",
data->cinfo.cur_comp_info[0]->v_samp_factor,
data->cinfo.cur_comp_info[1]->v_samp_factor,
data->cinfo.cur_comp_info[2]->v_samp_factor);
errno = EOPNOTSUPP;
return -1;
}
/* We don't want any padding as that may overflow our dest */
if (width % (8 * h_samp) || height % (8 * v_samp)) {
V4LCONVERT_ERR(
"resolution is not a multiple of dctsize");
errno = EIO;
return -1;
}
if (dest_pix_fmt == V4L2_PIX_FMT_YVU420) {
vdest = dest + width * height;
udest = vdest + (width * height) / 4;
} else {
udest = dest + width * height;
vdest = udest + (width * height) / 4;
}
data->cinfo.raw_data_out = TRUE;
data->cinfo.do_fancy_upsampling = FALSE;
jpeg_start_decompress(&data->cinfo);
/* Make libjpeg errors report that we've got some data */
data->jerr_errno = EPIPE;
if (h_samp == 1) {
result = decode_libjpeg_h_samp1(data, dest, udest,
vdest, v_samp);
} else {
result = decode_libjpeg_h_samp2(data, dest, udest,
vdest, v_samp);
}
if (result)
jpeg_abort_decompress(&data->cinfo);
else
jpeg_finish_decompress(&data->cinfo);
}
return result;
}
#endif // HAVE_JPEG

View File

@@ -0,0 +1,313 @@
/*
* memsrc.c
*
* Copyright (C) 1994-1996, Thomas G. Lane.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
* This file contains decompression data source routines for the case of
* reading JPEG data from a memory buffer that is preloaded with the entire
* JPEG file. This would not seem especially useful at first sight, but
* a number of people have asked for it.
* This is really just a stripped-down version of jdatasrc.c. Comparison
* of this code with jdatasrc.c may be helpful in seeing how to make
* custom source managers for other purposes.
*/
/* this is not a core library module, so it doesn't define JPEG_INTERNALS */
#ifdef ANDROID
#include <android-config.h>
#else
#include <config.h>
#endif
#include <stdlib.h>
#include <stdio.h>
#ifdef HAVE_JPEG
#include <jpeglib.h>
#include <jerror.h>
#include "jpeg_memsrcdest.h"
/* libjpeg8 and later come with their own (API compatible) memory source
and dest */
#if JPEG_LIB_VERSION < 80 && !defined(MEM_SRCDST_SUPPORTED)
/* Expanded data source object for memory input */
typedef struct {
struct jpeg_source_mgr pub; /* public fields */
JOCTET eoi_buffer[2]; /* a place to put a dummy EOI */
} my_source_mgr;
typedef my_source_mgr * my_src_ptr;
/*
* Initialize source --- called by jpeg_read_header
* before any data is actually read.
*/
METHODDEF(void)
init_source (j_decompress_ptr cinfo)
{
/* No work, since jpeg_mem_src set up the buffer pointer and count.
* Indeed, if we want to read multiple JPEG images from one buffer,
* this *must* not do anything to the pointer.
*/
}
/*
* Fill the input buffer --- called whenever buffer is emptied.
*
* In this application, this routine should never be called; if it is called,
* the decompressor has overrun the end of the input buffer, implying we
* supplied an incomplete or corrupt JPEG datastream. A simple error exit
* might be the most appropriate response.
*
* But what we choose to do in this code is to supply dummy EOI markers
* in order to force the decompressor to finish processing and supply
* some sort of output image, no matter how corrupted.
*/
METHODDEF(boolean)
fill_input_buffer (j_decompress_ptr cinfo)
{
my_src_ptr src = (my_src_ptr) cinfo->src;
WARNMS(cinfo, JWRN_JPEG_EOF);
/* Create a fake EOI marker */
src->eoi_buffer[0] = (JOCTET) 0xFF;
src->eoi_buffer[1] = (JOCTET) JPEG_EOI;
src->pub.next_input_byte = src->eoi_buffer;
src->pub.bytes_in_buffer = 2;
return TRUE;
}
/*
* Skip data --- used to skip over a potentially large amount of
* uninteresting data (such as an APPn marker).
*
* If we overrun the end of the buffer, we let fill_input_buffer deal with
* it. An extremely large skip could cause some time-wasting here, but
* it really isn't supposed to happen ... and the decompressor will never
* skip more than 64K anyway.
*/
METHODDEF(void)
skip_input_data (j_decompress_ptr cinfo, long num_bytes)
{
my_src_ptr src = (my_src_ptr) cinfo->src;
if (num_bytes > 0) {
while (num_bytes > (long) src->pub.bytes_in_buffer) {
num_bytes -= (long) src->pub.bytes_in_buffer;
(void) fill_input_buffer(cinfo);
/* note we assume that fill_input_buffer will never
* return FALSE, so suspension need not be handled.
*/
}
src->pub.next_input_byte += (size_t) num_bytes;
src->pub.bytes_in_buffer -= (size_t) num_bytes;
}
}
/*
* An additional method that can be provided by data source modules is the
* resync_to_restart method for error recovery in the presence of RST markers.
* For the moment, this source module just uses the default resync method
* provided by the JPEG library. That method assumes that no backtracking
* is possible.
*/
/*
* Terminate source --- called by jpeg_finish_decompress
* after all data has been read. Often a no-op.
*
* NB: *not* called by jpeg_abort or jpeg_destroy; surrounding
* application must deal with any cleanup that should happen even
* for error exit.
*/
METHODDEF(void)
term_source (j_decompress_ptr cinfo)
{
/* no work necessary here */
}
/*
* Prepare for input from a memory buffer.
*/
GLOBAL(void)
jpeg_mem_src (j_decompress_ptr cinfo, unsigned char * buffer,
unsigned long bufsize)
{
my_src_ptr src;
/* The source object is made permanent so that a series of JPEG images
* can be read from a single buffer by calling jpeg_mem_src
* only before the first one.
* This makes it unsafe to use this manager and a different source
* manager serially with the same JPEG object. Caveat programmer.
*/
if (cinfo->src == NULL) { /* first time for this JPEG object? */
cinfo->src = (struct jpeg_source_mgr *)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo,
JPOOL_PERMANENT,
sizeof(my_source_mgr));
}
src = (my_src_ptr) cinfo->src;
src->pub.init_source = init_source;
src->pub.fill_input_buffer = fill_input_buffer;
src->pub.skip_input_data = skip_input_data;
src->pub.resync_to_restart = jpeg_resync_to_restart; /* use default method */
src->pub.term_source = term_source;
src->pub.next_input_byte = buffer;
src->pub.bytes_in_buffer = bufsize;
}
/* Memory destination source modelled after Thomas G. Lane's memory source
support and jdatadst.c
Copyright (C) 2010, Hans de Goede
This code may be used under the same conditions as Thomas G. Lane's memory
source (see the copyright header at the top of this file).
*/
typedef struct {
struct jpeg_destination_mgr pub; /* public fields */
JOCTET **buffer; /* start of buffer */
unsigned long buf_size, *outsize;
} my_destination_mgr;
typedef my_destination_mgr * my_dest_ptr;
#define OUTPUT_BUF_SIZE 32768 /* choose an efficiently fwrite'able size */
/*
* Initialize destination --- called by jpeg_start_compress
* before any data is actually written.
*/
METHODDEF(void)
init_destination (j_compress_ptr cinfo)
{
/* No work, since jpeg_mem_dest set up the buffer pointer and count.
* Indeed, if we want to write multiple JPEG images to one buffer,
* this *must* not do anything to the pointer.
*/
}
/*
* Empty the output buffer --- called whenever buffer fills up.
*
* In typical applications, this should write the entire output buffer
* (ignoring the current state of next_output_byte & free_in_buffer),
* reset the pointer & count to the start of the buffer, and return TRUE
* indicating that the buffer has been dumped.
*
* In applications that need to be able to suspend compression due to output
* overrun, a FALSE return indicates that the buffer cannot be emptied now.
* In this situation, the compressor will return to its caller (possibly with
* an indication that it has not accepted all the supplied scanlines). The
* application should resume compression after it has made more room in the
* output buffer. Note that there are substantial restrictions on the use of
* suspension --- see the documentation.
*
* When suspending, the compressor will back up to a convenient restart point
* (typically the start of the current MCU). next_output_byte & free_in_buffer
* indicate where the restart point will be if the current call returns FALSE.
* Data beyond this point will be regenerated after resumption, so do not
* write it out when emptying the buffer externally.
*/
METHODDEF(boolean)
empty_output_buffer (j_compress_ptr cinfo)
{
my_dest_ptr dest = (my_dest_ptr) cinfo->dest;
*dest->buffer = realloc (*dest->buffer, dest->buf_size + OUTPUT_BUF_SIZE);
if (!*dest->buffer)
ERREXIT1(cinfo, JERR_OUT_OF_MEMORY, 0);
dest->pub.next_output_byte = *dest->buffer + dest->buf_size;
dest->pub.free_in_buffer = OUTPUT_BUF_SIZE;
dest->buf_size += OUTPUT_BUF_SIZE;
return TRUE;
}
/*
* Terminate destination --- called by jpeg_finish_compress
* after all data has been written. Usually needs to flush buffer.
*
* NB: *not* called by jpeg_abort or jpeg_destroy; surrounding
* application must deal with any cleanup that should happen even
* for error exit.
*/
METHODDEF(void)
term_destination (j_compress_ptr cinfo)
{
my_dest_ptr dest = (my_dest_ptr) cinfo->dest;
*dest->outsize = dest->buf_size - dest->pub.free_in_buffer;
}
GLOBAL(void)
jpeg_mem_dest (j_compress_ptr cinfo, unsigned char ** outbuffer,
unsigned long * outsize)
{
my_dest_ptr dest;
/* The destination object is made permanent so that multiple JPEG images
* can be written to the same file without re-executing jpeg_stdio_dest.
* This makes it dangerous to use this manager and a different destination
* manager serially with the same JPEG object, because their private object
* sizes may be different. Caveat programmer.
*/
if (cinfo->dest == NULL) { /* first time for this JPEG object? */
cinfo->dest = (struct jpeg_destination_mgr *)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo,
JPOOL_PERMANENT,
sizeof(my_destination_mgr));
}
dest = (my_dest_ptr) cinfo->dest;
dest->pub.init_destination = init_destination;
dest->pub.empty_output_buffer = empty_output_buffer;
dest->pub.term_destination = term_destination;
dest->buffer = outbuffer;
dest->buf_size = *outsize;
dest->outsize = outsize;
if (*dest->buffer == NULL || dest->buf_size == 0) {
/* Allocate initial buffer */
*dest->buffer = malloc(OUTPUT_BUF_SIZE);
if (*dest->buffer == NULL)
ERREXIT1(cinfo, JERR_OUT_OF_MEMORY, 10);
dest->buf_size = OUTPUT_BUF_SIZE;
}
dest->pub.next_output_byte = *dest->buffer;
dest->pub.free_in_buffer = dest->buf_size;
}
#endif /* JPEG_LIB_VERSION < 80 && !defined(MEM_SRCDST_SUPPORTED) */
#endif /* HAVE_JPEG */

View File

@@ -0,0 +1,13 @@
#include <jpeglib.h>
#if JPEG_LIB_VERSION < 80 && !defined(MEM_SRCDST_SUPPORTED)
void
jpeg_mem_src (j_decompress_ptr cinfo, unsigned char * buffer,
unsigned long bufsize);
void
jpeg_mem_dest (j_compress_ptr cinfo, unsigned char ** outbuffer,
unsigned long * outsize);
#endif

728
libv4lconvert/jpgl.c Normal file
View File

@@ -0,0 +1,728 @@
/*
* Implementation of JPEG Lite decoding algorithm
*
* Author & Copyright (c) 2003 : Sylvain Munaut <nw8xx ]at[ 246tNt.com>
*
* v4l library adaptation: Jean-François Moine <moinejf@free.fr>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
* Note this code was originally licensed under the GNU GPL instead of the
* GNU LGPL, its license has been changed with permission, see the permission
* mail at the end of this file.
*/
/* Original WebSite: nw802.sourceforge.net */
#include <stdlib.h>
#include "libv4lconvert-priv.h"
#define RING_QUEUE_ADVANCE_INDEX(rq,ind,n) (rq)->ind = ((rq)->ind + (n))
#define RING_QUEUE_DEQUEUE_BYTES(rq,n) RING_QUEUE_ADVANCE_INDEX(rq,ri,n)
#define RING_QUEUE_PEEK(rq,ofs) ((rq)->queue[((ofs) + (rq)->ri)])
struct RingQueue {
const unsigned char *queue;
int length;
int ri;
};
/* ============================================================================
* RingQueue bit reader
* ============================================================================
* All what is needed to read bit by nit from the RingQueue pump
* provided by usbvideo
* Critical part are macro and not functions to speed things up
* Rem: Data are read from the RingQueue as if they were 16bits Little Endian
* words. Most Significants Bits are outputed first.
*/
/* Structure used to store what we need. */
/* (We may need multiple simultaneous instance from several cam) */
struct rqBitReader {
int cur_bit;
unsigned int cur_data;
struct RingQueue *rq;
};
static inline void rqBR_init( struct rqBitReader *br, struct RingQueue *rq )
{
br->cur_bit = 16;
br->cur_data =
RING_QUEUE_PEEK( rq, 2 ) |
RING_QUEUE_PEEK( rq, 3 ) << 8 |
RING_QUEUE_PEEK( rq, 0 ) << 16 |
RING_QUEUE_PEEK( rq, 1 ) << 24 ;
RING_QUEUE_DEQUEUE_BYTES( rq, 2 );
br->rq = rq;
}
#define rqBR_peekBits(br,n) ( br->cur_data >> (32-n) )
#define rqBR_flushBits(br,n) do { \
br->cur_data <<= n; \
if ( (br->cur_bit -= n) <= 0 ) { \
br->cur_data |= \
RING_QUEUE_PEEK( br->rq, 2 ) << -br->cur_bit | \
RING_QUEUE_PEEK( br->rq, 3 ) << (8 - br->cur_bit); \
RING_QUEUE_DEQUEUE_BYTES( br->rq, 2 ); \
br->cur_bit += 16; \
} \
} while (0)
/* ============================================================================
* Real JPEG Lite stuff
* ============================================================================
*
* Precomputed tables
* Theses are computed at init time to make real-time operations faster.
* It takes some space ( about 9k ). But believe me it worth it !
*/
/* Variable Lenght Coding related tables, used for AC coefficient decoding
* TODO Check that 7 bits is enough ! */
static signed char vlcTbl_len[1<<10]; /* Meaningful bit count */
static signed char vlcTbl_run[1<<10]; /* Run */
static signed char vlcTbl_amp[1<<10]; /* Amplitude (without the sign) */
/* YUV->RGB conversion table */
static int yuvTbl_y[256];
static int yuvTbl_u1[256];
static int yuvTbl_u2[256];
static int yuvTbl_v1[256];
static int yuvTbl_v2[256];
/* Clamping table */
#define SAFE_CLAMP
#ifdef SAFE_CLAMP
static inline unsigned char clamp(int x) {
if (x > 255)
return 255;
if (x < 0)
return 0;
return x;
}
#define clamp_adjust(x) clamp(x+128)
#else
#define clamp(x) clampTbl[(x)+512]
#define clamp_adjust(x) clampTbl[(x)+640]
static char clampTbl[1280];
#endif
/* Code to initialize those tables */
static void vlcTbl_init(void)
{
/* Bases tables used to compute the bigger one
* To understands theses, look at the VLC doc in the
* US patent document. */
static const int vlc_num = 28;
static const int vlc_len[] =
{ 2, 2, 3, 3, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 7,
8 ,8 ,8 ,9, 9, 9, 10, 10, 10, 10, 10, 10 };
static const int vlc_run[] =
{ 0, 0, 0, 1, 0, 2, 3, 1, 0, 4, 0, 5, 1, 0, -1, -2,
2, 6, 0, 3, 1, 0, 1, 0, 7, 2, 0, 8 };
static const int vlc_amp[] =
{ 0, 1, 2, 1, 3, 1, 1, 2, 4, 1 ,5 ,1 ,3 ,6, -1, -2,
2, 1, 7, 2, 4, 8, 5, 9, 1 ,3, 10, 1 };
static const int vlc_cod[] =
{ 0x000, 0x002, 0x003, 0x006, 0x00E, 0x008, 0x00B, 0x012,
0x014, 0x03D, 0x03E, 0x078, 0x079, 0x07E, 0x026, 0x027,
0x054, 0x057, 0x0FF, 0x0AA, 0x0AC, 0x1FC, 0x156, 0x157,
0x15A, 0x15B, 0x3FA, 0x3FB };
/* Vars */
int i,j;
/* Main filling loop */
for ( i=0 ; i<(1<<10) ; i++ ) {
/* Find the matching one */
for ( j=0 ; j<vlc_num ; j++ ) {
if ( (i >> (10-vlc_len[j])) == vlc_cod[j] ) {
if ( vlc_run[j] >= 0 )
if ( vlc_amp[j] != 0 )
vlcTbl_len[i] = vlc_len[j] + 1;
else
vlcTbl_len[i] = vlc_len[j]; /* EOB */
else
vlcTbl_len[i] = 16;
vlcTbl_run[i] = vlc_run[j];
vlcTbl_amp[i] = vlc_amp[j];
break;
}
}
}
}
static void yuvTbl_init(void)
{
/* These tables are just pre-multiplied and pre-offseted
* YUV by the book
* R = 1.164 * (Y-16) + 1.596 * (U-128)
* G = 1.164 * (Y-16) - 0.813 * (U-128) - 0.391 * (V-128)
* B = 1.164 * (Y-16) + 2.018 * (V-128) */
int i;
/* We use fixed point << 16 */
for ( i=0 ; i < 256 ; i++ ) {
yuvTbl_y[i] = 76284 * (i- 16);
yuvTbl_u1[i] = 104595 * (i-128);
yuvTbl_u2[i] = 53281 * (i-128);
yuvTbl_v1[i] = 25625 * (i-128);
yuvTbl_v2[i] = 132252 * (i-128);
}
}
#ifndef SAFE_CLAMP
static void clampTbl_init(void)
{
/* Instead of doing if(...) to test for overrange, we use
* a clamping table */
int i;
for (i=0 ; i < 512 ; i++)
clampTbl[i] = 0;
for (i=512 ; i < 768 ; i++ )
clampTbl[i] = i - 512;
for (i=768 ; i < 1280 ; i++ )
clampTbl[i] = 255;
}
#endif
/*
* Internal helpers
*/
static inline int readAC( struct rqBitReader *br, int *run, int *amp )
{
/* Vars */
unsigned int cod;
/* Get 16 bits */
cod = rqBR_peekBits(br,16);
/* Lookup in the table */
*run = vlcTbl_run[cod>>6];
*amp = vlcTbl_amp[cod>>6];
rqBR_flushBits(br,vlcTbl_len[cod>>6]);
if (*amp > 0) {
/* Normal stuff, just correct the sign */
if (cod & (0x10000 >> vlcTbl_len[cod>>6]))
*amp = - *amp;
} else {
/* Handle special cases */
if (!*amp)
return 0;
if (*amp == -1) {
/* 0100110srrraaaaa */
*run = ( cod >> 5 ) & 0x07;
*amp = ( cod & 0x100) ?
-(cod&0x1F) : (cod&0x1F);
} else {
/* 0100111srrrraaaa */
*run = ( cod >> 4 ) & 0x0F;
*amp = ( cod & 0x100) ?
-(cod&0x0F) : (cod&0x0F);
}
}
return 1;
}
#define iDCT_column(b0,b1,b2,b3) do { \
int t0,t1,t2,t3; \
\
t0 = ( b1 + b3 ) << 5; \
t2 = t0 - (b3 << 4); \
t3 = (b1 * 47) - t0; \
t0 = b0 + b2; \
t1 = b0 - b2; \
\
b0 = ( t0 + t2 ); \
b1 = ( t1 + t3 ); \
b3 = ( t0 - t2 ); \
b2 = ( t1 - t3 ); \
} while (0)
#define iDCT_line(b0,b1,b2,b3) do { \
int t0,t1,t2,t3,bm0,bm2; \
\
bm0 = b0 << 7; \
bm2 = b2 << 7; \
\
t0 = bm0 + bm2; \
t1 = bm0 - bm2; \
t2 = b1 * 183 + b3 * 86; \
t3 = b1 * 86 - b3 * 183; \
\
b0 = ( t0 + t2 ) >> 22; \
b1 = ( t1 + t3 ) >> 22; \
b3 = ( t0 - t2 ) >> 22; \
b2 = ( t1 - t3 ) >> 22; \
} while (0)
/* Decode a block
* Basic ops : get the DC - get the ACs - deZigZag - deWeighting -
* deQuantization - iDCT
* Here they are a little mixed-up to speed all this up.
*/
static inline int decodeBlock( struct rqBitReader *br, int *block, int *dc )
{
/* Tables used for block decoding */
/* deZigZag table
*
* ZigZag: each of the coefficient of the DCT transformed 4x4
* matrix is taken in a certain order to make a linear
* array with the high frequency AC at the end
*
* / 0 1 5 6 \ .
* | 2 4 7 12 | This is the order taken. We must deZigZag
* | 3 8 11 13 | to reconstitute the original matrix
* \ 9 10 14 15 /
*/
static const int iZigZagTbl[16] =
{ 0, 1, 4, 8, 5, 2, 3, 6, 9,12, 13, 10, 7, 11, 14, 15 };
/* deQuantization, deWeighting & iDCT premultiply */
/*
* Weighting : Each DCT coefficient is weighted by a certain factor. We
* must compensate for this to rebuilt the original DCT matrix.
*
* Quantization: According to the read Q factor, DCT coefficient are
* quantized. We need to compensate for this.
*
* iDCT premultiply: Since for the first iDCT pass ( column ), we'll need
* to do some multiplication, the ones that we can
* integrate here, we do.
*
* Rem: - The factors are here presented in the ZigZaged order,
* because we will need those BEFORE the deZigZag
* - For more informations, consult jpgl_tbl.c, it's the little
* prog that computes this table
*/
static const int iQWTbl[4][16] = {
{ 32768, 17808, 794, 18618, 850, 18618, 43115, 1828,
40960, 1924, 2089, 45511, 2089, 49648, 2216, 2521 },
{ 32768, 35617, 1589, 37236, 1700, 37236, 86231, 3656,
81920, 3849, 4179, 91022, 4179, 99296, 4432, 5043 },
{ 32768, 71234, 3179, 74472, 3401, 74472, 172463, 7313,
163840, 7698, 8358, 182044, 8358, 198593, 8865, 10087 },
{ 32768, 142469, 6359, 148945, 6803, 148945, 344926, 14627,
327680, 15397, 16716, 364088, 16716, 397187, 17730, 20175 }
};
/* Vars */
int hdr;
int *eff_iQWTbl;
int cc, run, amp;
/* Read & Decode the block header ( Q, T, DC ) */
hdr = rqBR_peekBits(br,11);
if (hdr & 0x100) {
/* Differential mode */
if (hdr & 0x80)
*dc += ( hdr >> 3 ) | ~0xF;
else
*dc += ( hdr >> 3 ) & 0xF;
/* Flush the header bits */
rqBR_flushBits(br,8);
} else {
/* Direct mode */
if ( hdr & 0x80 )
*dc = hdr | ~0x7F;
else
*dc = hdr & 0x7F;
/* Flush the header bits */
rqBR_flushBits(br,11);
}
/* Clear the block & store DC ( with pre-multiply ) */
block[0] = *dc << 15;
block[1] = 0x00;
block[2] = 0x00;
block[3] = 0x00;
block[4] = 0x00;
block[5] = 0x00;
block[6] = 0x00;
block[7] = 0x00;
block[8] = 0x00;
block[9] = 0x00;
block[10] = 0x00;
block[11] = 0x00;
block[12] = 0x00;
block[13] = 0x00;
block[14] = 0x00;
block[15] = 0x00;
/* Read the AC coefficients
* at the same time, deZigZag, deQuantization, deWeighting & iDCT premultiply
*/
eff_iQWTbl = (int*) iQWTbl[hdr>>9];
cc = 0;
while ( readAC(br,&run,&amp) ) {
cc += run + 1;
if ( cc > 15 )
return -1;
block[iZigZagTbl[cc]] = amp * eff_iQWTbl[cc];
}
/* Do the column iDCT ( what's left to do ) */
iDCT_column(block[0], block[4], block[8], block[12]);
iDCT_column(block[1], block[5], block[9], block[13]);
iDCT_column(block[2], block[6], block[10], block[14]);
iDCT_column(block[3], block[7], block[11], block[15]);
/* Do the line iDCT ( complete one here ) */
iDCT_line(block[0], block[1], block[2], block[3]);
iDCT_line(block[4], block[5], block[6], block[7]);
iDCT_line(block[8], block[9], block[10], block[11]);
iDCT_line(block[12], block[13], block[14], block[15]);
return !(hdr & 0x700);
}
int v4lconvert_decode_jpgl(const unsigned char *inp, int src_size,
unsigned int dest_pix_fmt, unsigned char *fb,
int img_width, int img_height)
{
/* Vars */
struct RingQueue rq;
struct rqBitReader br;
int row, col; /* Row & Column in the image */
int x,y;
int block_idx;
unsigned char *Yline_baseptr, *Uline_baseptr, *Vline_baseptr;
unsigned char *Yline, *Uline, *Vline;
int Yline_baseofs, UVline_baseofs;
int dc_y, dc_u, dc_v; /* DC Coefficients */
int block_y[16*4]; /* Y blocks */
int block_u[16]; /* U block */
int block_v[16]; /* V block */
unsigned char *mainbuffer;
int yc,uc,vc;
/* init the decoder */
if (yuvTbl_y[0] == 0) {
vlcTbl_init();
yuvTbl_init();
#ifndef SAFE_CLAMP
clampTbl_init();
#endif
}
img_height /= 4;
/* Prepare a bit-by-bit reader */
rq.queue = inp;
rq.length = src_size;
rq.ri = 0;
rqBR_init(&br, &rq);
/* Allocate a big buffer & setup pointers */
switch (dest_pix_fmt) {
default:
/* case V4L2_PIX_FMT_RGB24: */
/* case V4L2_PIX_FMT_BGR24: */
mainbuffer = malloc(4 * (img_width + (img_width >> 1) + 2));
Yline_baseptr = mainbuffer;
Uline_baseptr = mainbuffer + (4 * img_width);
Vline_baseptr = Uline_baseptr + (img_width + 4);
break;
case V4L2_PIX_FMT_YUV420:
mainbuffer = NULL;
Yline_baseptr = fb;
Uline_baseptr = fb + img_width * img_height * 16;
Vline_baseptr = Uline_baseptr + img_width * img_height * 4;
break;
case V4L2_PIX_FMT_YVU420:
mainbuffer = NULL;
Yline_baseptr = fb;
Vline_baseptr = fb + img_width * img_height * 16;
Uline_baseptr = Vline_baseptr + img_width * img_height * 4;
break;
}
Yline_baseofs = img_width - 4;
UVline_baseofs = (img_width >> 2) - 3;
/* Process 4 lines at a time ( one block height ) */
for ( row=0 ; row<img_height ; row++ ) {
/* Line start reset DC */
dc_y = dc_u = dc_v = 0;
/* Process 16 columns at a time ( 4 block width ) */
for ( col=0 ; col<img_width ; col+=16 ) {
/* Decode blocks
* Block order : Y Y Y Y V U ( Why V before U ?
* that just depends what you call U&V ... I took the
* 'by-the-book' names and that makes V and then U,
* ... just ask the DivIO folks ;) )
*/
if ( decodeBlock(&br, block_y, &dc_y) && (!col) )
/* return; * Bad block, so bad frame ... */
;
decodeBlock(&br, block_y + 16, &dc_y);
decodeBlock(&br, block_y + 32, &dc_y);
decodeBlock(&br, block_y + 48, &dc_y);
decodeBlock(&br, block_v, &dc_v);
decodeBlock(&br, block_u, &dc_u);
/* Copy data to temporary buffers ( to make a complete line ) */
block_idx = 0;
Yline = Yline_baseptr + col;
Uline = Uline_baseptr + (col >> 2);
Vline = Vline_baseptr + (col >> 2);
for ( y=0 ; y<4 ; y++) {
/* Scan line */
for ( x=0 ; x<4 ; x++ ) {
/* Y block */
Yline[ 0] = clamp_adjust(block_y[block_idx ]);
Yline[ 4] = clamp_adjust(block_y[block_idx+16]);
Yline[ 8] = clamp_adjust(block_y[block_idx+32]);
Yline[12] = clamp_adjust(block_y[block_idx+48]);
/* U block */
*Uline = clamp_adjust(block_u[block_idx]);
/* V block */
*Vline = clamp_adjust(block_v[block_idx]);
/* Ajust pointers & index */
block_idx++;
Yline++;
Uline++;
Vline++;
}
/* Adjust pointers */
Yline += Yline_baseofs;
Uline += UVline_baseofs;
Vline += UVline_baseofs;
}
}
/* Handle interpolation special case ( at the end of the lines ) */
Uline = Uline_baseptr + (UVline_baseofs+2);
Vline = Vline_baseptr + (UVline_baseofs+2);
for ( y=0 ; y<4 ; y++ ) {
/* Copy the last pixel */
Uline[1] = Uline[0];
Vline[1] = Vline[0];
/* Adjust ptr */
Uline += UVline_baseofs+4;
Vline += UVline_baseofs+4;
}
/* We have 4 complete lines, so tempbuffer<YUV> -> framebuffer<RGB>
* Go line by line */
switch (dest_pix_fmt) {
case V4L2_PIX_FMT_RGB24:
Yline = Yline_baseptr;
Uline = Uline_baseptr;
Vline = Vline_baseptr;
for ( y=0 ; y<4 ; y++ ) {
/* Process 4 pixel at a time to handle interpolation
* for U & V values */
for ( x=0 ; x<img_width ; x+=4 ) {
/* First pixel */
yc = yuvTbl_y[*(Yline++)];
uc = Uline[0];
vc = Vline[0];
*(fb++) = clamp(( yc + yuvTbl_u1[uc] ) >> 16);
*(fb++) = clamp(( yc - yuvTbl_u2[uc] - yuvTbl_v1[vc] ) >> 16);
*(fb++) = clamp(( yc + yuvTbl_v2[vc] ) >> 16);
/* Second pixel */
yc = yuvTbl_y[*(Yline++)];
uc = ( 3*Uline[0] + Uline[1] ) >> 2;
vc = ( 3*Vline[0] + Vline[1] ) >> 2;
*(fb++) = clamp(( yc + yuvTbl_u1[uc] ) >> 16);
*(fb++) = clamp(( yc - yuvTbl_u2[uc] - yuvTbl_v1[vc] ) >> 16);
*(fb++) = clamp(( yc + yuvTbl_v2[vc] ) >> 16);
/* Third pixel */
yc = yuvTbl_y[*(Yline++)];
uc = ( Uline[0] + Uline[1] ) >> 1;
vc = ( Vline[0] + Vline[1] ) >> 1;
*(fb++) = clamp(( yc + yuvTbl_u1[uc] ) >> 16);
*(fb++) = clamp(( yc - yuvTbl_u2[uc] - yuvTbl_v1[vc] ) >> 16);
*(fb++) = clamp(( yc + yuvTbl_v2[vc] ) >> 16);
/* Fourth pixel */
yc = yuvTbl_y[*(Yline++)];
uc = ( Uline[0] + 3*Uline[1] ) >> 2;
vc = ( Vline[0] + 3*Vline[1] ) >> 2;
*(fb++) = clamp(( yc + yuvTbl_u1[uc] ) >> 16);
*(fb++) = clamp(( yc - yuvTbl_u2[uc] - yuvTbl_v1[vc] ) >> 16);
*(fb++) = clamp(( yc + yuvTbl_v2[vc] ) >> 16);
/* Adjust pointers */
Uline++;
Vline++;
}
/* Adjust pointers */
Uline++;
Vline++;
}
break;
case V4L2_PIX_FMT_BGR24:
Yline = Yline_baseptr;
Uline = Uline_baseptr;
Vline = Vline_baseptr;
for ( y=0 ; y<4 ; y++ ) {
/* Process 4 pixel at a time to handle interpolation
* for U & V values */
for ( x=0 ; x<img_width ; x+=4 ) {
/* First pixel */
yc = yuvTbl_y[*(Yline++)];
uc = Uline[0];
vc = Vline[0];
*(fb++) = clamp(( yc + yuvTbl_v2[vc] ) >> 16);
*(fb++) = clamp(( yc - yuvTbl_u2[uc] - yuvTbl_v1[vc] ) >> 16);
*(fb++) = clamp(( yc + yuvTbl_u1[uc] ) >> 16);
/* Second pixel */
yc = yuvTbl_y[*(Yline++)];
uc = ( 3*Uline[0] + Uline[1] ) >> 2;
vc = ( 3*Vline[0] + Vline[1] ) >> 2;
*(fb++) = clamp(( yc + yuvTbl_v2[vc] ) >> 16);
*(fb++) = clamp(( yc - yuvTbl_u2[uc] - yuvTbl_v1[vc] ) >> 16);
*(fb++) = clamp(( yc + yuvTbl_u1[uc] ) >> 16);
/* Third pixel */
yc = yuvTbl_y[*(Yline++)];
uc = ( Uline[0] + Uline[1] ) >> 1;
vc = ( Vline[0] + Vline[1] ) >> 1;
*(fb++) = clamp(( yc + yuvTbl_v2[vc] ) >> 16);
*(fb++) = clamp(( yc - yuvTbl_u2[uc] - yuvTbl_v1[vc] ) >> 16);
*(fb++) = clamp(( yc + yuvTbl_u1[uc] ) >> 16);
/* Fourth pixel */
yc = yuvTbl_y[*(Yline++)];
uc = ( Uline[0] + 3*Uline[1] ) >> 2;
vc = ( Vline[0] + 3*Vline[1] ) >> 2;
*(fb++) = clamp(( yc + yuvTbl_v2[vc] ) >> 16);
*(fb++) = clamp(( yc - yuvTbl_u2[uc] - yuvTbl_v1[vc] ) >> 16);
*(fb++) = clamp(( yc + yuvTbl_u1[uc] ) >> 16);
/* Adjust pointers */
Uline++;
Vline++;
}
/* Adjust pointers */
Uline++;
Vline++;
}
break;
case V4L2_PIX_FMT_YUV420:
case V4L2_PIX_FMT_YVU420:
Yline_baseptr += img_width * 4;
Uline_baseptr += img_width;
Vline_baseptr += img_width;
break;
}
}
/* Free our buffer */
if (mainbuffer != NULL)
free(mainbuffer);
return 0;
}
/*
Return-Path: tnt@246tNt.com
Received: from zimbra16-e3.priv.proxad.net (LHLO
zimbra16-e3.priv.proxad.net) (172.20.243.166) by
zimbra16-e3.priv.proxad.net with LMTP; Mon, 14 Feb 2011 21:10:38 +0100
(CET)
Received: from mailrelay011.isp.belgacom.be (mx26-g26.priv.proxad.net [172.20.243.96])
by zimbra16-e3.priv.proxad.net (Postfix) with ESMTP id 1A661157C5B
for <moinejf@free.fr>; Mon, 14 Feb 2011 21:10:38 +0100 (CET)
Received: from mailrelay011.isp.belgacom.be ([195.238.6.178])
by mx1-g20.free.fr (MXproxy) for moinejf@free.fr ;
Mon, 14 Feb 2011 21:10:36 +0100 (CET)
X-ProXaD-SC: state=HAM score=0
X-Belgacom-Dynamic: yes
X-IronPort-Anti-Spam-Filtered: true
X-IronPort-Anti-Spam-Result: ApIBAKsaWU1XQ5W2/2dsb2JhbAAMhBHOEpA5gSeBaYFYdgSLfw
Received: from 182.149-67-87.adsl-dyn.isp.belgacom.be (HELO [10.0.0.129]) ([87.67.149.182])
by relay.skynet.be with ESMTP; 14 Feb 2011 21:10:36 +0100
Message-ID: <4D598C7C.7080307@246tNt.com>
Date: Mon, 14 Feb 2011 21:11:40 +0100
From: Sylvain Munaut <tnt@246tNt.com>
User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.13) Gecko/20101219 Lightning/1.0b3pre Thunderbird/3.1.7
MIME-Version: 1.0
To: Jean-Francois Moine <moinejf@free.fr>
CC: Kjell Claesson <keyson@users.sourceforge.net>
Subject: Re: nw80x as a gspca subdriv
References: <20110209204208.4b19df88@tele> <4D53B3BF.9050908@246tNt.com> <20110214205107.18c29303@tele>
In-Reply-To: <20110214205107.18c29303@tele>
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 7bit
[snip]
> May I have your permission to relicense your JPEG Lite decompression
> code under the LGPL (version 2 or later)?
Yes, sure.
"""
I hereby allow the nw80x driver code, including the jpeg lite decoding
routines, to be used and distributed under the LGPL v2 or later.
"""
[snip]
Cheers,
Sylvain
*/

View File

@@ -0,0 +1,311 @@
/*
# (C) 2008 Hans de Goede <hdegoede@redhat.com>
#
# SPDX-FileCopyrightText: Copyright (c) 2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: LGPL-2.1-or-later
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 2.1 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
*/
#ifndef __LIBV4LCONVERT_PRIV_H
#define __LIBV4LCONVERT_PRIV_H
#ifdef ANDROID
#include <android-config.h>
#else
#include <config.h>
#endif
#include <stdio.h>
#include <stdint.h>
#include <sys/types.h>
#ifdef HAVE_JPEG
#include <jpeglib.h>
#endif
#include <setjmp.h>
#include "libv4l-plugin.h"
#include "libv4lconvert.h"
#include "control/libv4lcontrol.h"
#include "processing/libv4lprocessing.h"
#include "tinyjpeg.h"
#define ARRAY_SIZE(x) ((int)sizeof(x)/(int)sizeof((x)[0]))
#define BITS_PER_LONG (8 * sizeof(long))
#define V4LCONVERT_ERROR_MSG_SIZE 256
#define V4LCONVERT_MAX_FRAMESIZES 256
#define V4LCONVERT_ERR(...) \
snprintf(data->error_msg, V4LCONVERT_ERROR_MSG_SIZE, \
"v4l-convert: error " __VA_ARGS__)
/* Card flags */
#define V4LCONVERT_IS_UVC 0x01
#define V4LCONVERT_USE_TINYJPEG 0x02
struct v4lconvert_data {
int fd;
int flags; /* bitfield */
int control_flags; /* bitfield */
unsigned int no_formats;
unsigned long supported_src_formats[128 / BITS_PER_LONG];
char error_msg[V4LCONVERT_ERROR_MSG_SIZE];
struct jdec_private *tinyjpeg;
#ifdef HAVE_JPEG
struct jpeg_error_mgr jerr;
int jerr_errno;
jmp_buf jerr_jmp_state;
struct jpeg_decompress_struct cinfo;
int cinfo_initialized;
#endif // HAVE_JPEG
struct v4l2_frmsizeenum framesizes[V4LCONVERT_MAX_FRAMESIZES];
/* Bitmask of all supported src_formats which can do for a size */
int64_t framesize_supported_src_formats[V4LCONVERT_MAX_FRAMESIZES];
unsigned int no_framesizes;
int bandwidth;
int fps;
int convert1_buf_size;
int convert2_buf_size;
int rotate90_buf_size;
int flip_buf_size;
int convert_pixfmt_buf_size;
unsigned char *convert1_buf;
unsigned char *convert2_buf;
unsigned char *rotate90_buf;
unsigned char *flip_buf;
unsigned char *convert_pixfmt_buf;
struct v4lcontrol_data *control;
struct v4lprocessing_data *processing;
void *dev_ops_priv;
const struct libv4l_dev_ops *dev_ops;
/* Data for external decompression helpers code */
pid_t decompress_pid;
int decompress_in_pipe[2]; /* Data from helper to us */
int decompress_out_pipe[2]; /* Data from us to helper */
/* For mr97310a decoder */
int frames_dropped;
/* For cpia1 decoder */
unsigned char *previous_frame;
};
struct v4lconvert_pixfmt {
unsigned int fmt; /* v4l2 fourcc */
int bpp; /* bits per pixel, 0 for compressed formats */
int rgb_rank; /* rank for converting to rgb32 / bgr32 */
int yuv_rank; /* rank for converting to yuv420 / yvu420 */
int needs_conversion;
};
unsigned char *v4lconvert_alloc_buffer(int needed,
unsigned char **buf, int *buf_size);
int v4lconvert_oom_error(struct v4lconvert_data *data);
void v4lconvert_rgb24_to_yuv420(const unsigned char *src, unsigned char *dest,
const struct v4l2_format *src_fmt, int bgr, int yvu, int bpp);
void v4lconvert_yuv420_to_rgb24(const unsigned char *src, unsigned char *dst,
int width, int height, int yvu);
void v4lconvert_yuv420_to_bgr24(const unsigned char *src, unsigned char *dst,
int width, int height, int yvu);
void v4lconvert_yuyv_to_rgb24(const unsigned char *src, unsigned char *dst,
int width, int height, int stride);
void v4lconvert_yuyv_to_bgr24(const unsigned char *src, unsigned char *dst,
int width, int height, int stride);
void v4lconvert_yuyv_to_yuv420(const unsigned char *src, unsigned char *dst,
int width, int height, int stride, int yvu);
void v4lconvert_nv16_to_yuyv(const unsigned char *src, unsigned char *dest,
int width, int height);
void v4lconvert_yvyu_to_rgb24(const unsigned char *src, unsigned char *dst,
int width, int height, int stride);
void v4lconvert_yvyu_to_bgr24(const unsigned char *src, unsigned char *dst,
int width, int height, int stride);
void v4lconvert_uyvy_to_rgb24(const unsigned char *src, unsigned char *dst,
int width, int height, int stride);
void v4lconvert_uyvy_to_bgr24(const unsigned char *src, unsigned char *dst,
int width, int height, int stride);
void v4lconvert_uyvy_to_yuv420(const unsigned char *src, unsigned char *dst,
int width, int height, int stride, int yvu);
void v4lconvert_swap_rgb(const unsigned char *src, unsigned char *dst,
int width, int height);
void v4lconvert_swap_uv(const unsigned char *src, unsigned char *dst,
const struct v4l2_format *src_fmt);
void v4lconvert_grey_to_rgb24(const unsigned char *src, unsigned char *dest,
int width, int height);
void v4lconvert_grey_to_yuv420(const unsigned char *src, unsigned char *dest,
const struct v4l2_format *src_fmt);
void v4lconvert_y16_to_rgb24(const unsigned char *src, unsigned char *dest,
int width, int height, int little_endian);
void v4lconvert_y16_to_yuv420(const unsigned char *src, unsigned char *dest,
const struct v4l2_format *src_fmt, int little_endian);
void v4lconvert_rgb32_to_rgb24(const unsigned char *src, unsigned char *dest,
int width, int height, int bgr);
int v4lconvert_y10b_to_rgb24(struct v4lconvert_data *data,
const unsigned char *src, unsigned char *dest, int width, int height);
int v4lconvert_y10b_to_yuv420(struct v4lconvert_data *data,
const unsigned char *src, unsigned char *dest, int width, int height);
void v4lconvert_rgb565_to_rgb24(const unsigned char *src, unsigned char *dest,
int width, int height);
void v4lconvert_rgb565_to_bgr24(const unsigned char *src, unsigned char *dest,
int width, int height);
void v4lconvert_rgb565_to_yuv420(const unsigned char *src, unsigned char *dest,
const struct v4l2_format *src_fmt, int yvu);
void v4lconvert_spca501_to_yuv420(const unsigned char *src, unsigned char *dst,
int width, int height, int yvu);
void v4lconvert_spca505_to_yuv420(const unsigned char *src, unsigned char *dst,
int width, int height, int yvu);
void v4lconvert_spca508_to_yuv420(const unsigned char *src, unsigned char *dst,
int width, int height, int yvu);
void v4lconvert_cit_yyvyuy_to_yuv420(const unsigned char *src,
unsigned char *ydest,
int width, int height, int yvu);
void v4lconvert_konica_yuv420_to_yuv420(const unsigned char *src,
unsigned char *ydest,
int width, int height, int yvu);
void v4lconvert_m420_to_yuv420(const unsigned char *src,
unsigned char *ydest,
int width, int height, int yvu);
int v4lconvert_cpia1_to_yuv420(struct v4lconvert_data *data,
const unsigned char *src, int src_size,
unsigned char *dst, int width, int height, int yvu);
void v4lconvert_sn9c20x_to_yuv420(const unsigned char *src, unsigned char *dst,
int width, int height, int yvu);
int v4lconvert_se401_to_rgb24(struct v4lconvert_data *data,
const unsigned char *src, int src_size,
unsigned char *dest, int width, int height);
int v4lconvert_decode_jpeg_tinyjpeg(struct v4lconvert_data *data,
unsigned char *src, int src_size, unsigned char *dest,
struct v4l2_format *fmt, unsigned int dest_pix_fmt, int flags);
int v4lconvert_decode_jpeg_libjpeg(struct v4lconvert_data *data,
unsigned char *src, int src_size, unsigned char *dest,
struct v4l2_format *fmt, unsigned int dest_pix_fmt);
int v4lconvert_decode_jpgl(const unsigned char *src, int src_size,
unsigned int dest_pix_fmt, unsigned char *dest, int width, int height);
void v4lconvert_decode_spca561(const unsigned char *src, unsigned char *dst,
int width, int height);
void v4lconvert_decode_sn9c10x(const unsigned char *src, unsigned char *dst,
int width, int height);
int v4lconvert_decode_pac207(struct v4lconvert_data *data,
const unsigned char *inp, int src_size, unsigned char *outp,
int width, int height);
int v4lconvert_decode_mr97310a(struct v4lconvert_data *data,
const unsigned char *src, int src_size, unsigned char *dst,
int width, int height);
int v4lconvert_decode_jl2005bcd(struct v4lconvert_data *data,
const unsigned char *src, int src_size,
unsigned char *dest, int width, int height);
void v4lconvert_decode_sn9c2028(const unsigned char *src, unsigned char *dst,
int width, int height);
void v4lconvert_decode_sq905c(const unsigned char *src, unsigned char *dst,
int width, int height);
void v4lconvert_decode_stv0680(const unsigned char *src, unsigned char *dst,
int width, int height);
void v4lconvert_bayer_to_rgb24(const unsigned char *bayer,
unsigned char *rgb, int width, int height, const unsigned int stride, unsigned int pixfmt);
void v4lconvert_bayer_to_bgr24(const unsigned char *bayer,
unsigned char *rgb, int width, int height, const unsigned int stride, unsigned int pixfmt);
void v4lconvert_bayer_to_yuv420(const unsigned char *bayer, unsigned char *yuv,
int width, int height, const unsigned int stride, unsigned int src_pixfmt, int yvu);
void v4lconvert_bayer10_to_bayer8(void *bayer10,
unsigned char *bayer8, int width, int height);
void v4lconvert_bayer10p_to_bayer8(unsigned char *bayer10p,
unsigned char *bayer8, int width, int height);
void v4lconvert_bayer16_to_bayer8(unsigned char *bayer16,
unsigned char *bayer8, int width, int height);
void v4lconvert_hm12_to_rgb24(const unsigned char *src,
unsigned char *dst, int width, int height);
void v4lconvert_hm12_to_bgr24(const unsigned char *src,
unsigned char *dst, int width, int height);
void v4lconvert_hm12_to_yuv420(const unsigned char *src,
unsigned char *dst, int width, int height, int yvu);
void v4lconvert_hsv_to_rgb24(const unsigned char *src, unsigned char *dest,
int width, int height, int bgr, int Xin, unsigned char hsv_enc);
void v4lconvert_nv12_to_rgb24(const unsigned char *src, unsigned char *dest,
int width, int height, int bgr);
void v4lconvert_nv12_to_yuv420(const unsigned char *src, unsigned char *dest,
int width, int height, int yvu);
void v4lconvert_rotate90(unsigned char *src, unsigned char *dest,
struct v4l2_format *fmt);
void v4lconvert_flip(unsigned char *src, unsigned char *dest,
struct v4l2_format *fmt, int hflip, int vflip);
void v4lconvert_crop(unsigned char *src, unsigned char *dest,
const struct v4l2_format *src_fmt, const struct v4l2_format *dest_fmt);
int v4lconvert_helper_decompress(struct v4lconvert_data *data,
const char *helper, const unsigned char *src, int src_size,
unsigned char *dest, int dest_size, int width, int height, int command);
void v4lconvert_helper_cleanup(struct v4lconvert_data *data);
#endif

View File

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,24 @@
# SPDX-FileCopyrightText: Copyright (c) 2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: LGPL-2.1-or-later
v4lconvert_get_default_dev_ops
v4lconvert_create
v4lconvert_create_with_dev_ops
v4lconvert_destroy
v4lconvert_supported_dst_fmt_only
v4lconvert_try_format
v4lconvert_enum_fmt
v4lconvert_needs_conversion
v4lconvert_convert
v4lconvert_get_error_message
v4lconvert_enum_framesizes
v4lconvert_enum_frameintervals
v4lconvert_vidioc_queryctrl
v4lconvert_vidioc_g_ctrl
v4lconvert_vidioc_s_ctrl
v4lconvert_vidioc_g_ext_ctrls
v4lconvert_vidioc_try_ext_ctrls
v4lconvert_vidioc_s_ext_ctrls
v4lconvert_supported_dst_format
v4lconvert_get_fps
v4lconvert_set_fps
v4lconvert_fixup_fmt

View File

@@ -0,0 +1,11 @@
prefix=@prefix@
exec_prefix=@exec_prefix@
includedir=@includedir@
libdir=@libdir@
Name: libv4lconvert
Description: v4l format conversion library
Version: @PACKAGE_VERSION@
Libs: -L${libdir} -lv4lconvert
Libs.private: -lrt -lm @JPEG_LIBS@
Cflags: -I${includedir}

View File

@@ -0,0 +1,143 @@
/*-
* Copyright (c) 2009 Hans Petter Selasky. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/*
* The following file allows for having the complete V4L stack and
* hardware drivers in userland.
*/
#ifndef _LIBV4LSYSCALL_PRIV_H_
#define _LIBV4LSYSCALL_PRIV_H_
/* Some of these headers are not needed by us, but by linux/videodev2.h,
which is broken on some systems and doesn't include them itself :( */
#ifdef linux
#include <sys/time.h>
#include <sys/syscall.h>
#include <linux/types.h>
#include <linux/ioctl.h>
/* On 32 bits archs we always use mmap2, on 64 bits archs there is no mmap2 */
#ifdef __NR_mmap2
#if !defined(SYS_mmap2)
#define SYS_mmap2 __NR_mmap2
#endif
#define MMAP2_PAGE_SHIFT 12
#else
#define SYS_mmap2 SYS_mmap
#define MMAP2_PAGE_SHIFT 0
#endif
#endif
#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
#include <sys/time.h>
#include <sys/syscall.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#define _IOC_NR(cmd) ((cmd) & 0xFF)
#define _IOC_TYPE(cmd) IOCGROUP(cmd)
#define _IOC_SIZE(cmd) IOCPARM_LEN(cmd)
#define MAP_ANONYMOUS MAP_ANON
#define MMAP2_PAGE_SHIFT 0
#endif
#if defined(__OpenBSD__)
#include <sys/syscall.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#define _IOC_NR(cmd) ((cmd) & 0xFF)
#define _IOC_TYPE(cmd) IOCGROUP(cmd)
#define MMAP2_PAGE_SHIFT 0
#endif
#undef SYS_OPEN
#undef SYS_CLOSE
#undef SYS_IOCTL
#undef SYS_READ
#undef SYS_WRITE
#undef SYS_MMAP
#undef SYS_MUNMAP
#ifndef CONFIG_SYS_WRAPPER
#ifdef SYS_openat
#define SYS_OPEN(file, oflag, mode) \
syscall(SYS_openat, AT_FDCWD, (const char *)(file), (int)(oflag), (mode_t)(mode))
#else
#define SYS_OPEN(file, oflag, mode) \
syscall(SYS_open, (const char *)(file), (int)(oflag), (mode_t)(mode))
#endif
#define SYS_CLOSE(fd) \
syscall(SYS_close, (int)(fd))
#define SYS_IOCTL(fd, cmd, arg) \
syscall(SYS_ioctl, (int)(fd), (unsigned long)(cmd), (void *)(arg))
#define SYS_READ(fd, buf, len) \
syscall(SYS_read, (int)(fd), (void *)(buf), (size_t)(len));
#define SYS_WRITE(fd, buf, len) \
syscall(SYS_write, (int)(fd), (const void *)(buf), (size_t)(len));
#if defined(__FreeBSD__)
#define SYS_MMAP(addr, len, prot, flags, fd, off) \
__syscall(SYS_mmap, (void *)(addr), (size_t)(len), \
(int)(prot), (int)(flags), (int)(fd), (off_t)(off))
#elif defined(__FreeBSD_kernel__)
#define SYS_MMAP(addr, len, prot, flags, fd, off) \
syscall(SYS_mmap, (void *)(addr), (size_t)(len), \
(int)(prot), (int)(flags), (int)(fd), (off_t)(off))
#elif defined(__OpenBSD__)
register_t __syscall(quad_t, ...);
#define SYS_MMAP(addr, len, prot, flags, fd, offset) \
__syscall((quad_t)SYS_mmap, (void *)(addr), (size_t)(len), \
(int)(prot), (int)(flags), (int)(fd), 0, (off_t)(offset))
#else
#define SYS_MMAP(addr, len, prot, flags, fd, off) \
syscall(SYS_mmap2, (void *)(addr), (size_t)(len), \
(int)(prot), (int)(flags), (int)(fd), (off_t)((off) >> MMAP2_PAGE_SHIFT))
#endif
#define SYS_MUNMAP(addr, len) \
syscall(SYS_munmap, (void *)(addr), (size_t)(len))
#else
int v4lx_open_wrapper(const char *, int, int);
int v4lx_close_wrapper(int);
int v4lx_ioctl_wrapper(int, unsigned long, void *);
int v4lx_read_wrapper(int, void *, size_t);
int v4lx_write_wrapper(int, const void *, size_t);
void *v4lx_mmap_wrapper(void *, size_t, int, int, int, off_t);
int v4lx_munmap_wrapper(void *, size_t);
#define SYS_OPEN(...) v4lx_open_wrapper(__VA_ARGS__)
#define SYS_CLOSE(...) v4lx_close_wrapper(__VA_ARGS__)
#define SYS_IOCTL(...) v4lx_ioctl_wrapper(__VA_ARGS__)
#define SYS_READ(...) v4lx_read_wrapper(__VA_ARGS__)
#define SYS_WRITE(...) v4lx_write_wrapper(__VA_ARGS__)
#define SYS_MMAP(...) v4lx_mmap_wrapper(__VA_ARGS__)
#define SYS_MUNMAP(...) v4lx_munmap_wrapper(__VA_ARGS__)
#endif
#endif /* _LIBV4LSYSCALL_PRIV_H_ */

209
libv4lconvert/mr97310a.c Normal file
View File

@@ -0,0 +1,209 @@
/*
* MR97310A decoder
*
* Copyright (C) 2004-2009 Theodore Kilgore <kilgota@auburn.edu>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 51 Franklin Street - Suite 500,
* Boston, MA 02111-1307, USA.
*/
#include <unistd.h>
#include "libv4lconvert-priv.h"
#include "libv4lsyscall-priv.h"
#define CLIP(x) ((x) < 0 ? 0 : ((x) > 0xff) ? 0xff : (x))
#define MIN_CLOCKDIV_CID V4L2_CID_PRIVATE_BASE
/* FIXME not threadsafe */
static int decoder_initialized;
static struct {
unsigned char is_abs;
unsigned char len;
signed char val;
} table[256];
static void init_mr97310a_decoder(void)
{
int i;
int is_abs, val, len;
for (i = 0; i < 256; ++i) {
is_abs = 0;
val = 0;
len = 0;
if ((i & 0x80) == 0) {
/* code 0 */
val = 0;
len = 1;
} else if ((i & 0xe0) == 0xc0) {
/* code 110 */
val = -3;
len = 3;
} else if ((i & 0xe0) == 0xa0) {
/* code 101 */
val = 3;
len = 3;
} else if ((i & 0xf0) == 0x80) {
/* code 1000 */
val = 8;
len = 4;
} else if ((i & 0xf0) == 0x90) {
/* code 1001 */
val = -8;
len = 4;
} else if ((i & 0xf0) == 0xf0) {
/* code 1111 */
val = -20;
len = 4;
} else if ((i & 0xf8) == 0xe0) {
/* code 11100 */
val = 20;
len = 5;
} else if ((i & 0xf8) == 0xe8) {
/* code 11101xxxxx */
is_abs = 1;
val = 0; /* value is calculated later */
len = 5;
}
table[i].is_abs = is_abs;
table[i].val = val;
table[i].len = len;
}
decoder_initialized = 1;
}
static inline unsigned char get_byte(const unsigned char *inp,
unsigned int bitpos)
{
const unsigned char *addr;
addr = inp + (bitpos >> 3);
return (addr[0] << (bitpos & 7)) | (addr[1] >> (8 - (bitpos & 7)));
}
int v4lconvert_decode_mr97310a(struct v4lconvert_data *data,
const unsigned char *inp, int src_size,
unsigned char *outp, int width, int height)
{
int row, col;
int val;
int bitpos;
unsigned char code;
unsigned char lp, tp, tlp, trp;
struct v4l2_control min_clockdiv = { .id = MIN_CLOCKDIV_CID };
if (!decoder_initialized)
init_mr97310a_decoder();
/* remove the header */
inp += 12;
bitpos = 0;
/* main decoding loop */
for (row = 0; row < height; ++row) {
col = 0;
/* first two pixels in first two rows are stored as raw 8-bit */
if (row < 2) {
code = get_byte(inp, bitpos);
bitpos += 8;
*outp++ = code;
code = get_byte(inp, bitpos);
bitpos += 8;
*outp++ = code;
col += 2;
}
while (col < width) {
/* get bitcode */
code = get_byte(inp, bitpos);
/* update bit position */
bitpos += table[code].len;
/* calculate pixel value */
if (table[code].is_abs) {
/* get 5 more bits and use them as absolute value */
code = get_byte(inp, bitpos);
val = (code & 0xf8);
bitpos += 5;
} else {
/* value is relative to top or left pixel */
val = table[code].val;
lp = outp[-2];
if (row > 1) {
tlp = outp[-2 * width - 2];
tp = outp[-2 * width];
trp = outp[-2 * width + 2];
}
if (row < 2) {
/* top row: relative to left pixel */
val += lp;
} else if (col < 2) {
/* left column: relative to top pixel */
/* initial estimate */
val += (tp + trp) / 2;
} else if (col > width - 3) {
/* left column: relative to top pixel */
val += (tp + lp + tlp + 1) / 3;
/* main area: weighted average of tlp, trp,
* lp, and tp */
} else {
tlp >>= 1;
trp >>= 1;
/* initial estimate for predictor */
val += (lp + tp + tlp + trp + 1) / 3;
}
}
/* store pixel */
*outp++ = CLIP(val);
++col;
}
/* src_size - 12 because of 12 byte footer */
if (((bitpos - 1) / 8) >= (src_size - 12)) {
data->frames_dropped++;
if (data->frames_dropped == 3) {
/* Tell the driver to go slower as
the compression engine is not able to
compress the image enough, we may
fail to do this because older
drivers don't support this */
SYS_IOCTL(data->fd, VIDIOC_G_CTRL,
&min_clockdiv);
min_clockdiv.value++;
SYS_IOCTL(data->fd, VIDIOC_S_CTRL,
&min_clockdiv);
/* We return success here, because if we
return failure for too many frames in a row
libv4l2 will return an error to the
application and some applications abort
on the first error received. */
data->frames_dropped = 0;
return 0;
}
V4LCONVERT_ERR("incomplete mr97310a frame\n");
return -1;
}
}
data->frames_dropped = 0;
return 0;
}

View File

@@ -0,0 +1,666 @@
/* We would like to embed this inside libv4l, but we cannot as I've failed
to contact Mark W. McClelland to get permission to relicense this,
so this lives in an external (GPL licensed) helper */
/* OV511 Decompression Support Module
*
* Copyright (c) 1999-2003 Mark W. McClelland. All rights reserved.
* http://alpha.dyndns.org/ov511/
*
* Original decompression code Copyright 1998-2000 OmniVision Technologies
*
* 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 the
* Free Software Foundation; version 2 of the License.
*/
#include <limits.h>
#include <string.h>
#include <unistd.h>
#include "helper-funcs.h"
/******************************************************************************
* Decompression Functions
******************************************************************************/
static void DecompressYHI(unsigned char *pIn,
unsigned char *pOut,
int *iIn, /* in/out */
int *iOut, /* in/out */
const int w,
const int YUVFlag)
{
short ZigZag[64];
int temp[64];
int Zcnt_Flag = 0;
int Num8_Flag = 0;
int in_pos = *iIn;
int out_pos = *iOut;
int tmp, tmp1, tmp2, tmp3;
unsigned char header, ZTable[64];
short tmpl, tmph, half_byte, idx, count;
unsigned long ZigZag_length = 0, ZT_length, i, j;
short DeZigZag[64];
const short a = 11584;
const short b = 16068;
const short c = 15136;
const short d = 13624;
const short e = 9104;
const short f = 6270;
const short g = 3196;
int out_idx;
/* Take off every 'Zig' */
for (i = 0; i < 64; i++)
ZigZag[i] = 0;
/*****************************
* Read in the Y header byte *
*****************************/
header = pIn[in_pos];
in_pos++;
ZigZag_length = header & 0x3f;
ZigZag_length = ZigZag_length + 1;
Num8_Flag = header & 0x40;
Zcnt_Flag = header & 0x80;
/*************************
* Read in the Y content *
*************************/
if (Zcnt_Flag == 0) { /* Without Zero Table read contents directly */
/* Read in ZigZag[0] */
ZigZag[0] = pIn[in_pos++];
tmpl = pIn[in_pos++];
tmph = tmpl << 8;
ZigZag[0] = ZigZag[0] | tmph;
ZigZag[0] = ZigZag[0] << 4;
ZigZag[0] = ZigZag[0] >> 4;
if (Num8_Flag) { /* 8 Bits */
for (i = 1; i < ZigZag_length; i++) {
ZigZag[i] = pIn[in_pos++];
ZigZag[i] = ZigZag[i] << 8;
ZigZag[i] = ZigZag[i] >> 8;
}
} else { /* 12 bits and has no Zero Table */
idx = 1;
half_byte = 0;
for (i = 1; i < ZigZag_length; i++) {
if (half_byte == 0) {
ZigZag[i] = pIn[in_pos++];
tmpl = pIn[in_pos++];
tmph = tmpl << 8;
tmph = tmph & 0x0f00;
ZigZag[i] = ZigZag[i] | tmph;
ZigZag[i] = ZigZag[i] << 4;
ZigZag[i] = ZigZag[i] >> 4;
half_byte = 1;
} else {
ZigZag[i] = pIn[in_pos++];
ZigZag[i] = ZigZag[i] << 8;
tmpl = tmpl & 0x00f0;
ZigZag[i] = ZigZag[i] | tmpl;
ZigZag[i] = ZigZag[i] >> 4;
half_byte = 0;
}
}
}
} else { /* Has Zero Table */
/* Calculate Z-Table length */
ZT_length = ZigZag_length / 8;
tmp = ZigZag_length % 8;
if (tmp > 0)
ZT_length = ZT_length + 1;
/* Read in Zero Table */
for (j = 0; j < ZT_length; j++)
ZTable[j] = pIn[in_pos++];
/* Read in ZigZag[0] */
ZigZag[0] = pIn[in_pos++];
tmpl = pIn[in_pos++];
tmph = tmpl << 8;
ZigZag[0] = ZigZag[0] | tmph;
ZigZag[0] = ZigZag[0] << 4;
ZigZag[0] = ZigZag[0] >> 4;
/* Decode ZigZag */
idx = 0;
ZTable[idx] = ZTable[idx] << 1;
count = 7;
if (Num8_Flag) { /* 8 Bits and has zero table */
for (i = 1; i < ZigZag_length; i++) {
if ((ZTable[idx] & 0x80)) {
ZigZag[i] = pIn[in_pos++];
ZigZag[i] = ZigZag[i] << 8;
ZigZag[i] = ZigZag[i] >> 8;
}
ZTable[idx] = ZTable[idx]<<1;
count--;
if (count == 0) {
count = 8;
idx++;
}
}
} else { /* 12 bits and has Zero Table */
half_byte = 0;
for (i = 1; i < ZigZag_length; i++) {
if (ZTable[idx] & 0x80) {
if (half_byte == 0) {
ZigZag[i] = pIn[in_pos++];
tmpl = pIn[in_pos++];
tmph = tmpl << 8;
tmph = tmph & 0x0f00;
ZigZag[i] = ZigZag[i] | tmph;
ZigZag[i] = ZigZag[i] << 4;
ZigZag[i] = ZigZag[i] >> 4;
half_byte = 1;
} else {
ZigZag[i] = pIn[in_pos++];
ZigZag[i] = ZigZag[i] << 8;
tmpl = tmpl & 0x00f0;
ZigZag[i] = ZigZag[i] | tmpl;
ZigZag[i] = ZigZag[i] >> 4;
half_byte = 0;
}
}
ZTable[idx] = ZTable[idx] << 1;
count--;
if (count == 0) {
count = 8;
idx++;
}
}
}
}
/*************
* De-ZigZag *
*************/
for (j = 0; j < 64; j++)
DeZigZag[j] = 0;
if (YUVFlag == 1) {
DeZigZag[0] = ZigZag[0];
DeZigZag[1] = ZigZag[1] << 1;
DeZigZag[2] = ZigZag[5] << 1;
DeZigZag[3] = ZigZag[6] << 2;
DeZigZag[8] = ZigZag[2] << 1;
DeZigZag[9] = ZigZag[4] << 1;
DeZigZag[10] = ZigZag[7] << 1;
DeZigZag[11] = ZigZag[13] << 2;
DeZigZag[16] = ZigZag[3] << 1;
DeZigZag[17] = ZigZag[8] << 1;
DeZigZag[18] = ZigZag[12] << 2;
DeZigZag[19] = ZigZag[17] << 2;
DeZigZag[24] = ZigZag[9] << 2;
DeZigZag[25] = ZigZag[11] << 2;
DeZigZag[26] = ZigZag[18] << 2;
DeZigZag[27] = ZigZag[24] << 3;
} else {
DeZigZag[0] = ZigZag[0];
DeZigZag[1] = ZigZag[1] << 2;
DeZigZag[2] = ZigZag[5] << 2;
DeZigZag[3] = ZigZag[6] << 3;
DeZigZag[8] = ZigZag[2] << 2;
DeZigZag[9] = ZigZag[4] << 2;
DeZigZag[10] = ZigZag[7] << 2;
DeZigZag[11] = ZigZag[13] << 4;
DeZigZag[16] = ZigZag[3] << 2;
DeZigZag[17] = ZigZag[8] << 2;
DeZigZag[18] = ZigZag[12] << 3;
DeZigZag[19] = ZigZag[17] << 4;
DeZigZag[24] = ZigZag[9] << 3;
DeZigZag[25] = ZigZag[11] << 4;
DeZigZag[26] = ZigZag[18] << 4;
DeZigZag[27] = ZigZag[24] << 4;
}
/*****************
**** IDCT 1D ****
*****************/
#define IDCT_1D(c0, c1, c2, c3, in) \
do { \
tmp1 = ((c0) * DeZigZag[in]) + ((c2) * DeZigZag[(in) + 2]); \
tmp2 = (c1) * DeZigZag[(in) + 1]; \
tmp3 = (c3) * DeZigZag[(in) + 3]; \
} while (0)
#define COMPOSE_1(out1, out2) \
do { \
tmp = tmp1 + tmp2 + tmp3; \
temp[out1] = tmp >> 15; \
tmp = tmp1 - tmp2 - tmp3; \
temp[out2] = tmp >> 15; \
} while (0)
#define COMPOSE_2(out1, out2) \
do { \
tmp = tmp1 + tmp2 - tmp3; \
temp[out1] = tmp >> 15; \
tmp = tmp1 - tmp2 + tmp3; \
temp[out2] = tmp >> 15; \
} while (0)
/* j = 0 */
IDCT_1D(a, b, c, d, 0); COMPOSE_1(0, 56);
IDCT_1D(a, b, c, d, 8); COMPOSE_1(1, 57);
IDCT_1D(a, b, c, d, 16); COMPOSE_1(2, 58);
IDCT_1D(a, b, c, d, 24); COMPOSE_1(3, 59);
/* j = 1 */
IDCT_1D(a, d, f, g, 0); COMPOSE_2(8, 48);
IDCT_1D(a, d, f, g, 8); COMPOSE_2(9, 49);
IDCT_1D(a, d, f, g, 16); COMPOSE_2(10, 50);
IDCT_1D(a, d, f, g, 24); COMPOSE_2(11, 51);
/* j = 2 */
IDCT_1D(a, e, -f, b, 0); COMPOSE_2(16, 40);
IDCT_1D(a, e, -f, b, 8); COMPOSE_2(17, 41);
IDCT_1D(a, e, -f, b, 16); COMPOSE_2(18, 42);
IDCT_1D(a, e, -f, b, 24); COMPOSE_2(19, 43);
/* j = 3 */
IDCT_1D(a, g, -c, e, 0); COMPOSE_2(24, 32);
IDCT_1D(a, g, -c, e, 8); COMPOSE_2(25, 33);
IDCT_1D(a, g, -c, e, 16); COMPOSE_2(26, 34);
IDCT_1D(a, g, -c, e, 24); COMPOSE_2(27, 35);
#undef IDCT_1D
#undef COMPOSE_1
#undef COMPOSE_2
/*****************
**** IDCT 2D ****
*****************/
#define IDCT_2D(c0, c1, c2, c3, in) \
do { \
tmp = temp[in] * (c0) + temp[(in) + 1] * (c1) \
+ temp[(in) + 2] * (c2) + temp[(in) + 3] * (c3); \
} while (0)
#define STORE(i) \
do { \
tmp = tmp >> 15; \
tmp = tmp + 128; \
if (tmp > 255) \
tmp = 255; \
if (tmp < 0) \
tmp = 0; \
pOut[i] = (unsigned char)tmp; \
} while (0)
#define IDCT_2D_ROW(in) \
do { \
IDCT_2D(a, b, c, d, in); STORE(0 + out_idx); \
IDCT_2D(a, d, f, -g, in); STORE(1 + out_idx); \
IDCT_2D(a, e, -f, -b, in); STORE(2 + out_idx); \
IDCT_2D(a, g, -c, -e, in); STORE(3 + out_idx); \
IDCT_2D(a, -g, -c, e, in); STORE(4 + out_idx); \
IDCT_2D(a, -e, -f, b, in); STORE(5 + out_idx); \
IDCT_2D(a, -d, f, g, in); STORE(6 + out_idx); \
IDCT_2D(a, -b, c, -d, in); STORE(7 + out_idx); \
} while (0)
#define IDCT_2D_FAST(c0, c1, c2, c3, in) \
do { \
tmp1 = ((c0) * temp[in]) + ((c2) * temp[(in) + 2]); \
tmp2 = (c1) * temp[(in) + 1]; \
tmp3 = (c3) * temp[(in) + 3]; \
} while (0)
#define STORE_FAST_1(out1, out2) \
do { \
tmp = tmp1 + tmp2 + tmp3; \
STORE((out1) + out_idx); \
tmp = tmp1 - tmp2 - tmp3; \
STORE((out2) + out_idx); \
} while (0)
#define STORE_FAST_2(out1, out2) \
do { \
tmp = tmp1 + tmp2 - tmp3; \
STORE((out1) + out_idx); \
tmp = tmp1 - tmp2 + tmp3; \
STORE((out2) + out_idx); \
} while (0)
#define IDCT_2D_FAST_ROW(in) \
do { \
IDCT_2D_FAST(a, b, c, d, in); STORE_FAST_1(0, 7); \
IDCT_2D_FAST(a, d, f, g, in); STORE_FAST_2(1, 6); \
IDCT_2D_FAST(a, e, -f, b, in); STORE_FAST_2(2, 5); \
IDCT_2D_FAST(a, g, -c, e, in); STORE_FAST_2(3, 4); \
} while (0)
out_idx = out_pos;
IDCT_2D_ROW(0); out_idx += w;
IDCT_2D_ROW(8); out_idx += w;
IDCT_2D_ROW(16); out_idx += w;
IDCT_2D_ROW(24); out_idx += w;
IDCT_2D_ROW(32); out_idx += w;
IDCT_2D_ROW(40); out_idx += w;
IDCT_2D_FAST_ROW(48); out_idx += w;
IDCT_2D_FAST_ROW(56);
*iIn = in_pos;
*iOut = out_pos + 8;
}
#define DECOMP_Y() DecompressYHI(pIn, pY, &iIn, &iY, w, 1)
#define DECOMP_U() DecompressYHI(pIn, pU, &iIn, &iU, w / 2, 2)
#define DECOMP_V() DecompressYHI(pIn, pV, &iIn, &iV, w / 2, 2)
#if 0
static inline int
Decompress400HiNoMMX(unsigned char *pIn,
unsigned char *pOut,
const int w,
const int h,
const int inSize)
{
unsigned char *pY = pOut;
int x, y, iIn, iY;
iIn = 0;
for (y = 0; y < h; y += 8) {
iY = w * y;
for (x = 0; x < w; x += 8)
DECOMP_Y();
}
return 0;
}
#endif
static inline int
Decompress420HiNoMMX(unsigned char *pIn,
unsigned char *pOut,
const int w,
const int h,
const int inSize)
{
unsigned char *pY = pOut;
unsigned char *pU = pY + w * h;
unsigned char *pV = pU + w * h / 4;
int xY, xUV, iY, iU, iV, iIn, count;
const int nBlocks = (w * h) / (32 * 8);
iIn = 0;
iY = iU = iV = 0;
xY = xUV = 0;
for (count = 0; count < nBlocks; count++) {
DECOMP_U();
DECOMP_V(); xUV += 16;
if (xUV >= w) {
iU += (w * 7) / 2;
iV += (w * 7) / 2;
xUV = 0;
}
DECOMP_Y(); xY += 8;
DECOMP_Y(); xY += 8;
if (xY >= w) {
iY += w * 7;
xY = 0;
}
DECOMP_Y(); xY += 8;
DECOMP_Y(); xY += 8;
if (xY >= w) {
iY += w * 7;
xY = 0;
}
}
return 0;
}
/* Copies a 64-byte segment at pIn to an 8x8 block at pOut. The width of the
* image at pOut is specified by w.
*/
static inline void
make_8x8(unsigned char *pIn, unsigned char *pOut, int w)
{
unsigned char *pOut1 = pOut;
int x, y;
for (y = 0; y < 8; y++) {
pOut1 = pOut;
for (x = 0; x < 8; x++)
*pOut1++ = *pIn++;
pOut += w;
}
}
#if 0
/*
* For RAW BW (YUV 4:0:0) images, data show up in 256 byte segments.
* The segments represent 4 squares of 8x8 pixels as follows:
*
* 0 1 ... 7 64 65 ... 71 ... 192 193 ... 199
* 8 9 ... 15 72 73 ... 79 200 201 ... 207
* ... ... ...
* 56 57 ... 63 120 121 ... 127 248 249 ... 255
*
*/
static void
yuv400raw_to_yuv400p(struct ov511_frame *frame,
unsigned char *pIn0, unsigned char *pOut0)
{
int x, y;
unsigned char *pIn, *pOut, *pOutLine;
/* Copy Y */
pIn = pIn0;
pOutLine = pOut0;
for (y = 0; y < frame->rawheight - 1; y += 8) {
pOut = pOutLine;
for (x = 0; x < frame->rawwidth - 1; x += 8) {
make_8x8(pIn, pOut, frame->rawwidth);
pIn += 64;
pOut += 8;
}
pOutLine += 8 * frame->rawwidth;
}
}
#endif
/*
* For YUV 4:2:0 images, the data show up in 384 byte segments.
* The first 64 bytes of each segment are U, the next 64 are V. The U and
* V are arranged as follows:
*
* 0 1 ... 7
* 8 9 ... 15
* ...
* 56 57 ... 63
*
* U and V are shipped at half resolution (1 U,V sample -> one 2x2 block).
*
* The next 256 bytes are full resolution Y data and represent 4 squares
* of 8x8 pixels as follows:
*
* 0 1 ... 7 64 65 ... 71 ... 192 193 ... 199
* 8 9 ... 15 72 73 ... 79 200 201 ... 207
* ... ... ...
* 56 57 ... 63 120 121 ... 127 ... 248 249 ... 255
*
* Note that the U and V data in one segment represent a 16 x 16 pixel
* area, but the Y data represent a 32 x 8 pixel area. If the width is not an
* even multiple of 32, the extra 8x8 blocks within a 32x8 block belong to the
* next horizontal stripe.
*
* If dumppix module param is set, _parse_data just dumps the incoming segments,
* verbatim, in order, into the frame. When used with vidcat -f ppm -s 640x480
* this puts the data on the standard output and can be analyzed with the
* parseppm.c utility I wrote. That's a much faster way for figuring out how
* these data are scrambled.
*/
/* Converts from raw, uncompressed segments at pIn0 to a YUV420P frame at pOut0.
*
* FIXME: Currently only handles width and height that are multiples of 16
*/
static void
yuv420raw_to_yuv420p(unsigned char *pIn0, unsigned char *pOut0,
int width, int height)
{
int k, x, y;
unsigned char *pIn, *pOut, *pOutLine;
const unsigned int a = width * height;
const unsigned int w = width / 2;
/* Copy U and V */
pIn = pIn0;
pOutLine = pOut0 + a;
for (y = 0; y < height - 1; y += 16) {
pOut = pOutLine;
for (x = 0; x < width - 1; x += 16) {
make_8x8(pIn, pOut, w);
make_8x8(pIn + 64, pOut + a / 4, w);
pIn += 384;
pOut += 8;
}
pOutLine += 8 * w;
}
/* Copy Y */
pIn = pIn0 + 128;
pOutLine = pOut0;
k = 0;
for (y = 0; y < height - 1; y += 8) {
pOut = pOutLine;
for (x = 0; x < width - 1; x += 8) {
make_8x8(pIn, pOut, width);
pIn += 64;
pOut += 8;
if ((++k) > 3) {
k = 0;
pIn += 128;
}
}
pOutLine += 8 * width;
}
}
/* Remove all 0 blocks from input */
static void remove0blocks(unsigned char *pIn, int *inSize)
{
long long *in = (long long *)pIn;
long long *out = (long long *)pIn;
int i, j;
for (i = 0; i < *inSize; i += 32, in += 4) {
int all_zero = 1;
for (j = 0; j < 4; j++)
if (in[j]) {
all_zero = 0;
break;
}
/* Skip 32 byte blocks of all 0 */
if (all_zero)
continue;
for (j = 0; j < 4; j++)
*out++ = in[j];
}
*inSize -= (in - out) * 8;
}
static int v4lconvert_ov511_to_yuv420(unsigned char *src, unsigned char *dest,
int w, int h, int yvu, int src_size)
{
int rc = 0;
src_size -= 11; /* Remove footer */
remove0blocks(src, &src_size);
/* Compressed ? */
if (src[8] & 0x40)
rc = Decompress420HiNoMMX(src + 9, dest, w, h, src_size);
else
yuv420raw_to_yuv420p(src + 9, dest, w, h);
return rc;
}
int main(int argc, char *argv[])
{
int width, height, yvu, src_size, dest_size;
unsigned char src_buf[500000];
unsigned char dest_buf[500000];
while (1) {
if (v4lconvert_helper_read(STDIN_FILENO, &width, sizeof(int), argv[0]))
return 1; /* Erm, no way to recover without loosing sync with libv4l */
if (v4lconvert_helper_read(STDIN_FILENO, &height, sizeof(int), argv[0]))
return 1; /* Erm, no way to recover without loosing sync with libv4l */
if (v4lconvert_helper_read(STDIN_FILENO, &yvu, sizeof(int), argv[0]))
return 1; /* Erm, no way to recover without loosing sync with libv4l */
if (v4lconvert_helper_read(STDIN_FILENO, &src_size, sizeof(int), argv[0]))
return 1; /* Erm, no way to recover without loosing sync with libv4l */
if (src_size > sizeof(src_buf)) {
fprintf(stderr, "%s: error: src_buf too small, need: %d\n",
argv[0], src_size);
return 2;
}
if (v4lconvert_helper_read(STDIN_FILENO, src_buf, src_size, argv[0]))
return 1; /* Erm, no way to recover without loosing sync with libv4l */
dest_size = width * height * 3 / 2;
if (width <= 0 || width > SHRT_MAX || height <= 0 || height > SHRT_MAX) {
fprintf(stderr, "%s: error: width or height out of bounds\n",
argv[0]);
dest_size = -1;
} else if (dest_size > sizeof(dest_buf)) {
fprintf(stderr, "%s: error: dest_buf too small, need: %d\n",
argv[0], dest_size);
dest_size = -1;
} else if (v4lconvert_ov511_to_yuv420(src_buf, dest_buf, width, height,
yvu, src_size))
dest_size = -1;
if (v4lconvert_helper_write(STDOUT_FILENO, &dest_size, sizeof(int),
argv[0]))
return 1; /* Erm, no way to recover without loosing sync with libv4l */
if (dest_size == -1)
continue;
if (v4lconvert_helper_write(STDOUT_FILENO, dest_buf, dest_size, argv[0]))
return 1; /* Erm, no way to recover without loosing sync with libv4l */
}
}

1482
libv4lconvert/ov518-decomp.c Normal file
View File

File diff suppressed because it is too large Load Diff

437
libv4lconvert/pac207.c Normal file
View File

@@ -0,0 +1,437 @@
/*
# PAC207 decoder
# Bertrik.Sikken. Thomas Kaiser (C) 2005
# Copyright (C) 2003 2004 2005 Michel Xhaard
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 2.1 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
# Note this code was originally licensed under the GNU GPL instead of the
# GNU LGPL, its license has been changed with permission, see the permission
# mails at the end of this file.
*/
#include <string.h>
#include "libv4lconvert-priv.h"
#define CLIP(color) (unsigned char)(((color) > 0xFF) ? 0xff : (((color) < 0) ? 0 : (color)))
/* FIXME not threadsafe */
static int decoder_initialized;
static struct {
unsigned char is_abs;
unsigned char len;
signed char val;
} table[256];
static void init_pixart_decoder(void)
{
int i;
int is_abs, val, len;
for (i = 0; i < 256; i++) {
is_abs = 0;
val = 0;
len = 0;
if ((i & 0xC0) == 0) {
/* code 00 */
val = 0;
len = 2;
} else if ((i & 0xC0) == 0x40) {
/* code 01 */
val = -1;
len = 2;
} else if ((i & 0xC0) == 0x80) {
/* code 10 */
val = 1;
len = 2;
} else if ((i & 0xF0) == 0xC0) {
/* code 1100 */
val = -2;
len = 4;
} else if ((i & 0xF0) == 0xD0) {
/* code 1101 */
val = 2;
len = 4;
} else if ((i & 0xF8) == 0xE0) {
/* code 11100 */
val = -3;
len = 5;
} else if ((i & 0xF8) == 0xE8) {
/* code 11101 */
val = 3;
len = 5;
} else if ((i & 0xFC) == 0xF0) {
/* code 111100 */
val = -4;
len = 6;
} else if ((i & 0xFC) == 0xF4) {
/* code 111101 */
val = 4;
len = 6;
} else if ((i & 0xF8) == 0xF8) {
/* code 11111xxxxxx */
is_abs = 1;
val = 0;
len = 5;
}
table[i].is_abs = is_abs;
table[i].val = val;
table[i].len = len;
}
decoder_initialized = 1;
}
static inline unsigned char getByte(const unsigned char *inp,
unsigned int bitpos)
{
const unsigned char *addr;
addr = inp + (bitpos >> 3);
return (addr[0] << (bitpos & 7)) | (addr[1] >> (8 - (bitpos & 7)));
}
static inline unsigned short getShort(const unsigned char *pt)
{
return ((pt[0] << 8) | pt[1]);
}
static int
pac_decompress_row(const unsigned char *inp, unsigned char *outp, int width,
int step_size, int abs_bits)
{
int col;
int val;
int bitpos;
unsigned char code;
if (!decoder_initialized)
init_pixart_decoder();
/* first two pixels are stored as raw 8-bit */
*outp++ = inp[2];
*outp++ = inp[3];
bitpos = 32;
/* main decoding loop */
for (col = 2; col < width; col++) {
/* get bitcode */
code = getByte(inp, bitpos);
bitpos += table[code].len;
/* calculate pixel value */
if (table[code].is_abs) {
/* absolute value: get 6 more bits */
code = getByte(inp, bitpos);
bitpos += abs_bits;
*outp++ = code & ~(0xff >> abs_bits);
} else {
/* relative to left pixel */
val = outp[-2] + table[code].val * step_size;
*outp++ = CLIP(val);
}
}
/* return line length, rounded up to next 16-bit word */
return 2 * ((bitpos + 15) / 16);
}
int v4lconvert_decode_pac207(struct v4lconvert_data *data,
const unsigned char *inp, int src_size, unsigned char *outp,
int width, int height)
{
/* we should received a whole frame with header and EOL marker
in myframe->data and return a GBRG pattern in frame->tmpbuffer
remove the header then copy line by line EOL is set with 0x0f 0xf0 marker
or 0x1e 0xe1 for compressed line*/
const unsigned char *end = inp + src_size;
unsigned short word;
int row;
/* iterate over all rows */
for (row = 0; row < height; row++) {
if ((inp + 2) > end) {
V4LCONVERT_ERR("incomplete pac207 frame\n");
return -1;
}
word = getShort(inp);
switch (word) {
case 0x0FF0:
memcpy(outp, inp + 2, width);
inp += (2 + width);
break;
case 0x1EE1:
inp += pac_decompress_row(inp, outp, width, 5, 6);
break;
case 0x2DD2:
inp += pac_decompress_row(inp, outp, width, 9, 5);
break;
case 0x3CC3:
inp += pac_decompress_row(inp, outp, width, 17, 4);
break;
case 0x4BB4:
/* skip or copy line? */
memcpy(outp, outp - 2 * width, width);
inp += 2;
break;
default: /* corrupt frame */
V4LCONVERT_ERR("unknown pac207 row header: 0x%04x\n", (int)word);
return -1;
}
outp += width;
}
return 0;
}
/*
Return-Path: <thomas@kaiser-linux.li>
Received: from koko.hhs.nl ([145.52.2.16] verified)
by hhs.nl (CommuniGate Pro SMTP 4.3.6)
with ESMTP id 88906346 for j.w.r.degoede@hhs.nl; Thu, 26 Jun 2008 01:17:00 +0200
Received: from exim (helo=koko)
by koko.hhs.nl with local-smtp (Exim 4.62)
(envelope-from <thomas@kaiser-linux.li>)
id 1KBeEW-0001qu-H6
for j.w.r.degoede@hhs.nl; Thu, 26 Jun 2008 01:17:00 +0200
Received: from [192.87.102.74] (port=41049 helo=filter6-ams.mf.surf.net)
by koko.hhs.nl with esmtp (Exim 4.62)
(envelope-from <thomas@kaiser-linux.li>)
id 1KBeEV-0001qn-2T
for j.w.r.degoede@hhs.nl; Thu, 26 Jun 2008 01:17:00 +0200
Received: from smtp0.lie-comtel.li (smtp0.lie-comtel.li [217.173.238.80])
by filter6-ams.mf.surf.net (8.13.8/8.13.8/Debian-3) with ESMTP id m5PNGwSF007539
for <j.w.r.degoede@hhs.nl>; Thu, 26 Jun 2008 01:16:58 +0200
Received: from localhost (localhost.lie-comtel.li [127.0.0.1])
by smtp0.lie-comtel.li (Postfix) with ESMTP id DDB609FEC1D;
Thu, 26 Jun 2008 00:16:56 +0100 (GMT-1)
X-Virus-Scanned: Virus scanned by amavis at smtp.lie-comtel.li
Received: from [192.168.0.16] (217-173-228-198.cmts.powersurf.li [217.173.228.198])
by smtp0.lie-comtel.li (Postfix) with ESMTP id 80B589FEC19;
Thu, 26 Jun 2008 00:16:56 +0100 (GMT-1)
Message-ID: <4862D211.3000802@kaiser-linux.li>
Date: Thu, 26 Jun 2008 01:17:37 +0200
From: Thomas Kaiser <thomas@kaiser-linux.li>
User-Agent: Thunderbird 2.0.0.14 (X11/20080505)
MIME-Version: 1.0
To: Hans de Goede <j.w.r.degoede@hhs.nl>
CC: Thomas Kaiser <spca5xx@kaiser-linux.li>, bertrik@zonnet.nl,
mxhaard@magic.fr
Subject: Re: pac207 bayer decompression algorithm license question
References: <4862C0A4.3060003@hhs.nl>
In-Reply-To: <4862C0A4.3060003@hhs.nl>
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 7bit
X-Canit-CHI2: 0.00
X-Bayes-Prob: 0.0001 (Score 0, tokens from: @@RPTN)
X-Spam-Score: 0.00 () [Tag at 8.00]
X-CanItPRO-Stream: hhs:j.w.r.degoede@hhs.nl (inherits from hhs:default,base:default)
X-Canit-Stats-ID: 88604132 - 38b3b44cd798
X-Scanned-By: CanIt (www . roaringpenguin . com) on 192.87.102.74
X-Anti-Virus: Kaspersky Anti-Virus for MailServers 5.5.2/RELEASE, bases: 25062008 #787666, status: clean
Hello Hans
Hans de Goede wrote:
> Hi,
>
> As you may have seen on the mailinglist, I've created a userspace
> library to handle cam specific format handling in userspace where it
> belongs, see:
> http://hansdegoede.livejournal.com/
Yes, I saw it on the mail list and I think it is a good idea :-)
>
> I would like to also add support for decompressing the pac207's
> compressed bayer to this lib (and remove it from the kernel driver)
> for this I need permission to relicense the decompress code under the
> LGPL (version 2 or later).
Actually, this was done by Bertrik Sikken (bertrik@zonnet.nl), Michel
Xhaard (mxhaard@magic.fr) and me. But Bertrik was the one who found out
how to decode the lines :-)
>
> Can you give me permission for this, or if the code is not yours put
> me in contact with someone who can?
For me it's no problem to release it with LGPL. Maybe you have to ask
the other one's also.
>
> Thanks & Regards,
>
> Hans
Rgeards, Thomas
*/
/*
Return-Path: <mxhaard@magic.fr>
Received: from koko.hhs.nl ([145.52.2.16] verified)
by hhs.nl (CommuniGate Pro SMTP 4.3.6)
with ESMTP id 88910192 for j.w.r.degoede@hhs.nl; Thu, 26 Jun 2008 09:15:37 +0200
Received: from exim (helo=koko)
by koko.hhs.nl with local-smtp (Exim 4.62)
(envelope-from <mxhaard@magic.fr>)
id 1KBlhh-0006Fi-Oe
for j.w.r.degoede@hhs.nl; Thu, 26 Jun 2008 09:15:37 +0200
Received: from [194.171.167.220] (port=54180 helo=filter4-til.mf.surf.net)
by koko.hhs.nl with esmtp (Exim 4.62)
(envelope-from <mxhaard@magic.fr>)
id 1KBlhh-0006Fd-FY
for j.w.r.degoede@hhs.nl; Thu, 26 Jun 2008 09:15:37 +0200
Received: from smtp4-g19.free.fr (smtp4-g19.free.fr [212.27.42.30])
by filter4-til.mf.surf.net (8.13.8/8.13.8/Debian-3) with ESMTP id m5Q7FY1I006360
for <j.w.r.degoede@hhs.nl>; Thu, 26 Jun 2008 09:15:34 +0200
Received: from smtp4-g19.free.fr (localhost.localdomain [127.0.0.1])
by smtp4-g19.free.fr (Postfix) with ESMTP id 51C683EA0E7;
Thu, 26 Jun 2008 09:15:34 +0200 (CEST)
Received: from [192.168.1.11] (lns-bzn-54-82-251-105-53.adsl.proxad.net [82.251.105.53])
by smtp4-g19.free.fr (Postfix) with ESMTP id 1149E3EA0C7;
Thu, 26 Jun 2008 09:15:34 +0200 (CEST)
From: Michel Xhaard <mxhaard@magic.fr>
To: Hans de Goede <j.w.r.degoede@hhs.nl>
Subject: Re: pac207 bayer decompression algorithm license question
Date: Thu, 26 Jun 2008 11:15:32 +0200
User-Agent: KMail/1.9.5
Cc: bertrik@zonnet.nl, spca5xx@kaiser-linux.li,
"Jean-Francois Moine" <moinejf@free.fr>
References: <48633F02.3040108@hhs.nl>
In-Reply-To: <48633F02.3040108@hhs.nl>
MIME-Version: 1.0
Content-Type: text/plain;
charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: inline
Message-Id: <200806261115.32909.mxhaard@magic.fr>
X-Canit-CHI2: 0.00
X-Bayes-Prob: 0.0001 (Score 0, tokens from: @@RPTN)
X-Spam-Score: 0.00 () [Tag at 8.00]
X-CanItPRO-Stream: hhs:j.w.r.degoede@hhs.nl (inherits from hhs:default,base:default)
X-Canit-Stats-ID: 88656338 - 0dde233cb8b5
X-Scanned-By: CanIt (www . roaringpenguin . com) on 194.171.167.220
X-Anti-Virus: Kaspersky Anti-Virus for MailServers 5.5.2/RELEASE, bases: 26062008 #787720, status: clean
Le jeudi 26 juin 2008 09:02, Hans de Goede a =E9crit=A0:
> Hi,
>
> As you may have seen on the mailinglist, I've created a userspace library
> to handle cam specific format handling in userspace, see:
> http://hansdegoede.livejournal.com/
>
> I would like to also add support for decompressing the pac207's compressed
> bayer to this lib (and remove it from the kernel driver) and I've heard
> from Thomas Kaiser that you are a co-author of the decompression code. In
> order to add support for decompressing pac207 compressed bayer to libv4l I
> need permission to relicense the decompression code under the LGPL (versi=
on
> 2 or later).
>
> Can you give me permission for this?
>
> Thanks & Regards,
>
> Hans
>
>
>
> p.s.
>
> Thomas has already given permission.
=46or me it is ok and a good idea for all free world familly ;-).
Bests regards
=2D-=20
Michel Xhaard
http://mxhaard.free.fr
*/
/*
Return-Path: <bertrik@sikken.nl>
Received: from koko.hhs.nl ([145.52.2.16] verified)
by hhs.nl (CommuniGate Pro SMTP 4.3.6)
with ESMTP id 88940205 for j.w.r.degoede@hhs.nl; Thu, 26 Jun 2008 22:03:30 +0200
Received: from exim (helo=koko)
by koko.hhs.nl with local-smtp (Exim 4.62)
(envelope-from <bertrik@sikken.nl>)
id 1KBxgo-0003Dj-ET
for j.w.r.degoede@hhs.nl; Thu, 26 Jun 2008 22:03:30 +0200
Received: from [192.87.102.69] (port=51992 helo=filter1-ams.mf.surf.net)
by koko.hhs.nl with esmtp (Exim 4.62)
(envelope-from <bertrik@sikken.nl>)
id 1KBxgo-0003Dd-5i
for j.w.r.degoede@hhs.nl; Thu, 26 Jun 2008 22:03:30 +0200
Received: from pelian.kabelfoon.nl (pelian3.kabelfoon.nl [62.45.45.106])
by filter1-ams.mf.surf.net (8.13.8/8.13.8/Debian-3) with ESMTP id m5QK3ThE007720
for <j.w.r.degoede@hhs.nl>; Thu, 26 Jun 2008 22:03:29 +0200
Received: from [192.168.1.1] (062-015-045-062.dynamic.caiway.nl [62.45.15.62])
by pelian.kabelfoon.nl (Postfix) with ESMTP id 9239B428100
for <j.w.r.degoede@hhs.nl>; Thu, 26 Jun 2008 22:03:29 +0200 (CEST)
Message-ID: <4863F611.80104@sikken.nl>
Date: Thu, 26 Jun 2008 22:03:29 +0200
From: Bertrik Sikken <bertrik@sikken.nl>
User-Agent: Thunderbird 2.0.0.14 (Windows/20080421)
MIME-Version: 1.0
To: Hans de Goede <j.w.r.degoede@hhs.nl>
Subject: Re: pac207 bayer decompression algorithm license question
References: <48633F02.3040108@hhs.nl>
In-Reply-To: <48633F02.3040108@hhs.nl>
X-Enigmail-Version: 0.95.6
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 7bit
X-Canit-CHI2: 0.00
X-Bayes-Prob: 0.0001 (Score 0, tokens from: @@RPTN)
X-Spam-Score: 0.00 () [Tag at 8.00]
X-CanItPRO-Stream: hhs:j.w.r.degoede@hhs.nl (inherits from hhs:default,base:default)
X-Canit-Stats-ID: 88938005 - ef1f0836ffc7
X-Scanned-By: CanIt (www . roaringpenguin . com) on 192.87.102.69
X-Anti-Virus: Kaspersky Anti-Virus for MailServers 5.5.2/RELEASE, bases: 26062008 #787877, status: clean
Hallo Hans,
Hans de Goede wrote:
> Hi,
>
> As you may have seen on the mailinglist, I've created a userspace
> library to
> handle cam specific format handling in userspace, see:
> http://hansdegoede.livejournal.com/
O leuk, zoiets is naar mijn idee precies wat er nodig is voor webcam
support onder linux. Ik ben een jaar of 3 geleden heel actief geweest
met een aantal webcams, maar doe er tegenwoordig helemaal niets meer
aan.
> I would like to also add support for decompressing the pac207's compressed
> bayer to this lib (and remove it from the kernel driver) and I've heard
> from Thomas Kaiser that you are a co-author of the decompression code.
> In order to add support for decompressing pac207 compressed bayer to
> libv4l I need
> permission to relicense the decompression code under the LGPL (version 2
> or later).
>
> Can you give me permission for this?
Ja, vind ik goed.
Vriendelijke groet,
Bertrik
*/

View File

@@ -0,0 +1,221 @@
/*
# (C) 2008-2009 Hans de Goede <hdegoede@redhat.com>
#
# SPDX-FileCopyrightText: Copyright (c) 2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: LGPL-2.1-or-later
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 2.1 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
*/
#include <errno.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "libv4lprocessing.h"
#include "libv4lprocessing-priv.h"
#include "../libv4lconvert-priv.h" /* for PIX_FMT defines */
#include "../libv4lsyscall-priv.h"
static int autogain_active(struct v4lprocessing_data *data)
{
int autogain;
autogain = v4lcontrol_get_ctrl(data->control, V4LCONTROL_AUTOGAIN);
if (!autogain) {
/* Reset last_correction val */
data->last_gain_correction = 0;
}
return autogain;
}
/* Adjust ctrl value with steps steps, while not crossing limit */
static void autogain_adjust(struct v4l2_queryctrl *ctrl, int *value,
int steps, int limit, int accel)
{
int ctrl_range = (ctrl->maximum - ctrl->minimum) / ctrl->step;
/* If we are of 3 * deadzone or more, and we have a fine grained
control, take larger steps, otherwise we take ages to get to the
right setting point. We use 256 as tripping point for determining
fine grained controls here, as avg_lum has a range of 0 - 255. */
if (accel && abs(steps) >= 3 && ctrl_range > 256)
*value += steps * ctrl->step * (ctrl_range / 256);
/* If we are of by less than 3, but have a very finegrained control
still speed things up a bit */
else if (accel && ctrl_range > 1024)
*value += steps * ctrl->step * (ctrl_range / 1024);
else
*value += steps * ctrl->step;
if (steps > 0) {
if (*value > limit)
*value = limit;
} else {
if (*value < limit)
*value = limit;
}
}
/* auto gain and exposure algorithm based on the knee algorithm described here:
http://ytse.tricolour.net/docs/LowLightOptimization.html */
static int autogain_calculate_lookup_tables(
struct v4lprocessing_data *data,
unsigned char *buf, const struct v4l2_format *fmt)
{
int x, y, target, steps, avg_lum = 0;
int gain, exposure, orig_gain, orig_exposure, exposure_low;
struct v4l2_control ctrl;
struct v4l2_queryctrl gainctrl, expoctrl;
const int deadzone = 6;
ctrl.id = V4L2_CID_EXPOSURE;
expoctrl.id = V4L2_CID_EXPOSURE;
if (SYS_IOCTL(data->fd, VIDIOC_QUERYCTRL, &expoctrl) ||
SYS_IOCTL(data->fd, VIDIOC_G_CTRL, &ctrl))
return 0;
exposure = orig_exposure = ctrl.value;
/* Determine a value below which we try to not lower the exposure,
as most exposure controls tend to jump with big steps in the low
range, causing oscilation, so we prefer to use gain when exposure
has hit this value */
exposure_low = (expoctrl.maximum - expoctrl.minimum) / 10;
/* If we have a fine grained exposure control only avoid the last 10 steps */
steps = exposure_low / expoctrl.step;
if (steps > 10)
steps = 10;
exposure_low = steps * expoctrl.step + expoctrl.minimum;
ctrl.id = V4L2_CID_GAIN;
gainctrl.id = V4L2_CID_GAIN;
if (SYS_IOCTL(data->fd, VIDIOC_QUERYCTRL, &gainctrl) ||
SYS_IOCTL(data->fd, VIDIOC_G_CTRL, &ctrl))
return 0;
gain = orig_gain = ctrl.value;
switch (fmt->fmt.pix.pixelformat) {
case V4L2_PIX_FMT_SGBRG8:
case V4L2_PIX_FMT_SGRBG8:
case V4L2_PIX_FMT_SBGGR8:
case V4L2_PIX_FMT_SRGGB8:
buf += fmt->fmt.pix.height * fmt->fmt.pix.bytesperline / 4 +
fmt->fmt.pix.width / 4;
for (y = 0; (unsigned)y < fmt->fmt.pix.height / 2; y++) {
for (x = 0; (unsigned)x < fmt->fmt.pix.width / 2; x++)
avg_lum += *buf++;
buf += fmt->fmt.pix.bytesperline - fmt->fmt.pix.width / 2;
}
avg_lum /= fmt->fmt.pix.height * fmt->fmt.pix.width / 4;
break;
case V4L2_PIX_FMT_RGB24:
case V4L2_PIX_FMT_BGR24:
buf += fmt->fmt.pix.height * fmt->fmt.pix.bytesperline / 4 +
fmt->fmt.pix.width * 3 / 4;
for (y = 0; (unsigned)y < fmt->fmt.pix.height / 2; y++) {
for (x = 0; (unsigned)x < fmt->fmt.pix.width / 2; x++) {
avg_lum += *buf++;
avg_lum += *buf++;
avg_lum += *buf++;
}
buf += fmt->fmt.pix.bytesperline - fmt->fmt.pix.width * 3 / 2;
}
avg_lum /= fmt->fmt.pix.height * fmt->fmt.pix.width * 3 / 4;
break;
}
/* If we are off a multiple of deadzone, do multiple steps to reach the
desired lumination fast (with the risc of a slight overshoot) */
target = v4lcontrol_get_ctrl(data->control, V4LCONTROL_AUTOGAIN_TARGET);
steps = (target - avg_lum) / deadzone;
/* If we were decreasing and are now increasing, or vica versa, half the
number of steps to avoid overshooting and oscilating */
if ((steps > 0 && data->last_gain_correction < 0) ||
(steps < 0 && data->last_gain_correction > 0))
steps /= 2;
if (steps == 0)
return 0; /* Nothing to do */
if (steps < 0) {
if (exposure > expoctrl.default_value)
autogain_adjust(&expoctrl, &exposure, steps,
expoctrl.default_value, 1);
else if (gain > gainctrl.default_value)
autogain_adjust(&gainctrl, &gain, steps,
gainctrl.default_value, 1);
else if (exposure > exposure_low)
autogain_adjust(&expoctrl, &exposure, steps,
exposure_low, 1);
else if (gain > gainctrl.minimum)
autogain_adjust(&gainctrl, &gain, steps,
gainctrl.minimum, 1);
else if (exposure > expoctrl.minimum)
autogain_adjust(&expoctrl, &exposure, steps,
expoctrl.minimum, 0);
else
steps = 0;
} else {
if (exposure < exposure_low)
autogain_adjust(&expoctrl, &exposure, steps,
exposure_low, 0);
else if (gain < gainctrl.default_value)
autogain_adjust(&gainctrl, &gain, steps,
gainctrl.default_value, 1);
else if (exposure < expoctrl.default_value)
autogain_adjust(&expoctrl, &exposure, steps,
expoctrl.default_value, 1);
else if (gain < gainctrl.maximum)
autogain_adjust(&gainctrl, &gain, steps,
gainctrl.maximum, 1);
else if (exposure < expoctrl.maximum)
autogain_adjust(&expoctrl, &exposure, steps,
expoctrl.maximum, 1);
else
steps = 0;
}
if (steps) {
data->last_gain_correction = steps;
/* We are still settling down, force the next update sooner. Note we
skip the next frame as that is still captured with the old settings,
and another one just to be sure (because if we re-adjust based
on the old settings we might overshoot). */
data->lookup_table_update_counter = V4L2PROCESSING_UPDATE_RATE - 2;
}
if (gain != orig_gain) {
ctrl.id = V4L2_CID_GAIN;
ctrl.value = gain;
SYS_IOCTL(data->fd, VIDIOC_S_CTRL, &ctrl);
}
if (exposure != orig_exposure) {
ctrl.id = V4L2_CID_EXPOSURE;
ctrl.value = exposure;
SYS_IOCTL(data->fd, VIDIOC_S_CTRL, &ctrl);
}
return 0;
}
const struct v4lprocessing_filter autogain_filter = {
autogain_active, autogain_calculate_lookup_tables
};

View File

@@ -0,0 +1,62 @@
/*
# (C) 2008-2009 Hans de Goede <hdegoede@redhat.com>
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 2.1 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
*/
#include <math.h>
#include "libv4lprocessing.h"
#include "libv4lprocessing-priv.h"
#define CLIP(color) (unsigned char)(((color) > 0xff) ? 0xff : (((color) < 0) ? 0 : (color)))
static int gamma_active(struct v4lprocessing_data *data)
{
int gamma = v4lcontrol_get_ctrl(data->control, V4LCONTROL_GAMMA);
return gamma && gamma != 1000;
}
static int gamma_calculate_lookup_tables(
struct v4lprocessing_data *data,
unsigned char *buf, const struct v4l2_format *fmt)
{
int i, x, gamma;
gamma = v4lcontrol_get_ctrl(data->control, V4LCONTROL_GAMMA);
if (gamma == 0)
return 0;
if (gamma != data->last_gamma) {
for (i = 0; i < 256; i++) {
x = powf(i / 255.0, 1000.0 / gamma) * 255;
data->gamma_table[i] = CLIP(x);
}
data->last_gamma = gamma;
}
for (i = 0; i < 256; i++) {
data->comp1[i] = data->gamma_table[data->comp1[i]];
data->green[i] = data->gamma_table[data->green[i]];
data->comp2[i] = data->gamma_table[data->comp2[i]];
}
return 1;
}
const struct v4lprocessing_filter gamma_filter = {
gamma_active, gamma_calculate_lookup_tables
};

View File

@@ -0,0 +1,68 @@
/*
# (C) 2008-2009 Elmar Kleijn <elmar_kleijn@hotmail.com>
# (C) 2008-2009 Sjoerd Piepenbrink <need4weed@gmail.com>
# (C) 2008-2009 Hans de Goede <hdegoede@redhat.com>
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 2.1 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
*/
#ifndef __LIBV4LPROCESSING_PRIV_H
#define __LIBV4LPROCESSING_PRIV_H
#include "../control/libv4lcontrol.h"
#include "../libv4lsyscall-priv.h"
#define V4L2PROCESSING_UPDATE_RATE 10
struct v4lprocessing_data {
struct v4lcontrol_data *control;
int fd;
int do_process;
int controls_changed;
/* True if any of the lookup tables does not contain
linear 0-255 */
int lookup_table_active;
/* Counts the number of processed frames until a
V4L2PROCESSING_UPDATE_RATE overflow happens */
int lookup_table_update_counter;
/* RGB/BGR lookup tables */
unsigned char comp1[256];
unsigned char green[256];
unsigned char comp2[256];
/* Filter private data for filters which need it */
/* whitebalance.c data */
int green_avg;
int comp1_avg;
int comp2_avg;
/* gamma.c data */
int last_gamma;
unsigned char gamma_table[256];
/* autogain.c data */
int last_gain_correction;
};
struct v4lprocessing_filter {
/* Returns 1 if the filter is active */
int (*active)(struct v4lprocessing_data *data);
/* Returns 1 if any of the lookup tables was changed */
int (*calculate_lookup_tables)(struct v4lprocessing_data *data,
unsigned char *buf, const struct v4l2_format *fmt);
};
extern const struct v4lprocessing_filter whitebalance_filter;
extern const struct v4lprocessing_filter autogain_filter;
extern const struct v4lprocessing_filter gamma_filter;
#endif

Some files were not shown because too many files have changed in this diff Show More