mirror of
git://nv-tegra.nvidia.com/tegra/v4l2-src/v4l2_libs.git
synced 2025-12-22 01:14:00 +03:00
Updating prebuilts and/or headers
60e29f95ea52df4407d771330897813cdb38340f - libv4lconvert/libv4lsyscall-priv.h 1f1d1e05443c4b824cd697c0ce5efa9ea1277964 - libv4lconvert/ov518-decomp.c f4d73412805f12fa08dd79a43798a7f8d7acece9 - libv4lconvert/pac207.c cc3f3e94a21795990610e63887c30528bde7b42e - libv4lconvert/bayer.c 3c49d99b9753208a9c1c2a9c738a1e7ad291ca22 - libv4lconvert/jpeg_memsrcdest.h 3271d74d02e2f33c16e3e50aeb1268eb9c440782 - libv4lconvert/rgbyuv.c 1949e23fe99ccd0a05dcd084848f6d38b0af7ab6 - libv4lconvert/hm12.c 4eff5c1a5e0b99ce4d6e9aa63645d9628467fdc3 - libv4lconvert/sn9c2028-decomp.c b2c19c2eac71d39d3fb883cdc159a69c2afa8fd6 - libv4lconvert/ov511-decomp.c 84c9c3812d4b5f237c8cd616d37fc1161a212acc - libv4lconvert/se401.c 463725aa4dd3fecaf89c0b8bbf4747f8f7577935 - libv4lconvert/jpeg.c fbbffd8182b4fe2e85289b6e784f70cba7ea7b1d - libv4lconvert/sq905c.c db3c69c666e451c5d4ef6d1b5a3117f4b128baa4 - libv4lconvert/libv4lconvert-priv.h 8b7644ac3d5c4161cfb6dcc2a34013f4c379c665 - libv4lconvert/libv4lconvert.export 22fd03618c218ae14ba59a5aab5f30b0acd2b6ea - libv4lconvert/Makefile 72953a5a3a56b0188d35f49246356b9c8c35756c - libv4lconvert/helper.c 66dd7958319442bd52ba40ede28fbfe31bb4e074 - libv4lconvert/cpia1.c 1d9c446cd8a232da87bd79acebc93e018ec72499 - libv4lconvert/jidctflt.c cc8982bb6f753249181c715fe6430ffefc78c23b - libv4lconvert/stv0680.c 25130d299463897a09e8b9adf72389dac2e89fa4 - libv4lconvert/tinyjpeg-internal.h 22a502c238e48f4b939c81de41feccfc7c366766 - libv4lconvert/Makefile.dGPU fb3344cfa8df97688332ee4fd3b17968437e8ad5 - libv4lconvert/helper-funcs.h 5430e46abb1ac7039ed0309ca338237533ff29c9 - libv4lconvert/sn9c20x.c d6c1aba89bbcb6fef46a6f22b7ea01025435c44d - libv4lconvert/Makefile.am 3e8e6c1fb85e3c4b58c4e9b2b0a223ddc793edcb - libv4lconvert/libv4lconvert.pc.in 6ad4947dca51a7e67e056561cdb445d6c354d23c - libv4lconvert/libv4lconvert.c ff7444c48a8da88f8a466cfb138e30e585828cb3 - libv4lconvert/jl2005bcd.c 803c4d0b9364050eda163452b8792e62e221ab6d - libv4lconvert/tinyjpeg.h f061a4e0e45ca8e0dbab630dd477e19a6c915fda - libv4lconvert/spca501.c 07f8e7c84abfbbe76d49d8bfd1f4eae6ea39a90b - libv4lconvert/jpgl.c fa751ff0f78845f3b4591396710df3b165bc8d11 - libv4lconvert/mr97310a.c be9e3bf3d7d1086b6eed0c1bf2f574c2b1737c00 - libv4lconvert/tinyjpeg.c 033894511bd7e8a374a52486889658faa17918c4 - libv4lconvert/flip.c b694b6348e035b3da880824c2c2768145c9b5199 - libv4lconvert/jpeg_memsrcdest.c 725c9b8d0bfadba566cf200921e602961cb12705 - libv4lconvert/spca561-decompress.c ddd39b2fe0e2a86a6c64031ccc0d36edfd9b0f1a - libv4lconvert/sn9c10x.c f08c902ecd48c2739956606b502fc0b8e4007703 - libv4lconvert/crop.c dae9c69b7f019d7d4494cd56e2cf757e8510824a - libv4lconvert/processing/whitebalance.c 0390d660eb130f0e580832bcf8ad5069010d2696 - libv4lconvert/processing/libv4lprocessing.h a54c2cb0439e606af01d0b4f02704f411819d98c - libv4lconvert/processing/libv4lprocessing.c ebf12bcf99f35fb9c400b04a1439e68598268249 - libv4lconvert/processing/gamma.c 33ab91b54108e8c24cbb80c5c335d96391d440b2 - libv4lconvert/processing/libv4lprocessing-priv.h 7da402829dbff238ca6ac829c037a85476185db6 - libv4lconvert/processing/autogain.c 1e08fb01a598d71e3fc69656c4f2291f7dc13105 - libv4lconvert/control/libv4lcontrol.h 19a7fd04cdeba61172f281806d030472dee79fcd - libv4lconvert/control/libv4lcontrol.c 70f4992835e964b2698473971904375333e3659b - libv4lconvert/control/libv4lcontrol-priv.h 9d456d1772885d900865a8958c0291e13d509de5 - libv4l2/v4l2convert.c 7fa618184ff89737d13164be0b79e227d81f398c - libv4l2/log.c d1f2b6f016cfb90c616d848418feb915e3737fa7 - libv4l2/libv4l2.c 766aaca553b0166eb736557e44ad42b69464aa53 - libv4l2/libv4l2.export e6516370c43e4869e05a540d2e4ef584ac64890a - libv4l2/v4l2-plugin.c 752cb342c44989a8c172e3280e220a6fa2ec86b5 - libv4l2/Makefile 4ba98a607592ed0b8327b387af354544c65c9b67 - libv4l2/v4l2-plugin-android.c 2542aabb7fbff4b1a09faaadec6006c4410a6d10 - libv4l2/libv4l2-priv.h ffecae84262f548deac1da0fa51f1aba6b6f96a0 - libv4l2/Makefile.dGPU 8e335567bf404eeb3d180dd384309f687f2ab944 - libv4l2/Makefile.am cbcee4426c19c168c6f49d04af3a0b2e30c0b681 - libv4l2/libv4l2.pc.in c84a9a115a21d1fd20da0f6ca3df7b46dd23cd2a - include/config.h 1edc439e6c0fc98513fa4a69557eb6221d043be0 - include/libv4l2.h 6feb5b2b8c99c99712dd1ea7fe9ab674d58bf86b - include/libv4l1.h bc44111fd6b2f0374a9fc67b1b23666c5c498b2c - include/libv4l2rds.h f751b481c4a9203345cdbb6459d0f2882f7cdbd9 - include/libv4lconvert.h f2b73fa5ab10ea7038e58bd9a4461d8e16316249 - include/libv4l1-videodev.h 94434b9692371b7d5f54ddef2141d22d90079ce9 - include/libv4l-plugin.h c8b4fc511833f0993fa740a529e1f61e0f5a216f - include/libdvbv5/mpeg_es.h fb8d640da36b6a156cbe0ef12dc25468de89a2a1 - include/libdvbv5/dvb-sat.h 9a2b20076d6728b5799096e4149e33a73119e1ef - include/libdvbv5/desc_sat.h ac87e3306569dae329809f27ef227c5d50f0b60e - include/libdvbv5/desc_event_short.h efa3a711499f68ae370d49d98dc1963bf6bafcd8 - include/libdvbv5/desc_extension.h ad13bfa0b1642fc72cca387e62bc193974c8d5ee - include/libdvbv5/atsc_header.h b867a2e7941d718aa64b2f6a1402322b616cb2da - include/libdvbv5/pmt.h bdf514383ca0afe981cf4fd6af86440db2dc6667 - include/libdvbv5/pat.h 96db22ef84892a36d5df3cffa0b30d5bad01939c - include/libdvbv5/desc_logical_channel.h 92d4c28148d0b537c8afc289e1a76de68435cba0 - include/libdvbv5/dvb-scan.h 7544b5fb8f621a9c637c40d8f7a2a71f6ab4bd63 - include/libdvbv5/desc_hierarchy.h b72b6d1ffcdd81e3e631c7c20bb30e5c287dc7ff - include/libdvbv5/vct.h 9d523ee179af955a687662996050ee3cfaacf2ab - include/libdvbv5/crc32.h 6e6fd4c61c1f61006c63214cbe4868d49428ddb9 - include/libdvbv5/mpeg_pes.h d7a096d51e3050c8f52e0e2111d88b71a5313da1 - include/libdvbv5/dvb-demux.h 5b4a5e7fb30a7f28118be012837e73a7151d2619 - include/libdvbv5/cat.h 30e9a7240938943de2725f2b335b19ad320179a5 - include/libdvbv5/header.h 4c412880f0c49cd00cb16e56eed082c4744211a5 - include/libdvbv5/countries.h e81b7f75c11f175cf365fc7fb535e80828f10e24 - include/libdvbv5/dvb-file.h 2560f18846a535a2c02e1ae449511e731f11c011 - include/libdvbv5/desc_ca_identifier.h c18291ff9009bfe71a2c7c6f0fce75331dc95e30 - include/libdvbv5/sdt.h 44ab16a8d4eae09690c71a6301927c1da55dda6d - include/libdvbv5/descriptors.h 188fc2cbec97288787a7f66554a4b6288224f980 - include/libdvbv5/desc_isdbt_delivery.h c1212a9308d96730de547648d3cda2fc144d0e29 - include/libdvbv5/desc_atsc_service_location.h 7fb0966c6a1ccdf1a8844aed4a94d4ae1d02fcd7 - include/libdvbv5/dvb-fe.h 40a06b5375dbc0de88a15d26cc6c1e9a505119bc - include/libdvbv5/eit.h 22c83d133e5c1d2648efb3028e0d89c970d0aad4 - include/libdvbv5/desc_partial_reception.h 1ba874a7cad36ff31e4af3bfb37b98c05063d6b2 - include/libdvbv5/desc_event_extended.h 146f4f53fc49c66b59905249c0142efffd72fc54 - include/libdvbv5/desc_network_name.h 100c02ce3bc364ddff895c75f4fb1f928a748d2d - include/libdvbv5/desc_cable_delivery.h 7645dda247bcd45628afbb74ec2707a47050992e - include/libdvbv5/nit.h 73b7b0cf684de0e8a4eae49a8521f81b411d7b72 - include/libdvbv5/desc_ts_info.h 6bd2ed0beaf6aa4838e239198564fd8e1d20a3a1 - include/libdvbv5/desc_t2_delivery.h d562371bb8a3b961c4d63a0f5618453bdff4bcd3 - include/libdvbv5/dvb-log.h ef979f3276cc3cad6e947865a42643fbba860c69 - include/libdvbv5/mgt.h 2f55ba765c689500401111747bb381b5aca77b30 - include/libdvbv5/desc_ca.h 450fab787e61210c0c5f527df92c31c90b44a113 - include/libdvbv5/desc_service.h cabecc6d7c9fdf1c437273bd6a746bf83c156f72 - include/libdvbv5/desc_frequency_list.h 5e2dfc1d9a71805389e9a7932812695d0309050c - include/libdvbv5/dvb-frontend.h 7a6093b13354d054cac78ea118a96e813cac3395 - include/libdvbv5/atsc_eit.h 9b5cfad4a5f41cbf886507da6e79b07314827b32 - include/libdvbv5/desc_language.h 98365b48442b9e3abb58101983b5da8c14f78289 - include/libdvbv5/dvb-v5-std.h 4fe7def34ff640fc5e327b3596298169fdfe2f1c - include/libdvbv5/mpeg_ts.h 02168c58e3c772f116f075085579ac4a8422e819 - include/libdvbv5/desc_terrestrial_delivery.h Change-Id: I9171be045a8449f064603120422debb54883a76d
This commit is contained in:
110
commitFile.txt
Normal file
110
commitFile.txt
Normal file
@@ -0,0 +1,110 @@
|
||||
Updating prebuilts and/or headers
|
||||
|
||||
60e29f95ea52df4407d771330897813cdb38340f - libv4lconvert/libv4lsyscall-priv.h
|
||||
1f1d1e05443c4b824cd697c0ce5efa9ea1277964 - libv4lconvert/ov518-decomp.c
|
||||
f4d73412805f12fa08dd79a43798a7f8d7acece9 - libv4lconvert/pac207.c
|
||||
cc3f3e94a21795990610e63887c30528bde7b42e - libv4lconvert/bayer.c
|
||||
3c49d99b9753208a9c1c2a9c738a1e7ad291ca22 - libv4lconvert/jpeg_memsrcdest.h
|
||||
3271d74d02e2f33c16e3e50aeb1268eb9c440782 - libv4lconvert/rgbyuv.c
|
||||
1949e23fe99ccd0a05dcd084848f6d38b0af7ab6 - libv4lconvert/hm12.c
|
||||
4eff5c1a5e0b99ce4d6e9aa63645d9628467fdc3 - libv4lconvert/sn9c2028-decomp.c
|
||||
b2c19c2eac71d39d3fb883cdc159a69c2afa8fd6 - libv4lconvert/ov511-decomp.c
|
||||
84c9c3812d4b5f237c8cd616d37fc1161a212acc - libv4lconvert/se401.c
|
||||
463725aa4dd3fecaf89c0b8bbf4747f8f7577935 - libv4lconvert/jpeg.c
|
||||
fbbffd8182b4fe2e85289b6e784f70cba7ea7b1d - libv4lconvert/sq905c.c
|
||||
db3c69c666e451c5d4ef6d1b5a3117f4b128baa4 - libv4lconvert/libv4lconvert-priv.h
|
||||
8b7644ac3d5c4161cfb6dcc2a34013f4c379c665 - libv4lconvert/libv4lconvert.export
|
||||
22fd03618c218ae14ba59a5aab5f30b0acd2b6ea - libv4lconvert/Makefile
|
||||
72953a5a3a56b0188d35f49246356b9c8c35756c - libv4lconvert/helper.c
|
||||
66dd7958319442bd52ba40ede28fbfe31bb4e074 - libv4lconvert/cpia1.c
|
||||
1d9c446cd8a232da87bd79acebc93e018ec72499 - libv4lconvert/jidctflt.c
|
||||
cc8982bb6f753249181c715fe6430ffefc78c23b - libv4lconvert/stv0680.c
|
||||
25130d299463897a09e8b9adf72389dac2e89fa4 - libv4lconvert/tinyjpeg-internal.h
|
||||
22a502c238e48f4b939c81de41feccfc7c366766 - libv4lconvert/Makefile.dGPU
|
||||
fb3344cfa8df97688332ee4fd3b17968437e8ad5 - libv4lconvert/helper-funcs.h
|
||||
5430e46abb1ac7039ed0309ca338237533ff29c9 - libv4lconvert/sn9c20x.c
|
||||
d6c1aba89bbcb6fef46a6f22b7ea01025435c44d - libv4lconvert/Makefile.am
|
||||
3e8e6c1fb85e3c4b58c4e9b2b0a223ddc793edcb - libv4lconvert/libv4lconvert.pc.in
|
||||
6ad4947dca51a7e67e056561cdb445d6c354d23c - libv4lconvert/libv4lconvert.c
|
||||
ff7444c48a8da88f8a466cfb138e30e585828cb3 - libv4lconvert/jl2005bcd.c
|
||||
803c4d0b9364050eda163452b8792e62e221ab6d - libv4lconvert/tinyjpeg.h
|
||||
f061a4e0e45ca8e0dbab630dd477e19a6c915fda - libv4lconvert/spca501.c
|
||||
07f8e7c84abfbbe76d49d8bfd1f4eae6ea39a90b - libv4lconvert/jpgl.c
|
||||
fa751ff0f78845f3b4591396710df3b165bc8d11 - libv4lconvert/mr97310a.c
|
||||
be9e3bf3d7d1086b6eed0c1bf2f574c2b1737c00 - libv4lconvert/tinyjpeg.c
|
||||
033894511bd7e8a374a52486889658faa17918c4 - libv4lconvert/flip.c
|
||||
b694b6348e035b3da880824c2c2768145c9b5199 - libv4lconvert/jpeg_memsrcdest.c
|
||||
725c9b8d0bfadba566cf200921e602961cb12705 - libv4lconvert/spca561-decompress.c
|
||||
ddd39b2fe0e2a86a6c64031ccc0d36edfd9b0f1a - libv4lconvert/sn9c10x.c
|
||||
f08c902ecd48c2739956606b502fc0b8e4007703 - libv4lconvert/crop.c
|
||||
dae9c69b7f019d7d4494cd56e2cf757e8510824a - libv4lconvert/processing/whitebalance.c
|
||||
0390d660eb130f0e580832bcf8ad5069010d2696 - libv4lconvert/processing/libv4lprocessing.h
|
||||
a54c2cb0439e606af01d0b4f02704f411819d98c - libv4lconvert/processing/libv4lprocessing.c
|
||||
ebf12bcf99f35fb9c400b04a1439e68598268249 - libv4lconvert/processing/gamma.c
|
||||
33ab91b54108e8c24cbb80c5c335d96391d440b2 - libv4lconvert/processing/libv4lprocessing-priv.h
|
||||
7da402829dbff238ca6ac829c037a85476185db6 - libv4lconvert/processing/autogain.c
|
||||
1e08fb01a598d71e3fc69656c4f2291f7dc13105 - libv4lconvert/control/libv4lcontrol.h
|
||||
19a7fd04cdeba61172f281806d030472dee79fcd - libv4lconvert/control/libv4lcontrol.c
|
||||
70f4992835e964b2698473971904375333e3659b - libv4lconvert/control/libv4lcontrol-priv.h
|
||||
9d456d1772885d900865a8958c0291e13d509de5 - libv4l2/v4l2convert.c
|
||||
7fa618184ff89737d13164be0b79e227d81f398c - libv4l2/log.c
|
||||
d1f2b6f016cfb90c616d848418feb915e3737fa7 - libv4l2/libv4l2.c
|
||||
766aaca553b0166eb736557e44ad42b69464aa53 - libv4l2/libv4l2.export
|
||||
e6516370c43e4869e05a540d2e4ef584ac64890a - libv4l2/v4l2-plugin.c
|
||||
752cb342c44989a8c172e3280e220a6fa2ec86b5 - libv4l2/Makefile
|
||||
4ba98a607592ed0b8327b387af354544c65c9b67 - libv4l2/v4l2-plugin-android.c
|
||||
2542aabb7fbff4b1a09faaadec6006c4410a6d10 - libv4l2/libv4l2-priv.h
|
||||
ffecae84262f548deac1da0fa51f1aba6b6f96a0 - libv4l2/Makefile.dGPU
|
||||
8e335567bf404eeb3d180dd384309f687f2ab944 - libv4l2/Makefile.am
|
||||
cbcee4426c19c168c6f49d04af3a0b2e30c0b681 - libv4l2/libv4l2.pc.in
|
||||
c84a9a115a21d1fd20da0f6ca3df7b46dd23cd2a - include/config.h
|
||||
1edc439e6c0fc98513fa4a69557eb6221d043be0 - include/libv4l2.h
|
||||
6feb5b2b8c99c99712dd1ea7fe9ab674d58bf86b - include/libv4l1.h
|
||||
bc44111fd6b2f0374a9fc67b1b23666c5c498b2c - include/libv4l2rds.h
|
||||
f751b481c4a9203345cdbb6459d0f2882f7cdbd9 - include/libv4lconvert.h
|
||||
f2b73fa5ab10ea7038e58bd9a4461d8e16316249 - include/libv4l1-videodev.h
|
||||
94434b9692371b7d5f54ddef2141d22d90079ce9 - include/libv4l-plugin.h
|
||||
c8b4fc511833f0993fa740a529e1f61e0f5a216f - include/libdvbv5/mpeg_es.h
|
||||
fb8d640da36b6a156cbe0ef12dc25468de89a2a1 - include/libdvbv5/dvb-sat.h
|
||||
9a2b20076d6728b5799096e4149e33a73119e1ef - include/libdvbv5/desc_sat.h
|
||||
ac87e3306569dae329809f27ef227c5d50f0b60e - include/libdvbv5/desc_event_short.h
|
||||
efa3a711499f68ae370d49d98dc1963bf6bafcd8 - include/libdvbv5/desc_extension.h
|
||||
ad13bfa0b1642fc72cca387e62bc193974c8d5ee - include/libdvbv5/atsc_header.h
|
||||
b867a2e7941d718aa64b2f6a1402322b616cb2da - include/libdvbv5/pmt.h
|
||||
bdf514383ca0afe981cf4fd6af86440db2dc6667 - include/libdvbv5/pat.h
|
||||
96db22ef84892a36d5df3cffa0b30d5bad01939c - include/libdvbv5/desc_logical_channel.h
|
||||
92d4c28148d0b537c8afc289e1a76de68435cba0 - include/libdvbv5/dvb-scan.h
|
||||
7544b5fb8f621a9c637c40d8f7a2a71f6ab4bd63 - include/libdvbv5/desc_hierarchy.h
|
||||
b72b6d1ffcdd81e3e631c7c20bb30e5c287dc7ff - include/libdvbv5/vct.h
|
||||
9d523ee179af955a687662996050ee3cfaacf2ab - include/libdvbv5/crc32.h
|
||||
6e6fd4c61c1f61006c63214cbe4868d49428ddb9 - include/libdvbv5/mpeg_pes.h
|
||||
d7a096d51e3050c8f52e0e2111d88b71a5313da1 - include/libdvbv5/dvb-demux.h
|
||||
5b4a5e7fb30a7f28118be012837e73a7151d2619 - include/libdvbv5/cat.h
|
||||
30e9a7240938943de2725f2b335b19ad320179a5 - include/libdvbv5/header.h
|
||||
4c412880f0c49cd00cb16e56eed082c4744211a5 - include/libdvbv5/countries.h
|
||||
e81b7f75c11f175cf365fc7fb535e80828f10e24 - include/libdvbv5/dvb-file.h
|
||||
2560f18846a535a2c02e1ae449511e731f11c011 - include/libdvbv5/desc_ca_identifier.h
|
||||
c18291ff9009bfe71a2c7c6f0fce75331dc95e30 - include/libdvbv5/sdt.h
|
||||
44ab16a8d4eae09690c71a6301927c1da55dda6d - include/libdvbv5/descriptors.h
|
||||
188fc2cbec97288787a7f66554a4b6288224f980 - include/libdvbv5/desc_isdbt_delivery.h
|
||||
c1212a9308d96730de547648d3cda2fc144d0e29 - include/libdvbv5/desc_atsc_service_location.h
|
||||
7fb0966c6a1ccdf1a8844aed4a94d4ae1d02fcd7 - include/libdvbv5/dvb-fe.h
|
||||
40a06b5375dbc0de88a15d26cc6c1e9a505119bc - include/libdvbv5/eit.h
|
||||
22c83d133e5c1d2648efb3028e0d89c970d0aad4 - include/libdvbv5/desc_partial_reception.h
|
||||
1ba874a7cad36ff31e4af3bfb37b98c05063d6b2 - include/libdvbv5/desc_event_extended.h
|
||||
146f4f53fc49c66b59905249c0142efffd72fc54 - include/libdvbv5/desc_network_name.h
|
||||
100c02ce3bc364ddff895c75f4fb1f928a748d2d - include/libdvbv5/desc_cable_delivery.h
|
||||
7645dda247bcd45628afbb74ec2707a47050992e - include/libdvbv5/nit.h
|
||||
73b7b0cf684de0e8a4eae49a8521f81b411d7b72 - include/libdvbv5/desc_ts_info.h
|
||||
6bd2ed0beaf6aa4838e239198564fd8e1d20a3a1 - include/libdvbv5/desc_t2_delivery.h
|
||||
d562371bb8a3b961c4d63a0f5618453bdff4bcd3 - include/libdvbv5/dvb-log.h
|
||||
ef979f3276cc3cad6e947865a42643fbba860c69 - include/libdvbv5/mgt.h
|
||||
2f55ba765c689500401111747bb381b5aca77b30 - include/libdvbv5/desc_ca.h
|
||||
450fab787e61210c0c5f527df92c31c90b44a113 - include/libdvbv5/desc_service.h
|
||||
cabecc6d7c9fdf1c437273bd6a746bf83c156f72 - include/libdvbv5/desc_frequency_list.h
|
||||
5e2dfc1d9a71805389e9a7932812695d0309050c - include/libdvbv5/dvb-frontend.h
|
||||
7a6093b13354d054cac78ea118a96e813cac3395 - include/libdvbv5/atsc_eit.h
|
||||
9b5cfad4a5f41cbf886507da6e79b07314827b32 - include/libdvbv5/desc_language.h
|
||||
98365b48442b9e3abb58101983b5da8c14f78289 - include/libdvbv5/dvb-v5-std.h
|
||||
4fe7def34ff640fc5e327b3596298169fdfe2f1c - include/libdvbv5/mpeg_ts.h
|
||||
02168c58e3c772f116f075085579ac4a8422e819 - include/libdvbv5/desc_terrestrial_delivery.h
|
||||
220
include/config.h
Normal file
220
include/config.h
Normal file
@@ -0,0 +1,220 @@
|
||||
/* 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
221
include/libdvbv5/atsc_eit.h
Normal 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 General Public License
|
||||
* as published by the Free Software Foundation version 2
|
||||
* 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU 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 General Public License version 2 (GPLv2)
|
||||
* @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) \
|
||||
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
|
||||
60
include/libdvbv5/atsc_header.h
Normal file
60
include/libdvbv5/atsc_header.h
Normal file
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* 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 General Public License
|
||||
* as published by the Free Software Foundation version 2
|
||||
* 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU 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 General Public License version 2 (GPLv2)
|
||||
* @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 */
|
||||
107
include/libdvbv5/cat.h
Normal file
107
include/libdvbv5/cat.h
Normal file
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
* 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 General Public License
|
||||
* as published by the Free Software Foundation version 2
|
||||
* 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU 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 General Public License version 2 (GPLv2)
|
||||
* @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
|
||||
869
include/libdvbv5/countries.h
Normal file
869
include/libdvbv5/countries.h
Normal 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 General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* 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 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 General Public License version 2 (GPLv2)
|
||||
* @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
|
||||
59
include/libdvbv5/crc32.h
Normal file
59
include/libdvbv5/crc32.h
Normal file
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* 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 General Public License
|
||||
* as published by the Free Software Foundation version 2
|
||||
* 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU 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 General Public License version 2 (GPLv2)
|
||||
* @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
|
||||
|
||||
141
include/libdvbv5/desc_atsc_service_location.h
Normal file
141
include/libdvbv5/desc_atsc_service_location.h
Normal file
@@ -0,0 +1,141 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2014 - Mauro Carvalho Chehab <m.chehab@samsung.com>
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* 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 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 General Public License version 2 (GPLv2)
|
||||
* @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));
|
||||
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
|
||||
126
include/libdvbv5/desc_ca.h
Normal file
126
include/libdvbv5/desc_ca.h
Normal file
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
* 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 General Public License
|
||||
* as published by the Free Software Foundation version 2
|
||||
* 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU 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 General Public License version 2 (GPLv2)
|
||||
* @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
|
||||
115
include/libdvbv5/desc_ca_identifier.h
Normal file
115
include/libdvbv5/desc_ca_identifier.h
Normal file
@@ -0,0 +1,115 @@
|
||||
/*
|
||||
* 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 General Public License
|
||||
* as published by the Free Software Foundation version 2
|
||||
* 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU 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 General Public License version 2 (GPLv2)
|
||||
* @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
|
||||
133
include/libdvbv5/desc_cable_delivery.h
Normal file
133
include/libdvbv5/desc_cable_delivery.h
Normal file
@@ -0,0 +1,133 @@
|
||||
/*
|
||||
* 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 General Public License
|
||||
* as published by the Free Software Foundation version 2
|
||||
* 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU 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 General Public License version 2 (GPLv2)
|
||||
* @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
|
||||
126
include/libdvbv5/desc_event_extended.h
Normal file
126
include/libdvbv5/desc_event_extended.h
Normal file
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
* 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 General Public License
|
||||
* as published by the Free Software Foundation version 2
|
||||
* 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU 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 General Public License version 2 (GPLv2)
|
||||
* @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
|
||||
* @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;
|
||||
} __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
|
||||
119
include/libdvbv5/desc_event_short.h
Normal file
119
include/libdvbv5/desc_event_short.h
Normal file
@@ -0,0 +1,119 @@
|
||||
/*
|
||||
* 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 General Public License
|
||||
* as published by the Free Software Foundation version 2
|
||||
* 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU 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 General Public License version 2 (GPLv2)
|
||||
* @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
|
||||
225
include/libdvbv5/desc_extension.h
Normal file
225
include/libdvbv5/desc_extension.h
Normal file
@@ -0,0 +1,225 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2014 - Mauro Carvalho Chehab <m.chehab@samsung.com>
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* 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 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 General Public License version 2 (GPLv2)
|
||||
* @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
|
||||
113
include/libdvbv5/desc_frequency_list.h
Normal file
113
include/libdvbv5/desc_frequency_list.h
Normal file
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
* 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 General Public License
|
||||
* as published by the Free Software Foundation version 2
|
||||
* 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU 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 General Public License version 2 (GPLv2)
|
||||
* @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
|
||||
115
include/libdvbv5/desc_hierarchy.h
Normal file
115
include/libdvbv5/desc_hierarchy.h
Normal file
@@ -0,0 +1,115 @@
|
||||
/*
|
||||
* 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 General Public License
|
||||
* as published by the Free Software Foundation version 2
|
||||
* 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU 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 General Public License version 2 (GPLv2)
|
||||
* @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
|
||||
135
include/libdvbv5/desc_isdbt_delivery.h
Normal file
135
include/libdvbv5/desc_isdbt_delivery.h
Normal file
@@ -0,0 +1,135 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2014 - Mauro Carvalho Chehab <m.chehab@samsung.com>
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* 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 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 General Public License version 2 (GPLv2)
|
||||
* @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
|
||||
104
include/libdvbv5/desc_language.h
Normal file
104
include/libdvbv5/desc_language.h
Normal file
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* 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 General Public License
|
||||
* as published by the Free Software Foundation version 2
|
||||
* 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU 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 General Public License version 2 (GPLv2)
|
||||
* @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
|
||||
133
include/libdvbv5/desc_logical_channel.h
Normal file
133
include/libdvbv5/desc_logical_channel.h
Normal file
@@ -0,0 +1,133 @@
|
||||
/*
|
||||
* Copyright (c) 2013 - Mauro Carvalho Chehab <m.chehab@samsung.com>
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* 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 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 General Public License version 2 (GPLv2)
|
||||
* @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
|
||||
113
include/libdvbv5/desc_network_name.h
Normal file
113
include/libdvbv5/desc_network_name.h
Normal file
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
* 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 General Public License
|
||||
* as published by the Free Software Foundation version 2
|
||||
* 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU 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 General Public License version 2 (GPLv2)
|
||||
* @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
|
||||
126
include/libdvbv5/desc_partial_reception.h
Normal file
126
include/libdvbv5/desc_partial_reception.h
Normal file
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
* Copyright (c) 2013 - Mauro Carvalho Chehab <m.chehab@samsung.com>
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* 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 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 General Public License version 2 (GPLv2)
|
||||
* @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
|
||||
148
include/libdvbv5/desc_sat.h
Normal file
148
include/libdvbv5/desc_sat.h
Normal file
@@ -0,0 +1,148 @@
|
||||
/*
|
||||
* 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 General Public License
|
||||
* as published by the Free Software Foundation version 2
|
||||
* 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU 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 General Public License version 2 (GPLv2)
|
||||
* @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
|
||||
119
include/libdvbv5/desc_service.h
Normal file
119
include/libdvbv5/desc_service.h
Normal file
@@ -0,0 +1,119 @@
|
||||
/*
|
||||
* 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 General Public License
|
||||
* as published by the Free Software Foundation version 2
|
||||
* 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU 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 General Public License version 2 (GPLv2)
|
||||
* @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
|
||||
169
include/libdvbv5/desc_t2_delivery.h
Normal file
169
include/libdvbv5/desc_t2_delivery.h
Normal file
@@ -0,0 +1,169 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2014 - Mauro Carvalho Chehab <m.chehab@samsung.com>
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* 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 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 General Public License version 2 (GPLv2)
|
||||
* @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
|
||||
* @ingroup descriptors
|
||||
* @brief Structure to describe transponder subcell extension and frequencies
|
||||
*
|
||||
* @param cell_id_extension cell id extension
|
||||
* @param transposer_frequency transposer frequency
|
||||
*/
|
||||
struct dvb_desc_t2_delivery_subcell {
|
||||
uint8_t cell_id_extension;
|
||||
uint16_t transposer_frequency;
|
||||
} __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
|
||||
* @param frequency_loop_length size of the dvb_desc_t2_delivery::centre_frequency
|
||||
* vector
|
||||
*
|
||||
* @param subcel_info_loop_length size of the dvb_desc_t2_delivery::subcell
|
||||
* vector
|
||||
* @param subcell pointer to struct dvb_desc_t2_delivery_subcell
|
||||
*/
|
||||
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:3;
|
||||
uint16_t SISO_MISO:2;
|
||||
} __attribute__((packed));
|
||||
} __attribute__((packed));
|
||||
|
||||
uint32_t *centre_frequency;
|
||||
uint8_t frequency_loop_length;
|
||||
uint8_t subcel_info_loop_length;
|
||||
struct dvb_desc_t2_delivery_subcell *subcell;
|
||||
} __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[];
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
161
include/libdvbv5/desc_terrestrial_delivery.h
Normal file
161
include/libdvbv5/desc_terrestrial_delivery.h
Normal file
@@ -0,0 +1,161 @@
|
||||
/*
|
||||
* 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 General Public License
|
||||
* as published by the Free Software Foundation version 2
|
||||
* 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU 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 General Public License version 2 (GPLv2)
|
||||
* @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
|
||||
145
include/libdvbv5/desc_ts_info.h
Normal file
145
include/libdvbv5/desc_ts_info.h
Normal file
@@ -0,0 +1,145 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2014 - Mauro Carvalho Chehab <m.chehab@samsung.com>
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* 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 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 General Public License version 2 (GPLv2)
|
||||
* @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
|
||||
772
include/libdvbv5/descriptors.h
Normal file
772
include/libdvbv5/descriptors.h
Normal file
@@ -0,0 +1,772 @@
|
||||
/*
|
||||
* 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 General Public License
|
||||
* as published by the Free Software Foundation version 2
|
||||
* 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU 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 General Public License version 2 (GPLv2)
|
||||
* @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 ) \
|
||||
for( struct dvb_desc *_desc = _tbl->descriptor; _desc; _desc = _desc->next ) \
|
||||
|
||||
#define dvb_desc_find(_struct, _desc, _tbl, _type) \
|
||||
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_descriptior
|
||||
* @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_descriptior = 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,
|
||||
};
|
||||
|
||||
/* Please see desc_extension.h for extension_descriptor types */
|
||||
|
||||
#endif
|
||||
142
include/libdvbv5/dvb-demux.h
Normal file
142
include/libdvbv5/dvb-demux.h
Normal file
@@ -0,0 +1,142 @@
|
||||
/*
|
||||
* 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 General Public License
|
||||
* as published by the Free Software Foundation version 2
|
||||
* 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 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 General Public License version 2 (GPLv2)
|
||||
* @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.
|
||||
*/
|
||||
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 open.
|
||||
*/
|
||||
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 open.
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
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.
|
||||
*
|
||||
* @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 This function currently assumes that the PAT fits into one session.
|
||||
*
|
||||
* @return At return, it returns a negative value if error or the PID associated with
|
||||
* the desired Session ID.
|
||||
*/
|
||||
int dvb_get_pmt_pid(int dmxfd, int sid);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
771
include/libdvbv5/dvb-fe.h
Normal file
771
include/libdvbv5/dvb-fe.h
Normal file
@@ -0,0 +1,771 @@
|
||||
/*
|
||||
* 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 General Public License
|
||||
* as published by the Free Software Foundation version 2
|
||||
* 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU 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 General Public License version 2 (GPLv2)
|
||||
* @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[71];
|
||||
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
|
||||
514
include/libdvbv5/dvb-file.h
Normal file
514
include/libdvbv5/dvb-file.h
Normal file
@@ -0,0 +1,514 @@
|
||||
/*
|
||||
* 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 General Public License
|
||||
* as published by the Free Software Foundation version 2
|
||||
* 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 General Public License for more details.
|
||||
*/
|
||||
#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 General Public License version 2 (GPLv2)
|
||||
* @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;
|
||||
};
|
||||
|
||||
/**
|
||||
* @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
|
||||
592
include/libdvbv5/dvb-frontend.h
Normal file
592
include/libdvbv5/dvb-frontend.h
Normal file
@@ -0,0 +1,592 @@
|
||||
/*
|
||||
* frontend.h
|
||||
*
|
||||
* Copyright (C) 2000 Marcus Metzler <marcus@convergence.de>
|
||||
* Ralph Metzler <ralph@convergence.de>
|
||||
* Holger Waechtler <holger@convergence.de>
|
||||
* Andre Draszik <ad@convergence.de>
|
||||
* for convergence integrated media GmbH
|
||||
*
|
||||
* This program 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 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _DVBFRONTEND_H_
|
||||
#define _DVBFRONTEND_H_
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
typedef enum fe_type {
|
||||
FE_QPSK,
|
||||
FE_QAM,
|
||||
FE_OFDM,
|
||||
FE_ATSC
|
||||
} fe_type_t;
|
||||
|
||||
|
||||
typedef enum fe_caps {
|
||||
FE_IS_STUPID = 0,
|
||||
FE_CAN_INVERSION_AUTO = 0x1,
|
||||
FE_CAN_FEC_1_2 = 0x2,
|
||||
FE_CAN_FEC_2_3 = 0x4,
|
||||
FE_CAN_FEC_3_4 = 0x8,
|
||||
FE_CAN_FEC_4_5 = 0x10,
|
||||
FE_CAN_FEC_5_6 = 0x20,
|
||||
FE_CAN_FEC_6_7 = 0x40,
|
||||
FE_CAN_FEC_7_8 = 0x80,
|
||||
FE_CAN_FEC_8_9 = 0x100,
|
||||
FE_CAN_FEC_AUTO = 0x200,
|
||||
FE_CAN_QPSK = 0x400,
|
||||
FE_CAN_QAM_16 = 0x800,
|
||||
FE_CAN_QAM_32 = 0x1000,
|
||||
FE_CAN_QAM_64 = 0x2000,
|
||||
FE_CAN_QAM_128 = 0x4000,
|
||||
FE_CAN_QAM_256 = 0x8000,
|
||||
FE_CAN_QAM_AUTO = 0x10000,
|
||||
FE_CAN_TRANSMISSION_MODE_AUTO = 0x20000,
|
||||
FE_CAN_BANDWIDTH_AUTO = 0x40000,
|
||||
FE_CAN_GUARD_INTERVAL_AUTO = 0x80000,
|
||||
FE_CAN_HIERARCHY_AUTO = 0x100000,
|
||||
FE_CAN_8VSB = 0x200000,
|
||||
FE_CAN_16VSB = 0x400000,
|
||||
FE_HAS_EXTENDED_CAPS = 0x800000, /* We need more bitspace for newer APIs, indicate this. */
|
||||
FE_CAN_MULTISTREAM = 0x4000000, /* frontend supports multistream filtering */
|
||||
FE_CAN_TURBO_FEC = 0x8000000, /* frontend supports "turbo fec modulation" */
|
||||
FE_CAN_2G_MODULATION = 0x10000000, /* frontend supports "2nd generation modulation" (DVB-S2) */
|
||||
FE_NEEDS_BENDING = 0x20000000, /* not supported anymore, don't use (frontend requires frequency bending) */
|
||||
FE_CAN_RECOVER = 0x40000000, /* frontend can recover from a cable unplug automatically */
|
||||
FE_CAN_MUTE_TS = 0x80000000 /* frontend can stop spurious TS data output */
|
||||
} fe_caps_t;
|
||||
|
||||
|
||||
struct dvb_frontend_info {
|
||||
char name[128];
|
||||
fe_type_t type; /* DEPRECATED. Use DTV_ENUM_DELSYS instead */
|
||||
__u32 frequency_min;
|
||||
__u32 frequency_max;
|
||||
__u32 frequency_stepsize;
|
||||
__u32 frequency_tolerance;
|
||||
__u32 symbol_rate_min;
|
||||
__u32 symbol_rate_max;
|
||||
__u32 symbol_rate_tolerance; /* ppm */
|
||||
__u32 notifier_delay; /* DEPRECATED */
|
||||
fe_caps_t caps;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Check out the DiSEqC bus spec available on http://www.eutelsat.org/ for
|
||||
* the meaning of this struct...
|
||||
*/
|
||||
struct dvb_diseqc_master_cmd {
|
||||
__u8 msg [6]; /* { framing, address, command, data [3] } */
|
||||
__u8 msg_len; /* valid values are 3...6 */
|
||||
};
|
||||
|
||||
|
||||
struct dvb_diseqc_slave_reply {
|
||||
__u8 msg [4]; /* { framing, data [3] } */
|
||||
__u8 msg_len; /* valid values are 0...4, 0 means no msg */
|
||||
int timeout; /* return from ioctl after timeout ms with */
|
||||
}; /* errorcode when no message was received */
|
||||
|
||||
|
||||
typedef enum fe_sec_voltage {
|
||||
SEC_VOLTAGE_13,
|
||||
SEC_VOLTAGE_18,
|
||||
SEC_VOLTAGE_OFF
|
||||
} fe_sec_voltage_t;
|
||||
|
||||
|
||||
typedef enum fe_sec_tone_mode {
|
||||
SEC_TONE_ON,
|
||||
SEC_TONE_OFF
|
||||
} fe_sec_tone_mode_t;
|
||||
|
||||
|
||||
typedef enum fe_sec_mini_cmd {
|
||||
SEC_MINI_A,
|
||||
SEC_MINI_B
|
||||
} fe_sec_mini_cmd_t;
|
||||
|
||||
|
||||
/**
|
||||
* enum fe_status - enumerates the possible frontend status
|
||||
* @FE_HAS_SIGNAL: found something above the noise level
|
||||
* @FE_HAS_CARRIER: found a DVB signal
|
||||
* @FE_HAS_VITERBI: FEC is stable
|
||||
* @FE_HAS_SYNC: found sync bytes
|
||||
* @FE_HAS_LOCK: everything's working
|
||||
* @FE_TIMEDOUT: no lock within the last ~2 seconds
|
||||
* @FE_REINIT: frontend was reinitialized, application is recommended
|
||||
* to reset DiSEqC, tone and parameters
|
||||
*/
|
||||
|
||||
typedef enum fe_status {
|
||||
FE_HAS_SIGNAL = 0x01,
|
||||
FE_HAS_CARRIER = 0x02,
|
||||
FE_HAS_VITERBI = 0x04,
|
||||
FE_HAS_SYNC = 0x08,
|
||||
FE_HAS_LOCK = 0x10,
|
||||
FE_TIMEDOUT = 0x20,
|
||||
FE_REINIT = 0x40,
|
||||
} fe_status_t;
|
||||
|
||||
typedef enum fe_spectral_inversion {
|
||||
INVERSION_OFF,
|
||||
INVERSION_ON,
|
||||
INVERSION_AUTO
|
||||
} fe_spectral_inversion_t;
|
||||
|
||||
|
||||
typedef enum fe_code_rate {
|
||||
FEC_NONE = 0,
|
||||
FEC_1_2,
|
||||
FEC_2_3,
|
||||
FEC_3_4,
|
||||
FEC_4_5,
|
||||
FEC_5_6,
|
||||
FEC_6_7,
|
||||
FEC_7_8,
|
||||
FEC_8_9,
|
||||
FEC_AUTO,
|
||||
FEC_3_5,
|
||||
FEC_9_10,
|
||||
FEC_2_5,
|
||||
} fe_code_rate_t;
|
||||
|
||||
|
||||
typedef enum fe_modulation {
|
||||
QPSK,
|
||||
QAM_16,
|
||||
QAM_32,
|
||||
QAM_64,
|
||||
QAM_128,
|
||||
QAM_256,
|
||||
QAM_AUTO,
|
||||
VSB_8,
|
||||
VSB_16,
|
||||
PSK_8,
|
||||
APSK_16,
|
||||
APSK_32,
|
||||
DQPSK,
|
||||
QAM_4_NR,
|
||||
} fe_modulation_t;
|
||||
|
||||
typedef enum fe_transmit_mode {
|
||||
TRANSMISSION_MODE_2K,
|
||||
TRANSMISSION_MODE_8K,
|
||||
TRANSMISSION_MODE_AUTO,
|
||||
TRANSMISSION_MODE_4K,
|
||||
TRANSMISSION_MODE_1K,
|
||||
TRANSMISSION_MODE_16K,
|
||||
TRANSMISSION_MODE_32K,
|
||||
TRANSMISSION_MODE_C1,
|
||||
TRANSMISSION_MODE_C3780,
|
||||
} fe_transmit_mode_t;
|
||||
|
||||
#if defined(__DVB_CORE__) || !defined (__KERNEL__)
|
||||
typedef enum fe_bandwidth {
|
||||
BANDWIDTH_8_MHZ,
|
||||
BANDWIDTH_7_MHZ,
|
||||
BANDWIDTH_6_MHZ,
|
||||
BANDWIDTH_AUTO,
|
||||
BANDWIDTH_5_MHZ,
|
||||
BANDWIDTH_10_MHZ,
|
||||
BANDWIDTH_1_712_MHZ,
|
||||
} fe_bandwidth_t;
|
||||
#endif
|
||||
|
||||
typedef enum fe_guard_interval {
|
||||
GUARD_INTERVAL_1_32,
|
||||
GUARD_INTERVAL_1_16,
|
||||
GUARD_INTERVAL_1_8,
|
||||
GUARD_INTERVAL_1_4,
|
||||
GUARD_INTERVAL_AUTO,
|
||||
GUARD_INTERVAL_1_128,
|
||||
GUARD_INTERVAL_19_128,
|
||||
GUARD_INTERVAL_19_256,
|
||||
GUARD_INTERVAL_PN420,
|
||||
GUARD_INTERVAL_PN595,
|
||||
GUARD_INTERVAL_PN945,
|
||||
} fe_guard_interval_t;
|
||||
|
||||
|
||||
typedef enum fe_hierarchy {
|
||||
HIERARCHY_NONE,
|
||||
HIERARCHY_1,
|
||||
HIERARCHY_2,
|
||||
HIERARCHY_4,
|
||||
HIERARCHY_AUTO
|
||||
} fe_hierarchy_t;
|
||||
|
||||
enum fe_interleaving {
|
||||
INTERLEAVING_NONE,
|
||||
INTERLEAVING_AUTO,
|
||||
INTERLEAVING_240,
|
||||
INTERLEAVING_720,
|
||||
};
|
||||
|
||||
#if defined(__DVB_CORE__) || !defined (__KERNEL__)
|
||||
struct dvb_qpsk_parameters {
|
||||
__u32 symbol_rate; /* symbol rate in Symbols per second */
|
||||
fe_code_rate_t fec_inner; /* forward error correction (see above) */
|
||||
};
|
||||
|
||||
struct dvb_qam_parameters {
|
||||
__u32 symbol_rate; /* symbol rate in Symbols per second */
|
||||
fe_code_rate_t fec_inner; /* forward error correction (see above) */
|
||||
fe_modulation_t modulation; /* modulation type (see above) */
|
||||
};
|
||||
|
||||
struct dvb_vsb_parameters {
|
||||
fe_modulation_t modulation; /* modulation type (see above) */
|
||||
};
|
||||
|
||||
struct dvb_ofdm_parameters {
|
||||
fe_bandwidth_t bandwidth;
|
||||
fe_code_rate_t code_rate_HP; /* high priority stream code rate */
|
||||
fe_code_rate_t code_rate_LP; /* low priority stream code rate */
|
||||
fe_modulation_t constellation; /* modulation type (see above) */
|
||||
fe_transmit_mode_t transmission_mode;
|
||||
fe_guard_interval_t guard_interval;
|
||||
fe_hierarchy_t hierarchy_information;
|
||||
};
|
||||
|
||||
|
||||
struct dvb_frontend_parameters {
|
||||
__u32 frequency; /* (absolute) frequency in Hz for QAM/OFDM/ATSC */
|
||||
/* intermediate frequency in kHz for QPSK */
|
||||
fe_spectral_inversion_t inversion;
|
||||
union {
|
||||
struct dvb_qpsk_parameters qpsk;
|
||||
struct dvb_qam_parameters qam;
|
||||
struct dvb_ofdm_parameters ofdm;
|
||||
struct dvb_vsb_parameters vsb;
|
||||
} u;
|
||||
};
|
||||
|
||||
struct dvb_frontend_event {
|
||||
fe_status_t status;
|
||||
struct dvb_frontend_parameters parameters;
|
||||
};
|
||||
#endif
|
||||
|
||||
/* S2API Commands */
|
||||
#define DTV_UNDEFINED 0
|
||||
#define DTV_TUNE 1
|
||||
#define DTV_CLEAR 2
|
||||
#define DTV_FREQUENCY 3
|
||||
#define DTV_MODULATION 4
|
||||
#define DTV_BANDWIDTH_HZ 5
|
||||
#define DTV_INVERSION 6
|
||||
#define DTV_DISEQC_MASTER 7
|
||||
#define DTV_SYMBOL_RATE 8
|
||||
#define DTV_INNER_FEC 9
|
||||
#define DTV_VOLTAGE 10
|
||||
#define DTV_TONE 11
|
||||
#define DTV_PILOT 12
|
||||
#define DTV_ROLLOFF 13
|
||||
#define DTV_DISEQC_SLAVE_REPLY 14
|
||||
|
||||
/* Basic enumeration set for querying unlimited capabilities */
|
||||
#define DTV_FE_CAPABILITY_COUNT 15
|
||||
#define DTV_FE_CAPABILITY 16
|
||||
#define DTV_DELIVERY_SYSTEM 17
|
||||
|
||||
/* ISDB-T and ISDB-Tsb */
|
||||
#define DTV_ISDBT_PARTIAL_RECEPTION 18
|
||||
#define DTV_ISDBT_SOUND_BROADCASTING 19
|
||||
|
||||
#define DTV_ISDBT_SB_SUBCHANNEL_ID 20
|
||||
#define DTV_ISDBT_SB_SEGMENT_IDX 21
|
||||
#define DTV_ISDBT_SB_SEGMENT_COUNT 22
|
||||
|
||||
#define DTV_ISDBT_LAYERA_FEC 23
|
||||
#define DTV_ISDBT_LAYERA_MODULATION 24
|
||||
#define DTV_ISDBT_LAYERA_SEGMENT_COUNT 25
|
||||
#define DTV_ISDBT_LAYERA_TIME_INTERLEAVING 26
|
||||
|
||||
#define DTV_ISDBT_LAYERB_FEC 27
|
||||
#define DTV_ISDBT_LAYERB_MODULATION 28
|
||||
#define DTV_ISDBT_LAYERB_SEGMENT_COUNT 29
|
||||
#define DTV_ISDBT_LAYERB_TIME_INTERLEAVING 30
|
||||
|
||||
#define DTV_ISDBT_LAYERC_FEC 31
|
||||
#define DTV_ISDBT_LAYERC_MODULATION 32
|
||||
#define DTV_ISDBT_LAYERC_SEGMENT_COUNT 33
|
||||
#define DTV_ISDBT_LAYERC_TIME_INTERLEAVING 34
|
||||
|
||||
#define DTV_API_VERSION 35
|
||||
|
||||
#define DTV_CODE_RATE_HP 36
|
||||
#define DTV_CODE_RATE_LP 37
|
||||
#define DTV_GUARD_INTERVAL 38
|
||||
#define DTV_TRANSMISSION_MODE 39
|
||||
#define DTV_HIERARCHY 40
|
||||
|
||||
#define DTV_ISDBT_LAYER_ENABLED 41
|
||||
|
||||
#define DTV_STREAM_ID 42
|
||||
#define DTV_ISDBS_TS_ID_LEGACY DTV_STREAM_ID
|
||||
#define DTV_DVBT2_PLP_ID_LEGACY 43
|
||||
|
||||
#define DTV_ENUM_DELSYS 44
|
||||
|
||||
/* ATSC-MH */
|
||||
#define DTV_ATSCMH_FIC_VER 45
|
||||
#define DTV_ATSCMH_PARADE_ID 46
|
||||
#define DTV_ATSCMH_NOG 47
|
||||
#define DTV_ATSCMH_TNOG 48
|
||||
#define DTV_ATSCMH_SGN 49
|
||||
#define DTV_ATSCMH_PRC 50
|
||||
#define DTV_ATSCMH_RS_FRAME_MODE 51
|
||||
#define DTV_ATSCMH_RS_FRAME_ENSEMBLE 52
|
||||
#define DTV_ATSCMH_RS_CODE_MODE_PRI 53
|
||||
#define DTV_ATSCMH_RS_CODE_MODE_SEC 54
|
||||
#define DTV_ATSCMH_SCCC_BLOCK_MODE 55
|
||||
#define DTV_ATSCMH_SCCC_CODE_MODE_A 56
|
||||
#define DTV_ATSCMH_SCCC_CODE_MODE_B 57
|
||||
#define DTV_ATSCMH_SCCC_CODE_MODE_C 58
|
||||
#define DTV_ATSCMH_SCCC_CODE_MODE_D 59
|
||||
|
||||
#define DTV_INTERLEAVING 60
|
||||
#define DTV_LNA 61
|
||||
|
||||
/* Quality parameters */
|
||||
#define DTV_STAT_SIGNAL_STRENGTH 62
|
||||
#define DTV_STAT_CNR 63
|
||||
#define DTV_STAT_PRE_ERROR_BIT_COUNT 64
|
||||
#define DTV_STAT_PRE_TOTAL_BIT_COUNT 65
|
||||
#define DTV_STAT_POST_ERROR_BIT_COUNT 66
|
||||
#define DTV_STAT_POST_TOTAL_BIT_COUNT 67
|
||||
#define DTV_STAT_ERROR_BLOCK_COUNT 68
|
||||
#define DTV_STAT_TOTAL_BLOCK_COUNT 69
|
||||
|
||||
#define DTV_MAX_COMMAND DTV_STAT_TOTAL_BLOCK_COUNT
|
||||
|
||||
typedef enum fe_pilot {
|
||||
PILOT_ON,
|
||||
PILOT_OFF,
|
||||
PILOT_AUTO,
|
||||
} fe_pilot_t;
|
||||
|
||||
typedef enum fe_rolloff {
|
||||
ROLLOFF_35, /* Implied value in DVB-S, default for DVB-S2 */
|
||||
ROLLOFF_20,
|
||||
ROLLOFF_25,
|
||||
ROLLOFF_AUTO,
|
||||
} fe_rolloff_t;
|
||||
|
||||
typedef enum fe_delivery_system {
|
||||
SYS_UNDEFINED,
|
||||
SYS_DVBC_ANNEX_A,
|
||||
SYS_DVBC_ANNEX_B,
|
||||
SYS_DVBT,
|
||||
SYS_DSS,
|
||||
SYS_DVBS,
|
||||
SYS_DVBS2,
|
||||
SYS_DVBH,
|
||||
SYS_ISDBT,
|
||||
SYS_ISDBS,
|
||||
SYS_ISDBC,
|
||||
SYS_ATSC,
|
||||
SYS_ATSCMH,
|
||||
SYS_DTMB,
|
||||
SYS_CMMB,
|
||||
SYS_DAB,
|
||||
SYS_DVBT2,
|
||||
SYS_TURBO,
|
||||
SYS_DVBC_ANNEX_C,
|
||||
} fe_delivery_system_t;
|
||||
|
||||
/* backward compatibility */
|
||||
#define SYS_DVBC_ANNEX_AC SYS_DVBC_ANNEX_A
|
||||
#define SYS_DMBTH SYS_DTMB /* DMB-TH is legacy name, use DTMB instead */
|
||||
|
||||
/* ATSC-MH */
|
||||
|
||||
enum atscmh_sccc_block_mode {
|
||||
ATSCMH_SCCC_BLK_SEP = 0,
|
||||
ATSCMH_SCCC_BLK_COMB = 1,
|
||||
ATSCMH_SCCC_BLK_RES = 2,
|
||||
};
|
||||
|
||||
enum atscmh_sccc_code_mode {
|
||||
ATSCMH_SCCC_CODE_HLF = 0,
|
||||
ATSCMH_SCCC_CODE_QTR = 1,
|
||||
ATSCMH_SCCC_CODE_RES = 2,
|
||||
};
|
||||
|
||||
enum atscmh_rs_frame_ensemble {
|
||||
ATSCMH_RSFRAME_ENS_PRI = 0,
|
||||
ATSCMH_RSFRAME_ENS_SEC = 1,
|
||||
};
|
||||
|
||||
enum atscmh_rs_frame_mode {
|
||||
ATSCMH_RSFRAME_PRI_ONLY = 0,
|
||||
ATSCMH_RSFRAME_PRI_SEC = 1,
|
||||
ATSCMH_RSFRAME_RES = 2,
|
||||
};
|
||||
|
||||
enum atscmh_rs_code_mode {
|
||||
ATSCMH_RSCODE_211_187 = 0,
|
||||
ATSCMH_RSCODE_223_187 = 1,
|
||||
ATSCMH_RSCODE_235_187 = 2,
|
||||
ATSCMH_RSCODE_RES = 3,
|
||||
};
|
||||
|
||||
#define NO_STREAM_ID_FILTER (~0U)
|
||||
#define LNA_AUTO (~0U)
|
||||
|
||||
struct dtv_cmds_h {
|
||||
char *name; /* A display name for debugging purposes */
|
||||
|
||||
__u32 cmd; /* A unique ID */
|
||||
|
||||
/* Flags */
|
||||
__u32 set:1; /* Either a set or get property */
|
||||
__u32 buffer:1; /* Does this property use the buffer? */
|
||||
__u32 reserved:30; /* Align */
|
||||
};
|
||||
|
||||
/**
|
||||
* Scale types for the quality parameters.
|
||||
* @FE_SCALE_NOT_AVAILABLE: That QoS measure is not available. That
|
||||
* could indicate a temporary or a permanent
|
||||
* condition.
|
||||
* @FE_SCALE_DECIBEL: The scale is measured in 0.0001 dB steps, typically
|
||||
* used on signal measures.
|
||||
* @FE_SCALE_RELATIVE: The scale is a relative percentual measure,
|
||||
* ranging from 0 (0%) to 0xffff (100%).
|
||||
* @FE_SCALE_COUNTER: The scale counts the occurrence of an event, like
|
||||
* bit error, block error, lapsed time.
|
||||
*/
|
||||
enum fecap_scale_params {
|
||||
FE_SCALE_NOT_AVAILABLE = 0,
|
||||
FE_SCALE_DECIBEL,
|
||||
FE_SCALE_RELATIVE,
|
||||
FE_SCALE_COUNTER
|
||||
};
|
||||
|
||||
/**
|
||||
* struct dtv_stats - Used for reading a DTV status property
|
||||
*
|
||||
* @value: value of the measure. Should range from 0 to 0xffff;
|
||||
* @scale: Filled with enum fecap_scale_params - the scale
|
||||
* in usage for that parameter
|
||||
*
|
||||
* For most delivery systems, this will return a single value for each
|
||||
* parameter.
|
||||
* It should be noticed, however, that new OFDM delivery systems like
|
||||
* ISDB can use different modulation types for each group of carriers.
|
||||
* On such standards, up to 8 groups of statistics can be provided, one
|
||||
* for each carrier group (called "layer" on ISDB).
|
||||
* In order to be consistent with other delivery systems, the first
|
||||
* value refers to the entire set of carriers ("global").
|
||||
* dtv_status:scale should use the value FE_SCALE_NOT_AVAILABLE when
|
||||
* the value for the entire group of carriers or from one specific layer
|
||||
* is not provided by the hardware.
|
||||
* st.len should be filled with the latest filled status + 1.
|
||||
*
|
||||
* In other words, for ISDB, those values should be filled like:
|
||||
* u.st.stat.svalue[0] = global statistics;
|
||||
* u.st.stat.scale[0] = FE_SCALE_DECIBELS;
|
||||
* u.st.stat.value[1] = layer A statistics;
|
||||
* u.st.stat.scale[1] = FE_SCALE_NOT_AVAILABLE (if not available);
|
||||
* u.st.stat.svalue[2] = layer B statistics;
|
||||
* u.st.stat.scale[2] = FE_SCALE_DECIBELS;
|
||||
* u.st.stat.svalue[3] = layer C statistics;
|
||||
* u.st.stat.scale[3] = FE_SCALE_DECIBELS;
|
||||
* u.st.len = 4;
|
||||
*/
|
||||
struct dtv_stats {
|
||||
__u8 scale; /* enum fecap_scale_params type */
|
||||
union {
|
||||
__u64 uvalue; /* for counters and relative scales */
|
||||
__s64 svalue; /* for 0.0001 dB measures */
|
||||
};
|
||||
} __attribute__ ((packed));
|
||||
|
||||
|
||||
#define MAX_DTV_STATS 4
|
||||
|
||||
struct dtv_fe_stats {
|
||||
__u8 len;
|
||||
struct dtv_stats stat[MAX_DTV_STATS];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct dtv_property {
|
||||
__u32 cmd;
|
||||
__u32 reserved[3];
|
||||
union {
|
||||
__u32 data;
|
||||
struct dtv_fe_stats st;
|
||||
struct {
|
||||
__u8 data[32];
|
||||
__u32 len;
|
||||
__u32 reserved1[3];
|
||||
void *reserved2;
|
||||
} buffer;
|
||||
} u;
|
||||
int result;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* num of properties cannot exceed DTV_IOCTL_MAX_MSGS per ioctl */
|
||||
#define DTV_IOCTL_MAX_MSGS 64
|
||||
|
||||
struct dtv_properties {
|
||||
__u32 num;
|
||||
struct dtv_property *props;
|
||||
};
|
||||
|
||||
#define FE_SET_PROPERTY _IOW('o', 82, struct dtv_properties)
|
||||
#define FE_GET_PROPERTY _IOR('o', 83, struct dtv_properties)
|
||||
|
||||
|
||||
/**
|
||||
* When set, this flag will disable any zigzagging or other "normal" tuning
|
||||
* behaviour. Additionally, there will be no automatic monitoring of the lock
|
||||
* status, and hence no frontend events will be generated. If a frontend device
|
||||
* is closed, this flag will be automatically turned off when the device is
|
||||
* reopened read-write.
|
||||
*/
|
||||
#define FE_TUNE_MODE_ONESHOT 0x01
|
||||
|
||||
|
||||
#define FE_GET_INFO _IOR('o', 61, struct dvb_frontend_info)
|
||||
|
||||
#define FE_DISEQC_RESET_OVERLOAD _IO('o', 62)
|
||||
#define FE_DISEQC_SEND_MASTER_CMD _IOW('o', 63, struct dvb_diseqc_master_cmd)
|
||||
#define FE_DISEQC_RECV_SLAVE_REPLY _IOR('o', 64, struct dvb_diseqc_slave_reply)
|
||||
#define FE_DISEQC_SEND_BURST _IO('o', 65) /* fe_sec_mini_cmd_t */
|
||||
|
||||
#define FE_SET_TONE _IO('o', 66) /* fe_sec_tone_mode_t */
|
||||
#define FE_SET_VOLTAGE _IO('o', 67) /* fe_sec_voltage_t */
|
||||
#define FE_ENABLE_HIGH_LNB_VOLTAGE _IO('o', 68) /* int */
|
||||
|
||||
#define FE_READ_STATUS _IOR('o', 69, fe_status_t)
|
||||
#define FE_READ_BER _IOR('o', 70, __u32)
|
||||
#define FE_READ_SIGNAL_STRENGTH _IOR('o', 71, __u16)
|
||||
#define FE_READ_SNR _IOR('o', 72, __u16)
|
||||
#define FE_READ_UNCORRECTED_BLOCKS _IOR('o', 73, __u32)
|
||||
|
||||
#define FE_SET_FRONTEND _IOW('o', 76, struct dvb_frontend_parameters)
|
||||
#define FE_GET_FRONTEND _IOR('o', 77, struct dvb_frontend_parameters)
|
||||
#define FE_SET_FRONTEND_TUNE_MODE _IO('o', 81) /* unsigned int */
|
||||
#define FE_GET_EVENT _IOR('o', 78, struct dvb_frontend_event)
|
||||
|
||||
#define FE_DISHNETWORK_SEND_LEGACY_CMD _IO('o', 80) /* unsigned int */
|
||||
|
||||
#endif /*_DVBFRONTEND_H_*/
|
||||
111
include/libdvbv5/dvb-log.h
Normal file
111
include/libdvbv5/dvb-log.h
Normal file
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
* 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 General Public License
|
||||
* as published by the Free Software Foundation version 2
|
||||
* 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU 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 General Public License version 2 (GPLv2)
|
||||
* @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 )));
|
||||
|
||||
/*
|
||||
* Macros used internally inside libdvbv5 frontend part, to output logs
|
||||
*/
|
||||
|
||||
#ifndef _DOXYGEN
|
||||
|
||||
#ifndef __DVB_FE_PRIV_H
|
||||
|
||||
#define dvb_log(fmt, arg...) do {\
|
||||
parms->logfunc(LOG_INFO, fmt, ##arg); \
|
||||
} while (0)
|
||||
#define dvb_logerr(fmt, arg...) do {\
|
||||
parms->logfunc(LOG_ERR, fmt, ##arg); \
|
||||
} while (0)
|
||||
#define dvb_logdbg(fmt, arg...) do {\
|
||||
parms->logfunc(LOG_DEBUG, fmt, ##arg); \
|
||||
} while (0)
|
||||
#define dvb_logwarn(fmt, arg...) do {\
|
||||
parms->logfunc(LOG_WARNING, fmt, ##arg); \
|
||||
} while (0)
|
||||
#define dvb_loginfo(fmt, arg...) do {\
|
||||
parms->logfunc(LOG_NOTICE, fmt, ##arg); \
|
||||
} while (0)
|
||||
|
||||
#define dvb_perror(msg) do {\
|
||||
parms->logfunc(LOG_ERR, "%s: %s", msg, strerror(errno)); \
|
||||
} while (0)
|
||||
|
||||
#else
|
||||
|
||||
#define dvb_log(fmt, arg...) do {\
|
||||
parms->p.logfunc(LOG_INFO, fmt, ##arg); \
|
||||
} while (0)
|
||||
#define dvb_logerr(fmt, arg...) do {\
|
||||
parms->p.logfunc(LOG_ERR, fmt, ##arg); \
|
||||
} while (0)
|
||||
#define dvb_logdbg(fmt, arg...) do {\
|
||||
parms->p.logfunc(LOG_DEBUG, fmt, ##arg); \
|
||||
} while (0)
|
||||
#define dvb_logwarn(fmt, arg...) do {\
|
||||
parms->p.logfunc(LOG_WARNING, fmt, ##arg); \
|
||||
} while (0)
|
||||
#define dvb_loginfo(fmt, arg...) do {\
|
||||
parms->p.logfunc(LOG_NOTICE, fmt, ##arg); \
|
||||
} while (0)
|
||||
|
||||
#define dvb_perror(msg) do {\
|
||||
parms->p.logfunc(LOG_ERR, "%s: %s", msg, strerror(errno)); \
|
||||
} while (0)
|
||||
|
||||
#endif
|
||||
|
||||
#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
|
||||
151
include/libdvbv5/dvb-sat.h
Normal file
151
include/libdvbv5/dvb-sat.h
Normal file
@@ -0,0 +1,151 @@
|
||||
/*
|
||||
* 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 General Public License
|
||||
* as published by the Free Software Foundation version 2
|
||||
* 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU 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 General Public License version 2 (GPLv2)
|
||||
* @author Mauro Carvalho Chehab
|
||||
*
|
||||
* @par Bug Report
|
||||
* Please submit bug reports and patches to linux-media@vger.kernel.org
|
||||
*/
|
||||
|
||||
/*
|
||||
* Satellite handling functions
|
||||
*/
|
||||
|
||||
/**
|
||||
* @struct dvbsat_freqrange
|
||||
* @brief Defines a frequency range used by Satellite
|
||||
* @ingroup satellite
|
||||
*
|
||||
* @param low low frequency, in kHz
|
||||
* @param high high frequency, in kHz
|
||||
*/
|
||||
struct dvbsat_freqrange {
|
||||
unsigned low, high;
|
||||
};
|
||||
|
||||
/**
|
||||
* @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
|
||||
* @param lowfreq Low frequency Intermediate Frequency of the LNBf, in kHz
|
||||
* @param highfreq High frequency Intermediate frequency of the LNBf,
|
||||
* in kHz
|
||||
* @param rangeswitch For LNBf that has multiple frequency ranges controlled
|
||||
* by a voltage change, specify the start frequency where
|
||||
* the second range will be applied.
|
||||
* @param freqrange Contains the range(s) of frequencies supported by a
|
||||
* given LNBf.
|
||||
*
|
||||
* 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;
|
||||
unsigned lowfreq, highfreq;
|
||||
|
||||
unsigned rangeswitch;
|
||||
|
||||
struct dvbsat_freqrange 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.
|
||||
*/
|
||||
const struct dvb_sat_lnb *dvb_sat_get_lnb(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);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // _LIBSAT_H
|
||||
419
include/libdvbv5/dvb-scan.h
Normal file
419
include/libdvbv5/dvb-scan.h
Normal file
@@ -0,0 +1,419 @@
|
||||
/*
|
||||
* 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 General Public License
|
||||
* as published by the Free Software Foundation version 2
|
||||
* 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU 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 General Public License version 2 (GPLv2)
|
||||
* @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
|
||||
* @param vct VCT table descriptor pointer
|
||||
* @param program PAT/PMT array associated programs found at MPEG-TS
|
||||
* @param nit NIT table descriptor pointer
|
||||
* @param sdt SDT table descriptor pointer
|
||||
* @param num_program Number of program entries at program array.
|
||||
*
|
||||
* Those descriptors are filled by the scan routines when the tables are
|
||||
* found. Otherwise, they're NULL.
|
||||
*/
|
||||
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_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
|
||||
268
include/libdvbv5/dvb-v5-std.h
Normal file
268
include/libdvbv5/dvb-v5-std.h
Normal file
@@ -0,0 +1,268 @@
|
||||
/*
|
||||
* 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 General Public License
|
||||
* as published by the Free Software Foundation version 2
|
||||
* 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU 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 General Public License version 2 (GPLv2)
|
||||
* @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
|
||||
224
include/libdvbv5/eit.h
Normal file
224
include/libdvbv5/eit.h
Normal file
@@ -0,0 +1,224 @@
|
||||
/*
|
||||
* 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 General Public License
|
||||
* as published by the Free Software Foundation version 2
|
||||
* 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU 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 General Public License version 2 (GPLv2)
|
||||
* @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
|
||||
* @ingroup dvb_table
|
||||
* @def DVB_TABLE_EIT_SCHEDULE_OTHER
|
||||
* @brief Start table ID for the DVB EIT schedule data on other TS
|
||||
* @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 /* - 0x5F */
|
||||
#define DVB_TABLE_EIT_SCHEDULE_OTHER 0x60 /* - 0x6F */
|
||||
|
||||
/**
|
||||
* @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) \
|
||||
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
|
||||
140
include/libdvbv5/header.h
Normal file
140
include/libdvbv5/header.h
Normal file
@@ -0,0 +1,140 @@
|
||||
/*
|
||||
* 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 General Public License
|
||||
* as published by the Free Software Foundation version 2
|
||||
* 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU 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 General Public License version 2 (GPLv2)
|
||||
* @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;
|
||||
} __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 TS ID
|
||||
* @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
|
||||
187
include/libdvbv5/mgt.h
Normal file
187
include/libdvbv5/mgt.h
Normal 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 General Public License
|
||||
* as published by the Free Software Foundation version 2
|
||||
* 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU 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 General Public License version 2 (GPLv2)
|
||||
* @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 ) \
|
||||
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
|
||||
249
include/libdvbv5/mpeg_es.h
Normal file
249
include/libdvbv5/mpeg_es.h
Normal file
@@ -0,0 +1,249 @@
|
||||
/*
|
||||
* 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 General Public License
|
||||
* as published by the Free Software Foundation version 2
|
||||
* 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU 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 General Public License version 2 (GPLv2)
|
||||
* @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
|
||||
249
include/libdvbv5/mpeg_pes.h
Normal file
249
include/libdvbv5/mpeg_pes.h
Normal file
@@ -0,0 +1,249 @@
|
||||
/*
|
||||
* 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 General Public License
|
||||
* as published by the Free Software Foundation version 2
|
||||
* 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU 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 General Public License version 2 (GPLv2)
|
||||
* @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
|
||||
173
include/libdvbv5/mpeg_ts.h
Normal file
173
include/libdvbv5/mpeg_ts.h
Normal file
@@ -0,0 +1,173 @@
|
||||
/*
|
||||
* 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 General Public License
|
||||
* as published by the Free Software Foundation version 2
|
||||
* 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU 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 General Public License version 2 (GPLv2)
|
||||
* @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
276
include/libdvbv5/nit.h
Normal 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 General Public License
|
||||
* as published by the Free Software Foundation version 2
|
||||
* 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU 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 General Public License version 2 (GPLv2)
|
||||
* @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 ) \
|
||||
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
172
include/libdvbv5/pat.h
Normal 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 General Public License
|
||||
* as published by the Free Software Foundation version 2
|
||||
* 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU 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 General Public License version 2 (GPLv2)
|
||||
* @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) \
|
||||
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
|
||||
289
include/libdvbv5/pmt.h
Normal file
289
include/libdvbv5/pmt.h
Normal file
@@ -0,0 +1,289 @@
|
||||
/*
|
||||
* 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 General Public License
|
||||
* as published by the Free Software Foundation version 2
|
||||
* 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU 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 General Public License version 2 (GPLv2)
|
||||
* @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_reserved0 = 0x00,
|
||||
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_reserved = 0x15,
|
||||
stream_private = 0x80
|
||||
};
|
||||
|
||||
/**
|
||||
* @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) \
|
||||
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
187
include/libdvbv5/sdt.h
Normal 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 General Public License
|
||||
* as published by the Free Software Foundation version 2
|
||||
* 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU 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 General Public License version 2 (GPLv2)
|
||||
* @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) \
|
||||
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
251
include/libdvbv5/vct.h
Normal file
@@ -0,0 +1,251 @@
|
||||
/*
|
||||
* Copyright (c) 2013 - Mauro Carvalho Chehab <m.chehab@samsung.com>
|
||||
* 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 General Public License
|
||||
* as published by the Free Software Foundation version 2
|
||||
* 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU 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 General Public License version 2 (GPLv2)
|
||||
* @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) \
|
||||
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
|
||||
45
include/libv4l-plugin.h
Normal file
45
include/libv4l-plugin.h
Normal file
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* 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, version 2.1,
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* 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
207
include/libv4l1-videodev.h
Normal 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__)
|
||||
#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
|
||||
74
include/libv4l1.h
Normal file
74
include/libv4l1.h
Normal file
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
# (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, version 2.1,
|
||||
# as published by the Free Software Foundation.
|
||||
#
|
||||
# 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
|
||||
115
include/libv4l2.h
Normal file
115
include/libv4l2.h
Normal file
@@ -0,0 +1,115 @@
|
||||
/*
|
||||
# (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, version 2.1,
|
||||
# as published by the Free Software Foundation.
|
||||
#
|
||||
# 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 occured. */
|
||||
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
|
||||
351
include/libv4l2rds.h
Normal file
351
include/libv4l2rds.h
Normal file
@@ -0,0 +1,351 @@
|
||||
/*
|
||||
* Copyright 2012 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
|
||||
* Author: Konke Radlow <koradlow@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, version 2.1,
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* 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 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 __LIBV4L2RDS
|
||||
#define __LIBV4L2RDS
|
||||
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <linux/videodev2.h>
|
||||
|
||||
#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
|
||||
156
include/libv4lconvert.h
Normal file
156
include/libv4lconvert.h
Normal file
@@ -0,0 +1,156 @@
|
||||
/*
|
||||
# (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, version 2.1,
|
||||
# as published by the Free Software Foundation.
|
||||
#
|
||||
# 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__)
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/ioctl.h>
|
||||
#endif
|
||||
|
||||
/* end broken header workaround includes */
|
||||
|
||||
#include <linux/videodev2.h>
|
||||
|
||||
#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
|
||||
61
libv4l2/Makefile
Normal file
61
libv4l2/Makefile
Normal file
@@ -0,0 +1,61 @@
|
||||
###############################################################################
|
||||
#
|
||||
# Copyright (c) 2018-2019, NVIDIA CORPORATION. All rights reserved.
|
||||
#
|
||||
# NVIDIA Corporation and its licensors retain all intellectual property
|
||||
# and proprietary rights in and to this software, related documentation
|
||||
# and any modifications thereto. Any use, reproduction, disclosure or
|
||||
# distribution of this software and related documentation without an express
|
||||
# license agreement from NVIDIA Corporation is strictly prohibited.
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
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/tegra
|
||||
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 tegra/$(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)
|
||||
28
libv4l2/Makefile.am
Normal file
28
libv4l2/Makefile.am
Normal file
@@ -0,0 +1,28 @@
|
||||
if WITH_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 v4l2-plugin.c log.c libv4l2-priv.h
|
||||
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
|
||||
36
libv4l2/Makefile.dGPU
Normal file
36
libv4l2/Makefile.dGPU
Normal file
@@ -0,0 +1,36 @@
|
||||
###############################################################################
|
||||
#
|
||||
# Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved.
|
||||
#
|
||||
# NVIDIA Corporation and its licensors retain all intellectual property
|
||||
# and proprietary rights in and to this software, related documentation
|
||||
# and any modifications thereto. Any use, reproduction, disclosure or
|
||||
# distribution of this software and related documentation without an express
|
||||
# license agreement from NVIDIA Corporation 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
|
||||
118
libv4l2/libv4l2-priv.h
Normal file
118
libv4l2/libv4l2-priv.h
Normal file
@@ -0,0 +1,118 @@
|
||||
/*
|
||||
# (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, version 2.1,
|
||||
# as published by the Free Software Foundation.
|
||||
#
|
||||
# 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 */
|
||||
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);
|
||||
|
||||
/* From log.c */
|
||||
extern const char *v4l2_ioctls[];
|
||||
void v4l2_log_ioctl(unsigned long int request, void *arg, int result);
|
||||
|
||||
#endif
|
||||
1781
libv4l2/libv4l2.c
Normal file
1781
libv4l2/libv4l2.c
Normal file
File diff suppressed because it is too large
Load Diff
13
libv4l2/libv4l2.export
Normal file
13
libv4l2/libv4l2.export
Normal file
@@ -0,0 +1,13 @@
|
||||
# Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved.
|
||||
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
12
libv4l2/libv4l2.pc.in
Normal 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}
|
||||
259
libv4l2/log.c
Normal file
259
libv4l2/log.c
Normal file
@@ -0,0 +1,259 @@
|
||||
/*
|
||||
# (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, version 2.1,
|
||||
# as published by the Free Software Foundation.
|
||||
#
|
||||
# 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"
|
||||
#include <linux/videodev2.h>
|
||||
#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_RESERVED)] = "VIDIOC_RESERVED",
|
||||
[_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);
|
||||
}
|
||||
151
libv4l2/v4l2-plugin-android.c
Normal file
151
libv4l2/v4l2-plugin-android.c
Normal file
@@ -0,0 +1,151 @@
|
||||
/*
|
||||
* 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, version 2.1,
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* 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 then -1 (the actual file descriptor).
|
||||
As soon as a plugin returns another value then -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);
|
||||
}
|
||||
}
|
||||
120
libv4l2/v4l2-plugin.c
Normal file
120
libv4l2/v4l2-plugin.c
Normal file
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
* 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, version 2.1,
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* 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 then -1 (the actual file descriptor).
|
||||
As soon as a plugin returns another value then -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;
|
||||
uint32_t 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;
|
||||
|
||||
for (i = 0; i < globbuf.gl_pathc; i++) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
167
libv4l2/v4l2convert.c
Normal file
167
libv4l2/v4l2convert.c
Normal file
@@ -0,0 +1,167 @@
|
||||
/*
|
||||
# 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, version 2.1,
|
||||
# as published by the Free Software Foundation.
|
||||
#
|
||||
# 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
|
||||
|
||||
#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>
|
||||
#include <linux/videodev2.h>
|
||||
#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
|
||||
67
libv4lconvert/Makefile
Normal file
67
libv4lconvert/Makefile
Normal file
@@ -0,0 +1,67 @@
|
||||
###############################################################################
|
||||
#
|
||||
# Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved.
|
||||
#
|
||||
# NVIDIA Corporation and its licensors retain all intellectual property
|
||||
# and proprietary rights in and to this software, related documentation
|
||||
# and any modifications thereto. Any use, reproduction, disclosure or
|
||||
# distribution of this software and related documentation without an express
|
||||
# license agreement from NVIDIA Corporation is strictly prohibited.
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
SO_NAME := libnvv4lconvert.so
|
||||
DEST_DIR ?= /usr/lib/aarch64-linux-gnu/tegra
|
||||
|
||||
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/tegra
|
||||
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 tegra/$(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)
|
||||
31
libv4lconvert/Makefile.am
Normal file
31
libv4lconvert/Makefile.am
Normal file
@@ -0,0 +1,31 @@
|
||||
if WITH_LIBV4L
|
||||
lib_LTLIBRARIES = libv4lconvert.la
|
||||
libv4lconvertpriv_PROGRAMS = ov511-decomp ov518-decomp
|
||||
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.c 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
|
||||
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
|
||||
41
libv4lconvert/Makefile.dGPU
Normal file
41
libv4lconvert/Makefile.dGPU
Normal file
@@ -0,0 +1,41 @@
|
||||
###############################################################################
|
||||
#
|
||||
# Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved.
|
||||
#
|
||||
# NVIDIA Corporation and its licensors retain all intellectual property
|
||||
# and proprietary rights in and to this software, related documentation
|
||||
# and any modifications thereto. Any use, reproduction, disclosure or
|
||||
# distribution of this software and related documentation without an express
|
||||
# license agreement from NVIDIA Corporation 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
|
||||
632
libv4lconvert/bayer.c
Normal file
632
libv4lconvert/bayer.c
Normal file
@@ -0,0 +1,632 @@
|
||||
/*
|
||||
* 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, 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 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);
|
||||
}
|
||||
79
libv4lconvert/control/libv4lcontrol-priv.h
Normal file
79
libv4lconvert/control/libv4lcontrol-priv.h
Normal 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, version 2.1,
|
||||
# as published by the Free Software Foundation.
|
||||
#
|
||||
# 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
|
||||
1120
libv4lconvert/control/libv4lcontrol.c
Normal file
1120
libv4lconvert/control/libv4lcontrol.c
Normal file
File diff suppressed because it is too large
Load Diff
78
libv4lconvert/control/libv4lcontrol.h
Normal file
78
libv4lconvert/control/libv4lcontrol.h
Normal file
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
# (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, version 2.1,
|
||||
# as published by the Free Software Foundation.
|
||||
#
|
||||
# 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
|
||||
213
libv4lconvert/cpia1.c
Normal file
213
libv4lconvert/cpia1.c
Normal file
@@ -0,0 +1,213 @@
|
||||
/*
|
||||
# (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, version 2.1,
|
||||
# as published by the Free Software Foundation.
|
||||
#
|
||||
# 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;
|
||||
}
|
||||
287
libv4lconvert/crop.c
Normal file
287
libv4lconvert/crop.c
Normal file
@@ -0,0 +1,287 @@
|
||||
/*
|
||||
|
||||
# RGB and YUV crop routines
|
||||
|
||||
# (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, version 2.1,
|
||||
# as published by the Free Software Foundation.
|
||||
#
|
||||
# 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;
|
||||
}
|
||||
}
|
||||
266
libv4lconvert/flip.c
Normal file
266
libv4lconvert/flip.c
Normal file
@@ -0,0 +1,266 @@
|
||||
/*
|
||||
|
||||
# RGB / YUV flip/rotate routines
|
||||
|
||||
# (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, version 2.1,
|
||||
# as published by the Free Software Foundation.
|
||||
#
|
||||
# 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);
|
||||
}
|
||||
79
libv4lconvert/helper-funcs.h
Normal file
79
libv4lconvert/helper-funcs.h
Normal 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;
|
||||
}
|
||||
219
libv4lconvert/helper.c
Normal file
219
libv4lconvert/helper.c
Normal file
@@ -0,0 +1,219 @@
|
||||
/*
|
||||
# (C) 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, version 2.1,
|
||||
# as published by the Free Software Foundation.
|
||||
#
|
||||
# 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;
|
||||
}
|
||||
}
|
||||
158
libv4lconvert/hm12.c
Normal file
158
libv4lconvert/hm12.c
Normal file
@@ -0,0 +1,158 @@
|
||||
/*
|
||||
|
||||
cx2341x HM12 conversion routines
|
||||
|
||||
(C) 2009 Hans Verkuil <hverkuil@xs4all.nl>
|
||||
|
||||
This program 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 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
284
libv4lconvert/jidctflt.c
Normal 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;
|
||||
}
|
||||
}
|
||||
|
||||
219
libv4lconvert/jl2005bcd.c
Normal file
219
libv4lconvert/jl2005bcd.c
Normal file
@@ -0,0 +1,219 @@
|
||||
/* 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, version 2.1,
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* 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 */
|
||||
428
libv4lconvert/jpeg.c
Normal file
428
libv4lconvert/jpeg.c
Normal file
@@ -0,0 +1,428 @@
|
||||
/*
|
||||
# (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, version 2.1,
|
||||
# as published by the Free Software Foundation.
|
||||
#
|
||||
# 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
|
||||
313
libv4lconvert/jpeg_memsrcdest.c
Normal file
313
libv4lconvert/jpeg_memsrcdest.c
Normal 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
|
||||
|
||||
/* 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 */
|
||||
#endif /* HAVE_JPEG */
|
||||
13
libv4lconvert/jpeg_memsrcdest.h
Normal file
13
libv4lconvert/jpeg_memsrcdest.h
Normal file
@@ -0,0 +1,13 @@
|
||||
#include <jpeglib.h>
|
||||
|
||||
#if JPEG_LIB_VERSION < 80
|
||||
|
||||
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
|
||||
727
libv4lconvert/jpgl.c
Normal file
727
libv4lconvert/jpgl.c
Normal file
@@ -0,0 +1,727 @@
|
||||
/*
|
||||
* 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, version 2.1,
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* 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,&) ) {
|
||||
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 make 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
|
||||
*/
|
||||
283
libv4lconvert/libv4lconvert-priv.h
Normal file
283
libv4lconvert/libv4lconvert-priv.h
Normal file
@@ -0,0 +1,283 @@
|
||||
/*
|
||||
# (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, version 2.1,
|
||||
# as published by the Free Software Foundation.
|
||||
#
|
||||
# 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 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;
|
||||
int64_t supported_src_formats; /* bitfield */
|
||||
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];
|
||||
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_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_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_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
|
||||
1701
libv4lconvert/libv4lconvert.c
Normal file
1701
libv4lconvert/libv4lconvert.c
Normal file
File diff suppressed because it is too large
Load Diff
23
libv4lconvert/libv4lconvert.export
Normal file
23
libv4lconvert/libv4lconvert.export
Normal file
@@ -0,0 +1,23 @@
|
||||
# Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved.
|
||||
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
|
||||
11
libv4lconvert/libv4lconvert.pc.in
Normal file
11
libv4lconvert/libv4lconvert.pc.in
Normal 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}
|
||||
129
libv4lconvert/libv4lsyscall-priv.h
Normal file
129
libv4lconvert/libv4lsyscall-priv.h
Normal file
@@ -0,0 +1,129 @@
|
||||
/*-
|
||||
* 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
|
||||
|
||||
#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))
|
||||
#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_ */
|
||||
208
libv4lconvert/mr97310a.c
Normal file
208
libv4lconvert/mr97310a.c
Normal file
@@ -0,0 +1,208 @@
|
||||
/*
|
||||
* 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, version 2, 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 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;
|
||||
}
|
||||
666
libv4lconvert/ov511-decomp.c
Normal file
666
libv4lconvert/ov511-decomp.c
Normal 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 */
|
||||
}
|
||||
}
|
||||
1480
libv4lconvert/ov518-decomp.c
Normal file
1480
libv4lconvert/ov518-decomp.c
Normal file
File diff suppressed because it is too large
Load Diff
436
libv4lconvert/pac207.c
Normal file
436
libv4lconvert/pac207.c
Normal file
@@ -0,0 +1,436 @@
|
||||
/*
|
||||
|
||||
# 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, version 2.1,
|
||||
# as published by the Free Software Foundation.
|
||||
#
|
||||
# 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
|
||||
*/
|
||||
217
libv4lconvert/processing/autogain.c
Normal file
217
libv4lconvert/processing/autogain.c
Normal file
@@ -0,0 +1,217 @@
|
||||
/*
|
||||
# (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, version 2.1,
|
||||
# as published by the Free Software Foundation.
|
||||
#
|
||||
# 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 then 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;
|
||||
}
|
||||
|
||||
struct v4lprocessing_filter autogain_filter = {
|
||||
autogain_active, autogain_calculate_lookup_tables
|
||||
};
|
||||
61
libv4lconvert/processing/gamma.c
Normal file
61
libv4lconvert/processing/gamma.c
Normal file
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
# (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, version 2.1,
|
||||
# as published by the Free Software Foundation.
|
||||
#
|
||||
# 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;
|
||||
}
|
||||
|
||||
struct v4lprocessing_filter gamma_filter = {
|
||||
gamma_active, gamma_calculate_lookup_tables
|
||||
};
|
||||
67
libv4lconvert/processing/libv4lprocessing-priv.h
Normal file
67
libv4lconvert/processing/libv4lprocessing-priv.h
Normal file
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
# (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, version 2.1,
|
||||
# as published by the Free Software Foundation.
|
||||
#
|
||||
# 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 struct v4lprocessing_filter whitebalance_filter;
|
||||
extern struct v4lprocessing_filter autogain_filter;
|
||||
extern struct v4lprocessing_filter gamma_filter;
|
||||
|
||||
#endif
|
||||
187
libv4lconvert/processing/libv4lprocessing.c
Normal file
187
libv4lconvert/processing/libv4lprocessing.c
Normal file
@@ -0,0 +1,187 @@
|
||||
/*
|
||||
# (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, version 2.1,
|
||||
# as published by the Free Software Foundation.
|
||||
#
|
||||
# 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 */
|
||||
|
||||
static struct v4lprocessing_filter *filters[] = {
|
||||
&whitebalance_filter,
|
||||
&autogain_filter,
|
||||
&gamma_filter,
|
||||
};
|
||||
|
||||
struct v4lprocessing_data *v4lprocessing_create(int fd, struct v4lcontrol_data *control)
|
||||
{
|
||||
struct v4lprocessing_data *data =
|
||||
calloc(1, sizeof(struct v4lprocessing_data));
|
||||
|
||||
if (!data) {
|
||||
fprintf(stderr, "libv4lprocessing: error: out of memory!\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
data->fd = fd;
|
||||
data->control = control;
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
void v4lprocessing_destroy(struct v4lprocessing_data *data)
|
||||
{
|
||||
free(data);
|
||||
}
|
||||
|
||||
int v4lprocessing_pre_processing(struct v4lprocessing_data *data)
|
||||
{
|
||||
int i;
|
||||
|
||||
data->do_process = 0;
|
||||
for (i = 0; i < ARRAY_SIZE(filters); i++) {
|
||||
if (filters[i]->active(data))
|
||||
data->do_process = 1;
|
||||
}
|
||||
|
||||
data->controls_changed |= v4lcontrol_controls_changed(data->control);
|
||||
|
||||
return data->do_process;
|
||||
}
|
||||
|
||||
static void v4lprocessing_update_lookup_tables(struct v4lprocessing_data *data,
|
||||
unsigned char *buf, const struct v4l2_format *fmt)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 256; i++) {
|
||||
data->comp1[i] = i;
|
||||
data->green[i] = i;
|
||||
data->comp2[i] = i;
|
||||
}
|
||||
|
||||
data->lookup_table_active = 0;
|
||||
for (i = 0; i < ARRAY_SIZE(filters); i++) {
|
||||
if (filters[i]->active(data)) {
|
||||
if (filters[i]->calculate_lookup_tables(data, buf, fmt))
|
||||
data->lookup_table_active = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void v4lprocessing_do_processing(struct v4lprocessing_data *data,
|
||||
unsigned char *buf, const struct v4l2_format *fmt)
|
||||
{
|
||||
int x, y;
|
||||
|
||||
switch (fmt->fmt.pix.pixelformat) {
|
||||
case V4L2_PIX_FMT_SGBRG8:
|
||||
case V4L2_PIX_FMT_SGRBG8: /* Bayer patterns starting with green */
|
||||
for (y = 0; (unsigned)y < fmt->fmt.pix.height / 2; y++) {
|
||||
for (x = 0; (unsigned)x < fmt->fmt.pix.width / 2; x++) {
|
||||
*buf = data->green[*buf];
|
||||
buf++;
|
||||
*buf = data->comp1[*buf];
|
||||
buf++;
|
||||
}
|
||||
buf += fmt->fmt.pix.bytesperline - fmt->fmt.pix.width;
|
||||
for (x = 0; (unsigned)x < fmt->fmt.pix.width / 2; x++) {
|
||||
*buf = data->comp2[*buf];
|
||||
buf++;
|
||||
*buf = data->green[*buf];
|
||||
buf++;
|
||||
}
|
||||
buf += fmt->fmt.pix.bytesperline - fmt->fmt.pix.width;
|
||||
}
|
||||
break;
|
||||
|
||||
case V4L2_PIX_FMT_SBGGR8:
|
||||
case V4L2_PIX_FMT_SRGGB8: /* Bayer patterns *NOT* starting with green */
|
||||
for (y = 0; (unsigned)y < fmt->fmt.pix.height / 2; y++) {
|
||||
for (x = 0; (unsigned)x < fmt->fmt.pix.width / 2; x++) {
|
||||
*buf = data->comp1[*buf];
|
||||
buf++;
|
||||
*buf = data->green[*buf];
|
||||
buf++;
|
||||
}
|
||||
buf += fmt->fmt.pix.bytesperline - fmt->fmt.pix.width;
|
||||
for (x = 0; (unsigned)x < fmt->fmt.pix.width / 2; x++) {
|
||||
*buf = data->green[*buf];
|
||||
buf++;
|
||||
*buf = data->comp2[*buf];
|
||||
buf++;
|
||||
}
|
||||
buf += fmt->fmt.pix.bytesperline - fmt->fmt.pix.width;
|
||||
}
|
||||
break;
|
||||
|
||||
case V4L2_PIX_FMT_RGB24:
|
||||
case V4L2_PIX_FMT_BGR24:
|
||||
for (y = 0; (unsigned)y < fmt->fmt.pix.height; y++) {
|
||||
for (x = 0; (unsigned)x < fmt->fmt.pix.width; x++) {
|
||||
*buf = data->comp1[*buf];
|
||||
buf++;
|
||||
*buf = data->green[*buf];
|
||||
buf++;
|
||||
*buf = data->comp2[*buf];
|
||||
buf++;
|
||||
}
|
||||
buf += fmt->fmt.pix.bytesperline - 3 * fmt->fmt.pix.width;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void v4lprocessing_processing(struct v4lprocessing_data *data,
|
||||
unsigned char *buf, const struct v4l2_format *fmt)
|
||||
{
|
||||
if (!data->do_process)
|
||||
return;
|
||||
|
||||
/* Do we support the current pixformat? */
|
||||
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:
|
||||
case V4L2_PIX_FMT_RGB24:
|
||||
case V4L2_PIX_FMT_BGR24:
|
||||
break;
|
||||
default:
|
||||
return; /* Non supported pix format */
|
||||
}
|
||||
|
||||
if (data->controls_changed ||
|
||||
data->lookup_table_update_counter == V4L2PROCESSING_UPDATE_RATE) {
|
||||
data->controls_changed = 0;
|
||||
data->lookup_table_update_counter = 0;
|
||||
/* Do this after resetting lookup_table_update_counter so that filters can
|
||||
force the next update to be sooner when they changed camera settings */
|
||||
v4lprocessing_update_lookup_tables(data, buf, fmt);
|
||||
} else
|
||||
data->lookup_table_update_counter++;
|
||||
|
||||
if (data->lookup_table_active)
|
||||
v4lprocessing_do_processing(data, buf, fmt);
|
||||
|
||||
data->do_process = 0;
|
||||
}
|
||||
42
libv4lconvert/processing/libv4lprocessing.h
Normal file
42
libv4lconvert/processing/libv4lprocessing.h
Normal file
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
# (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, version 2.1,
|
||||
# as published by the Free Software Foundation.
|
||||
#
|
||||
# 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_H
|
||||
#define __LIBV4LPROCESSING_H
|
||||
|
||||
#include "../libv4lsyscall-priv.h"
|
||||
#include <linux/videodev2.h>
|
||||
|
||||
struct v4lprocessing_data;
|
||||
struct v4lcontrol_data;
|
||||
|
||||
struct v4lprocessing_data *v4lprocessing_create(int fd, struct v4lcontrol_data *data);
|
||||
void v4lprocessing_destroy(struct v4lprocessing_data *data);
|
||||
|
||||
/* Prepare to process 1 frame, returns 1 if processing is necesary,
|
||||
return 0 if no processing will be done */
|
||||
int v4lprocessing_pre_processing(struct v4lprocessing_data *data);
|
||||
|
||||
/* Do the actual processing, this is a nop if v4lprocessing_pre_processing()
|
||||
returned 0, or if called more then 1 time after a single
|
||||
v4lprocessing_pre_processing() call. */
|
||||
void v4lprocessing_processing(struct v4lprocessing_data *data,
|
||||
unsigned char *buf, const struct v4l2_format *fmt);
|
||||
|
||||
#endif
|
||||
209
libv4lconvert/processing/whitebalance.c
Normal file
209
libv4lconvert/processing/whitebalance.c
Normal file
@@ -0,0 +1,209 @@
|
||||
/*
|
||||
# (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, version 2.1,
|
||||
# as published by the Free Software Foundation.
|
||||
#
|
||||
# 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 */
|
||||
|
||||
#define CLIP256(color) (((color) > 0xff) ? 0xff : (((color) < 0) ? 0 : (color)))
|
||||
#define CLIP(color, min, max) (((color) > (max)) ? (max) : (((color) < (min)) ? (min) : (color)))
|
||||
|
||||
static int whitebalance_active(struct v4lprocessing_data *data)
|
||||
{
|
||||
int wb;
|
||||
|
||||
wb = v4lcontrol_get_ctrl(data->control, V4LCONTROL_WHITEBALANCE);
|
||||
if (!wb) {
|
||||
/* Reset cached color averages */
|
||||
data->green_avg = 0;
|
||||
}
|
||||
|
||||
return wb;
|
||||
}
|
||||
|
||||
static int whitebalance_calculate_lookup_tables_generic(
|
||||
struct v4lprocessing_data *data, int green_avg, int comp1_avg, int comp2_avg)
|
||||
{
|
||||
int i, avg_avg;
|
||||
const int threshold = 64;
|
||||
const int max_step = 128;
|
||||
|
||||
/* Clip averages (restricts maximum white balance correction) */
|
||||
green_avg = CLIP(green_avg, 512, 3072);
|
||||
comp1_avg = CLIP(comp1_avg, 512, 3072);
|
||||
comp2_avg = CLIP(comp2_avg, 512, 3072);
|
||||
|
||||
/* First frame ? */
|
||||
if (data->green_avg == 0) {
|
||||
data->green_avg = green_avg;
|
||||
data->comp1_avg = comp1_avg;
|
||||
data->comp2_avg = comp2_avg;
|
||||
} else {
|
||||
/* Slowly adjust the averages used for the correction, so that
|
||||
we do not get a sudden change in colors */
|
||||
int throttling = 0;
|
||||
|
||||
if (abs(data->green_avg - green_avg) > max_step) {
|
||||
if (data->green_avg < green_avg)
|
||||
data->green_avg += max_step;
|
||||
else
|
||||
data->green_avg -= max_step;
|
||||
throttling = 1;
|
||||
} else
|
||||
data->green_avg = green_avg;
|
||||
|
||||
if (abs(data->comp1_avg - comp1_avg) > max_step) {
|
||||
if (data->comp1_avg < comp1_avg)
|
||||
data->comp1_avg += max_step;
|
||||
else
|
||||
data->comp1_avg -= max_step;
|
||||
throttling = 1;
|
||||
} else
|
||||
data->comp1_avg = comp1_avg;
|
||||
|
||||
if (abs(data->comp2_avg - comp2_avg) > max_step) {
|
||||
if (data->comp2_avg < comp2_avg)
|
||||
data->comp2_avg += max_step;
|
||||
else
|
||||
data->comp2_avg -= max_step;
|
||||
throttling = 1;
|
||||
} else
|
||||
data->comp2_avg = comp2_avg;
|
||||
|
||||
/*
|
||||
* If we are still converging to a stable update situation,
|
||||
* re-calc the lookup tables next frame, but only if no
|
||||
* other processing plugin has already asked for a shorter
|
||||
* update cycle, as asking for an update each frame while
|
||||
* some other pluging is trying to adjust hw settings is bad.
|
||||
*/
|
||||
if (throttling && data->lookup_table_update_counter == 0)
|
||||
data->lookup_table_update_counter =
|
||||
V4L2PROCESSING_UPDATE_RATE;
|
||||
}
|
||||
|
||||
if (abs(data->green_avg - data->comp1_avg) < threshold &&
|
||||
abs(data->green_avg - data->comp2_avg) < threshold &&
|
||||
abs(data->comp1_avg - data->comp2_avg) < threshold)
|
||||
return 0;
|
||||
|
||||
avg_avg = (data->green_avg + data->comp1_avg + data->comp2_avg) / 3;
|
||||
|
||||
for (i = 0; i < 256; i++) {
|
||||
data->comp1[i] = CLIP256(data->comp1[i] * avg_avg / data->comp1_avg);
|
||||
data->green[i] = CLIP256(data->green[i] * avg_avg / data->green_avg);
|
||||
data->comp2[i] = CLIP256(data->comp2[i] * avg_avg / data->comp2_avg);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int whitebalance_calculate_lookup_tables_bayer(
|
||||
struct v4lprocessing_data *data, unsigned char *buf,
|
||||
const struct v4l2_format *fmt, int starts_with_green)
|
||||
{
|
||||
int x, y, a1 = 0, a2 = 0, b1 = 0, b2 = 0;
|
||||
int green_avg, comp1_avg, comp2_avg;
|
||||
|
||||
for (y = 0; (unsigned)y < fmt->fmt.pix.height; y += 2) {
|
||||
for (x = 0; (unsigned)x < fmt->fmt.pix.width; x += 2) {
|
||||
a1 += *buf++;
|
||||
a2 += *buf++;
|
||||
}
|
||||
buf += fmt->fmt.pix.bytesperline - fmt->fmt.pix.width;
|
||||
for (x = 0; (unsigned)x < fmt->fmt.pix.width; x += 2) {
|
||||
b1 += *buf++;
|
||||
b2 += *buf++;
|
||||
}
|
||||
buf += fmt->fmt.pix.bytesperline - fmt->fmt.pix.width;
|
||||
}
|
||||
|
||||
if (starts_with_green) {
|
||||
green_avg = a1 / 2 + b2 / 2;
|
||||
comp1_avg = a2;
|
||||
comp2_avg = b1;
|
||||
} else {
|
||||
green_avg = a2 / 2 + b1 / 2;
|
||||
comp1_avg = a1;
|
||||
comp2_avg = b2;
|
||||
}
|
||||
|
||||
/* Norm avg to ~ 0 - 4095 */
|
||||
green_avg /= fmt->fmt.pix.width * fmt->fmt.pix.height / 64;
|
||||
comp1_avg /= fmt->fmt.pix.width * fmt->fmt.pix.height / 64;
|
||||
comp2_avg /= fmt->fmt.pix.width * fmt->fmt.pix.height / 64;
|
||||
|
||||
return whitebalance_calculate_lookup_tables_generic(data, green_avg,
|
||||
comp1_avg, comp2_avg);
|
||||
}
|
||||
|
||||
static int whitebalance_calculate_lookup_tables_rgb(
|
||||
struct v4lprocessing_data *data, unsigned char *buf,
|
||||
const struct v4l2_format *fmt)
|
||||
{
|
||||
int x, y, green_avg = 0, comp1_avg = 0, comp2_avg = 0;
|
||||
|
||||
for (y = 0; (unsigned)y < fmt->fmt.pix.height; y++) {
|
||||
for (x = 0; (unsigned)x < fmt->fmt.pix.width; x++) {
|
||||
comp1_avg += *buf++;
|
||||
green_avg += *buf++;
|
||||
comp2_avg += *buf++;
|
||||
}
|
||||
buf += fmt->fmt.pix.bytesperline - fmt->fmt.pix.width * 3;
|
||||
}
|
||||
|
||||
/* Norm avg to ~ 0 - 4095 */
|
||||
green_avg /= fmt->fmt.pix.width * fmt->fmt.pix.height / 16;
|
||||
comp1_avg /= fmt->fmt.pix.width * fmt->fmt.pix.height / 16;
|
||||
comp2_avg /= fmt->fmt.pix.width * fmt->fmt.pix.height / 16;
|
||||
|
||||
return whitebalance_calculate_lookup_tables_generic(data, green_avg,
|
||||
comp1_avg, comp2_avg);
|
||||
}
|
||||
|
||||
|
||||
static int whitebalance_calculate_lookup_tables(
|
||||
struct v4lprocessing_data *data,
|
||||
unsigned char *buf, const struct v4l2_format *fmt)
|
||||
{
|
||||
switch (fmt->fmt.pix.pixelformat) {
|
||||
case V4L2_PIX_FMT_SGBRG8:
|
||||
case V4L2_PIX_FMT_SGRBG8: /* Bayer patterns starting with green */
|
||||
return whitebalance_calculate_lookup_tables_bayer(data, buf, fmt, 1);
|
||||
|
||||
case V4L2_PIX_FMT_SBGGR8:
|
||||
case V4L2_PIX_FMT_SRGGB8: /* Bayer patterns *NOT* starting with green */
|
||||
return whitebalance_calculate_lookup_tables_bayer(data, buf, fmt, 0);
|
||||
|
||||
case V4L2_PIX_FMT_RGB24:
|
||||
case V4L2_PIX_FMT_BGR24:
|
||||
return whitebalance_calculate_lookup_tables_rgb(data, buf, fmt);
|
||||
}
|
||||
|
||||
return 0; /* Should never happen */
|
||||
}
|
||||
|
||||
struct v4lprocessing_filter whitebalance_filter = {
|
||||
whitebalance_active, whitebalance_calculate_lookup_tables
|
||||
};
|
||||
756
libv4lconvert/rgbyuv.c
Normal file
756
libv4lconvert/rgbyuv.c
Normal file
@@ -0,0 +1,756 @@
|
||||
/*
|
||||
|
||||
# RGB <-> YUV conversion routines
|
||||
# (C) 2008 Hans de Goede <hdegoede@redhat.com>
|
||||
|
||||
# RGB565 conversion routines
|
||||
# (C) 2009 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, version 2.1,
|
||||
# as published by the Free Software Foundation.
|
||||
#
|
||||
# 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"
|
||||
|
||||
#define RGB2Y(r, g, b, y) \
|
||||
(y) = ((8453 * (r) + 16594 * (g) + 3223 * (b) + 524288) >> 15)
|
||||
|
||||
#define RGB2UV(r, g, b, u, v) \
|
||||
do { \
|
||||
(u) = ((-4878 * (r) - 9578 * (g) + 14456 * (b) + 4210688) >> 15); \
|
||||
(v) = ((14456 * (r) - 12105 * (g) - 2351 * (b) + 4210688) >> 15); \
|
||||
} while (0)
|
||||
|
||||
void v4lconvert_rgb24_to_yuv420(const unsigned char *src, unsigned char *dest,
|
||||
const struct v4l2_format *src_fmt, int bgr, int yvu, int bpp)
|
||||
{
|
||||
unsigned int x, y;
|
||||
unsigned char *udest, *vdest;
|
||||
|
||||
/* Y */
|
||||
for (y = 0; y < src_fmt->fmt.pix.height; y++) {
|
||||
for (x = 0; x < src_fmt->fmt.pix.width; x++) {
|
||||
if (bgr)
|
||||
RGB2Y(src[2], src[1], src[0], *dest++);
|
||||
else
|
||||
RGB2Y(src[0], src[1], src[2], *dest++);
|
||||
src += bpp;
|
||||
}
|
||||
|
||||
src += src_fmt->fmt.pix.bytesperline - bpp * src_fmt->fmt.pix.width;
|
||||
}
|
||||
src -= src_fmt->fmt.pix.height * src_fmt->fmt.pix.bytesperline;
|
||||
|
||||
/* U + V */
|
||||
if (yvu) {
|
||||
vdest = dest;
|
||||
udest = dest + src_fmt->fmt.pix.width * src_fmt->fmt.pix.height / 4;
|
||||
} else {
|
||||
udest = dest;
|
||||
vdest = dest + src_fmt->fmt.pix.width * src_fmt->fmt.pix.height / 4;
|
||||
}
|
||||
|
||||
for (y = 0; y < src_fmt->fmt.pix.height / 2; y++) {
|
||||
for (x = 0; x < src_fmt->fmt.pix.width / 2; x++) {
|
||||
int avg_src[3];
|
||||
|
||||
avg_src[0] = (src[0] + src[bpp] + src[src_fmt->fmt.pix.bytesperline] +
|
||||
src[src_fmt->fmt.pix.bytesperline + bpp]) / 4;
|
||||
avg_src[1] = (src[1] + src[bpp + 1] + src[src_fmt->fmt.pix.bytesperline + 1] +
|
||||
src[src_fmt->fmt.pix.bytesperline + bpp + 1]) / 4;
|
||||
avg_src[2] = (src[2] + src[bpp + 2] + src[src_fmt->fmt.pix.bytesperline + 2] +
|
||||
src[src_fmt->fmt.pix.bytesperline + bpp + 2]) / 4;
|
||||
if (bgr)
|
||||
RGB2UV(avg_src[2], avg_src[1], avg_src[0], *udest++, *vdest++);
|
||||
else
|
||||
RGB2UV(avg_src[0], avg_src[1], avg_src[2], *udest++, *vdest++);
|
||||
src += 2 * bpp;
|
||||
}
|
||||
src += 2 * src_fmt->fmt.pix.bytesperline - bpp * src_fmt->fmt.pix.width;
|
||||
}
|
||||
}
|
||||
|
||||
#define YUV2R(y, u, v) ({ \
|
||||
int r = (y) + ((((v) - 128) * 1436) >> 10); r > 255 ? 255 : r < 0 ? 0 : r; })
|
||||
#define YUV2G(y, u, v) ({ \
|
||||
int g = (y) - ((((u) - 128) * 352 + ((v) - 128) * 731) >> 10); g > 255 ? 255 : g < 0 ? 0 : g; })
|
||||
#define YUV2B(y, u, v) ({ \
|
||||
int b = (y) + ((((u) - 128) * 1814) >> 10); b > 255 ? 255 : b < 0 ? 0 : b; })
|
||||
|
||||
#define CLIP(color) (unsigned char)(((color) > 0xFF) ? 0xff : (((color) < 0) ? 0 : (color)))
|
||||
|
||||
void v4lconvert_yuv420_to_bgr24(const unsigned char *src, unsigned char *dest,
|
||||
int width, int height, int yvu)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
const unsigned char *ysrc = src;
|
||||
const unsigned char *usrc, *vsrc;
|
||||
|
||||
if (yvu) {
|
||||
vsrc = src + width * height;
|
||||
usrc = vsrc + (width * height) / 4;
|
||||
} else {
|
||||
usrc = src + width * height;
|
||||
vsrc = usrc + (width * height) / 4;
|
||||
}
|
||||
|
||||
for (i = 0; i < height; i++) {
|
||||
for (j = 0; j < width; j += 2) {
|
||||
#if 1 /* fast slightly less accurate multiplication free code */
|
||||
int u1 = (((*usrc - 128) << 7) + (*usrc - 128)) >> 6;
|
||||
int rg = (((*usrc - 128) << 1) + (*usrc - 128) +
|
||||
((*vsrc - 128) << 2) + ((*vsrc - 128) << 1)) >> 3;
|
||||
int v1 = (((*vsrc - 128) << 1) + (*vsrc - 128)) >> 1;
|
||||
|
||||
*dest++ = CLIP(*ysrc + u1);
|
||||
*dest++ = CLIP(*ysrc - rg);
|
||||
*dest++ = CLIP(*ysrc + v1);
|
||||
ysrc++;
|
||||
|
||||
*dest++ = CLIP(*ysrc + u1);
|
||||
*dest++ = CLIP(*ysrc - rg);
|
||||
*dest++ = CLIP(*ysrc + v1);
|
||||
#else
|
||||
*dest++ = YUV2B(*ysrc, *usrc, *vsrc);
|
||||
*dest++ = YUV2G(*ysrc, *usrc, *vsrc);
|
||||
*dest++ = YUV2R(*ysrc, *usrc, *vsrc);
|
||||
ysrc++;
|
||||
|
||||
*dest++ = YUV2B(*ysrc, *usrc, *vsrc);
|
||||
*dest++ = YUV2G(*ysrc, *usrc, *vsrc);
|
||||
*dest++ = YUV2R(*ysrc, *usrc, *vsrc);
|
||||
#endif
|
||||
ysrc++;
|
||||
usrc++;
|
||||
vsrc++;
|
||||
}
|
||||
/* Rewind u and v for next line */
|
||||
if (!(i & 1)) {
|
||||
usrc -= width / 2;
|
||||
vsrc -= width / 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void v4lconvert_yuv420_to_rgb24(const unsigned char *src, unsigned char *dest,
|
||||
int width, int height, int yvu)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
const unsigned char *ysrc = src;
|
||||
const unsigned char *usrc, *vsrc;
|
||||
|
||||
if (yvu) {
|
||||
vsrc = src + width * height;
|
||||
usrc = vsrc + (width * height) / 4;
|
||||
} else {
|
||||
usrc = src + width * height;
|
||||
vsrc = usrc + (width * height) / 4;
|
||||
}
|
||||
|
||||
for (i = 0; i < height; i++) {
|
||||
for (j = 0; j < width; j += 2) {
|
||||
#if 1 /* fast slightly less accurate multiplication free code */
|
||||
int u1 = (((*usrc - 128) << 7) + (*usrc - 128)) >> 6;
|
||||
int rg = (((*usrc - 128) << 1) + (*usrc - 128) +
|
||||
((*vsrc - 128) << 2) + ((*vsrc - 128) << 1)) >> 3;
|
||||
int v1 = (((*vsrc - 128) << 1) + (*vsrc - 128)) >> 1;
|
||||
|
||||
*dest++ = CLIP(*ysrc + v1);
|
||||
*dest++ = CLIP(*ysrc - rg);
|
||||
*dest++ = CLIP(*ysrc + u1);
|
||||
ysrc++;
|
||||
|
||||
*dest++ = CLIP(*ysrc + v1);
|
||||
*dest++ = CLIP(*ysrc - rg);
|
||||
*dest++ = CLIP(*ysrc + u1);
|
||||
#else
|
||||
*dest++ = YUV2R(*ysrc, *usrc, *vsrc);
|
||||
*dest++ = YUV2G(*ysrc, *usrc, *vsrc);
|
||||
*dest++ = YUV2B(*ysrc, *usrc, *vsrc);
|
||||
ysrc++;
|
||||
|
||||
*dest++ = YUV2R(*ysrc, *usrc, *vsrc);
|
||||
*dest++ = YUV2G(*ysrc, *usrc, *vsrc);
|
||||
*dest++ = YUV2B(*ysrc, *usrc, *vsrc);
|
||||
#endif
|
||||
ysrc++;
|
||||
usrc++;
|
||||
vsrc++;
|
||||
}
|
||||
/* Rewind u and v for next line */
|
||||
if (!(i&1)) {
|
||||
usrc -= width / 2;
|
||||
vsrc -= width / 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void v4lconvert_yuyv_to_bgr24(const unsigned char *src, unsigned char *dest,
|
||||
int width, int height, int stride)
|
||||
{
|
||||
int j;
|
||||
|
||||
while (--height >= 0) {
|
||||
for (j = 0; j + 1 < width; j += 2) {
|
||||
int u = src[1];
|
||||
int v = src[3];
|
||||
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++ = CLIP(src[0] + u1);
|
||||
*dest++ = CLIP(src[0] - rg);
|
||||
*dest++ = CLIP(src[0] + v1);
|
||||
|
||||
*dest++ = CLIP(src[2] + u1);
|
||||
*dest++ = CLIP(src[2] - rg);
|
||||
*dest++ = CLIP(src[2] + v1);
|
||||
src += 4;
|
||||
}
|
||||
src += stride - width * 2;
|
||||
}
|
||||
}
|
||||
|
||||
void v4lconvert_yuyv_to_rgb24(const unsigned char *src, unsigned char *dest,
|
||||
int width, int height, int stride)
|
||||
{
|
||||
int j;
|
||||
|
||||
while (--height >= 0) {
|
||||
for (j = 0; j + 1 < width; j += 2) {
|
||||
int u = src[1];
|
||||
int v = src[3];
|
||||
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++ = CLIP(src[0] + v1);
|
||||
*dest++ = CLIP(src[0] - rg);
|
||||
*dest++ = CLIP(src[0] + u1);
|
||||
|
||||
*dest++ = CLIP(src[2] + v1);
|
||||
*dest++ = CLIP(src[2] - rg);
|
||||
*dest++ = CLIP(src[2] + u1);
|
||||
src += 4;
|
||||
}
|
||||
src += stride - (width * 2);
|
||||
}
|
||||
}
|
||||
|
||||
void v4lconvert_yuyv_to_yuv420(const unsigned char *src, unsigned char *dest,
|
||||
int width, int height, int stride, int yvu)
|
||||
{
|
||||
int i, j;
|
||||
const unsigned char *src1;
|
||||
unsigned char *udest, *vdest;
|
||||
|
||||
/* copy the Y values */
|
||||
src1 = src;
|
||||
for (i = 0; i < height; i++) {
|
||||
for (j = 0; j + 1 < width; j += 2) {
|
||||
*dest++ = src1[0];
|
||||
*dest++ = src1[2];
|
||||
src1 += 4;
|
||||
}
|
||||
src1 += stride - width * 2;
|
||||
}
|
||||
|
||||
/* copy the U and V values */
|
||||
src++; /* point to V */
|
||||
src1 = src + stride; /* next line */
|
||||
if (yvu) {
|
||||
vdest = dest;
|
||||
udest = dest + width * height / 4;
|
||||
} else {
|
||||
udest = dest;
|
||||
vdest = dest + width * height / 4;
|
||||
}
|
||||
for (i = 0; i < height; i += 2) {
|
||||
for (j = 0; j + 1 < width; j += 2) {
|
||||
*udest++ = ((int) src[0] + src1[0]) / 2; /* U */
|
||||
*vdest++ = ((int) src[2] + src1[2]) / 2; /* V */
|
||||
src += 4;
|
||||
src1 += 4;
|
||||
}
|
||||
src1 += stride - width * 2;
|
||||
src = src1;
|
||||
src1 += stride;
|
||||
}
|
||||
}
|
||||
|
||||
void v4lconvert_yvyu_to_bgr24(const unsigned char *src, unsigned char *dest,
|
||||
int width, int height, int stride)
|
||||
{
|
||||
int j;
|
||||
|
||||
while (--height >= 0) {
|
||||
for (j = 0; j + 1 < width; j += 2) {
|
||||
int u = src[3];
|
||||
int v = src[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++ = CLIP(src[0] + u1);
|
||||
*dest++ = CLIP(src[0] - rg);
|
||||
*dest++ = CLIP(src[0] + v1);
|
||||
|
||||
*dest++ = CLIP(src[2] + u1);
|
||||
*dest++ = CLIP(src[2] - rg);
|
||||
*dest++ = CLIP(src[2] + v1);
|
||||
src += 4;
|
||||
}
|
||||
src += stride - (width * 2);
|
||||
}
|
||||
}
|
||||
|
||||
void v4lconvert_yvyu_to_rgb24(const unsigned char *src, unsigned char *dest,
|
||||
int width, int height, int stride)
|
||||
{
|
||||
int j;
|
||||
|
||||
while (--height >= 0) {
|
||||
for (j = 0; j + 1 < width; j += 2) {
|
||||
int u = src[3];
|
||||
int v = src[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++ = CLIP(src[0] + v1);
|
||||
*dest++ = CLIP(src[0] - rg);
|
||||
*dest++ = CLIP(src[0] + u1);
|
||||
|
||||
*dest++ = CLIP(src[2] + v1);
|
||||
*dest++ = CLIP(src[2] - rg);
|
||||
*dest++ = CLIP(src[2] + u1);
|
||||
src += 4;
|
||||
}
|
||||
src += stride - (width * 2);
|
||||
}
|
||||
}
|
||||
|
||||
void v4lconvert_uyvy_to_bgr24(const unsigned char *src, unsigned char *dest,
|
||||
int width, int height, int stride)
|
||||
{
|
||||
int j;
|
||||
|
||||
while (--height >= 0) {
|
||||
for (j = 0; j + 1 < width; j += 2) {
|
||||
int u = src[0];
|
||||
int v = src[2];
|
||||
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++ = CLIP(src[1] + u1);
|
||||
*dest++ = CLIP(src[1] - rg);
|
||||
*dest++ = CLIP(src[1] + v1);
|
||||
|
||||
*dest++ = CLIP(src[3] + u1);
|
||||
*dest++ = CLIP(src[3] - rg);
|
||||
*dest++ = CLIP(src[3] + v1);
|
||||
src += 4;
|
||||
}
|
||||
src += stride - width * 2;
|
||||
}
|
||||
}
|
||||
|
||||
void v4lconvert_uyvy_to_rgb24(const unsigned char *src, unsigned char *dest,
|
||||
int width, int height, int stride)
|
||||
{
|
||||
int j;
|
||||
|
||||
while (--height >= 0) {
|
||||
for (j = 0; j + 1 < width; j += 2) {
|
||||
int u = src[0];
|
||||
int v = src[2];
|
||||
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++ = CLIP(src[1] + v1);
|
||||
*dest++ = CLIP(src[1] - rg);
|
||||
*dest++ = CLIP(src[1] + u1);
|
||||
|
||||
*dest++ = CLIP(src[3] + v1);
|
||||
*dest++ = CLIP(src[3] - rg);
|
||||
*dest++ = CLIP(src[3] + u1);
|
||||
src += 4;
|
||||
}
|
||||
src += stride - width * 2;
|
||||
}
|
||||
}
|
||||
|
||||
void v4lconvert_uyvy_to_yuv420(const unsigned char *src, unsigned char *dest,
|
||||
int width, int height, int stride, int yvu)
|
||||
{
|
||||
int i, j;
|
||||
const unsigned char *src1;
|
||||
unsigned char *udest, *vdest;
|
||||
|
||||
/* copy the Y values */
|
||||
src1 = src;
|
||||
for (i = 0; i < height; i++) {
|
||||
for (j = 0; j + 1 < width; j += 2) {
|
||||
*dest++ = src1[1];
|
||||
*dest++ = src1[3];
|
||||
src1 += 4;
|
||||
}
|
||||
src1 += stride - width * 2;
|
||||
}
|
||||
|
||||
/* copy the U and V values */
|
||||
src1 = src + stride; /* next line */
|
||||
if (yvu) {
|
||||
vdest = dest;
|
||||
udest = dest + width * height / 4;
|
||||
} else {
|
||||
udest = dest;
|
||||
vdest = dest + width * height / 4;
|
||||
}
|
||||
for (i = 0; i < height; i += 2) {
|
||||
for (j = 0; j + 1 < width; j += 2) {
|
||||
*udest++ = ((int) src[0] + src1[0]) / 2; /* U */
|
||||
*vdest++ = ((int) src[2] + src1[2]) / 2; /* V */
|
||||
src += 4;
|
||||
src1 += 4;
|
||||
}
|
||||
src1 += stride - width * 2;
|
||||
src = src1;
|
||||
src1 += stride;
|
||||
}
|
||||
}
|
||||
|
||||
void v4lconvert_swap_rgb(const unsigned char *src, unsigned char *dst,
|
||||
int width, int height)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < (width * height); i++) {
|
||||
unsigned char tmp0, tmp1;
|
||||
tmp0 = *src++;
|
||||
tmp1 = *src++;
|
||||
*dst++ = *src++;
|
||||
*dst++ = tmp1;
|
||||
*dst++ = tmp0;
|
||||
}
|
||||
}
|
||||
|
||||
void v4lconvert_swap_uv(const unsigned char *src, unsigned char *dest,
|
||||
const struct v4l2_format *src_fmt)
|
||||
{
|
||||
unsigned int y;
|
||||
|
||||
/* Copy Y */
|
||||
for (y = 0; y < src_fmt->fmt.pix.height; y++) {
|
||||
memcpy(dest, src, src_fmt->fmt.pix.width);
|
||||
dest += src_fmt->fmt.pix.width;
|
||||
src += src_fmt->fmt.pix.bytesperline;
|
||||
}
|
||||
|
||||
/* Copy component 2 */
|
||||
src += src_fmt->fmt.pix.height * src_fmt->fmt.pix.bytesperline / 4;
|
||||
for (y = 0; y < src_fmt->fmt.pix.height / 2; y++) {
|
||||
memcpy(dest, src, src_fmt->fmt.pix.width / 2);
|
||||
dest += src_fmt->fmt.pix.width / 2;
|
||||
src += src_fmt->fmt.pix.bytesperline / 2;
|
||||
}
|
||||
|
||||
/* Copy component 1 */
|
||||
src -= src_fmt->fmt.pix.height * src_fmt->fmt.pix.bytesperline / 2;
|
||||
for (y = 0; y < src_fmt->fmt.pix.height / 2; y++) {
|
||||
memcpy(dest, src, src_fmt->fmt.pix.width / 2);
|
||||
dest += src_fmt->fmt.pix.width / 2;
|
||||
src += src_fmt->fmt.pix.bytesperline / 2;
|
||||
}
|
||||
}
|
||||
|
||||
void v4lconvert_rgb565_to_rgb24(const unsigned char *src, unsigned char *dest,
|
||||
int width, int height)
|
||||
{
|
||||
int j;
|
||||
while (--height >= 0) {
|
||||
for (j = 0; j < width; j++) {
|
||||
unsigned short tmp = *(unsigned short *)src;
|
||||
|
||||
/* Original format: rrrrrggg gggbbbbb */
|
||||
*dest++ = 0xf8 & (tmp >> 8);
|
||||
*dest++ = 0xfc & (tmp >> 3);
|
||||
*dest++ = 0xf8 & (tmp << 3);
|
||||
|
||||
src += 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void v4lconvert_rgb565_to_bgr24(const unsigned char *src, unsigned char *dest,
|
||||
int width, int height)
|
||||
{
|
||||
int j;
|
||||
while (--height >= 0) {
|
||||
for (j = 0; j < width; j++) {
|
||||
unsigned short tmp = *(unsigned short *)src;
|
||||
|
||||
/* Original format: rrrrrggg gggbbbbb */
|
||||
*dest++ = 0xf8 & (tmp << 3);
|
||||
*dest++ = 0xfc & (tmp >> 3);
|
||||
*dest++ = 0xf8 & (tmp >> 8);
|
||||
|
||||
src += 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void v4lconvert_rgb565_to_yuv420(const unsigned char *src, unsigned char *dest,
|
||||
const struct v4l2_format *src_fmt, int yvu)
|
||||
{
|
||||
unsigned int x, y;
|
||||
unsigned short tmp;
|
||||
unsigned char *udest, *vdest;
|
||||
unsigned r[4], g[4], b[4];
|
||||
int avg_src[3];
|
||||
|
||||
/* Y */
|
||||
for (y = 0; y < src_fmt->fmt.pix.height; y++) {
|
||||
for (x = 0; x < src_fmt->fmt.pix.width; x++) {
|
||||
tmp = *(unsigned short *)src;
|
||||
r[0] = 0xf8 & (tmp << 3);
|
||||
g[0] = 0xfc & (tmp >> 3);
|
||||
b[0] = 0xf8 & (tmp >> 8);
|
||||
RGB2Y(r[0], g[0], b[0], *dest++);
|
||||
src += 2;
|
||||
}
|
||||
src += src_fmt->fmt.pix.bytesperline - 2 * src_fmt->fmt.pix.width;
|
||||
}
|
||||
src -= src_fmt->fmt.pix.height * src_fmt->fmt.pix.bytesperline;
|
||||
|
||||
/* U + V */
|
||||
if (yvu) {
|
||||
vdest = dest;
|
||||
udest = dest + src_fmt->fmt.pix.width * src_fmt->fmt.pix.height / 4;
|
||||
} else {
|
||||
udest = dest;
|
||||
vdest = dest + src_fmt->fmt.pix.width * src_fmt->fmt.pix.height / 4;
|
||||
}
|
||||
|
||||
for (y = 0; y < src_fmt->fmt.pix.height / 2; y++) {
|
||||
for (x = 0; x < src_fmt->fmt.pix.width / 2; x++) {
|
||||
tmp = *(unsigned short *)src;
|
||||
r[0] = 0xf8 & (tmp << 3);
|
||||
g[0] = 0xfc & (tmp >> 3);
|
||||
b[0] = 0xf8 & (tmp >> 8);
|
||||
|
||||
tmp = *(((unsigned short *)src) + 1);
|
||||
r[1] = 0xf8 & (tmp << 3);
|
||||
g[1] = 0xfc & (tmp >> 3);
|
||||
b[1] = 0xf8 & (tmp >> 8);
|
||||
|
||||
tmp = *(((unsigned short *)src) + src_fmt->fmt.pix.bytesperline);
|
||||
r[2] = 0xf8 & (tmp << 3);
|
||||
g[2] = 0xfc & (tmp >> 3);
|
||||
b[2] = 0xf8 & (tmp >> 8);
|
||||
|
||||
tmp = *(((unsigned short *)src) + src_fmt->fmt.pix.bytesperline + 1);
|
||||
r[3] = 0xf8 & (tmp << 3);
|
||||
g[3] = 0xfc & (tmp >> 3);
|
||||
b[3] = 0xf8 & (tmp >> 8);
|
||||
|
||||
avg_src[0] = (r[0] + r[1] + r[2] + r[3]) / 4;
|
||||
avg_src[1] = (g[0] + g[1] + g[2] + g[3]) / 4;
|
||||
avg_src[2] = (b[0] + b[1] + b[2] + b[3]) / 4;
|
||||
RGB2UV(avg_src[0], avg_src[1], avg_src[2], *udest++, *vdest++);
|
||||
src += 4;
|
||||
}
|
||||
src += 2 * src_fmt->fmt.pix.bytesperline - 2 * src_fmt->fmt.pix.width;
|
||||
}
|
||||
}
|
||||
|
||||
void v4lconvert_y16_to_rgb24(const unsigned char *src, unsigned char *dest,
|
||||
int width, int height, int little_endian)
|
||||
{
|
||||
int j;
|
||||
|
||||
if (little_endian)
|
||||
src++;
|
||||
|
||||
while (--height >= 0) {
|
||||
for (j = 0; j < width; j++) {
|
||||
*dest++ = *src;
|
||||
*dest++ = *src;
|
||||
*dest++ = *src;
|
||||
src+=2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void v4lconvert_y16_to_yuv420(const unsigned char *src, unsigned char *dest,
|
||||
const struct v4l2_format *src_fmt, int little_endian)
|
||||
{
|
||||
unsigned int x, y;
|
||||
|
||||
if (little_endian)
|
||||
src++;
|
||||
|
||||
/* Y */
|
||||
for (y = 0; y < src_fmt->fmt.pix.height; y++)
|
||||
for (x = 0; x < src_fmt->fmt.pix.width; x++){
|
||||
*dest++ = *src;
|
||||
src+=2;
|
||||
}
|
||||
|
||||
/* Clear U/V */
|
||||
memset(dest, 0x80, src_fmt->fmt.pix.width * src_fmt->fmt.pix.height / 2);
|
||||
}
|
||||
|
||||
void v4lconvert_grey_to_rgb24(const unsigned char *src, unsigned char *dest,
|
||||
int width, int height)
|
||||
{
|
||||
int j;
|
||||
while (--height >= 0) {
|
||||
for (j = 0; j < width; j++) {
|
||||
*dest++ = *src;
|
||||
*dest++ = *src;
|
||||
*dest++ = *src;
|
||||
src++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void v4lconvert_grey_to_yuv420(const unsigned char *src, unsigned char *dest,
|
||||
const struct v4l2_format *src_fmt)
|
||||
{
|
||||
unsigned int x, y;
|
||||
|
||||
/* Y */
|
||||
for (y = 0; y < src_fmt->fmt.pix.height; y++)
|
||||
for (x = 0; x < src_fmt->fmt.pix.width; x++)
|
||||
*dest++ = *src++;
|
||||
|
||||
/* Clear U/V */
|
||||
memset(dest, 0x80, src_fmt->fmt.pix.width * src_fmt->fmt.pix.height / 2);
|
||||
}
|
||||
|
||||
/* Unpack buffer of (vw bit) data into padded 16bit buffer. */
|
||||
static inline void convert_packed_to_16bit(const uint8_t *raw, uint16_t *unpacked,
|
||||
int vw, int unpacked_len)
|
||||
{
|
||||
int mask = (1 << vw) - 1;
|
||||
uint32_t buffer = 0;
|
||||
int bitsIn = 0;
|
||||
while (unpacked_len--) {
|
||||
while (bitsIn < vw) {
|
||||
buffer = (buffer << 8) | *(raw++);
|
||||
bitsIn += 8;
|
||||
}
|
||||
bitsIn -= vw;
|
||||
*(unpacked++) = (buffer >> bitsIn) & mask;
|
||||
}
|
||||
}
|
||||
|
||||
int v4lconvert_y10b_to_rgb24(struct v4lconvert_data *data,
|
||||
const unsigned char *src, unsigned char *dest, int width, int height)
|
||||
{
|
||||
unsigned char *unpacked_buffer;
|
||||
|
||||
unpacked_buffer = v4lconvert_alloc_buffer(width * height * 2,
|
||||
&data->convert_pixfmt_buf,
|
||||
&data->convert_pixfmt_buf_size);
|
||||
if (!unpacked_buffer)
|
||||
return v4lconvert_oom_error(data);
|
||||
|
||||
convert_packed_to_16bit((uint8_t *)src, (uint16_t *)unpacked_buffer,
|
||||
10, width * height);
|
||||
|
||||
int j;
|
||||
unsigned short *tmp = (unsigned short *)unpacked_buffer;
|
||||
while (--height >= 0) {
|
||||
for (j = 0; j < width; j++) {
|
||||
|
||||
/* Only 10 useful bits, so we discard the LSBs */
|
||||
*dest++ = (*tmp & 0x3ff) >> 2;
|
||||
*dest++ = (*tmp & 0x3ff) >> 2;
|
||||
*dest++ = (*tmp & 0x3ff) >> 2;
|
||||
|
||||
/* +1 means two bytes as we are dealing with (unsigned short) */
|
||||
tmp += 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int v4lconvert_y10b_to_yuv420(struct v4lconvert_data *data,
|
||||
const unsigned char *src, unsigned char *dest, int width, int height)
|
||||
{
|
||||
unsigned char *unpacked_buffer;
|
||||
|
||||
unpacked_buffer = v4lconvert_alloc_buffer(width * height * 2,
|
||||
&data->convert_pixfmt_buf,
|
||||
&data->convert_pixfmt_buf_size);
|
||||
if (!unpacked_buffer)
|
||||
return v4lconvert_oom_error(data);
|
||||
|
||||
convert_packed_to_16bit((uint8_t *)src, (uint16_t *)unpacked_buffer,
|
||||
10, width * height);
|
||||
|
||||
int x, y;
|
||||
unsigned short *tmp = (unsigned short *)unpacked_buffer;
|
||||
|
||||
/* Y */
|
||||
for (y = 0; y < height; y++)
|
||||
for (x = 0; x < width; x++) {
|
||||
|
||||
/* Only 10 useful bits, so we discard the LSBs */
|
||||
*dest++ = (*tmp & 0x3ff) >> 2;
|
||||
|
||||
/* +1 means two bytes as we are dealing with (unsigned short) */
|
||||
tmp += 1;
|
||||
}
|
||||
|
||||
/* Clear U/V */
|
||||
memset(dest, 0x80, width * height / 2);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void v4lconvert_rgb32_to_rgb24(const unsigned char *src, unsigned char *dest,
|
||||
int width, int height,int bgr)
|
||||
{
|
||||
int j;
|
||||
while (--height >= 0) {
|
||||
for (j = 0; j < width; j++) {
|
||||
if (bgr){
|
||||
*dest++ = src[2];
|
||||
*dest++ = src[1];
|
||||
*dest++ = src[0];
|
||||
src+=4;
|
||||
}
|
||||
else{
|
||||
*dest++ = *src++;
|
||||
*dest++ = *src++;
|
||||
*dest++ = *src++;
|
||||
src+=1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
164
libv4lconvert/se401.c
Normal file
164
libv4lconvert/se401.c
Normal file
@@ -0,0 +1,164 @@
|
||||
/*
|
||||
# (C) 2011 Hans de Goede <hdegoede@redhat.com>
|
||||
|
||||
# The compression algorithm has been taken from the v4l1 se401 linux kernel
|
||||
# driver by Jeroen B. Vreeken (pe1rxq@amsat.org)
|
||||
|
||||
# This program 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 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 <errno.h>
|
||||
|
||||
/* The se401 compression algorithm uses a fixed quant factor, which
|
||||
can be configured by setting the high nibble of the SE401_OPERATINGMODE
|
||||
feature. This needs to exactly match what is in the SE401 driver! */
|
||||
#define SE401_QUANT_FACT 8
|
||||
|
||||
static void wr_pixel(int p, uint8_t **dest, int pitch, int *x)
|
||||
{
|
||||
int i = *x;
|
||||
|
||||
/* First 3 pixels of each line are absolute */
|
||||
if (i < 3) {
|
||||
(*dest)[i] = p * SE401_QUANT_FACT;
|
||||
} else {
|
||||
(*dest)[i] = (*dest)[i - 3] + p * SE401_QUANT_FACT;
|
||||
}
|
||||
|
||||
*x += 1;
|
||||
if (*x == pitch) {
|
||||
*x = 0;
|
||||
*dest += pitch;
|
||||
}
|
||||
}
|
||||
|
||||
enum decode_state {
|
||||
get_len,
|
||||
sign_bit,
|
||||
other_bits,
|
||||
};
|
||||
|
||||
static int decode_JangGu(const uint8_t *data, int bits, int plen, int pixels,
|
||||
uint8_t **dest, int pitch, int *x)
|
||||
{
|
||||
enum decode_state state = get_len;
|
||||
int len = 0;
|
||||
int value = 0;
|
||||
int bitnr;
|
||||
int bit;
|
||||
|
||||
while (plen) {
|
||||
bitnr = 8;
|
||||
while (bitnr && bits) {
|
||||
bit = ((*data) >> (bitnr-1))&1;
|
||||
switch (state) {
|
||||
case get_len:
|
||||
if (bit) {
|
||||
len++;
|
||||
} else {
|
||||
if (!len) {
|
||||
wr_pixel(0, dest, pitch, x);
|
||||
if (!--pixels)
|
||||
return 0;
|
||||
} else {
|
||||
state = sign_bit;
|
||||
value = 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case sign_bit:
|
||||
if (bit)
|
||||
value = 0;
|
||||
else
|
||||
value = -(1 << len) + 1;
|
||||
state = other_bits;
|
||||
/* fall through for positive number and
|
||||
len == 1 handling */
|
||||
case other_bits:
|
||||
len--;
|
||||
value += bit << len;
|
||||
if (len == 0) {
|
||||
/* Done write pixel and get bit len of
|
||||
the next one */
|
||||
state = get_len;
|
||||
wr_pixel(value, dest, pitch, x);
|
||||
if (!--pixels)
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
bitnr--;
|
||||
bits--;
|
||||
}
|
||||
data++;
|
||||
plen--;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int v4lconvert_se401_to_rgb24(struct v4lconvert_data *data,
|
||||
const unsigned char *src, int src_size,
|
||||
unsigned char *dest, int width, int height)
|
||||
{
|
||||
int in, plen, bits, pixels, info;
|
||||
int x = 0, total_pixels = 0;
|
||||
|
||||
if (!src || !dest)
|
||||
goto error;
|
||||
|
||||
for (in = 0; in + 4 < src_size; in += plen) {
|
||||
bits = src[in + 3] + (src[in + 2] << 8);
|
||||
pixels = src[in + 1] + ((src[in + 0] & 0x3f) << 8);
|
||||
info = (src[in + 0] & 0xc0) >> 6;
|
||||
plen = ((bits + 47) >> 4) << 1;
|
||||
/* Sanity checks */
|
||||
if (plen > 1024) {
|
||||
V4LCONVERT_ERR("invalid se401 packet len %d", plen);
|
||||
goto error;
|
||||
}
|
||||
if (in + plen > src_size) {
|
||||
V4LCONVERT_ERR("incomplete se401 packet");
|
||||
goto error;
|
||||
}
|
||||
if (total_pixels + pixels > width * height) {
|
||||
V4LCONVERT_ERR("se401 frame overflow");
|
||||
goto error;
|
||||
}
|
||||
/* info: 0 inter packet, 1 eof, 2 sof, 3 not used */
|
||||
if ((in == 0 && info != 2) ||
|
||||
(in > 0 && in + plen < src_size && info != 0) ||
|
||||
(in + plen == src_size && info != 1)) {
|
||||
V4LCONVERT_ERR("invalid se401 frame info value");
|
||||
goto error;
|
||||
}
|
||||
if (decode_JangGu(&src[in + 4], bits, plen, pixels * 3,
|
||||
&dest, width * 3, &x)) {
|
||||
V4LCONVERT_ERR("short se401 packet");
|
||||
goto error;
|
||||
}
|
||||
total_pixels += pixels;
|
||||
}
|
||||
|
||||
if (in != src_size || total_pixels != width * height) {
|
||||
V4LCONVERT_ERR("se401 frame size mismatch");
|
||||
goto error;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
errno = EIO;
|
||||
return -1;
|
||||
}
|
||||
273
libv4lconvert/sn9c10x.c
Normal file
273
libv4lconvert/sn9c10x.c
Normal file
@@ -0,0 +1,273 @@
|
||||
/*
|
||||
# sonix decoder
|
||||
# Bertrik.Sikken. (C) 2005
|
||||
|
||||
# This program 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 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
|
||||
# mail at the end of this file.
|
||||
*/
|
||||
|
||||
#include "libv4lconvert-priv.h"
|
||||
|
||||
#define CLAMP(x) ((x) < 0 ? 0 : ((x) > 255) ? 255 : (x))
|
||||
|
||||
struct code_table {
|
||||
int is_abs;
|
||||
int len;
|
||||
int val;
|
||||
int unk;
|
||||
};
|
||||
|
||||
|
||||
/* local storage */
|
||||
/* FIXME not thread safe !! */
|
||||
static struct code_table table[256];
|
||||
static int init_done;
|
||||
|
||||
/*
|
||||
sonix_decompress_init
|
||||
=====================
|
||||
pre-calculates a locally stored table for efficient huffman-decoding.
|
||||
|
||||
Each entry at index x in the table represents the codeword
|
||||
present at the MSB of byte x.
|
||||
|
||||
*/
|
||||
static void sonix_decompress_init(void)
|
||||
{
|
||||
int i;
|
||||
int is_abs, val, len, unk;
|
||||
|
||||
for (i = 0; i < 256; i++) {
|
||||
is_abs = 0;
|
||||
val = 0;
|
||||
len = 0;
|
||||
unk = 0;
|
||||
if ((i & 0x80) == 0) {
|
||||
/* code 0 */
|
||||
val = 0;
|
||||
len = 1;
|
||||
} else if ((i & 0xE0) == 0x80) {
|
||||
/* code 100 */
|
||||
val = 4;
|
||||
len = 3;
|
||||
} else if ((i & 0xE0) == 0xA0) {
|
||||
/* code 101 */
|
||||
val = -4;
|
||||
len = 3;
|
||||
} else if ((i & 0xF0) == 0xD0) {
|
||||
/* code 1101 */
|
||||
val = 11;
|
||||
len = 4;
|
||||
} else if ((i & 0xF0) == 0xF0) {
|
||||
/* code 1111 */
|
||||
val = -11;
|
||||
len = 4;
|
||||
} else if ((i & 0xF8) == 0xC8) {
|
||||
/* code 11001 */
|
||||
val = 20;
|
||||
len = 5;
|
||||
} else if ((i & 0xFC) == 0xC0) {
|
||||
/* code 110000 */
|
||||
val = -20;
|
||||
len = 6;
|
||||
} else if ((i & 0xFC) == 0xC4) {
|
||||
/* code 110001xx: unknown */
|
||||
val = 0;
|
||||
len = 8;
|
||||
unk = 1;
|
||||
} else if ((i & 0xF0) == 0xE0) {
|
||||
/* code 1110xxxx */
|
||||
is_abs = 1;
|
||||
val = (i & 0x0F) << 4;
|
||||
len = 8;
|
||||
}
|
||||
table[i].is_abs = is_abs;
|
||||
table[i].val = val;
|
||||
table[i].len = len;
|
||||
table[i].unk = unk;
|
||||
}
|
||||
|
||||
init_done = 1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
sonix_decompress
|
||||
================
|
||||
decompresses an image encoded by a SN9C101 camera controller chip.
|
||||
|
||||
IN width
|
||||
height
|
||||
inp pointer to compressed frame (with header already stripped)
|
||||
OUT outp pointer to decompressed frame
|
||||
|
||||
Returns 0 if the operation was successful.
|
||||
Returns <0 if operation failed.
|
||||
|
||||
*/
|
||||
void v4lconvert_decode_sn9c10x(const unsigned char *inp, unsigned char *outp,
|
||||
int width, int height)
|
||||
{
|
||||
int row, col;
|
||||
int val;
|
||||
int bitpos;
|
||||
unsigned char code;
|
||||
const unsigned char *addr;
|
||||
|
||||
if (!init_done)
|
||||
sonix_decompress_init();
|
||||
|
||||
bitpos = 0;
|
||||
for (row = 0; row < height; row++) {
|
||||
col = 0;
|
||||
|
||||
/* first two pixels in first two rows are stored as raw 8-bit */
|
||||
if (row < 2) {
|
||||
addr = inp + (bitpos >> 3);
|
||||
code = (addr[0] << (bitpos & 7)) | (addr[1] >> (8 - (bitpos & 7)));
|
||||
bitpos += 8;
|
||||
*outp++ = code;
|
||||
|
||||
addr = inp + (bitpos >> 3);
|
||||
code = (addr[0] << (bitpos & 7)) | (addr[1] >> (8 - (bitpos & 7)));
|
||||
bitpos += 8;
|
||||
*outp++ = code;
|
||||
|
||||
col += 2;
|
||||
}
|
||||
|
||||
while (col < width) {
|
||||
/* get bitcode from bitstream */
|
||||
addr = inp + (bitpos >> 3);
|
||||
code = (addr[0] << (bitpos & 7)) | (addr[1] >> (8 - (bitpos & 7)));
|
||||
|
||||
/* update bit position */
|
||||
bitpos += table[code].len;
|
||||
|
||||
/* Skip unknown codes (most likely they indicate
|
||||
a change of the delta's the various codes encode) */
|
||||
if (table[code].unk)
|
||||
continue;
|
||||
|
||||
/* calculate pixel value */
|
||||
val = table[code].val;
|
||||
if (!table[code].is_abs) {
|
||||
/* value is relative to top and left pixel */
|
||||
if (col < 2) {
|
||||
/* left column: relative to top pixel */
|
||||
val += outp[-2 * width];
|
||||
} else if (row < 2) {
|
||||
/* top row: relative to left pixel */
|
||||
val += outp[-2];
|
||||
} else {
|
||||
/* main area: average of left pixel and top pixel */
|
||||
val += (outp[-2] + outp[-2 * width]) / 2;
|
||||
}
|
||||
}
|
||||
|
||||
/* store pixel */
|
||||
*outp++ = CLAMP(val);
|
||||
col++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
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 89132066 for j.w.r.degoede@hhs.nl; Thu, 03 Jul 2008 15:19:55 +0200
|
||||
Received: from exim (helo=koko)
|
||||
by koko.hhs.nl with local-smtp (Exim 4.62)
|
||||
(envelope-from <bertrik@sikken.nl>)
|
||||
id 1KEOj5-0000nq-KR
|
||||
for j.w.r.degoede@hhs.nl; Thu, 03 Jul 2008 15:19:55 +0200
|
||||
Received: from [192.87.102.69] (port=33783 helo=filter1-ams.mf.surf.net)
|
||||
by koko.hhs.nl with esmtp (Exim 4.62)
|
||||
(envelope-from <bertrik@sikken.nl>)
|
||||
id 1KEOj5-0000nj-7r
|
||||
for j.w.r.degoede@hhs.nl; Thu, 03 Jul 2008 15:19:55 +0200
|
||||
Received: from cardassian.kabelfoon.nl (cardassian3.kabelfoon.nl [62.45.45.105])
|
||||
by filter1-ams.mf.surf.net (8.13.8/8.13.8/Debian-3) with ESMTP id m63DJsKW032598
|
||||
for <j.w.r.degoede@hhs.nl>; Thu, 3 Jul 2008 15:19:54 +0200
|
||||
Received: from [192.168.1.1] (044-013-045-062.dynamic.caiway.nl [62.45.13.44])
|
||||
by cardassian.kabelfoon.nl (Postfix) with ESMTP id 77761341D9A
|
||||
for <j.w.r.degoede@hhs.nl>; Thu, 3 Jul 2008 15:19:54 +0200 (CEST)
|
||||
Message-ID: <486CD1F9.8000307@sikken.nl>
|
||||
Date: Thu, 03 Jul 2008 15:19:53 +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> <4863F611.80104@sikken.nl> <486CC6AF.7050509@hhs.nl>
|
||||
In-Reply-To: <486CC6AF.7050509@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: 90943081 - 6a9ff19e8165
|
||||
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: 03072008 #811719, status: clean
|
||||
|
||||
-----BEGIN PGP SIGNED MESSAGE-----
|
||||
Hash: SHA1
|
||||
|
||||
Hans de Goede wrote:
|
||||
| Bertrik Sikken wrote:
|
||||
|> Hallo Hans,
|
||||
|>
|
||||
|> Hans de Goede wrote:
|
||||
|>> 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.
|
||||
|>
|
||||
|
|
||||
| Thanks!
|
||||
|
|
||||
| I'm currently working on adding support for the sn9c10x bayer
|
||||
| compression to libv4l too, and I noticed this was written by you too.
|
||||
|
|
||||
| May I have your permission to relicense the sn9c10x bayer decompression
|
||||
| code under the LGPL (version 2 or later)?
|
||||
|
||||
I hereby grant you permission to relicense the sn9c10x bayer
|
||||
decompression code under the LGPL (version 2 or later).
|
||||
|
||||
Kind regards,
|
||||
Bertrik
|
||||
-----BEGIN PGP SIGNATURE-----
|
||||
Version: GnuPG v1.4.7 (MingW32)
|
||||
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org
|
||||
|
||||
iD8DBQFIbNH5ETD6mlrWxPURAipvAJ9sv1ZpHyb81NMFejr6x0wqHX3i7QCfRDoB
|
||||
jZi2e5lUjEh5KvS0dqXbi9I=
|
||||
=KQfR
|
||||
-----END PGP SIGNATURE-----
|
||||
*/
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user